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 "brushpropertymanager.h" |
30 | #include "qtpropertymanager.h" |
31 | #include "designerpropertymanager.h" |
32 | #include "qtpropertybrowserutils_p.h" |
33 | |
34 | #include <QtCore/qcoreapplication.h> |
35 | #include <QtCore/qvariant.h> |
36 | #include <QtCore/qstring.h> |
37 | |
38 | static const char *brushStyles[] = { |
39 | QT_TRANSLATE_NOOP("BrushPropertyManager" , "No brush" ), |
40 | QT_TRANSLATE_NOOP("BrushPropertyManager" , "Solid" ), |
41 | QT_TRANSLATE_NOOP("BrushPropertyManager" , "Dense 1" ), |
42 | QT_TRANSLATE_NOOP("BrushPropertyManager" , "Dense 2" ), |
43 | QT_TRANSLATE_NOOP("BrushPropertyManager" , "Dense 3" ), |
44 | QT_TRANSLATE_NOOP("BrushPropertyManager" , "Dense 4" ), |
45 | QT_TRANSLATE_NOOP("BrushPropertyManager" , "Dense 5" ), |
46 | QT_TRANSLATE_NOOP("BrushPropertyManager" , "Dense 6" ), |
47 | QT_TRANSLATE_NOOP("BrushPropertyManager" , "Dense 7" ), |
48 | QT_TRANSLATE_NOOP("BrushPropertyManager" , "Horizontal" ), |
49 | QT_TRANSLATE_NOOP("BrushPropertyManager" , "Vertical" ), |
50 | QT_TRANSLATE_NOOP("BrushPropertyManager" , "Cross" ), |
51 | QT_TRANSLATE_NOOP("BrushPropertyManager" , "Backward diagonal" ), |
52 | QT_TRANSLATE_NOOP("BrushPropertyManager" , "Forward diagonal" ), |
53 | QT_TRANSLATE_NOOP("BrushPropertyManager" , "Crossing diagonal" ), |
54 | }; |
55 | |
56 | QT_BEGIN_NAMESPACE |
57 | |
58 | namespace qdesigner_internal { |
59 | |
60 | BrushPropertyManager::BrushPropertyManager() = default; |
61 | |
62 | int BrushPropertyManager::brushStyleToIndex(Qt::BrushStyle st) |
63 | { |
64 | switch (st) { |
65 | case Qt::NoBrush: return 0; |
66 | case Qt::SolidPattern: return 1; |
67 | case Qt::Dense1Pattern: return 2; |
68 | case Qt::Dense2Pattern: return 3; |
69 | case Qt::Dense3Pattern: return 4; |
70 | case Qt::Dense4Pattern: return 5; |
71 | case Qt::Dense5Pattern: return 6; |
72 | case Qt::Dense6Pattern: return 7; |
73 | case Qt::Dense7Pattern: return 8; |
74 | case Qt::HorPattern: return 9; |
75 | case Qt::VerPattern: return 10; |
76 | case Qt::CrossPattern: return 11; |
77 | case Qt::BDiagPattern: return 12; |
78 | case Qt::FDiagPattern: return 13; |
79 | case Qt::DiagCrossPattern: return 14; |
80 | default: break; |
81 | } |
82 | return 0; |
83 | } |
84 | |
85 | Qt::BrushStyle BrushPropertyManager::brushStyleIndexToStyle(int brushStyleIndex) |
86 | { |
87 | switch (brushStyleIndex) { |
88 | case 0: return Qt::NoBrush; |
89 | case 1: return Qt::SolidPattern; |
90 | case 2: return Qt::Dense1Pattern; |
91 | case 3: return Qt::Dense2Pattern; |
92 | case 4: return Qt::Dense3Pattern; |
93 | case 5: return Qt::Dense4Pattern; |
94 | case 6: return Qt::Dense5Pattern; |
95 | case 7: return Qt::Dense6Pattern; |
96 | case 8: return Qt::Dense7Pattern; |
97 | case 9: return Qt::HorPattern; |
98 | case 10: return Qt::VerPattern; |
99 | case 11: return Qt::CrossPattern; |
100 | case 12: return Qt::BDiagPattern; |
101 | case 13: return Qt::FDiagPattern; |
102 | case 14: return Qt::DiagCrossPattern; |
103 | } |
104 | return Qt::NoBrush; |
105 | } |
106 | |
107 | static void clearBrushIcons(); |
108 | |
109 | namespace { |
110 | class EnumIndexIconMap : public QMap<int, QIcon> |
111 | { |
112 | public: |
113 | EnumIndexIconMap() |
114 | { |
115 | qAddPostRoutine(clearBrushIcons); |
116 | } |
117 | }; |
118 | } |
119 | |
120 | Q_GLOBAL_STATIC(EnumIndexIconMap, brushIcons) |
121 | |
122 | static void clearBrushIcons() |
123 | { |
124 | brushIcons()->clear(); |
125 | } |
126 | |
127 | const BrushPropertyManager::EnumIndexIconMap &BrushPropertyManager::brushStyleIcons() |
128 | { |
129 | // Create a map of icons for the brush style editor |
130 | if (brushIcons()->empty()) { |
131 | const int brushStyleCount = sizeof(brushStyles)/sizeof(const char *); |
132 | QBrush brush(Qt::black); |
133 | for (int i = 0; i < brushStyleCount; i++) { |
134 | const Qt::BrushStyle style = brushStyleIndexToStyle(brushStyleIndex: i); |
135 | brush.setStyle(style); |
136 | brushIcons()->insert(akey: i, avalue: QtPropertyBrowserUtils::brushValueIcon(b: brush)); |
137 | } |
138 | } |
139 | return *(brushIcons()); |
140 | } |
141 | |
142 | QString BrushPropertyManager::brushStyleIndexToString(int brushStyleIndex) |
143 | { |
144 | const int brushStyleCount = sizeof(brushStyles)/sizeof(const char *); |
145 | return brushStyleIndex < brushStyleCount ? QCoreApplication::translate(context: "BrushPropertyManager" , key: brushStyles[brushStyleIndex]) : QString(); |
146 | } |
147 | |
148 | void BrushPropertyManager::initializeProperty(QtVariantPropertyManager *vm, QtProperty *property, int enumTypeId) |
149 | { |
150 | m_brushValues.insert(akey: property, avalue: QBrush()); |
151 | // style |
152 | QtVariantProperty *styleSubProperty = vm->addProperty(propertyType: enumTypeId, name: QCoreApplication::translate(context: "BrushPropertyManager" , key: "Style" )); |
153 | property->addSubProperty(property: styleSubProperty); |
154 | QStringList styles; |
155 | for (const char *brushStyle : brushStyles) |
156 | styles.push_back(t: QCoreApplication::translate(context: "BrushPropertyManager" , key: brushStyle)); |
157 | styleSubProperty->setAttribute(QStringLiteral("enumNames" ), value: styles); |
158 | styleSubProperty->setAttribute(QStringLiteral("enumIcons" ), value: QVariant::fromValue(value: brushStyleIcons())); |
159 | m_brushPropertyToStyleSubProperty.insert(akey: property, avalue: styleSubProperty); |
160 | m_brushStyleSubPropertyToProperty.insert(akey: styleSubProperty, avalue: property); |
161 | // color |
162 | QtVariantProperty *colorSubProperty = vm->addProperty(propertyType: QVariant::Color, name: QCoreApplication::translate(context: "BrushPropertyManager" , key: "Color" )); |
163 | property->addSubProperty(property: colorSubProperty); |
164 | m_brushPropertyToColorSubProperty.insert(akey: property, avalue: colorSubProperty); |
165 | m_brushColorSubPropertyToProperty.insert(akey: colorSubProperty, avalue: property); |
166 | } |
167 | |
168 | bool BrushPropertyManager::uninitializeProperty(QtProperty *property) |
169 | { |
170 | const PropertyBrushMap::iterator brit = m_brushValues.find(akey: property); // Brushes |
171 | if (brit == m_brushValues.end()) |
172 | return false; |
173 | m_brushValues.erase(it: brit); |
174 | // style |
175 | PropertyToPropertyMap::iterator subit = m_brushPropertyToStyleSubProperty.find(akey: property); |
176 | if (subit != m_brushPropertyToStyleSubProperty.end()) { |
177 | QtProperty *styleProp = subit.value(); |
178 | m_brushStyleSubPropertyToProperty.remove(akey: styleProp); |
179 | m_brushPropertyToStyleSubProperty.erase(it: subit); |
180 | delete styleProp; |
181 | } |
182 | // color |
183 | subit = m_brushPropertyToColorSubProperty.find(akey: property); |
184 | if (subit != m_brushPropertyToColorSubProperty.end()) { |
185 | QtProperty *colorProp = subit.value(); |
186 | m_brushColorSubPropertyToProperty.remove(akey: colorProp); |
187 | m_brushPropertyToColorSubProperty.erase(it: subit); |
188 | delete colorProp; |
189 | } |
190 | return true; |
191 | } |
192 | |
193 | void BrushPropertyManager::slotPropertyDestroyed(QtProperty *property) |
194 | { |
195 | PropertyToPropertyMap::iterator subit = m_brushStyleSubPropertyToProperty.find(akey: property); |
196 | if (subit != m_brushStyleSubPropertyToProperty.end()) { |
197 | m_brushPropertyToStyleSubProperty[subit.value()] = 0; |
198 | m_brushStyleSubPropertyToProperty.erase(it: subit); |
199 | } |
200 | subit = m_brushColorSubPropertyToProperty.find(akey: property); |
201 | if (subit != m_brushColorSubPropertyToProperty.end()) { |
202 | m_brushPropertyToColorSubProperty[subit.value()] = 0; |
203 | m_brushColorSubPropertyToProperty.erase(it: subit); |
204 | } |
205 | } |
206 | |
207 | |
208 | int BrushPropertyManager::valueChanged(QtVariantPropertyManager *vm, QtProperty *property, const QVariant &value) |
209 | { |
210 | switch (value.type()) { |
211 | case QVariant::Int: // Style subproperty? |
212 | if (QtProperty *brushProperty = m_brushStyleSubPropertyToProperty.value(akey: property, adefaultValue: 0)) { |
213 | const QBrush oldValue = m_brushValues.value(akey: brushProperty); |
214 | QBrush newBrush = oldValue; |
215 | const int index = value.toInt(); |
216 | newBrush.setStyle(brushStyleIndexToStyle(brushStyleIndex: index)); |
217 | if (newBrush == oldValue) |
218 | return DesignerPropertyManager::Unchanged; |
219 | vm->variantProperty(property: brushProperty)->setValue(newBrush); |
220 | return DesignerPropertyManager::Changed; |
221 | } |
222 | break; |
223 | case QVariant::Color: // Color subproperty? |
224 | if (QtProperty *brushProperty = m_brushColorSubPropertyToProperty.value(akey: property, adefaultValue: 0)) { |
225 | const QBrush oldValue = m_brushValues.value(akey: brushProperty); |
226 | QBrush newBrush = oldValue; |
227 | newBrush.setColor(qvariant_cast<QColor>(v: value)); |
228 | if (newBrush == oldValue) |
229 | return DesignerPropertyManager::Unchanged; |
230 | vm->variantProperty(property: brushProperty)->setValue(newBrush); |
231 | return DesignerPropertyManager::Changed; |
232 | } |
233 | break; |
234 | default: |
235 | break; |
236 | } |
237 | return DesignerPropertyManager::NoMatch; |
238 | } |
239 | |
240 | int BrushPropertyManager::setValue(QtVariantPropertyManager *vm, QtProperty *property, const QVariant &value) |
241 | { |
242 | if (value.type() != QVariant::Brush) |
243 | return DesignerPropertyManager::NoMatch; |
244 | const PropertyBrushMap::iterator brit = m_brushValues.find(akey: property); |
245 | if (brit == m_brushValues.end()) |
246 | return DesignerPropertyManager::NoMatch; |
247 | |
248 | const QBrush newBrush = qvariant_cast<QBrush>(v: value); |
249 | if (newBrush == brit.value()) |
250 | return DesignerPropertyManager::Unchanged; |
251 | brit.value() = newBrush; |
252 | if (QtProperty *styleProperty = m_brushPropertyToStyleSubProperty.value(akey: property)) |
253 | vm->variantProperty(property: styleProperty)->setValue(brushStyleToIndex(st: newBrush.style())); |
254 | if (QtProperty *colorProperty = m_brushPropertyToColorSubProperty.value(akey: property)) |
255 | vm->variantProperty(property: colorProperty)->setValue(newBrush.color()); |
256 | |
257 | return DesignerPropertyManager::Changed; |
258 | } |
259 | |
260 | bool BrushPropertyManager::valueText(const QtProperty *property, QString *text) const |
261 | { |
262 | const PropertyBrushMap::const_iterator brit = m_brushValues.constFind(akey: const_cast<QtProperty *>(property)); |
263 | if (brit == m_brushValues.constEnd()) |
264 | return false; |
265 | const QBrush &brush = brit.value(); |
266 | const QString styleName = brushStyleIndexToString(brushStyleIndex: brushStyleToIndex(st: brush.style())); |
267 | *text = QCoreApplication::translate(context: "BrushPropertyManager" , key: "[%1, %2]" ) |
268 | .arg(args: styleName, args: QtPropertyBrowserUtils::colorValueText(c: brush.color())); |
269 | return true; |
270 | } |
271 | |
272 | bool BrushPropertyManager::valueIcon(const QtProperty *property, QIcon *icon) const |
273 | { |
274 | const PropertyBrushMap::const_iterator brit = m_brushValues.constFind(akey: const_cast<QtProperty *>(property)); |
275 | if (brit == m_brushValues.constEnd()) |
276 | return false; |
277 | *icon = QtPropertyBrowserUtils::brushValueIcon(b: brit.value()); |
278 | return true; |
279 | } |
280 | |
281 | bool BrushPropertyManager::value(const QtProperty *property, QVariant *v) const |
282 | { |
283 | const PropertyBrushMap::const_iterator brit = m_brushValues.constFind(akey: const_cast<QtProperty *>(property)); |
284 | if (brit == m_brushValues.constEnd()) |
285 | return false; |
286 | v->setValue(brit.value()); |
287 | return true; |
288 | } |
289 | } |
290 | |
291 | QT_END_NAMESPACE |
292 | |