summaryrefslogtreecommitdiffstats
path: root/api/logic/settings/SettingsObject.h
blob: 10a34f810a59aa4869c5c5a22a2470e9fa37988c (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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
/* Copyright 2013-2018 MultiMC Contributors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#pragma once

#include <QObject>
#include <QMap>
#include <QStringList>
#include <QVariant>
#include <memory>

#include "multimc_logic_export.h"

class Setting;
class SettingsObject;

typedef std::shared_ptr<SettingsObject> SettingsObjectPtr;

/*!
 * \brief The SettingsObject handles communicating settings between the application and a
 *settings file.
 * The class keeps a list of Setting objects. Each Setting object represents one
 * of the application's settings. These Setting objects are registered with
 * a SettingsObject and can be managed similarly to the way a list works.
 *
 * \author Andrew Okin
 * \date 2/22/2013
 *
 * \sa Setting
 */
class MULTIMC_LOGIC_EXPORT SettingsObject : public QObject
{
    Q_OBJECT
public:
    class Lock
    {
    public:
        Lock(SettingsObjectPtr locked)
            :m_locked(locked)
        {
            m_locked->suspendSave();
        }
        ~Lock()
        {
            m_locked->resumeSave();
        }
    private:
        SettingsObjectPtr m_locked;
    };
public:
    explicit SettingsObject(QObject *parent = 0);
    virtual ~SettingsObject();
    /*!
     * Registers an override setting for the given original setting in this settings object
     * gate decides if the passthrough (true) or the original (false) is used for value
     *
     * This will fail if there is already a setting with the same ID as
     * the one that is being registered.
     * \return A valid Setting shared pointer if successful.
     */
    std::shared_ptr<Setting> registerOverride(std::shared_ptr<Setting> original, std::shared_ptr<Setting> gate);

    /*!
     * Registers a passthorugh setting for the given original setting in this settings object
     * gate decides if the passthrough (true) or the original (false) is used for value
     *
     * This will fail if there is already a setting with the same ID as
     * the one that is being registered.
     * \return A valid Setting shared pointer if successful.
     */
    std::shared_ptr<Setting> registerPassthrough(std::shared_ptr<Setting> original, std::shared_ptr<Setting> gate);

    /*!
     * Registers the given setting with this SettingsObject and connects the necessary  signals.
     *
     * This will fail if there is already a setting with the same ID as
     * the one that is being registered.
     * \return A valid Setting shared pointer if successful.
     */
    std::shared_ptr<Setting> registerSetting(QStringList synonyms,
                                             QVariant defVal = QVariant());

    /*!
     * Registers the given setting with this SettingsObject and connects the necessary signals.
     *
     * This will fail if there is already a setting with the same ID as
     * the one that is being registered.
     * \return A valid Setting shared pointer if successful.
     */
    std::shared_ptr<Setting> registerSetting(QString id, QVariant defVal = QVariant())
    {
        return registerSetting(QStringList(id), defVal);
    }

    /*!
     * \brief Gets the setting with the given ID.
     * \param id The ID of the setting to get.
     * \return A pointer to the setting with the given ID.
     * Returns null if there is no setting with the given ID.
     * \sa operator []()
     */
    std::shared_ptr<Setting> getSetting(const QString &id) const;

    /*!
     * \brief Gets the value of the setting with the given ID.
     * \param id The ID of the setting to get.
     * \return The setting's value as a QVariant.
     * If no setting with the given ID exists, returns an invalid QVariant.
     */
    QVariant get(const QString &id) const;

    /*!
     * \brief Sets the value of the setting with the given ID.
     * If no setting with the given ID exists, returns false
     * \param id The ID of the setting to change.
     * \param value The new value of the setting.
     * \return True if successful, false if it failed.
     */
    bool set(const QString &id, QVariant value);

    /*!
     * \brief Reverts the setting with the given ID to default.
     * \param id The ID of the setting to reset.
     */
    void reset(const QString &id) const;

    /*!
     * \brief Checks if this SettingsObject contains a setting with the given ID.
     * \param id The ID to check for.
     * \return True if the SettingsObject has a setting with the given ID.
     */
    bool contains(const QString &id);

    /*!
     * \brief Reloads the settings and emit signals for changed settings
     * \return True if reloading was successful
     */
    virtual bool reload();

    virtual void suspendSave() = 0;
    virtual void resumeSave() = 0;
signals:
    /*!
     * \brief Signal emitted when one of this SettingsObject object's settings changes.
     * This is usually just connected directly to each Setting object's
     * SettingChanged() signals.
     * \param setting A reference to the Setting object that changed.
     * \param value The Setting object's new value.
     */
    void SettingChanged(const Setting &setting, QVariant value);

    /*!
     * \brief Signal emitted when one of this SettingsObject object's settings resets.
     * This is usually just connected directly to each Setting object's
     * settingReset() signals.
     * \param setting A reference to the Setting object that changed.
     */
    void settingReset(const Setting &setting);

protected
slots:
    /*!
     * \brief Changes a setting.
     * This slot is usually connected to each Setting object's
     * SettingChanged() signal. The signal is emitted, causing this slot
     * to update the setting's value in the config file.
     * \param setting A reference to the Setting object that changed.
     * \param value The setting's new value.
     */
    virtual void changeSetting(const Setting &setting, QVariant value) = 0;

    /*!
     * \brief Resets a setting.
     * This slot is usually connected to each Setting object's
     * settingReset() signal. The signal is emitted, causing this slot
     * to update the setting's value in the config file.
     * \param setting A reference to the Setting object that changed.
     */
    virtual void resetSetting(const Setting &setting) = 0;

protected:
    /*!
     * \brief Connects the necessary signals to the given Setting.
     * \param setting The setting to connect.
     */
    void connectSignals(const Setting &setting);

    /*!
     * \brief Function used by Setting objects to get their values from the SettingsObject.
     * \param setting The
     * \return
     */
    virtual QVariant retrieveValue(const Setting &setting) = 0;

    friend class Setting;

private:
    QMap<QString, std::shared_ptr<Setting>> m_settings;
protected:
    bool m_suspendSave = false;
    bool m_doSave = false;
};