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);
221 if (!_indoorPaletteFact) {
222 _indoorPaletteFact = _createSettingsFact(indoorPaletteName);
225 return _indoorPaletteFact;
230 if (!_qLocaleLanguageFact) {
231 _qLocaleLanguageFact = _createSettingsFact(qLocaleLanguageName);
234 FactMetaData* metaData = _qLocaleLanguageFact->metaData();
235 QStringList rgEnumStrings;
236 QVariantList rgEnumValues;
239 rgEnumStrings.append(_rgLanguageInfo[0].languageName);
240 rgEnumValues.append(_rgLanguageInfo[0].languageId);
242 for (
const auto& languageInfo: _rgLanguageInfo) {
243 if (_rgReleaseLanguages.contains(languageInfo.languageId)) {
244 rgEnumStrings.append(languageInfo.languageName);
245 rgEnumValues.append(languageInfo.languageId);
248 for (
const auto& languageInfo: _rgLanguageInfo) {
249 if (_rgPartialLanguages.contains(languageInfo.languageId)) {
250 rgEnumStrings.append(QString(languageInfo.languageName) + AppSettings::tr(
" (Partial)"));
251 rgEnumValues.append(languageInfo.languageId);
254#ifdef QGC_DAILY_BUILD
256 for (
const auto& languageInfo: _rgLanguageInfo) {
257 if (!_rgReleaseLanguages.contains(languageInfo.languageId) && !_rgPartialLanguages.contains(languageInfo.languageId)) {
258 rgEnumStrings.append(QString(languageInfo.languageName) + AppSettings::tr(
" (Test Only)"));
259 rgEnumValues.append(languageInfo.languageId);
265 rgEnumStrings.append(AppSettings::tr(
"Pseudo Localization (Test Only)"));
266 rgEnumValues.append(QLocale::Esperanto);
268 metaData->
setEnumInfo(rgEnumStrings, rgEnumValues);
270 if (_qLocaleLanguageFact->enumIndex() == -1) {
271 _qLocaleLanguageFact->setRawValue(QLocale::AnyLanguage);
274 return _qLocaleLanguageFact;
277void AppSettings::_qLocaleLanguageChanged()
282void AppSettings::_checkSavePathDirectories(
void)
284 const QString savePath = this->savePath()->rawValue().toString();
299QString AppSettings::_childSavePath(
const char* directory)
301 const QString rootPath = savePath()->rawValue().toString();
302 if (rootPath.isEmpty()) {
306 const QDir rootDir(rootPath);
307 if (!rootDir.exists()) {
311 return rootDir.filePath(directory);
314void AppSettings::_indoorPaletteChanged(
void)
368 QStringList strIdList = firstRunPromptIds.toString().split(
",", Qt::SkipEmptyParts);
370 for (
const QString& strId: strIdList) {
371 rgIds.append(strId.toInt());
379 for (
int id: rgIds) {
380 strList.append(QString::number(
id));
382 return QVariant(strList.join(
","));
388 if (!rgIds.contains(
id)) {
399QLocale::Language AppSettings::_qLocaleLanguageEarlyAccess(
void)
404 QLocale::Language localeLanguage =
static_cast<QLocale::Language
>(settings.value(qLocaleLanguageName).toInt());
405 for (
auto& languageInfo: _rgLanguageInfo) {
406 if (languageInfo.languageId == localeLanguage) {
407 return localeLanguage;
412 if (localeLanguage == QLocale::Esperanto) {
413 return localeLanguage;
417 localeLanguage = QLocale::AnyLanguage;
418 settings.setValue(qLocaleLanguageName, localeLanguage);
420 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.