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#include "qdesigner_propertyeditor_p.h"
30#include "pluginmanager_p.h"
31
32#include <QtDesigner/abstractformeditor.h>
33#include <QtDesigner/dynamicpropertysheet.h>
34#include <QtDesigner/propertysheet.h>
35#include <QtDesigner/qextensionmanager.h>
36#include <widgetfactory_p.h>
37#include <QtWidgets/qaction.h>
38#include <QtWidgets/qlineedit.h>
39#include <QtWidgets/qabstractbutton.h>
40
41QT_BEGIN_NAMESPACE
42
43namespace qdesigner_internal {
44using StringPropertyParameters = QDesignerPropertyEditor::StringPropertyParameters;
45// A map of property name to type
46using PropertyNameTypeMap = QHash<QString, StringPropertyParameters>;
47
48// Compile a map of hard-coded string property types
49static const PropertyNameTypeMap &stringPropertyTypes()
50{
51 static PropertyNameTypeMap propertyNameTypeMap;
52 if (propertyNameTypeMap.isEmpty()) {
53 const StringPropertyParameters richtext(ValidationRichText, true);
54 // Accessibility. Both are texts the narrator reads
55 propertyNameTypeMap.insert(QStringLiteral("accessibleDescription"), avalue: richtext);
56 propertyNameTypeMap.insert(QStringLiteral("accessibleName"), avalue: richtext);
57 // object names
58 const StringPropertyParameters objectName(ValidationObjectName, false);
59 propertyNameTypeMap.insert(QStringLiteral("buddy"), avalue: objectName);
60 propertyNameTypeMap.insert(QStringLiteral("currentItemName"), avalue: objectName);
61 propertyNameTypeMap.insert(QStringLiteral("currentPageName"), avalue: objectName);
62 propertyNameTypeMap.insert(QStringLiteral("currentTabName"), avalue: objectName);
63 propertyNameTypeMap.insert(QStringLiteral("layoutName"), avalue: objectName);
64 propertyNameTypeMap.insert(QStringLiteral("spacerName"), avalue: objectName);
65 // Style sheet
66 propertyNameTypeMap.insert(QStringLiteral("styleSheet"), avalue: StringPropertyParameters(ValidationStyleSheet, false));
67 // Buttons/ QCommandLinkButton
68 const StringPropertyParameters multiline(ValidationMultiLine, true);
69 propertyNameTypeMap.insert(QStringLiteral("description"), avalue: multiline);
70 propertyNameTypeMap.insert(QStringLiteral("iconText"), avalue: multiline);
71 // Tooltips, etc.
72 propertyNameTypeMap.insert(QStringLiteral("toolTip"), avalue: richtext);
73 propertyNameTypeMap.insert(QStringLiteral("whatsThis"), avalue: richtext);
74 propertyNameTypeMap.insert(QStringLiteral("windowIconText"), avalue: richtext);
75 propertyNameTypeMap.insert(QStringLiteral("html"), avalue: richtext);
76 // A QWizard page id
77 propertyNameTypeMap.insert(QStringLiteral("pageId"), avalue: StringPropertyParameters(ValidationSingleLine, false));
78 // QPlainTextEdit
79 propertyNameTypeMap.insert(QStringLiteral("plainText"), avalue: StringPropertyParameters(ValidationMultiLine, true));
80 }
81 return propertyNameTypeMap;
82}
83
84QDesignerPropertyEditor::QDesignerPropertyEditor(QWidget *parent, Qt::WindowFlags flags) :
85 QDesignerPropertyEditorInterface(parent, flags)
86{
87 // Make old signal work for compatibility
88 connect(sender: this, signal: &QDesignerPropertyEditorInterface::propertyChanged,
89 receiver: this, slot: &QDesignerPropertyEditor::slotPropertyChanged);
90}
91
92static inline bool isDynamicProperty(QDesignerFormEditorInterface *core, QObject *object,
93 const QString &propertyName)
94{
95 if (const QDesignerDynamicPropertySheetExtension *dynamicSheet = qt_extension<QDesignerDynamicPropertySheetExtension*>(manager: core->extensionManager(), object)) {
96 if (dynamicSheet->dynamicPropertiesAllowed()) {
97 if (QDesignerPropertySheetExtension *propertySheet = qt_extension<QDesignerPropertySheetExtension*>(manager: core->extensionManager(), object)) {
98 const int index = propertySheet->indexOf(name: propertyName);
99 return index >= 0 && dynamicSheet->isDynamicProperty(index);
100 }
101 }
102 }
103 return false;
104}
105
106QDesignerPropertyEditor::StringPropertyParameters QDesignerPropertyEditor::textPropertyValidationMode(
107 QDesignerFormEditorInterface *core, const QObject *object,
108 const QString &propertyName, bool isMainContainer)
109{
110 // object name - no comment
111 if (propertyName == QStringLiteral("objectName")) {
112 const TextPropertyValidationMode vm = isMainContainer ? ValidationObjectNameScope : ValidationObjectName;
113 return StringPropertyParameters(vm, false);
114 }
115
116 // Check custom widgets by class.
117 const QString className = WidgetFactory::classNameOf(core, o: object);
118 const QDesignerCustomWidgetData customData = core->pluginManager()->customWidgetData(className);
119 if (!customData.isNull()) {
120 StringPropertyParameters customType;
121 if (customData.xmlStringPropertyType(name: propertyName, type: &customType))
122 return customType;
123 }
124
125 if (isDynamicProperty(core, object: const_cast<QObject *>(object), propertyName))
126 return StringPropertyParameters(ValidationMultiLine, true);
127
128 // Check hardcoded property ames
129 const PropertyNameTypeMap::const_iterator hit = stringPropertyTypes().constFind(akey: propertyName);
130 if (hit != stringPropertyTypes().constEnd())
131 return hit.value();
132
133 // text: Check according to widget type.
134 if (propertyName == QStringLiteral("text")) {
135 if (qobject_cast<const QAction *>(object) || qobject_cast<const QLineEdit *>(object))
136 return StringPropertyParameters(ValidationSingleLine, true);
137 if (qobject_cast<const QAbstractButton *>(object))
138 return StringPropertyParameters(ValidationMultiLine, true);
139 return StringPropertyParameters(ValidationRichText, true);
140 }
141
142 // Fuzzy matching
143 if (propertyName.endsWith(QStringLiteral("Name")))
144 return StringPropertyParameters(ValidationSingleLine, true);
145
146 if (propertyName.endsWith(QStringLiteral("ToolTip")))
147 return StringPropertyParameters(ValidationRichText, true);
148
149#ifdef Q_OS_WIN // No translation for the active X "control" property
150 if (propertyName == QStringLiteral("control") && className == QStringLiteral("QAxWidget"))
151 return StringPropertyParameters(ValidationSingleLine, false);
152#endif
153
154 // default to single
155 return StringPropertyParameters(ValidationSingleLine, true);
156}
157
158void QDesignerPropertyEditor::emitPropertyValueChanged(const QString &name, const QVariant &value, bool enableSubPropertyHandling)
159{
160 // Avoid duplicate signal emission - see below
161 m_propertyChangedForwardingBlocked = true;
162 emit propertyValueChanged(name, value, enableSubPropertyHandling);
163 emit propertyChanged(name, value);
164 m_propertyChangedForwardingBlocked = false;
165}
166
167void QDesignerPropertyEditor::slotPropertyChanged(const QString &name, const QVariant &value)
168{
169 // Forward signal from Integration using the old interfaces.
170 if (!m_propertyChangedForwardingBlocked)
171 emit propertyValueChanged(name, value, enableSubPropertyHandling: true);
172}
173
174}
175
176QT_END_NAMESPACE
177

source code of qttools/src/designer/src/lib/shared/qdesigner_propertyeditor.cpp