Line data Source code
1 : /*
2 : * SPDX-License-Identifier: GPL-3.0-only
3 : * MuseScore-CLA-applies
4 : *
5 : * MuseScore Studio
6 : * Music Composition & Notation
7 : *
8 : * Copyright (C) 2021 MuseScore Limited and others
9 : *
10 : * This program is free software: you can redistribute it and/or modify
11 : * it under the terms of the GNU General Public License version 3 as
12 : * published by the Free Software Foundation.
13 : *
14 : * This program is distributed in the hope that it will be useful,
15 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 : * GNU General Public License for more details.
18 : *
19 : * You should have received a copy of the GNU General Public License
20 : * along with this program. If not, see <https://www.gnu.org/licenses/>.
21 : */
22 : #include "globalconfiguration.h"
23 :
24 : #include <QString>
25 : #include <QStandardPaths>
26 : #include <QDir>
27 : #include <QCoreApplication>
28 :
29 : #include "settings.h"
30 :
31 : #include "muse_framework_config.h"
32 :
33 : #include "log.h"
34 :
35 : using namespace muse;
36 :
37 : static const Settings::Key BACKUP_KEY("global", "application/backup/subfolder");
38 : static const Settings::Key DEV_MODE_ENABLED_KEY("global", "application/devModeEnabled");
39 : static const Settings::Key METRIC_UNIT_KEY("global", "application/metricUnit");
40 : static const Settings::Key HIGH_RESOLUTION_TIMERS("global", "application/highResolutionTimers");
41 :
42 : static const std::string MUSEHUB_WEB_URL("https://www.musehub.com/");
43 :
44 : static const QString INSTALL_ROOT_TOKEN("${INSTALL_ROOT}");
45 :
46 0 : static QString appInstallRoot()
47 : {
48 0 : return QDir::cleanPath(QCoreApplication::applicationDirPath() + "/..");
49 : }
50 :
51 46 : void GlobalConfiguration::init()
52 : {
53 46 : settings()->setDefaultValue(DEV_MODE_ENABLED_KEY, Val(application()->unstable()));
54 46 : settings()->setDefaultValue(HIGH_RESOLUTION_TIMERS, Val(false));
55 46 : }
56 :
57 0 : io::path_t GlobalConfiguration::appBinPath() const
58 : {
59 0 : return QCoreApplication::applicationFilePath();
60 : }
61 :
62 0 : io::path_t GlobalConfiguration::appBinDirPath() const
63 : {
64 0 : return io::path_t(QCoreApplication::applicationDirPath());
65 : }
66 :
67 0 : io::path_t GlobalConfiguration::appDataPath() const
68 : {
69 0 : if (m_appDataPath.empty()) {
70 0 : m_appDataPath = resolveAppDataPath();
71 : }
72 0 : return m_appDataPath;
73 : }
74 :
75 0 : QString GlobalConfiguration::resolveAppDataPath() const
76 : {
77 : #ifdef Q_OS_WIN
78 : QDir dir(QCoreApplication::applicationDirPath() + QString("/../"));
79 : return dir.absolutePath() + "/";
80 : #elif defined(Q_OS_MAC)
81 : QDir dir(QCoreApplication::applicationDirPath() + QString("/../Resources"));
82 : return dir.absolutePath() + "/";
83 : #elif defined(Q_OS_WASM)
84 : return "/files/share";
85 : #else
86 : // Try relative path (needed for portable AppImage and non-standard installations)
87 0 : QDir dir(QCoreApplication::applicationDirPath() + QString("/../" MUSE_APP_INSTALL_RESOURCES_LOCATION));
88 0 : if (dir.exists()) {
89 0 : return dir.absolutePath() + "/";
90 : }
91 : // Otherwise fall back to default location (e.g. if binary has moved relative to share)
92 0 : return QString(MUSE_APP_INSTALL_PREFIX "/" MUSE_APP_INSTALL_RESOURCES_LOCATION "/");
93 : #endif
94 0 : }
95 :
96 0 : bool GlobalConfiguration::isBundledWithApp(const io::path_t& path) const
97 : {
98 0 : if (!io::isAbsolute(path)) {
99 0 : return false;
100 : }
101 :
102 0 : const QString root = appInstallRoot();
103 0 : const QString abs = QDir::cleanPath(path.toQString());
104 0 : return abs == root || abs.startsWith(root + "/");
105 0 : }
106 :
107 0 : io::path_t GlobalConfiguration::toBundledPath(const io::path_t& path) const
108 : {
109 0 : IF_ASSERT_FAILED(isBundledWithApp(path)) {
110 0 : return path;
111 : }
112 :
113 0 : const QString root = appInstallRoot();
114 0 : return io::path_t(INSTALL_ROOT_TOKEN + QDir::cleanPath(path.toQString()).mid(root.length()));
115 0 : }
116 :
117 0 : bool GlobalConfiguration::isBundledPath(const io::path_t& path) const
118 : {
119 0 : return path.toQString().startsWith(INSTALL_ROOT_TOKEN);
120 : }
121 :
122 0 : io::path_t GlobalConfiguration::fromBundledPath(const io::path_t& path) const
123 : {
124 0 : IF_ASSERT_FAILED(isBundledPath(path)) {
125 0 : return path;
126 : }
127 :
128 0 : const QString rel = path.toQString().mid(INSTALL_ROOT_TOKEN.length());
129 0 : return io::path_t(QDir::cleanPath(appInstallRoot() + rel));
130 0 : }
131 :
132 0 : io::path_t GlobalConfiguration::appConfigPath() const
133 : {
134 0 : return QStandardPaths::writableLocation(QStandardPaths::ConfigLocation);
135 : }
136 :
137 46 : io::path_t GlobalConfiguration::userAppDataPath() const
138 : {
139 46 : if (m_userAppDataPath.empty()) {
140 46 : m_userAppDataPath = resolveUserAppDataPath();
141 : }
142 46 : return m_userAppDataPath;
143 : }
144 :
145 46 : QString GlobalConfiguration::resolveUserAppDataPath() const
146 : {
147 : #ifdef WIN_PORTABLE
148 : return QDir::cleanPath(QString("%1/../../../Data/settings").arg(QCoreApplication::applicationDirPath()));
149 : #elif defined(Q_OS_WASM)
150 : return QString("/files/data");
151 : #else
152 46 : return QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation);
153 : #endif
154 : }
155 :
156 0 : io::path_t GlobalConfiguration::userBackupPath() const
157 : {
158 0 : return settings()->value(BACKUP_KEY).toString();
159 : }
160 :
161 8 : io::path_t GlobalConfiguration::userDataPath() const
162 : {
163 8 : static io::path_t p = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation) + "/" + QCoreApplication::applicationName();
164 8 : return p;
165 : }
166 :
167 0 : io::path_t GlobalConfiguration::homePath() const
168 : {
169 0 : static io::path_t p = QStandardPaths::writableLocation(QStandardPaths::HomeLocation);
170 0 : return p;
171 : }
172 :
173 0 : io::path_t GlobalConfiguration::downloadsPath() const
174 : {
175 0 : static io::path_t p = QStandardPaths::writableLocation(QStandardPaths::DownloadLocation);
176 0 : return p;
177 : }
178 :
179 0 : io::path_t GlobalConfiguration::documentsPath() const
180 : {
181 0 : static io::path_t p = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation);
182 0 : return p;
183 : }
184 :
185 0 : io::path_t GlobalConfiguration::genericDataPath() const
186 : {
187 0 : static io::path_t p = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation);
188 0 : return p;
189 : }
190 :
191 0 : bool GlobalConfiguration::useFactorySettings() const
192 : {
193 0 : return false;
194 : }
195 :
196 0 : bool GlobalConfiguration::enableExperimental() const
197 : {
198 0 : return false;
199 : }
200 :
201 0 : bool GlobalConfiguration::devModeEnabled() const
202 : {
203 0 : return settings()->value(DEV_MODE_ENABLED_KEY).toBool();
204 : }
205 :
206 0 : void GlobalConfiguration::setDevModeEnabled(bool enabled)
207 : {
208 0 : settings()->setSharedValue(DEV_MODE_ENABLED_KEY, Val(enabled));
209 0 : }
210 :
211 0 : bool GlobalConfiguration::metricUnit() const
212 : {
213 0 : return settings()->value(METRIC_UNIT_KEY).toBool();
214 : }
215 :
216 0 : void GlobalConfiguration::setMetricUnit(bool metricUnit)
217 : {
218 0 : settings()->setSharedValue(METRIC_UNIT_KEY, Val(metricUnit));
219 0 : }
220 :
221 0 : std::string GlobalConfiguration::museHubWebUrl() const
222 : {
223 0 : return MUSEHUB_WEB_URL;
224 : }
225 :
226 0 : bool GlobalConfiguration::highResolutionTimers() const
227 : {
228 0 : return settings()->value(HIGH_RESOLUTION_TIMERS).toBool();
229 : }
|