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_PROPERTYCOMMAND_H |
41 | #define QDESIGNER_PROPERTYCOMMAND_H |
42 | |
43 | #include "qdesigner_formwindowcommand_p.h" |
44 | |
45 | #include <QtCore/qvariant.h> |
46 | #include <QtCore/qlist.h> |
47 | #include <QtCore/qpair.h> |
48 | #include <QtCore/qsharedpointer.h> |
49 | |
50 | QT_BEGIN_NAMESPACE |
51 | |
52 | class QDesignerFormWindowInterface; |
53 | class QDesignerPropertySheetExtension; |
54 | class QDesignerIntegration; |
55 | |
56 | namespace qdesigner_internal { |
57 | |
58 | enum SpecialProperty { |
59 | SP_None, SP_ObjectName, SP_LayoutName, SP_SpacerName,SP_WindowTitle, |
60 | SP_MinimumSize, SP_MaximumSize, SP_Geometry, SP_Icon, SP_CurrentTabName, SP_CurrentItemName, SP_CurrentPageName, |
61 | SP_AutoDefault, SP_Alignment, SP_Shortcut, SP_Orientation |
62 | }; |
63 | |
64 | //Determine special property |
65 | enum SpecialProperty getSpecialProperty(const QString& propertyName); |
66 | |
67 | // A helper class for applying properties to objects. |
68 | // Can be used for Set commands (setValue(), restoreOldValue()) or |
69 | // Reset Commands restoreDefaultValue(), restoreOldValue()). |
70 | // |
71 | class QDESIGNER_SHARED_EXPORT PropertyHelper { |
72 | Q_DISABLE_COPY(PropertyHelper) |
73 | public: |
74 | // A pair of Value and changed flag |
75 | using Value = QPair<QVariant, bool>; |
76 | |
77 | enum ObjectType {OT_Object, OT_FreeAction, OT_AssociatedAction, OT_Widget}; |
78 | |
79 | PropertyHelper(QObject* object, |
80 | SpecialProperty specialProperty, |
81 | QDesignerPropertySheetExtension *sheet, |
82 | int index); |
83 | virtual ~PropertyHelper() = default; |
84 | |
85 | QObject *object() const { return m_object; } |
86 | SpecialProperty specialProperty() const { return m_specialProperty; } |
87 | // set a new value. Can be overwritten to perform a transformation (see |
88 | // handling of Arrow key move in FormWindow class). |
89 | virtual Value setValue(QDesignerFormWindowInterface *fw, const QVariant &value, bool changed, unsigned subPropertyMask); |
90 | |
91 | // restore old value |
92 | Value restoreOldValue(QDesignerFormWindowInterface *fw); |
93 | // set default value |
94 | Value restoreDefaultValue(QDesignerFormWindowInterface *fw); |
95 | |
96 | inline QVariant oldValue() const |
97 | { return m_oldValue.first; } |
98 | |
99 | inline void setOldValue(const QVariant &oldValue) |
100 | { m_oldValue.first = oldValue; } |
101 | |
102 | // required updates for this property (bit mask) |
103 | enum UpdateMask { UpdatePropertyEditor=1, UpdateObjectInspector=2 }; |
104 | unsigned updateMask() const; |
105 | |
106 | // can be merged into one command (that is, object and name match) |
107 | bool canMerge(const PropertyHelper &other) const; |
108 | QDesignerIntegration *integration(QDesignerFormWindowInterface *fw) const; |
109 | |
110 | static void triggerActionChanged(QAction *a); |
111 | |
112 | private: |
113 | // Apply the value and update. Returns corrected value |
114 | Value applyValue(QDesignerFormWindowInterface *fw, const QVariant &oldValue, Value newValue); |
115 | |
116 | static void checkApplyWidgetValue(QDesignerFormWindowInterface *fw, QWidget* w, |
117 | SpecialProperty specialProperty, QVariant &v); |
118 | |
119 | void updateObject(QDesignerFormWindowInterface *fw, const QVariant &oldValue, const QVariant &newValue); |
120 | QVariant findDefaultValue(QDesignerFormWindowInterface *fw) const; |
121 | void ensureUniqueObjectName(QDesignerFormWindowInterface *fw, QObject *object) const; |
122 | SpecialProperty m_specialProperty; |
123 | |
124 | QPointer<QObject> m_object; |
125 | ObjectType m_objectType; |
126 | QPointer<QWidget> m_parentWidget; |
127 | |
128 | QDesignerPropertySheetExtension *m_propertySheet; |
129 | int m_index; |
130 | |
131 | Value m_oldValue; |
132 | }; |
133 | |
134 | // Base class for commands that can be applied to several widgets |
135 | |
136 | class QDESIGNER_SHARED_EXPORT PropertyListCommand : public QDesignerFormWindowCommand { |
137 | public: |
138 | explicit PropertyListCommand(QDesignerFormWindowInterface *formWindow, QUndoCommand *parent = nullptr); |
139 | |
140 | QObject* object(int index = 0) const; |
141 | |
142 | QVariant oldValue(int index = 0) const; |
143 | |
144 | void setOldValue(const QVariant &oldValue, int index = 0); |
145 | |
146 | // Calls restoreDefaultValue() and update() |
147 | void undo() override; |
148 | |
149 | protected: |
150 | using PropertyHelperPtr = QSharedPointer<PropertyHelper>; |
151 | using PropertyHelperList = QList<PropertyHelperPtr>; |
152 | |
153 | // add an object |
154 | bool add(QObject *object, const QString &propertyName); |
155 | |
156 | // Init from a list and make sure referenceObject is added first to obtain the right property group |
157 | bool initList(const QObjectList &list, const QString &apropertyName, QObject *referenceObject = nullptr); |
158 | |
159 | // set a new value, return update mask |
160 | unsigned setValue(const QVariant &value, bool changed, unsigned subPropertyMask); |
161 | |
162 | // restore old value, return update mask |
163 | unsigned restoreOldValue(); |
164 | // set default value, return update mask |
165 | unsigned restoreDefaultValue(); |
166 | |
167 | // update designer |
168 | void update(unsigned updateMask); |
169 | |
170 | // check if lists are aequivalent for command merging (same widgets and props) |
171 | bool canMergeLists(const PropertyHelperList& other) const; |
172 | |
173 | PropertyHelperList& propertyHelperList() { return m_propertyHelperList; } |
174 | const PropertyHelperList& propertyHelperList() const { return m_propertyHelperList; } |
175 | |
176 | const QString propertyName() const; |
177 | SpecialProperty specialProperty() const; |
178 | |
179 | // Helper struct describing a property used for checking whether |
180 | // properties of different widgets are equivalent |
181 | struct PropertyDescription { |
182 | public: |
183 | PropertyDescription() = default; |
184 | PropertyDescription(const QString &propertyName, QDesignerPropertySheetExtension *propertySheet, int index); |
185 | bool equals(const PropertyDescription &p) const; |
186 | void debug() const; |
187 | |
188 | QString m_propertyName; |
189 | QString m_propertyGroup; |
190 | QVariant::Type m_propertyType = QVariant::Invalid; |
191 | SpecialProperty m_specialProperty = SP_None; |
192 | }; |
193 | const PropertyDescription &propertyDescription() const { return m_propertyDescription; } |
194 | |
195 | protected: |
196 | virtual PropertyHelper *createPropertyHelper(QObject *o, SpecialProperty sp, |
197 | QDesignerPropertySheetExtension *sheet, int sheetIndex) const; |
198 | |
199 | private: |
200 | PropertyDescription m_propertyDescription; |
201 | PropertyHelperList m_propertyHelperList; |
202 | }; |
203 | |
204 | class QDESIGNER_SHARED_EXPORT SetPropertyCommand: public PropertyListCommand |
205 | { |
206 | |
207 | public: |
208 | explicit SetPropertyCommand(QDesignerFormWindowInterface *formWindow, QUndoCommand *parent = nullptr); |
209 | |
210 | bool init(QObject *object, const QString &propertyName, const QVariant &newValue); |
211 | bool init(const QObjectList &list, const QString &propertyName, const QVariant &newValue, |
212 | QObject *referenceObject = nullptr, bool enableSubPropertyHandling = true); |
213 | |
214 | |
215 | inline QVariant newValue() const |
216 | { return m_newValue; } |
217 | |
218 | inline void setNewValue(const QVariant &newValue) |
219 | { m_newValue = newValue; } |
220 | |
221 | int id() const override; |
222 | bool mergeWith(const QUndoCommand *other) override; |
223 | |
224 | void redo() override; |
225 | |
226 | protected: |
227 | virtual QVariant mergeValue(const QVariant &newValue); |
228 | |
229 | private: |
230 | unsigned subPropertyMask(const QVariant &newValue, QObject *referenceObject); |
231 | void setDescription(); |
232 | QVariant m_newValue; |
233 | unsigned m_subPropertyMask; |
234 | }; |
235 | |
236 | class QDESIGNER_SHARED_EXPORT ResetPropertyCommand: public PropertyListCommand |
237 | { |
238 | |
239 | public: |
240 | explicit ResetPropertyCommand(QDesignerFormWindowInterface *formWindow); |
241 | |
242 | bool init(QObject *object, const QString &propertyName); |
243 | bool init(const QObjectList &list, const QString &propertyName, QObject *referenceObject = nullptr); |
244 | |
245 | virtual void redo(); |
246 | |
247 | protected: |
248 | virtual bool mergeWith(const QUndoCommand *) { return false; } |
249 | |
250 | private: |
251 | void setDescription(); |
252 | QString m_propertyName; |
253 | }; |
254 | |
255 | |
256 | class QDESIGNER_SHARED_EXPORT AddDynamicPropertyCommand: public QDesignerFormWindowCommand |
257 | { |
258 | |
259 | public: |
260 | explicit AddDynamicPropertyCommand(QDesignerFormWindowInterface *formWindow); |
261 | |
262 | bool init(const QList<QObject *> &selection, QObject *current, const QString &propertyName, const QVariant &value); |
263 | |
264 | virtual void redo(); |
265 | virtual void undo(); |
266 | private: |
267 | void setDescription(); |
268 | QString m_propertyName; |
269 | QList<QObject *> m_selection; |
270 | QVariant m_value; |
271 | }; |
272 | |
273 | class QDESIGNER_SHARED_EXPORT RemoveDynamicPropertyCommand: public QDesignerFormWindowCommand |
274 | { |
275 | |
276 | public: |
277 | explicit RemoveDynamicPropertyCommand(QDesignerFormWindowInterface *formWindow); |
278 | |
279 | bool init(const QList<QObject *> &selection, QObject *current, const QString &propertyName); |
280 | |
281 | virtual void redo(); |
282 | virtual void undo(); |
283 | private: |
284 | void setDescription(); |
285 | QString m_propertyName; |
286 | QMap<QObject *, QPair<QVariant, bool> > m_objectToValueAndChanged; |
287 | }; |
288 | |
289 | } // namespace qdesigner_internal |
290 | |
291 | QT_END_NAMESPACE |
292 | |
293 | #endif // QDESIGNER_PROPERTYCOMMAND_H |
294 | |