Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qdesigner_command.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
3// Qt-Security score:significant reason:default
4
8#include "layout_p.h"
12#include "shared_enums_p.h"
13#include "metadatabase_p.h"
15#include <abstractformbuilder.h>
16
17#include <QtDesigner/abstractformwindow.h>
18#include <QtDesigner/abstractformeditor.h>
19#include <QtDesigner/propertysheet.h>
20#include <QtDesigner/abstractactioneditor.h>
21#include <QtDesigner/abstractpropertyeditor.h>
22#include <QtDesigner/qextensionmanager.h>
23#include <QtDesigner/container.h>
24#include <QtDesigner/layoutdecoration.h>
25#include <QtDesigner/abstractwidgetfactory.h>
26#include <QtDesigner/abstractobjectinspector.h>
27#include <QtDesigner/abstractintegration.h>
28#include <QtDesigner/abstractformwindowcursor.h>
29#include <QtCore/qdebug.h>
30#include <QtCore/qtextstream.h>
31#include <QtCore/qqueue.h>
32
33#include <QtWidgets/qmenubar.h>
34#include <QtWidgets/qstatusbar.h>
35#include <QtWidgets/qtoolbar.h>
36#include <QtWidgets/qtoolbox.h>
37#include <QtWidgets/qstackedwidget.h>
38#include <QtWidgets/qtabwidget.h>
39#include <QtWidgets/qtablewidget.h>
40#include <QtWidgets/qtreewidget.h>
41#include <QtWidgets/qlistwidget.h>
42#include <QtWidgets/qcombobox.h>
43#include <QtWidgets/qsplitter.h>
44#include <QtWidgets/qdockwidget.h>
45#include <QtWidgets/qmainwindow.h>
46#include <QtWidgets/qwizard.h>
47#include <QtWidgets/qapplication.h>
48#include <QtWidgets/qformlayout.h>
49
50#include <algorithm>
51
52Q_DECLARE_METATYPE(QWidgetList)
53
54QT_BEGIN_NAMESPACE
55
56using namespace Qt::StringLiterals;
57
58static inline void setPropertySheetWindowTitle(const QDesignerFormEditorInterface *core, QObject *o, const QString &t)
59{
60 if (QDesignerPropertySheetExtension *sheet = qt_extension<QDesignerPropertySheetExtension*>(core->extensionManager(), o)) {
61 const int idx = sheet->indexOf(u"windowTitle"_s);
62 if (idx != -1) {
63 sheet->setProperty(idx, t);
64 sheet->setChanged(idx, true);
65 }
66 }
67}
68
69namespace qdesigner_internal {
70
71// Helpers for the dynamic properties that store Z/Widget order
72static const char widgetOrderPropertyC[] = "_q_widgetOrder";
73static const char zOrderPropertyC[] = "_q_zOrder";
74
75static void addToWidgetListDynamicProperty(QWidget *parentWidget, QWidget *widget, const char *name, int index = -1)
76{
77 auto list = qvariant_cast<QWidgetList>(parentWidget->property(name));
78 list.removeAll(widget);
79 if (index >= 0 && index < list.size()) {
80 list.insert(index, widget);
81 } else {
82 list.append(widget);
83 }
84 parentWidget->setProperty(name, QVariant::fromValue(list));
85}
86
87static int removeFromWidgetListDynamicProperty(QWidget *parentWidget, QWidget *widget, const char *name)
88{
89 auto list = qvariant_cast<QWidgetList>(parentWidget->property(name));
90 const auto firstIndex = list.indexOf(widget);
91 if (firstIndex != -1) {
92 list.removeAll(widget);
93 parentWidget->setProperty(name, QVariant::fromValue(list));
94 }
95 return firstIndex;
96}
97
98// ---- InsertWidgetCommand ----
106
111
131
133{
134 w->update();
135
136 for (auto *child : w->children()) {
137 if (QWidget *w = qobject_cast<QWidget*>(child))
138 recursiveUpdate(w);
139 }
140}
141
185
210
212{
213 const auto label_list = formWindow()->findChildren<QLabel*>();
214 if (label_list.isEmpty())
215 return;
216
217 const QString buddyProperty = u"buddy"_s;
219 // Re-set the buddy (The sheet locates the object by name and sets it)
220 for (QLabel *label : label_list) {
222 const int idx = sheet->indexOf(buddyProperty);
223 if (idx != -1) {
224 const QVariant value = sheet->property(idx);
227 }
228 }
229 }
230}
231
232// ---- ChangeZOrderCommand ----
237
239{
241
243
244 setText(QApplication::translate("Command", "Change Z-order of '%1'").arg(widget->objectName()));
245
248 if (index != -1 && index + 1 < m_oldParentZOrder.size())
250}
251
258
268
269// ---- RaiseWidgetCommand ----
274
280
288
290{
291 widget->raise();
292}
293
294// ---- LowerWidgetCommand ----
299
307
313
315{
316 widget->lower();
317}
318
319// ---- ManageWidgetCommandHelper
321
334
340
342{
343 // Manage the managed children after parent
345 for (auto *w : std::as_const(m_managedChildren))
346 fw->manageWidget(w);
347}
348
350{
351 // Unmanage the managed children first
352 for (auto *w : std::as_const(m_managedChildren))
355}
356
357// ---- DeleteWidgetCommand ----
371
376
378{
382 m_flags = flags;
384 m_splitterIndex = -1;
385 bool isManaged = false; // Check for a managed layout
386 QLayout *layout = nullptr;
388 if (!isManaged)
390 switch (m_layoutType) {
391 case LayoutInfo::HSplitter:
392 case LayoutInfo::VSplitter: {
396 }
397 break;
398 case LayoutInfo::NoLayout:
399 break;
400 default:
403 break;
404 }
405
408
409 // Build the list of managed children
411
412 setText(QApplication::translate("Command", "Delete '%1'").arg(widget->objectName()));
413}
414
416{
419
421 const int count = c->count();
422 for (int i=0; i<count; ++i) {
423 if (c->widget(i) == m_widget) {
424 c->remove(i);
425 return;
426 }
427 }
428 }
429
432
435
436 if (m_layoutHelper)
437 switch (m_layoutType) {
438 case LayoutInfo::NoLayout:
439 case LayoutInfo::HSplitter:
440 case LayoutInfo::VSplitter:
441 break;
442 default:
443 // Attempt to simplify grids if a row/column becomes empty
445 if (m_layoutSimplified) {
448 }
449 break;
450 }
451
452 if (!(m_flags & DoNotUnmanage))
454
456 m_widget->hide();
457
458 if (m_tabOrderIndex != -1) {
462 }
463}
464
466{
469
471
474 return;
475 }
476
479
481
482 if (!(m_flags & DoNotUnmanage))
484 // ### set up alignment
485 switch (m_layoutType) {
486 case LayoutInfo::NoLayout:
487 break;
488 case LayoutInfo::HSplitter:
489 case LayoutInfo::VSplitter: {
493 } break;
494 default: {
501 }
502 break;
503 }
504
505 m_widget->show();
506
507 if (m_tabOrderIndex != -1) {
511 }
512}
513
514// ---- ReparentWidgetCommand ----
519
536
561
582
588
594
596{
597 for (QWidget *w : std::as_const(m_widgets)) {
598 if (w)
600 }
602}
603
605{
606 // Update class names in ObjectInspector, PropertyEditor
610 if (QObject *o = core->propertyEditor()->object())
612}
613
615{
616 for (QWidget *w : std::as_const(m_widgets)) {
617 if (w)
618 demoteWidget(core(), w);
619 }
621}
622
623// ---- DemoteFromCustomWidgetCommand ----
624
631
636
641
646
647// ---------- CursorSelectionState
649
661
663{
664 if (m_selection.isEmpty()) {
666 } else {
667 // Select current as last
669 for (const auto &wp : m_selection) {
670 if (!wp.isNull() && wp.data() != m_current)
671 formWindow->selectWidget(wp.data(), true);
672 }
673 if (m_current)
675 }
676}
677
678// ---- LayoutCommand ----
679
685
687{
688 delete m_layout;
689}
690
694{
700
701 switch (layoutType) {
702 case LayoutInfo::Grid:
703 setText(QApplication::translate("Command", "Lay out using grid"));
704 break;
705 case LayoutInfo::VBox:
706 setText(QApplication::translate("Command", "Lay out vertically"));
707 break;
708 case LayoutInfo::HBox:
709 setText(QApplication::translate("Command", "Lay out horizontally"));
710 break;
711 default:
712 break;
713 }
714 // Delayed setup to avoid confusion in case we are chained
715 // with a BreakLayout in a morph layout macro
716 m_setup = false;
717}
718
720{
721 if (!m_setup) {
722 m_layout->setup();
724 m_setup = true;
725 }
728}
729
731{
733
737 delete deco; // release the extension
738
739 // ### generalize (put in function)
740 if (!m_layoutBase && lb != nullptr && !(qobject_cast<QLayoutWidget*>(lb) || qobject_cast<QSplitter*>(lb))) {
741 core->metaDataBase()->add(lb);
742 lb->show();
743 }
746}
747
748// ---- BreakLayoutCommand ----
756
758{
759 delete m_layoutHelper;
760 delete m_layout;
761 delete m_properties;
762}
763
768
770{
771 return m_propertyMask;
772}
773
775{
777
781 QLayout *layoutToBeBroken = nullptr;
785
787 switch (layoutType) {
788 case LayoutInfo::NoLayout:
789 case LayoutInfo::HSplitter:
790 case LayoutInfo::VSplitter:
792 break;
793 case LayoutInfo::HBox:
794 case LayoutInfo::VBox: // Margin/spacing need to be saved
796 break;
797 default: // Margin/spacing need to be saved + has a state (empty rows/columns of a grid)
799 break;
800 }
801 Q_ASSERT(m_layout != nullptr);
802 m_layout->sort();
803
804
808 }
809 if (type >= LayoutHasState)
812}
813
815{
816 if (!m_layout)
817 return;
818
822 formWindow()->clearSelection(false);
823 if (m_layoutHelper)
826 delete deco; // release the extension
827
828 for (QWidget *widget : std::as_const(m_widgets)) {
829 widget->resize(widget->size().expandedTo(QSize(16, 16)));
830 }
831 // Update unless we are in an intermediate state of morphing layout
832 // in which a QLayoutWidget will have no layout at all.
835}
836
853// ---- SimplifyLayoutCommand
855 QDesignerFormWindowCommand(QApplication::translate("Command", "Simplify Grid Layout"), formWindow),
856 m_area(0, 0, 32767, 32767),
857 m_layoutBase(nullptr),
858 m_layoutHelper(nullptr),
859 m_layoutSimplified(false)
860{
861}
862
867
869{
870 if (!w)
871 return false;
872 QLayout *layout = nullptr;
874 if (layoutType)
875 *layoutType = type;
876 if (!layout)
877 return false;
878 switch (type) { // Known negatives
879 case LayoutInfo::NoLayout:
881 case LayoutInfo::HSplitter:
882 case LayoutInfo::VSplitter:
883 case LayoutInfo::HBox:
884 case LayoutInfo::VBox:
885 return false;
886 default:
887 break;
888 }
889 switch (type) {
890 case LayoutInfo::Grid:
892 case LayoutInfo::Form:
894 default:
895 break;
896 }
897 return false;
898}
899
912
926
927// ---- ToolBoxCommand ----
933
934ToolBoxCommand::~ToolBoxCommand() = default;
935
944
955
957{
961
962 QDesignerPropertySheetExtension *sheet = qt_extension<QDesignerPropertySheetExtension*>(formWindow()->core()->extensionManager(), m_toolBox);
963 if (sheet) {
965 sheet->setProperty(sheet->indexOf(u"currentItemText"_s), QVariant::fromValue(itemText));
966 }
967
968 m_widget->show();
971}
972
973// ---- MoveToolBoxPageCommand ----
980
982
994
1000
1006
1007// ---- DeleteToolBoxPageCommand ----
1012
1014
1016{
1018 setText(QApplication::translate("Command", "Delete Page"));
1019}
1020
1022{
1023 removePage();
1024 cheapUpdate();
1025}
1026
1028{
1029 addPage();
1030 cheapUpdate();
1031}
1032
1033// ---- AddToolBoxPageCommand ----
1038
1040
1045
1047{
1049
1051 if (mode == InsertAfter)
1052 m_index++;
1054 m_itemText = QApplication::translate("Command", "Page");
1055 m_itemIcon = QIcon();
1056 m_widget->setObjectName(u"page"_s);
1058
1059 setText(QApplication::translate("Command", "Insert Page"));
1060
1061 QDesignerFormEditorInterface *core = formWindow()->core();
1063}
1064
1066{
1067 addPage();
1068 cheapUpdate();
1069}
1070
1072{
1073 removePage();
1074 cheapUpdate();
1075}
1076
1077// ---- TabWidgetCommand ----
1083
1085
1094
1106
1108{
1109 m_widget->setParent(nullptr);
1111 m_widget->show();
1113
1114 QDesignerPropertySheetExtension *sheet = qt_extension<QDesignerPropertySheetExtension*>(formWindow()->core()->extensionManager(), m_tabWidget);
1115 if (sheet) {
1117 sheet->setProperty(sheet->indexOf(u"currentTabText"_s),
1119 }
1120
1123}
1124
1125// ---- DeleteTabPageCommand ----
1130
1132
1134{
1136 setText(QApplication::translate("Command", "Delete Page"));
1137}
1138
1140{
1141 removePage();
1142 cheapUpdate();
1143}
1144
1146{
1147 addPage();
1148 cheapUpdate();
1149}
1150
1151// ---- AddTabPageCommand ----
1156
1158
1163
1165{
1167
1169 if (mode == InsertAfter)
1170 m_index++;
1172 m_itemText = QApplication::translate("Command", "Page");
1173 m_itemIcon = QIcon();
1174 m_widget->setObjectName(u"tab"_s);
1176
1177 setText(QApplication::translate("Command", "Insert Page"));
1178
1179 QDesignerFormEditorInterface *core = formWindow()->core();
1181}
1182
1184{
1185 addPage();
1186 cheapUpdate();
1187}
1188
1190{
1191 removePage();
1192 cheapUpdate();
1193}
1194
1195// ---- MoveTabPageCommand ----
1202
1204
1206 const QIcon &icon, const QString &label,
1207 int index, int newIndex)
1208{
1210 setText(QApplication::translate("Command", "Move Page"));
1211
1212 m_page = page;
1214 m_oldIndex = index;
1215 m_label = label;
1216 m_icon = icon;
1217}
1218
1225
1232
1233// ---- StackedWidgetCommand ----
1239
1241
1248
1259
1270
1271// ---- MoveStackedWidgetCommand ----
1278
1280
1290
1296
1302
1303// ---- DeleteStackedWidgetPageCommand ----
1308
1310
1316
1318{
1319 removePage();
1320 cheapUpdate();
1321}
1322
1324{
1325 addPage();
1326 cheapUpdate();
1327}
1328
1329// ---- AddStackedWidgetPageCommand ----
1334
1336
1341
1343{
1345
1347 if (mode == InsertAfter)
1348 m_index++;
1350 m_widget->setObjectName(u"page"_s);
1352
1353 setText(QApplication::translate("Command", "Insert Page"));
1354
1355 QDesignerFormEditorInterface *core = formWindow()->core();
1357}
1358
1360{
1361 addPage();
1362 cheapUpdate();
1363}
1364
1366{
1367 removePage();
1368 cheapUpdate();
1369}
1370
1371// ---- TabOrderCommand ----
1377
1388
1393
1398
1399// ---- CreateMenuBarCommand ----
1404
1406{
1408 QDesignerFormEditorInterface *core = formWindow()->core();
1411}
1412
1414{
1415 QDesignerFormEditorInterface *core = formWindow()->core();
1416 auto *c = qt_extension<QDesignerContainerExtension*>(core->extensionManager(), m_mainWindow);
1418
1419 m_menuBar->setObjectName(u"menuBar"_s);
1424}
1425
1427{
1428 QDesignerFormEditorInterface *core = formWindow()->core();
1429 auto *c = qt_extension<QDesignerContainerExtension*>(core->extensionManager(), m_mainWindow);
1430 for (int i = 0; i < c->count(); ++i) {
1431 if (c->widget(i) == m_menuBar) {
1432 c->remove(i);
1433 break;
1434 }
1435 }
1436
1439}
1440
1441// ---- DeleteMenuBarCommand ----
1446
1452
1454{
1455 if (m_mainWindow) {
1456 auto *c = qt_extension<QDesignerContainerExtension*>(core()->extensionManager(), m_mainWindow);
1457 Q_ASSERT(c != nullptr);
1458 for (int i=0; i<c->count(); ++i) {
1459 if (c->widget(i) == m_menuBar) {
1460 c->remove(i);
1461 break;
1462 }
1463 }
1464 }
1465
1467 m_menuBar->hide();
1470}
1471
1473{
1474 if (m_mainWindow) {
1476 auto *c = qt_extension<QDesignerContainerExtension*>(core()->extensionManager(), m_mainWindow);
1477
1479
1481 m_menuBar->show();
1483 }
1484}
1485
1486// ---- CreateStatusBarCommand ----
1491
1493{
1495 QDesignerFormEditorInterface *core = formWindow()->core();
1498}
1499
1501{
1502 QDesignerFormEditorInterface *core = formWindow()->core();
1503 auto *c = qt_extension<QDesignerContainerExtension*>(core->extensionManager(), m_mainWindow);
1505
1506 m_statusBar->setObjectName(u"statusBar"_s);
1510}
1511
1513{
1514 QDesignerFormEditorInterface *core = formWindow()->core();
1515 QDesignerContainerExtension *c = qt_extension<QDesignerContainerExtension*>(core->extensionManager(), m_mainWindow);
1516 for (int i = 0; i < c->count(); ++i) {
1517 if (c->widget(i) == m_statusBar) {
1518 c->remove(i);
1519 break;
1520 }
1521 }
1522
1525}
1526
1527// ---- DeleteStatusBarCommand ----
1532
1538
1540{
1541 if (m_mainWindow) {
1543 Q_ASSERT(c != nullptr);
1544 for (int i=0; i<c->count(); ++i) {
1545 if (c->widget(i) == m_statusBar) {
1546 c->remove(i);
1547 break;
1548 }
1549 }
1550 }
1551
1553 m_statusBar->hide();
1556}
1557
1571
1572// ---- AddToolBarCommand ----
1577
1579{
1581 QDesignerWidgetFactoryInterface * wf = formWindow()->core()->widgetFactory();
1582 // Pass on 0 parent first to avoid reparenting flicker.
1583 m_toolBar = qobject_cast<QToolBar*>(wf->createWidget(u"QToolBar"_s, nullptr));
1584 m_toolBar->setProperty("_q_desiredArea", QVariant(area));
1586 m_toolBar->hide();
1587}
1588
1590{
1591 QDesignerFormEditorInterface *core = formWindow()->core();
1593
1594 QDesignerContainerExtension *c = qt_extension<QDesignerContainerExtension*>(core->extensionManager(), m_mainWindow);
1596
1597 m_toolBar->setObjectName(u"toolBar"_s);
1601}
1602
1604{
1605 QDesignerFormEditorInterface *core = formWindow()->core();
1607 QDesignerContainerExtension *c = qt_extension<QDesignerContainerExtension*>(core->extensionManager(), m_mainWindow);
1608 for (int i = 0; i < c->count(); ++i) {
1609 if (c->widget(i) == m_toolBar) {
1610 c->remove(i);
1611 break;
1612 }
1613 }
1615}
1616
1617// ---- DockWidgetCommand:: ----
1622
1624
1629
1630// ---- AddDockWidgetCommand ----
1635
1641
1648
1660
1662{
1665 for (int i = 0; i < c->count(); ++i) {
1666 if (c->widget(i) == m_dockWidget) {
1667 c->remove(i);
1668 break;
1669 }
1670 }
1671
1674}
1675
1676// ---- AdjustWidgetSizeCommand ----
1681
1683{
1684 m_widget = widget;
1685 setText(QApplication::translate("Command", "Adjust Size of '%1'").arg(widget->objectName()));
1686}
1687
1689{
1691 // Return the outer, embedding widget if it is the main container
1694 return m_widget;
1695}
1696
1698{
1700 m_geometry = aw->geometry();
1702 aw->adjustSize();
1703 const bool isMainContainer = aw != m_widget;
1704 if (!isMainContainer) {
1705 /* When doing adjustsize on a selected non-laid out child that has been enlarged
1706 * and pushed partially over the top/left edge[s], it is possible that it "disappears"
1707 * when shrinking. In that case, move it back so that it remains visible. */
1708 if (aw->parentWidget()->layout() == nullptr) {
1710 const QRect newGeometry = aw->geometry();
1712 if (newGeometry.bottom() <= contentsRect.y())
1714 if (newGeometry.right() <= contentsRect.x())
1716 if (newPos != m_geometry.topLeft())
1717 aw->move(newPos);
1718 }
1719 }
1721}
1722
1731
1733{
1735 if (propertyEditor->object() == m_widget)
1736 propertyEditor->setPropertyValue(u"geometry"_s, m_widget->geometry(), true);
1737 }
1738}
1739// ------------ ChangeFormLayoutItemRoleCommand
1740
1746
1752
1757
1762
1764{
1765 switch (op) {
1766 case SpanningToLabel:
1767 return LabelToSpanning;
1768 case SpanningToField:
1769 return FieldToSpanning;
1770 case LabelToSpanning:
1771 return SpanningToLabel;
1772 case FieldToSpanning:
1773 return SpanningToField;
1774 }
1775 return SpanningToField;
1776}
1777
1779{
1781 const int index = fl->indexOf(m_widget);
1782 Q_ASSERT(index != -1);
1783 int row = 0;
1786 Q_ASSERT(index != -1);
1788 const QRect area = QRect(0, row, 2, 1);
1789 switch (op) {
1790 case SpanningToLabel:
1793 break;
1794 case SpanningToField:
1797 break;
1798 case LabelToSpanning:
1799 case FieldToSpanning:
1802 break;
1803 }
1804}
1805
1807{
1809 if (!fl)
1810 return 0;
1811 const int index = fl->indexOf(w);
1812 if (index == -1)
1813 return 0;
1814 int row = 0, col = 0, colspan = 0;
1816 // Spanning item?
1817 if (colspan > 1)
1819 // Is the neighbouring column free, that is, can the current item be expanded?
1822 if (empty)
1823 return col == 0 ? LabelToSpanning : FieldToSpanning;
1824 return 0;
1825}
1826
1828{
1829 if (auto *layout = LayoutInfo::managedLayout(core, w->parentWidget())) {
1830 if (auto *fl = qobject_cast<QFormLayout *>(layout))
1831 return fl;
1832 }
1833 return nullptr;
1834}
1835
1836// ---- ChangeLayoutItemGeometry ----
1841
1862
1864{
1866 Q_ASSERT(layout != nullptr);
1867
1869 Q_ASSERT(grid != nullptr);
1870
1871 const int itemIndex = grid->indexOf(m_widget);
1872 Q_ASSERT(itemIndex != -1);
1873
1875 delete item;
1876
1878 qWarning() << "ChangeLayoutItemGeometry::changeItemPosition: Nonempty cell at " << g << '.';
1879
1880 grid->addWidget(m_widget, g.top(), g.left(), g.height(), g.width());
1881
1882 grid->invalidate();
1883 grid->activate();
1884
1886
1887 formWindow()->clearSelection(false);
1889}
1890
1895
1900
1901// ---- ContainerWidgetCommand ----
1907
1909
1915
1925
1927{
1929 if (const int count = c->count()) {
1930 // Undo add after last?
1931 const int deleteIndex = m_index >= 0 ? m_index : count - 1;
1933 m_widget->hide();
1935 }
1936 }
1937}
1938
1940{
1942 int newCurrentIndex = 0;
1943 if (m_index >= 0) {
1946 } else {
1948 newCurrentIndex = c->count() -1 ;
1949 }
1950 m_widget->show();
1952 }
1953}
1954
1955// ---- DeleteContainerWidgetPageCommand ----
1960
1962
1964{
1966 switch (ct) {
1967 case WizardContainer:
1968 case PageContainer:
1969 setText(QApplication::translate("Command", "Delete Page"));
1970 break;
1971 case MdiContainer:
1972 setText(QApplication::translate("Command", "Delete Subwindow"));
1973 break;
1974 }
1975}
1976
1982
1984{
1985 addPage();
1986 cheapUpdate();
1987}
1988
1989// ---- AddContainerWidgetPageCommand ----
1994
1996
1998{
2000
2002 m_index = c->currentIndex();
2003 if (m_index >= 0 && mode == InsertAfter)
2004 m_index++;
2005 m_widget = nullptr;
2007 switch (ct) {
2008 case PageContainer:
2009 setText(QApplication::translate("Command", "Insert Page"));
2011 m_widget->setObjectName(u"page"_s);
2012 break;
2013 case MdiContainer:
2014 setText(QApplication::translate("Command", "Insert Subwindow"));
2016 m_widget->setObjectName(u"subwindow"_s);
2018 break;
2019 case WizardContainer: // Apply style, don't manage
2020 m_widget = core->widgetFactory()->createWidget(u"QWizardPage"_s, nullptr);
2021 break;
2022 }
2025 }
2026}
2027
2029{
2030 addPage();
2031 cheapUpdate();
2032}
2033
2035{
2036 removePage();
2037 cheapUpdate();
2038}
2039
2045
2047
2053
2064
2069
2074
2087
2088template<class T>
2089static void copyRoleFromItem(ItemData *id, int role, const T *item)
2090{
2091 QVariant v = item->data(role);
2092 if (v.isValid())
2094}
2095
2096template<class T>
2097static void copyRolesFromItem(ItemData *id, const T *item, bool editor)
2098{
2099 static const Qt::ItemFlags defaultFlags = T().flags();
2100
2101 for (int i : itemRoles)
2103
2104 if (editor)
2106 else if (item->flags() != defaultFlags)
2108}
2109
2110template<class T>
2111static void copyRolesToItem(const ItemData *id, T *item, DesignerIconCache *iconCache, bool editor)
2112{
2113 for (auto it = id->m_properties.cbegin(), end = id->m_properties.cend(); it != end; ++it) {
2114 if (it.value().isValid()) {
2115 if (!editor && it.key() == ItemFlagsShadowRole) {
2116 item->setFlags((Qt::ItemFlags)it.value().toInt());
2117 } else {
2118 item->setData(it.key(), it.value());
2119 switch (it.key()) {
2120 case Qt::DecorationPropertyRole:
2121 if (iconCache)
2122 item->setIcon(iconCache->icon(qvariant_cast<PropertySheetIconValue>(it.value())));
2123 break;
2124 case Qt::DisplayPropertyRole:
2125 item->setText(qvariant_cast<PropertySheetStringValue>(it.value()).value());
2126 break;
2127 case Qt::ToolTipPropertyRole:
2128 item->setToolTip(qvariant_cast<PropertySheetStringValue>(it.value()).value());
2129 break;
2130 case Qt::StatusTipPropertyRole:
2131 item->setStatusTip(qvariant_cast<PropertySheetStringValue>(it.value()).value());
2132 break;
2133 case Qt::WhatsThisPropertyRole:
2134 item->setWhatsThis(qvariant_cast<PropertySheetStringValue>(it.value()).value());
2135 break;
2136 }
2137 }
2138 }
2139 }
2140
2141 if (editor)
2142 item->setFlags(item->flags() | Qt::ItemIsEditable);
2143}
2144
2149
2151{
2152 auto *item = new QListWidgetItem();
2154 return item;
2155}
2156
2161
2168
2170{
2172 if (v.isValid())
2174}
2175
2185
2212
2214{
2215 for (int i = 0; i < item->columnCount(); i++)
2217}
2218
2220{
2221 auto *item = new QTreeWidgetItem;
2222 int i = 0;
2223 for (const ItemData &id : m_items)
2225 return item;
2226}
2227
2229{
2230 m_items.clear();
2231
2232 for (int i = 0; i < listWidget->count(); i++)
2234}
2235
2252
2254{
2255 m_items.clear();
2256
2257 const int count = comboBox->count();
2258 for (int i = 0; i < count; i++) {
2259 // We might encounter items added in a custom combo
2260 // constructor. Ignore those.
2262 if (!textValue.isNull()) {
2266 if (!iconValue.isNull())
2269 }
2270 }
2271}
2272
2293
2294// --------- TableWidgetContents
2295
2297
2306
2308{
2309 return QString::number(i + 1);
2310}
2311
2313{
2314 static const Qt::ItemFlags defaultFlags = QTableWidgetItem().flags();
2315
2316 if (item->flags() != defaultFlags)
2317 return true;
2318
2320 if (!text.isEmpty()) {
2322 return true;
2323 } else {
2324 // FIXME: This doesn't seem to make sense
2325 return true;
2326 }
2327
2328 auto pred = [item](int i) {
2329 return i != Qt::DisplayPropertyRole && item->data(i).isValid();
2330 };
2331 return std::any_of(std::begin(itemRoles), std::end(itemRoles), pred);
2332}
2333
2341
2343{
2344 clear();
2347 // horiz header: Legacy behaviour: auto-generate number for empty items
2348 for (int col = 0; col < m_columnCount; col++)
2351 // vertical header: Legacy behaviour: auto-generate number for empty items
2352 for (int row = 0; row < m_rowCount; row++)
2355 // cell data
2356 for (int col = 0; col < m_columnCount; col++)
2357 for (int row = 0; row < m_rowCount; row++)
2358 if (const QTableWidgetItem *item = tableWidget->item(row, col))
2359 if (nonEmpty(item, -1))
2361}
2362
2364{
2365 tableWidget->clear();
2366
2369
2370 // horiz header
2371 int col = 0;
2372 for (const ItemData &id : m_horizontalHeader.m_items) {
2373 if (id.isValid())
2375 col++;
2376 }
2377 // vertical header
2378 int row = 0;
2379 for (const ItemData &id : m_verticalHeader.m_items) {
2380 if (id.isValid())
2382 row++;
2383 }
2384 // items
2385 for (auto it = m_items.cbegin(), icend = m_items.cend(); it != icend; ++ it) {
2388 }
2389}
2390
2391bool comparesEqual(const TableWidgetContents &lhs,
2392 const TableWidgetContents &rhs) noexcept
2393{
2394 return lhs.m_columnCount == rhs.m_columnCount && lhs.m_rowCount == rhs.m_rowCount &&
2395 lhs.m_horizontalHeader.m_items == rhs.m_horizontalHeader.m_items &&
2396 lhs.m_verticalHeader.m_items == rhs.m_verticalHeader.m_items &&
2397 lhs.m_items == rhs.m_items;
2398}
2399
2400// ---- ChangeTableContentsCommand ----
2408
2416
2422
2428
2429// --------- TreeWidgetContents
2432{
2433 static const Qt::ItemFlags defaultFlags = QTreeWidgetItem().flags();
2434
2435 if (editor) {
2437 m_itemFlags = v.isValid() ? v.toInt() : -1;
2438 } else {
2439 m_itemFlags = (item->flags() != defaultFlags) ? int(item->flags()) : -1;
2440 }
2441
2442 for (int i = 0; i < item->childCount(); i++)
2444}
2445
2465
2466bool comparesEqual(const TreeWidgetContents::ItemContents &lhs,
2467 const TreeWidgetContents::ItemContents &rhs) noexcept
2468{
2469 return lhs.m_itemFlags == rhs.m_itemFlags && lhs.m_items == rhs.m_items
2470 && lhs.m_children == rhs.m_children;
2471}
2472
2478
2486
2497
2498// ---- ChangeTreeContentsCommand ----
2506
2514
2519
2524
2525// ---- ChangeListContentsCommand ----
2532
2542
2552
2560
2568
2569// ---- AddActionCommand ----
2570
2575
2577{
2578 Q_ASSERT(m_action == nullptr);
2579 m_action = action;
2580}
2581
2587
2593
2594// ---- RemoveActionCommand ----
2595
2600
2602{
2604 // We only want menus and toolbars, no toolbuttons.
2606 for (QObject *obj : associatedObjects) {
2607 if (!qobject_cast<const QMenu *>(obj) && !qobject_cast<const QToolBar *>(obj))
2608 continue;
2609 auto *widget = static_cast<QWidget *>(obj);
2610 const auto actionList = widget->actions();
2611 for (qsizetype i = 0, size = actionList.size(); i < size; ++i) {
2612 if (actionList.at(i) == action) {
2613 QAction *before = nullptr;
2614 if (i + 1 < size)
2615 before = actionList.at(i + 1);
2617 break;
2618 }
2619 }
2620 }
2621 return result;
2622}
2623
2625{
2626 Q_ASSERT(m_action == nullptr);
2627 m_action = action;
2628
2630}
2631
2633{
2635 for (const ActionDataItem &item : std::as_const(m_actionData)) {
2637 }
2638 // Notify components (for example, signal slot editor)
2641
2644 if (!m_actionData.isEmpty())
2646}
2647
2657
2658// ---- ActionInsertionCommand ----
2659
2668
2679
2681{
2682 Q_ASSERT(m_action != nullptr);
2683 Q_ASSERT(m_parentWidget != nullptr);
2684
2685 if (m_beforeAction)
2687 else
2689
2690 if (m_update) {
2691 cheapUpdate();
2692 if (QMenu *menu = m_action->menu())
2694 else
2696 PropertyHelper::triggerActionChanged(m_action); // Update Used column in action editor.
2697 }
2698}
2700{
2701 Q_ASSERT(m_action != nullptr);
2702 Q_ASSERT(m_parentWidget != nullptr);
2703
2705 menu->hideSubMenu();
2706
2708
2709 if (m_update) {
2710 cheapUpdate();
2712 PropertyHelper::triggerActionChanged(m_action); // Update Used column in action editor.
2713 }
2714}
2715
2720// ---- RemoveActionFromCommand ----
2721
2726
2727// ---- AddMenuActionCommand ----
2728
2738
2750
2762
2764{
2765 m_action->menu()->setParent(nullptr);
2766 QMenu *menu = m_action->menu();
2768 menu->setParent(nullptr);
2771 cheapUpdate();
2773}
2774
2779
2780// ---- RemoveMenuActionCommand ----
2785
2786// ---- CreateSubmenuCommand ----
2794
2801
2809
2816
2817// ---- DeleteToolBarCommand ----
2822
2828
2830{
2831 if (m_mainWindow) {
2832 QDesignerContainerExtension *c = qt_extension<QDesignerContainerExtension*>(core()->extensionManager(), m_mainWindow);
2833 Q_ASSERT(c != nullptr);
2834 for (int i=0; i<c->count(); ++i) {
2835 if (c->widget(i) == m_toolBar) {
2836 c->remove(i);
2837 break;
2838 }
2839 }
2840 }
2841
2843 m_toolBar->hide();
2846}
2847
2849{
2850 if (m_mainWindow) {
2852 QDesignerContainerExtension *c = qt_extension<QDesignerContainerExtension*>(core()->extensionManager(), m_mainWindow);
2853
2855
2857 m_toolBar->show();
2859 }
2860}
2861
2862} // namespace qdesigner_internal
2863
2864QT_END_NAMESPACE
friend class QWidget
Definition qpainter.h:432
Auxiliary methods to store/retrieve settings.
static const int itemRoles[]
static void copyRoleFromItem(ItemData *id, int role, const T *item)
static void copyRolesToItem(const ItemData *id, T *item, DesignerIconCache *iconCache, bool editor)
static void copyRolesFromItem(ItemData *id, const T *item, bool editor)
static int removeFromWidgetListDynamicProperty(QWidget *parentWidget, QWidget *widget, const char *name)
static RemoveActionCommand::ActionData findActionIn(QAction *action)
static void copyRoleFromItem(ItemData *id, int role, const QTreeWidgetItem *item, int column)
static void addToWidgetListDynamicProperty(QWidget *parentWidget, QWidget *widget, const char *name, int index=-1)
static void recursiveUpdate(QWidget *w)
static const char widgetOrderPropertyC[]
static const char zOrderPropertyC[]
bool comparesEqual(const DeviceProfile &lhs, const DeviceProfile &rhs) noexcept
static void setPropertySheetWindowTitle(const QDesignerFormEditorInterface *core, QObject *o, const QString &t)