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 //
30 //  W A R N I N G
31 //  -------------
32 //
33 // This file is not part of the Qt API.  It exists for the convenience
34 // of Qt Designer.  This header
35 // file may change from version to version without notice, or even be removed.
36 //
37 // We mean it.
38 //
39 
40 #ifndef QDESIGNER_COMMAND_H
41 #define QDESIGNER_COMMAND_H
42 
43 #include "shared_global_p.h"
44 #include "shared_enums_p.h"
45 #include "layoutinfo_p.h"
46 #include "qdesigner_utils_p.h"
47 #include "qdesigner_formwindowcommand_p.h"
48 #include "qdesigner_formeditorcommand_p.h"
49 
50 #include <QtDesigner/layoutdecoration.h>
51 
52 #include <QtGui/qicon.h>
53 #include <QtCore/qobject.h>
54 #include <QtCore/qpair.h>
55 #include <QtCore/qmap.h>
56 #include <QtCore/qhash.h>
57 #include <QtCore/qpoint.h>
58 #include <QtCore/qrect.h>
59 #include <QtCore/qvector.h>
60 
61 QT_BEGIN_NAMESPACE
62 
63 class QDesignerContainerExtension;
64 class QDesignerMetaDataBaseItemInterface;
65 class QDesignerMenu;
66 
67 class QMenuBar;
68 class QStatusBar;
69 class QToolBar;
70 class QToolBox;
71 class QTabWidget;
72 class QTableWidget;
73 class QTableWidgetItem;
74 class QTreeWidget;
75 class QTreeWidgetItem;
76 class QListWidget;
77 class QListWidgetItem;
78 class QComboBox;
79 class QStackedWidget;
80 class QDockWidget;
81 class QMainWindow;
82 class QFormLayout;
83 
84 namespace qdesigner_internal {
85 
86 class Layout;
87 class LayoutHelper;
88 class PropertySheetIconValue;
89 class DesignerIconCache;
90 struct LayoutProperties;
91 
92 class QDESIGNER_SHARED_EXPORT InsertWidgetCommand: public QDesignerFormWindowCommand
93 {
94 
95 public:
96     explicit InsertWidgetCommand(QDesignerFormWindowInterface *formWindow);
97     ~InsertWidgetCommand() override;
98 
99     void init(QWidget *widget, bool already_in_form = false, int layoutRow = -1, int layoutColumn = -1);
100 
101     void redo() override;
102     void undo() override;
103 
104 private:
105     void refreshBuddyLabels();
106 
107     QPointer<QWidget> m_widget;
108     QDesignerLayoutDecorationExtension::InsertMode m_insertMode;
109     QPair<int, int> m_cell;
110     LayoutHelper* m_layoutHelper;
111     bool m_widgetWasManaged;
112 };
113 
114 class QDESIGNER_SHARED_EXPORT ChangeZOrderCommand: public QDesignerFormWindowCommand
115 {
116 
117 public:
118     explicit ChangeZOrderCommand(QDesignerFormWindowInterface *formWindow);
119 
120     void init(QWidget *widget);
121 
122     void redo() override;
123     void undo() override;
124 protected:
125     virtual QWidgetList reorderWidget(const QWidgetList &list, QWidget *widget) const = 0;
126     virtual void reorder(QWidget *widget) const = 0;
127 
128 private:
129     QPointer<QWidget> m_widget;
130     QPointer<QWidget> m_oldPreceding;
131     QWidgetList m_oldParentZOrder;
132 };
133 
134 class QDESIGNER_SHARED_EXPORT RaiseWidgetCommand: public ChangeZOrderCommand
135 {
136 
137 public:
138     explicit RaiseWidgetCommand(QDesignerFormWindowInterface *formWindow);
139 
140     void init(QWidget *widget);
141 
142 protected:
143     QWidgetList reorderWidget(const QWidgetList &list, QWidget *widget) const override;
144     void reorder(QWidget *widget) const override;
145 };
146 
147 class QDESIGNER_SHARED_EXPORT LowerWidgetCommand: public ChangeZOrderCommand
148 {
149 
150 public:
151     explicit LowerWidgetCommand(QDesignerFormWindowInterface *formWindow);
152 
153     void init(QWidget *widget);
154 
155 protected:
156     QWidgetList reorderWidget(const QWidgetList &list, QWidget *widget) const override;
157     void reorder(QWidget *widget) const override;
158 };
159 
160 class QDESIGNER_SHARED_EXPORT AdjustWidgetSizeCommand: public QDesignerFormWindowCommand
161 {
162 
163 public:
164     explicit AdjustWidgetSizeCommand(QDesignerFormWindowInterface *formWindow);
165 
166     void init(QWidget *widget);
167 
168     void redo() override;
169     void undo() override;
170 
171 private:
172     QWidget *widgetForAdjust() const;
173     bool adjustNonLaidOutMainContainer(QWidget *integrationContainer);
174     void updatePropertyEditor() const;
175 
176     QPointer<QWidget> m_widget;
177     QRect m_geometry;
178 };
179 
180 // Helper to correctly unmanage a widget and its children for delete operations
181 class  QDESIGNER_SHARED_EXPORT ManageWidgetCommandHelper {
182 public:
183     using WidgetVector = QVector<QWidget *>;
184 
185     ManageWidgetCommandHelper();
186     void init(const QDesignerFormWindowInterface *fw, QWidget *widget);
187     void init(QWidget *widget, const WidgetVector &managedChildren);
188 
189     void manage(QDesignerFormWindowInterface *fw);
190     void unmanage(QDesignerFormWindowInterface *fw);
191 
managedChildren()192     const WidgetVector &managedChildren() const { return m_managedChildren; }
193 private:
194     QWidget *m_widget = nullptr;
195     WidgetVector m_managedChildren;
196 };
197 
198 class QDESIGNER_SHARED_EXPORT DeleteWidgetCommand: public QDesignerFormWindowCommand
199 {
200 
201 public:
202     explicit DeleteWidgetCommand(QDesignerFormWindowInterface *formWindow);
203     ~DeleteWidgetCommand() override;
204 
205     enum DeleteFlags { DoNotUnmanage = 0x1, DoNotSimplifyLayout = 0x2 };
206 
207     void init(QWidget *widget, unsigned flags = 0);
208 
209     void redo() override;
210     void undo() override;
211 
212 private:
213     QPointer<QWidget> m_widget;
214     QPointer<QWidget> m_parentWidget;
215     QRect m_geometry;
216     LayoutInfo::Type m_layoutType;
217     LayoutHelper* m_layoutHelper;
218     unsigned m_flags;
219     QRect m_layoutPosition;
220     int m_splitterIndex;
221     bool m_layoutSimplified;
222     QDesignerMetaDataBaseItemInterface *m_formItem;
223     int m_tabOrderIndex;
224     int m_widgetOrderIndex;
225     int m_zOrderIndex;
226     ManageWidgetCommandHelper m_manageHelper;
227 };
228 
229 class QDESIGNER_SHARED_EXPORT ReparentWidgetCommand: public QDesignerFormWindowCommand
230 {
231 
232 public:
233     explicit ReparentWidgetCommand(QDesignerFormWindowInterface *formWindow);
234 
235     void init(QWidget *widget, QWidget *parentWidget);
236 
237     void redo() override;
238     void undo() override;
239 
240 private:
241     QPointer<QWidget> m_widget;
242     QPoint m_oldPos;
243     QPoint m_newPos;
244     QPointer<QWidget> m_oldParentWidget;
245     QPointer<QWidget> m_newParentWidget;
246     QWidgetList m_oldParentList;
247     QWidgetList m_oldParentZOrder;
248 };
249 
250 class QDESIGNER_SHARED_EXPORT ChangeFormLayoutItemRoleCommand : public QDesignerFormWindowCommand
251 {
252 public:
253     enum Operation { SpanningToLabel = 0x1, SpanningToField = 0x2, LabelToSpanning = 0x4, FieldToSpanning =0x8 };
254 
255     explicit ChangeFormLayoutItemRoleCommand(QDesignerFormWindowInterface *formWindow);
256 
257     void init(QWidget *widget, Operation op);
258 
259     void redo() override;
260     void undo() override;
261 
262     // Return a mask of possible operations of that item
263     static unsigned possibleOperations(QDesignerFormEditorInterface *core, QWidget *w);
264 
265 private:
266     static QFormLayout *managedFormLayoutOf(QDesignerFormEditorInterface *core, QWidget *w);
267     static Operation reverseOperation(Operation op);
268     void doOperation(Operation op);
269 
270     QPointer<QWidget> m_widget;
271     Operation m_operation;
272 };
273 
274 class QDESIGNER_SHARED_EXPORT ChangeLayoutItemGeometry: public QDesignerFormWindowCommand
275 {
276 
277 public:
278     explicit ChangeLayoutItemGeometry(QDesignerFormWindowInterface *formWindow);
279 
280     void init(QWidget *widget, int row, int column, int rowspan, int colspan);
281 
282     void redo() override;
283     void undo() override;
284 
285 protected:
286     void changeItemPosition(const QRect &g);
287 
288 private:
289     QPointer<QWidget> m_widget;
290     QRect m_oldInfo;
291     QRect m_newInfo;
292 };
293 
294 class QDESIGNER_SHARED_EXPORT TabOrderCommand: public QDesignerFormWindowCommand
295 {
296 
297 public:
298     explicit TabOrderCommand(QDesignerFormWindowInterface *formWindow);
299 
300     void init(const QWidgetList &newTabOrder);
301 
oldTabOrder()302     inline QWidgetList oldTabOrder() const
303     { return m_oldTabOrder; }
304 
newTabOrder()305     inline QWidgetList newTabOrder() const
306     { return m_newTabOrder; }
307 
308     void redo() override;
309     void undo() override;
310 
311 private:
312     QDesignerMetaDataBaseItemInterface *m_widgetItem;
313     QWidgetList m_oldTabOrder;
314     QWidgetList m_newTabOrder;
315 };
316 
317 class QDESIGNER_SHARED_EXPORT PromoteToCustomWidgetCommand : public QDesignerFormWindowCommand
318 {
319 public:
320     using WidgetPointerList = QVector<QPointer<QWidget> >;
321 
322     explicit PromoteToCustomWidgetCommand(QDesignerFormWindowInterface *formWindow);
323 
324     void init(const WidgetPointerList &widgets, const QString &customClassName);
325     void redo() override;
326     void undo() override;
327 
328 private:
329     void updateSelection();
330     WidgetPointerList m_widgets;
331     QString m_customClassName;
332 };
333 
334 class QDESIGNER_SHARED_EXPORT DemoteFromCustomWidgetCommand : public QDesignerFormWindowCommand
335 {
336 public:
337     using WidgetList = PromoteToCustomWidgetCommand::WidgetPointerList;
338 
339     explicit DemoteFromCustomWidgetCommand(QDesignerFormWindowInterface *formWindow);
340 
341     void init(const WidgetList &promoted);
342     void redo() override;
343     void undo() override;
344 private:
345     PromoteToCustomWidgetCommand m_promote_cmd;
346 };
347 
348 // Mixin class for storing the selection state
349 class QDESIGNER_SHARED_EXPORT CursorSelectionState {
350     Q_DISABLE_COPY_MOVE(CursorSelectionState)
351 public:
352     CursorSelectionState();
353 
354     void save(const QDesignerFormWindowInterface *formWindow);
355     void restore(QDesignerFormWindowInterface *formWindow) const;
356 
357 private:
358     using WidgetPointerList = QVector<QPointer<QWidget> >;
359     WidgetPointerList m_selection;
360     QPointer<QWidget> m_current;
361 };
362 
363 class QDESIGNER_SHARED_EXPORT LayoutCommand: public QDesignerFormWindowCommand
364 {
365 
366 public:
367     explicit LayoutCommand(QDesignerFormWindowInterface *formWindow);
368     ~LayoutCommand() override;
369 
widgets()370     inline QWidgetList widgets() const { return m_widgets; }
371 
372     void init(QWidget *parentWidget, const QWidgetList &widgets, LayoutInfo::Type layoutType,
373               QWidget *layoutBase = nullptr,
374               // Reparent/Hide instances of QLayoutWidget.
375               bool reparentLayoutWidget = true);
376 
377     void redo() override;
378     void undo() override;
379 
380 private:
381     QPointer<QWidget> m_parentWidget;
382     QWidgetList m_widgets;
383     QPointer<QWidget> m_layoutBase;
384     QPointer<Layout> m_layout;
385     CursorSelectionState m_cursorSelectionState;
386     bool m_setup;
387 };
388 
389 class QDESIGNER_SHARED_EXPORT BreakLayoutCommand: public QDesignerFormWindowCommand
390 {
391 
392 public:
393     explicit BreakLayoutCommand(QDesignerFormWindowInterface *formWindow);
394     ~BreakLayoutCommand() override;
395 
widgets()396     inline QWidgetList widgets() const { return m_widgets; }
397 
398     void init(const QWidgetList &widgets, QWidget *layoutBase,
399               // Reparent/Hide instances of QLayoutWidget.
400               bool reparentLayoutWidget = true);
401 
402     void redo() override;
403     void undo() override;
404 
405     // Access the properties of the layout, 0 in case of splitters.
406     const LayoutProperties *layoutProperties() const;
407     int propertyMask() const;
408 
409 private:
410     QWidgetList m_widgets;
411     QPointer<QWidget> m_layoutBase;
412     QPointer<Layout> m_layout;
413     LayoutHelper* m_layoutHelper;
414     LayoutProperties *m_properties;
415     int m_propertyMask;
416     CursorSelectionState m_cursorSelectionState;
417 };
418 
419 class QDESIGNER_SHARED_EXPORT SimplifyLayoutCommand: public QDesignerFormWindowCommand
420 {
421 public:
422     explicit SimplifyLayoutCommand(QDesignerFormWindowInterface *formWindow);
423     ~SimplifyLayoutCommand() override;
424 
425     bool init(QWidget *layoutBase);
426 
427     // Quick check
428     static bool canSimplify(QDesignerFormEditorInterface *core, const QWidget *w, int *layoutType = nullptr);
429 
430     void redo() override;
431     void undo() override;
432 
433 private:
434     const QRect m_area;
435     QWidget *m_layoutBase;
436     LayoutHelper* m_layoutHelper;
437     bool m_layoutSimplified;
438 };
439 
440 class ToolBoxCommand: public QDesignerFormWindowCommand
441 {
442 
443 public:
444     explicit ToolBoxCommand(QDesignerFormWindowInterface *formWindow);
445     ~ToolBoxCommand() override;
446 
447     void init(QToolBox *toolBox);
448 
449 protected:
450     void removePage();
451     void addPage();
452 
453     QPointer<QToolBox> m_toolBox;
454     QPointer<QWidget> m_widget;
455     int m_index;
456     QString m_itemText;
457     QIcon m_itemIcon;
458 };
459 
460 class MoveToolBoxPageCommand: public ToolBoxCommand
461 {
462 
463 public:
464     explicit MoveToolBoxPageCommand(QDesignerFormWindowInterface *formWindow);
465     ~MoveToolBoxPageCommand() override;
466 
467     void init(QToolBox *toolBox, QWidget *page, int newIndex);
468 
469     void redo() override;
470     void undo() override;
471 
472 private:
473     int m_newIndex;
474     int m_oldIndex;
475 };
476 
477 class DeleteToolBoxPageCommand: public ToolBoxCommand
478 {
479 
480 public:
481     explicit DeleteToolBoxPageCommand(QDesignerFormWindowInterface *formWindow);
482     ~DeleteToolBoxPageCommand() override;
483 
484     void init(QToolBox *toolBox);
485 
486     void redo() override;
487     void undo() override;
488 };
489 
490 class AddToolBoxPageCommand: public ToolBoxCommand
491 {
492 
493 public:
494     enum InsertionMode {
495         InsertBefore,
496         InsertAfter
497     };
498     explicit AddToolBoxPageCommand(QDesignerFormWindowInterface *formWindow);
499     ~AddToolBoxPageCommand() override;
500 
501     void init(QToolBox *toolBox);
502     void init(QToolBox *toolBox, InsertionMode mode);
503 
504     void redo() override;
505     void undo() override;
506 };
507 
508 class TabWidgetCommand: public QDesignerFormWindowCommand
509 {
510 
511 public:
512     explicit TabWidgetCommand(QDesignerFormWindowInterface *formWindow);
513     ~TabWidgetCommand() override;
514 
515     void init(QTabWidget *tabWidget);
516 
517 protected:
518     void removePage();
519     void addPage();
520 
521     QPointer<QTabWidget> m_tabWidget;
522     QPointer<QWidget> m_widget;
523     int m_index;
524     QString m_itemText;
525     QIcon m_itemIcon;
526 };
527 
528 class DeleteTabPageCommand: public TabWidgetCommand
529 {
530 
531 public:
532     explicit DeleteTabPageCommand(QDesignerFormWindowInterface *formWindow);
533     ~DeleteTabPageCommand() override;
534 
535     void init(QTabWidget *tabWidget);
536 
537     void redo() override;
538     void undo() override;
539 };
540 
541 class AddTabPageCommand: public TabWidgetCommand
542 {
543 
544 public:
545     enum InsertionMode {
546         InsertBefore,
547         InsertAfter
548     };
549     explicit AddTabPageCommand(QDesignerFormWindowInterface *formWindow);
550     ~AddTabPageCommand() override;
551 
552     void init(QTabWidget *tabWidget);
553     void init(QTabWidget *tabWidget, InsertionMode mode);
554 
555     void redo() override;
556     void undo() override;
557 };
558 
559 class MoveTabPageCommand: public TabWidgetCommand
560 {
561 
562 public:
563     explicit MoveTabPageCommand(QDesignerFormWindowInterface *formWindow);
564     ~MoveTabPageCommand() override;
565 
566     void init(QTabWidget *tabWidget, QWidget *page,
567                       const QIcon &icon, const QString &label,
568                       int index, int newIndex);
569 
570     void redo() override;
571     void undo() override;
572 
573 private:
574     int m_newIndex;
575     int m_oldIndex;
576     QPointer<QWidget> m_page;
577     QString m_label;
578     QIcon m_icon;
579 };
580 
581 class StackedWidgetCommand: public QDesignerFormWindowCommand
582 {
583 
584 public:
585     explicit StackedWidgetCommand(QDesignerFormWindowInterface *formWindow);
586     ~StackedWidgetCommand() override;
587 
588     void init(QStackedWidget *stackedWidget);
589 
590 protected:
591     void removePage();
592     void addPage();
593 
594     QPointer<QStackedWidget> m_stackedWidget;
595     QPointer<QWidget> m_widget;
596     int m_index;
597 };
598 
599 class MoveStackedWidgetCommand: public StackedWidgetCommand
600 {
601 
602 public:
603     explicit MoveStackedWidgetCommand(QDesignerFormWindowInterface *formWindow);
604     ~MoveStackedWidgetCommand() override;
605 
606     void init(QStackedWidget *stackedWidget, QWidget *page, int newIndex);
607 
608     void redo() override;
609     void undo() override;
610 
611 private:
612     int m_newIndex;
613     int m_oldIndex;
614 };
615 
616 class DeleteStackedWidgetPageCommand: public StackedWidgetCommand
617 {
618 
619 public:
620     explicit DeleteStackedWidgetPageCommand(QDesignerFormWindowInterface *formWindow);
621     ~DeleteStackedWidgetPageCommand() override;
622 
623     void init(QStackedWidget *stackedWidget);
624 
625     void redo() override;
626     void undo() override;
627 };
628 
629 class AddStackedWidgetPageCommand: public StackedWidgetCommand
630 {
631 
632 public:
633     enum InsertionMode {
634         InsertBefore,
635         InsertAfter
636     };
637     explicit AddStackedWidgetPageCommand(QDesignerFormWindowInterface *formWindow);
638     ~AddStackedWidgetPageCommand() override;
639 
640     void init(QStackedWidget *stackedWidget);
641     void init(QStackedWidget *stackedWidget, InsertionMode mode);
642 
643     void redo() override;
644     void undo() override;
645 };
646 
647 class  CreateMenuBarCommand: public QDesignerFormWindowCommand
648 {
649 
650 public:
651     explicit CreateMenuBarCommand(QDesignerFormWindowInterface *formWindow);
652 
653     void init(QMainWindow *mainWindow);
654 
655     void undo() override;
656     void redo() override;
657 
658 private:
659     QPointer<QMainWindow> m_mainWindow;
660     QPointer<QMenuBar> m_menuBar;
661 };
662 
663 class DeleteMenuBarCommand: public QDesignerFormWindowCommand
664 {
665 
666 public:
667     explicit DeleteMenuBarCommand(QDesignerFormWindowInterface *formWindow);
668 
669     void init(QMenuBar *menuBar);
670 
671     void undo() override;
672     void redo() override;
673 
674 private:
675     QPointer<QMainWindow> m_mainWindow;
676     QPointer<QMenuBar> m_menuBar;
677 };
678 
679 class CreateStatusBarCommand: public QDesignerFormWindowCommand
680 {
681 
682 public:
683     explicit CreateStatusBarCommand(QDesignerFormWindowInterface *formWindow);
684 
685     void init(QMainWindow *mainWindow);
686 
687     void undo() override;
688     void redo() override;
689 
690 private:
691     QPointer<QMainWindow> m_mainWindow;
692     QPointer<QStatusBar> m_statusBar;
693 };
694 
695 class QDESIGNER_SHARED_EXPORT DeleteStatusBarCommand: public QDesignerFormWindowCommand
696 {
697 
698 public:
699     explicit DeleteStatusBarCommand(QDesignerFormWindowInterface *formWindow);
700 
701     void init(QStatusBar *statusBar);
702 
703     void undo() override;
704     void redo() override;
705 
706 private:
707     QPointer<QMainWindow> m_mainWindow;
708     QPointer<QStatusBar> m_statusBar;
709 };
710 
711 class AddToolBarCommand: public QDesignerFormWindowCommand
712 {
713 
714 public:
715     explicit AddToolBarCommand(QDesignerFormWindowInterface *formWindow);
716 
717     void init(QMainWindow *mainWindow, Qt::ToolBarArea area);
718 
719     void undo() override;
720     void redo() override;
721 
722 private:
723     QPointer<QMainWindow> m_mainWindow;
724     QPointer<QToolBar> m_toolBar;
725 };
726 
727 class DeleteToolBarCommand: public QDesignerFormWindowCommand
728 {
729 
730 public:
731     explicit DeleteToolBarCommand(QDesignerFormWindowInterface *formWindow);
732 
733     void init(QToolBar *toolBar);
734 
735     void undo() override;
736     void redo() override;
737 
738 private:
739     QPointer<QMainWindow> m_mainWindow;
740     QPointer<QToolBar> m_toolBar;
741 };
742 
743 class DockWidgetCommand: public QDesignerFormWindowCommand
744 {
745 
746 public:
747     explicit DockWidgetCommand(const QString &description, QDesignerFormWindowInterface *formWindow);
748     ~DockWidgetCommand() override;
749 
750     void init(QDockWidget *dockWidget);
751 
752 protected:
753     QPointer<QDockWidget> m_dockWidget;
754 };
755 
756 class AddDockWidgetCommand: public QDesignerFormWindowCommand
757 {
758 
759 public:
760     explicit AddDockWidgetCommand(QDesignerFormWindowInterface *formWindow);
761 
762     void init(QMainWindow *mainWindow, QDockWidget *dockWidget);
763     void init(QMainWindow *mainWindow);
764 
765     void undo() override;
766     void redo() override;
767 
768 private:
769     QPointer<QMainWindow> m_mainWindow;
770     QPointer<QDockWidget> m_dockWidget;
771 };
772 
773 class QDESIGNER_SHARED_EXPORT ContainerWidgetCommand: public QDesignerFormWindowCommand
774 {
775 
776 public:
777     explicit ContainerWidgetCommand(QDesignerFormWindowInterface *formWindow);
778     ~ContainerWidgetCommand() override;
779 
780     QDesignerContainerExtension *containerExtension() const;
781 
782     void init(QWidget *containerWidget);
783 
784 protected:
785     void removePage();
786     void addPage();
787 
788     QPointer<QWidget> m_containerWidget;
789     QPointer<QWidget> m_widget;
790     int m_index;
791 };
792 
793 class QDESIGNER_SHARED_EXPORT DeleteContainerWidgetPageCommand: public ContainerWidgetCommand
794 {
795 
796 public:
797     explicit DeleteContainerWidgetPageCommand(QDesignerFormWindowInterface *formWindow);
798     ~DeleteContainerWidgetPageCommand() override;
799 
800     void init(QWidget *containerWidget, ContainerType ct);
801 
802     void redo() override;
803     void undo() override;
804 };
805 
806 class QDESIGNER_SHARED_EXPORT AddContainerWidgetPageCommand: public ContainerWidgetCommand
807 {
808 
809 public:
810     enum InsertionMode {
811         InsertBefore,
812         InsertAfter
813     };
814     explicit AddContainerWidgetPageCommand(QDesignerFormWindowInterface *formWindow);
815     ~AddContainerWidgetPageCommand() override;
816 
817     void init(QWidget *containerWidget, ContainerType ct, InsertionMode mode);
818 
819     void redo() override;
820     void undo() override;
821 };
822 
823 class QDESIGNER_SHARED_EXPORT ChangeCurrentPageCommand: public QDesignerFormWindowCommand
824 {
825 
826 public:
827     explicit ChangeCurrentPageCommand(QDesignerFormWindowInterface *formWindow);
828     ~ChangeCurrentPageCommand() override;
829 
830     QDesignerContainerExtension *containerExtension() const;
831 
832     void init(QWidget *containerWidget, int newIndex);
833 
834     void redo() override;
835     void undo() override;
836 
837 protected:
838     QPointer<QWidget> m_containerWidget;
839     QPointer<QWidget> m_widget;
840     int m_oldIndex;
841     int m_newIndex;
842 };
843 
844 struct QDESIGNER_SHARED_EXPORT ItemData {
845     ItemData() = default;
846 
847     ItemData(const QListWidgetItem *item, bool editor);
848     ItemData(const QTableWidgetItem *item, bool editor);
849     ItemData(const QTreeWidgetItem *item, int column);
850     QListWidgetItem *createListItem(DesignerIconCache *iconCache, bool editor) const;
851     QTableWidgetItem *createTableItem(DesignerIconCache *iconCache, bool editor) const;
852     void fillTreeItemColumn(QTreeWidgetItem *item, int column, DesignerIconCache *iconCache) const;
853 
isValidItemData854     bool isValid() const { return !m_properties.isEmpty(); }
855     bool operator==(const ItemData &rhs) const { return m_properties == rhs.m_properties; }
856     bool operator!=(const ItemData &rhs) const { return m_properties != rhs.m_properties; }
857 
858     QHash<int, QVariant> m_properties;
859 };
860 
861 struct QDESIGNER_SHARED_EXPORT ListContents {
862     ListContents() = default;
863 
864     ListContents(const QTreeWidgetItem *item);
865     QTreeWidgetItem *createTreeItem(DesignerIconCache *iconCache) const;
866 
867     void createFromListWidget(const QListWidget *listWidget, bool editor);
868     void applyToListWidget(QListWidget *listWidget, DesignerIconCache *iconCache, bool editor) const;
869     void createFromComboBox(const QComboBox *listWidget);
870     void applyToComboBox(QComboBox *listWidget, DesignerIconCache *iconCache) const;
871 
872     bool operator==(const ListContents &rhs) const { return m_items == rhs.m_items; }
873     bool operator!=(const ListContents &rhs) const { return m_items != rhs.m_items; }
874 
875     QVector<ItemData> m_items;
876 };
877 
878 // Data structure representing the contents of a QTableWidget with
879 // methods to retrieve and apply for ChangeTableContentsCommand
880 struct QDESIGNER_SHARED_EXPORT TableWidgetContents {
881 
882     using CellRowColumnAddress = QPair<int, int>;
883     using TableItemMap = QMap<CellRowColumnAddress, ItemData>;
884 
885     TableWidgetContents();
886     void clear();
887 
888     void fromTableWidget(const QTableWidget *tableWidget, bool editor);
889     void applyToTableWidget(QTableWidget *tableWidget, DesignerIconCache *iconCache, bool editor) const;
890 
891     bool operator==(const TableWidgetContents &rhs) const;
892     bool operator!=(const TableWidgetContents &rhs) const { return !(*this == rhs); }
893 
894     static bool nonEmpty(const QTableWidgetItem *item, int headerColumn);
895     static QString defaultHeaderText(int i);
896     static void insertHeaderItem(const QTableWidgetItem *item, int i, ListContents *header, bool editor);
897 
898     int m_columnCount = 0;
899     int m_rowCount = 0;
900     ListContents m_horizontalHeader;
901     ListContents m_verticalHeader;
902     TableItemMap m_items;
903 };
904 
905 class QDESIGNER_SHARED_EXPORT ChangeTableContentsCommand: public QDesignerFormWindowCommand
906 {
907 public:
908     explicit ChangeTableContentsCommand(QDesignerFormWindowInterface *formWindow);
909 
910     void init(QTableWidget *tableWidget, const TableWidgetContents &oldCont, const TableWidgetContents &newCont);
911     void redo() override;
912     void undo() override;
913 
914 private:
915     QPointer<QTableWidget> m_tableWidget;
916     TableWidgetContents m_oldContents;
917     TableWidgetContents m_newContents;
918     DesignerIconCache *m_iconCache;
919 };
920 
921 // Data structure representing the contents of a QTreeWidget with
922 // methods to retrieve and apply for ChangeTreeContentsCommand
923 struct QDESIGNER_SHARED_EXPORT TreeWidgetContents {
924 
925     struct ItemContents : public ListContents {
926         ItemContents() = default;
927         ItemContents(const QTreeWidgetItem *item, bool editor);
928         QTreeWidgetItem *createTreeItem(DesignerIconCache *iconCache, bool editor) const;
929 
930         bool operator==(const ItemContents &rhs) const;
931         bool operator!=(const ItemContents &rhs) const { return !(*this == rhs); }
932 
933         int m_itemFlags = -1;
934         //bool m_firstColumnSpanned:1;
935         //bool m_hidden:1;
936         //bool m_expanded:1;
937         QVector<ItemContents> m_children;
938     };
939 
940     void clear();
941 
942     void fromTreeWidget(const QTreeWidget *treeWidget, bool editor);
943     void applyToTreeWidget(QTreeWidget *treeWidget, DesignerIconCache *iconCache, bool editor) const;
944 
945     bool operator==(const TreeWidgetContents &rhs) const;
946     bool operator!=(const TreeWidgetContents &rhs) const { return !(*this == rhs); }
947 
948     ListContents m_headerItem;
949     QVector<ItemContents> m_rootItems;
950 };
951 
952 class QDESIGNER_SHARED_EXPORT ChangeTreeContentsCommand: public QDesignerFormWindowCommand
953 {
954 
955 public:
956     explicit ChangeTreeContentsCommand(QDesignerFormWindowInterface *formWindow);
957 
958     void init(QTreeWidget *treeWidget, const TreeWidgetContents &oldState, const TreeWidgetContents &newState);
959     void redo() override;
960     void undo() override;
961     enum ApplyIconStrategy {
962         SetIconStrategy,
963         ResetIconStrategy
964     };
965 private:
966     QPointer<QTreeWidget> m_treeWidget;
967     TreeWidgetContents m_oldState;
968     TreeWidgetContents m_newState;
969     DesignerIconCache *m_iconCache;
970 };
971 
972 class QDESIGNER_SHARED_EXPORT ChangeListContentsCommand: public QDesignerFormWindowCommand
973 {
974 
975 public:
976     explicit ChangeListContentsCommand(QDesignerFormWindowInterface *formWindow);
977 
978     void init(QListWidget *listWidget, const ListContents &oldItems, const ListContents &items);
979     void init(QComboBox *comboBox, const ListContents &oldItems, const ListContents &items);
980     void redo() override;
981     void undo() override;
982 private:
983     QPointer<QListWidget> m_listWidget;
984     QPointer<QComboBox> m_comboBox;
985     ListContents m_oldItemsState;
986     ListContents m_newItemsState;
987     DesignerIconCache *m_iconCache;
988 };
989 
990 class QDESIGNER_SHARED_EXPORT AddActionCommand : public QDesignerFormWindowCommand
991 {
992 
993 public:
994     explicit AddActionCommand(QDesignerFormWindowInterface *formWindow);
995     void init(QAction *action);
996     void redo() override;
997     void undo() override;
998 private:
999     QAction *m_action;
1000 };
1001 
1002 // Note: This command must be executed within a macro since it
1003 // makes the form emit objectRemoved() which might cause other components
1004 // to add commands (for example, removal of signals and slots
1005 class QDESIGNER_SHARED_EXPORT RemoveActionCommand : public QDesignerFormWindowCommand
1006 {
1007 
1008 public:
1009     explicit RemoveActionCommand(QDesignerFormWindowInterface *formWindow);
1010     void init(QAction *action);
1011     void redo() override;
1012     void undo() override;
1013 
1014     struct ActionDataItem {
1015         ActionDataItem(QAction *_before = nullptr, QWidget *_widget = nullptr)
beforeActionDataItem1016             : before(_before), widget(_widget) {}
1017         QAction *before;
1018         QWidget *widget;
1019     };
1020     using ActionData = QVector<ActionDataItem>;
1021 
1022 private:
1023     QAction *m_action;
1024 
1025     ActionData m_actionData;
1026 };
1027 
1028 class ActionInsertionCommand : public QDesignerFormWindowCommand
1029 {
1030 
1031 protected:
1032     ActionInsertionCommand(const QString &text, QDesignerFormWindowInterface *formWindow);
1033 
1034 public:
1035     void init(QWidget *parentWidget, QAction *action, QAction *beforeAction = nullptr, bool update = true);
1036 
1037 protected:
1038     void insertAction();
1039     void removeAction();
1040 
1041 private:
1042     QWidget *m_parentWidget;
1043     QAction *m_action;
1044     QAction *m_beforeAction;
1045     bool m_update;
1046 };
1047 
1048 class InsertActionIntoCommand : public ActionInsertionCommand
1049 {
1050 
1051 public:
1052     explicit InsertActionIntoCommand(QDesignerFormWindowInterface *formWindow);
1053 
redo()1054     void redo() override {  insertAction(); }
undo()1055     void undo() override {  removeAction(); }
1056 };
1057 
1058 class RemoveActionFromCommand : public ActionInsertionCommand
1059 {
1060 
1061 public:
1062     explicit RemoveActionFromCommand(QDesignerFormWindowInterface *formWindow);
1063 
redo()1064     void redo() override {  removeAction(); }
undo()1065     void undo() override {  insertAction(); }
1066 };
1067 
1068 class MenuActionCommand : public QDesignerFormWindowCommand
1069 {
1070 public:
1071     void init(QAction *action, QAction *actionBefore, QWidget *associatedWidget, QWidget *objectToSelect);
1072 
1073 protected:
1074     MenuActionCommand(const QString &text, QDesignerFormWindowInterface *formWindow);
1075     void insertMenu();
1076     void removeMenu();
1077 
1078 private:
1079     QAction *m_action;
1080     QAction *m_actionBefore;
1081     QWidget *m_menuParent;
1082     QWidget *m_associatedWidget;
1083     QWidget *m_objectToSelect;
1084 };
1085 
1086 class AddMenuActionCommand : public MenuActionCommand
1087 {
1088 
1089 public:
1090     explicit AddMenuActionCommand(QDesignerFormWindowInterface *formWindow);
1091 
redo()1092     void redo() override { insertMenu(); }
undo()1093     void undo() override { removeMenu(); }
1094 };
1095 
1096 class RemoveMenuActionCommand : public MenuActionCommand
1097 {
1098 
1099 public:
1100     explicit RemoveMenuActionCommand(QDesignerFormWindowInterface *formWindow);
1101 
redo()1102     void redo() override { removeMenu(); }
undo()1103     void undo() override { insertMenu(); }
1104 };
1105 
1106 class CreateSubmenuCommand : public QDesignerFormWindowCommand
1107 {
1108 
1109 public:
1110     explicit CreateSubmenuCommand(QDesignerFormWindowInterface *formWindow);
1111     void init(QDesignerMenu *menu, QAction *action, QObject *m_objectToSelect = nullptr);
1112     void redo() override;
1113     void undo() override;
1114 private:
1115     QAction *m_action;
1116     QDesignerMenu *m_menu;
1117     QObject *m_objectToSelect;
1118 };
1119 
1120 } // namespace qdesigner_internal
1121 
1122 QT_END_NAMESPACE
1123 
1124 #endif // QDESIGNER_COMMAND_H
1125