1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the Qt Designer of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:GPL-EXCEPT$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU
19** General Public License version 3 as published by the Free Software
20** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
21** included in the packaging of this file. Please review the following
22** information to ensure the GNU General Public License requirements will
23** be met: https://www.gnu.org/licenses/gpl-3.0.html.
24**
25** $QT_END_LICENSE$
26**
27****************************************************************************/
28
29#include "treewidgeteditor.h"
30#include <formwindowbase_p.h>
31#include <iconloader_p.h>
32#include <qdesigner_command_p.h>
33#include <qdesigner_utils_p.h>
34#include <abstractformbuilder.h>
35#include <designerpropertymanager.h>
36#include <qttreepropertybrowser.h>
37
38#include <QtDesigner/abstractformwindow.h>
39#include <QtDesigner/abstractformeditor.h>
40
41#include <QtCore/qdir.h>
42#include <QtCore/qqueue.h>
43#include <QtWidgets/qheaderview.h>
44#include <QtWidgets/qtreewidgetitemiterator.h>
45
46QT_BEGIN_NAMESPACE
47
48namespace qdesigner_internal {
49
50TreeWidgetEditor::TreeWidgetEditor(QDesignerFormWindowInterface *form, QDialog *dialog)
51 : AbstractItemEditor(form, nullptr), m_updatingBrowser(false)
52{
53 m_columnEditor = new ItemListEditor(form, this);
54 m_columnEditor->setObjectName(QStringLiteral("columnEditor"));
55 m_columnEditor->setNewItemText(tr(s: "New Column"));
56 ui.setupUi(dialog);
57
58 injectPropertyBrowser(parent: ui.itemsTab, widget: ui.widget);
59 connect(sender: ui.showPropertiesButton, signal: &QAbstractButton::clicked,
60 receiver: this, slot: &TreeWidgetEditor::togglePropertyBrowser);
61 setPropertyBrowserVisible(false);
62
63 ui.tabWidget->insertTab(index: 0, widget: m_columnEditor, tr(s: "&Columns"));
64 ui.tabWidget->setCurrentIndex(0);
65 setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
66
67 ui.newItemButton->setIcon(createIconSet(name: QString::fromUtf8(str: "plus.png")));
68 ui.newSubItemButton->setIcon(createIconSet(name: QString::fromUtf8(str: "downplus.png")));
69 ui.deleteItemButton->setIcon(createIconSet(name: QString::fromUtf8(str: "minus.png")));
70 ui.moveItemUpButton->setIcon(createIconSet(name: QString::fromUtf8(str: "up.png")));
71 ui.moveItemDownButton->setIcon(createIconSet(name: QString::fromUtf8(str: "down.png")));
72 ui.moveItemRightButton->setIcon(createIconSet(name: QString::fromUtf8(str: "leveldown.png")));
73 ui.moveItemLeftButton->setIcon(createIconSet(name: QString::fromUtf8(str: "levelup.png")));
74
75 ui.treeWidget->header()->setSectionsMovable(false);
76
77 connect(sender: ui.newItemButton, signal: &QAbstractButton::clicked, receiver: this, slot: &TreeWidgetEditor::on_newItemButton_clicked);
78 connect(sender: ui.newSubItemButton, signal: &QAbstractButton::clicked, receiver: this, slot: &TreeWidgetEditor::on_newSubItemButton_clicked);
79 connect(sender: ui.moveItemUpButton, signal: &QAbstractButton::clicked, receiver: this, slot: &TreeWidgetEditor::on_moveItemUpButton_clicked);
80 connect(sender: ui.moveItemDownButton, signal: &QAbstractButton::clicked, receiver: this, slot: &TreeWidgetEditor::on_moveItemDownButton_clicked);
81 connect(sender: ui.moveItemRightButton, signal: &QAbstractButton::clicked, receiver: this, slot: &TreeWidgetEditor::on_moveItemRightButton_clicked);
82 connect(sender: ui.moveItemLeftButton, signal: &QAbstractButton::clicked, receiver: this, slot: &TreeWidgetEditor::on_moveItemLeftButton_clicked);
83 connect(sender: ui.deleteItemButton, signal: &QAbstractButton::clicked, receiver: this, slot: &TreeWidgetEditor::on_deleteItemButton_clicked);
84 connect(sender: ui.treeWidget, signal: &QTreeWidget::currentItemChanged,
85 receiver: this, slot: &TreeWidgetEditor::on_treeWidget_currentItemChanged);
86 connect(sender: ui.treeWidget, signal: &QTreeWidget::itemChanged,
87 receiver: this, slot: &TreeWidgetEditor::on_treeWidget_itemChanged);
88
89 connect(sender: m_columnEditor, signal: &ItemListEditor::indexChanged,
90 receiver: this, slot: &TreeWidgetEditor::on_columnEditor_indexChanged);
91 connect(sender: m_columnEditor, signal: &ItemListEditor::itemChanged,
92 receiver: this, slot: &TreeWidgetEditor::on_columnEditor_itemChanged);
93 connect(sender: m_columnEditor, signal: &ItemListEditor::itemInserted,
94 receiver: this, slot: &TreeWidgetEditor::on_columnEditor_itemInserted);
95 connect(sender: m_columnEditor, signal: &ItemListEditor::itemDeleted,
96 receiver: this, slot: &TreeWidgetEditor::on_columnEditor_itemDeleted);
97 connect(sender: m_columnEditor, signal: &ItemListEditor::itemMovedUp,
98 receiver: this, slot: &TreeWidgetEditor::on_columnEditor_itemMovedUp);
99 connect(sender: m_columnEditor, signal: &ItemListEditor::itemMovedDown,
100 receiver: this, slot: &TreeWidgetEditor::on_columnEditor_itemMovedDown);
101
102 connect(sender: iconCache(), signal: &DesignerIconCache::reloaded, receiver: this, slot: &TreeWidgetEditor::cacheReloaded);
103}
104
105static AbstractItemEditor::PropertyDefinition treeHeaderPropList[] = {
106 { .role: Qt::DisplayPropertyRole, .type: 0, .typeFunc: DesignerPropertyManager::designerStringTypeId, .name: "text" },
107 { .role: Qt::DecorationPropertyRole, .type: 0, .typeFunc: DesignerPropertyManager::designerIconTypeId, .name: "icon" },
108 { .role: Qt::ToolTipPropertyRole, .type: 0, .typeFunc: DesignerPropertyManager::designerStringTypeId, .name: "toolTip" },
109 { .role: Qt::StatusTipPropertyRole, .type: 0, .typeFunc: DesignerPropertyManager::designerStringTypeId, .name: "statusTip" },
110 { .role: Qt::WhatsThisPropertyRole, .type: 0, .typeFunc: DesignerPropertyManager::designerStringTypeId, .name: "whatsThis" },
111 { .role: Qt::FontRole, .type: QVariant::Font, .typeFunc: nullptr, .name: "font" },
112 { .role: Qt::TextAlignmentRole, .type: 0, .typeFunc: DesignerPropertyManager::designerAlignmentTypeId, .name: "textAlignment" },
113 { .role: Qt::BackgroundRole, .type: QVariant::Color, .typeFunc: nullptr, .name: "background" },
114 { .role: Qt::ForegroundRole, .type: QVariant::Brush, .typeFunc: nullptr, .name: "foreground" },
115 { .role: 0, .type: 0, .typeFunc: nullptr, .name: nullptr }
116};
117
118static AbstractItemEditor::PropertyDefinition treeItemColumnPropList[] = {
119 { .role: Qt::DisplayPropertyRole, .type: 0, .typeFunc: DesignerPropertyManager::designerStringTypeId, .name: "text" },
120 { .role: Qt::DecorationPropertyRole, .type: 0, .typeFunc: DesignerPropertyManager::designerIconTypeId, .name: "icon" },
121 { .role: Qt::ToolTipPropertyRole, .type: 0, .typeFunc: DesignerPropertyManager::designerStringTypeId, .name: "toolTip" },
122 { .role: Qt::StatusTipPropertyRole, .type: 0, .typeFunc: DesignerPropertyManager::designerStringTypeId, .name: "statusTip" },
123 { .role: Qt::WhatsThisPropertyRole, .type: 0, .typeFunc: DesignerPropertyManager::designerStringTypeId, .name: "whatsThis" },
124 { .role: Qt::FontRole, .type: QVariant::Font, .typeFunc: nullptr, .name: "font" },
125 { .role: Qt::TextAlignmentRole, .type: 0, .typeFunc: DesignerPropertyManager::designerAlignmentTypeId, .name: "textAlignment" },
126 { .role: Qt::BackgroundRole, .type: QVariant::Brush, .typeFunc: nullptr, .name: "background" },
127 { .role: Qt::ForegroundRole, .type: QVariant::Brush, .typeFunc: nullptr, .name: "foreground" },
128 { .role: Qt::CheckStateRole, .type: 0, .typeFunc: QtVariantPropertyManager::enumTypeId, .name: "checkState" },
129 { .role: 0, .type: 0, .typeFunc: nullptr, .name: nullptr }
130};
131
132static AbstractItemEditor::PropertyDefinition treeItemCommonPropList[] = {
133 { .role: ItemFlagsShadowRole, .type: 0, .typeFunc: QtVariantPropertyManager::flagTypeId, .name: "flags" },
134 { .role: 0, .type: 0, .typeFunc: nullptr, .name: nullptr }
135};
136
137QtVariantProperty *TreeWidgetEditor::setupPropertyGroup(const QString &title, PropertyDefinition *propDefs)
138{
139 setupProperties(propList: propDefs);
140 QtVariantProperty *groupProp = m_propertyManager->addProperty(propertyType: QtVariantPropertyManager::groupTypeId(), name: title);
141 for (QtVariantProperty *prop : qAsConst(t&: m_rootProperties))
142 groupProp->addSubProperty(property: prop);
143 m_rootProperties.clear();
144 return groupProp;
145}
146
147TreeWidgetContents TreeWidgetEditor::fillContentsFromTreeWidget(QTreeWidget *treeWidget)
148{
149 TreeWidgetContents treeCont;
150 treeCont.fromTreeWidget(treeWidget, editor: false);
151 treeCont.applyToTreeWidget(treeWidget: ui.treeWidget, iconCache: iconCache(), editor: true);
152
153 treeCont.m_headerItem.applyToListWidget(listWidget: m_columnEditor->listWidget(), iconCache: iconCache(), editor: true);
154 m_columnEditor->setupEditor(object: treeWidget, propDefs: treeHeaderPropList);
155
156 QList<QtVariantProperty*> rootProperties;
157 rootProperties.append(t: setupPropertyGroup(title: tr(s: "Per column properties"), propDefs: treeItemColumnPropList));
158 rootProperties.append(t: setupPropertyGroup(title: tr(s: "Common properties"), propDefs: treeItemCommonPropList));
159 m_rootProperties = rootProperties;
160 m_propertyBrowser->setPropertiesWithoutValueMarked(true);
161 m_propertyBrowser->setRootIsDecorated(false);
162 setupObject(treeWidget);
163
164 if (ui.treeWidget->topLevelItemCount() > 0)
165 ui.treeWidget->setCurrentItem(ui.treeWidget->topLevelItem(index: 0));
166
167 updateEditor();
168
169 return treeCont;
170}
171
172TreeWidgetContents TreeWidgetEditor::contents() const
173{
174 TreeWidgetContents retVal;
175 retVal.fromTreeWidget(treeWidget: ui.treeWidget, editor: true);
176 return retVal;
177}
178
179void TreeWidgetEditor::setItemData(int role, const QVariant &v)
180{
181 const int col = (role == ItemFlagsShadowRole) ? 0 : ui.treeWidget->currentColumn();
182 QVariant newValue = v;
183 BoolBlocker block(m_updatingBrowser);
184 if (role == Qt::FontRole && newValue.type() == QVariant::Font) {
185 QFont oldFont = ui.treeWidget->font();
186 QFont newFont = qvariant_cast<QFont>(v: newValue).resolve(oldFont);
187 newValue = QVariant::fromValue(value: newFont);
188 ui.treeWidget->currentItem()->setData(column: col, role, value: QVariant()); // force the right font with the current resolve mask is set (item view bug)
189 }
190 ui.treeWidget->currentItem()->setData(column: col, role, value: newValue);
191}
192
193QVariant TreeWidgetEditor::getItemData(int role) const
194{
195 const int col = (role == ItemFlagsShadowRole) ? 0 : ui.treeWidget->currentColumn();
196 return ui.treeWidget->currentItem()->data(column: col, role);
197}
198
199int TreeWidgetEditor::defaultItemFlags() const
200{
201 static const int flags = QTreeWidgetItem().flags();
202 return flags;
203}
204
205void TreeWidgetEditor::on_newItemButton_clicked()
206{
207 QTreeWidgetItem *curItem = ui.treeWidget->currentItem();
208 QTreeWidgetItem *newItem = nullptr;
209 ui.treeWidget->blockSignals(b: true);
210 if (curItem) {
211 if (curItem->parent())
212 newItem = new QTreeWidgetItem(curItem->parent(), curItem);
213 else
214 newItem = new QTreeWidgetItem(ui.treeWidget, curItem);
215 } else
216 newItem = new QTreeWidgetItem(ui.treeWidget);
217 const QString newItemText = tr(s: "New Item");
218 newItem->setText(column: 0, atext: newItemText);
219 newItem->setData(column: 0, role: Qt::DisplayPropertyRole, value: QVariant::fromValue(value: PropertySheetStringValue(newItemText)));
220 newItem->setFlags(newItem->flags() | Qt::ItemIsEditable);
221 ui.treeWidget->blockSignals(b: false);
222
223 ui.treeWidget->setCurrentItem(item: newItem, column: qMax(a: ui.treeWidget->currentColumn(), b: 0));
224 updateEditor();
225 ui.treeWidget->editItem(item: newItem, column: ui.treeWidget->currentColumn());
226}
227
228void TreeWidgetEditor::on_newSubItemButton_clicked()
229{
230 QTreeWidgetItem *curItem = ui.treeWidget->currentItem();
231 if (!curItem)
232 return;
233
234 ui.treeWidget->blockSignals(b: true);
235 QTreeWidgetItem *newItem = new QTreeWidgetItem(curItem);
236 const QString newItemText = tr(s: "New Subitem");
237 newItem->setText(column: 0, atext: newItemText);
238 newItem->setData(column: 0, role: Qt::DisplayPropertyRole, value: QVariant::fromValue(value: PropertySheetStringValue(newItemText)));
239 newItem->setFlags(newItem->flags() | Qt::ItemIsEditable);
240 ui.treeWidget->blockSignals(b: false);
241
242 ui.treeWidget->setCurrentItem(item: newItem, column: ui.treeWidget->currentColumn());
243 updateEditor();
244 ui.treeWidget->editItem(item: newItem, column: ui.treeWidget->currentColumn());
245}
246
247void TreeWidgetEditor::on_deleteItemButton_clicked()
248{
249 QTreeWidgetItem *curItem = ui.treeWidget->currentItem();
250 if (!curItem)
251 return;
252
253 QTreeWidgetItem *nextCurrent = nullptr;
254 if (curItem->parent()) {
255 int idx = curItem->parent()->indexOfChild(achild: curItem);
256 if (idx == curItem->parent()->childCount() - 1)
257 idx--;
258 else
259 idx++;
260 if (idx < 0)
261 nextCurrent = curItem->parent();
262 else
263 nextCurrent = curItem->parent()->child(index: idx);
264 } else {
265 int idx = ui.treeWidget->indexOfTopLevelItem(item: curItem);
266 if (idx == ui.treeWidget->topLevelItemCount() - 1)
267 idx--;
268 else
269 idx++;
270 if (idx >= 0)
271 nextCurrent = ui.treeWidget->topLevelItem(index: idx);
272 }
273 closeEditors();
274 ui.treeWidget->blockSignals(b: true);
275 delete curItem;
276 ui.treeWidget->blockSignals(b: false);
277
278 if (nextCurrent)
279 ui.treeWidget->setCurrentItem(item: nextCurrent, column: ui.treeWidget->currentColumn());
280 updateEditor();
281}
282
283void TreeWidgetEditor::on_moveItemUpButton_clicked()
284{
285 QTreeWidgetItem *curItem = ui.treeWidget->currentItem();
286 if (!curItem)
287 return;
288
289 int idx;
290 if (curItem->parent())
291 idx = curItem->parent()->indexOfChild(achild: curItem);
292 else
293 idx = ui.treeWidget->indexOfTopLevelItem(item: curItem);
294 if (idx == 0)
295 return;
296
297 QTreeWidgetItem *takenItem;
298 ui.treeWidget->blockSignals(b: true);
299 if (curItem->parent()) {
300 QTreeWidgetItem *parentItem = curItem->parent();
301 takenItem = parentItem->takeChild(index: idx);
302 parentItem->insertChild(index: idx - 1, child: takenItem);
303 } else {
304 takenItem = ui.treeWidget->takeTopLevelItem(index: idx);
305 ui.treeWidget->insertTopLevelItem(index: idx - 1, item: takenItem);
306 }
307 ui.treeWidget->blockSignals(b: false);
308
309 ui.treeWidget->setCurrentItem(item: takenItem, column: ui.treeWidget->currentColumn());
310 updateEditor();
311}
312
313void TreeWidgetEditor::on_moveItemDownButton_clicked()
314{
315 QTreeWidgetItem *curItem = ui.treeWidget->currentItem();
316 if (!curItem)
317 return;
318
319 int idx, idxCount;
320 if (curItem->parent()) {
321 idx = curItem->parent()->indexOfChild(achild: curItem);
322 idxCount = curItem->parent()->childCount();
323 } else {
324 idx = ui.treeWidget->indexOfTopLevelItem(item: curItem);
325 idxCount = ui.treeWidget->topLevelItemCount();
326 }
327 if (idx == idxCount - 1)
328 return;
329
330 QTreeWidgetItem *takenItem;
331 ui.treeWidget->blockSignals(b: true);
332 if (curItem->parent()) {
333 QTreeWidgetItem *parentItem = curItem->parent();
334 takenItem = parentItem->takeChild(index: idx);
335 parentItem->insertChild(index: idx + 1, child: takenItem);
336 } else {
337 takenItem = ui.treeWidget->takeTopLevelItem(index: idx);
338 ui.treeWidget->insertTopLevelItem(index: idx + 1, item: takenItem);
339 }
340 ui.treeWidget->blockSignals(b: false);
341
342 ui.treeWidget->setCurrentItem(item: takenItem, column: ui.treeWidget->currentColumn());
343 updateEditor();
344}
345
346void TreeWidgetEditor::on_moveItemLeftButton_clicked()
347{
348 QTreeWidgetItem *curItem = ui.treeWidget->currentItem();
349 if (!curItem)
350 return;
351
352 QTreeWidgetItem *parentItem = curItem->parent();
353 if (!parentItem)
354 return;
355
356 ui.treeWidget->blockSignals(b: true);
357 QTreeWidgetItem *takenItem = parentItem->takeChild(index: parentItem->indexOfChild(achild: curItem));
358 if (parentItem->parent()) {
359 int idx = parentItem->parent()->indexOfChild(achild: parentItem);
360 parentItem->parent()->insertChild(index: idx, child: takenItem);
361 } else {
362 int idx = ui.treeWidget->indexOfTopLevelItem(item: parentItem);
363 ui.treeWidget->insertTopLevelItem(index: idx, item: takenItem);
364 }
365 ui.treeWidget->blockSignals(b: false);
366
367 ui.treeWidget->setCurrentItem(item: takenItem, column: ui.treeWidget->currentColumn());
368 updateEditor();
369}
370
371void TreeWidgetEditor::on_moveItemRightButton_clicked()
372{
373 QTreeWidgetItem *curItem = ui.treeWidget->currentItem();
374 if (!curItem)
375 return;
376
377 int idx, idxCount;
378 if (curItem->parent()) {
379 idx = curItem->parent()->indexOfChild(achild: curItem);
380 idxCount = curItem->parent()->childCount();
381 } else {
382 idx = ui.treeWidget->indexOfTopLevelItem(item: curItem);
383 idxCount = ui.treeWidget->topLevelItemCount();
384 }
385 if (idx == idxCount - 1)
386 return;
387
388 QTreeWidgetItem *takenItem;
389 ui.treeWidget->blockSignals(b: true);
390 if (curItem->parent()) {
391 QTreeWidgetItem *parentItem = curItem->parent()->child(index: idx + 1);
392 takenItem = curItem->parent()->takeChild(index: idx);
393 parentItem->insertChild(index: 0, child: takenItem);
394 } else {
395 QTreeWidgetItem *parentItem = ui.treeWidget->topLevelItem(index: idx + 1);
396 takenItem = ui.treeWidget->takeTopLevelItem(index: idx);
397 parentItem->insertChild(index: 0, child: takenItem);
398 }
399 ui.treeWidget->blockSignals(b: false);
400
401 ui.treeWidget->setCurrentItem(item: takenItem, column: ui.treeWidget->currentColumn());
402 updateEditor();
403}
404
405void TreeWidgetEditor::togglePropertyBrowser()
406{
407 setPropertyBrowserVisible(!m_propertyBrowser->isVisible());
408}
409
410void TreeWidgetEditor::setPropertyBrowserVisible(bool v)
411{
412 ui.showPropertiesButton->setText(v ? tr(s: "Properties &>>") : tr(s: "Properties &<<"));
413 m_propertyBrowser->setVisible(v);
414}
415
416void TreeWidgetEditor::on_treeWidget_currentItemChanged()
417{
418 m_columnEditor->setCurrentIndex(ui.treeWidget->currentColumn());
419 updateEditor();
420}
421
422void TreeWidgetEditor::on_treeWidget_itemChanged(QTreeWidgetItem *item, int column)
423{
424 if (m_updatingBrowser)
425 return;
426
427 PropertySheetStringValue val = qvariant_cast<PropertySheetStringValue>(v: item->data(column, role: Qt::DisplayPropertyRole));
428 val.setValue(item->text(column));
429 BoolBlocker block(m_updatingBrowser);
430 item->setData(column, role: Qt::DisplayPropertyRole, value: QVariant::fromValue(value: val));
431
432 updateBrowser();
433}
434
435void TreeWidgetEditor::on_columnEditor_indexChanged(int idx)
436{
437 if (QTreeWidgetItem *item = ui.treeWidget->currentItem())
438 ui.treeWidget->setCurrentItem(item, column: idx);
439}
440
441void TreeWidgetEditor::on_columnEditor_itemChanged(int idx, int role, const QVariant &v)
442{
443 if (role == Qt::DisplayPropertyRole)
444 ui.treeWidget->headerItem()->setData(column: idx, role: Qt::EditRole, value: qvariant_cast<PropertySheetStringValue>(v).value());
445 ui.treeWidget->headerItem()->setData(column: idx, role, value: v);
446}
447
448void TreeWidgetEditor::updateEditor()
449{
450 QTreeWidgetItem *current = ui.treeWidget->currentItem();
451
452 bool itemsEnabled = false;
453 bool currentItemEnabled = false;
454 bool moveItemUpEnabled = false;
455 bool moveItemDownEnabled = false;
456 bool moveItemRightEnabled = false;
457 bool moveItemLeftEnabled = false;
458
459 if (ui.treeWidget->columnCount() > 0) {
460 itemsEnabled = true;
461 if (current) {
462 int idx;
463 int idxCount;
464 currentItemEnabled = true;
465 if (current->parent()) {
466 moveItemLeftEnabled = true;
467 idx = current->parent()->indexOfChild(achild: current);
468 idxCount = current->parent()->childCount();
469 } else {
470 idx = ui.treeWidget->indexOfTopLevelItem(item: current);
471 idxCount = ui.treeWidget->topLevelItemCount();
472 }
473 if (idx > 0)
474 moveItemUpEnabled = true;
475 if (idx < idxCount - 1) {
476 moveItemDownEnabled = true;
477 moveItemRightEnabled = true;
478 }
479 }
480 }
481 ui.tabWidget->setTabEnabled(index: 1, enabled: itemsEnabled);
482 ui.newSubItemButton->setEnabled(currentItemEnabled);
483 ui.deleteItemButton->setEnabled(currentItemEnabled);
484
485 ui.moveItemUpButton->setEnabled(moveItemUpEnabled);
486 ui.moveItemDownButton->setEnabled(moveItemDownEnabled);
487 ui.moveItemRightButton->setEnabled(moveItemRightEnabled);
488 ui.moveItemLeftButton->setEnabled(moveItemLeftEnabled);
489
490 if (current)
491 updateBrowser();
492 else
493 m_propertyBrowser->clear();
494}
495
496void TreeWidgetEditor::moveColumnItems(const PropertyDefinition *propList,
497 QTreeWidgetItem *item, int fromColumn, int toColumn, int step)
498{
499 BoolBlocker block(m_updatingBrowser);
500
501 QList<QVariant> saveCol;
502 for (int j = 0; propList[j].name; j++)
503 saveCol.append(t: item->data(column: toColumn, role: propList[j].role));
504 QVariant editVariant = item->data(column: toColumn, role: Qt::EditRole);
505 QVariant toolTipVariant = item->data(column: toColumn, role: Qt::ToolTipRole);
506 QVariant statusTipVariant = item->data(column: toColumn, role: Qt::StatusTipRole);
507 QVariant whatsThisVariant = item->data(column: toColumn, role: Qt::WhatsThisRole);
508 QVariant decorationVariant = item->data(column: toColumn, role: Qt::DecorationRole);
509 for (int i = toColumn; i != fromColumn; i += step) {
510 for (int j = 0; propList[j].name; j++)
511 item->setData(column: i, role: propList[j].role, value: item->data(column: i + step, role: propList[j].role));
512 item->setData(column: i, role: Qt::EditRole, value: item->data(column: i + step, role: Qt::EditRole));
513 item->setData(column: i, role: Qt::ToolTipRole, value: item->data(column: i + step, role: Qt::ToolTipRole));
514 item->setData(column: i, role: Qt::StatusTipRole, value: item->data(column: i + step, role: Qt::StatusTipRole));
515 item->setData(column: i, role: Qt::WhatsThisRole, value: item->data(column: i + step, role: Qt::WhatsThisRole));
516 item->setData(column: i, role: Qt::DecorationRole, value: item->data(column: i + step, role: Qt::DecorationRole));
517 }
518 for (int j = 0; propList[j].name; j++)
519 item->setData(column: fromColumn, role: propList[j].role, value: saveCol[j]);
520 item->setData(column: fromColumn, role: Qt::EditRole, value: editVariant);
521 item->setData(column: fromColumn, role: Qt::ToolTipRole, value: toolTipVariant);
522 item->setData(column: fromColumn, role: Qt::StatusTipRole, value: statusTipVariant);
523 item->setData(column: fromColumn, role: Qt::WhatsThisRole, value: whatsThisVariant);
524 item->setData(column: fromColumn, role: Qt::DecorationRole, value: decorationVariant);
525}
526
527void TreeWidgetEditor::moveColumns(int fromColumn, int toColumn, int step)
528{
529 ui.treeWidget->blockSignals(b: true);
530
531 moveColumnItems(propList: treeHeaderPropList, item: ui.treeWidget->headerItem(), fromColumn, toColumn, step);
532
533 QQueue<QTreeWidgetItem *> pendingQueue;
534 for (int i = 0; i < ui.treeWidget->topLevelItemCount(); i++)
535 pendingQueue.enqueue(t: ui.treeWidget->topLevelItem(index: i));
536
537 while (!pendingQueue.isEmpty()) {
538 QTreeWidgetItem *item = pendingQueue.dequeue();
539 for (int i = 0; i < item->childCount(); i++)
540 pendingQueue.enqueue(t: item->child(index: i));
541
542 moveColumnItems(propList: treeItemColumnPropList, item, fromColumn, toColumn, step);
543 }
544
545 ui.treeWidget->blockSignals(b: false);
546}
547
548void TreeWidgetEditor::moveColumnsLeft(int fromColumn, int toColumn)
549{
550 if (fromColumn >= toColumn)
551 return;
552
553 moveColumns(fromColumn, toColumn, step: -1);
554}
555
556void TreeWidgetEditor::moveColumnsRight(int fromColumn, int toColumn)
557{
558 if (fromColumn >= toColumn)
559 return;
560
561 moveColumns(fromColumn: toColumn, toColumn: fromColumn, step: 1);
562}
563
564void TreeWidgetEditor::on_columnEditor_itemInserted(int idx)
565{
566 int columnCount = ui.treeWidget->columnCount();
567 ui.treeWidget->setColumnCount(columnCount + 1);
568 ui.treeWidget->headerItem()->setText(column: columnCount, atext: m_columnEditor->newItemText());
569 moveColumnsLeft(fromColumn: idx, toColumn: columnCount);
570
571 updateEditor();
572}
573
574void TreeWidgetEditor::on_columnEditor_itemDeleted(int idx)
575{
576 closeEditors();
577
578 int columnCount = ui.treeWidget->columnCount() - 1;
579 if (!columnCount)
580 ui.treeWidget->clear();
581 else
582 moveColumnsRight(fromColumn: idx, toColumn: columnCount);
583 ui.treeWidget->setColumnCount(columnCount);
584
585 updateEditor();
586}
587
588void TreeWidgetEditor::on_columnEditor_itemMovedUp(int idx)
589{
590 moveColumnsRight(fromColumn: idx - 1, toColumn: idx);
591
592 ui.treeWidget->setCurrentItem(item: ui.treeWidget->currentItem(), column: idx - 1);
593 updateEditor();
594}
595
596void TreeWidgetEditor::on_columnEditor_itemMovedDown(int idx)
597{
598 moveColumnsLeft(fromColumn: idx, toColumn: idx + 1);
599
600 ui.treeWidget->setCurrentItem(item: ui.treeWidget->currentItem(), column: idx + 1);
601 updateEditor();
602}
603
604void TreeWidgetEditor::closeEditors()
605{
606 if (QTreeWidgetItem *cur = ui.treeWidget->currentItem() ) {
607 const int numCols = cur->columnCount ();
608 for (int i = 0; i < numCols; i++)
609 ui.treeWidget->closePersistentEditor (item: cur, column: i);
610 }
611}
612
613void TreeWidgetEditor::cacheReloaded()
614{
615 reloadIconResources(iconCache: iconCache(), object: ui.treeWidget);
616}
617
618TreeWidgetEditorDialog::TreeWidgetEditorDialog(QDesignerFormWindowInterface *form, QWidget *parent) :
619 QDialog(parent), m_editor(form, this)
620{
621 setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
622}
623
624TreeWidgetContents TreeWidgetEditorDialog::fillContentsFromTreeWidget(QTreeWidget *treeWidget)
625{
626 return m_editor.fillContentsFromTreeWidget(treeWidget);
627}
628
629TreeWidgetContents TreeWidgetEditorDialog::contents() const
630{
631 return m_editor.contents();
632}
633
634} // namespace qdesigner_internal
635
636QT_END_NAMESPACE
637

source code of qttools/src/designer/src/components/taskmenu/treewidgeteditor.cpp