src/configuration.cpp

branch
projects
changeset 935
8d98ee0dc917
parent 933
f4c80d92e71e
child 941
f895379d7fab
equal deleted inserted replaced
930:ab77deb851fa 935:8d98ee0dc917
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 "main.h"
30 #include "configuration.h"
31 #include "miscallenous.h"
32 #include "mainWindow.h"
33 #include "ldDocument.h"
34 #include "glRenderer.h"
35 #include "config.aux"
36
37 #ifdef _WIN32
38 # define EXTENSION ".ini"
39 #else
40 # define EXTENSION ".cfg"
41 #endif // _WIN32
42
43 #define MAX_CONFIG 512
44
45 static QMap<QString, AbstractConfigEntry*> EntriesByName;
46 static QList<AbstractConfigEntry*> ConfigurationEntries;
47
48 AbstractConfigEntry::AbstractConfigEntry (QString name) :
49 m_name (name) {}
50
51 void Config::Initialize()
52 {
53 SetupConfigurationLists();
54 print ("Configuration initialized with %1 entries\n", ConfigurationEntries.size());
55 }
56
57 static void InitConfigurationEntry (AbstractConfigEntry* entry)
58 {
59 ConfigurationEntries << entry;
60 EntriesByName[entry->name()] = entry;
61 }
62
63 //
64 // Load the configuration from file
65 //
66 bool Config::Load()
67 {
68 QSettings* settings = SettingsObject();
69 print ("Loading configuration file from %1\n", settings->fileName());
70
71 for (AbstractConfigEntry* cfg : ConfigurationEntries)
72 {
73 if (cfg == null)
74 break;
75
76 QVariant val = settings->value (cfg->name(), cfg->getDefaultAsVariant());
77 cfg->loadFromVariant (val);
78 }
79
80 if (g_win != null)
81 g_win->loadShortcuts (settings);
82
83 delete settings;
84 return true;
85 }
86
87 //
88 // Save the configuration to disk
89 //
90 bool Config::Save()
91 {
92 QSettings* settings = SettingsObject();
93
94 for (AbstractConfigEntry* cfg : ConfigurationEntries)
95 {
96 if (not cfg->isDefault())
97 settings->setValue (cfg->name(), cfg->toVariant());
98 else
99 settings->remove (cfg->name());
100 }
101
102 if (g_win != null)
103 g_win->saveShortcuts (settings);
104
105 settings->sync();
106 print ("Configuration saved to %1.\n", settings->fileName());
107 delete settings;
108 return true;
109 }
110
111 //
112 // Reset configuration to defaults.
113 //
114 void Config::ResetToDefaults()
115 {
116 for (AbstractConfigEntry* cfg : ConfigurationEntries)
117 cfg->resetValue();
118 }
119
120 //
121 // Where is the configuration file located at?
122 //
123 QString Config::FilePath (QString file)
124 {
125 return Config::DirectoryPath() + DIRSLASH + file;
126 }
127
128 //
129 // Directory of the configuration file.
130 //
131 QString Config::DirectoryPath()
132 {
133 QSettings* settings = SettingsObject();
134 QString result = Dirname (settings->fileName());
135 delete settings;
136 return result;
137 }
138
139 //
140 // Accessor to the settings object
141 //
142 QSettings* Config::SettingsObject()
143 {
144 QString path = qApp->applicationDirPath() + "/" UNIXNAME EXTENSION;
145 return new QSettings (path, QSettings::IniFormat);
146 }
147
148 //
149 // Accessor to entry list
150 //
151 QList<AbstractConfigEntry*> const& Config::AllConfigEntries()
152 {
153 return ConfigurationEntries;
154 }
155
156 AbstractConfigEntry* Config::FindByName (QString const& name)
157 {
158 auto it = EntriesByName.find (name);
159 return (it != EntriesByName.end()) ? *it : null;
160 }
161
162 template<typename T>
163 static T* GetConfigByName (QString name, AbstractConfigEntry::Type type)
164 {
165 auto it = EntriesByName.find (name);
166
167 if (it == EntriesByName.end())
168 return null;
169
170 AbstractConfigEntry* cfg = it.value();
171
172 if (cfg->getType() != type)
173 {
174 fprint (stderr, "type of %1 is %2, not %3\n", name, cfg->getType(), type);
175 abort();
176 }
177
178 return reinterpret_cast<T*> (cfg);
179 }
180
181 #undef IMPLEMENT_CONFIG
182
183 #define IMPLEMENT_CONFIG(NAME) \
184 NAME##ConfigEntry* NAME##ConfigEntry::getByName (QString name) \
185 { \
186 return GetConfigByName<NAME##ConfigEntry> (name, E##NAME##Type); \
187 }
188
189 IMPLEMENT_CONFIG (Int)
190 IMPLEMENT_CONFIG (String)
191 IMPLEMENT_CONFIG (Bool)
192 IMPLEMENT_CONFIG (Float)
193 IMPLEMENT_CONFIG (List)
194 IMPLEMENT_CONFIG (KeySequence)
195 IMPLEMENT_CONFIG (Vertex)
196
197 void IntConfigEntry::loadFromVariant (const QVariant& val)
198 {
199 *m_valueptr = val.toInt();
200 }
201
202 void StringConfigEntry::loadFromVariant (const QVariant& val)
203 {
204 *m_valueptr = val.toString();
205 }
206
207 void BoolConfigEntry::loadFromVariant (const QVariant& val)
208 {
209 *m_valueptr = val.toBool();
210 }
211
212 void ListConfigEntry::loadFromVariant (const QVariant& val)
213 {
214 *m_valueptr = val.toList();
215 }
216
217 void KeySequenceConfigEntry::loadFromVariant (const QVariant& val)
218 {
219 *m_valueptr = val.toString();
220 }
221
222 void FloatConfigEntry::loadFromVariant (const QVariant& val)
223 {
224 *m_valueptr = val.toDouble();
225 }
226
227 void VertexConfigEntry::loadFromVariant (const QVariant& val)
228 {
229 *m_valueptr = val.value<Vertex>();
230 }

mercurial