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
7#include "layout_p.h"
11#include "shared_enums_p.h"
12#include "metadatabase_p.h"
14#include <abstractformbuilder.h>
15
16#include <QtDesigner/abstractformwindow.h>
17#include <QtDesigner/abstractformeditor.h>
18#include <QtDesigner/propertysheet.h>
19#include <QtDesigner/abstractactioneditor.h>
20#include <QtDesigner/abstractpropertyeditor.h>
21#include <QtDesigner/qextensionmanager.h>
22#include <QtDesigner/container.h>
23#include <QtDesigner/layoutdecoration.h>
24#include <QtDesigner/abstractwidgetfactory.h>
25#include <QtDesigner/abstractobjectinspector.h>
26#include <QtDesigner/abstractintegration.h>
27#include <QtDesigner/abstractformwindowcursor.h>
28#include <QtCore/qdebug.h>
29#include <QtCore/qtextstream.h>
30#include <QtCore/qqueue.h>
31
32#include <QtWidgets/qmenubar.h>
33#include <QtWidgets/qstatusbar.h>
34#include <QtWidgets/qtoolbar.h>
35#include <QtWidgets/qtoolbox.h>
36#include <QtWidgets/qstackedwidget.h>
37#include <QtWidgets/qtabwidget.h>
38#include <QtWidgets/qtablewidget.h>
39#include <QtWidgets/qtreewidget.h>
40#include <QtWidgets/qlistwidget.h>
41#include <QtWidgets/qcombobox.h>
42#include <QtWidgets/qsplitter.h>
43#include <QtWidgets/qdockwidget.h>
44#include <QtWidgets/qmainwindow.h>
45#include <QtWidgets/qwizard.h>
46#include <QtWidgets/qapplication.h>
47#include <QtWidgets/qformlayout.h>
48
49#include <algorithm>
50
51Q_DECLARE_METATYPE(QWidgetList)
52
53QT_BEGIN_NAMESPACE
54
55using namespace Qt::StringLiterals;
56
57static inline void setPropertySheetWindowTitle(const QDesignerFormEditorInterface *core, QObject *o, const QString &t)
58{
59 if (QDesignerPropertySheetExtension *sheet = qt_extension<QDesignerPropertySheetExtension*>(core->extensionManager(), o)) {
60 const int idx = sheet->indexOf(u"windowTitle"_s);
61 if (idx != -1) {
62 sheet->setProperty(idx, t);
63 sheet->setChanged(idx, true);
64 }
65 }
66}
67
68namespace qdesigner_internal {
69
70// Helpers for the dynamic properties that store Z/Widget order
71static const char widgetOrderPropertyC[] = "_q_widgetOrder";
72static const char zOrderPropertyC[] = "_q_zOrder";
73
74static void addToWidgetListDynamicProperty(QWidget *parentWidget, QWidget *widget, const char *name, int index = -1)
75{
76 auto list = qvariant_cast<QWidgetList>(parentWidget->property(name));
77 list.removeAll(widget);
78 if (index >= 0 && index < list.size()) {
79 list.insert(index, widget);
80 } else {
81 list.append(widget);
82 }
83 parentWidget->setProperty(name, QVariant::fromValue(list));
84}
85
86static int removeFromWidgetListDynamicProperty(QWidget *parentWidget, QWidget *widget, const char *name)
87{
88 auto list = qvariant_cast<QWidgetList>(parentWidget->property(name));
89 const auto firstIndex = list.indexOf(widget);
90 if (firstIndex != -1) {
91 list.removeAll(widget);
92 parentWidget->setProperty(name, QVariant::fromValue(list));
93 }
94 return firstIndex;
95}
96
97// ---- InsertWidgetCommand ----
105
110
130
132{
133 w->update();
134
135 for (auto *child : w->children()) {
136 if (QWidget *w = qobject_cast<QWidget*>(child))
137 recursiveUpdate(w);
138 }
139}
140
184
209
211{
212 const auto label_list = formWindow()->findChildren<QLabel*>();
213 if (label_list.isEmpty())
214 return;
215
216 const QString buddyProperty = u"buddy"_s;
218 // Re-set the buddy (The sheet locates the object by name and sets it)
219 for (QLabel *label : label_list) {
221 const int idx = sheet->indexOf(buddyProperty);
222 if (idx != -1) {
223 const QVariant value = sheet->property(idx);
226 }
227 }
228 }
229}
230
231// ---- ChangeZOrderCommand ----
236
238{
240
242
243 setText(QApplication::translate("Command", "Change Z-order of '%1'").arg(widget->objectName()));
244
247 if (index != -1 && index + 1 < m_oldParentZOrder.size())
249}
250
257
267
268// ---- RaiseWidgetCommand ----
273
279
287
289{
290 widget->raise();
291}
292
293// ---- LowerWidgetCommand ----
298
306
312
314{
315 widget->lower();
316}
317
318// ---- ManageWidgetCommandHelper
320
333
339
341{
342 // Manage the managed children after parent
344 for (auto *w : std::as_const(m_managedChildren))
345 fw->manageWidget(w);
346}
347
349{
350 // Unmanage the managed children first
351 for (auto *w : std::as_const(m_managedChildren))
354}
355
356// ---- DeleteWidgetCommand ----
370
375
377{
381 m_flags = flags;
383 m_splitterIndex = -1;
384 bool isManaged = false; // Check for a managed layout
385 QLayout *layout = nullptr;
387 if (!isManaged)
389 switch (m_layoutType) {
390 case LayoutInfo::HSplitter:
391 case LayoutInfo::VSplitter: {
395 }
396 break;
397 case LayoutInfo::NoLayout:
398 break;
399 default:
402 break;
403 }
404
407
408 // Build the list of managed children
410
411 setText(QApplication::translate("Command", "Delete '%1'").arg(widget->objectName()));
412}
413
415{
418
420 const int count = c->count();
421 for (int i=0; i<count; ++i) {
422 if (c->widget(i) == m_widget) {
423 c->remove(i);
424 return;
425 }
426 }
427 }
428
431
434
435 if (m_layoutHelper)
436 switch (m_layoutType) {
437 case LayoutInfo::NoLayout:
438 case LayoutInfo::HSplitter:
439 case LayoutInfo::VSplitter:
440 break;
441 default:
442 // Attempt to simplify grids if a row/column becomes empty
444 if (m_layoutSimplified) {
447 }
448 break;
449 }
450
451 if (!(m_flags & DoNotUnmanage))
453
455 m_widget->hide();
456
457 if (m_tabOrderIndex != -1) {
461 }
462}
463
465{
468
470
473 return;
474 }
475
478
480
481 if (!(m_flags & DoNotUnmanage))
483 // ### set up alignment
484 switch (m_layoutType) {
485 case LayoutInfo::NoLayout:
486 break;
487 case LayoutInfo::HSplitter:
488 case LayoutInfo::VSplitter: {
492 } break;
493 default: {
500 }
501 break;
502 }
503
504 m_widget->show();
505
506 if (m_tabOrderIndex != -1) {
510 }
511}
512
513// ---- ReparentWidgetCommand ----
518
535
560
581
587
593
595{
596 for (QWidget *w : std::as_const(m_widgets)) {
597 if (w)
599 }
601}
602
604{
605 // Update class names in ObjectInspector, PropertyEditor
609 if (QObject *o = core->propertyEditor()->object())
611}
612
614{
615 for (QWidget *w : std::as_const(m_widgets)) {
616 if (w)
617 demoteWidget(core(), w);
618 }
620}
621
622// ---- DemoteFromCustomWidgetCommand ----
623
630
635
640
645
646// ---------- CursorSelectionState
648
660
662{
663 if (m_selection.isEmpty()) {
665 } else {
666 // Select current as last
668 for (const auto &wp : m_selection) {
669 if (!wp.isNull() && wp.data() != m_current)
670 formWindow->selectWidget(wp.data(), true);
671 }
672 if (m_current)
674 }
675}
676
677// ---- LayoutCommand ----
678
684
686{
687 delete m_layout;
688}
689
693{
699
700 switch (layoutType) {
701 case LayoutInfo::Grid:
702 setText(QApplication::translate("Command", "Lay out using grid"));
703 break;
704 case LayoutInfo::VBox:
705 setText(QApplication::translate("Command", "Lay out vertically"));
706 break;
707 case LayoutInfo::HBox:
708 setText(QApplication::translate("Command", "Lay out horizontally"));
709 break;
710 default:
711 break;
712 }
713 // Delayed setup to avoid confusion in case we are chained
714 // with a BreakLayout in a morph layout macro
715 m_setup = false;
716}
717
719{
720 if (!m_setup) {
721 m_layout->setup();
723 m_setup = true;
724 }
727}
728
730{
732
736 delete deco; // release the extension
737
738 // ### generalize (put in function)
739 if (!m_layoutBase && lb != nullptr && !(qobject_cast<QLayoutWidget*>(lb) || qobject_cast<QSplitter*>(lb))) {
740 core->metaDataBase()->add(lb);
741 lb->show();
742 }
745}
746
747// ---- BreakLayoutCommand ----
755
757{
758 delete m_layoutHelper;
759 delete m_layout;
760 delete m_properties;
761}
762
767
769{
770 return m_propertyMask;
771}
772
774{
776
780 QLayout *layoutToBeBroken = nullptr;
784
786 switch (layoutType) {
787 case LayoutInfo::NoLayout:
788 case LayoutInfo::HSplitter:
789 case LayoutInfo::VSplitter:
791 break;
792 case LayoutInfo::HBox:
793 case LayoutInfo::VBox: // Margin/spacing need to be saved
795 break;
796 default: // Margin/spacing need to be saved + has a state (empty rows/columns of a grid)
798 break;
799 }
800 Q_ASSERT(m_layout != nullptr);
801 m_layout->sort();
802
803
807 }
808 if (type >= LayoutHasState)
811}
812
814{
815 if (!m_layout)
816 return;
817
821 formWindow()->clearSelection(false);
822 if (m_layoutHelper)
825 delete deco; // release the extension
826
827 for (QWidget *widget : std::as_const(m_widgets)) {
828 widget->resize(widget->size().expandedTo(QSize(16, 16)));
829 }
830 // Update unless we are in an intermediate state of morphing layout
831 // in which a QLayoutWidget will have no layout at all.
834}
835
852// ---- SimplifyLayoutCommand
854 QDesignerFormWindowCommand(QApplication::translate("Command", "Simplify Grid Layout"), formWindow),
855 m_area(0, 0, 32767, 32767),
856 m_layoutBase(nullptr),
857 m_layoutHelper(nullptr),
858 m_layoutSimplified(false)
859{
860}
861
866
868{
869 if (!w)
870 return false;
871 QLayout *layout = nullptr;
873 if (layoutType)
874 *layoutType = type;
875 if (!layout)
876 return false;
877 switch (type) { // Known negatives
878 case LayoutInfo::NoLayout:
880 case LayoutInfo::HSplitter:
881 case LayoutInfo::VSplitter:
882 case LayoutInfo::HBox:
883 case LayoutInfo::VBox:
884 return false;
885 default:
886 break;
887 }
888 switch (type) {
889 case LayoutInfo::Grid:
891 case LayoutInfo::Form:
893 default:
894 break;
895 }
896 return false;
897}
898
911
925
926// ---- ToolBoxCommand ----
932
933ToolBoxCommand::~ToolBoxCommand() = default;
934
943
954
956{
960
961 QDesignerPropertySheetExtension *sheet = qt_extension<QDesignerPropertySheetExtension*>(formWindow()->core()->extensionManager(), m_toolBox);
962 if (sheet) {
964 sheet->setProperty(sheet->indexOf(u"currentItemText"_s), QVariant::fromValue(itemText));
965 }
966
967 m_widget->show();
970}
971
972// ---- MoveToolBoxPageCommand ----
979
981
993
999
1005
1006// ---- DeleteToolBoxPageCommand ----
1011
1013
1015{
1017 setText(QApplication::translate("Command", "Delete Page"));
1018}
1019
1021{
1022 removePage();
1023 cheapUpdate();
1024}
1025
1027{
1028 addPage();
1029 cheapUpdate();
1030}
1031
1032// ---- AddToolBoxPageCommand ----
1037
1039
1044
1046{
1048
1050 if (mode == InsertAfter)
1051 m_index++;
1053 m_itemText = QApplication::translate("Command", "Page");
1054 m_itemIcon = QIcon();
1055 m_widget->setObjectName(u"page"_s);
1057
1058 setText(QApplication::translate("Command", "Insert Page"));
1059
1060 QDesignerFormEditorInterface *core = formWindow()->core();
1062}
1063
1065{
1066 addPage();
1067 cheapUpdate();
1068}
1069
1071{
1072 removePage();
1073 cheapUpdate();
1074}
1075
1076// ---- TabWidgetCommand ----
1082
1084
1093
1105
1107{
1108 m_widget->setParent(nullptr);
1110 m_widget->show();
1112
1113 QDesignerPropertySheetExtension *sheet = qt_extension<QDesignerPropertySheetExtension*>(formWindow()->core()->extensionManager(), m_tabWidget);
1114 if (sheet) {
1116 sheet->setProperty(sheet->indexOf(u"currentTabText"_s),
1118 }
1119
1122}
1123
1124// ---- DeleteTabPageCommand ----
1129
1131
1133{
1135 setText(QApplication::translate("Command", "Delete Page"));
1136}
1137
1139{
1140 removePage();
1141 cheapUpdate();
1142}
1143
1145{
1146 addPage();
1147 cheapUpdate();
1148}
1149
1150// ---- AddTabPageCommand ----
1155
1157
1162
1164{
1166
1168 if (mode == InsertAfter)
1169 m_index++;
1171 m_itemText = QApplication::translate("Command", "Page");
1172 m_itemIcon = QIcon();
1173 m_widget->setObjectName(u"tab"_s);
1175
1176 setText(QApplication::translate("Command", "Insert Page"));
1177
1178 QDesignerFormEditorInterface *core = formWindow()->core();
1180}
1181
1183{
1184 addPage();
1185 cheapUpdate();
1186}
1187
1189{
1190 removePage();
1191 cheapUpdate();
1192}
1193
1194// ---- MoveTabPageCommand ----
1201
1203
1205 const QIcon &icon, const QString &label,
1206 int index, int newIndex)
1207{
1209 setText(QApplication::translate("Command", "Move Page"));
1210
1211 m_page = page;
1213 m_oldIndex = index;
1214 m_label = label;
1215 m_icon = icon;
1216}
1217
1224
1231
1232// ---- StackedWidgetCommand ----
1238
1240
1247
1258
1269
1270// ---- MoveStackedWidgetCommand ----
1277
1279
1289
1295
1301
1302// ---- DeleteStackedWidgetPageCommand ----
1307
1309
1315
1317{
1318 removePage();
1319 cheapUpdate();
1320}
1321
1323{
1324 addPage();
1325 cheapUpdate();
1326}
1327
1328// ---- AddStackedWidgetPageCommand ----
1333
1335
1340
1342{
1344
1346 if (mode == InsertAfter)
1347 m_index++;
1349 m_widget->setObjectName(u"page"_s);
1351
1352 setText(QApplication::translate("Command", "Insert Page"));
1353
1354 QDesignerFormEditorInterface *core = formWindow()->core();
1356}
1357
1359{
1360 addPage();
1361 cheapUpdate();
1362}
1363
1365{
1366 removePage();
1367 cheapUpdate();
1368}
1369
1370// ---- TabOrderCommand ----
1376
1387
1392
1397
1398// ---- CreateMenuBarCommand ----
1403
1405{
1407 QDesignerFormEditorInterface *core = formWindow()->core();
1410}
1411
1413{
1414 QDesignerFormEditorInterface *core = formWindow()->core();
1415 auto *c = qt_extension<QDesignerContainerExtension*>(core->extensionManager(), m_mainWindow);
1417
1418 m_menuBar->setObjectName(u"menuBar"_s);
1423}
1424
1426{
1427 QDesignerFormEditorInterface *core = formWindow()->core();
1428 auto *c = qt_extension<QDesignerContainerExtension*>(core->extensionManager(), m_mainWindow);
1429 for (int i = 0; i < c->count(); ++i) {
1430 if (c->widget(i) == m_menuBar) {
1431 c->remove(i);
1432 break;
1433 }
1434 }
1435
1438}
1439
1440// ---- DeleteMenuBarCommand ----
1445
1451
1453{
1454 if (m_mainWindow) {
1455 auto *c = qt_extension<QDesignerContainerExtension*>(core()->extensionManager(), m_mainWindow);
1456 Q_ASSERT(c != nullptr);
1457 for (int i=0; i<c->count(); ++i) {
1458 if (c->widget(i) == m_menuBar) {
1459 c->remove(i);
1460 break;
1461 }
1462 }
1463 }
1464
1466 m_menuBar->hide();
1469}
1470
1472{
1473 if (m_mainWindow) {
1475 auto *c = qt_extension<QDesignerContainerExtension*>(core()->extensionManager(), m_mainWindow);
1476
1478
1480 m_menuBar->show();
1482 }
1483}
1484
1485// ---- CreateStatusBarCommand ----
1490
1492{
1494 QDesignerFormEditorInterface *core = formWindow()->core();
1497}
1498
1500{
1501 QDesignerFormEditorInterface *core = formWindow()->core();
1502 auto *c = qt_extension<QDesignerContainerExtension*>(core->extensionManager(), m_mainWindow);
1504
1505 m_statusBar->setObjectName(u"statusBar"_s);
1509}
1510
1512{
1513 QDesignerFormEditorInterface *core = formWindow()->core();
1514 QDesignerContainerExtension *c = qt_extension<QDesignerContainerExtension*>(core->extensionManager(), m_mainWindow);
1515 for (int i = 0; i < c->count(); ++i) {
1516 if (c->widget(i) == m_statusBar) {
1517 c->remove(i);
1518 break;
1519 }
1520 }
1521
1524}
1525
1526// ---- DeleteStatusBarCommand ----
1531
1537
1539{
1540 if (m_mainWindow) {
1542 Q_ASSERT(c != nullptr);
1543 for (int i=0; i<c->count(); ++i) {
1544 if (c->widget(i) == m_statusBar) {
1545 c->remove(i);
1546 break;
1547 }
1548 }
1549 }
1550
1552 m_statusBar->hide();
1555}
1556
1570
1571// ---- AddToolBarCommand ----
1576
1578{
1580 QDesignerWidgetFactoryInterface * wf = formWindow()->core()->widgetFactory();
1581 // Pass on 0 parent first to avoid reparenting flicker.
1582 m_toolBar = qobject_cast<QToolBar*>(wf->createWidget(u"QToolBar"_s, nullptr));
1583 m_toolBar->setProperty("_q_desiredArea", QVariant(area));
1585 m_toolBar->hide();
1586}
1587
1589{
1590 QDesignerFormEditorInterface *core = formWindow()->core();
1592
1593 QDesignerContainerExtension *c = qt_extension<QDesignerContainerExtension*>(core->extensionManager(), m_mainWindow);
1595
1596 m_toolBar->setObjectName(u"toolBar"_s);
1600}
1601
1603{
1604 QDesignerFormEditorInterface *core = formWindow()->core();
1606 QDesignerContainerExtension *c = qt_extension<QDesignerContainerExtension*>(core->extensionManager(), m_mainWindow);
1607 for (int i = 0; i < c->count(); ++i) {
1608 if (c->widget(i) == m_toolBar) {
1609 c->remove(i);
1610 break;
1611 }
1612 }
1614}
1615
1616// ---- DockWidgetCommand:: ----
1621
1623
1628
1629// ---- AddDockWidgetCommand ----
1634
1640
1647
1659
1661{
1664 for (int i = 0; i < c->count(); ++i) {
1665 if (c->widget(i) == m_dockWidget) {
1666 c->remove(i);
1667 break;
1668 }
1669 }
1670
1673}
1674
1675// ---- AdjustWidgetSizeCommand ----
1680
1682{
1683 m_widget = widget;
1684 setText(QApplication::translate("Command", "Adjust Size of '%1'").arg(widget->objectName()));
1685}
1686
1688{
1690 // Return the outer, embedding widget if it is the main container
1693 return m_widget;
1694}
1695
1697{
1699 m_geometry = aw->geometry();
1701 aw->adjustSize();
1702 const bool isMainContainer = aw != m_widget;
1703 if (!isMainContainer) {
1704 /* When doing adjustsize on a selected non-laid out child that has been enlarged
1705 * and pushed partially over the top/left edge[s], it is possible that it "disappears"
1706 * when shrinking. In that case, move it back so that it remains visible. */
1707 if (aw->parentWidget()->layout() == nullptr) {
1709 const QRect newGeometry = aw->geometry();
1711 if (newGeometry.bottom() <= contentsRect.y())
1713 if (newGeometry.right() <= contentsRect.x())
1715 if (newPos != m_geometry.topLeft())
1716 aw->move(newPos);
1717 }
1718 }
1720}
1721
1730
1732{
1734 if (propertyEditor->object() == m_widget)
1735 propertyEditor->setPropertyValue(u"geometry"_s, m_widget->geometry(), true);
1736 }
1737}
1738// ------------ ChangeFormLayoutItemRoleCommand
1739
1745
1751
1756
1761
1763{
1764 switch (op) {
1765 case SpanningToLabel:
1766 return LabelToSpanning;
1767 case SpanningToField:
1768 return FieldToSpanning;
1769 case LabelToSpanning:
1770 return SpanningToLabel;
1771 case FieldToSpanning:
1772 return SpanningToField;
1773 }
1774 return SpanningToField;
1775}
1776
1778{
1780 const int index = fl->indexOf(m_widget);
1781 Q_ASSERT(index != -1);
1782 int row = 0;
1785 Q_ASSERT(index != -1);
1787 const QRect area = QRect(0, row, 2, 1);
1788 switch (op) {
1789 case SpanningToLabel:
1792 break;
1793 case SpanningToField:
1796 break;
1797 case LabelToSpanning:
1798 case FieldToSpanning:
1801 break;
1802 }
1803}
1804
1806{
1808 if (!fl)
1809 return 0;
1810 const int index = fl->indexOf(w);
1811 if (index == -1)
1812 return 0;
1813 int row = 0, col = 0, colspan = 0;
1815 // Spanning item?
1816 if (colspan > 1)
1818 // Is the neighbouring column free, that is, can the current item be expanded?
1821 if (empty)
1822 return col == 0 ? LabelToSpanning : FieldToSpanning;
1823 return 0;
1824}
1825
1827{
1828 if (auto *layout = LayoutInfo::managedLayout(core, w->parentWidget())) {
1829 if (auto *fl = qobject_cast<QFormLayout *>(layout))
1830 return fl;
1831 }
1832 return nullptr;
1833}
1834
1835// ---- ChangeLayoutItemGeometry ----
1840
1861
1863{
1865 Q_ASSERT(layout != nullptr);
1866
1868 Q_ASSERT(grid != nullptr);
1869
1870 const int itemIndex = grid->indexOf(m_widget);
1871 Q_ASSERT(itemIndex != -1);
1872
1874 delete item;
1875
1877 qWarning() << "ChangeLayoutItemGeometry::changeItemPosition: Nonempty cell at " << g << '.';
1878
1879 grid->addWidget(m_widget, g.top(), g.left(), g.height(), g.width());
1880
1881 grid->invalidate();
1882 grid->activate();
1883
1885
1886 formWindow()->clearSelection(false);
1888}
1889
1894
1899
1900// ---- ContainerWidgetCommand ----
1906
1908
1914
1924
1926{
1928 if (const int count = c->count()) {
1929 // Undo add after last?
1930 const int deleteIndex = m_index >= 0 ? m_index : count - 1;
1932 m_widget->hide();
1934 }
1935 }
1936}
1937
1939{
1941 int newCurrentIndex = 0;
1942 if (m_index >= 0) {
1945 } else {
1947 newCurrentIndex = c->count() -1 ;
1948 }
1949 m_widget->show();
1951 }
1952}
1953
1954// ---- DeleteContainerWidgetPageCommand ----
1959
1961
1963{
1965 switch (ct) {
1966 case WizardContainer:
1967 case PageContainer:
1968 setText(QApplication::translate("Command", "Delete Page"));
1969 break;
1970 case MdiContainer:
1971 setText(QApplication::translate("Command", "Delete Subwindow"));
1972 break;
1973 }
1974}
1975
1981
1983{
1984 addPage();
1985 cheapUpdate();
1986}
1987
1988// ---- AddContainerWidgetPageCommand ----
1993
1995
1997{
1999
2001 m_index = c->currentIndex();
2002 if (m_index >= 0 && mode == InsertAfter)
2003 m_index++;
2004 m_widget = nullptr;
2006 switch (ct) {
2007 case PageContainer:
2008 setText(QApplication::translate("Command", "Insert Page"));
2010 m_widget->setObjectName(u"page"_s);
2011 break;
2012 case MdiContainer:
2013 setText(QApplication::translate("Command", "Insert Subwindow"));
2015 m_widget->setObjectName(u"subwindow"_s);
2017 break;
2018 case WizardContainer: // Apply style, don't manage
2019 m_widget = core->widgetFactory()->createWidget(u"QWizardPage"_s, nullptr);
2020 break;
2021 }
2024 }
2025}
2026
2028{
2029 addPage();
2030 cheapUpdate();
2031}
2032
2034{
2035 removePage();
2036 cheapUpdate();
2037}
2038
2044
2046
2052
2063
2068
2073
2086
2087template<class T>
2088static void copyRoleFromItem(ItemData *id, int role, const T *item)
2089{
2090 QVariant v = item->data(role);
2091 if (v.isValid())
2093}
2094
2095template<class T>
2096static void copyRolesFromItem(ItemData *id, const T *item, bool editor)
2097{
2098 static const Qt::ItemFlags defaultFlags = T().flags();
2099
2100 for (int i : itemRoles)
2102
2103 if (editor)
2105 else if (item->flags() != defaultFlags)
2107}
2108
2109template<class T>
2110static void copyRolesToItem(const ItemData *id, T *item, DesignerIconCache *iconCache, bool editor)
2111{
2112 for (auto it = id->m_properties.cbegin(), end = id->m_properties.cend(); it != end; ++it) {
2113 if (it.value().isValid()) {
2114 if (!editor && it.key() == ItemFlagsShadowRole) {
2115 item->setFlags((Qt::ItemFlags)it.value().toInt());
2116 } else {
2117 item->setData(it.key(), it.value());
2118 switch (it.key()) {
2119 case Qt::DecorationPropertyRole:
2120 if (iconCache)
2121 item->setIcon(iconCache->icon(qvariant_cast<PropertySheetIconValue>(it.value())));
2122 break;
2123 case Qt::DisplayPropertyRole:
2124 item->setText(qvariant_cast<PropertySheetStringValue>(it.value()).value());
2125 break;
2126 case Qt::ToolTipPropertyRole:
2127 item->setToolTip(qvariant_cast<PropertySheetStringValue>(it.value()).value());
2128 break;
2129 case Qt::StatusTipPropertyRole:
2130 item->setStatusTip(qvariant_cast<PropertySheetStringValue>(it.value()).value());
2131 break;
2132 case Qt::WhatsThisPropertyRole:
2133 item->setWhatsThis(qvariant_cast<PropertySheetStringValue>(it.value()).value());
2134 break;
2135 }
2136 }
2137 }
2138 }
2139
2140 if (editor)
2141 item->setFlags(item->flags() | Qt::ItemIsEditable);
2142}
2143
2148
2150{
2151 auto *item = new QListWidgetItem();
2153 return item;
2154}
2155
2160
2167
2169{
2171 if (v.isValid())
2173}
2174
2184
2211
2213{
2214 for (int i = 0; i < item->columnCount(); i++)
2216}
2217
2219{
2220 auto *item = new QTreeWidgetItem;
2221 int i = 0;
2222 for (const ItemData &id : m_items)
2224 return item;
2225}
2226
2228{
2229 m_items.clear();
2230
2231 for (int i = 0; i < listWidget->count(); i++)
2233}
2234
2251
2253{
2254 m_items.clear();
2255
2256 const int count = comboBox->count();
2257 for (int i = 0; i < count; i++) {
2258 // We might encounter items added in a custom combo
2259 // constructor. Ignore those.
2261 if (!textValue.isNull()) {
2265 if (!iconValue.isNull())
2268 }
2269 }
2270}
2271
2292
2293// --------- TableWidgetContents
2294
2296
2305
2307{
2308 return QString::number(i + 1);
2309}
2310
2312{
2313 static const Qt::ItemFlags defaultFlags = QTableWidgetItem().flags();
2314
2315 if (item->flags() != defaultFlags)
2316 return true;
2317
2319 if (!text.isEmpty()) {
2321 return true;
2322 } else {
2323 // FIXME: This doesn't seem to make sense
2324 return true;
2325 }
2326
2327 auto pred = [item](int i) {
2328 return i != Qt::DisplayPropertyRole && item->data(i).isValid();
2329 };
2330 return std::any_of(std::begin(itemRoles), std::end(itemRoles), pred);
2331}
2332
2340
2342{
2343 clear();
2346 // horiz header: Legacy behaviour: auto-generate number for empty items
2347 for (int col = 0; col < m_columnCount; col++)
2350 // vertical header: Legacy behaviour: auto-generate number for empty items
2351 for (int row = 0; row < m_rowCount; row++)
2354 // cell data
2355 for (int col = 0; col < m_columnCount; col++)
2356 for (int row = 0; row < m_rowCount; row++)
2357 if (const QTableWidgetItem *item = tableWidget->item(row, col))
2358 if (nonEmpty(item, -1))
2360}
2361
2363{
2364 tableWidget->clear();
2365
2368
2369 // horiz header
2370 int col = 0;
2371 for (const ItemData &id : m_horizontalHeader.m_items) {
2372 if (id.isValid())
2374 col++;
2375 }
2376 // vertical header
2377 int row = 0;
2378 for (const ItemData &id : m_verticalHeader.m_items) {
2379 if (id.isValid())
2381 row++;
2382 }
2383 // items
2384 for (auto it = m_items.cbegin(), icend = m_items.cend(); it != icend; ++ it) {
2387 }
2388}
2389
2390bool comparesEqual(const TableWidgetContents &lhs,
2391 const TableWidgetContents &rhs) noexcept
2392{
2393 return lhs.m_columnCount == rhs.m_columnCount && lhs.m_rowCount == rhs.m_rowCount &&
2394 lhs.m_horizontalHeader.m_items == rhs.m_horizontalHeader.m_items &&
2395 lhs.m_verticalHeader.m_items == rhs.m_verticalHeader.m_items &&
2396 lhs.m_items == rhs.m_items;
2397}
2398
2399// ---- ChangeTableContentsCommand ----
2407
2415
2421
2427
2428// --------- TreeWidgetContents
2431{
2432 static const Qt::ItemFlags defaultFlags = QTreeWidgetItem().flags();
2433
2434 if (editor) {
2436 m_itemFlags = v.isValid() ? v.toInt() : -1;
2437 } else {
2438 m_itemFlags = (item->flags() != defaultFlags) ? int(item->flags()) : -1;
2439 }
2440
2441 for (int i = 0; i < item->childCount(); i++)
2443}
2444
2464
2465bool comparesEqual(const TreeWidgetContents::ItemContents &lhs,
2466 const TreeWidgetContents::ItemContents &rhs) noexcept
2467{
2468 return lhs.m_itemFlags == rhs.m_itemFlags && lhs.m_items == rhs.m_items
2469 && lhs.m_children == rhs.m_children;
2470}
2471
2477
2485
2496
2497// ---- ChangeTreeContentsCommand ----
2505
2513
2518
2523
2524// ---- ChangeListContentsCommand ----
2531
2541
2551
2559
2567
2568// ---- AddActionCommand ----
2569
2574
2576{
2577 Q_ASSERT(m_action == nullptr);
2578 m_action = action;
2579}
2580
2586
2592
2593// ---- RemoveActionCommand ----
2594
2599
2601{
2603 // We only want menus and toolbars, no toolbuttons.
2605 for (QObject *obj : associatedObjects) {
2606 if (!qobject_cast<const QMenu *>(obj) && !qobject_cast<const QToolBar *>(obj))
2607 continue;
2608 auto *widget = static_cast<QWidget *>(obj);
2609 const auto actionList = widget->actions();
2610 for (qsizetype i = 0, size = actionList.size(); i < size; ++i) {
2611 if (actionList.at(i) == action) {
2612 QAction *before = nullptr;
2613 if (i + 1 < size)
2614 before = actionList.at(i + 1);
2616 break;
2617 }
2618 }
2619 }
2620 return result;
2621}
2622
2624{
2625 Q_ASSERT(m_action == nullptr);
2626 m_action = action;
2627
2629}
2630
2632{
2634 for (const ActionDataItem &item : std::as_const(m_actionData)) {
2636 }
2637 // Notify components (for example, signal slot editor)
2640
2643 if (!m_actionData.isEmpty())
2645}
2646
2656
2657// ---- ActionInsertionCommand ----
2658
2667
2678
2680{
2681 Q_ASSERT(m_action != nullptr);
2682 Q_ASSERT(m_parentWidget != nullptr);
2683
2684 if (m_beforeAction)
2686 else
2688
2689 if (m_update) {
2690 cheapUpdate();
2691 if (QMenu *menu = m_action->menu())
2693 else
2695 PropertyHelper::triggerActionChanged(m_action); // Update Used column in action editor.
2696 }
2697}
2699{
2700 Q_ASSERT(m_action != nullptr);
2701 Q_ASSERT(m_parentWidget != nullptr);
2702
2704 menu->hideSubMenu();
2705
2707
2708 if (m_update) {
2709 cheapUpdate();
2711 PropertyHelper::triggerActionChanged(m_action); // Update Used column in action editor.
2712 }
2713}
2714
2719// ---- RemoveActionFromCommand ----
2720
2725
2726// ---- AddMenuActionCommand ----
2727
2737
2749
2761
2763{
2764 m_action->menu()->setParent(nullptr);
2765 QMenu *menu = m_action->menu();
2767 menu->setParent(nullptr);
2770 cheapUpdate();
2772}
2773
2778
2779// ---- RemoveMenuActionCommand ----
2784
2785// ---- CreateSubmenuCommand ----
2793
2800
2808
2815
2816// ---- DeleteToolBarCommand ----
2821
2827
2829{
2830 if (m_mainWindow) {
2831 QDesignerContainerExtension *c = qt_extension<QDesignerContainerExtension*>(core()->extensionManager(), m_mainWindow);
2832 Q_ASSERT(c != nullptr);
2833 for (int i=0; i<c->count(); ++i) {
2834 if (c->widget(i) == m_toolBar) {
2835 c->remove(i);
2836 break;
2837 }
2838 }
2839 }
2840
2842 m_toolBar->hide();
2845}
2846
2848{
2849 if (m_mainWindow) {
2851 QDesignerContainerExtension *c = qt_extension<QDesignerContainerExtension*>(core()->extensionManager(), m_mainWindow);
2852
2854
2856 m_toolBar->show();
2858 }
2859}
2860
2861} // namespace qdesigner_internal
2862
2863QT_END_NAMESPACE
friend class QWidget
Definition qpainter.h:431
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)