1 | // Copyright (C) 2021 The Qt Company Ltd. |
---|---|
2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 |
3 | |
4 | #include "qqmltoolingsettings_p.h" |
5 | |
6 | #include <algorithm> |
7 | |
8 | #include <QtCore/qdebug.h> |
9 | #include <QtCore/qdir.h> |
10 | #include <QtCore/qfileinfo.h> |
11 | #include <QtCore/qset.h> |
12 | #if QT_CONFIG(settings) |
13 | #include <QtCore/qsettings.h> |
14 | #endif |
15 | #include <QtCore/qstandardpaths.h> |
16 | |
17 | using namespace Qt::StringLiterals; |
18 | |
19 | void QQmlToolingSettings::addOption(const QString &name, QVariant defaultValue) |
20 | { |
21 | m_values[name] = defaultValue; |
22 | } |
23 | |
24 | bool QQmlToolingSettings::read(const QString &settingsFilePath) |
25 | { |
26 | #if QT_CONFIG(settings) |
27 | if (!QFileInfo::exists(file: settingsFilePath)) |
28 | return false; |
29 | |
30 | if (m_currentSettingsPath == settingsFilePath) |
31 | return true; |
32 | |
33 | QSettings settings(settingsFilePath, QSettings::IniFormat); |
34 | |
35 | for (const QString &key : settings.allKeys()) |
36 | m_values[key] = settings.value(key).toString(); |
37 | |
38 | m_currentSettingsPath = settingsFilePath; |
39 | |
40 | return true; |
41 | #else |
42 | return false; |
43 | #endif |
44 | } |
45 | |
46 | bool QQmlToolingSettings::writeDefaults() const |
47 | { |
48 | #if QT_CONFIG(settings) |
49 | const QString path = QFileInfo(u".%1.ini"_s.arg(a: m_toolName)).absoluteFilePath(); |
50 | |
51 | QSettings settings(path, QSettings::IniFormat); |
52 | for (auto it = m_values.constBegin(); it != m_values.constEnd(); ++it) { |
53 | settings.setValue(key: it.key(), value: it.value().isNull() ? QString() : it.value()); |
54 | } |
55 | |
56 | settings.sync(); |
57 | |
58 | if (settings.status() != QSettings::NoError) { |
59 | qWarning() << "Failed to write default settings to"<< path |
60 | << "Error:"<< settings.status(); |
61 | return false; |
62 | } |
63 | |
64 | qInfo() << "Wrote default settings to"<< path; |
65 | return true; |
66 | #else |
67 | return false; |
68 | #endif |
69 | } |
70 | |
71 | bool QQmlToolingSettings::search(const QString &path) |
72 | { |
73 | #if QT_CONFIG(settings) |
74 | QFileInfo fileInfo(path); |
75 | QDir dir(fileInfo.isDir() ? path : fileInfo.dir()); |
76 | |
77 | QSet<QString> dirs; |
78 | |
79 | const QString settingsFileName = u".%1.ini"_s.arg(a: m_toolName); |
80 | |
81 | while (dir.exists() && dir.isReadable()) { |
82 | const QString dirPath = dir.absolutePath(); |
83 | |
84 | if (m_seenDirectories.contains(key: dirPath)) { |
85 | const QString cachedIniPath = m_seenDirectories[dirPath]; |
86 | if (cachedIniPath.isEmpty()) |
87 | return false; |
88 | |
89 | return read(settingsFilePath: cachedIniPath); |
90 | } |
91 | |
92 | dirs << dirPath; |
93 | |
94 | const QString iniFile = dir.absoluteFilePath(fileName: settingsFileName); |
95 | |
96 | if (read(settingsFilePath: iniFile)) { |
97 | for (const QString &dir : std::as_const(t&: dirs)) |
98 | m_seenDirectories[dir] = iniFile; |
99 | return true; |
100 | } |
101 | |
102 | if (!dir.cdUp()) |
103 | break; |
104 | } |
105 | |
106 | if (const QString iniFile = QStandardPaths::locate(type: QStandardPaths::GenericConfigLocation, fileName: u"%1.ini"_s.arg(a: m_toolName)); |
107 | !iniFile.isEmpty()) { |
108 | if (read(settingsFilePath: iniFile)) { |
109 | for (const QString &dir : std::as_const(t&: dirs)) |
110 | m_seenDirectories[dir] = iniFile; |
111 | return true; |
112 | } |
113 | } |
114 | |
115 | // No INI file found anywhere, record the failure so we won't have to traverse the entire |
116 | // filesystem again |
117 | for (const QString &dir : std::as_const(t&: dirs)) |
118 | m_seenDirectories[dir] = QString(); |
119 | |
120 | #endif |
121 | return false; |
122 | } |
123 | |
124 | QVariant QQmlToolingSettings::value(QString name) const |
125 | { |
126 | return m_values.value(key: name); |
127 | } |
128 | |
129 | bool QQmlToolingSettings::isSet(QString name) const |
130 | { |
131 | if (!m_values.contains(key: name)) |
132 | return false; |
133 | |
134 | QVariant variant = m_values[name]; |
135 | |
136 | // Unset is encoded as an empty string |
137 | return !(variant.canConvert(targetType: QMetaType(QMetaType::QString)) && variant.toString().isEmpty()); |
138 | } |
139 |