#include "settings_interface.h" #include #include const QVariant default_setting(const QString &key); SettingsInterface::~SettingsInterface() { delete modified; modified = nullptr; } // Read a setting key and return the value associated with it. // See SettingsInterface::write_setting() for updating a key's value. const QVariant SettingsInterface::read_setting(const QString &key) { qDebug() << "Read value of" << key; if (must_clear.contains(key)) return default_setting(key); if (modified and modified->contains(key)) return modified->value(key); return qt_settings.value(key, default_setting(key)); } // Write a new value for key. Isn't written to disk until you use SettingsInterface::commit(). void SettingsInterface::write_setting(const QString &key, const QVariant &value) { if (not modified) modified = new QHash; modified->insert(key, value); qDebug() << "New modified key value:" << key << value; // As the key has a new value it doesn't have to be cleared and thus if all keys were to be cleared it isn't true anymore must_clear.removeOne(key); must_clear_all = false; } // Clear a setting and use the default value instead void SettingsInterface::clear_setting(const QString &key) { must_clear.append(key); } // Clear all settings and only use the default values void SettingsInterface::clear_all() { // Optimization to be able to clear all settings faster must_clear_all = true; // Construct a list of all settings in case one gets (written) a new value and thus must not be removed afterwards must_clear.append(qt_settings.allKeys()); if (modified) must_clear.append(modified->keys()); must_clear.removeDuplicates(); } // Write the changed settings into the internal QSetting memeber. They are then written to disk. // A return value of false indicates that an error occured while writing the config to disk. bool SettingsInterface::commit() { /* If everything has to be cleared, it is cleared and synced. * If nothing has been modified or has to removed, then quits. * If a few key(s) have to be removed they are removed, after that * if key(s) have been modified/added they are added, then synced. */ if (must_clear_all) { qt_settings.clear(); must_clear_all = false; goto sync; } else if ((not modified or (modified and modified->isEmpty())) and must_clear.isEmpty()) return true; if (not must_clear.isEmpty()) { for (int i = 0; i < must_clear.size(); ++i) qt_settings.remove(must_clear.at(i)); must_clear.clear(); } if (not modified) goto sync; { QHash::const_iterator i = modified->constBegin(); while (i != modified->constEnd()) { qt_settings.setValue(i.key(), i.value()); qDebug() << "Wrote to disk" << i.key() << i.value(); ++i; } modified->clear(); } sync: qt_settings.sync(); qDebug() << "Sync done"; return qt_settings.status() == QSettings::NoError; } // whether the key been changed from its default value. bool SettingsInterface::is_default(const QString &key) { return ((modified and modified->contains(key)) or qt_settings.contains(key)); } // Whether the key been modified and not yet been commited to disk. bool SettingsInterface::is_uncommited(const QString &key) { if (not modified) return false; return modified->contains(key); } // Return the default setting value for key. const QVariant default_setting(const QString &key) { // This is not ideal as a compile time created key-value store would be better. Though won't it end up with making the same code? if (key == "ui/timezone") return AppSettingsTypes::Timezone::LOCALTIME; else if (key == "net/access_internet") return true; else if (key == "net/download_emoji") return true; else if (key == "net/download_attachments") return true; else if (key == "net/instance/type") return AppSettingsTypes::InstanceType::MASTODON; else if (key == "net/instance/address" or key == "net/instance/token") return ""; else if (key == "ui/recent_files") return QStringList(); else return -1; }