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