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";
namingModeKey()59 static inline QString namingModeKey() { return QStringLiteral("naming"); }
underScoreNamingMode()60 static inline QString underScoreNamingMode() { return QStringLiteral("underscore"); }
camelCaseNamingMode()61 static inline QString camelCaseNamingMode() { return QStringLiteral("camelcase"); }
62 
63 using namespace qdesigner_internal;
64 
checkTemplatePath(const QString & path,bool create)65 static bool checkTemplatePath(const QString &path, bool create)
66 {
67     QDir current(QDir::current());
68     if (current.exists(path))
69         return true;
70 
71     if (!create)
72         return false;
73 
74     if (current.mkpath(path))
75         return true;
76 
77     qdesigner_internal::designerWarning(QCoreApplication::translate("QDesignerSharedSettings", "The template path %1 could not be created.").arg(path));
78     return false;
79 }
80 
81 namespace qdesigner_internal {
82 
QDesignerSharedSettings(QDesignerFormEditorInterface * core)83 QDesignerSharedSettings::QDesignerSharedSettings(QDesignerFormEditorInterface *core)
84         : m_settings(core->settingsManager())
85 {
86 }
87 
defaultGrid() const88 Grid QDesignerSharedSettings::defaultGrid() const
89 {
90     Grid grid;
91     const QVariantMap defaultGridMap
92             = m_settings->value(QLatin1String(defaultGridKey), QVariantMap()).toMap();
93     if (!defaultGridMap.isEmpty())
94         grid.fromVariantMap(defaultGridMap);
95     return grid;
96 }
97 
setDefaultGrid(const Grid & grid)98 void QDesignerSharedSettings::setDefaultGrid(const Grid &grid)
99 {
100     m_settings->setValue(QLatin1String(defaultGridKey), grid.toVariantMap());
101 }
102 
defaultFormTemplatePaths()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, 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, false))
120             rc += path;
121     }
122     return rc;
123 }
124 
formTemplatePaths() const125 QStringList QDesignerSharedSettings::formTemplatePaths() const
126 {
127     return m_settings->value(QLatin1String(formTemplatePathsKey),
128                             defaultFormTemplatePaths()).toStringList();
129 }
130 
setFormTemplatePaths(const QStringList & paths)131 void QDesignerSharedSettings::setFormTemplatePaths(const QStringList &paths)
132 {
133     m_settings->setValue(QLatin1String(formTemplatePathsKey), paths);
134 }
135 
formTemplate() const136 QString  QDesignerSharedSettings::formTemplate() const
137 {
138     return m_settings->value(QLatin1String(formTemplateKey)).toString();
139 }
140 
setFormTemplate(const QString & t)141 void QDesignerSharedSettings::setFormTemplate(const QString &t)
142 {
143     m_settings->setValue(QLatin1String(formTemplateKey), t);
144 }
145 
setAdditionalFormTemplatePaths(const QStringList & additionalPaths)146 void QDesignerSharedSettings::setAdditionalFormTemplatePaths(const QStringList &additionalPaths)
147 {
148     // merge template paths
149     QStringList templatePaths = defaultFormTemplatePaths();
150     templatePaths += additionalPaths;
151     setFormTemplatePaths(templatePaths);
152 }
153 
additionalFormTemplatePaths() const154 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(internalTemplatePath);
160         if (index != -1)
161             rc.removeAt(index);
162     }
163     return rc;
164 }
165 
newFormSize() const166 QSize QDesignerSharedSettings::newFormSize() const
167 {
168     return m_settings->value(QLatin1String(newFormSizeKey), QSize(0, 0)).toSize();
169 }
170 
setNewFormSize(const QSize & s)171 void  QDesignerSharedSettings::setNewFormSize(const QSize &s)
172 {
173     if (s.isNull()) {
174         m_settings->remove(QLatin1String(newFormSizeKey));
175     } else {
176         m_settings->setValue(QLatin1String(newFormSizeKey), s);
177     }
178 }
179 
180 
customPreviewConfiguration() const181 PreviewConfiguration QDesignerSharedSettings::customPreviewConfiguration() const
182 {
183     PreviewConfiguration configuration;
184     configuration.fromSettings(QLatin1String(previewKey), m_settings);
185     return configuration;
186 }
187 
setCustomPreviewConfiguration(const PreviewConfiguration & configuration)188 void QDesignerSharedSettings::setCustomPreviewConfiguration(const PreviewConfiguration &configuration)
189 {
190     configuration.toSettings(QLatin1String(previewKey), m_settings);
191 }
192 
isCustomPreviewConfigurationEnabled() const193 bool QDesignerSharedSettings::isCustomPreviewConfigurationEnabled() const
194 {
195     m_settings->beginGroup(QLatin1String(previewKey));
196     bool isEnabled = m_settings->value(QLatin1String(enabledKey), false).toBool();
197     m_settings->endGroup();
198     return isEnabled;
199 }
200 
setCustomPreviewConfigurationEnabled(bool enabled)201 void QDesignerSharedSettings::setCustomPreviewConfigurationEnabled(bool enabled)
202 {
203     m_settings->beginGroup(QLatin1String(previewKey));
204     m_settings->setValue(QLatin1String(enabledKey), enabled);
205     m_settings->endGroup();
206 }
207 
userDeviceSkins() const208 QStringList QDesignerSharedSettings::userDeviceSkins() const
209 {
210     m_settings->beginGroup(QLatin1String(previewKey));
211     QStringList userDeviceSkins
212             = m_settings->value(QLatin1String(userDeviceSkinsKey), QStringList()).toStringList();
213     m_settings->endGroup();
214     return userDeviceSkins;
215 }
216 
setUserDeviceSkins(const QStringList & userDeviceSkins)217 void QDesignerSharedSettings::setUserDeviceSkins(const QStringList &userDeviceSkins)
218 {
219     m_settings->beginGroup(QLatin1String(previewKey));
220     m_settings->setValue(QLatin1String(userDeviceSkinsKey), userDeviceSkins);
221     m_settings->endGroup();
222 }
223 
zoom() const224 int QDesignerSharedSettings::zoom() const
225 {
226     return m_settings->value(QLatin1String(zoomKey), 100).toInt();
227 }
228 
setZoom(int z)229 void QDesignerSharedSettings::setZoom(int z)
230 {
231     m_settings->setValue(QLatin1String(zoomKey), QVariant(z));
232 }
233 
objectNamingMode() const234 ObjectNamingMode QDesignerSharedSettings::objectNamingMode() const
235 {
236     const QString value = m_settings->value(namingModeKey()).toString();
237     return value == camelCaseNamingMode()
238         ? qdesigner_internal::CamelCase : qdesigner_internal::Underscore;
239 }
240 
setObjectNamingMode(ObjectNamingMode n)241 void QDesignerSharedSettings::setObjectNamingMode(ObjectNamingMode n)
242 {
243     const QString value = n == qdesigner_internal::CamelCase
244         ? camelCaseNamingMode() : underScoreNamingMode();
245     m_settings->setValue(namingModeKey(), QVariant(value));
246 }
247 
zoomEnabled() const248 bool QDesignerSharedSettings::zoomEnabled() const
249 {
250     return m_settings->value(QLatin1String(zoomEnabledKey), false).toBool();
251 }
252 
setZoomEnabled(bool v)253 void QDesignerSharedSettings::setZoomEnabled(bool v)
254 {
255      m_settings->setValue(QLatin1String(zoomEnabledKey), v);
256 }
257 
currentDeviceProfile() const258 DeviceProfile QDesignerSharedSettings::currentDeviceProfile() const
259 {
260     return deviceProfileAt(currentDeviceProfileIndex());
261 }
262 
setCurrentDeviceProfileIndex(int i)263 void QDesignerSharedSettings::setCurrentDeviceProfileIndex(int i)
264 {
265     m_settings->setValue(QLatin1String(deviceProfileIndexKey), i);
266 }
267 
currentDeviceProfileIndex() const268 int QDesignerSharedSettings::currentDeviceProfileIndex() const
269 {
270      return m_settings->value(QLatin1String(deviceProfileIndexKey), -1).toInt();
271 }
272 
msgWarnDeviceProfileXml(const QString & msg)273 static inline QString msgWarnDeviceProfileXml(const QString &msg)
274 {
275     return QCoreApplication::translate("QDesignerSharedSettings", "An error has been encountered while parsing device profile XML: %1").arg(msg);
276 }
277 
deviceProfileAt(int idx) const278 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(xmls.at(idx), &errorMessage)) {
288         rc.clear();
289         designerWarning(msgWarnDeviceProfileXml(errorMessage));
290     }
291     return rc;
292 }
293 
deviceProfileXml() const294 QStringList QDesignerSharedSettings::deviceProfileXml() const
295 {
296     return m_settings->value(QLatin1String(deviceProfilesKey), QStringList()).toStringList();
297 }
298 
deviceProfiles() const299 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(*it, &errorMessage)) {
311             rc.push_back(dp);
312         } else {
313             designerWarning(msgWarnDeviceProfileXml(errorMessage));
314         }
315     }
316     return rc;
317 }
318 
setDeviceProfiles(const DeviceProfileList & dp)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(it->toXml());
325     m_settings->setValue(QLatin1String(deviceProfilesKey), l);
326 }
327 }
328 
329 QT_END_NAMESPACE
330