3#include <QtCore/QApplicationStatic>
4#include <QtCore/QRegularExpression>
42 : QQmlPropertyMap(this, parent)
44 qCDebug(SettingsManagerLog) <<
this;
49 qCDebug(SettingsManagerLog) <<
this;
54 return _settingsManagerInstance();
94 static const QRegularExpression validAccessorRe(QStringLiteral(
"^[a-z_][A-Za-z0-9_]*$"));
95 if (!validAccessorRe.match(accessorName).hasMatch() || !group) {
96 qCWarning(SettingsManagerLog) <<
"registerCustomSettingsGroup: invalid accessor name or null group" << accessorName;
100 if (contains(accessorName)) {
101 qCWarning(SettingsManagerLog) <<
"registerCustomSettingsGroup: accessor already registered" << accessorName;
103 if (group != value(accessorName).value<QObject*>()) {
108 if (staticMetaObject.indexOfProperty(accessorName.toUtf8().constData()) != -1) {
109 qCWarning(SettingsManagerLog) <<
"registerCustomSettingsGroup: accessor collides with a built-in settings group" << accessorName;
114 group->setParent(
this);
115 insert(accessorName, QVariant::fromValue<QObject*>(group));
116 qCDebug(SettingsManagerLog) <<
"Registered custom settings group" << accessorName;
140 return _gpsCorrectionSettings;
150void SettingsManager::_loadSettingsFiles()
172 if (!settingsDir.exists()) {
173 qCWarning(SettingsManagerLog) <<
"Settings directory does not exist:" << settingsDir.absolutePath();
177 QStringList settingsFiles = settingsDir.entryList(QStringList() << QString(
"*.%1").arg(_appSettings->
settingsFileExtension), QDir::Files);
178 for (
const QString &fileName : settingsFiles) {
179 QFileInfo fileInfo(settingsDir, fileName);
180 if (!fileInfo.isFile())
continue;
183 qCDebug(SettingsManagerLog) <<
"Loading settings file:" << fileInfo.absoluteFilePath();
185 QJsonDocument jsonDoc;
188 qCWarning(SettingsManagerLog) <<
"Failed to load settings file:" << fileInfo.absoluteFilePath() <<
errorString;
192 QJsonObject jsonObject = jsonDoc.object();
197 qCWarning(SettingsManagerLog) <<
"Settings file failed validation:" << fileInfo.absoluteFilePath() <<
errorString;
204 static const QList<JsonParsing::KeyValidateInfo> keyInfoList = {
205 { kJsonGroupsObjectKey, QJsonValue::Object,
true },
208 qCWarning(SettingsManagerLog) <<
"Settings file incorrect format:" << fileInfo.absoluteFilePath() <<
errorString;
212 auto groupsObject = jsonObject[kJsonGroupsObjectKey].toObject();
213 for (
const QString &groupName : groupsObject.
keys()) {
214 qCDebug(SettingsManagerLog) <<
" Loading settings group:" << groupName;
216 const QJsonValue &groupValue = groupsObject[groupName];
217 if (!groupValue.isObject()) {
218 qCWarning(SettingsManagerLog) <<
"Settings file incorrect format, group is not an object:" << fileInfo.absoluteFilePath()
223 auto groupObject = groupValue.toObject();
224 for (
const QString &settingName : groupObject.
keys()) {
225 qCDebug(SettingsManagerLog) <<
" Loading settings:" << groupName << settingName;
227 if (!groupObject[settingName].isObject()) {
228 qCWarning(SettingsManagerLog) <<
"Settings file incorrect format, setting is not an object:" << fileInfo.absoluteFilePath()
229 << groupName << settingName;
234 QJsonObject metaDataObject = groupObject[settingName].toObject();
235 _settingsFileOverrides[groupName][settingName] = metaDataObject;
246 if (!settingsManager) {
247 qCWarning(SettingsManagerLog) <<
"SettingsManager instance not available";
253 const auto &groupOverrides = settingsManager->_settingsFileOverrides;
254 if (groupOverrides.contains(settingsGroup) && groupOverrides[settingsGroup].contains(metaData.
name())) {
255 QJsonObject settingOverrideJsonObject = groupOverrides[settingsGroup][metaData.
name()];
258 settingOverrideJsonObject[
"name"] = metaData.
name();
261 qCDebug(SettingsManagerLog) <<
"Applying settings file override for" << settingsGroup << metaData.
name();
265 QJsonObject factMetaDataJsonObject = settingOverrideJsonObject;
266 factMetaDataJsonObject.remove(kJsonVisibleKey);
267 factMetaDataJsonObject.remove(kJsonForceRawValueKey);
271 if (settingOverrideJsonObject.contains(kJsonForceRawValueKey) && settingOverrideJsonObject.contains(kJsonVisibleKey)) {
273 qCWarning(SettingsManagerLog) <<
"Ignoring settings file override which combines 'forceRawValue' and 'visible' keys:" << settingsGroup << metaData.
name();
274 }
else if (overrideMetaData->name() != metaData.
name()) {
277 qCWarning(SettingsManagerLog) <<
"Ignoring settings file override which failed validation:" << settingsGroup << metaData.
name();
280 for (
const QString &metaDataName : factMetaDataJsonObject.keys()) {
281 if (metaDataName == FactMetaData::_defaultValueJsonKey) {
282 qCDebug(SettingsManagerLog) <<
" Setting default to" << overrideMetaData->rawDefaultValue();
284 }
else if (metaDataName == FactMetaData::_minJsonKey) {
285 qCDebug(SettingsManagerLog) <<
" Setting min to" << overrideMetaData->rawMin();
286 metaData.
setRawMin(overrideMetaData->rawMin());
287 }
else if (metaDataName == FactMetaData::_maxJsonKey) {
288 qCDebug(SettingsManagerLog) <<
" Setting max to" << overrideMetaData->rawMax();
289 metaData.
setRawMax(overrideMetaData->rawMax());
290 }
else if (metaDataName == FactMetaData::_decimalPlacesJsonKey) {
291 qCDebug(SettingsManagerLog) <<
" Setting decimalPlaces to" << overrideMetaData->decimalPlaces();
293 }
else if (metaDataName == FactMetaData::_enumValuesJsonKey) {
294 qCDebug(SettingsManagerLog) <<
" Setting enumInfo to" << overrideMetaData->enumValues() << overrideMetaData->enumStrings();
295 metaData.
setEnumInfo(overrideMetaData->enumStrings(), overrideMetaData->enumValues());
296 }
else if (metaDataName == FactMetaData::_enumBitmaskArrayJsonKey) {
297 qCDebug(SettingsManagerLog) <<
" Setting bitmaskInfo to" << overrideMetaData->bitmaskValues() << overrideMetaData->bitmaskStrings();
298 metaData.
setBitmaskInfo(overrideMetaData->bitmaskStrings(), overrideMetaData->bitmaskValues());
299 }
else if (metaDataName == FactMetaData::_longDescriptionJsonKey) {
300 qCDebug(SettingsManagerLog) <<
" Setting longDesc to" << overrideMetaData->longDescription();
302 }
else if (metaDataName == FactMetaData::_shortDescriptionJsonKey) {
303 qCDebug(SettingsManagerLog) <<
" Setting shortDesc to" << overrideMetaData->shortDescription();
309 if (settingOverrideJsonObject.contains(kJsonForceRawValueKey)) {
310 qCDebug(SettingsManagerLog) <<
" Setting forceRawValue to" << settingOverrideJsonObject[kJsonForceRawValueKey];
311 metaData.
setRawDefaultValue(settingOverrideJsonObject[kJsonForceRawValueKey].toVariant());
314 if (settingOverrideJsonObject.contains(kJsonVisibleKey)) {
315 qCDebug(SettingsManagerLog) <<
" Setting visibility to" << settingOverrideJsonObject[kJsonVisibleKey].toBool();
316 userVisible = settingOverrideJsonObject[kJsonVisibleKey].toBool();
#define QGC_LOGGING_CATEGORY(name, categoryStr)
Q_APPLICATION_STATIC(SettingsManager, _settingsManagerInstance)
std::array< MsgOutKey, 4 > keys
QString settingsSavePath()
static constexpr const char * settingsFileExtension
virtual void registerCustomSettings(SettingsManager *settingsManager)
virtual void adjustSettingMetaData(const QString &settingsGroup, FactMetaData &metaData, bool &userVisible)
static QGCCorePlugin * instance()
Provides access to group of settings.
Provides access to all app settings.
AutoConnectSettings * autoConnectSettings() const
void registerCustomSettingsGroup(const QString &accessorName, SettingsGroup *group)
Viewer3DSettings * viewer3DSettings() const
JoystickManagerSettings * joystickManagerSettings() const
MapsSettings * mapsSettings() const
FlightMapSettings * flightMapSettings() const
ADSBVehicleManagerSettings * adsbVehicleManagerSettings() const
PlanViewSettings * planViewSettings() const
UnitsSettings * unitsSettings() const
RTKSettings * rtkSettings() const
LogViewerSettings * logViewerSettings() const
BatteryIndicatorSettings * batteryIndicatorSettings() const
FirmwareUpgradeSettings * firmwareUpgradeSettings() const
FlightModeSettings * flightModeSettings() const
static SettingsManager * instance()
APMMavlinkStreamRateSettings * apmMavlinkStreamRateSettings() const
LogManagerSettings * logManagerSettings() const
VideoSettings * videoSettings() const
static void adjustSettingMetaData(const QString &settingsGroup, FactMetaData &metaData, bool &userVisible)
AppSettings * appSettings() const
OfflineMapsSettings * offlineMapsSettings() const
GPSCorrectionSettings * gpsCorrectionSettings() const
RemoteIDSettings * remoteIDSettings() const
MavlinkActionsSettings * mavlinkActionsSettings() const
FlyViewSettings * flyViewSettings() const
GimbalControllerSettings * gimbalControllerSettings() const
MavlinkSettings * mavlinkSettings() const
NTRIPSettings * ntripSettings() const
bool validateInternalQGCJsonFile(const QJsonObject &jsonObject, const QString &expectedFileType, int minSupportedVersion, int maxSupportedVersion, int &version, QString &errorString)
bool validateKeys(const QJsonObject &jsonObject, const QList< KeyValidateInfo > &keyInfo, QString &errorString)
Validates that all required keys are present and that listed keys have the expected type.
bool isJsonFile(const QByteArray &bytes, QJsonDocument &jsonDoc, QString &errorString)
Determines whether an in-memory byte buffer contains parseable JSON content.