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