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//
5// W A R N I N G
6// -------------
7//
8// This file is not part of the Qt API. It exists for the convenience
9// of Qt Designer. This header
10// file may change from version to version without notice, or even be removed.
11//
12// We mean it.
13//
14
15#ifndef QDESIGNER_UTILS_H
16#define QDESIGNER_UTILS_H
17
18#include "shared_global_p.h"
19
20#include <QtDesigner/abstractformwindow.h>
21
22#include <QtCore/qvariant.h>
23#include <QtCore/qshareddata.h>
24#include <QtCore/qmap.h>
25#include <QtWidgets/qmainwindow.h>
26#include <QtGui/qicon.h>
27#include <QtGui/qpixmap.h>
28
29QT_BEGIN_NAMESPACE
30
31class QDebug;
32
33namespace qdesigner_internal {
34class QDesignerFormWindowCommand;
35class DesignerIconCache;
36class FormWindowBase;
37
38
39QDESIGNER_SHARED_EXPORT QString dataDirectory();
40
41QDESIGNER_SHARED_EXPORT QString legacyDataDirectory();
42
43QDESIGNER_SHARED_EXPORT void designerWarning(const QString &message);
44
45QDESIGNER_SHARED_EXPORT void reloadIconResources(DesignerIconCache *iconCache, QObject *object);
46
47/* Flag/Enumeration helpers for the property sheet: Enumeration or flag values are returned by the property sheet
48 * as a pair of meta type and integer value.
49 * The meta type carries all the information required for the property editor and serialization
50 * by the form builders (names, etc).
51 * Note that the property editor uses unqualified names ("Cancel") while the form builder serialization (uic)
52 * requires the whole string
53 * ("QDialogButtonBox::Cancel" or "org.qt-project.qt.gui.QDialogButtonBox.StandardButton.Cancel").*/
54
55/* --------- MetaEnum: Base class representing a QMetaEnum with lookup functions
56 * in both ways. Template of int type since unsigned is more suitable for flags.
57 * The keyToValue() is ignorant of scopes, it can handle fully qualified or unqualified names. */
58
59template <class IntType>
60class MetaEnum
61{
62public:
63 using KeyToValueMap = QMap<QString, IntType>;
64
65 MetaEnum(const QString &name, const QString &scope, const QString &separator);
66 MetaEnum() = default;
67 void addKey(IntType value, const QString &name);
68
69 QString valueToKey(IntType value, bool *ok = nullptr) const;
70 // Ignorant of scopes.
71 IntType keyToValue(QString key, bool *ok = nullptr) const;
72
73 const QString &name() const { return m_name; }
74 const QString &scope() const { return m_scope; }
75 const QString &separator() const { return m_separator; }
76
77 const QStringList &keys() const { return m_keys; }
78 const KeyToValueMap &keyToValueMap() const { return m_keyToValueMap; }
79
80protected:
81 void appendQualifiedName(const QString &key, QString &target) const;
82
83private:
84 QString m_name;
85 QString m_scope;
86 QString m_separator;
87 KeyToValueMap m_keyToValueMap;
88 QStringList m_keys;
89};
90
91template <class IntType>
92MetaEnum<IntType>::MetaEnum(const QString &name, const QString &scope, const QString &separator) :
93 m_name(name),
94 m_scope(scope),
95 m_separator(separator)
96{
97}
98
99template <class IntType>
100void MetaEnum<IntType>::addKey(IntType value, const QString &name)
101{
102 m_keyToValueMap.insert(name, value);
103 m_keys.append(t: name);
104}
105
106template <class IntType>
107QString MetaEnum<IntType>::valueToKey(IntType value, bool *ok) const
108{
109 const QString rc = m_keyToValueMap.key(value);
110 if (ok)
111 *ok = !rc.isEmpty();
112 return rc;
113}
114
115template <class IntType>
116IntType MetaEnum<IntType>::keyToValue(QString key, bool *ok) const
117{
118 if (!m_scope.isEmpty() && key.startsWith(s: m_scope))
119 key.remove(i: 0, len: m_scope.size() + m_separator.size());
120 const auto it = m_keyToValueMap.find(key);
121 const bool found = it != m_keyToValueMap.constEnd();
122 if (ok)
123 *ok = found;
124 return found ? it.value() : IntType(0);
125}
126
127template <class IntType>
128void MetaEnum<IntType>::appendQualifiedName(const QString &key, QString &target) const
129{
130 if (!m_scope.isEmpty()) {
131 target += m_scope;
132 target += m_separator;
133 }
134 target += key;
135}
136
137// -------------- DesignerMetaEnum: Meta type for enumerations
138
139class QDESIGNER_SHARED_EXPORT DesignerMetaEnum : public MetaEnum<int>
140{
141public:
142 DesignerMetaEnum(const QString &name, const QString &scope, const QString &separator);
143 DesignerMetaEnum() = default;
144
145 enum SerializationMode { FullyQualified, NameOnly };
146 QString toString(int value, SerializationMode sm, bool *ok = nullptr) const;
147
148 QString messageToStringFailed(int value) const;
149 QString messageParseFailed(const QString &s) const;
150
151 // parse a string (ignorant of scopes)
152 int parseEnum(const QString &s, bool *ok = nullptr) const { return keyToValue(key: s, ok); }
153};
154
155// -------------- DesignerMetaFlags: Meta type for flags.
156// Note that while the handling of flags is done using unsigned integers, the actual values returned
157// by the property system are integers.
158
159class QDESIGNER_SHARED_EXPORT DesignerMetaFlags : public MetaEnum<uint>
160{
161public:
162 DesignerMetaFlags(const QString &name, const QString &scope, const QString &separator);
163 DesignerMetaFlags() = default;
164
165 enum SerializationMode { FullyQualified, NameOnly };
166 QString toString(int value, SerializationMode sm) const;
167 QStringList flags(int value) const;
168
169 QString messageParseFailed(const QString &s) const;
170 // parse a string (ignorant of scopes)
171 int parseFlags(const QString &s, bool *ok = nullptr) const;
172};
173
174// -------------- EnumValue: Returned by the property sheet for enumerations
175
176struct QDESIGNER_SHARED_EXPORT PropertySheetEnumValue
177{
178 PropertySheetEnumValue(int v, const DesignerMetaEnum &me);
179 PropertySheetEnumValue();
180
181 int value{0};
182 DesignerMetaEnum metaEnum;
183};
184
185// -------------- FlagValue: Returned by the property sheet for flags
186
187struct QDESIGNER_SHARED_EXPORT PropertySheetFlagValue
188{
189 PropertySheetFlagValue(int v, const DesignerMetaFlags &mf);
190 PropertySheetFlagValue();
191
192 int value{0};
193 DesignerMetaFlags metaFlags;
194};
195
196// -------------- PixmapValue: Returned by the property sheet for pixmaps
197class QDESIGNER_SHARED_EXPORT PropertySheetPixmapValue
198{
199public:
200 PropertySheetPixmapValue(const QString &path);
201 PropertySheetPixmapValue();
202
203 bool operator==(const PropertySheetPixmapValue &other) const { return compare(other) == 0; }
204 bool operator!=(const PropertySheetPixmapValue &other) const { return compare(other) != 0; }
205 bool operator<(const PropertySheetPixmapValue &other) const { return compare(other) < 0; }
206
207 // Check where a pixmap comes from
208 enum PixmapSource { LanguageResourcePixmap , ResourcePixmap, FilePixmap };
209 static PixmapSource getPixmapSource(QDesignerFormEditorInterface *core, const QString & path);
210
211 PixmapSource pixmapSource(QDesignerFormEditorInterface *core) const { return getPixmapSource(core, path: m_path); }
212
213 QString path() const;
214 void setPath(const QString &path); // passing the empty path resets the pixmap
215
216 int compare(const PropertySheetPixmapValue &other) const;
217
218private:
219 QString m_path;
220};
221
222// -------------- IconValue: Returned by the property sheet for icons
223
224class PropertySheetIconValueData;
225
226class QDESIGNER_SHARED_EXPORT PropertySheetIconValue
227{
228 public:
229 PropertySheetIconValue(const PropertySheetPixmapValue &pixmap);
230 PropertySheetIconValue();
231 ~PropertySheetIconValue();
232 PropertySheetIconValue(const PropertySheetIconValue &);
233 PropertySheetIconValue &operator=(const PropertySheetIconValue &);
234
235 bool operator==(const PropertySheetIconValue &other) const { return equals(rhs: other); }
236 bool operator!=(const PropertySheetIconValue &other) const { return !equals(rhs: other); }
237 bool operator<(const PropertySheetIconValue &other) const;
238
239 bool isEmpty() const;
240
241 QString theme() const;
242 void setTheme(const QString &);
243
244 PropertySheetPixmapValue pixmap(QIcon::Mode mode, QIcon::State state) const;
245 void setPixmap(QIcon::Mode mode, QIcon::State state, const PropertySheetPixmapValue &path); // passing the empty path resets the pixmap
246
247 uint mask() const;
248 uint compare(const PropertySheetIconValue &other) const;
249 void assign(const PropertySheetIconValue &other, uint mask);
250
251 // Convenience accessors to get themed/unthemed icons.
252 PropertySheetIconValue themed() const;
253 PropertySheetIconValue unthemed() const;
254
255 using ModeStateKey = QPair<QIcon::Mode, QIcon::State>;
256 using ModeStateToPixmapMap = QMap<ModeStateKey, PropertySheetPixmapValue>;
257
258 const ModeStateToPixmapMap &paths() const;
259
260private:
261 bool equals(const PropertySheetIconValue &rhs) const;
262 QSharedDataPointer<PropertySheetIconValueData> m_data;
263};
264
265QDESIGNER_SHARED_EXPORT QDebug operator<<(QDebug, const PropertySheetIconValue &);
266
267class QDESIGNER_SHARED_EXPORT DesignerPixmapCache : public QObject
268{
269 Q_OBJECT
270public:
271 DesignerPixmapCache(QObject *parent = nullptr);
272 QPixmap pixmap(const PropertySheetPixmapValue &value) const;
273 void clear();
274signals:
275 void reloaded();
276private:
277 mutable QMap<PropertySheetPixmapValue, QPixmap> m_cache;
278 friend class FormWindowBase;
279};
280
281class QDESIGNER_SHARED_EXPORT DesignerIconCache : public QObject
282{
283 Q_OBJECT
284public:
285 explicit DesignerIconCache(DesignerPixmapCache *pixmapCache, QObject *parent = nullptr);
286 QIcon icon(const PropertySheetIconValue &value) const;
287 void clear();
288signals:
289 void reloaded();
290private:
291 mutable QMap<PropertySheetIconValue, QIcon> m_cache;
292 DesignerPixmapCache *m_pixmapCache;
293 friend class FormWindowBase;
294};
295
296// -------------- PropertySheetTranslatableData: Base class for translatable properties.
297class QDESIGNER_SHARED_EXPORT PropertySheetTranslatableData
298{
299protected:
300 PropertySheetTranslatableData(bool translatable = true,
301 const QString &disambiguation = QString(),
302 const QString &comment = QString());
303 bool equals(const PropertySheetTranslatableData &rhs) const;
304
305public:
306 bool translatable() const { return m_translatable; }
307 void setTranslatable(bool translatable) { m_translatable = translatable; }
308 QString disambiguation() const { return m_disambiguation; }
309 void setDisambiguation(const QString &d) { m_disambiguation = d; }
310 QString comment() const { return m_comment; }
311 void setComment(const QString &comment) { m_comment = comment; }
312 QString id() const { return m_id; }
313 void setId(const QString &id) { m_id = id; }
314
315private:
316 bool m_translatable;
317 QString m_disambiguation;
318 QString m_comment;
319 QString m_id;
320};
321
322// -------------- StringValue: Returned by the property sheet for strings
323class QDESIGNER_SHARED_EXPORT PropertySheetStringValue : public PropertySheetTranslatableData
324{
325public:
326 PropertySheetStringValue(const QString &value = QString(), bool translatable = true,
327 const QString &disambiguation = QString(), const QString &comment = QString());
328
329 bool operator==(const PropertySheetStringValue &other) const { return equals(rhs: other); }
330 bool operator!=(const PropertySheetStringValue &other) const { return !equals(rhs: other); }
331
332 QString value() const;
333 void setValue(const QString &value);
334
335private:
336 bool equals(const PropertySheetStringValue &rhs) const;
337
338 QString m_value;
339};
340
341// -------------- StringValue: Returned by the property sheet for string lists
342class QDESIGNER_SHARED_EXPORT PropertySheetStringListValue : public PropertySheetTranslatableData
343{
344public:
345 PropertySheetStringListValue(const QStringList &value = QStringList(),
346 bool translatable = true,
347 const QString &disambiguation = QString(),
348 const QString &comment = QString());
349
350 bool operator==(const PropertySheetStringListValue &other) const { return equals(rhs: other); }
351 bool operator!=(const PropertySheetStringListValue &other) const { return !equals(rhs: other); }
352
353 QStringList value() const;
354 void setValue(const QStringList &value);
355
356private:
357 bool equals(const PropertySheetStringListValue &rhs) const;
358
359 QStringList m_value;
360};
361
362// -------------- StringValue: Returned by the property sheet for strings
363class QDESIGNER_SHARED_EXPORT PropertySheetKeySequenceValue : public PropertySheetTranslatableData
364{
365public:
366 PropertySheetKeySequenceValue(const QKeySequence &value = QKeySequence(),
367 bool translatable = true,
368 const QString &disambiguation = QString(),
369 const QString &comment = QString());
370 PropertySheetKeySequenceValue(const QKeySequence::StandardKey &standardKey,
371 bool translatable = true,
372 const QString &disambiguation = QString(),
373 const QString &comment = QString());
374
375 bool operator==(const PropertySheetKeySequenceValue &other) const { return equals(rhs: other); }
376 bool operator!=(const PropertySheetKeySequenceValue &other) const { return !equals(rhs: other); }
377
378 QKeySequence value() const;
379 void setValue(const QKeySequence &value);
380 QKeySequence::StandardKey standardKey() const;
381 void setStandardKey(const QKeySequence::StandardKey &standardKey);
382 bool isStandardKey() const;
383
384private:
385 bool equals(const PropertySheetKeySequenceValue &rhs) const;
386
387 QKeySequence m_value;
388 QKeySequence::StandardKey m_standardKey;
389};
390
391} // namespace qdesigner_internal
392
393QT_END_NAMESPACE
394
395
396// NOTE: Do not move this code, needed for GCC 3.3
397Q_DECLARE_METATYPE(qdesigner_internal::PropertySheetEnumValue)
398Q_DECLARE_METATYPE(qdesigner_internal::PropertySheetFlagValue)
399Q_DECLARE_METATYPE(qdesigner_internal::PropertySheetPixmapValue)
400Q_DECLARE_METATYPE(qdesigner_internal::PropertySheetIconValue)
401Q_DECLARE_METATYPE(qdesigner_internal::PropertySheetStringValue)
402Q_DECLARE_METATYPE(qdesigner_internal::PropertySheetStringListValue)
403Q_DECLARE_METATYPE(qdesigner_internal::PropertySheetKeySequenceValue)
404
405
406QT_BEGIN_NAMESPACE
407
408namespace qdesigner_internal {
409
410
411// Create a command to change a text property (that is, create a reset property command if the text is empty)
412QDESIGNER_SHARED_EXPORT QDesignerFormWindowCommand *createTextPropertyCommand(const QString &propertyName, const QString &text, QObject *object, QDesignerFormWindowInterface *fw);
413
414// Returns preferred task menu action for managed widget
415QDESIGNER_SHARED_EXPORT QAction *preferredEditAction(QDesignerFormEditorInterface *core, QWidget *managedWidget);
416
417enum class UicLanguage
418{
419 Cpp,
420 Python,
421};
422
423// Convenience to run UIC
424QDESIGNER_SHARED_EXPORT bool runUIC(const QString &fileName, UicLanguage language,
425 QByteArray& ba, QString &errorMessage);
426
427// Find a suitable variable name for a class.
428QDESIGNER_SHARED_EXPORT QString qtify(const QString &name);
429
430/* UpdateBlocker: Blocks the updates of the widget passed on while in scope.
431 * Does nothing if the incoming widget already has updatesEnabled==false
432 * which is important to avoid side-effects when putting it into QStackedLayout. */
433
434class QDESIGNER_SHARED_EXPORT UpdateBlocker {
435 Q_DISABLE_COPY_MOVE(UpdateBlocker)
436
437public:
438 UpdateBlocker(QWidget *w);
439 ~UpdateBlocker();
440
441private:
442 QWidget *m_widget;
443 const bool m_enabled;
444};
445
446// QPalette helpers: Mask for a single color role/group
447QDESIGNER_SHARED_EXPORT quint64 paletteResolveMask(QPalette::ColorGroup colorGroup,
448 QPalette::ColorRole colorRole);
449// Mask for the colors of a role in all groups (Active/Inactive/Disabled)
450QDESIGNER_SHARED_EXPORT quint64 paletteResolveMask(QPalette::ColorRole colorRole);
451
452namespace Utils {
453
454inline int valueOf(const QVariant &value, bool *ok = nullptr)
455{
456 if (value.canConvert<PropertySheetEnumValue>()) {
457 if (ok)
458 *ok = true;
459 return qvariant_cast<PropertySheetEnumValue>(v: value).value;
460 }
461 if (value.canConvert<PropertySheetFlagValue>()) {
462 if (ok)
463 *ok = true;
464 return qvariant_cast<PropertySheetFlagValue>(v: value).value;
465 }
466 return value.toInt(ok);
467}
468
469inline bool isObjectAncestorOf(QObject *ancestor, QObject *child)
470{
471 QObject *obj = child;
472 while (obj != nullptr) {
473 if (obj == ancestor)
474 return true;
475 obj = obj->parent();
476 }
477 return false;
478}
479
480inline bool isCentralWidget(QDesignerFormWindowInterface *fw, QWidget *widget)
481{
482 if (! fw || ! widget)
483 return false;
484
485 if (widget == fw->mainContainer())
486 return true;
487
488 // ### generalize for other containers
489 if (QMainWindow *mw = qobject_cast<QMainWindow*>(object: fw->mainContainer())) {
490 return mw->centralWidget() == widget;
491 }
492
493 return false;
494}
495
496} // namespace Utils
497
498} // namespace qdesigner_internal
499
500QT_END_NAMESPACE
501
502#endif // QDESIGNER_UTILS_H
503

source code of qttools/src/designer/src/lib/shared/qdesigner_utils_p.h