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
49Q_DECLARE_METATYPE(QWidgetList)
50
51QT_BEGIN_NAMESPACE
52
53using namespace Qt::StringLiterals;
54
55static inline void setPropertySheetWindowTitle(const QDesignerFormEditorInterface *core, QObject *o, const QString &t)
56{
57 if (QDesignerPropertySheetExtension *sheet = qt_extension<QDesignerPropertySheetExtension*>(core->extensionManager(), o)) {
58 const int idx = sheet->indexOf(u"windowTitle"_s);
59 if (idx != -1) {
60 sheet->setProperty(idx, t);
61 sheet->setChanged(idx, true);
62 }
63 }
64}
65
66namespace qdesigner_internal {
67
68// Helpers for the dynamic properties that store Z/Widget order
69static const char widgetOrderPropertyC[] = "_q_widgetOrder";
70static const char zOrderPropertyC[] = "_q_zOrder";
71
72static void addToWidgetListDynamicProperty(QWidget *parentWidget, QWidget *widget, const char *name, int index = -1)
73{
74 QWidgetList list = qvariant_cast<QWidgetList>(parentWidget->property(name));
75 list.removeAll(widget);
76 if (index >= 0 && index < list.size()) {
77 list.insert(index, widget);
78 } else {
79 list.append(widget);
80 }
81 parentWidget->setProperty(name, QVariant::fromValue(list));
82}
83
84static int removeFromWidgetListDynamicProperty(QWidget *parentWidget, QWidget *widget, const char *name)
85{
86 QWidgetList list = qvariant_cast<QWidgetList>(parentWidget->property(name));
87 const int firstIndex = list.indexOf(widget);
88 if (firstIndex != -1) {
89 list.removeAll(widget);
90 parentWidget->setProperty(name, QVariant::fromValue(list));
91 }
92 return firstIndex;
93}
94
95// ---- InsertWidgetCommand ----
103
108
128
130{
131 w->update();
132
133 for (auto *child : w->children()) {
134 if (QWidget *w = qobject_cast<QWidget*>(child))
135 recursiveUpdate(w);
136 }
137}
138
182
207
209{
210 const auto label_list = formWindow()->findChildren<QLabel*>();
211 if (label_list.isEmpty())
212 return;
213
214 const QString buddyProperty = u"buddy"_s;
216 // Re-set the buddy (The sheet locates the object by name and sets it)
217 for (QLabel *label : label_list) {
219 const int idx = sheet->indexOf(buddyProperty);
220 if (idx != -1) {
221 const QVariant value = sheet->property(idx);
224 }
225 }
226 }
227}
228
229// ---- ChangeZOrderCommand ----
234
236{
238
240
241 setText(QApplication::translate("Command", "Change Z-order of '%1'").arg(widget->objectName()));
242
245 if (index != -1 && index + 1 < m_oldParentZOrder.size())
247}
248
255
265
266// ---- RaiseWidgetCommand ----
271
277
285
287{
288 widget->raise();
289}
290
291// ---- LowerWidgetCommand ----
296
304
310
312{
313 widget->lower();
314}
315
316// ---- ManageWidgetCommandHelper
318
331
337
339{
340 // Manage the managed children after parent
342 for (auto *w : std::as_const(m_managedChildren))
343 fw->manageWidget(w);
344}
345
347{
348 // Unmanage the managed children first
349 for (auto *w : std::as_const(m_managedChildren))
352}
353
354// ---- DeleteWidgetCommand ----
368
373
375{
379 m_flags = flags;
381 m_splitterIndex = -1;
382 bool isManaged; // Check for a managed layout
385 if (!isManaged)
387 switch (m_layoutType) {
388 case LayoutInfo::HSplitter:
389 case LayoutInfo::VSplitter: {
393 }
394 break;
395 case LayoutInfo::NoLayout:
396 break;
397 default:
400 break;
401 }
402
405
406 // Build the list of managed children
408
409 setText(QApplication::translate("Command", "Delete '%1'").arg(widget->objectName()));
410}
411
413{
416
418 const int count = c->count();
419 for (int i=0; i<count; ++i) {
420 if (c->widget(i) == m_widget) {
421 c->remove(i);
422 return;
423 }
424 }
425 }
426
429
432
433 if (m_layoutHelper)
434 switch (m_layoutType) {
435 case LayoutInfo::NoLayout:
436 case LayoutInfo::HSplitter:
437 case LayoutInfo::VSplitter:
438 break;
439 default:
440 // Attempt to simplify grids if a row/column becomes empty
442 if (m_layoutSimplified) {
445 }
446 break;
447 }
448
449 if (!(m_flags & DoNotUnmanage))
451
453 m_widget->hide();
454
455 if (m_tabOrderIndex != -1) {
459 }
460}
461
463{
466
468
471 return;
472 }
473
476
478
479 if (!(m_flags & DoNotUnmanage))
481 // ### set up alignment
482 switch (m_layoutType) {
483 case LayoutInfo::NoLayout:
484 break;
485 case LayoutInfo::HSplitter:
486 case LayoutInfo::VSplitter: {
490 } break;
491 default: {
498 }
499 break;
500 }
501
502 m_widget->show();
503
504 if (m_tabOrderIndex != -1) {
508 }
509}
510
511// ---- ReparentWidgetCommand ----
516
533
558
579
585
591
593{
594 for (QWidget *w : std::as_const(m_widgets)) {
595 if (w)
597 }
599}
600
602{
603 // Update class names in ObjectInspector, PropertyEditor
607 if (QObject *o = core->propertyEditor()->object())
609}
610
612{
613 for (QWidget *w : std::as_const(m_widgets)) {
614 if (w)
615 demoteWidget(core(), w);
616 }
618}
619
620// ---- DemoteFromCustomWidgetCommand ----
621
628
633
638
643
644// ---------- CursorSelectionState
646
658
660{
661 if (m_selection.isEmpty()) {
663 } else {
664 // Select current as last
666 for (const auto &wp : m_selection) {
667 if (!wp.isNull() && wp.data() != m_current)
668 formWindow->selectWidget(wp.data(), true);
669 }
670 if (m_current)
672 }
673}
674
675// ---- LayoutCommand ----
676
682
684{
685 delete m_layout;
686}
687
691{
697
698 switch (layoutType) {
699 case LayoutInfo::Grid:
700 setText(QApplication::translate("Command", "Lay out using grid"));
701 break;
702 case LayoutInfo::VBox:
703 setText(QApplication::translate("Command", "Lay out vertically"));
704 break;
705 case LayoutInfo::HBox:
706 setText(QApplication::translate("Command", "Lay out horizontally"));
707 break;
708 default:
709 break;
710 }
711 // Delayed setup to avoid confusion in case we are chained
712 // with a BreakLayout in a morph layout macro
713 m_setup = false;
714}
715
717{
718 if (!m_setup) {
719 m_layout->setup();
721 m_setup = true;
722 }
725}
726
728{
730
734 delete deco; // release the extension
735
736 // ### generalize (put in function)
737 if (!m_layoutBase && lb != nullptr && !(qobject_cast<QLayoutWidget*>(lb) || qobject_cast<QSplitter*>(lb))) {
738 core->metaDataBase()->add(lb);
739 lb->show();
740 }
743}
744
745// ---- BreakLayoutCommand ----
753
755{
756 delete m_layoutHelper;
757 delete m_layout;
758 delete m_properties;
759}
760
765
767{
768 return m_propertyMask;
769}
770
772{
774
782
784 switch (layoutType) {
785 case LayoutInfo::NoLayout:
786 case LayoutInfo::HSplitter:
787 case LayoutInfo::VSplitter:
789 break;
790 case LayoutInfo::HBox:
791 case LayoutInfo::VBox: // Margin/spacing need to be saved
793 break;
794 default: // Margin/spacing need to be saved + has a state (empty rows/columns of a grid)
796 break;
797 }
798 Q_ASSERT(m_layout != nullptr);
799 m_layout->sort();
800
801
805 }
806 if (type >= LayoutHasState)
809}
810
812{
813 if (!m_layout)
814 return;
815
819 formWindow()->clearSelection(false);
820 if (m_layoutHelper)
823 delete deco; // release the extension
824
825 for (QWidget *widget : std::as_const(m_widgets)) {
826 widget->resize(widget->size().expandedTo(QSize(16, 16)));
827 }
828 // Update unless we are in an intermediate state of morphing layout
829 // in which a QLayoutWidget will have no layout at all.
832}
833
850// ---- SimplifyLayoutCommand
852 QDesignerFormWindowCommand(QApplication::translate("Command", "Simplify Grid Layout"), formWindow),
853 m_area(0, 0, 32767, 32767),
854 m_layoutBase(nullptr),
855 m_layoutHelper(nullptr),
856 m_layoutSimplified(false)
857{
858}
859
864
866{
867 if (!w)
868 return false;
871 if (layoutType)
872 *layoutType = type;
873 if (!layout)
874 return false;
875 switch (type) { // Known negatives
876 case LayoutInfo::NoLayout:
878 case LayoutInfo::HSplitter:
879 case LayoutInfo::VSplitter:
880 case LayoutInfo::HBox:
881 case LayoutInfo::VBox:
882 return false;
883 default:
884 break;
885 }
886 switch (type) {
887 case LayoutInfo::Grid:
889 case LayoutInfo::Form:
891 default:
892 break;
893 }
894 return false;
895}
896
909
923
924// ---- ToolBoxCommand ----
930
931ToolBoxCommand::~ToolBoxCommand() = default;
932
941
952
969
970// ---- MoveToolBoxPageCommand ----
977
979
991
997
1003
1004// ---- DeleteToolBoxPageCommand ----
1009
1011
1013{
1015 setText(QApplication::translate("Command", "Delete Page"));
1016}
1017
1019{
1020 removePage();
1021 cheapUpdate();
1022}
1023
1025{
1026 addPage();
1027 cheapUpdate();
1028}
1029
1030// ---- AddToolBoxPageCommand ----
1035
1037
1042
1044{
1046
1048 if (mode == InsertAfter)
1049 m_index++;
1051 m_itemText = QApplication::translate("Command", "Page");
1052 m_itemIcon = QIcon();
1053 m_widget->setObjectName(u"page"_s);
1055
1056 setText(QApplication::translate("Command", "Insert Page"));
1057
1058 QDesignerFormEditorInterface *core = formWindow()->core();
1060}
1061
1063{
1064 addPage();
1065 cheapUpdate();
1066}
1067
1069{
1070 removePage();
1071 cheapUpdate();
1072}
1073
1074// ---- TabWidgetCommand ----
1080
1082
1091
1103
1121
1122// ---- DeleteTabPageCommand ----
1127
1129
1131{
1133 setText(QApplication::translate("Command", "Delete Page"));
1134}
1135
1137{
1138 removePage();
1139 cheapUpdate();
1140}
1141
1143{
1144 addPage();
1145 cheapUpdate();
1146}
1147
1148// ---- AddTabPageCommand ----
1153
1155
1160
1162{
1164
1166 if (mode == InsertAfter)
1167 m_index++;
1169 m_itemText = QApplication::translate("Command", "Page");
1170 m_itemIcon = QIcon();
1171 m_widget->setObjectName(u"tab"_s);
1173
1174 setText(QApplication::translate("Command", "Insert Page"));
1175
1176 QDesignerFormEditorInterface *core = formWindow()->core();
1178}
1179
1181{
1182 addPage();
1183 cheapUpdate();
1184}
1185
1187{
1188 removePage();
1189 cheapUpdate();
1190}
1191
1192// ---- MoveTabPageCommand ----
1199
1201
1203 const QIcon &icon, const QString &label,
1204 int index, int newIndex)
1205{
1207 setText(QApplication::translate("Command", "Move Page"));
1208
1209 m_page = page;
1211 m_oldIndex = index;
1212 m_label = label;
1213 m_icon = icon;
1214}
1215
1222
1229
1230// ---- StackedWidgetCommand ----
1236
1238
1245
1256
1267
1268// ---- MoveStackedWidgetCommand ----
1275
1277
1287
1293
1299
1300// ---- DeleteStackedWidgetPageCommand ----
1305
1307
1313
1315{
1316 removePage();
1317 cheapUpdate();
1318}
1319
1321{
1322 addPage();
1323 cheapUpdate();
1324}
1325
1326// ---- AddStackedWidgetPageCommand ----
1331
1333
1338
1340{
1342
1344 if (mode == InsertAfter)
1345 m_index++;
1347 m_widget->setObjectName(u"page"_s);
1349
1350 setText(QApplication::translate("Command", "Insert Page"));
1351
1352 QDesignerFormEditorInterface *core = formWindow()->core();
1354}
1355
1357{
1358 addPage();
1359 cheapUpdate();
1360}
1361
1363{
1364 removePage();
1365 cheapUpdate();
1366}
1367
1368// ---- TabOrderCommand ----
1374
1385
1390
1395
1396// ---- CreateMenuBarCommand ----
1401
1403{
1405 QDesignerFormEditorInterface *core = formWindow()->core();
1408}
1409
1423
1425{
1426 QDesignerFormEditorInterface *core = formWindow()->core();
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) {
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
1486
1487// ---- CreateStatusBarCommand ----
1492
1494{
1496 QDesignerFormEditorInterface *core = formWindow()->core();
1499}
1500
1513
1515{
1516 QDesignerFormEditorInterface *core = formWindow()->core();
1518 for (int i = 0; i < c->count(); ++i) {
1519 if (c->widget(i) == m_statusBar) {
1520 c->remove(i);
1521 break;
1522 }
1523 }
1524
1527}
1528
1529// ---- DeleteStatusBarCommand ----
1534
1540
1542{
1543 if (m_mainWindow) {
1545 Q_ASSERT(c != nullptr);
1546 for (int i=0; i<c->count(); ++i) {
1547 if (c->widget(i) == m_statusBar) {
1548 c->remove(i);
1549 break;
1550 }
1551 }
1552 }
1553
1555 m_statusBar->hide();
1558}
1559
1573
1574// ---- AddToolBarCommand ----
1579
1581{
1583 QDesignerWidgetFactoryInterface * wf = formWindow()->core()->widgetFactory();
1584 // Pass on 0 parent first to avoid reparenting flicker.
1585 m_toolBar = qobject_cast<QToolBar*>(wf->createWidget(u"QToolBar"_s, nullptr));
1586 m_toolBar->setProperty("_q_desiredArea", QVariant(area));
1588 m_toolBar->hide();
1589}
1590
1604
1606{
1607 QDesignerFormEditorInterface *core = formWindow()->core();
1610 for (int i = 0; i < c->count(); ++i) {
1611 if (c->widget(i) == m_toolBar) {
1612 c->remove(i);
1613 break;
1614 }
1615 }
1617}
1618
1619// ---- DockWidgetCommand:: ----
1624
1626
1631
1632// ---- AddDockWidgetCommand ----
1637
1643
1650
1662
1664{
1667 for (int i = 0; i < c->count(); ++i) {
1668 if (c->widget(i) == m_dockWidget) {
1669 c->remove(i);
1670 break;
1671 }
1672 }
1673
1676}
1677
1678// ---- AdjustWidgetSizeCommand ----
1683
1685{
1686 m_widget = widget;
1687 setText(QApplication::translate("Command", "Adjust Size of '%1'").arg(widget->objectName()));
1688}
1689
1691{
1693 // Return the outer, embedding widget if it is the main container
1696 return m_widget;
1697}
1698
1700{
1702 m_geometry = aw->geometry();
1704 aw->adjustSize();
1705 const bool isMainContainer = aw != m_widget;
1706 if (!isMainContainer) {
1707 /* When doing adjustsize on a selected non-laid out child that has been enlarged
1708 * and pushed partially over the top/left edge[s], it is possible that it "disappears"
1709 * when shrinking. In that case, move it back so that it remains visible. */
1710 if (aw->parentWidget()->layout() == nullptr) {
1712 const QRect newGeometry = aw->geometry();
1714 if (newGeometry.bottom() <= contentsRect.y())
1716 if (newGeometry.right() <= contentsRect.x())
1718 if (newPos != m_geometry.topLeft())
1719 aw->move(newPos);
1720 }
1721 }
1723}
1724
1733
1735{
1737 if (propertyEditor->object() == m_widget)
1738 propertyEditor->setPropertyValue(u"geometry"_s, m_widget->geometry(), true);
1739 }
1740}
1741// ------------ ChangeFormLayoutItemRoleCommand
1742
1748
1754
1759
1764
1766{
1767 switch (op) {
1768 case SpanningToLabel:
1769 return LabelToSpanning;
1770 case SpanningToField:
1771 return FieldToSpanning;
1772 case LabelToSpanning:
1773 return SpanningToLabel;
1774 case FieldToSpanning:
1775 return SpanningToField;
1776 }
1777 return SpanningToField;
1778}
1779
1781{
1783 const int index = fl->indexOf(m_widget);
1784 Q_ASSERT(index != -1);
1785 int row;
1788 Q_ASSERT(index != -1);
1790 const QRect area = QRect(0, row, 2, 1);
1791 switch (op) {
1792 case SpanningToLabel:
1795 break;
1796 case SpanningToField:
1799 break;
1800 case LabelToSpanning:
1801 case FieldToSpanning:
1804 break;
1805 }
1806}
1807
1809{
1811 if (!fl)
1812 return 0;
1813 const int index = fl->indexOf(w);
1814 if (index == -1)
1815 return 0;
1816 int row, col, colspan;
1818 // Spanning item?
1819 if (colspan > 1)
1821 // Is the neighbouring column free, that is, can the current item be expanded?
1824 if (empty)
1825 return col == 0 ? LabelToSpanning : FieldToSpanning;
1826 return 0;
1827}
1828
1830{
1833 return fl;
1834 return nullptr;
1835}
1836
1837// ---- ChangeLayoutItemGeometry ----
1842
1863
1865{
1867 Q_ASSERT(layout != nullptr);
1868
1870 Q_ASSERT(grid != nullptr);
1871
1872 const int itemIndex = grid->indexOf(m_widget);
1873 Q_ASSERT(itemIndex != -1);
1874
1876 delete item;
1877
1879 qWarning() << "ChangeLayoutItemGeometry::changeItemPosition: Nonempty cell at " << g << '.';
1880
1881 grid->addWidget(m_widget, g.top(), g.left(), g.height(), g.width());
1882
1883 grid->invalidate();
1884 grid->activate();
1885
1887
1888 formWindow()->clearSelection(false);
1890}
1891
1896
1901
1902// ---- ContainerWidgetCommand ----
1908
1910
1916
1926
1928{
1930 if (const int count = c->count()) {
1931 // Undo add after last?
1932 const int deleteIndex = m_index >= 0 ? m_index : count - 1;
1934 m_widget->hide();
1936 }
1937 }
1938}
1939
1941{
1943 int newCurrentIndex;
1944 if (m_index >= 0) {
1947 } else {
1949 newCurrentIndex = c->count() -1 ;
1950 }
1951 m_widget->show();
1953 }
1954}
1955
1956// ---- DeleteContainerWidgetPageCommand ----
1961
1963
1965{
1967 switch (ct) {
1968 case WizardContainer:
1969 case PageContainer:
1970 setText(QApplication::translate("Command", "Delete Page"));
1971 break;
1972 case MdiContainer:
1973 setText(QApplication::translate("Command", "Delete Subwindow"));
1974 break;
1975 }
1976}
1977
1983
1985{
1986 addPage();
1987 cheapUpdate();
1988}
1989
1990// ---- AddContainerWidgetPageCommand ----
1995
1997
1999{
2001
2003 m_index = c->currentIndex();
2004 if (m_index >= 0 && mode == InsertAfter)
2005 m_index++;
2006 m_widget = nullptr;
2008 switch (ct) {
2009 case PageContainer:
2010 setText(QApplication::translate("Command", "Insert Page"));
2012 m_widget->setObjectName(u"page"_s);
2013 break;
2014 case MdiContainer:
2015 setText(QApplication::translate("Command", "Insert Subwindow"));
2017 m_widget->setObjectName(u"subwindow"_s);
2019 break;
2020 case WizardContainer: // Apply style, don't manage
2021 m_widget = core->widgetFactory()->createWidget(u"QWizardPage"_s, nullptr);
2022 break;
2023 }
2026 }
2027}
2028
2030{
2031 addPage();
2032 cheapUpdate();
2033}
2034
2036{
2037 removePage();
2038 cheapUpdate();
2039}
2040
2046
2048
2054
2065
2070
2075
2088
2089template<class T>
2090static void copyRoleFromItem(ItemData *id, int role, const T *item)
2091{
2092 QVariant v = item->data(role);
2093 if (v.isValid())
2095}
2096
2097template<class T>
2098static void copyRolesFromItem(ItemData *id, const T *item, bool editor)
2099{
2100 static const Qt::ItemFlags defaultFlags = T().flags();
2101
2102 for (int i : itemRoles)
2104
2105 if (editor)
2107 else if (item->flags() != defaultFlags)
2109}
2110
2111template<class T>
2112static void copyRolesToItem(const ItemData *id, T *item, DesignerIconCache *iconCache, bool editor)
2113{
2114 for (auto it = id->m_properties.cbegin(), end = id->m_properties.cend(); it != end; ++it) {
2115 if (it.value().isValid()) {
2116 if (!editor && it.key() == ItemFlagsShadowRole) {
2117 item->setFlags((Qt::ItemFlags)it.value().toInt());
2118 } else {
2119 item->setData(it.key(), it.value());
2120 switch (it.key()) {
2121 case Qt::DecorationPropertyRole:
2122 if (iconCache)
2123 item->setIcon(iconCache->icon(qvariant_cast<PropertySheetIconValue>(it.value())));
2124 break;
2125 case Qt::DisplayPropertyRole:
2126 item->setText(qvariant_cast<PropertySheetStringValue>(it.value()).value());
2127 break;
2128 case Qt::ToolTipPropertyRole:
2129 item->setToolTip(qvariant_cast<PropertySheetStringValue>(it.value()).value());
2130 break;
2131 case Qt::StatusTipPropertyRole:
2132 item->setStatusTip(qvariant_cast<PropertySheetStringValue>(it.value()).value());
2133 break;
2134 case Qt::WhatsThisPropertyRole:
2135 item->setWhatsThis(qvariant_cast<PropertySheetStringValue>(it.value()).value());
2136 break;
2137 }
2138 }
2139 }
2140 }
2141
2142 if (editor)
2143 item->setFlags(item->flags() | Qt::ItemIsEditable);
2144}
2145
2150
2157
2162
2169
2171{
2173 if (v.isValid())
2175}
2176
2186
2213
2215{
2216 for (int i = 0; i < item->columnCount(); i++)
2218}
2219
2221{
2223 int i = 0;
2224 for (const ItemData &id : m_items)
2226 return item;
2227}
2228
2230{
2231 m_items.clear();
2232
2233 for (int i = 0; i < listWidget->count(); i++)
2235}
2236
2253
2255{
2256 m_items.clear();
2257
2258 const int count = comboBox->count();
2259 for (int i = 0; i < count; i++) {
2260 // We might encounter items added in a custom combo
2261 // constructor. Ignore those.
2263 if (!textValue.isNull()) {
2267 if (!iconValue.isNull())
2270 }
2271 }
2272}
2273
2294
2295// --------- TableWidgetContents
2296
2298
2307
2309{
2310 return QString::number(i + 1);
2311}
2312
2314{
2315 static const Qt::ItemFlags defaultFlags = QTableWidgetItem().flags();
2316
2317 if (item->flags() != defaultFlags)
2318 return true;
2319
2321 if (!text.isEmpty()) {
2323 return true;
2324 } else {
2325 // FIXME: This doesn't seem to make sense
2326 return true;
2327 }
2328
2329 for (int i : itemRoles) {
2330 if (i != Qt::DisplayPropertyRole && item->data(i).isValid())
2331 return true;
2332 }
2333
2334 return false;
2335}
2336
2344
2346{
2347 clear();
2350 // horiz header: Legacy behaviour: auto-generate number for empty items
2351 for (int col = 0; col < m_columnCount; col++)
2354 // vertical header: Legacy behaviour: auto-generate number for empty items
2355 for (int row = 0; row < m_rowCount; row++)
2358 // cell data
2359 for (int col = 0; col < m_columnCount; col++)
2360 for (int row = 0; row < m_rowCount; row++)
2361 if (const QTableWidgetItem *item = tableWidget->item(row, col))
2362 if (nonEmpty(item, -1))
2364}
2365
2367{
2368 tableWidget->clear();
2369
2372
2373 // horiz header
2374 int col = 0;
2375 for (const ItemData &id : m_horizontalHeader.m_items) {
2376 if (id.isValid())
2378 col++;
2379 }
2380 // vertical header
2381 int row = 0;
2382 for (const ItemData &id : m_verticalHeader.m_items) {
2383 if (id.isValid())
2385 row++;
2386 }
2387 // items
2388 for (auto it = m_items.cbegin(), icend = m_items.cend(); it != icend; ++ it) {
2391 }
2392}
2393
2394bool comparesEqual(const TableWidgetContents &lhs,
2395 const TableWidgetContents &rhs) noexcept
2396{
2397 return lhs.m_columnCount == rhs.m_columnCount && lhs.m_rowCount == rhs.m_rowCount &&
2398 lhs.m_horizontalHeader.m_items == rhs.m_horizontalHeader.m_items &&
2399 lhs.m_verticalHeader.m_items == rhs.m_verticalHeader.m_items &&
2400 lhs.m_items == rhs.m_items;
2401}
2402
2403// ---- ChangeTableContentsCommand ----
2412
2420
2426
2432
2433// --------- TreeWidgetContents
2436{
2437 static const Qt::ItemFlags defaultFlags = QTreeWidgetItem().flags();
2438
2439 if (editor) {
2441 m_itemFlags = v.isValid() ? v.toInt() : -1;
2442 } else {
2443 m_itemFlags = (item->flags() != defaultFlags) ? int(item->flags()) : -1;
2444 }
2445
2446 for (int i = 0; i < item->childCount(); i++)
2448}
2449
2469
2470bool comparesEqual(const TreeWidgetContents::ItemContents &lhs,
2471 const TreeWidgetContents::ItemContents &rhs) noexcept
2472{
2473 return lhs.m_itemFlags == rhs.m_itemFlags && lhs.m_items == rhs.m_items
2474 && lhs.m_children == rhs.m_children;
2475}
2476
2482
2490
2501
2502// ---- ChangeTreeContentsCommand ----
2511
2519
2524
2529
2530// ---- ChangeListContentsCommand ----
2538
2548
2558
2566
2574
2575// ---- AddActionCommand ----
2576
2582
2584{
2585 Q_ASSERT(m_action == nullptr);
2586 m_action = action;
2587}
2588
2594
2600
2601// ---- RemoveActionCommand ----
2602
2608
2610{
2612 // We only want menus and toolbars, no toolbuttons.
2614 for (QObject *obj : associatedObjects) {
2615 if (!qobject_cast<const QMenu *>(obj) && !qobject_cast<const QToolBar *>(obj))
2616 continue;
2617 QWidget *widget = static_cast<QWidget *>(obj);
2618 const auto actionList = widget->actions();
2619 for (qsizetype i = 0, size = actionList.size(); i < size; ++i) {
2620 if (actionList.at(i) == action) {
2621 QAction *before = nullptr;
2622 if (i + 1 < size)
2623 before = actionList.at(i + 1);
2625 break;
2626 }
2627 }
2628 }
2629 return result;
2630}
2631
2633{
2634 Q_ASSERT(m_action == nullptr);
2635 m_action = action;
2636
2638}
2639
2641{
2643 for (const ActionDataItem &item : std::as_const(m_actionData)) {
2645 }
2646 // Notify components (for example, signal slot editor)
2649
2652 if (!m_actionData.isEmpty())
2654}
2655
2665
2666// ---- ActionInsertionCommand ----
2667
2676
2687
2689{
2690 Q_ASSERT(m_action != nullptr);
2691 Q_ASSERT(m_parentWidget != nullptr);
2692
2693 if (m_beforeAction)
2695 else
2697
2698 if (m_update) {
2699 cheapUpdate();
2700 if (QMenu *menu = m_action->menu())
2702 else
2704 PropertyHelper::triggerActionChanged(m_action); // Update Used column in action editor.
2705 }
2706}
2708{
2709 Q_ASSERT(m_action != nullptr);
2710 Q_ASSERT(m_parentWidget != nullptr);
2711
2713 menu->hideSubMenu();
2714
2716
2717 if (m_update) {
2718 cheapUpdate();
2720 PropertyHelper::triggerActionChanged(m_action); // Update Used column in action editor.
2721 }
2722}
2723
2728// ---- RemoveActionFromCommand ----
2729
2734
2735// ---- AddMenuActionCommand ----
2736
2746
2758
2770
2772{
2773 m_action->menu()->setParent(nullptr);
2774 QMenu *menu = m_action->menu();
2776 menu->setParent(nullptr);
2779 cheapUpdate();
2781}
2782
2787
2788// ---- RemoveMenuActionCommand ----
2793
2794// ---- CreateSubmenuCommand ----
2802
2809
2817
2824
2825// ---- DeleteToolBarCommand ----
2830
2836
2838{
2839 if (m_mainWindow) {
2841 Q_ASSERT(c != nullptr);
2842 for (int i=0; i<c->count(); ++i) {
2843 if (c->widget(i) == m_toolBar) {
2844 c->remove(i);
2845 break;
2846 }
2847 }
2848 }
2849
2851 m_toolBar->hide();
2854}
2855
2869
2870} // namespace qdesigner_internal
2871
2872QT_END_NAMESPACE
friend class QWidget
Definition qpainter.h:421
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)