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 "shared_settings_p.h" |
30 | #include "grid_p.h" |
31 | #include "previewmanager_p.h" |
32 | #include "qdesigner_utils_p.h" |
33 | |
34 | #include <actioneditor_p.h> |
35 | |
36 | #include <QtDesigner/abstractformeditor.h> |
37 | #include <QtDesigner/abstractsettings.h> |
38 | |
39 | #include <QtCore/qstringlist.h> |
40 | #include <QtCore/qdir.h> |
41 | #include <QtCore/qvariant.h> |
42 | #include <QtCore/qcoreapplication.h> |
43 | #include <QtCore/qsize.h> |
44 | |
45 | QT_BEGIN_NAMESPACE |
46 | |
47 | static const char *designerPath = "/.designer" ; |
48 | static const char *defaultGridKey = "defaultGrid" ; |
49 | static const char *previewKey = "Preview" ; |
50 | static const char *enabledKey = "Enabled" ; |
51 | static const char *userDeviceSkinsKey= "UserDeviceSkins" ; |
52 | static const char *zoomKey = "zoom" ; |
53 | static const char *zoomEnabledKey = "zoomEnabled" ; |
54 | static const char *deviceProfileIndexKey = "DeviceProfileIndex" ; |
55 | static const char *deviceProfilesKey = "DeviceProfiles" ; |
56 | static const char *formTemplatePathsKey = "FormTemplatePaths" ; |
57 | static const char *formTemplateKey = "FormTemplate" ; |
58 | static const char *newFormSizeKey = "NewFormSize" ; |
59 | static inline QString namingModeKey() { return QStringLiteral("naming" ); } |
60 | static inline QString underScoreNamingMode() { return QStringLiteral("underscore" ); } |
61 | static inline QString camelCaseNamingMode() { return QStringLiteral("camelcase" ); } |
62 | |
63 | using namespace qdesigner_internal; |
64 | |
65 | static bool checkTemplatePath(const QString &path, bool create) |
66 | { |
67 | QDir current(QDir::current()); |
68 | if (current.exists(name: path)) |
69 | return true; |
70 | |
71 | if (!create) |
72 | return false; |
73 | |
74 | if (current.mkpath(dirPath: path)) |
75 | return true; |
76 | |
77 | qdesigner_internal::designerWarning(message: QCoreApplication::translate(context: "QDesignerSharedSettings" , key: "The template path %1 could not be created." ).arg(a: path)); |
78 | return false; |
79 | } |
80 | |
81 | namespace qdesigner_internal { |
82 | |
83 | QDesignerSharedSettings::QDesignerSharedSettings(QDesignerFormEditorInterface *core) |
84 | : m_settings(core->settingsManager()) |
85 | { |
86 | } |
87 | |
88 | Grid QDesignerSharedSettings::defaultGrid() const |
89 | { |
90 | Grid grid; |
91 | const QVariantMap defaultGridMap |
92 | = m_settings->value(key: QLatin1String(defaultGridKey), defaultValue: QVariantMap()).toMap(); |
93 | if (!defaultGridMap.isEmpty()) |
94 | grid.fromVariantMap(vm: defaultGridMap); |
95 | return grid; |
96 | } |
97 | |
98 | void QDesignerSharedSettings::setDefaultGrid(const Grid &grid) |
99 | { |
100 | m_settings->setValue(key: QLatin1String(defaultGridKey), value: grid.toVariantMap()); |
101 | } |
102 | |
103 | const QStringList &QDesignerSharedSettings::defaultFormTemplatePaths() |
104 | { |
105 | static QStringList rc; |
106 | if (rc.isEmpty()) { |
107 | // Ensure default form template paths |
108 | const QString templatePath = QStringLiteral("/templates" ); |
109 | // home |
110 | QString path = QDir::homePath(); |
111 | path += QLatin1String(designerPath); |
112 | path += templatePath; |
113 | if (checkTemplatePath(path, create: true)) |
114 | rc += path; |
115 | |
116 | // designer/bin: Might be owned by root in some installations, do not force it. |
117 | path = qApp->applicationDirPath(); |
118 | path += templatePath; |
119 | if (checkTemplatePath(path, create: false)) |
120 | rc += path; |
121 | } |
122 | return rc; |
123 | } |
124 | |
125 | QStringList QDesignerSharedSettings::formTemplatePaths() const |
126 | { |
127 | return m_settings->value(key: QLatin1String(formTemplatePathsKey), |
128 | defaultValue: defaultFormTemplatePaths()).toStringList(); |
129 | } |
130 | |
131 | void QDesignerSharedSettings::setFormTemplatePaths(const QStringList &paths) |
132 | { |
133 | m_settings->setValue(key: QLatin1String(formTemplatePathsKey), value: paths); |
134 | } |
135 | |
136 | QString QDesignerSharedSettings::formTemplate() const |
137 | { |
138 | return m_settings->value(key: QLatin1String(formTemplateKey)).toString(); |
139 | } |
140 | |
141 | void QDesignerSharedSettings::setFormTemplate(const QString &t) |
142 | { |
143 | m_settings->setValue(key: QLatin1String(formTemplateKey), value: t); |
144 | } |
145 | |
146 | void QDesignerSharedSettings::setAdditionalFormTemplatePaths(const QStringList &additionalPaths) |
147 | { |
148 | // merge template paths |
149 | QStringList templatePaths = defaultFormTemplatePaths(); |
150 | templatePaths += additionalPaths; |
151 | setFormTemplatePaths(templatePaths); |
152 | } |
153 | |
154 | QStringList QDesignerSharedSettings::additionalFormTemplatePaths() const |
155 | { |
156 | // get template paths excluding internal ones |
157 | QStringList rc = formTemplatePaths(); |
158 | for (const QString &internalTemplatePath : defaultFormTemplatePaths()) { |
159 | const int index = rc.indexOf(t: internalTemplatePath); |
160 | if (index != -1) |
161 | rc.removeAt(i: index); |
162 | } |
163 | return rc; |
164 | } |
165 | |
166 | QSize QDesignerSharedSettings::newFormSize() const |
167 | { |
168 | return m_settings->value(key: QLatin1String(newFormSizeKey), defaultValue: QSize(0, 0)).toSize(); |
169 | } |
170 | |
171 | void QDesignerSharedSettings::setNewFormSize(const QSize &s) |
172 | { |
173 | if (s.isNull()) { |
174 | m_settings->remove(key: QLatin1String(newFormSizeKey)); |
175 | } else { |
176 | m_settings->setValue(key: QLatin1String(newFormSizeKey), value: s); |
177 | } |
178 | } |
179 | |
180 | |
181 | PreviewConfiguration QDesignerSharedSettings::customPreviewConfiguration() const |
182 | { |
183 | PreviewConfiguration configuration; |
184 | configuration.fromSettings(prefix: QLatin1String(previewKey), settings: m_settings); |
185 | return configuration; |
186 | } |
187 | |
188 | void QDesignerSharedSettings::setCustomPreviewConfiguration(const PreviewConfiguration &configuration) |
189 | { |
190 | configuration.toSettings(prefix: QLatin1String(previewKey), settings: m_settings); |
191 | } |
192 | |
193 | bool QDesignerSharedSettings::isCustomPreviewConfigurationEnabled() const |
194 | { |
195 | m_settings->beginGroup(prefix: QLatin1String(previewKey)); |
196 | bool isEnabled = m_settings->value(key: QLatin1String(enabledKey), defaultValue: false).toBool(); |
197 | m_settings->endGroup(); |
198 | return isEnabled; |
199 | } |
200 | |
201 | void QDesignerSharedSettings::setCustomPreviewConfigurationEnabled(bool enabled) |
202 | { |
203 | m_settings->beginGroup(prefix: QLatin1String(previewKey)); |
204 | m_settings->setValue(key: QLatin1String(enabledKey), value: enabled); |
205 | m_settings->endGroup(); |
206 | } |
207 | |
208 | QStringList QDesignerSharedSettings::userDeviceSkins() const |
209 | { |
210 | m_settings->beginGroup(prefix: QLatin1String(previewKey)); |
211 | QStringList userDeviceSkins |
212 | = m_settings->value(key: QLatin1String(userDeviceSkinsKey), defaultValue: QStringList()).toStringList(); |
213 | m_settings->endGroup(); |
214 | return userDeviceSkins; |
215 | } |
216 | |
217 | void QDesignerSharedSettings::setUserDeviceSkins(const QStringList &userDeviceSkins) |
218 | { |
219 | m_settings->beginGroup(prefix: QLatin1String(previewKey)); |
220 | m_settings->setValue(key: QLatin1String(userDeviceSkinsKey), value: userDeviceSkins); |
221 | m_settings->endGroup(); |
222 | } |
223 | |
224 | int QDesignerSharedSettings::zoom() const |
225 | { |
226 | return m_settings->value(key: QLatin1String(zoomKey), defaultValue: 100).toInt(); |
227 | } |
228 | |
229 | void QDesignerSharedSettings::setZoom(int z) |
230 | { |
231 | m_settings->setValue(key: QLatin1String(zoomKey), value: QVariant(z)); |
232 | } |
233 | |
234 | ObjectNamingMode QDesignerSharedSettings::objectNamingMode() const |
235 | { |
236 | const QString value = m_settings->value(key: namingModeKey()).toString(); |
237 | return value == camelCaseNamingMode() |
238 | ? qdesigner_internal::CamelCase : qdesigner_internal::Underscore; |
239 | } |
240 | |
241 | void QDesignerSharedSettings::setObjectNamingMode(ObjectNamingMode n) |
242 | { |
243 | const QString value = n == qdesigner_internal::CamelCase |
244 | ? camelCaseNamingMode() : underScoreNamingMode(); |
245 | m_settings->setValue(key: namingModeKey(), value: QVariant(value)); |
246 | } |
247 | |
248 | bool QDesignerSharedSettings::zoomEnabled() const |
249 | { |
250 | return m_settings->value(key: QLatin1String(zoomEnabledKey), defaultValue: false).toBool(); |
251 | } |
252 | |
253 | void QDesignerSharedSettings::setZoomEnabled(bool v) |
254 | { |
255 | m_settings->setValue(key: QLatin1String(zoomEnabledKey), value: v); |
256 | } |
257 | |
258 | DeviceProfile QDesignerSharedSettings::currentDeviceProfile() const |
259 | { |
260 | return deviceProfileAt(idx: currentDeviceProfileIndex()); |
261 | } |
262 | |
263 | void QDesignerSharedSettings::setCurrentDeviceProfileIndex(int i) |
264 | { |
265 | m_settings->setValue(key: QLatin1String(deviceProfileIndexKey), value: i); |
266 | } |
267 | |
268 | int QDesignerSharedSettings::currentDeviceProfileIndex() const |
269 | { |
270 | return m_settings->value(key: QLatin1String(deviceProfileIndexKey), defaultValue: -1).toInt(); |
271 | } |
272 | |
273 | static inline QString msgWarnDeviceProfileXml(const QString &msg) |
274 | { |
275 | return QCoreApplication::translate(context: "QDesignerSharedSettings" , key: "An error has been encountered while parsing device profile XML: %1" ).arg(a: msg); |
276 | } |
277 | |
278 | DeviceProfile QDesignerSharedSettings::deviceProfileAt(int idx) const |
279 | { |
280 | DeviceProfile rc; |
281 | if (idx < 0) |
282 | return rc; |
283 | const QStringList xmls = deviceProfileXml(); |
284 | if (idx >= xmls.size()) |
285 | return rc; |
286 | QString errorMessage; |
287 | if (!rc.fromXml(xml: xmls.at(i: idx), errorMessage: &errorMessage)) { |
288 | rc.clear(); |
289 | designerWarning(message: msgWarnDeviceProfileXml(msg: errorMessage)); |
290 | } |
291 | return rc; |
292 | } |
293 | |
294 | QStringList QDesignerSharedSettings::deviceProfileXml() const |
295 | { |
296 | return m_settings->value(key: QLatin1String(deviceProfilesKey), defaultValue: QStringList()).toStringList(); |
297 | } |
298 | |
299 | QDesignerSharedSettings::DeviceProfileList QDesignerSharedSettings::deviceProfiles() const |
300 | { |
301 | DeviceProfileList rc; |
302 | const QStringList xmls = deviceProfileXml(); |
303 | if (xmls.isEmpty()) |
304 | return rc; |
305 | // De-serialize |
306 | QString errorMessage; |
307 | DeviceProfile dp; |
308 | const QStringList::const_iterator scend = xmls.constEnd(); |
309 | for (QStringList::const_iterator it = xmls.constBegin(); it != scend; ++it) { |
310 | if (dp.fromXml(xml: *it, errorMessage: &errorMessage)) { |
311 | rc.push_back(t: dp); |
312 | } else { |
313 | designerWarning(message: msgWarnDeviceProfileXml(msg: errorMessage)); |
314 | } |
315 | } |
316 | return rc; |
317 | } |
318 | |
319 | void QDesignerSharedSettings::setDeviceProfiles(const DeviceProfileList &dp) |
320 | { |
321 | QStringList l; |
322 | const DeviceProfileList::const_iterator dcend = dp.constEnd(); |
323 | for (DeviceProfileList::const_iterator it = dp.constBegin(); it != dcend; ++it) |
324 | l.push_back(t: it->toXml()); |
325 | m_settings->setValue(key: QLatin1String(deviceProfilesKey), value: l); |
326 | } |
327 | } |
328 | |
329 | QT_END_NAMESPACE |
330 | |