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 "qdesigner_command_p.h"
30 #include "qdesigner_propertycommand_p.h"
31 #include "qdesigner_utils_p.h"
32 #include "layout_p.h"
33 #include "qlayout_widget_p.h"
34 #include "qdesigner_widget_p.h"
35 #include "qdesigner_menu_p.h"
36 #include "shared_enums_p.h"
37 #include "metadatabase_p.h"
38 #include "formwindowbase_p.h"
39 #include <abstractformbuilder.h>
40 
41 #include <QtDesigner/abstractformwindow.h>
42 #include <QtDesigner/abstractformeditor.h>
43 #include <QtDesigner/propertysheet.h>
44 #include <QtDesigner/abstractactioneditor.h>
45 #include <QtDesigner/abstractpropertyeditor.h>
46 #include <QtDesigner/qextensionmanager.h>
47 #include <QtDesigner/container.h>
48 #include <QtDesigner/layoutdecoration.h>
49 #include <QtDesigner/abstractwidgetfactory.h>
50 #include <QtDesigner/abstractobjectinspector.h>
51 #include <QtDesigner/abstractintegration.h>
52 #include <QtDesigner/abstractformwindowcursor.h>
53 #include <QtCore/qdebug.h>
54 #include <QtCore/qtextstream.h>
55 #include <QtCore/qqueue.h>
56 
57 #include <QtWidgets/qmenubar.h>
58 #include <QtWidgets/qstatusbar.h>
59 #include <QtWidgets/qtoolbar.h>
60 #include <QtWidgets/qtoolbox.h>
61 #include <QtWidgets/qstackedwidget.h>
62 #include <QtWidgets/qtabwidget.h>
63 #include <QtWidgets/qtablewidget.h>
64 #include <QtWidgets/qtreewidget.h>
65 #include <QtWidgets/qlistwidget.h>
66 #include <QtWidgets/qcombobox.h>
67 #include <QtWidgets/qsplitter.h>
68 #include <QtWidgets/qdockwidget.h>
69 #include <QtWidgets/qmainwindow.h>
70 #include <QtWidgets/qwizard.h>
71 #include <QtWidgets/qapplication.h>
72 #include <QtWidgets/qformlayout.h>
73 
Q_DECLARE_METATYPE(QWidgetList)74 Q_DECLARE_METATYPE(QWidgetList)
75 
76 QT_BEGIN_NAMESPACE
77 
78 static inline void setPropertySheetWindowTitle(const QDesignerFormEditorInterface *core, QObject *o, const QString &t)
79 {
80     if (QDesignerPropertySheetExtension *sheet = qt_extension<QDesignerPropertySheetExtension*>(core->extensionManager(), o)) {
81         const int idx = sheet->indexOf(QStringLiteral("windowTitle"));
82         if (idx != -1) {
83             sheet->setProperty(idx, t);
84             sheet->setChanged(idx, true);
85         }
86     }
87 }
88 
89 namespace qdesigner_internal {
90 
91 // Helpers for the dynamic properties that store Z/Widget order
92 static const char *widgetOrderPropertyC = "_q_widgetOrder";
93 static const char *zOrderPropertyC = "_q_zOrder";
94 
addToWidgetListDynamicProperty(QWidget * parentWidget,QWidget * widget,const char * name,int index=-1)95 static void addToWidgetListDynamicProperty(QWidget *parentWidget, QWidget *widget, const char *name, int index = -1)
96 {
97     QWidgetList list = qvariant_cast<QWidgetList>(parentWidget->property(name));
98     list.removeAll(widget);
99     if (index >= 0 && index < list.size()) {
100         list.insert(index, widget);
101     } else {
102         list.append(widget);
103     }
104     parentWidget->setProperty(name, QVariant::fromValue(list));
105 }
106 
removeFromWidgetListDynamicProperty(QWidget * parentWidget,QWidget * widget,const char * name)107 static int removeFromWidgetListDynamicProperty(QWidget *parentWidget, QWidget *widget, const char *name)
108 {
109     QWidgetList list = qvariant_cast<QWidgetList>(parentWidget->property(name));
110     const int firstIndex = list.indexOf(widget);
111     if (firstIndex != -1) {
112         list.removeAll(widget);
113         parentWidget->setProperty(name, QVariant::fromValue(list));
114     }
115     return firstIndex;
116 }
117 
118 // ---- InsertWidgetCommand ----
InsertWidgetCommand(QDesignerFormWindowInterface * formWindow)119 InsertWidgetCommand::InsertWidgetCommand(QDesignerFormWindowInterface *formWindow)  :
120     QDesignerFormWindowCommand(QString(), formWindow),
121     m_insertMode(QDesignerLayoutDecorationExtension::InsertWidgetMode),
122     m_layoutHelper(nullptr),
123     m_widgetWasManaged(false)
124 {
125 }
126 
~InsertWidgetCommand()127 InsertWidgetCommand::~InsertWidgetCommand()
128 {
129     delete m_layoutHelper;
130 }
131 
init(QWidget * widget,bool already_in_form,int layoutRow,int layoutColumn)132 void InsertWidgetCommand::init(QWidget *widget, bool already_in_form, int layoutRow, int layoutColumn)
133 {
134     m_widget = widget;
135 
136     setText(QApplication::translate("Command", "Insert '%1'").arg(widget->objectName()));
137 
138     QWidget *parentWidget = m_widget->parentWidget();
139     QDesignerFormEditorInterface *core = formWindow()->core();
140     QDesignerLayoutDecorationExtension *deco = qt_extension<QDesignerLayoutDecorationExtension*>(core->extensionManager(), parentWidget);
141 
142     m_insertMode = deco ? deco->currentInsertMode() : QDesignerLayoutDecorationExtension::InsertWidgetMode;
143     if (layoutRow >= 0 && layoutColumn >= 0) {
144         m_cell.first = layoutRow;
145         m_cell.second = layoutColumn;
146     } else {
147         m_cell = deco ? deco->currentCell() : qMakePair(0, 0);
148     }
149     m_widgetWasManaged = already_in_form;
150 }
151 
recursiveUpdate(QWidget * w)152 static void recursiveUpdate(QWidget *w)
153 {
154     w->update();
155 
156     const QObjectList &l = w->children();
157     const QObjectList::const_iterator cend = l.end();
158     for ( QObjectList::const_iterator it = l.begin(); it != cend; ++it) {
159         if (QWidget *w = qobject_cast<QWidget*>(*it))
160             recursiveUpdate(w);
161     }
162 }
163 
redo()164 void InsertWidgetCommand::redo()
165 {
166     QWidget *parentWidget = m_widget->parentWidget();
167     Q_ASSERT(parentWidget);
168 
169     addToWidgetListDynamicProperty(parentWidget, m_widget, widgetOrderPropertyC);
170     addToWidgetListDynamicProperty(parentWidget, m_widget, zOrderPropertyC);
171 
172     QDesignerFormEditorInterface *core = formWindow()->core();
173     QDesignerLayoutDecorationExtension *deco = qt_extension<QDesignerLayoutDecorationExtension*>(core->extensionManager(), parentWidget);
174 
175     if (deco != nullptr) {
176         const LayoutInfo::Type type = LayoutInfo::layoutType(core, LayoutInfo::managedLayout(core, parentWidget));
177         m_layoutHelper = LayoutHelper::createLayoutHelper(type);
178         m_layoutHelper->pushState(core, parentWidget);
179         if (type == LayoutInfo::Grid) {
180             switch (m_insertMode) {
181                 case QDesignerLayoutDecorationExtension::InsertRowMode: {
182                     deco->insertRow(m_cell.first);
183                 } break;
184 
185                 case QDesignerLayoutDecorationExtension::InsertColumnMode: {
186                     deco->insertColumn(m_cell.second);
187                 } break;
188 
189                 default: break;
190             } // end switch
191         }
192         deco->insertWidget(m_widget, m_cell);
193     }
194 
195     if (!m_widgetWasManaged)
196         formWindow()->manageWidget(m_widget);
197     m_widget->show();
198     formWindow()->emitSelectionChanged();
199 
200     if (parentWidget && parentWidget->layout()) {
201         recursiveUpdate(parentWidget);
202         parentWidget->layout()->invalidate();
203     }
204 
205     refreshBuddyLabels();
206 }
207 
undo()208 void InsertWidgetCommand::undo()
209 {
210     QWidget *parentWidget = m_widget->parentWidget();
211 
212     QDesignerFormEditorInterface *core = formWindow()->core();
213     QDesignerLayoutDecorationExtension *deco = qt_extension<QDesignerLayoutDecorationExtension*>(core->extensionManager(), parentWidget);
214 
215     if (deco) {
216         deco->removeWidget(m_widget);
217         m_layoutHelper->popState(core, parentWidget);
218     }
219 
220     if (!m_widgetWasManaged) {
221         formWindow()->unmanageWidget(m_widget);
222         m_widget->hide();
223     }
224 
225     removeFromWidgetListDynamicProperty(parentWidget, m_widget, widgetOrderPropertyC);
226     removeFromWidgetListDynamicProperty(parentWidget, m_widget, zOrderPropertyC);
227 
228     formWindow()->emitSelectionChanged();
229 
230     refreshBuddyLabels();
231 }
232 
refreshBuddyLabels()233 void InsertWidgetCommand::refreshBuddyLabels()
234 {
235     const auto label_list = formWindow()->findChildren<QLabel*>();
236     if (label_list.isEmpty())
237         return;
238 
239     const QString buddyProperty = QStringLiteral("buddy");
240     const QByteArray objectNameU8 = m_widget->objectName().toUtf8();
241     // Re-set the buddy (The sheet locates the object by name and sets it)
242     for (QLabel *label : label_list) {
243         if (QDesignerPropertySheetExtension* sheet = propertySheet(label)) {
244             const int idx = sheet->indexOf(buddyProperty);
245             if (idx != -1) {
246                 const QVariant value = sheet->property(idx);
247                 if (value.toByteArray() == objectNameU8)
248                     sheet->setProperty(idx, value);
249             }
250         }
251     }
252 }
253 
254 // ---- ChangeZOrderCommand ----
ChangeZOrderCommand(QDesignerFormWindowInterface * formWindow)255 ChangeZOrderCommand::ChangeZOrderCommand(QDesignerFormWindowInterface *formWindow)
256     : QDesignerFormWindowCommand(QString(), formWindow)
257 {
258 }
259 
init(QWidget * widget)260 void ChangeZOrderCommand::init(QWidget *widget)
261 {
262     Q_ASSERT(widget);
263 
264     m_widget = widget;
265 
266     setText(QApplication::translate("Command", "Change Z-order of '%1'").arg(widget->objectName()));
267 
268     m_oldParentZOrder = qvariant_cast<QWidgetList>(widget->parentWidget()->property("_q_zOrder"));
269     const int index = m_oldParentZOrder.indexOf(m_widget);
270     if (index != -1 && index + 1 < m_oldParentZOrder.count())
271         m_oldPreceding = m_oldParentZOrder.at(index + 1);
272 }
273 
redo()274 void ChangeZOrderCommand::redo()
275 {
276     m_widget->parentWidget()->setProperty("_q_zOrder", QVariant::fromValue(reorderWidget(m_oldParentZOrder, m_widget)));
277 
278     reorder(m_widget);
279 }
280 
undo()281 void ChangeZOrderCommand::undo()
282 {
283     m_widget->parentWidget()->setProperty("_q_zOrder", QVariant::fromValue(m_oldParentZOrder));
284 
285     if (m_oldPreceding)
286         m_widget->stackUnder(m_oldPreceding);
287     else
288         m_widget->raise();
289 }
290 
291 // ---- RaiseWidgetCommand ----
RaiseWidgetCommand(QDesignerFormWindowInterface * formWindow)292 RaiseWidgetCommand::RaiseWidgetCommand(QDesignerFormWindowInterface *formWindow)
293     : ChangeZOrderCommand(formWindow)
294 {
295 }
296 
init(QWidget * widget)297 void RaiseWidgetCommand::init(QWidget *widget)
298 {
299     ChangeZOrderCommand::init(widget);
300     setText(QApplication::translate("Command", "Raise '%1'").arg(widget->objectName()));
301 }
302 
reorderWidget(const QWidgetList & list,QWidget * widget) const303 QWidgetList RaiseWidgetCommand::reorderWidget(const QWidgetList &list, QWidget *widget) const
304 {
305     QWidgetList l = list;
306     l.removeAll(widget);
307     l.append(widget);
308     return l;
309 }
310 
reorder(QWidget * widget) const311 void RaiseWidgetCommand::reorder(QWidget *widget) const
312 {
313     widget->raise();
314 }
315 
316 // ---- LowerWidgetCommand ----
LowerWidgetCommand(QDesignerFormWindowInterface * formWindow)317 LowerWidgetCommand::LowerWidgetCommand(QDesignerFormWindowInterface *formWindow)
318     : ChangeZOrderCommand(formWindow)
319 {
320 }
321 
reorderWidget(const QWidgetList & list,QWidget * widget) const322 QWidgetList LowerWidgetCommand::reorderWidget(const QWidgetList &list, QWidget *widget) const
323 {
324     QWidgetList l = list;
325     l.removeAll(widget);
326     l.prepend(widget);
327     return l;
328 }
329 
init(QWidget * widget)330 void LowerWidgetCommand::init(QWidget *widget)
331 {
332     ChangeZOrderCommand::init(widget);
333     setText(QApplication::translate("Command", "Lower '%1'").arg(widget->objectName()));
334 }
335 
reorder(QWidget * widget) const336 void LowerWidgetCommand::reorder(QWidget *widget) const
337 {
338     widget->lower();
339 }
340 
341 // ---- ManageWidgetCommandHelper
342 ManageWidgetCommandHelper::ManageWidgetCommandHelper() = default;
343 
init(const QDesignerFormWindowInterface * fw,QWidget * widget)344 void ManageWidgetCommandHelper::init(const QDesignerFormWindowInterface *fw, QWidget *widget)
345 {
346     m_widget = widget;
347     m_managedChildren.clear();
348 
349     const QWidgetList children = m_widget->findChildren<QWidget *>();
350     if (children.isEmpty())
351         return;
352 
353     m_managedChildren.reserve(children.size());
354     const QWidgetList::const_iterator lcend = children.constEnd();
355     for (QWidgetList::const_iterator it = children.constBegin(); it != lcend; ++it)
356         if (fw->isManaged(*it))
357             m_managedChildren.push_back(*it);
358 }
359 
init(QWidget * widget,const WidgetVector & managedChildren)360 void ManageWidgetCommandHelper::init(QWidget *widget, const WidgetVector &managedChildren)
361 {
362     m_widget = widget;
363     m_managedChildren = managedChildren;
364 }
365 
manage(QDesignerFormWindowInterface * fw)366 void ManageWidgetCommandHelper::manage(QDesignerFormWindowInterface *fw)
367 {
368     // Manage the managed children after parent
369     fw->manageWidget(m_widget);
370     if (!m_managedChildren.isEmpty()) {
371         const WidgetVector::const_iterator lcend = m_managedChildren.constEnd();
372         for (WidgetVector::const_iterator it = m_managedChildren.constBegin(); it != lcend; ++it)
373             fw->manageWidget(*it);
374     }
375 }
376 
unmanage(QDesignerFormWindowInterface * fw)377 void ManageWidgetCommandHelper::unmanage(QDesignerFormWindowInterface *fw)
378 {
379     // Unmanage the managed children first
380     if (!m_managedChildren.isEmpty()) {
381         const WidgetVector::const_iterator lcend = m_managedChildren.constEnd();
382         for (WidgetVector::const_iterator it = m_managedChildren.constBegin(); it != lcend; ++it)
383             fw->unmanageWidget(*it);
384     }
385     fw->unmanageWidget(m_widget);
386 }
387 
388 // ---- DeleteWidgetCommand ----
DeleteWidgetCommand(QDesignerFormWindowInterface * formWindow)389 DeleteWidgetCommand::DeleteWidgetCommand(QDesignerFormWindowInterface *formWindow) :
390     QDesignerFormWindowCommand(QString(), formWindow),
391     m_layoutType(LayoutInfo::NoLayout),
392     m_layoutHelper(nullptr),
393     m_flags(0),
394     m_splitterIndex(-1),
395     m_layoutSimplified(false),
396     m_formItem(nullptr),
397     m_tabOrderIndex(-1),
398     m_widgetOrderIndex(-1),
399     m_zOrderIndex(-1)
400 {
401 }
402 
~DeleteWidgetCommand()403 DeleteWidgetCommand::~DeleteWidgetCommand()
404 {
405     delete  m_layoutHelper;
406 }
407 
init(QWidget * widget,unsigned flags)408 void DeleteWidgetCommand::init(QWidget *widget, unsigned flags)
409 {
410     m_widget = widget;
411     m_parentWidget = widget->parentWidget();
412     m_geometry = widget->geometry();
413     m_flags = flags;
414     m_layoutType = LayoutInfo::NoLayout;
415     m_splitterIndex = -1;
416     bool isManaged; // Check for a managed layout
417     QLayout *layout;
418     m_layoutType = LayoutInfo::laidoutWidgetType(formWindow()->core(), m_widget, &isManaged, &layout);
419     if (!isManaged)
420         m_layoutType = LayoutInfo::NoLayout;
421     switch (m_layoutType) {
422     case LayoutInfo::HSplitter:
423     case LayoutInfo::VSplitter: {
424         QSplitter *splitter = qobject_cast<QSplitter *>(m_parentWidget);
425         Q_ASSERT(splitter);
426         m_splitterIndex = splitter->indexOf(widget);
427     }
428         break;
429     case LayoutInfo::NoLayout:
430         break;
431     default:
432         m_layoutHelper = LayoutHelper::createLayoutHelper(m_layoutType);
433         m_layoutPosition = m_layoutHelper->itemInfo(layout, m_widget);
434         break;
435     }
436 
437     m_formItem = formWindow()->core()->metaDataBase()->item(formWindow());
438     m_tabOrderIndex = m_formItem->tabOrder().indexOf(widget);
439 
440     // Build the list of managed children
441     m_manageHelper.init(formWindow(), m_widget);
442 
443     setText(QApplication::translate("Command", "Delete '%1'").arg(widget->objectName()));
444 }
445 
redo()446 void DeleteWidgetCommand::redo()
447 {
448     formWindow()->clearSelection();
449     QDesignerFormEditorInterface *core = formWindow()->core();
450 
451     if (QDesignerContainerExtension *c = qt_extension<QDesignerContainerExtension*>(core->extensionManager(), m_parentWidget)) {
452         const int count = c->count();
453         for (int i=0; i<count; ++i) {
454             if (c->widget(i) == m_widget) {
455                 c->remove(i);
456                 return;
457             }
458         }
459     }
460 
461     m_widgetOrderIndex = removeFromWidgetListDynamicProperty(m_parentWidget, m_widget, widgetOrderPropertyC);
462     m_zOrderIndex = removeFromWidgetListDynamicProperty(m_parentWidget, m_widget, zOrderPropertyC);
463 
464     if (QDesignerLayoutDecorationExtension *deco = qt_extension<QDesignerLayoutDecorationExtension*>(core->extensionManager(), m_parentWidget))
465         deco->removeWidget(m_widget);
466 
467     if (m_layoutHelper)
468         switch (m_layoutType) {
469         case LayoutInfo::NoLayout:
470         case LayoutInfo::HSplitter:
471         case LayoutInfo::VSplitter:
472             break;
473         default:
474             // Attempt to simplify grids if a row/column becomes empty
475             m_layoutSimplified = (m_flags & DoNotSimplifyLayout) ? false : m_layoutHelper->canSimplify(core, m_parentWidget, m_layoutPosition);
476             if (m_layoutSimplified) {
477                 m_layoutHelper->pushState(core, m_parentWidget);
478                 m_layoutHelper->simplify(core, m_parentWidget, m_layoutPosition);
479             }
480             break;
481         }
482 
483     if (!(m_flags & DoNotUnmanage))
484         m_manageHelper.unmanage(formWindow());
485 
486     m_widget->setParent(formWindow());
487     m_widget->hide();
488 
489     if (m_tabOrderIndex != -1) {
490         QWidgetList tab_order = m_formItem->tabOrder();
491         tab_order.removeAt(m_tabOrderIndex);
492         m_formItem->setTabOrder(tab_order);
493     }
494 }
495 
undo()496 void DeleteWidgetCommand::undo()
497 {
498     QDesignerFormEditorInterface *core = formWindow()->core();
499     formWindow()->clearSelection();
500 
501     m_widget->setParent(m_parentWidget);
502 
503     if (QDesignerContainerExtension *c = qt_extension<QDesignerContainerExtension*>(core->extensionManager(), m_parentWidget)) {
504         c->addWidget(m_widget);
505         return;
506     }
507 
508     addToWidgetListDynamicProperty(m_parentWidget, m_widget, widgetOrderPropertyC, m_widgetOrderIndex);
509     addToWidgetListDynamicProperty(m_parentWidget, m_widget, zOrderPropertyC, m_zOrderIndex);
510 
511     m_widget->setGeometry(m_geometry);
512 
513     if (!(m_flags & DoNotUnmanage))
514         m_manageHelper.manage(formWindow());
515     // ### set up alignment
516     switch (m_layoutType) {
517     case LayoutInfo::NoLayout:
518         break;
519     case LayoutInfo::HSplitter:
520     case LayoutInfo::VSplitter: {
521         QSplitter *splitter = qobject_cast<QSplitter *>(m_widget->parent());
522         Q_ASSERT(splitter);
523         splitter->insertWidget(m_splitterIndex, m_widget);
524     } break;
525     default: {
526         Q_ASSERT(m_layoutHelper);
527         if (m_layoutSimplified)
528             m_layoutHelper->popState(core, m_parentWidget);
529         QLayout *layout = LayoutInfo::managedLayout(core, m_parentWidget);
530         Q_ASSERT(m_layoutType == LayoutInfo::layoutType(core, layout));
531         m_layoutHelper->insertWidget(layout, m_layoutPosition, m_widget);
532     }
533         break;
534     }
535 
536     m_widget->show();
537 
538     if (m_tabOrderIndex != -1) {
539         QWidgetList tab_order = m_formItem->tabOrder();
540         tab_order.insert(m_tabOrderIndex, m_widget);
541         m_formItem->setTabOrder(tab_order);
542     }
543 }
544 
545 // ---- ReparentWidgetCommand ----
ReparentWidgetCommand(QDesignerFormWindowInterface * formWindow)546 ReparentWidgetCommand::ReparentWidgetCommand(QDesignerFormWindowInterface *formWindow)
547     : QDesignerFormWindowCommand(QString(), formWindow)
548 {
549 }
550 
init(QWidget * widget,QWidget * parentWidget)551 void ReparentWidgetCommand::init(QWidget *widget, QWidget *parentWidget)
552 {
553     Q_ASSERT(widget);
554 
555     m_widget = widget;
556     m_oldParentWidget = widget->parentWidget();
557     m_newParentWidget = parentWidget;
558 
559     m_oldPos = m_widget->pos();
560     m_newPos = m_newParentWidget->mapFromGlobal(m_oldParentWidget->mapToGlobal(m_oldPos));
561 
562     setText(QApplication::translate("Command", "Reparent '%1'").arg(widget->objectName()));
563 
564     m_oldParentList = qvariant_cast<QWidgetList>(m_oldParentWidget->property("_q_widgetOrder"));
565     m_oldParentZOrder = qvariant_cast<QWidgetList>(m_oldParentWidget->property("_q_zOrder"));
566 }
567 
redo()568 void ReparentWidgetCommand::redo()
569 {
570     m_widget->setParent(m_newParentWidget);
571     m_widget->move(m_newPos);
572 
573     QWidgetList oldList = m_oldParentList;
574     oldList.removeAll(m_widget);
575     m_oldParentWidget->setProperty("_q_widgetOrder", QVariant::fromValue(oldList));
576 
577     QWidgetList newList = qvariant_cast<QWidgetList>(m_newParentWidget->property("_q_widgetOrder"));
578     newList.append(m_widget);
579     m_newParentWidget->setProperty("_q_widgetOrder", QVariant::fromValue(newList));
580 
581     QWidgetList oldZOrder = m_oldParentZOrder;
582     oldZOrder.removeAll(m_widget);
583     m_oldParentWidget->setProperty("_q_zOrder", QVariant::fromValue(oldZOrder));
584 
585     QWidgetList newZOrder = qvariant_cast<QWidgetList>(m_newParentWidget->property("_q_zOrder"));
586     newZOrder.append(m_widget);
587     m_newParentWidget->setProperty("_q_zOrder", QVariant::fromValue(newZOrder));
588 
589     m_widget->show();
590     core()->objectInspector()->setFormWindow(formWindow());
591 }
592 
undo()593 void ReparentWidgetCommand::undo()
594 {
595     m_widget->setParent(m_oldParentWidget);
596     m_widget->move(m_oldPos);
597 
598     m_oldParentWidget->setProperty("_q_widgetOrder", QVariant::fromValue(m_oldParentList));
599 
600     QWidgetList newList = qvariant_cast<QWidgetList>(m_newParentWidget->property("_q_widgetOrder"));
601     newList.removeAll(m_widget);
602     m_newParentWidget->setProperty("_q_widgetOrder", QVariant::fromValue(newList));
603 
604     m_oldParentWidget->setProperty("_q_zOrder", QVariant::fromValue(m_oldParentZOrder));
605 
606     QWidgetList newZOrder = qvariant_cast<QWidgetList>(m_newParentWidget->property("_q_zOrder"));
607     newZOrder.removeAll(m_widget);
608     m_newParentWidget->setProperty("_q_zOrder", QVariant::fromValue(newZOrder));
609 
610     m_widget->show();
611     core()->objectInspector()->setFormWindow(formWindow());
612 }
613 
PromoteToCustomWidgetCommand(QDesignerFormWindowInterface * formWindow)614 PromoteToCustomWidgetCommand::PromoteToCustomWidgetCommand
615                                 (QDesignerFormWindowInterface *formWindow)
616     : QDesignerFormWindowCommand(QApplication::translate("Command", "Promote to custom widget"), formWindow)
617 {
618 }
619 
init(const WidgetPointerList & widgets,const QString & customClassName)620 void PromoteToCustomWidgetCommand::init(const WidgetPointerList &widgets,const QString &customClassName)
621 {
622     m_widgets = widgets;
623     m_customClassName = customClassName;
624 }
625 
redo()626 void PromoteToCustomWidgetCommand::redo()
627 {
628     for (QWidget *w : qAsConst(m_widgets)) {
629         if (w)
630             promoteWidget(core(), w, m_customClassName);
631     }
632     updateSelection();
633 }
634 
updateSelection()635 void PromoteToCustomWidgetCommand::updateSelection()
636 {
637     // Update class names in ObjectInspector, PropertyEditor
638     QDesignerFormWindowInterface *fw = formWindow();
639     QDesignerFormEditorInterface *core = fw->core();
640     core->objectInspector()->setFormWindow(fw);
641     if (QObject *o = core->propertyEditor()->object())
642         core->propertyEditor()->setObject(o);
643 }
644 
undo()645 void PromoteToCustomWidgetCommand::undo()
646 {
647     for (QWidget *w : qAsConst(m_widgets)) {
648         if (w)
649             demoteWidget(core(), w);
650     }
651     updateSelection();
652 }
653 
654 // ---- DemoteFromCustomWidgetCommand ----
655 
DemoteFromCustomWidgetCommand(QDesignerFormWindowInterface * formWindow)656 DemoteFromCustomWidgetCommand::DemoteFromCustomWidgetCommand
657                                     (QDesignerFormWindowInterface *formWindow) :
658     QDesignerFormWindowCommand(QApplication::translate("Command", "Demote from custom widget"), formWindow),
659     m_promote_cmd(formWindow)
660 {
661 }
662 
init(const WidgetList & promoted)663 void DemoteFromCustomWidgetCommand::init(const WidgetList &promoted)
664 {
665     m_promote_cmd.init(promoted, promotedCustomClassName(core(), promoted.constFirst()));
666 }
667 
redo()668 void DemoteFromCustomWidgetCommand::redo()
669 {
670     m_promote_cmd.undo();
671 }
672 
undo()673 void DemoteFromCustomWidgetCommand::undo()
674 {
675     m_promote_cmd.redo();
676 }
677 
678 // ----------  CursorSelectionState
679 CursorSelectionState::CursorSelectionState() = default;
680 
save(const QDesignerFormWindowInterface * formWindow)681 void CursorSelectionState::save(const QDesignerFormWindowInterface *formWindow)
682 {
683     const QDesignerFormWindowCursorInterface *cursor = formWindow->cursor();
684     m_selection.clear();
685     m_current = cursor->current();
686     if (cursor->hasSelection()) {
687         const int count = cursor->selectedWidgetCount();
688         for(int i = 0; i < count; i++)
689             m_selection.push_back(cursor->selectedWidget(i));
690     }
691 }
692 
restore(QDesignerFormWindowInterface * formWindow) const693 void CursorSelectionState::restore(QDesignerFormWindowInterface *formWindow) const
694 {
695     if (m_selection.isEmpty()) {
696         formWindow->clearSelection(true);
697     } else {
698         // Select current as last
699         formWindow->clearSelection(false);
700         const WidgetPointerList::const_iterator cend = m_selection.constEnd();
701         for (WidgetPointerList::const_iterator it = m_selection.constBegin(); it != cend; ++it)
702             if (QWidget *w = *it)
703                 if (w != m_current)
704                     formWindow->selectWidget(*it, true);
705         if (m_current)
706             formWindow->selectWidget(m_current, true);
707     }
708 }
709 
710 // ---- LayoutCommand ----
711 
LayoutCommand(QDesignerFormWindowInterface * formWindow)712 LayoutCommand::LayoutCommand(QDesignerFormWindowInterface *formWindow) :
713     QDesignerFormWindowCommand(QString(), formWindow),
714     m_setup(false)
715 {
716 }
717 
~LayoutCommand()718 LayoutCommand::~LayoutCommand()
719 {
720     delete m_layout;
721 }
722 
init(QWidget * parentWidget,const QWidgetList & widgets,LayoutInfo::Type layoutType,QWidget * layoutBase,bool reparentLayoutWidget)723 void LayoutCommand::init(QWidget *parentWidget, const QWidgetList &widgets,
724                          LayoutInfo::Type layoutType, QWidget *layoutBase,
725                          bool reparentLayoutWidget)
726 {
727     m_parentWidget = parentWidget;
728     m_widgets = widgets;
729     formWindow()->simplifySelection(&m_widgets);
730     m_layout = Layout::createLayout(widgets, parentWidget, formWindow(), layoutBase, layoutType);
731     m_layout->setReparentLayoutWidget(reparentLayoutWidget);
732 
733     switch (layoutType) {
734     case LayoutInfo::Grid:
735         setText(QApplication::translate("Command", "Lay out using grid"));
736         break;
737     case LayoutInfo::VBox:
738         setText(QApplication::translate("Command", "Lay out vertically"));
739         break;
740     case LayoutInfo::HBox:
741         setText(QApplication::translate("Command", "Lay out horizontally"));
742         break;
743     default:
744         break;
745     }
746     // Delayed setup to avoid confusion in case we are chained
747     // with a BreakLayout in a morph layout macro
748     m_setup = false;
749 }
750 
redo()751 void LayoutCommand::redo()
752 {
753     if (!m_setup) {
754         m_layout->setup();
755         m_cursorSelectionState.save(formWindow());
756         m_setup = true;
757     }
758     m_layout->doLayout();
759     core()->objectInspector()->setFormWindow(formWindow());
760 }
761 
undo()762 void LayoutCommand::undo()
763 {
764     QDesignerFormEditorInterface *core = formWindow()->core();
765 
766     QWidget *lb = m_layout->layoutBaseWidget();
767     QDesignerLayoutDecorationExtension *deco = qt_extension<QDesignerLayoutDecorationExtension*>(core->extensionManager(), lb);
768     m_layout->undoLayout();
769     delete deco; // release the extension
770 
771     // ### generalize (put in function)
772     if (!m_layoutBase && lb != nullptr && !(qobject_cast<QLayoutWidget*>(lb) || qobject_cast<QSplitter*>(lb))) {
773         core->metaDataBase()->add(lb);
774         lb->show();
775     }
776     m_cursorSelectionState.restore(formWindow());
777     core->objectInspector()->setFormWindow(formWindow());
778 }
779 
780 // ---- BreakLayoutCommand ----
BreakLayoutCommand(QDesignerFormWindowInterface * formWindow)781 BreakLayoutCommand::BreakLayoutCommand(QDesignerFormWindowInterface *formWindow) :
782     QDesignerFormWindowCommand(QApplication::translate("Command", "Break layout"), formWindow),
783     m_layoutHelper(nullptr),
784     m_properties(nullptr),
785     m_propertyMask(0)
786 {
787 }
788 
~BreakLayoutCommand()789 BreakLayoutCommand::~BreakLayoutCommand()
790 {
791     delete m_layoutHelper;
792     delete m_layout;
793     delete m_properties;
794 }
795 
layoutProperties() const796 const LayoutProperties *BreakLayoutCommand::layoutProperties() const
797 {
798     return m_properties;
799 }
800 
propertyMask() const801 int BreakLayoutCommand::propertyMask() const
802 {
803     return m_propertyMask;
804 }
805 
init(const QWidgetList & widgets,QWidget * layoutBase,bool reparentLayoutWidget)806 void BreakLayoutCommand::init(const QWidgetList &widgets, QWidget *layoutBase, bool reparentLayoutWidget)
807 {
808     enum Type { SplitterLayout, LayoutHasMarginSpacing, LayoutHasState };
809 
810     const QDesignerFormEditorInterface *core = formWindow()->core();
811     m_widgets = widgets;
812     m_layoutBase = core->widgetFactory()->containerOfWidget(layoutBase);
813     QLayout *layoutToBeBroken;
814     const LayoutInfo::Type layoutType = LayoutInfo::managedLayoutType(core, m_layoutBase, &layoutToBeBroken);
815     m_layout = Layout::createLayout(widgets, m_layoutBase, formWindow(), layoutBase, layoutType);
816     m_layout->setReparentLayoutWidget(reparentLayoutWidget);
817 
818     Type type = LayoutHasState;
819     switch (layoutType) {
820     case LayoutInfo::NoLayout:
821     case LayoutInfo::HSplitter:
822     case LayoutInfo::VSplitter:
823         type = SplitterLayout;
824         break;
825     case LayoutInfo::HBox:
826     case LayoutInfo::VBox: // Margin/spacing need to be saved
827         type = LayoutHasMarginSpacing;
828         break;
829     default: // Margin/spacing need to be saved + has a state (empty rows/columns of a grid)
830         type = LayoutHasState;
831         break;
832     }
833     Q_ASSERT(m_layout != nullptr);
834     m_layout->sort();
835 
836 
837     if (type >= LayoutHasMarginSpacing) {
838         m_properties = new LayoutProperties;
839         m_propertyMask = m_properties->fromPropertySheet(core, layoutToBeBroken, LayoutProperties::AllProperties);
840     }
841     if (type >= LayoutHasState)
842          m_layoutHelper = LayoutHelper::createLayoutHelper(layoutType);
843     m_cursorSelectionState.save(formWindow());
844 }
845 
redo()846 void BreakLayoutCommand::redo()
847 {
848     if (!m_layout)
849         return;
850 
851     QDesignerFormEditorInterface *core = formWindow()->core();
852     QWidget *lb = m_layout->layoutBaseWidget();
853     QDesignerLayoutDecorationExtension *deco = qt_extension<QDesignerLayoutDecorationExtension*>(core->extensionManager(), lb);
854     formWindow()->clearSelection(false);
855     if (m_layoutHelper)
856         m_layoutHelper->pushState(core, m_layoutBase);
857     m_layout->breakLayout();
858     delete deco; // release the extension
859 
860     for (QWidget *widget : qAsConst(m_widgets)) {
861         widget->resize(widget->size().expandedTo(QSize(16, 16)));
862     }
863     // Update unless we are in an intermediate state of morphing layout
864     // in which a QLayoutWidget will have no layout at all.
865     if (m_layout->reparentLayoutWidget())
866         core->objectInspector()->setFormWindow(formWindow());
867 }
868 
undo()869 void BreakLayoutCommand::undo()
870 {
871     if (!m_layout)
872         return;
873 
874     formWindow()->clearSelection(false);
875     m_layout->doLayout();
876     if (m_layoutHelper)
877         m_layoutHelper->popState(formWindow()->core(), m_layoutBase);
878 
879     QLayout *layoutToRestored = LayoutInfo::managedLayout(formWindow()->core(), m_layoutBase);
880     if (m_properties && m_layoutBase && layoutToRestored)
881         m_properties->toPropertySheet(formWindow()->core(), layoutToRestored, m_propertyMask);
882      m_cursorSelectionState.restore(formWindow());
883     core()->objectInspector()->setFormWindow(formWindow());
884 }
885 // ---- SimplifyLayoutCommand
SimplifyLayoutCommand(QDesignerFormWindowInterface * formWindow)886 SimplifyLayoutCommand::SimplifyLayoutCommand(QDesignerFormWindowInterface *formWindow) :
887     QDesignerFormWindowCommand(QApplication::translate("Command", "Simplify Grid Layout"), formWindow),
888     m_area(0, 0, 32767, 32767),
889     m_layoutBase(nullptr),
890     m_layoutHelper(nullptr),
891     m_layoutSimplified(false)
892 {
893 }
894 
~SimplifyLayoutCommand()895 SimplifyLayoutCommand::~SimplifyLayoutCommand()
896 {
897     delete m_layoutHelper;
898 }
899 
canSimplify(QDesignerFormEditorInterface * core,const QWidget * w,int * layoutType)900 bool SimplifyLayoutCommand::canSimplify(QDesignerFormEditorInterface *core, const QWidget *w, int *layoutType)
901 {
902     if (!w)
903         return false;
904     QLayout *layout;
905     const LayoutInfo::Type type = LayoutInfo::managedLayoutType(core, w, &layout);
906     if (layoutType)
907         *layoutType = type;
908     if (!layout)
909         return false;
910     switch (type) { // Known negatives
911     case LayoutInfo::NoLayout:
912     case LayoutInfo::UnknownLayout:
913     case LayoutInfo::HSplitter:
914     case LayoutInfo::VSplitter:
915     case LayoutInfo::HBox:
916     case LayoutInfo::VBox:
917         return false;
918     default:
919         break;
920     }
921     switch (type) {
922     case LayoutInfo::Grid:
923         return QLayoutSupport::canSimplifyQuickCheck(qobject_cast<QGridLayout*>(layout));
924     case LayoutInfo::Form:
925         return QLayoutSupport::canSimplifyQuickCheck(qobject_cast<const QFormLayout*>(layout));
926     default:
927         break;
928     }
929     return false;
930 }
931 
init(QWidget * layoutBase)932 bool SimplifyLayoutCommand::init(QWidget *layoutBase)
933 {
934     QDesignerFormEditorInterface *core = formWindow()->core();
935     m_layoutSimplified = false;
936     int type;
937     if (canSimplify(core, layoutBase, &type)) {
938         m_layoutBase = layoutBase;
939         m_layoutHelper = LayoutHelper::createLayoutHelper(type);
940         m_layoutSimplified = m_layoutHelper->canSimplify(core, layoutBase, m_area);
941     }
942     return m_layoutSimplified;
943 }
944 
redo()945 void SimplifyLayoutCommand::redo()
946 {
947     const QDesignerFormEditorInterface *core = formWindow()->core();
948     if (m_layoutSimplified) {
949         m_layoutHelper->pushState(core, m_layoutBase);
950         m_layoutHelper->simplify(core, m_layoutBase, m_area);
951     }
952 }
undo()953 void SimplifyLayoutCommand::undo()
954 {
955     if (m_layoutSimplified)
956          m_layoutHelper->popState(formWindow()->core(), m_layoutBase);
957 }
958 
959 // ---- ToolBoxCommand ----
ToolBoxCommand(QDesignerFormWindowInterface * formWindow)960 ToolBoxCommand::ToolBoxCommand(QDesignerFormWindowInterface *formWindow)  :
961     QDesignerFormWindowCommand(QString(), formWindow),
962     m_index(-1)
963 {
964 }
965 
966 ToolBoxCommand::~ToolBoxCommand() = default;
967 
init(QToolBox * toolBox)968 void ToolBoxCommand::init(QToolBox *toolBox)
969 {
970     m_toolBox = toolBox;
971     m_index = m_toolBox->currentIndex();
972     m_widget = m_toolBox->widget(m_index);
973     m_itemText = m_toolBox->itemText(m_index);
974     m_itemIcon = m_toolBox->itemIcon(m_index);
975 }
976 
removePage()977 void ToolBoxCommand::removePage()
978 {
979     m_toolBox->removeItem(m_index);
980 
981     m_widget->hide();
982     m_widget->setParent(formWindow());
983     formWindow()->clearSelection();
984     formWindow()->selectWidget(m_toolBox, true);
985 
986 }
987 
addPage()988 void ToolBoxCommand::addPage()
989 {
990     m_widget->setParent(m_toolBox);
991     m_toolBox->insertItem(m_index, m_widget, m_itemIcon, m_itemText);
992     m_toolBox->setCurrentIndex(m_index);
993 
994     QDesignerPropertySheetExtension *sheet = qt_extension<QDesignerPropertySheetExtension*>(formWindow()->core()->extensionManager(), m_toolBox);
995     if (sheet) {
996         qdesigner_internal::PropertySheetStringValue itemText(m_itemText);
997         sheet->setProperty(sheet->indexOf(QStringLiteral("currentItemText")), QVariant::fromValue(itemText));
998     }
999 
1000     m_widget->show();
1001     formWindow()->clearSelection();
1002     formWindow()->selectWidget(m_toolBox, true);
1003 }
1004 
1005 // ---- MoveToolBoxPageCommand ----
MoveToolBoxPageCommand(QDesignerFormWindowInterface * formWindow)1006 MoveToolBoxPageCommand::MoveToolBoxPageCommand(QDesignerFormWindowInterface *formWindow) :
1007     ToolBoxCommand(formWindow),
1008     m_newIndex(-1),
1009     m_oldIndex(-1)
1010 {
1011 }
1012 
1013 MoveToolBoxPageCommand::~MoveToolBoxPageCommand() = default;
1014 
init(QToolBox * toolBox,QWidget * page,int newIndex)1015 void MoveToolBoxPageCommand::init(QToolBox *toolBox, QWidget *page, int newIndex)
1016 {
1017     ToolBoxCommand::init(toolBox);
1018     setText(QApplication::translate("Command", "Move Page"));
1019 
1020     m_widget = page;
1021     m_oldIndex = m_toolBox->indexOf(m_widget);
1022     m_itemText = m_toolBox->itemText(m_oldIndex);
1023     m_itemIcon = m_toolBox->itemIcon(m_oldIndex);
1024     m_newIndex = newIndex;
1025 }
1026 
redo()1027 void MoveToolBoxPageCommand::redo()
1028 {
1029     m_toolBox->removeItem(m_oldIndex);
1030     m_toolBox->insertItem(m_newIndex, m_widget, m_itemIcon, m_itemText);
1031 }
1032 
undo()1033 void MoveToolBoxPageCommand::undo()
1034 {
1035     m_toolBox->removeItem(m_newIndex);
1036     m_toolBox->insertItem(m_oldIndex, m_widget, m_itemIcon, m_itemText);
1037 }
1038 
1039 // ---- DeleteToolBoxPageCommand ----
DeleteToolBoxPageCommand(QDesignerFormWindowInterface * formWindow)1040 DeleteToolBoxPageCommand::DeleteToolBoxPageCommand(QDesignerFormWindowInterface *formWindow)
1041     : ToolBoxCommand(formWindow)
1042 {
1043 }
1044 
1045 DeleteToolBoxPageCommand::~DeleteToolBoxPageCommand() = default;
1046 
init(QToolBox * toolBox)1047 void DeleteToolBoxPageCommand::init(QToolBox *toolBox)
1048 {
1049     ToolBoxCommand::init(toolBox);
1050     setText(QApplication::translate("Command", "Delete Page"));
1051 }
1052 
redo()1053 void DeleteToolBoxPageCommand::redo()
1054 {
1055     removePage();
1056     cheapUpdate();
1057 }
1058 
undo()1059 void DeleteToolBoxPageCommand::undo()
1060 {
1061     addPage();
1062     cheapUpdate();
1063 }
1064 
1065 // ---- AddToolBoxPageCommand ----
AddToolBoxPageCommand(QDesignerFormWindowInterface * formWindow)1066 AddToolBoxPageCommand::AddToolBoxPageCommand(QDesignerFormWindowInterface *formWindow)
1067     : ToolBoxCommand(formWindow)
1068 {
1069 }
1070 
1071 AddToolBoxPageCommand::~AddToolBoxPageCommand() = default;
1072 
init(QToolBox * toolBox)1073 void AddToolBoxPageCommand::init(QToolBox *toolBox)
1074 {
1075     init(toolBox, InsertBefore);
1076 }
1077 
init(QToolBox * toolBox,InsertionMode mode)1078 void AddToolBoxPageCommand::init(QToolBox *toolBox, InsertionMode mode)
1079 {
1080     m_toolBox = toolBox;
1081 
1082     m_index = m_toolBox->currentIndex();
1083     if (mode == InsertAfter)
1084         m_index++;
1085     m_widget = new QDesignerWidget(formWindow(), m_toolBox);
1086     m_itemText = QApplication::translate("Command", "Page");
1087     m_itemIcon = QIcon();
1088     m_widget->setObjectName(QStringLiteral("page"));
1089     formWindow()->ensureUniqueObjectName(m_widget);
1090 
1091     setText(QApplication::translate("Command", "Insert Page"));
1092 
1093     QDesignerFormEditorInterface *core = formWindow()->core();
1094     core->metaDataBase()->add(m_widget);
1095 }
1096 
redo()1097 void AddToolBoxPageCommand::redo()
1098 {
1099     addPage();
1100     cheapUpdate();
1101 }
1102 
undo()1103 void AddToolBoxPageCommand::undo()
1104 {
1105     removePage();
1106     cheapUpdate();
1107 }
1108 
1109 // ---- TabWidgetCommand ----
TabWidgetCommand(QDesignerFormWindowInterface * formWindow)1110 TabWidgetCommand::TabWidgetCommand(QDesignerFormWindowInterface *formWindow) :
1111     QDesignerFormWindowCommand(QString(), formWindow),
1112     m_index(-1)
1113 {
1114 }
1115 
1116 TabWidgetCommand::~TabWidgetCommand() = default;
1117 
init(QTabWidget * tabWidget)1118 void TabWidgetCommand::init(QTabWidget *tabWidget)
1119 {
1120     m_tabWidget = tabWidget;
1121     m_index = m_tabWidget->currentIndex();
1122     m_widget = m_tabWidget->widget(m_index);
1123     m_itemText = m_tabWidget->tabText(m_index);
1124     m_itemIcon = m_tabWidget->tabIcon(m_index);
1125 }
1126 
removePage()1127 void TabWidgetCommand::removePage()
1128 {
1129     m_tabWidget->removeTab(m_index);
1130 
1131     m_widget->hide();
1132     m_widget->setParent(formWindow());
1133     m_tabWidget->setCurrentIndex(qMin(m_index, m_tabWidget->count()));
1134 
1135     formWindow()->clearSelection();
1136     formWindow()->selectWidget(m_tabWidget, true);
1137 }
1138 
addPage()1139 void TabWidgetCommand::addPage()
1140 {
1141     m_widget->setParent(nullptr);
1142     m_tabWidget->insertTab(m_index, m_widget, m_itemIcon, m_itemText);
1143     m_widget->show();
1144     m_tabWidget->setCurrentIndex(m_index);
1145 
1146     QDesignerPropertySheetExtension *sheet = qt_extension<QDesignerPropertySheetExtension*>(formWindow()->core()->extensionManager(), m_tabWidget);
1147     if (sheet) {
1148         qdesigner_internal::PropertySheetStringValue itemText(m_itemText);
1149         sheet->setProperty(sheet->indexOf(QStringLiteral("currentTabText")), QVariant::fromValue(itemText));
1150     }
1151 
1152     formWindow()->clearSelection();
1153     formWindow()->selectWidget(m_tabWidget, true);
1154 }
1155 
1156 // ---- DeleteTabPageCommand ----
DeleteTabPageCommand(QDesignerFormWindowInterface * formWindow)1157 DeleteTabPageCommand::DeleteTabPageCommand(QDesignerFormWindowInterface *formWindow)
1158     : TabWidgetCommand(formWindow)
1159 {
1160 }
1161 
1162 DeleteTabPageCommand::~DeleteTabPageCommand() = default;
1163 
init(QTabWidget * tabWidget)1164 void DeleteTabPageCommand::init(QTabWidget *tabWidget)
1165 {
1166     TabWidgetCommand::init(tabWidget);
1167     setText(QApplication::translate("Command", "Delete Page"));
1168 }
1169 
redo()1170 void DeleteTabPageCommand::redo()
1171 {
1172     removePage();
1173     cheapUpdate();
1174 }
1175 
undo()1176 void DeleteTabPageCommand::undo()
1177 {
1178     addPage();
1179     cheapUpdate();
1180 }
1181 
1182 // ---- AddTabPageCommand ----
AddTabPageCommand(QDesignerFormWindowInterface * formWindow)1183 AddTabPageCommand::AddTabPageCommand(QDesignerFormWindowInterface *formWindow)
1184     : TabWidgetCommand(formWindow)
1185 {
1186 }
1187 
1188 AddTabPageCommand::~AddTabPageCommand() = default;
1189 
init(QTabWidget * tabWidget)1190 void AddTabPageCommand::init(QTabWidget *tabWidget)
1191 {
1192     init(tabWidget, InsertBefore);
1193 }
1194 
init(QTabWidget * tabWidget,InsertionMode mode)1195 void AddTabPageCommand::init(QTabWidget *tabWidget, InsertionMode mode)
1196 {
1197     m_tabWidget = tabWidget;
1198 
1199     m_index = m_tabWidget->currentIndex();
1200     if (mode == InsertAfter)
1201         m_index++;
1202     m_widget = new QDesignerWidget(formWindow(), m_tabWidget);
1203     m_itemText = QApplication::translate("Command", "Page");
1204     m_itemIcon = QIcon();
1205     m_widget->setObjectName(QStringLiteral("tab"));
1206     formWindow()->ensureUniqueObjectName(m_widget);
1207 
1208     setText(QApplication::translate("Command", "Insert Page"));
1209 
1210     QDesignerFormEditorInterface *core = formWindow()->core();
1211     core->metaDataBase()->add(m_widget);
1212 }
1213 
redo()1214 void AddTabPageCommand::redo()
1215 {
1216     addPage();
1217     cheapUpdate();
1218 }
1219 
undo()1220 void AddTabPageCommand::undo()
1221 {
1222     removePage();
1223     cheapUpdate();
1224 }
1225 
1226 // ---- MoveTabPageCommand ----
MoveTabPageCommand(QDesignerFormWindowInterface * formWindow)1227 MoveTabPageCommand::MoveTabPageCommand(QDesignerFormWindowInterface *formWindow) :
1228     TabWidgetCommand(formWindow),
1229     m_newIndex(-1),
1230     m_oldIndex(-1)
1231 {
1232 }
1233 
1234 MoveTabPageCommand::~MoveTabPageCommand() = default;
1235 
init(QTabWidget * tabWidget,QWidget * page,const QIcon & icon,const QString & label,int index,int newIndex)1236 void MoveTabPageCommand::init(QTabWidget *tabWidget, QWidget *page,
1237                       const QIcon &icon, const QString &label,
1238                       int index, int newIndex)
1239 {
1240     TabWidgetCommand::init(tabWidget);
1241     setText(QApplication::translate("Command", "Move Page"));
1242 
1243     m_page = page;
1244     m_newIndex = newIndex;
1245     m_oldIndex = index;
1246     m_label = label;
1247     m_icon = icon;
1248 }
1249 
redo()1250 void MoveTabPageCommand::redo()
1251 {
1252     m_tabWidget->removeTab(m_oldIndex);
1253     m_tabWidget->insertTab(m_newIndex, m_page, m_icon, m_label);
1254     m_tabWidget->setCurrentIndex(m_newIndex);
1255 }
1256 
undo()1257 void MoveTabPageCommand::undo()
1258 {
1259     m_tabWidget->removeTab(m_newIndex);
1260     m_tabWidget->insertTab(m_oldIndex, m_page, m_icon, m_label);
1261     m_tabWidget->setCurrentIndex(m_oldIndex);
1262 }
1263 
1264 // ---- StackedWidgetCommand ----
StackedWidgetCommand(QDesignerFormWindowInterface * formWindow)1265 StackedWidgetCommand::StackedWidgetCommand(QDesignerFormWindowInterface *formWindow) :
1266     QDesignerFormWindowCommand(QString(), formWindow),
1267     m_index(-1)
1268 {
1269 }
1270 
1271 StackedWidgetCommand::~StackedWidgetCommand() = default;
1272 
init(QStackedWidget * stackedWidget)1273 void StackedWidgetCommand::init(QStackedWidget *stackedWidget)
1274 {
1275     m_stackedWidget = stackedWidget;
1276     m_index = m_stackedWidget->currentIndex();
1277     m_widget = m_stackedWidget->widget(m_index);
1278 }
1279 
removePage()1280 void StackedWidgetCommand::removePage()
1281 {
1282     m_stackedWidget->removeWidget(m_stackedWidget->widget(m_index));
1283 
1284     m_widget->hide();
1285     m_widget->setParent(formWindow());
1286 
1287     formWindow()->clearSelection();
1288     formWindow()->selectWidget(m_stackedWidget, true);
1289 }
1290 
addPage()1291 void StackedWidgetCommand::addPage()
1292 {
1293     m_stackedWidget->insertWidget(m_index, m_widget);
1294 
1295     m_widget->show();
1296     m_stackedWidget->setCurrentIndex(m_index);
1297 
1298     formWindow()->clearSelection();
1299     formWindow()->selectWidget(m_stackedWidget, true);
1300 }
1301 
1302 // ---- MoveStackedWidgetCommand ----
MoveStackedWidgetCommand(QDesignerFormWindowInterface * formWindow)1303 MoveStackedWidgetCommand::MoveStackedWidgetCommand(QDesignerFormWindowInterface *formWindow) :
1304     StackedWidgetCommand(formWindow),
1305     m_newIndex(-1),
1306     m_oldIndex(-1)
1307 {
1308 }
1309 
1310 MoveStackedWidgetCommand::~MoveStackedWidgetCommand() = default;
1311 
init(QStackedWidget * stackedWidget,QWidget * page,int newIndex)1312 void MoveStackedWidgetCommand::init(QStackedWidget *stackedWidget, QWidget *page, int newIndex)
1313 {
1314     StackedWidgetCommand::init(stackedWidget);
1315     setText(QApplication::translate("Command", "Move Page"));
1316 
1317     m_widget = page;
1318     m_newIndex = newIndex;
1319     m_oldIndex = m_stackedWidget->indexOf(m_widget);
1320 }
1321 
redo()1322 void MoveStackedWidgetCommand::redo()
1323 {
1324     m_stackedWidget->removeWidget(m_widget);
1325     m_stackedWidget->insertWidget(m_newIndex, m_widget);
1326 }
1327 
undo()1328 void MoveStackedWidgetCommand::undo()
1329 {
1330     m_stackedWidget->removeWidget(m_widget);
1331     m_stackedWidget->insertWidget(m_oldIndex, m_widget);
1332 }
1333 
1334 // ---- DeleteStackedWidgetPageCommand ----
DeleteStackedWidgetPageCommand(QDesignerFormWindowInterface * formWindow)1335 DeleteStackedWidgetPageCommand::DeleteStackedWidgetPageCommand(QDesignerFormWindowInterface *formWindow)
1336     : StackedWidgetCommand(formWindow)
1337 {
1338 }
1339 
1340 DeleteStackedWidgetPageCommand::~DeleteStackedWidgetPageCommand() = default;
1341 
init(QStackedWidget * stackedWidget)1342 void DeleteStackedWidgetPageCommand::init(QStackedWidget *stackedWidget)
1343 {
1344     StackedWidgetCommand::init(stackedWidget);
1345     setText(QApplication::translate("Command", "Delete Page"));
1346 }
1347 
redo()1348 void DeleteStackedWidgetPageCommand::redo()
1349 {
1350     removePage();
1351     cheapUpdate();
1352 }
1353 
undo()1354 void DeleteStackedWidgetPageCommand::undo()
1355 {
1356     addPage();
1357     cheapUpdate();
1358 }
1359 
1360 // ---- AddStackedWidgetPageCommand ----
AddStackedWidgetPageCommand(QDesignerFormWindowInterface * formWindow)1361 AddStackedWidgetPageCommand::AddStackedWidgetPageCommand(QDesignerFormWindowInterface *formWindow)
1362     : StackedWidgetCommand(formWindow)
1363 {
1364 }
1365 
1366 AddStackedWidgetPageCommand::~AddStackedWidgetPageCommand() = default;
1367 
init(QStackedWidget * stackedWidget)1368 void AddStackedWidgetPageCommand::init(QStackedWidget *stackedWidget)
1369 {
1370     init(stackedWidget, InsertBefore);
1371 }
1372 
init(QStackedWidget * stackedWidget,InsertionMode mode)1373 void AddStackedWidgetPageCommand::init(QStackedWidget *stackedWidget, InsertionMode mode)
1374 {
1375     m_stackedWidget = stackedWidget;
1376 
1377     m_index = m_stackedWidget->currentIndex();
1378     if (mode == InsertAfter)
1379         m_index++;
1380     m_widget = new QDesignerWidget(formWindow(), m_stackedWidget);
1381     m_widget->setObjectName(QStringLiteral("page"));
1382     formWindow()->ensureUniqueObjectName(m_widget);
1383 
1384     setText(QApplication::translate("Command", "Insert Page"));
1385 
1386     QDesignerFormEditorInterface *core = formWindow()->core();
1387     core->metaDataBase()->add(m_widget);
1388 }
1389 
redo()1390 void AddStackedWidgetPageCommand::redo()
1391 {
1392     addPage();
1393     cheapUpdate();
1394 }
1395 
undo()1396 void AddStackedWidgetPageCommand::undo()
1397 {
1398     removePage();
1399     cheapUpdate();
1400 }
1401 
1402 // ---- TabOrderCommand ----
TabOrderCommand(QDesignerFormWindowInterface * formWindow)1403 TabOrderCommand::TabOrderCommand(QDesignerFormWindowInterface *formWindow)
1404     : QDesignerFormWindowCommand(QApplication::translate("Command", "Change Tab order"), formWindow),
1405       m_widgetItem(nullptr)
1406 {
1407 }
1408 
init(const QWidgetList & newTabOrder)1409 void TabOrderCommand::init(const QWidgetList &newTabOrder)
1410 {
1411     QDesignerFormEditorInterface *core = formWindow()->core();
1412     Q_ASSERT(core);
1413 
1414     m_widgetItem = core->metaDataBase()->item(formWindow());
1415     Q_ASSERT(m_widgetItem);
1416     m_oldTabOrder = m_widgetItem->tabOrder();
1417     m_newTabOrder = newTabOrder;
1418 }
1419 
redo()1420 void TabOrderCommand::redo()
1421 {
1422     m_widgetItem->setTabOrder(m_newTabOrder);
1423 }
1424 
undo()1425 void TabOrderCommand::undo()
1426 {
1427     m_widgetItem->setTabOrder(m_oldTabOrder);
1428 }
1429 
1430 // ---- CreateMenuBarCommand ----
CreateMenuBarCommand(QDesignerFormWindowInterface * formWindow)1431 CreateMenuBarCommand::CreateMenuBarCommand(QDesignerFormWindowInterface *formWindow)
1432     : QDesignerFormWindowCommand(QApplication::translate("Command", "Create Menu Bar"), formWindow)
1433 {
1434 }
1435 
init(QMainWindow * mainWindow)1436 void CreateMenuBarCommand::init(QMainWindow *mainWindow)
1437 {
1438     m_mainWindow = mainWindow;
1439     QDesignerFormEditorInterface *core = formWindow()->core();
1440     m_menuBar = qobject_cast<QMenuBar*>(core->widgetFactory()->createWidget(QStringLiteral("QMenuBar"), m_mainWindow));
1441     core->widgetFactory()->initialize(m_menuBar);
1442 }
1443 
redo()1444 void CreateMenuBarCommand::redo()
1445 {
1446     QDesignerFormEditorInterface *core = formWindow()->core();
1447     QDesignerContainerExtension *c;
1448     c = qt_extension<QDesignerContainerExtension*>(core->extensionManager(), m_mainWindow);
1449     c->addWidget(m_menuBar);
1450 
1451     m_menuBar->setObjectName(QStringLiteral("menuBar"));
1452     formWindow()->ensureUniqueObjectName(m_menuBar);
1453     core->metaDataBase()->add(m_menuBar);
1454     formWindow()->emitSelectionChanged();
1455     m_menuBar->setFocus();
1456 }
1457 
undo()1458 void CreateMenuBarCommand::undo()
1459 {
1460     QDesignerFormEditorInterface *core = formWindow()->core();
1461     QDesignerContainerExtension *c;
1462     c = qt_extension<QDesignerContainerExtension*>(core->extensionManager(), m_mainWindow);
1463     for (int i = 0; i < c->count(); ++i) {
1464         if (c->widget(i) == m_menuBar) {
1465             c->remove(i);
1466             break;
1467         }
1468     }
1469 
1470     core->metaDataBase()->remove(m_menuBar);
1471     formWindow()->emitSelectionChanged();
1472 }
1473 
1474 // ---- DeleteMenuBarCommand ----
DeleteMenuBarCommand(QDesignerFormWindowInterface * formWindow)1475 DeleteMenuBarCommand::DeleteMenuBarCommand(QDesignerFormWindowInterface *formWindow)
1476     : QDesignerFormWindowCommand(QApplication::translate("Command", "Delete Menu Bar"), formWindow)
1477 {
1478 }
1479 
init(QMenuBar * menuBar)1480 void DeleteMenuBarCommand::init(QMenuBar *menuBar)
1481 {
1482     m_menuBar = menuBar;
1483     m_mainWindow = qobject_cast<QMainWindow*>(menuBar->parentWidget());
1484 }
1485 
redo()1486 void DeleteMenuBarCommand::redo()
1487 {
1488     if (m_mainWindow) {
1489         QDesignerContainerExtension *c;
1490         c = qt_extension<QDesignerContainerExtension*>(core()->extensionManager(), m_mainWindow);
1491         Q_ASSERT(c != nullptr);
1492         for (int i=0; i<c->count(); ++i) {
1493             if (c->widget(i) == m_menuBar) {
1494                 c->remove(i);
1495                 break;
1496             }
1497         }
1498     }
1499 
1500     core()->metaDataBase()->remove(m_menuBar);
1501     m_menuBar->hide();
1502     m_menuBar->setParent(formWindow());
1503     formWindow()->emitSelectionChanged();
1504 }
1505 
undo()1506 void DeleteMenuBarCommand::undo()
1507 {
1508     if (m_mainWindow) {
1509         m_menuBar->setParent(m_mainWindow);
1510         QDesignerContainerExtension *c;
1511         c = qt_extension<QDesignerContainerExtension*>(core()->extensionManager(), m_mainWindow);
1512 
1513         c->addWidget(m_menuBar);
1514 
1515         core()->metaDataBase()->add(m_menuBar);
1516         m_menuBar->show();
1517         formWindow()->emitSelectionChanged();
1518     }
1519 }
1520 
1521 // ---- CreateStatusBarCommand ----
CreateStatusBarCommand(QDesignerFormWindowInterface * formWindow)1522 CreateStatusBarCommand::CreateStatusBarCommand(QDesignerFormWindowInterface *formWindow)
1523     : QDesignerFormWindowCommand(QApplication::translate("Command", "Create Status Bar"), formWindow)
1524 {
1525 }
1526 
init(QMainWindow * mainWindow)1527 void CreateStatusBarCommand::init(QMainWindow *mainWindow)
1528 {
1529     m_mainWindow = mainWindow;
1530     QDesignerFormEditorInterface *core = formWindow()->core();
1531     m_statusBar = qobject_cast<QStatusBar*>(core->widgetFactory()->createWidget(QStringLiteral("QStatusBar"), m_mainWindow));
1532     core->widgetFactory()->initialize(m_statusBar);
1533 }
1534 
redo()1535 void CreateStatusBarCommand::redo()
1536 {
1537     QDesignerFormEditorInterface *core = formWindow()->core();
1538     QDesignerContainerExtension *c;
1539     c = qt_extension<QDesignerContainerExtension*>(core->extensionManager(), m_mainWindow);
1540     c->addWidget(m_statusBar);
1541 
1542     m_statusBar->setObjectName(QStringLiteral("statusBar"));
1543     formWindow()->ensureUniqueObjectName(m_statusBar);
1544     core->metaDataBase()->add(m_statusBar);
1545     formWindow()->emitSelectionChanged();
1546 }
1547 
undo()1548 void CreateStatusBarCommand::undo()
1549 {
1550     QDesignerFormEditorInterface *core = formWindow()->core();
1551     QDesignerContainerExtension *c = qt_extension<QDesignerContainerExtension*>(core->extensionManager(), m_mainWindow);
1552     for (int i = 0; i < c->count(); ++i) {
1553         if (c->widget(i) == m_statusBar) {
1554             c->remove(i);
1555             break;
1556         }
1557     }
1558 
1559     core->metaDataBase()->remove(m_statusBar);
1560     formWindow()->emitSelectionChanged();
1561 }
1562 
1563 // ---- DeleteStatusBarCommand ----
DeleteStatusBarCommand(QDesignerFormWindowInterface * formWindow)1564 DeleteStatusBarCommand::DeleteStatusBarCommand(QDesignerFormWindowInterface *formWindow)
1565     : QDesignerFormWindowCommand(QApplication::translate("Command", "Delete Status Bar"), formWindow)
1566 {
1567 }
1568 
init(QStatusBar * statusBar)1569 void DeleteStatusBarCommand::init(QStatusBar *statusBar)
1570 {
1571     m_statusBar = statusBar;
1572     m_mainWindow = qobject_cast<QMainWindow*>(statusBar->parentWidget());
1573 }
1574 
redo()1575 void DeleteStatusBarCommand::redo()
1576 {
1577     if (m_mainWindow) {
1578         QDesignerContainerExtension *c = qt_extension<QDesignerContainerExtension*>(core()->extensionManager(), m_mainWindow);
1579         Q_ASSERT(c != nullptr);
1580         for (int i=0; i<c->count(); ++i) {
1581             if (c->widget(i) == m_statusBar) {
1582                 c->remove(i);
1583                 break;
1584             }
1585         }
1586     }
1587 
1588     core()->metaDataBase()->remove(m_statusBar);
1589     m_statusBar->hide();
1590     m_statusBar->setParent(formWindow());
1591     formWindow()->emitSelectionChanged();
1592 }
1593 
undo()1594 void DeleteStatusBarCommand::undo()
1595 {
1596     if (m_mainWindow) {
1597         m_statusBar->setParent(m_mainWindow);
1598         QDesignerContainerExtension *c = qt_extension<QDesignerContainerExtension*>(core()->extensionManager(), m_mainWindow);
1599 
1600         c->addWidget(m_statusBar);
1601 
1602         core()->metaDataBase()->add(m_statusBar);
1603         m_statusBar->show();
1604         formWindow()->emitSelectionChanged();
1605     }
1606 }
1607 
1608 // ---- AddToolBarCommand ----
AddToolBarCommand(QDesignerFormWindowInterface * formWindow)1609 AddToolBarCommand::AddToolBarCommand(QDesignerFormWindowInterface *formWindow)
1610     : QDesignerFormWindowCommand(QApplication::translate("Command", "Add Tool Bar"), formWindow)
1611 {
1612 }
1613 
init(QMainWindow * mainWindow,Qt::ToolBarArea area)1614 void AddToolBarCommand::init(QMainWindow *mainWindow, Qt::ToolBarArea area)
1615 {
1616     m_mainWindow = mainWindow;
1617     QDesignerWidgetFactoryInterface * wf =  formWindow()->core()->widgetFactory();
1618     // Pass on 0 parent first to avoid reparenting flicker.
1619     m_toolBar = qobject_cast<QToolBar*>(wf->createWidget(QStringLiteral("QToolBar"), nullptr));
1620     m_toolBar->setProperty("_q_desiredArea", QVariant(area));
1621     wf->initialize(m_toolBar);
1622     m_toolBar->hide();
1623 }
1624 
redo()1625 void AddToolBarCommand::redo()
1626 {
1627     QDesignerFormEditorInterface *core = formWindow()->core();
1628     core->metaDataBase()->add(m_toolBar);
1629 
1630     QDesignerContainerExtension *c = qt_extension<QDesignerContainerExtension*>(core->extensionManager(), m_mainWindow);
1631     c->addWidget(m_toolBar);
1632 
1633     m_toolBar->setObjectName(QStringLiteral("toolBar"));
1634     formWindow()->ensureUniqueObjectName(m_toolBar);
1635     setPropertySheetWindowTitle(core, m_toolBar, m_toolBar->objectName());
1636     formWindow()->emitSelectionChanged();
1637 }
1638 
undo()1639 void AddToolBarCommand::undo()
1640 {
1641     QDesignerFormEditorInterface *core = formWindow()->core();
1642     core->metaDataBase()->remove(m_toolBar);
1643     QDesignerContainerExtension *c = qt_extension<QDesignerContainerExtension*>(core->extensionManager(), m_mainWindow);
1644     for (int i = 0; i < c->count(); ++i) {
1645         if (c->widget(i) == m_toolBar) {
1646             c->remove(i);
1647             break;
1648         }
1649     }
1650     formWindow()->emitSelectionChanged();
1651 }
1652 
1653 // ---- DockWidgetCommand:: ----
DockWidgetCommand(const QString & description,QDesignerFormWindowInterface * formWindow)1654 DockWidgetCommand::DockWidgetCommand(const QString &description, QDesignerFormWindowInterface *formWindow)
1655     : QDesignerFormWindowCommand(description, formWindow)
1656 {
1657 }
1658 
1659 DockWidgetCommand::~DockWidgetCommand() = default;
1660 
init(QDockWidget * dockWidget)1661 void DockWidgetCommand::init(QDockWidget *dockWidget)
1662 {
1663     m_dockWidget = dockWidget;
1664 }
1665 
1666 // ---- AddDockWidgetCommand ----
AddDockWidgetCommand(QDesignerFormWindowInterface * formWindow)1667 AddDockWidgetCommand::AddDockWidgetCommand(QDesignerFormWindowInterface *formWindow)
1668     : QDesignerFormWindowCommand(QApplication::translate("Command", "Add Dock Window"), formWindow)
1669 {
1670 }
1671 
init(QMainWindow * mainWindow,QDockWidget * dockWidget)1672 void AddDockWidgetCommand::init(QMainWindow *mainWindow, QDockWidget *dockWidget)
1673 {
1674     m_mainWindow = mainWindow;
1675     m_dockWidget = dockWidget;
1676 }
1677 
init(QMainWindow * mainWindow)1678 void AddDockWidgetCommand::init(QMainWindow *mainWindow)
1679 {
1680     m_mainWindow = mainWindow;
1681     QDesignerFormEditorInterface *core = formWindow()->core();
1682     m_dockWidget = qobject_cast<QDockWidget*>(core->widgetFactory()->createWidget(QStringLiteral("QDockWidget"), m_mainWindow));
1683 }
1684 
redo()1685 void AddDockWidgetCommand::redo()
1686 {
1687     QDesignerFormEditorInterface *core = formWindow()->core();
1688     QDesignerContainerExtension *c = qt_extension<QDesignerContainerExtension*>(core->extensionManager(), m_mainWindow);
1689     c->addWidget(m_dockWidget);
1690 
1691     m_dockWidget->setObjectName(QStringLiteral("dockWidget"));
1692     formWindow()->ensureUniqueObjectName(m_dockWidget);
1693     formWindow()->manageWidget(m_dockWidget);
1694     formWindow()->emitSelectionChanged();
1695 }
1696 
undo()1697 void AddDockWidgetCommand::undo()
1698 {
1699     QDesignerFormEditorInterface *core = formWindow()->core();
1700     QDesignerContainerExtension *c = qt_extension<QDesignerContainerExtension*>(core->extensionManager(), m_mainWindow);
1701     for (int i = 0; i < c->count(); ++i) {
1702         if (c->widget(i) == m_dockWidget) {
1703             c->remove(i);
1704             break;
1705         }
1706     }
1707 
1708     formWindow()->unmanageWidget(m_dockWidget);
1709     formWindow()->emitSelectionChanged();
1710 }
1711 
1712 // ---- AdjustWidgetSizeCommand ----
AdjustWidgetSizeCommand(QDesignerFormWindowInterface * formWindow)1713 AdjustWidgetSizeCommand::AdjustWidgetSizeCommand(QDesignerFormWindowInterface *formWindow)
1714     : QDesignerFormWindowCommand(QString(), formWindow)
1715 {
1716 }
1717 
init(QWidget * widget)1718 void AdjustWidgetSizeCommand::init(QWidget *widget)
1719 {
1720     m_widget = widget;
1721     setText(QApplication::translate("Command", "Adjust Size of '%1'").arg(widget->objectName()));
1722 }
1723 
widgetForAdjust() const1724 QWidget *AdjustWidgetSizeCommand::widgetForAdjust() const
1725 {
1726     QDesignerFormWindowInterface *fw = formWindow();
1727     // Return the outer, embedding widget if it is the main container
1728     if (Utils::isCentralWidget(fw, m_widget))
1729         return fw->core()->integration()->containerWindow(m_widget);
1730     return m_widget;
1731 }
1732 
redo()1733 void AdjustWidgetSizeCommand::redo()
1734 {
1735     QWidget *aw = widgetForAdjust();
1736     m_geometry = aw->geometry();
1737     QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
1738     aw->adjustSize();
1739     const bool isMainContainer = aw != m_widget;
1740     if (!isMainContainer) {
1741         /* When doing adjustsize on a selected non-laid out child that has been enlarged
1742          * and pushed partially over the top/left edge[s], it is possible that it "disappears"
1743          * when shrinking. In that case, move it back so that it remains visible. */
1744         if (aw->parentWidget()->layout() == nullptr) {
1745             const QRect contentsRect = aw->parentWidget()->contentsRect();
1746             const QRect newGeometry = aw->geometry();
1747             QPoint newPos = m_geometry.topLeft();
1748             if (newGeometry.bottom() <= contentsRect.y())
1749                 newPos.setY(contentsRect.y());
1750             if (newGeometry.right() <= contentsRect.x())
1751                 newPos.setX(contentsRect.x());
1752             if (newPos != m_geometry.topLeft())
1753                 aw->move(newPos);
1754         }
1755     }
1756     updatePropertyEditor();
1757 }
1758 
undo()1759 void AdjustWidgetSizeCommand::undo()
1760 {
1761     QWidget *aw = widgetForAdjust();
1762     aw->resize(m_geometry.size());
1763     if (m_geometry.topLeft() != aw->geometry().topLeft())
1764         aw->move(m_geometry.topLeft());
1765     updatePropertyEditor();
1766 }
1767 
updatePropertyEditor() const1768 void AdjustWidgetSizeCommand::updatePropertyEditor() const
1769 {
1770     if (QDesignerPropertyEditorInterface *propertyEditor = formWindow()->core()->propertyEditor()) {
1771         if (propertyEditor->object() == m_widget)
1772             propertyEditor->setPropertyValue(QStringLiteral("geometry"), m_widget->geometry(), true);
1773     }
1774 }
1775 // ------------  ChangeFormLayoutItemRoleCommand
1776 
ChangeFormLayoutItemRoleCommand(QDesignerFormWindowInterface * formWindow)1777 ChangeFormLayoutItemRoleCommand::ChangeFormLayoutItemRoleCommand(QDesignerFormWindowInterface *formWindow) :
1778     QDesignerFormWindowCommand(QApplication::translate("Command", "Change Form Layout Item Geometry"), formWindow),
1779     m_operation(SpanningToLabel)
1780 {
1781 }
1782 
init(QWidget * widget,Operation op)1783 void ChangeFormLayoutItemRoleCommand::init(QWidget *widget, Operation op)
1784 {
1785     m_widget = widget;
1786     m_operation = op;
1787 }
1788 
redo()1789 void ChangeFormLayoutItemRoleCommand::redo()
1790 {
1791     doOperation(m_operation);
1792 }
1793 
undo()1794 void ChangeFormLayoutItemRoleCommand::undo()
1795 {
1796     doOperation(reverseOperation(m_operation));
1797 }
1798 
reverseOperation(Operation op)1799 ChangeFormLayoutItemRoleCommand::Operation ChangeFormLayoutItemRoleCommand::reverseOperation(Operation op)
1800 {
1801     switch (op) {
1802     case SpanningToLabel:
1803         return LabelToSpanning;
1804     case SpanningToField:
1805         return FieldToSpanning;
1806     case LabelToSpanning:
1807         return SpanningToLabel;
1808     case FieldToSpanning:
1809         return SpanningToField;
1810     }
1811     return SpanningToField;
1812 }
1813 
doOperation(Operation op)1814 void ChangeFormLayoutItemRoleCommand::doOperation(Operation op)
1815 {
1816     QFormLayout *fl = ChangeFormLayoutItemRoleCommand::managedFormLayoutOf(formWindow()->core(), m_widget);
1817     const int index = fl->indexOf(m_widget);
1818     Q_ASSERT(index != -1);
1819      int row;
1820     QFormLayout::ItemRole role;
1821     fl->getItemPosition (index, &row, &role);
1822     Q_ASSERT(index != -1);
1823     QLayoutItem *item = fl->takeAt(index);
1824     const QRect area = QRect(0, row, 2, 1);
1825     switch (op) {
1826     case SpanningToLabel:
1827         fl->setItem(row, QFormLayout::LabelRole, item);
1828         QLayoutSupport::createEmptyCells(fl);
1829         break;
1830     case SpanningToField:
1831         fl->setItem(row, QFormLayout::FieldRole, item);
1832         QLayoutSupport::createEmptyCells(fl);
1833         break;
1834     case LabelToSpanning:
1835     case FieldToSpanning:
1836         QLayoutSupport::removeEmptyCells(fl, area);
1837         fl->setItem(row, QFormLayout::SpanningRole, item);
1838         break;
1839     }
1840 }
1841 
possibleOperations(QDesignerFormEditorInterface * core,QWidget * w)1842 unsigned ChangeFormLayoutItemRoleCommand::possibleOperations(QDesignerFormEditorInterface *core, QWidget *w)
1843 {
1844     QFormLayout *fl = managedFormLayoutOf(core, w);
1845     if (!fl)
1846         return 0;
1847     const int index = fl->indexOf(w);
1848     if (index == -1)
1849         return 0;
1850     int row, col, colspan;
1851     getFormLayoutItemPosition(fl, index, &row, &col, nullptr, &colspan);
1852     // Spanning item?
1853     if (colspan > 1)
1854         return SpanningToLabel|SpanningToField;
1855     // Is the neighbouring column free, that is, can the current item be expanded?
1856     const QFormLayout::ItemRole neighbouringRole = col == 0 ? QFormLayout::FieldRole : QFormLayout::LabelRole;
1857     const bool empty = LayoutInfo::isEmptyItem(fl->itemAt(row, neighbouringRole));
1858     if (empty)
1859         return col == 0 ? LabelToSpanning : FieldToSpanning;
1860     return 0;
1861 }
1862 
managedFormLayoutOf(QDesignerFormEditorInterface * core,QWidget * w)1863 QFormLayout *ChangeFormLayoutItemRoleCommand::managedFormLayoutOf(QDesignerFormEditorInterface *core, QWidget *w)
1864 {
1865     if (QLayout *layout = LayoutInfo::managedLayout(core, w->parentWidget()))
1866         if (QFormLayout *fl = qobject_cast<QFormLayout *>(layout))
1867             return fl;
1868     return nullptr;
1869 }
1870 
1871 // ---- ChangeLayoutItemGeometry ----
ChangeLayoutItemGeometry(QDesignerFormWindowInterface * formWindow)1872 ChangeLayoutItemGeometry::ChangeLayoutItemGeometry(QDesignerFormWindowInterface *formWindow)
1873     : QDesignerFormWindowCommand(QApplication::translate("Command", "Change Layout Item Geometry"), formWindow)
1874 {
1875 }
1876 
init(QWidget * widget,int row,int column,int rowspan,int colspan)1877 void ChangeLayoutItemGeometry::init(QWidget *widget, int row, int column, int rowspan, int colspan)
1878 {
1879     m_widget = widget;
1880     Q_ASSERT(m_widget->parentWidget() != nullptr);
1881 
1882     QLayout *layout = LayoutInfo::managedLayout(formWindow()->core(), m_widget->parentWidget());
1883     Q_ASSERT(layout != nullptr);
1884 
1885     QGridLayout *grid = qobject_cast<QGridLayout*>(layout);
1886     Q_ASSERT(grid != nullptr);
1887 
1888     const int itemIndex = grid->indexOf(m_widget);
1889     Q_ASSERT(itemIndex != -1);
1890 
1891     int current_row, current_column, current_rowspan, current_colspan;
1892     grid->getItemPosition(itemIndex, &current_row, &current_column, &current_rowspan, &current_colspan);
1893 
1894     m_oldInfo.setRect(current_column, current_row, current_colspan, current_rowspan);
1895     m_newInfo.setRect(column, row, colspan, rowspan);
1896 }
1897 
changeItemPosition(const QRect & g)1898 void ChangeLayoutItemGeometry::changeItemPosition(const QRect &g)
1899 {
1900     QLayout *layout = LayoutInfo::managedLayout(formWindow()->core(), m_widget->parentWidget());
1901     Q_ASSERT(layout != nullptr);
1902 
1903     QGridLayout *grid = qobject_cast<QGridLayout*>(layout);
1904     Q_ASSERT(grid != nullptr);
1905 
1906     const int itemIndex = grid->indexOf(m_widget);
1907     Q_ASSERT(itemIndex != -1);
1908 
1909     QLayoutItem *item = grid->takeAt(itemIndex);
1910     delete item;
1911 
1912     if (!QLayoutSupport::removeEmptyCells(grid, g))
1913         qWarning() << "ChangeLayoutItemGeometry::changeItemPosition: Nonempty cell at " <<  g << '.';
1914 
1915     grid->addWidget(m_widget, g.top(), g.left(), g.height(), g.width());
1916 
1917     grid->invalidate();
1918     grid->activate();
1919 
1920     QLayoutSupport::createEmptyCells(grid);
1921 
1922     formWindow()->clearSelection(false);
1923     formWindow()->selectWidget(m_widget, true);
1924 }
1925 
redo()1926 void ChangeLayoutItemGeometry::redo()
1927 {
1928     changeItemPosition(m_newInfo);
1929 }
1930 
undo()1931 void ChangeLayoutItemGeometry::undo()
1932 {
1933     changeItemPosition(m_oldInfo);
1934 }
1935 
1936 // ---- ContainerWidgetCommand ----
ContainerWidgetCommand(QDesignerFormWindowInterface * formWindow)1937 ContainerWidgetCommand::ContainerWidgetCommand(QDesignerFormWindowInterface *formWindow)  :
1938     QDesignerFormWindowCommand(QString(), formWindow),
1939     m_index(-1)
1940 {
1941 }
1942 
1943 ContainerWidgetCommand::~ContainerWidgetCommand() = default;
1944 
containerExtension() const1945 QDesignerContainerExtension *ContainerWidgetCommand::containerExtension() const
1946 {
1947     QExtensionManager *mgr = core()->extensionManager();
1948     return qt_extension<QDesignerContainerExtension*>(mgr, m_containerWidget);
1949 }
1950 
init(QWidget * containerWidget)1951 void ContainerWidgetCommand::init(QWidget *containerWidget)
1952 {
1953     m_containerWidget = containerWidget;
1954 
1955     if (QDesignerContainerExtension *c = containerExtension()) {
1956         m_index = c->currentIndex();
1957         m_widget = c->widget(m_index);
1958     }
1959 }
1960 
removePage()1961 void ContainerWidgetCommand::removePage()
1962 {
1963     if (QDesignerContainerExtension *c = containerExtension()) {
1964         if (const int count = c->count()) {
1965             // Undo add after last?
1966             const int deleteIndex = m_index >= 0 ? m_index : count - 1;
1967             c->remove(deleteIndex);
1968             m_widget->hide();
1969             m_widget->setParent(formWindow());
1970         }
1971     }
1972 }
1973 
addPage()1974 void ContainerWidgetCommand::addPage()
1975 {
1976     if (QDesignerContainerExtension *c = containerExtension()) {
1977         int newCurrentIndex;
1978         if (m_index >= 0) {
1979             c->insertWidget(m_index, m_widget);
1980             newCurrentIndex = m_index;
1981         } else {
1982             c->addWidget(m_widget);
1983             newCurrentIndex = c->count() -1 ;
1984         }
1985         m_widget->show();
1986         c->setCurrentIndex(newCurrentIndex);
1987     }
1988 }
1989 
1990 // ---- DeleteContainerWidgetPageCommand ----
DeleteContainerWidgetPageCommand(QDesignerFormWindowInterface * formWindow)1991 DeleteContainerWidgetPageCommand::DeleteContainerWidgetPageCommand(QDesignerFormWindowInterface *formWindow)
1992     : ContainerWidgetCommand(formWindow)
1993 {
1994 }
1995 
1996 DeleteContainerWidgetPageCommand::~DeleteContainerWidgetPageCommand() = default;
1997 
init(QWidget * containerWidget,ContainerType ct)1998 void DeleteContainerWidgetPageCommand::init(QWidget *containerWidget, ContainerType ct)
1999 {
2000     ContainerWidgetCommand::init(containerWidget);
2001     switch (ct) {
2002     case WizardContainer:
2003     case PageContainer:
2004         setText(QApplication::translate("Command", "Delete Page"));
2005         break;
2006     case MdiContainer:
2007         setText(QApplication::translate("Command", "Delete Subwindow"));
2008         break;
2009     }
2010 }
2011 
redo()2012 void DeleteContainerWidgetPageCommand::redo()
2013 {
2014     removePage();
2015     cheapUpdate();
2016 }
2017 
undo()2018 void DeleteContainerWidgetPageCommand::undo()
2019 {
2020     addPage();
2021     cheapUpdate();
2022 }
2023 
2024 // ---- AddContainerWidgetPageCommand ----
AddContainerWidgetPageCommand(QDesignerFormWindowInterface * formWindow)2025 AddContainerWidgetPageCommand::AddContainerWidgetPageCommand(QDesignerFormWindowInterface *formWindow)
2026     : ContainerWidgetCommand(formWindow)
2027 {
2028 }
2029 
2030 AddContainerWidgetPageCommand::~AddContainerWidgetPageCommand() = default;
2031 
init(QWidget * containerWidget,ContainerType ct,InsertionMode mode)2032 void AddContainerWidgetPageCommand::init(QWidget *containerWidget, ContainerType ct, InsertionMode mode)
2033 {
2034     m_containerWidget = containerWidget;
2035 
2036     if (QDesignerContainerExtension *c = containerExtension()) {
2037         m_index = c->currentIndex();
2038         if (m_index >= 0 && mode == InsertAfter)
2039             m_index++;
2040         m_widget = nullptr;
2041         const QDesignerFormEditorInterface *core = formWindow()->core();
2042         switch (ct) {
2043         case PageContainer:
2044             setText(QApplication::translate("Command", "Insert Page"));
2045             m_widget = new QDesignerWidget(formWindow(), m_containerWidget);
2046             m_widget->setObjectName(QStringLiteral("page"));
2047             break;
2048         case MdiContainer:
2049             setText(QApplication::translate("Command", "Insert Subwindow"));
2050             m_widget = new QDesignerWidget(formWindow(), m_containerWidget);
2051             m_widget->setObjectName(QStringLiteral("subwindow"));
2052             setPropertySheetWindowTitle(core, m_widget, QApplication::translate("Command", "Subwindow"));
2053             break;
2054         case WizardContainer: // Apply style, don't manage
2055             m_widget = core->widgetFactory()->createWidget(QStringLiteral("QWizardPage"), nullptr);
2056             break;
2057         }
2058         formWindow()->ensureUniqueObjectName(m_widget);
2059         core->metaDataBase()->add(m_widget);
2060     }
2061 }
2062 
redo()2063 void AddContainerWidgetPageCommand::redo()
2064 {
2065     addPage();
2066     cheapUpdate();
2067 }
2068 
undo()2069 void AddContainerWidgetPageCommand::undo()
2070 {
2071     removePage();
2072     cheapUpdate();
2073 }
2074 
ChangeCurrentPageCommand(QDesignerFormWindowInterface * formWindow)2075 ChangeCurrentPageCommand::ChangeCurrentPageCommand(QDesignerFormWindowInterface *formWindow)
2076     :
2077     QDesignerFormWindowCommand(QString(), formWindow), m_oldIndex(0), m_newIndex(0)
2078 {
2079 }
2080 
2081 ChangeCurrentPageCommand::~ChangeCurrentPageCommand() = default;
2082 
containerExtension() const2083 QDesignerContainerExtension *ChangeCurrentPageCommand::containerExtension() const
2084 {
2085     QExtensionManager *mgr = core()->extensionManager();
2086     return qt_extension<QDesignerContainerExtension*>(mgr, m_containerWidget);
2087 }
2088 
init(QWidget * containerWidget,int newIndex)2089 void ChangeCurrentPageCommand::init(QWidget *containerWidget, int newIndex)
2090 {
2091     m_containerWidget = containerWidget;
2092 
2093     if (QDesignerContainerExtension *c = containerExtension()) {
2094         m_newIndex = newIndex;
2095         m_oldIndex = c->currentIndex();
2096         m_widget = c->widget(m_oldIndex);
2097     }
2098 }
2099 
redo()2100 void ChangeCurrentPageCommand::redo()
2101 {
2102     containerExtension()->setCurrentIndex(m_newIndex);
2103 }
2104 
undo()2105 void ChangeCurrentPageCommand::undo()
2106 {
2107     containerExtension()->setCurrentIndex(m_oldIndex);
2108 }
2109 
2110 static const int itemRoles[] = {
2111     Qt::DecorationPropertyRole,
2112     Qt::DisplayPropertyRole,
2113     Qt::ToolTipPropertyRole,
2114     Qt::StatusTipPropertyRole,
2115     Qt::WhatsThisPropertyRole,
2116     Qt::FontRole,
2117     Qt::TextAlignmentRole,
2118     Qt::BackgroundRole,
2119     Qt::ForegroundRole,
2120     Qt::CheckStateRole
2121 };
2122 
2123 template<class T>
copyRoleFromItem(ItemData * id,int role,const T * item)2124 static void copyRoleFromItem(ItemData *id, int role, const T *item)
2125 {
2126     QVariant v = item->data(role);
2127     if (v.isValid())
2128         id->m_properties.insert(role, v);
2129 }
2130 
2131 template<class T>
copyRolesFromItem(ItemData * id,const T * item,bool editor)2132 static void copyRolesFromItem(ItemData *id, const T *item, bool editor)
2133 {
2134     static const Qt::ItemFlags defaultFlags = T().flags();
2135 
2136     for (int i : itemRoles)
2137         copyRoleFromItem<T>(id, i, item);
2138 
2139     if (editor)
2140         copyRoleFromItem<T>(id, ItemFlagsShadowRole, item);
2141     else if (item->flags() != defaultFlags)
2142         id->m_properties.insert(ItemFlagsShadowRole, QVariant::fromValue(int(item->flags())));
2143 }
2144 
2145 template<class T>
copyRolesToItem(const ItemData * id,T * item,DesignerIconCache * iconCache,bool editor)2146 static void copyRolesToItem(const ItemData *id, T *item, DesignerIconCache *iconCache, bool editor)
2147 {
2148     QHash<int, QVariant>::const_iterator it = id->m_properties.constBegin(),
2149             end = id->m_properties.constEnd();
2150     for (; it != end; ++it)
2151         if (it.value().isValid()) {
2152             if (!editor && it.key() == ItemFlagsShadowRole) {
2153                 item->setFlags((Qt::ItemFlags)it.value().toInt());
2154             } else {
2155                 item->setData(it.key(), it.value());
2156                 switch (it.key()) {
2157                 case Qt::DecorationPropertyRole:
2158                     if (iconCache)
2159                         item->setIcon(iconCache->icon(qvariant_cast<PropertySheetIconValue>(it.value())));
2160                     break;
2161                 case Qt::DisplayPropertyRole:
2162                     item->setText(qvariant_cast<PropertySheetStringValue>(it.value()).value());
2163                     break;
2164                 case Qt::ToolTipPropertyRole:
2165                     item->setToolTip(qvariant_cast<PropertySheetStringValue>(it.value()).value());
2166                     break;
2167                 case Qt::StatusTipPropertyRole:
2168                     item->setStatusTip(qvariant_cast<PropertySheetStringValue>(it.value()).value());
2169                     break;
2170                 case Qt::WhatsThisPropertyRole:
2171                     item->setWhatsThis(qvariant_cast<PropertySheetStringValue>(it.value()).value());
2172                     break;
2173                 }
2174             }
2175         }
2176 
2177     if (editor)
2178         item->setFlags(item->flags() | Qt::ItemIsEditable);
2179 }
2180 
ItemData(const QListWidgetItem * item,bool editor)2181 ItemData::ItemData(const QListWidgetItem *item, bool editor)
2182 {
2183     copyRolesFromItem<QListWidgetItem>(this, item, editor);
2184 }
2185 
createListItem(DesignerIconCache * iconCache,bool editor) const2186 QListWidgetItem *ItemData::createListItem(DesignerIconCache *iconCache, bool editor) const
2187 {
2188     QListWidgetItem *item = new QListWidgetItem();
2189     copyRolesToItem(this, item, iconCache, editor);
2190     return item;
2191 }
2192 
ItemData(const QTableWidgetItem * item,bool editor)2193 ItemData::ItemData(const QTableWidgetItem *item, bool editor)
2194 {
2195     copyRolesFromItem(this, item, editor);
2196 }
2197 
createTableItem(DesignerIconCache * iconCache,bool editor) const2198 QTableWidgetItem *ItemData::createTableItem(DesignerIconCache *iconCache, bool editor) const
2199 {
2200     QTableWidgetItem *item = new QTableWidgetItem;
2201     copyRolesToItem(this, item, iconCache, editor);
2202     return item;
2203 }
2204 
copyRoleFromItem(ItemData * id,int role,const QTreeWidgetItem * item,int column)2205 static void copyRoleFromItem(ItemData *id, int role, const QTreeWidgetItem *item, int column)
2206 {
2207     QVariant v = item->data(column, role);
2208     if (v.isValid())
2209         id->m_properties.insert(role, v);
2210 }
2211 
ItemData(const QTreeWidgetItem * item,int column)2212 ItemData::ItemData(const QTreeWidgetItem *item, int column)
2213 {
2214     copyRoleFromItem(this, Qt::EditRole, item, column);
2215     PropertySheetStringValue str(item->text(column));
2216     m_properties.insert(Qt::DisplayPropertyRole, QVariant::fromValue(str));
2217 
2218     for (int i : itemRoles)
2219         copyRoleFromItem(this, i, item, column);
2220 }
2221 
fillTreeItemColumn(QTreeWidgetItem * item,int column,DesignerIconCache * iconCache) const2222 void ItemData::fillTreeItemColumn(QTreeWidgetItem *item, int column, DesignerIconCache *iconCache) const
2223 {
2224     QHash<int, QVariant>::const_iterator it = m_properties.constBegin(), end = m_properties.constEnd();
2225     for (; it != end; ++it)
2226         if (it.value().isValid()) {
2227             item->setData(column, it.key(), it.value());
2228             switch (it.key()) {
2229             case Qt::DecorationPropertyRole:
2230                 if (iconCache)
2231                     item->setIcon(column, iconCache->icon(qvariant_cast<PropertySheetIconValue>(it.value())));
2232                 break;
2233             case Qt::DisplayPropertyRole:
2234                 item->setText(column, qvariant_cast<PropertySheetStringValue>(it.value()).value());
2235                 break;
2236             case Qt::ToolTipPropertyRole:
2237                 item->setToolTip(column, qvariant_cast<PropertySheetStringValue>(it.value()).value());
2238                 break;
2239             case Qt::StatusTipPropertyRole:
2240                 item->setStatusTip(column, qvariant_cast<PropertySheetStringValue>(it.value()).value());
2241                 break;
2242             case Qt::WhatsThisPropertyRole:
2243                 item->setWhatsThis(column, qvariant_cast<PropertySheetStringValue>(it.value()).value());
2244                 break;
2245             }
2246         }
2247 }
2248 
ListContents(const QTreeWidgetItem * item)2249 ListContents::ListContents(const QTreeWidgetItem *item)
2250 {
2251     for (int i = 0; i < item->columnCount(); i++)
2252         m_items.append(ItemData(item, i));
2253 }
2254 
createTreeItem(DesignerIconCache * iconCache) const2255 QTreeWidgetItem *ListContents::createTreeItem(DesignerIconCache *iconCache) const
2256 {
2257     QTreeWidgetItem *item = new QTreeWidgetItem;
2258     int i = 0;
2259     for (const ItemData &id : m_items)
2260         id.fillTreeItemColumn(item, i++, iconCache);
2261     return item;
2262 }
2263 
createFromListWidget(const QListWidget * listWidget,bool editor)2264 void ListContents::createFromListWidget(const QListWidget *listWidget, bool editor)
2265 {
2266     m_items.clear();
2267 
2268     for (int i = 0; i < listWidget->count(); i++)
2269         m_items.append(ItemData(listWidget->item(i), editor));
2270 }
2271 
applyToListWidget(QListWidget * listWidget,DesignerIconCache * iconCache,bool editor) const2272 void ListContents::applyToListWidget(QListWidget *listWidget, DesignerIconCache *iconCache, bool editor) const
2273 {
2274     listWidget->clear();
2275 
2276     int i = 0;
2277     for (const ItemData &entry : m_items) {
2278         if (!entry.isValid())
2279             new QListWidgetItem(TableWidgetContents::defaultHeaderText(i), listWidget);
2280         else
2281             listWidget->addItem(entry.createListItem(iconCache, editor));
2282         i++;
2283     }
2284 }
2285 
createFromComboBox(const QComboBox * comboBox)2286 void ListContents::createFromComboBox(const QComboBox *comboBox)
2287 {
2288     m_items.clear();
2289 
2290     const int count = comboBox->count();
2291     for (int i = 0; i < count; i++) {
2292         // We might encounter items added in a custom combo
2293         // constructor. Ignore those.
2294         const QVariant textValue = comboBox->itemData(i, Qt::DisplayPropertyRole);
2295         if (!textValue.isNull()) {
2296             ItemData entry;
2297             entry.m_properties.insert(Qt::DisplayPropertyRole, textValue);
2298             const QVariant iconValue =  comboBox->itemData(i, Qt::DecorationPropertyRole);
2299             if (!iconValue.isNull())
2300                 entry.m_properties.insert(Qt::DecorationPropertyRole, iconValue);
2301             m_items.append(entry);
2302         }
2303     }
2304 }
2305 
applyToComboBox(QComboBox * comboBox,DesignerIconCache * iconCache) const2306 void ListContents::applyToComboBox(QComboBox *comboBox, DesignerIconCache *iconCache) const
2307 {
2308     comboBox->clear();
2309 
2310     for (const ItemData &hash : m_items) {
2311         QIcon icon;
2312         if (iconCache)
2313             icon = iconCache->icon(qvariant_cast<PropertySheetIconValue>(
2314                     hash.m_properties[Qt::DecorationPropertyRole]));
2315         QVariant var = hash.m_properties[Qt::DisplayPropertyRole];
2316         PropertySheetStringValue str = qvariant_cast<PropertySheetStringValue>(var);
2317         comboBox->addItem(icon, str.value());
2318         comboBox->setItemData(comboBox->count() - 1,
2319                               var,
2320                               Qt::DisplayPropertyRole);
2321         comboBox->setItemData(comboBox->count() - 1,
2322                               hash.m_properties[Qt::DecorationPropertyRole],
2323                               Qt::DecorationPropertyRole);
2324     }
2325 }
2326 
2327 // --------- TableWidgetContents
2328 
2329 TableWidgetContents::TableWidgetContents() = default;
2330 
clear()2331 void TableWidgetContents::clear()
2332 {
2333     m_horizontalHeader.m_items.clear();
2334     m_verticalHeader.m_items.clear();
2335     m_items.clear();
2336     m_columnCount = 0;
2337     m_rowCount = 0;
2338 }
2339 
defaultHeaderText(int i)2340 QString TableWidgetContents::defaultHeaderText(int i)
2341 {
2342     return QString::number(i + 1);
2343 }
2344 
nonEmpty(const QTableWidgetItem * item,int headerColumn)2345 bool TableWidgetContents::nonEmpty(const QTableWidgetItem *item, int headerColumn)
2346 {
2347     static const Qt::ItemFlags defaultFlags = QTableWidgetItem().flags();
2348 
2349     if (item->flags() != defaultFlags)
2350         return true;
2351 
2352     QString text = qvariant_cast<PropertySheetStringValue>(item->data(Qt::DisplayPropertyRole)).value();
2353     if (!text.isEmpty()) {
2354         if (headerColumn < 0 || text != defaultHeaderText(headerColumn))
2355             return true;
2356     } else {
2357         // FIXME: This doesn't seem to make sense
2358         return true;
2359     }
2360 
2361     for (int i : itemRoles) {
2362         if (i != Qt::DisplayPropertyRole && item->data(i).isValid())
2363             return true;
2364     }
2365 
2366     return false;
2367 }
2368 
insertHeaderItem(const QTableWidgetItem * item,int i,ListContents * header,bool editor)2369 void TableWidgetContents::insertHeaderItem(const QTableWidgetItem *item, int i, ListContents *header, bool editor)
2370 {
2371     if (nonEmpty(item, i))
2372         header->m_items.append(ItemData(item, editor));
2373     else
2374         header->m_items.append(ItemData());
2375 }
2376 
fromTableWidget(const QTableWidget * tableWidget,bool editor)2377 void TableWidgetContents::fromTableWidget(const QTableWidget *tableWidget, bool editor)
2378 {
2379     clear();
2380     m_columnCount = tableWidget->columnCount();
2381     m_rowCount = tableWidget->rowCount();
2382     // horiz header: Legacy behaviour: auto-generate number for empty items
2383     for (int col = 0; col <  m_columnCount; col++)
2384         if (const QTableWidgetItem *item = tableWidget->horizontalHeaderItem(col))
2385             insertHeaderItem(item, col, &m_horizontalHeader, editor);
2386     // vertical header: Legacy behaviour: auto-generate number for empty items
2387     for (int row = 0; row < m_rowCount; row++)
2388         if (const QTableWidgetItem *item = tableWidget->verticalHeaderItem(row))
2389             insertHeaderItem(item, row, &m_verticalHeader, editor);
2390     // cell data
2391     for (int col = 0; col < m_columnCount; col++)
2392         for (int row = 0; row < m_rowCount; row++)
2393             if (const QTableWidgetItem *item = tableWidget->item(row, col))
2394                 if (nonEmpty(item, -1))
2395                     m_items.insert(CellRowColumnAddress(row, col), ItemData(item, editor));
2396 }
2397 
applyToTableWidget(QTableWidget * tableWidget,DesignerIconCache * iconCache,bool editor) const2398 void TableWidgetContents::applyToTableWidget(QTableWidget *tableWidget, DesignerIconCache *iconCache, bool editor) const
2399 {
2400     tableWidget->clear();
2401 
2402     tableWidget->setColumnCount(m_columnCount);
2403     tableWidget->setRowCount(m_rowCount);
2404 
2405     // horiz header
2406     int col = 0;
2407     for (const ItemData &id : m_horizontalHeader.m_items) {
2408         if (id.isValid())
2409             tableWidget->setHorizontalHeaderItem(col, id.createTableItem(iconCache, editor));
2410         col++;
2411     }
2412     // vertical header
2413     int row = 0;
2414     for (const ItemData &id : m_verticalHeader.m_items) {
2415         if (id.isValid())
2416             tableWidget->setVerticalHeaderItem(row, id.createTableItem(iconCache, editor));
2417         row++;
2418     }
2419     // items
2420     const TableItemMap::const_iterator icend = m_items.constEnd();
2421     for (TableItemMap::const_iterator it = m_items.constBegin(); it !=  icend; ++ it)
2422         tableWidget->setItem(it.key().first, it.key().second, it.value().createTableItem(iconCache, editor));
2423 }
2424 
operator ==(const TableWidgetContents & rhs) const2425 bool TableWidgetContents::operator==(const TableWidgetContents &rhs) const
2426 {
2427     if (m_columnCount != rhs.m_columnCount || m_rowCount !=  rhs.m_rowCount)
2428         return false;
2429 
2430     return m_horizontalHeader.m_items == rhs.m_horizontalHeader.m_items &&
2431            m_verticalHeader.m_items == rhs.m_verticalHeader.m_items &&
2432            m_items == rhs.m_items;
2433 }
2434 
2435 // ---- ChangeTableContentsCommand ----
ChangeTableContentsCommand(QDesignerFormWindowInterface * formWindow)2436 ChangeTableContentsCommand::ChangeTableContentsCommand(QDesignerFormWindowInterface *formWindow)  :
2437     QDesignerFormWindowCommand(QApplication::translate("Command", "Change Table Contents"),
2438     formWindow), m_iconCache(nullptr)
2439 {
2440     FormWindowBase *fwb = qobject_cast<FormWindowBase *>(formWindow);
2441     if (fwb)
2442         m_iconCache = fwb->iconCache();
2443 }
2444 
init(QTableWidget * tableWidget,const TableWidgetContents & oldCont,const TableWidgetContents & newCont)2445 void ChangeTableContentsCommand::init(QTableWidget *tableWidget,
2446         const TableWidgetContents &oldCont, const TableWidgetContents &newCont)
2447 {
2448     m_tableWidget = tableWidget;
2449     m_oldContents = oldCont;
2450     m_newContents = newCont;
2451 }
2452 
redo()2453 void ChangeTableContentsCommand::redo()
2454 {
2455     m_newContents.applyToTableWidget(m_tableWidget, m_iconCache, false);
2456     QMetaObject::invokeMethod(m_tableWidget, "updateGeometries");
2457 }
2458 
undo()2459 void ChangeTableContentsCommand::undo()
2460 {
2461     m_oldContents.applyToTableWidget(m_tableWidget, m_iconCache, false);
2462     QMetaObject::invokeMethod(m_tableWidget, "updateGeometries");
2463 }
2464 
2465 // --------- TreeWidgetContents
ItemContents(const QTreeWidgetItem * item,bool editor)2466 TreeWidgetContents::ItemContents::ItemContents(const QTreeWidgetItem *item, bool editor) :
2467     ListContents(item)
2468 {
2469     static const Qt::ItemFlags defaultFlags = QTreeWidgetItem().flags();
2470 
2471     if (editor) {
2472         QVariant v = item->data(0, ItemFlagsShadowRole);
2473         m_itemFlags = v.isValid() ? v.toInt() : -1;
2474     } else  {
2475         m_itemFlags = (item->flags() != defaultFlags) ? int(item->flags()) : -1;
2476     }
2477 
2478     for (int i = 0; i < item->childCount(); i++)
2479         m_children.append(ItemContents(item->child(i), editor));
2480 }
2481 
createTreeItem(DesignerIconCache * iconCache,bool editor) const2482 QTreeWidgetItem *TreeWidgetContents::ItemContents::createTreeItem(DesignerIconCache *iconCache, bool editor) const
2483 {
2484     QTreeWidgetItem *item = ListContents::createTreeItem(iconCache);
2485 
2486     if (editor)
2487         item->setFlags(item->flags() | Qt::ItemIsEditable);
2488 
2489     if (m_itemFlags != -1) {
2490         if (editor)
2491             item->setData(0, ItemFlagsShadowRole, QVariant::fromValue(m_itemFlags));
2492         else
2493             item->setFlags((Qt::ItemFlags)m_itemFlags);
2494     }
2495 
2496     for (const ItemContents &ic : m_children)
2497         item->addChild(ic.createTreeItem(iconCache, editor));
2498 
2499     return item;
2500 }
2501 
operator ==(const TreeWidgetContents::ItemContents & rhs) const2502 bool TreeWidgetContents::ItemContents::operator==(const TreeWidgetContents::ItemContents &rhs) const
2503 {
2504     return
2505         m_itemFlags == rhs.m_itemFlags &&
2506         m_items == rhs.m_items &&
2507         m_children == rhs.m_children;
2508 }
2509 
clear()2510 void TreeWidgetContents::clear()
2511 {
2512     m_headerItem.m_items.clear();
2513     m_rootItems.clear();
2514 }
2515 
fromTreeWidget(const QTreeWidget * treeWidget,bool editor)2516 void TreeWidgetContents::fromTreeWidget(const QTreeWidget *treeWidget, bool editor)
2517 {
2518     clear();
2519     m_headerItem = ListContents(treeWidget->headerItem());
2520     for (int col = 0; col < treeWidget->topLevelItemCount(); col++)
2521         m_rootItems.append(ItemContents(treeWidget->topLevelItem(col), editor));
2522 }
2523 
applyToTreeWidget(QTreeWidget * treeWidget,DesignerIconCache * iconCache,bool editor) const2524 void TreeWidgetContents::applyToTreeWidget(QTreeWidget *treeWidget, DesignerIconCache *iconCache, bool editor) const
2525 {
2526     treeWidget->clear();
2527 
2528     treeWidget->setColumnCount(m_headerItem.m_items.count());
2529     treeWidget->setHeaderItem(m_headerItem.createTreeItem(iconCache));
2530     for (const ItemContents &ic : m_rootItems)
2531         treeWidget->addTopLevelItem(ic.createTreeItem(iconCache, editor));
2532     treeWidget->expandAll();
2533 }
2534 
operator ==(const TreeWidgetContents & rhs) const2535 bool TreeWidgetContents::operator==(const TreeWidgetContents &rhs) const
2536 {
2537     return
2538         m_headerItem == rhs.m_headerItem &&
2539         m_rootItems == rhs.m_rootItems;
2540 }
2541 
2542 // ---- ChangeTreeContentsCommand ----
ChangeTreeContentsCommand(QDesignerFormWindowInterface * formWindow)2543 ChangeTreeContentsCommand::ChangeTreeContentsCommand(QDesignerFormWindowInterface *formWindow)
2544     : QDesignerFormWindowCommand(QApplication::translate("Command", "Change Tree Contents"), formWindow),
2545         m_iconCache(nullptr)
2546 {
2547     FormWindowBase *fwb = qobject_cast<FormWindowBase *>(formWindow);
2548     if (fwb)
2549         m_iconCache = fwb->iconCache();
2550 }
2551 
init(QTreeWidget * treeWidget,const TreeWidgetContents & oldState,const TreeWidgetContents & newState)2552 void ChangeTreeContentsCommand::init(QTreeWidget *treeWidget,
2553         const TreeWidgetContents &oldState, const TreeWidgetContents &newState)
2554 {
2555     m_treeWidget = treeWidget;
2556     m_oldState = oldState;
2557     m_newState = newState;
2558 }
2559 
redo()2560 void ChangeTreeContentsCommand::redo()
2561 {
2562     m_newState.applyToTreeWidget(m_treeWidget, m_iconCache, false);
2563 }
2564 
undo()2565 void ChangeTreeContentsCommand::undo()
2566 {
2567     m_oldState.applyToTreeWidget(m_treeWidget, m_iconCache, false);
2568 }
2569 
2570 // ---- ChangeListContentsCommand ----
ChangeListContentsCommand(QDesignerFormWindowInterface * formWindow)2571 ChangeListContentsCommand::ChangeListContentsCommand(QDesignerFormWindowInterface *formWindow)
2572     : QDesignerFormWindowCommand(QString(), formWindow), m_iconCache(nullptr)
2573 {
2574     FormWindowBase *fwb = qobject_cast<FormWindowBase *>(formWindow);
2575     if (fwb)
2576         m_iconCache = fwb->iconCache();
2577 }
2578 
init(QListWidget * listWidget,const ListContents & oldItems,const ListContents & items)2579 void ChangeListContentsCommand::init(QListWidget *listWidget,
2580         const ListContents &oldItems, const ListContents &items)
2581 {
2582     m_listWidget = listWidget;
2583     m_comboBox = nullptr;
2584 
2585     m_newItemsState = items;
2586     m_oldItemsState = oldItems;
2587 }
2588 
init(QComboBox * comboBox,const ListContents & oldItems,const ListContents & items)2589 void ChangeListContentsCommand::init(QComboBox *comboBox,
2590         const ListContents &oldItems, const ListContents &items)
2591 {
2592     m_listWidget = nullptr;
2593     m_comboBox = comboBox;
2594 
2595     m_newItemsState = items;
2596     m_oldItemsState = oldItems;
2597 }
2598 
redo()2599 void ChangeListContentsCommand::redo()
2600 {
2601     if (m_listWidget)
2602         m_newItemsState.applyToListWidget(m_listWidget, m_iconCache, false);
2603     else if (m_comboBox)
2604         m_newItemsState.applyToComboBox(m_comboBox, m_iconCache);
2605 }
2606 
undo()2607 void ChangeListContentsCommand::undo()
2608 {
2609     if (m_listWidget)
2610         m_oldItemsState.applyToListWidget(m_listWidget, m_iconCache, false);
2611     else if (m_comboBox)
2612         m_oldItemsState.applyToComboBox(m_comboBox, m_iconCache);
2613 }
2614 
2615 // ---- AddActionCommand ----
2616 
AddActionCommand(QDesignerFormWindowInterface * formWindow)2617 AddActionCommand::AddActionCommand(QDesignerFormWindowInterface *formWindow) :
2618     QDesignerFormWindowCommand(QApplication::translate("Command", "Add action"), formWindow)
2619 {
2620     m_action = nullptr;
2621 }
2622 
init(QAction * action)2623 void AddActionCommand::init(QAction *action)
2624 {
2625     Q_ASSERT(m_action == nullptr);
2626     m_action = action;
2627 }
2628 
redo()2629 void AddActionCommand::redo()
2630 {
2631     core()->actionEditor()->setFormWindow(formWindow());
2632     core()->actionEditor()->manageAction(m_action);
2633 }
2634 
undo()2635 void AddActionCommand::undo()
2636 {
2637     core()->actionEditor()->setFormWindow(formWindow());
2638     core()->actionEditor()->unmanageAction(m_action);
2639 }
2640 
2641 // ---- RemoveActionCommand ----
2642 
RemoveActionCommand(QDesignerFormWindowInterface * formWindow)2643 RemoveActionCommand::RemoveActionCommand(QDesignerFormWindowInterface *formWindow) :
2644     QDesignerFormWindowCommand(QApplication::translate("Command", "Remove action"), formWindow),
2645     m_action(0)
2646 {
2647 }
2648 
findActionIn(QAction * action)2649 static RemoveActionCommand::ActionData findActionIn(QAction *action)
2650 {
2651     RemoveActionCommand::ActionData result;
2652     // We only want menus and toolbars, no toolbuttons.
2653     const QWidgetList &associatedWidgets = action->associatedWidgets();
2654     for (QWidget *widget : associatedWidgets) {
2655         if (qobject_cast<const QMenu *>(widget) || qobject_cast<const QToolBar *>(widget)) {
2656             const auto actionList = widget->actions();
2657             const int size = actionList.size();
2658             for (int i = 0; i < size; ++i) {
2659                 if (actionList.at(i) == action) {
2660                     QAction *before = nullptr;
2661                     if (i + 1 < size)
2662                         before = actionList.at(i + 1);
2663                     result.append(RemoveActionCommand::ActionDataItem(before, widget));
2664                     break;
2665                 }
2666             }
2667         }
2668     }
2669     return result;
2670 }
2671 
init(QAction * action)2672 void RemoveActionCommand::init(QAction *action)
2673 {
2674     Q_ASSERT(m_action == nullptr);
2675     m_action = action;
2676 
2677     m_actionData = findActionIn(action);
2678 }
2679 
redo()2680 void RemoveActionCommand::redo()
2681 {
2682     QDesignerFormWindowInterface *fw = formWindow();
2683     for (const ActionDataItem &item : qAsConst(m_actionData)) {
2684         item.widget->removeAction(m_action);
2685     }
2686     // Notify components (for example, signal slot editor)
2687     if (qdesigner_internal::FormWindowBase *fwb = qobject_cast<qdesigner_internal::FormWindowBase *>(fw))
2688         fwb->emitObjectRemoved(m_action);
2689 
2690     core()->actionEditor()->setFormWindow(fw);
2691     core()->actionEditor()->unmanageAction(m_action);
2692     if (!m_actionData.isEmpty())
2693         core()->objectInspector()->setFormWindow(fw);
2694 }
2695 
undo()2696 void RemoveActionCommand::undo()
2697 {
2698     core()->actionEditor()->setFormWindow(formWindow());
2699     core()->actionEditor()->manageAction(m_action);
2700     for (const ActionDataItem &item : qAsConst(m_actionData))
2701         item.widget->insertAction(item.before, m_action);
2702     if (!m_actionData.isEmpty())
2703         core()->objectInspector()->setFormWindow(formWindow());
2704 }
2705 
2706 // ---- ActionInsertionCommand ----
2707 
ActionInsertionCommand(const QString & text,QDesignerFormWindowInterface * formWindow)2708 ActionInsertionCommand::ActionInsertionCommand(const QString &text, QDesignerFormWindowInterface *formWindow) :
2709     QDesignerFormWindowCommand(text, formWindow),
2710     m_parentWidget(nullptr),
2711     m_action(nullptr),
2712     m_beforeAction(nullptr),
2713     m_update(false)
2714 {
2715 }
2716 
init(QWidget * parentWidget,QAction * action,QAction * beforeAction,bool update)2717 void ActionInsertionCommand::init(QWidget *parentWidget, QAction *action, QAction *beforeAction, bool update)
2718 {
2719     Q_ASSERT(m_parentWidget == nullptr);
2720     Q_ASSERT(m_action == nullptr);
2721 
2722     m_parentWidget = parentWidget;
2723     m_action = action;
2724     m_beforeAction = beforeAction;
2725     m_update = update;
2726 }
2727 
insertAction()2728 void ActionInsertionCommand::insertAction()
2729 {
2730     Q_ASSERT(m_action != nullptr);
2731     Q_ASSERT(m_parentWidget != nullptr);
2732 
2733     if (m_beforeAction)
2734         m_parentWidget->insertAction(m_beforeAction, m_action);
2735     else
2736         m_parentWidget->addAction(m_action);
2737 
2738     if (m_update) {
2739         cheapUpdate();
2740         if (QMenu *menu = m_action->menu())
2741             selectUnmanagedObject(menu);
2742         else
2743             selectUnmanagedObject(m_action);
2744         PropertyHelper::triggerActionChanged(m_action); // Update Used column in action editor.
2745     }
2746 }
removeAction()2747 void ActionInsertionCommand::removeAction()
2748 {
2749     Q_ASSERT(m_action != nullptr);
2750     Q_ASSERT(m_parentWidget != nullptr);
2751 
2752     if (QDesignerMenu *menu = qobject_cast<QDesignerMenu*>(m_parentWidget))
2753         menu->hideSubMenu();
2754 
2755     m_parentWidget->removeAction(m_action);
2756 
2757     if (m_update) {
2758         cheapUpdate();
2759         selectUnmanagedObject(m_parentWidget);
2760         PropertyHelper::triggerActionChanged(m_action); // Update Used column in action editor.
2761     }
2762 }
2763 
InsertActionIntoCommand(QDesignerFormWindowInterface * formWindow)2764 InsertActionIntoCommand::InsertActionIntoCommand(QDesignerFormWindowInterface *formWindow) :
2765     ActionInsertionCommand(QApplication::translate("Command", "Add action"), formWindow)
2766 {
2767 }
2768 // ---- RemoveActionFromCommand ----
2769 
RemoveActionFromCommand(QDesignerFormWindowInterface * formWindow)2770 RemoveActionFromCommand::RemoveActionFromCommand(QDesignerFormWindowInterface *formWindow) :
2771     ActionInsertionCommand(QApplication::translate("Command", "Remove action"), formWindow)
2772 {
2773 }
2774 
2775 // ---- AddMenuActionCommand ----
2776 
MenuActionCommand(const QString & text,QDesignerFormWindowInterface * formWindow)2777 MenuActionCommand::MenuActionCommand(const QString &text, QDesignerFormWindowInterface *formWindow) :
2778     QDesignerFormWindowCommand(text, formWindow),
2779     m_action(nullptr),
2780     m_actionBefore(nullptr),
2781     m_menuParent(nullptr),
2782     m_associatedWidget(nullptr),
2783     m_objectToSelect(nullptr)
2784 {
2785 }
2786 
init(QAction * action,QAction * actionBefore,QWidget * associatedWidget,QWidget * objectToSelect)2787 void MenuActionCommand::init(QAction *action, QAction *actionBefore,
2788                              QWidget *associatedWidget, QWidget *objectToSelect)
2789 {
2790     QMenu *menu = action->menu();
2791     Q_ASSERT(menu);
2792     m_menuParent = menu->parentWidget();
2793     m_action = action;
2794     m_actionBefore = actionBefore;
2795     m_associatedWidget = associatedWidget;
2796     m_objectToSelect = objectToSelect;
2797 }
2798 
insertMenu()2799 void MenuActionCommand::insertMenu()
2800 {
2801     core()->metaDataBase()->add(m_action);
2802     QMenu *menu = m_action->menu();
2803     if (m_menuParent && menu->parentWidget() != m_menuParent)
2804         menu->setParent(m_menuParent);
2805     core()->metaDataBase()->add(menu);
2806     m_associatedWidget->insertAction(m_actionBefore, m_action);
2807     cheapUpdate();
2808     selectUnmanagedObject(menu);
2809 }
2810 
removeMenu()2811 void MenuActionCommand::removeMenu()
2812 {
2813     m_action->menu()->setParent(nullptr);
2814     QMenu *menu = m_action->menu();
2815     core()->metaDataBase()->remove(menu);
2816     menu->setParent(nullptr);
2817     core()->metaDataBase()->remove(m_action);
2818     m_associatedWidget->removeAction(m_action);
2819     cheapUpdate();
2820     selectUnmanagedObject(m_objectToSelect);
2821 }
2822 
AddMenuActionCommand(QDesignerFormWindowInterface * formWindow)2823 AddMenuActionCommand::AddMenuActionCommand(QDesignerFormWindowInterface *formWindow)  :
2824     MenuActionCommand(QApplication::translate("Command", "Add menu"), formWindow)
2825 {
2826 }
2827 
2828 // ---- RemoveMenuActionCommand ----
RemoveMenuActionCommand(QDesignerFormWindowInterface * formWindow)2829 RemoveMenuActionCommand::RemoveMenuActionCommand(QDesignerFormWindowInterface *formWindow) :
2830     MenuActionCommand(QApplication::translate("Command", "Remove menu"), formWindow)
2831 {
2832 }
2833 
2834 // ---- CreateSubmenuCommand ----
CreateSubmenuCommand(QDesignerFormWindowInterface * formWindow)2835 CreateSubmenuCommand::CreateSubmenuCommand(QDesignerFormWindowInterface *formWindow) :
2836     QDesignerFormWindowCommand(QApplication::translate("Command", "Create submenu"), formWindow),
2837     m_action(nullptr),
2838     m_menu(nullptr),
2839     m_objectToSelect(nullptr)
2840 {
2841 }
2842 
init(QDesignerMenu * menu,QAction * action,QObject * objectToSelect)2843 void CreateSubmenuCommand::init(QDesignerMenu *menu, QAction *action, QObject *objectToSelect)
2844 {
2845     m_menu = menu;
2846     m_action = action;
2847     m_objectToSelect = objectToSelect;
2848 }
2849 
redo()2850 void CreateSubmenuCommand::redo()
2851 {
2852     m_menu->createRealMenuAction(m_action);
2853     cheapUpdate();
2854     if (m_objectToSelect)
2855         selectUnmanagedObject(m_objectToSelect);
2856 }
2857 
undo()2858 void CreateSubmenuCommand::undo()
2859 {
2860     m_menu->removeRealMenu(m_action);
2861     cheapUpdate();
2862     selectUnmanagedObject(m_menu);
2863 }
2864 
2865 // ---- DeleteToolBarCommand ----
DeleteToolBarCommand(QDesignerFormWindowInterface * formWindow)2866 DeleteToolBarCommand::DeleteToolBarCommand(QDesignerFormWindowInterface *formWindow)
2867     : QDesignerFormWindowCommand(QApplication::translate("Command", "Delete Tool Bar"), formWindow)
2868 {
2869 }
2870 
init(QToolBar * toolBar)2871 void DeleteToolBarCommand::init(QToolBar *toolBar)
2872 {
2873     m_toolBar = toolBar;
2874     m_mainWindow = qobject_cast<QMainWindow*>(toolBar->parentWidget());
2875 }
2876 
redo()2877 void DeleteToolBarCommand::redo()
2878 {
2879     if (m_mainWindow) {
2880         QDesignerContainerExtension *c = qt_extension<QDesignerContainerExtension*>(core()->extensionManager(), m_mainWindow);
2881         Q_ASSERT(c != nullptr);
2882         for (int i=0; i<c->count(); ++i) {
2883             if (c->widget(i) == m_toolBar) {
2884                 c->remove(i);
2885                 break;
2886             }
2887         }
2888     }
2889 
2890     core()->metaDataBase()->remove(m_toolBar);
2891     m_toolBar->hide();
2892     m_toolBar->setParent(formWindow());
2893     formWindow()->emitSelectionChanged();
2894 }
2895 
undo()2896 void DeleteToolBarCommand::undo()
2897 {
2898     if (m_mainWindow) {
2899         m_toolBar->setParent(m_mainWindow);
2900         QDesignerContainerExtension *c = qt_extension<QDesignerContainerExtension*>(core()->extensionManager(), m_mainWindow);
2901 
2902         c->addWidget(m_toolBar);
2903 
2904         core()->metaDataBase()->add(m_toolBar);
2905         m_toolBar->show();
2906         formWindow()->emitSelectionChanged();
2907     }
2908 }
2909 
2910 } // namespace qdesigner_internal
2911 
2912 QT_END_NAMESPACE
2913