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 tools applications 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 #ifndef CPPWRITEINITIALIZATION_H
30 #define CPPWRITEINITIALIZATION_H
31 
32 #include "treewalker.h"
33 #include <qpair.h>
34 #include <qhash.h>
35 #include <qset.h>
36 #include <qmap.h>
37 #include <qstack.h>
38 #include <qtextstream.h>
39 
40 QT_BEGIN_NAMESPACE
41 
42 class Driver;
43 class Uic;
44 class DomBrush;
45 class DomFont;
46 class DomResourceIcon;
47 class DomSizePolicy;
48 class DomStringList;
49 struct Option;
50 
51 namespace CPP {
52     // Handle for a flat DOM font to get comparison functionality required for maps
53     class FontHandle {
54     public:
55         FontHandle(const DomFont *domFont);
56         int compare(const FontHandle &) const;
57     private:
58         const DomFont *m_domFont;
59     };
60     inline bool operator ==(const FontHandle &f1, const FontHandle &f2) { return f1.compare(f2) == 0; }
61     inline bool operator  <(const FontHandle &f1, const FontHandle &f2) { return f1.compare(f2) < 0; }
62 
63     // Handle for a flat DOM icon to get comparison functionality required for maps
64     class IconHandle {
65     public:
66         IconHandle(const DomResourceIcon *domIcon);
67         int compare(const IconHandle &) const;
68     private:
69         const DomResourceIcon *m_domIcon;
70     };
71     inline bool operator ==(const IconHandle &i1, const IconHandle &i2) { return i1.compare(i2) == 0; }
72     inline bool operator  <(const IconHandle &i1, const IconHandle &i2) { return i1.compare(i2) < 0; }
73 
74     // Handle for a flat DOM size policy to get comparison functionality required for maps
75     class SizePolicyHandle {
76     public:
77         SizePolicyHandle(const DomSizePolicy *domSizePolicy);
78         int compare(const SizePolicyHandle &) const;
79     private:
80         const DomSizePolicy *m_domSizePolicy;
81     };
82     inline bool operator ==(const SizePolicyHandle &f1, const SizePolicyHandle &f2) { return f1.compare(f2) == 0; }
83     inline bool operator  <(const SizePolicyHandle &f1, const SizePolicyHandle &f2) { return f1.compare(f2) < 0; }
84 
85 
86 struct WriteInitialization : public TreeWalker
87 {
88     using DomPropertyList = QList<DomProperty*>;
89     using DomPropertyMap = QHash<QString, DomProperty*>;
90 
91     WriteInitialization(Uic *uic);
92 
93 //
94 // widgets
95 //
96     void acceptUI(DomUI *node) override;
97     void acceptWidget(DomWidget *node) override;
98 
99     void acceptLayout(DomLayout *node) override;
100     void acceptSpacer(DomSpacer *node) override;
101     void acceptLayoutItem(DomLayoutItem *node) override;
102 
103 //
104 // actions
105 //
106     void acceptActionGroup(DomActionGroup *node) override;
107     void acceptAction(DomAction *node) override;
108     void acceptActionRef(DomActionRef *node) override;
109 
110 //
111 // tab stops
112 //
113     void acceptTabStops(DomTabStops *tabStops) override;
114 
115 //
116 // custom widgets
117 //
118     void acceptCustomWidgets(DomCustomWidgets *node) override;
119     void acceptCustomWidget(DomCustomWidget *node) override;
120 
121 //
122 // layout defaults/functions
123 //
acceptLayoutDefaultWriteInitialization124     void acceptLayoutDefault(DomLayoutDefault *node) override   { m_LayoutDefaultHandler.acceptLayoutDefault(node); }
acceptLayoutFunctionWriteInitialization125     void acceptLayoutFunction(DomLayoutFunction *node) override { m_LayoutDefaultHandler.acceptLayoutFunction(node); }
126 
127 //
128 // signal/slot connections
129 //
130     void acceptConnection(DomConnection *connection) override;
131 
132     enum {
133         Use43UiFile = 0,
134         TopLevelMargin,
135         ChildMargin,
136         SubLayoutMargin
137     };
138 
139 private:
140     static QString domColor2QString(const DomColor *c);
141 
142     QString iconCall(const DomProperty *prop);
143     QString pixCall(const DomProperty *prop) const;
144     QString pixCall(const QString &type, const QString &text) const;
145     QString trCall(const QString &str, const QString &comment = QString(), const QString &id = QString()) const;
146     QString trCall(DomString *str, const QString &defaultString = QString()) const;
147     QString noTrCall(DomString *str, const QString &defaultString = QString()) const;
148     QString autoTrCall(DomString *str, const QString &defaultString = QString()) const;
149     inline QTextStream &autoTrOutput(const DomProperty *str);
150     QTextStream &autoTrOutput(const DomString *str, const QString &defaultString = QString());
151     // Apply a comma-separated list of values using a function "setSomething(int idx, value)"
152     void writePropertyList(const QString &varName, const QString &setFunction, const QString &value, const QString &defaultValue);
153 
154     enum { WritePropertyIgnoreMargin = 1, WritePropertyIgnoreSpacing = 2, WritePropertyIgnoreObjectName = 4 };
155     QString writeStringListProperty(const DomStringList *list) const;
156     void writeProperties(const QString &varName, const QString &className, const DomPropertyList &lst, unsigned flags = 0);
157     void writeColorGroup(DomColorGroup *colorGroup, const QString &group, const QString &paletteName);
158     void writeBrush(const DomBrush *brush, const QString &brushName);
159 
160 //
161 // special initialization
162 //
163     class Item {
164         Q_DISABLE_COPY_MOVE(Item)
165     public:
166         Item(const QString &itemClassName, const QString &indent, QTextStream &setupUiStream, QTextStream &retranslateUiStream, Driver *driver);
167         ~Item();
168         enum EmptyItemPolicy {
169             DontConstruct,
170             ConstructItemOnly,
171             ConstructItemAndVariable
172         };
173         QString writeSetupUi(const QString &parent, EmptyItemPolicy emptyItemPolicy = ConstructItemOnly);
174         void writeRetranslateUi(const QString &parentPath);
175         void addSetter(const QString &setter, const QString &directive = QString(), bool translatable = false); // don't call it if you already added *this as a child of another Item
176         void addChild(Item *child); // all setters should already been added
177     private:
178         struct ItemData
179         {
180             QMultiMap<QString, QString> setters; // directive to setter
181             QSet<QString> directives;
182             enum TemporaryVariableGeneratorPolicy { // policies with priority, number describes the priority
183                 DontGenerate = 1,
184                 GenerateWithMultiDirective = 2,
185                 Generate = 3
186             } policy = DontGenerate;
187         };
188         ItemData m_setupUiData;
189         ItemData m_retranslateUiData;
190         QVector<Item *> m_children;
191         Item *m_parent = nullptr;
192 
193         const QString m_itemClassName;
194         const QString m_indent;
195         QTextStream &m_setupUiStream;
196         QTextStream &m_retranslateUiStream;
197         Driver *m_driver;
198     };
199     using Items = QVector<Item *>;
200 
201     void addInitializer(Item *item,
202             const QString &name, int column, const QString &value, const QString &directive = QString(), bool translatable = false) const;
203     void addQtFlagsInitializer(Item *item, const DomPropertyMap &properties,
204             const QString &name, int column = -1) const;
205     void addQtEnumInitializer(Item *item,
206                     const DomPropertyMap &properties, const QString &name, int column = -1) const;
207     void addBrushInitializer(Item *item,
208                     const DomPropertyMap &properties, const QString &name, int column = -1);
209     void addStringInitializer(Item *item,
210             const DomPropertyMap &properties, const QString &name, int column = -1, const QString &directive = QString()) const;
211     void addCommonInitializers(Item *item,
212                     const DomPropertyMap &properties, int column = -1);
213 
214     void initializeMenu(DomWidget *w, const QString &parentWidget);
215     void initializeComboBox(DomWidget *w);
216     void initializeListWidget(DomWidget *w);
217     void initializeTreeWidget(DomWidget *w);
218     Items initializeTreeWidgetItems(const QVector<DomItem *> &domItems);
219     void initializeTableWidget(DomWidget *w);
220 
221     QString disableSorting(DomWidget *w, const QString &varName);
222     void enableSorting(DomWidget *w, const QString &varName, const QString &tempName);
223 
224     struct Declaration
225     {
226         QString name;
227         QString className;
228     };
229 
230     Declaration findDeclaration(const QString &name);
231 
232 private:
233     QString writeFontProperties(const DomFont *f);
234     QString writeIconProperties(const DomResourceIcon *i);
235     void writePixmapFunctionIcon(QTextStream &output, const QString &iconName,
236                                  const QString &indent, const DomResourceIcon *i) const;
237     QString writeSizePolicy(const DomSizePolicy *sp);
238     QString writeBrushInitialization(const DomBrush *brush);
239     void addButtonGroup(const DomWidget *node, const QString &varName);
240     void addWizardPage(const QString &pageVarName, const DomWidget *page, const QString &parentWidget);
241 
242     const Uic *m_uic;
243     Driver *m_driver;
244     QTextStream &m_output;
245     const Option &m_option;
246     QString m_indent;
247     QString m_dindent;
248     bool m_stdsetdef = true;
249 
250     struct Buddy
251     {
252         QString labelVarName;
253         QString buddyAttributeName;
254     };
255     friend class QTypeInfo<Buddy>;
256 
257     QStack<DomWidget*> m_widgetChain;
258     QStack<DomLayout*> m_layoutChain;
259     QStack<DomActionGroup*> m_actionGroupChain;
260     QVector<Buddy> m_buddies;
261 
262     QSet<QString> m_buttonGroups;
263     using ColorBrushHash = QHash<uint, QString>;
264     ColorBrushHash m_colorBrushHash;
265     // Map from font properties to  font variable name for reuse
266     // Map from size policy to  variable for reuse
267     using FontPropertiesNameMap = QMap<FontHandle, QString>;
268     using IconPropertiesNameMap = QMap<IconHandle, QString>;
269     using SizePolicyNameMap = QMap<SizePolicyHandle, QString>;
270     FontPropertiesNameMap m_fontPropertiesNameMap;
271     IconPropertiesNameMap m_iconPropertiesNameMap;
272     SizePolicyNameMap     m_sizePolicyNameMap;
273 
274     class LayoutDefaultHandler {
275     public:
276         LayoutDefaultHandler();
277         void acceptLayoutDefault(DomLayoutDefault *node);
278         void acceptLayoutFunction(DomLayoutFunction *node);
279 
280         // Write out the layout margin and spacing properties applying the defaults.
281         void writeProperties(const QString &indent, const QString &varName,
282                              const DomPropertyMap &pm, int marginType,
283                              bool suppressMarginDefault, QTextStream &str) const;
284     private:
285         void writeProperty(int p, const QString &indent, const QString &objectName, const DomPropertyMap &pm,
286                            const QString &propertyName, const QString &setter, int defaultStyleValue,
287                            bool suppressDefault, QTextStream &str) const;
288 
289         enum Properties { Margin, Spacing, NumProperties };
290         enum StateFlags { HasDefaultValue = 1, HasDefaultFunction = 2};
291         unsigned m_state[NumProperties];
292         int m_defaultValues[NumProperties];
293         QString m_functions[NumProperties];
294     };
295 
296     // layout defaults
297     LayoutDefaultHandler m_LayoutDefaultHandler;
298     int m_layoutMarginType = TopLevelMargin;
299 
300     QString m_generatedClass;
301     QString m_mainFormVarName;
302     bool m_mainFormUsedInRetranslateUi = false;
303 
304     QString m_delayedInitialization;
305     QTextStream m_delayedOut;
306 
307     QString m_refreshInitialization;
308     QTextStream m_refreshOut;
309 
310     QString m_delayedActionInitialization;
311     QTextStream m_actionOut;
312 
313     bool m_layoutWidget = false;
314     bool m_firstThemeIcon = true;
315     bool m_connectSlotsByName = true;
316 };
317 
318 } // namespace CPP
319 
320 Q_DECLARE_TYPEINFO(CPP::WriteInitialization::Buddy, Q_MOVABLE_TYPE);
321 
322 QT_END_NAMESPACE
323 
324 #endif // CPPWRITEINITIALIZATION_H
325