aboutsummaryrefslogtreecommitdiffstats
path: root/src/settings_interface.cpp
blob: 13e20661f6f299abdc096be01bd541d5ada74691 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
#include "settings_interface.h"
#include <QDebug>
#include <qvariant.h>

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<QString, QVariant>;
    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<QString, QVariant>::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;
}