src/configuration.cpp

changeset 971
c00f9665a9f8
parent 970
c8aae45afd85
child 972
a34b73114823
equal deleted inserted replaced
970:c8aae45afd85 971:c00f9665a9f8
1 /*
2 * LDForge: LDraw parts authoring CAD
3 * Copyright (C) 2013 - 2015 Teemu Piippo
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 * =====================================================================
18 *
19 * config.cxx: Configuration management. I don't like how unsafe QSettings
20 * is so this implements a type-safer and identifer-safer wrapping system of
21 * configuration variables. QSettings is used underlyingly, this is a matter
22 * of interface.
23 */
24
25 #include <errno.h>
26 #include <QDir>
27 #include <QTextStream>
28 #include <QSettings>
29 #include <QApplication>
30 #include "main.h"
31 #include "configuration.h"
32 #include "miscallenous.h"
33 #include "mainwindow.h"
34 #include "ldDocument.h"
35 #include "glRenderer.h"
36 #include "configuration.inc"
37
38 #ifdef _WIN32
39 # define EXTENSION ".ini"
40 #else
41 # define EXTENSION ".cfg"
42 #endif // _WIN32
43
44 #define MAX_CONFIG 512
45
46 static QMap<QString, AbstractConfigEntry*> EntriesByName;
47 static QList<AbstractConfigEntry*> ConfigurationEntries;
48
49 AbstractConfigEntry::AbstractConfigEntry (QString name) :
50 m_name (name) {}
51
52 void Config::Initialize()
53 {
54 SetupConfigurationLists();
55 print ("Configuration initialized with %1 entries\n", ConfigurationEntries.size());
56 }
57
58 static void InitConfigurationEntry (AbstractConfigEntry* entry)
59 {
60 ConfigurationEntries << entry;
61 EntriesByName[entry->name()] = entry;
62 }
63
64 //
65 // Load the configuration from file
66 //
67 bool Config::Load()
68 {
69 QSettings* settings = SettingsObject();
70 print ("Loading configuration file from %1\n", settings->fileName());
71
72 for (AbstractConfigEntry* cfg : ConfigurationEntries)
73 {
74 if (cfg == null)
75 break;
76
77 QVariant val = settings->value (cfg->name(), cfg->getDefaultAsVariant());
78 cfg->loadFromVariant (val);
79 }
80
81 if (g_win != null)
82 g_win->loadShortcuts (settings);
83
84 delete settings;
85 return true;
86 }
87
88 //
89 // Save the configuration to disk
90 //
91 bool Config::Save()
92 {
93 QSettings* settings = SettingsObject();
94
95 for (AbstractConfigEntry* cfg : ConfigurationEntries)
96 {
97 if (not cfg->isDefault())
98 settings->setValue (cfg->name(), cfg->toVariant());
99 else
100 settings->remove (cfg->name());
101 }
102
103 if (g_win != null)
104 g_win->saveShortcuts (settings);
105
106 settings->sync();
107 print ("Configuration saved to %1.\n", settings->fileName());
108 delete settings;
109 return true;
110 }
111
112 //
113 // Reset configuration to defaults.
114 //
115 void Config::ResetToDefaults()
116 {
117 for (AbstractConfigEntry* cfg : ConfigurationEntries)
118 cfg->resetValue();
119 }
120
121 //
122 // Where is the configuration file located at?
123 //
124 QString Config::FilePath (QString file)
125 {
126 return Config::DirectoryPath() + DIRSLASH + file;
127 }
128
129 //
130 // Directory of the configuration file.
131 //
132 QString Config::DirectoryPath()
133 {
134 QSettings* settings = SettingsObject();
135 QString result = Dirname (settings->fileName());
136 delete settings;
137 return result;
138 }
139
140 //
141 // Accessor to the settings object
142 //
143 QSettings* Config::SettingsObject()
144 {
145 QString path = qApp->applicationDirPath() + "/" UNIXNAME EXTENSION;
146 return new QSettings (path, QSettings::IniFormat);
147 }
148
149 //
150 // Accessor to entry list
151 //
152 QList<AbstractConfigEntry*> const& Config::AllConfigEntries()
153 {
154 return ConfigurationEntries;
155 }
156
157 AbstractConfigEntry* Config::FindByName (QString const& name)
158 {
159 auto it = EntriesByName.find (name);
160 return (it != EntriesByName.end()) ? *it : null;
161 }
162
163 template<typename T>
164 static T* GetConfigByName (QString name, AbstractConfigEntry::Type type)
165 {
166 auto it = EntriesByName.find (name);
167
168 if (it == EntriesByName.end())
169 return null;
170
171 AbstractConfigEntry* cfg = it.value();
172
173 if (cfg->getType() != type)
174 {
175 fprint (stderr, "type of %1 is %2, not %3\n", name, cfg->getType(), type);
176 abort();
177 }
178
179 return reinterpret_cast<T*> (cfg);
180 }
181
182 #undef IMPLEMENT_CONFIG
183
184 #define IMPLEMENT_CONFIG(NAME) \
185 NAME##ConfigEntry* NAME##ConfigEntry::getByName (QString name) \
186 { \
187 return GetConfigByName<NAME##ConfigEntry> (name, E##NAME##Type); \
188 }
189
190 IMPLEMENT_CONFIG (Int)
191 IMPLEMENT_CONFIG (String)
192 IMPLEMENT_CONFIG (Bool)
193 IMPLEMENT_CONFIG (Float)
194 IMPLEMENT_CONFIG (List)
195 IMPLEMENT_CONFIG (KeySequence)
196 IMPLEMENT_CONFIG (Vertex)
197
198 void IntConfigEntry::loadFromVariant (const QVariant& val)
199 {
200 *m_valueptr = val.toInt();
201 }
202
203 void StringConfigEntry::loadFromVariant (const QVariant& val)
204 {
205 *m_valueptr = val.toString();
206 }
207
208 void BoolConfigEntry::loadFromVariant (const QVariant& val)
209 {
210 *m_valueptr = val.toBool();
211 }
212
213 void ListConfigEntry::loadFromVariant (const QVariant& val)
214 {
215 *m_valueptr = val.toList();
216 }
217
218 void KeySequenceConfigEntry::loadFromVariant (const QVariant& val)
219 {
220 *m_valueptr = val.toString();
221 }
222
223 void FloatConfigEntry::loadFromVariant (const QVariant& val)
224 {
225 *m_valueptr = val.toDouble();
226 }
227
228 void VertexConfigEntry::loadFromVariant (const QVariant& val)
229 {
230 *m_valueptr = val.value<Vertex>();
231 }

mercurial