-
Notifications
You must be signed in to change notification settings - Fork 0
/
settings.h
129 lines (103 loc) · 5.48 KB
/
settings.h
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
#pragma once
#include <QtWidgets/QTreeWidgetItem>
#include <QtCore/QVariant>
#include "specialize.h"
class QDomDocument;
class QDomNode;
/// @class Settings
/// @brief Handle application settings in a sane fashion
///
/// Settings is a base class, not intended to be instantiated directly. It
/// contains only "generic" Qt code, and should be subclassed to implement
/// persistent storage using the backend of your choice (XML, JSON, sqlite,
/// etc.).
///
/// <aside>
/// Why not just use QSettings? For some reason, QSettings in the INI
/// format was not handling my application data in a predictable way.
/// Array names were becoming section names, and settings were becoming
/// obscured and inaccessible. I wrote this class to provide a wrapper
/// around a more structured backend (e.g., XML) for more predictable
/// results, and to have a "living document" that can be updated and
/// changed on the fly while the application runs.
/// </aside>
class Settings
{
public:
Settings(const QString& application, const QString& base_filename);
virtual ~Settings() {}
virtual bool init(bool = false) { return false; }
virtual bool flush() { return false; }
virtual bool remove() { return false; }
virtual QString get_filename() { return filename; }
void set_version(int version) { this->version = version; }
int get_version() const { return version; }
QString get_error_string() const { return error_string; }
int begin_section(const QString& path);
void clear_section(const QString& path);
void clear_section();
void end_section();
int begin_array(const QString& path);
void end_array();
bool set_array_index(int index);
QVariant get_item(const QString& item_name, const QVariant& default_value = QVariant());
QVariant get_item(int index, const QVariant& default_value = QVariant());
QVariant get_array_item(int index, const QString &element_name, const QVariant& default_value = QVariant());
QVariant get_array_item(const QString& array_name, int index, const QString &element_name, const QVariant& default_value = QVariant());
void set_item(const QString& item_name, const QVariant& value);
void set_array_item(int index, const QString &element_name, const QVariant& element_value = QVariant());
void set_array_item(const QString& array_name, int index, const QString &element_name, const QVariant& element_value = QVariant());
protected: // typedefs and enums
using Item = QTreeWidgetItem;
SPECIALIZE_SHAREDPTR(Item, Item) // "ItemPointer"
SPECIALIZE_MAP(QString, Item*, SectionPath) // "SectionPathMap"
protected: // methods
QString fix_type_name(const QString& type_name);
QString get_current_path(const QStringList& current_path);
QStringList construct_path(const QString& path = QString());
Item* create_path(const QString& path);
// overridable, format-specific I/O functions (XML, JSON, etc.)
// the base class does nothing
virtual Item* read_section(QDomNode*, Item*, QStringList&) { return nullptr; }
virtual Item* read_array(QDomNode*, Item*, QStringList &) { return nullptr; }
virtual Item* read_element(QDomNode*, Item*) { return nullptr; }
virtual Item* read_item(QDomNode*, Item*) { return nullptr; }
virtual void write_section(Item*, QDomNode*, QDomDocument*) {}
virtual void write_array(Item*, QDomNode*, QDomDocument*) {}
virtual void write_element(Item*, QDomNode*, QDomDocument*) {}
virtual void write_item(Item*, QDomNode*, QDomDocument*) {}
protected: // data members
ItemPointer tree_root;
SectionPathMap section_path_map;
QString application;
QString filename;
QString error_string;
QStringList default_section;
QStringList default_array;
QList<int> current_array_index;
int version{1};
};
SPECIALIZE_SHAREDPTR(Settings, Settings) // "SettingsPointer"
/// @class SettingsXML
/// @brief Specialization of Settings for XML backend
///
/// This subclass of Settings implements persistent storage using XML
/// as the backend.
class SettingsXML : public Settings
{
public:
SettingsXML(const QString& application, const QString& base_filename);
bool init(bool clear = false) override;
bool flush() override;
bool remove() override;
protected: // methods
// format-specific I/O functions (XML, JSON, etc.)
Item* read_section(QDomNode* node, Item* parent, QStringList& current_path) override;
Item* read_array(QDomNode* node, Item* parent, QStringList ¤t_path) override;
Item* read_element(QDomNode *node, Item* parent) override;
Item* read_item(QDomNode* node, Item* parent) override;
void write_section(Item* section, QDomNode* parent, QDomDocument* doc) override;
void write_array(Item* array, QDomNode* parent, QDomDocument* doc) override;
void write_element(Item* element, QDomNode* parent, QDomDocument* doc) override;
void write_item(Item* item, QDomNode* parent, QDomDocument* doc) override;
};