15#include <QtCore/QStandardPaths>
17#include <QtCore/QSettings>
22QList<QLocale::Language>
AppSettings::_rgReleaseLanguages = {
33QList<QLocale::Language> AppSettings::_rgPartialLanguages = {
37AppSettings::LanguageInfo_t AppSettings::_rgLanguageInfo[] = {
38 { QLocale::AnyLanguage,
"System" },
39 { QLocale::Azerbaijani,
"Azerbaijani (Azerbaijani)" },
40 { QLocale::Bulgarian,
"български (Bulgarian)" },
41 { QLocale::Chinese,
"中文 (Chinese)" },
42 { QLocale::Dutch,
"Nederlands (Dutch)" },
43 { QLocale::English,
"English" },
44 { QLocale::Finnish,
"Suomi (Finnish)" },
45 { QLocale::French,
"Français (French)" },
46 { QLocale::German,
"Deutsche (German)" },
47 { QLocale::Greek,
"Ελληνικά (Greek)" },
48 { QLocale::Hebrew,
"עברית (Hebrew)" },
49 { QLocale::Italian,
"Italiano (Italian)" },
50 { QLocale::Japanese,
"日本語 (Japanese)" },
51 { QLocale::Korean,
"한국어 (Korean)" },
52 { QLocale::NorwegianBokmal,
"Norsk (Norwegian)" },
53 { QLocale::Polish,
"Polskie (Polish)" },
54 { QLocale::Portuguese,
"Português (Portuguese)" },
55 { QLocale::Russian,
"Pусский (Russian)" },
56 { QLocale::Spanish,
"Español (Spanish)" },
57 { QLocale::Swedish,
"Svenska (Swedish)" },
58 { QLocale::Turkish,
"Türk (Turkish)" }
65 const auto isSupported = [&supportedFirmwareClasses](
const QVariant &value) {
68 for (
const char *factName : { preferredFirmwareClassName, offlineEditingFirmwareClassName }) {
69 FactMetaData *
const metaData = _nameToMetaDataMap.value(factName);
71 qCWarning(AppSettingsLog) <<
"Missing metadata for fact" << factName;
74 const QVariantList enumValues = metaData->
enumValues();
75 for (
const QVariant &enumValue : enumValues) {
76 if (!isSupported(enumValue)) {
83 for (
Fact *
const fact : { preferredFirmwareClass(), offlineEditingFirmwareClass() }) {
84 if (!isSupported(fact->rawValue())) {
85 if (isSupported(fact->rawDefaultValue())) {
86 fact->setRawValue(fact->rawDefaultValue());
87 }
else if (!fact->enumValues().isEmpty()) {
88 fact->setRawValue(fact->enumValues().constFirst());
97 SettingsFact* savePathFact = qobject_cast<SettingsFact*>(savePath());
98 QString appName = QCoreApplication::applicationName();
99#if defined(Q_OS_ANDROID) || defined(Q_OS_IOS)
101 bool userHasModifiedSavePath =
false;
103 bool userHasModifiedSavePath = !savePathFact->rawValue().toString().isEmpty() || !_nameToMetaDataMap[savePathName]->rawDefaultValue().toString().isEmpty();
106 if (!userHasModifiedSavePath) {
107#if defined(Q_OS_ANDROID) || defined(Q_OS_IOS)
110 QDir rootDir = QDir(QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation));
111 savePathFact->setRawValue(rootDir.absolutePath());
115 if (!androidDontSaveToSDCard()->rawValue().toBool()) {
117 qCDebug(AppSettingsLog) <<
"AndroidInterface::getSDCardPath()" << rootDirPath;
118 if (rootDirPath.isEmpty() || !QDir(rootDirPath).exists()) {
120 qCWarning(AppSettingsLog) <<
"Save to SD card specified for application data. But no SD card present or permissions not granted. Using internal storage.";
121 }
else if (!QFileInfo(rootDirPath).isWritable()) {
123 QGC::showAppMessage(AppSettings::tr(
"Save to SD card specified for application data. But SD card is write protected. Using internal storage."));
127 if (rootDirPath.isEmpty()) {
128 rootDirPath = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation);
130 savePathFact->setRawValue(QDir(rootDirPath).filePath(appName));
132 savePathFact->setUserVisible(
false);
136 rootDir = QDir(QStandardPaths::writableLocation(QStandardPaths::TempLocation));
138 rootDir = QDir(QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation));
140 savePathFact->setRawValue(rootDir.filePath(appName));
150 Fact*
const fact = savePath();
151 if (value.toBool()) {
152 const QString internalBasePath = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation);
153 fact->
setRawValue(QDir(internalBasePath).filePath(appName));
159 if (!sdRootPath.isEmpty() && QDir(sdRootPath).exists() && QFileInfo(sdRootPath).isWritable()) {
160 fact->
setRawValue(QDir(sdRootPath).filePath(appName));
166 _checkSavePathDirectories();
170 if (value.toUInt() != 0) {
171 offlineEditingFirmwareClass()->setRawValue(value);
175 if (value.toUInt() != 0) {
176 offlineEditingVehicleClass()->setRawValue(value);
222 if (!_indoorPaletteFact) {
223 _indoorPaletteFact = _createSettingsFact(indoorPaletteName);
226 return _indoorPaletteFact;
231 if (!_qLocaleLanguageFact) {
232 _qLocaleLanguageFact = _createSettingsFact(qLocaleLanguageName);
235 FactMetaData* metaData = _qLocaleLanguageFact->metaData();
236 QStringList rgEnumStrings;
237 QVariantList rgEnumValues;
240 rgEnumStrings.append(_rgLanguageInfo[0].languageName);
241 rgEnumValues.append(_rgLanguageInfo[0].languageId);
243 for (
const auto& languageInfo: _rgLanguageInfo) {
244 if (_rgReleaseLanguages.contains(languageInfo.languageId)) {
245 rgEnumStrings.append(languageInfo.languageName);
246 rgEnumValues.append(languageInfo.languageId);
249 for (
const auto& languageInfo: _rgLanguageInfo) {
250 if (_rgPartialLanguages.contains(languageInfo.languageId)) {
251 rgEnumStrings.append(QString(languageInfo.languageName) + AppSettings::tr(
" (Partial)"));
252 rgEnumValues.append(languageInfo.languageId);
255#ifdef QGC_DAILY_BUILD
257 for (
const auto& languageInfo: _rgLanguageInfo) {
258 if (!_rgReleaseLanguages.contains(languageInfo.languageId) && !_rgPartialLanguages.contains(languageInfo.languageId)) {
259 rgEnumStrings.append(QString(languageInfo.languageName) + AppSettings::tr(
" (Test Only)"));
260 rgEnumValues.append(languageInfo.languageId);
266 rgEnumStrings.append(AppSettings::tr(
"Pseudo Localization (Test Only)"));
267 rgEnumValues.append(QLocale::Esperanto);
269 metaData->
setEnumInfo(rgEnumStrings, rgEnumValues);
271 if (_qLocaleLanguageFact->enumIndex() == -1) {
272 _qLocaleLanguageFact->setRawValue(QLocale::AnyLanguage);
275 return _qLocaleLanguageFact;
278void AppSettings::_qLocaleLanguageChanged()
283void AppSettings::_checkSavePathDirectories(
void)
285 const QString savePath = this->savePath()->rawValue().toString();
300QString AppSettings::_childSavePath(
const char* directory)
302 const QString rootPath = savePath()->rawValue().toString();
303 if (rootPath.isEmpty()) {
307 const QDir rootDir(rootPath);
308 if (!rootDir.exists()) {
312 return rootDir.filePath(directory);
315void AppSettings::_indoorPaletteChanged(
void)
369 QStringList strIdList = firstRunPromptIds.toString().split(
",", Qt::SkipEmptyParts);
371 for (
const QString& strId: strIdList) {
372 rgIds.append(strId.toInt());
380 for (
int id: rgIds) {
381 strList.append(QString::number(
id));
383 return QVariant(strList.join(
","));
389 if (!rgIds.contains(
id)) {
400QLocale::Language AppSettings::_qLocaleLanguageEarlyAccess(
void)
405 QLocale::Language localeLanguage =
static_cast<QLocale::Language
>(settings.value(qLocaleLanguageName).toInt());
406 for (
auto& languageInfo: _rgLanguageInfo) {
407 if (languageInfo.languageId == localeLanguage) {
408 return localeLanguage;
413 if (localeLanguage == QLocale::Esperanto) {
414 return localeLanguage;
418 localeLanguage = QLocale::AnyLanguage;
419 settings.setValue(qLocaleLanguageName, localeLanguage);
421 return localeLanguage;
#define QGC_LOGGING_CATEGORY(name, categoryStr)
#define DECLARE_SETTINGSFACT_NO_FUNC(CLASS, NAME)
#define DECLARE_SETTINGSFACT(CLASS, NAME)
#define DECLARE_SETTINGGROUP(NAME, GROUP)
static QVariant firstRunPromptsIdsListToVariant(const QList< int > &rgIds)
QString telemetrySavePath()
static constexpr const char * settingsDirectory
QString parameterSavePath()
static constexpr const char * photoDirectory
static constexpr const char * telemetryDirectory
Q_INVOKABLE void firstRunPromptIdsMarkIdAsShown(int id)
static constexpr const char * logDirectory
QString settingsSavePath()
static constexpr const char * videoDirectory
static QList< int > firstRunPromptsIdsVariantToList(const QVariant &firstRunPromptIds)
static constexpr const char * missionDirectory
static constexpr const char * mavlinkActionsDirectory
QString missionSavePath()
static constexpr const char * crashDirectory
QString mavlinkActionsSavePath()
static constexpr const char * parameterDirectory
A Fact is used to hold a single value within the system.
void rawValueChanged(const QVariant &value)
void setRawValue(const QVariant &value)
QList< QGCMAVLink::FirmwareClass_t > supportedFirmwareClasses()
Returns list of firmwares which are supported by the system.
static FirmwarePluginManager * instance()
QGCPalette is used in QML ui to expose color properties for the QGC palette.
static void setGlobalTheme(Theme newTheme)
A SettingsFact is Fact which holds a QSettings value.
bool ensureDirectoryExists(const QString &path)
QString joinPath(const QString &dir, const QString &name)
void showAppMessage(const QString &message, const QString &title)
Modal application message. Queued if the UI isn't ready yet.