/[svn]/gigedit/trunk/src/gigedit/Settings.cpp
ViewVC logotype

Contents of /gigedit/trunk/src/gigedit/Settings.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3202 - (show annotations) (download)
Mon May 22 18:58:46 2017 UTC (6 years, 10 months ago) by persson
File size: 12911 byte(s)
* fixed building with G_DISABLE_DEPRECATED

1 /*
2 Copyright (c) 2014-2017 Christian Schoenebeck
3
4 This file is part of "gigedit" and released under the terms of the
5 GNU General Public License version 2.
6 */
7
8 #include "global.h"
9 #include "Settings.h"
10 #include <glib.h>
11 #include <glibmm/keyfile.h>
12 #include <iostream>
13 #include <stdio.h>
14 #include <fstream>
15 #include <string.h>
16
17 #if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION < 40) || GTKMM_MAJOR_VERSION < 2
18 # define HAS_GLIB_KEYFILE_SAVE_TO_FILE 0
19 #else
20 # define HAS_GLIB_KEYFILE_SAVE_TO_FILE 1
21 #endif
22
23 static std::string configDir() {
24 //printf("configDir '%s'\n", g_get_user_config_dir());
25 return g_get_user_config_dir();
26 }
27
28 static std::string dirSep() {
29 //printf("sep '%s'\n", G_DIR_SEPARATOR_S);
30 return G_DIR_SEPARATOR_S;
31 }
32
33 static std::string configFile() {
34 return configDir() + dirSep() + "gigedit.conf";
35 }
36
37 static std::string groupName(Settings::Group_t group) {
38 switch (group) {
39 case Settings::GLOBAL: return "Global";
40 case Settings::MAIN_WINDOW: return "MainWindow";
41 case Settings::SCRIPT_EDITOR: return "ScriptEditor";
42 case Settings::DIMENSION_MANAGER: return "DimensionManager";
43 case Settings::SCRIPT_SLOTS: return "ScriptSlots";
44 case Settings::COMBINE_INSTRUMENTS: return "CombineInstruments";
45 case Settings::MIDI_RULES: return "MidiRules";
46 case Settings::FILE_PROPS: return "FileProps";
47 case Settings::INSTR_PROPS: return "InstrProps";
48 case Settings::SAMPLE_REFS: return "SampleRefs";
49 case Settings::MACRO_EDITOR: return "MacroEditor";
50 case Settings::MACROS_SETUP: return "MacrosSetup";
51 case Settings::MACROS: return "Macros";
52 }
53 return "Global";
54 }
55
56 #if !HAS_GLIB_KEYFILE_SAVE_TO_FILE
57
58 static bool saveToFile(Glib::KeyFile* keyfile, std::string filename) {
59 Glib::ustring s = keyfile->to_data();
60 std::ofstream out;
61 out.open(filename.c_str(), std::ios_base::out | std::ios_base::trunc);
62 out << s;
63 out.close();
64 return true;
65 }
66
67 #endif // ! HAS_GLIB_KEYFILE_SAVE_TO_FILE
68
69 static Settings* _instance = NULL;
70
71 Settings* Settings::singleton() {
72 if (!_instance) {
73 _instance = new Settings;
74 _instance->load();
75 }
76 return _instance;
77 }
78
79 Settings::Settings() : Glib::ObjectBase(typeid(Settings)),
80 warnUserOnExtensions(*this, GLOBAL, "warnUserOnExtensions", true),
81 syncSamplerInstrumentSelection(*this, GLOBAL, "syncSamplerInstrumentSelection", true),
82 moveRootNoteWithRegionMoved(*this, GLOBAL, "moveRootNoteWithRegionMoved", true),
83 autoRestoreWindowDimension(*this, GLOBAL, "autoRestoreWindowDimension", false),
84 saveWithTemporaryFile(*this, GLOBAL, "saveWithTemporaryFile", false),
85 mainWindowX(*this, MAIN_WINDOW, "x", -1),
86 mainWindowY(*this, MAIN_WINDOW, "y", -1),
87 mainWindowW(*this, MAIN_WINDOW, "w", -1),
88 mainWindowH(*this, MAIN_WINDOW, "h", -1),
89 scriptEditorWindowX(*this, SCRIPT_EDITOR, "x", -1),
90 scriptEditorWindowY(*this, SCRIPT_EDITOR, "y", -1),
91 scriptEditorWindowW(*this, SCRIPT_EDITOR, "w", -1),
92 scriptEditorWindowH(*this, SCRIPT_EDITOR, "h", -1),
93 scriptEditorFontSize(*this, SCRIPT_EDITOR, "fontSize", -1),
94 dimensionManagerWindowX(*this, DIMENSION_MANAGER, "x", -1),
95 dimensionManagerWindowY(*this, DIMENSION_MANAGER, "y", -1),
96 dimensionManagerWindowW(*this, DIMENSION_MANAGER, "w", -1),
97 dimensionManagerWindowH(*this, DIMENSION_MANAGER, "h", -1),
98 scriptSlotsWindowX(*this, SCRIPT_SLOTS, "x", -1),
99 scriptSlotsWindowY(*this, SCRIPT_SLOTS, "y", -1),
100 scriptSlotsWindowW(*this, SCRIPT_SLOTS, "w", -1),
101 scriptSlotsWindowH(*this, SCRIPT_SLOTS, "h", -1),
102 combineInstrumentsWindowX(*this, COMBINE_INSTRUMENTS, "x", -1),
103 combineInstrumentsWindowY(*this, COMBINE_INSTRUMENTS, "y", -1),
104 combineInstrumentsWindowW(*this, COMBINE_INSTRUMENTS, "w", -1),
105 combineInstrumentsWindowH(*this, COMBINE_INSTRUMENTS, "h", -1),
106 midiRulesWindowX(*this, MIDI_RULES, "x", -1),
107 midiRulesWindowY(*this, MIDI_RULES, "y", -1),
108 midiRulesWindowW(*this, MIDI_RULES, "w", -1),
109 midiRulesWindowH(*this, MIDI_RULES, "h", -1),
110 filePropsWindowX(*this, FILE_PROPS, "x", -1),
111 filePropsWindowY(*this, FILE_PROPS, "y", -1),
112 filePropsWindowW(*this, FILE_PROPS, "w", -1),
113 filePropsWindowH(*this, FILE_PROPS, "h", -1),
114 instrPropsWindowX(*this, INSTR_PROPS, "x", -1),
115 instrPropsWindowY(*this, INSTR_PROPS, "y", -1),
116 instrPropsWindowW(*this, INSTR_PROPS, "w", -1),
117 instrPropsWindowH(*this, INSTR_PROPS, "h", -1),
118 sampleRefsWindowX(*this, SAMPLE_REFS, "x", -1),
119 sampleRefsWindowY(*this, SAMPLE_REFS, "y", -1),
120 sampleRefsWindowW(*this, SAMPLE_REFS, "w", -1),
121 sampleRefsWindowH(*this, SAMPLE_REFS, "h", -1),
122 macroEditorWindowX(*this, MACRO_EDITOR, "x", -1),
123 macroEditorWindowY(*this, MACRO_EDITOR, "y", -1),
124 macroEditorWindowW(*this, MACRO_EDITOR, "w", -1),
125 macroEditorWindowH(*this, MACRO_EDITOR, "h", -1),
126 macrosSetupWindowX(*this, MACROS_SETUP, "x", -1),
127 macrosSetupWindowY(*this, MACROS_SETUP, "y", -1),
128 macrosSetupWindowW(*this, MACROS_SETUP, "w", -1),
129 macrosSetupWindowH(*this, MACROS_SETUP, "h", -1),
130 m_ignoreNotifies(false)
131 {
132 m_boolProps.push_back(&warnUserOnExtensions);
133 m_boolProps.push_back(&syncSamplerInstrumentSelection);
134 m_boolProps.push_back(&moveRootNoteWithRegionMoved);
135 m_boolProps.push_back(&autoRestoreWindowDimension);
136 m_boolProps.push_back(&saveWithTemporaryFile);
137 m_intProps.push_back(&mainWindowX);
138 m_intProps.push_back(&mainWindowY);
139 m_intProps.push_back(&mainWindowW);
140 m_intProps.push_back(&mainWindowH);
141 m_intProps.push_back(&scriptEditorWindowX);
142 m_intProps.push_back(&scriptEditorWindowY);
143 m_intProps.push_back(&scriptEditorWindowW);
144 m_intProps.push_back(&scriptEditorWindowH);
145 m_intProps.push_back(&scriptEditorFontSize);
146 m_intProps.push_back(&dimensionManagerWindowX);
147 m_intProps.push_back(&dimensionManagerWindowY);
148 m_intProps.push_back(&dimensionManagerWindowW);
149 m_intProps.push_back(&dimensionManagerWindowH);
150 m_intProps.push_back(&scriptSlotsWindowX);
151 m_intProps.push_back(&scriptSlotsWindowY);
152 m_intProps.push_back(&scriptSlotsWindowW);
153 m_intProps.push_back(&scriptSlotsWindowH);
154 m_intProps.push_back(&combineInstrumentsWindowX);
155 m_intProps.push_back(&combineInstrumentsWindowY);
156 m_intProps.push_back(&combineInstrumentsWindowW);
157 m_intProps.push_back(&combineInstrumentsWindowH);
158 m_intProps.push_back(&midiRulesWindowX);
159 m_intProps.push_back(&midiRulesWindowY);
160 m_intProps.push_back(&midiRulesWindowW);
161 m_intProps.push_back(&midiRulesWindowH);
162 m_intProps.push_back(&filePropsWindowX);
163 m_intProps.push_back(&filePropsWindowY);
164 m_intProps.push_back(&filePropsWindowW);
165 m_intProps.push_back(&filePropsWindowH);
166 m_intProps.push_back(&instrPropsWindowX);
167 m_intProps.push_back(&instrPropsWindowY);
168 m_intProps.push_back(&instrPropsWindowW);
169 m_intProps.push_back(&instrPropsWindowH);
170 m_intProps.push_back(&sampleRefsWindowX);
171 m_intProps.push_back(&sampleRefsWindowY);
172 m_intProps.push_back(&sampleRefsWindowW);
173 m_intProps.push_back(&sampleRefsWindowH);
174 m_intProps.push_back(&macroEditorWindowX);
175 m_intProps.push_back(&macroEditorWindowY);
176 m_intProps.push_back(&macroEditorWindowW);
177 m_intProps.push_back(&macroEditorWindowH);
178 m_intProps.push_back(&macrosSetupWindowX);
179 m_intProps.push_back(&macrosSetupWindowY);
180 m_intProps.push_back(&macrosSetupWindowW);
181 m_intProps.push_back(&macrosSetupWindowH);
182 }
183
184 void Settings::onPropertyChanged(Glib::PropertyBase* pProperty, RawValueType_t type, Group_t group) {
185 if (m_ignoreNotifies) return;
186
187 //printf("Settings::onPropertyChanged(%s)\n", pProperty->get_name().c_str());
188
189 Glib::KeyFile file;
190 try {
191 bool ok = file.load_from_file(configFile());
192 if (!ok) {
193 std::cerr << "Could not load '" << configFile() << "'\n" << std::flush;
194 }
195 } catch (...) {
196 std::cerr << "Could not load '" << configFile() << "'\n" << std::flush;
197 }
198
199 switch (type) {
200 case BOOLEAN: {
201 Property<bool>* prop = static_cast<Property<bool>*>(pProperty);
202 //std::cout << "Saving bool setting '" << prop->get_name() << "'\n" << std::flush;
203 file.set_boolean(groupName(prop->group()), prop->get_name(), prop->get_value());
204 break;
205 }
206 case INTEGER: {
207 Property<int>* prop = static_cast<Property<int>*>(pProperty);
208 //std::cout << "Saving int setting '" << prop->get_name() << "'\n" << std::flush;
209 file.set_integer(groupName(prop->group()), prop->get_name(), prop->get_value());
210 break;
211 }
212 case UNKNOWN:
213 std::cerr << "BUG: Unknown setting raw type of property '" << pProperty->get_name() << "'\n" << std::flush;
214 return;
215 }
216
217 try {
218 #if HAS_GLIB_KEYFILE_SAVE_TO_FILE
219 bool ok = file.save_to_file(configFile());
220 #else
221 bool ok = saveToFile(&file, configFile());
222 #endif
223 if (!ok) {
224 std::cerr << "Failed saving gigedit config to '" << configFile() << "'\n" << std::flush;
225 } else {
226 //std::cout <<"gigedit CONFIG SAVED\n";
227 }
228 } catch (...) {
229 std::cerr << "Failed saving gigedit config to '" << configFile() << "'\n" << std::flush;
230 }
231 }
232
233 void Settings::load() {
234 Glib::KeyFile file;
235 try {
236 bool ok = file.load_from_file(configFile());
237 if (!ok) return;
238 } catch (...) {
239 std::cerr << "Could not load gigedit config file '" << configFile() << "'\n" << std::flush;
240 return;
241 }
242
243 // ignore onPropertyChanged() calls during updating the property values below
244 m_ignoreNotifies = true;
245
246 for (int i = 0; i < m_boolProps.size(); ++i) {
247 Property<bool>* prop = static_cast<Property<bool>*>(m_boolProps[i]);
248 try {
249 const std::string group = groupName(prop->group());
250 if (!file.has_group(group)) continue;
251 if (!file.has_key(group, prop->get_name())) continue;
252 const bool value = file.get_boolean(group, prop->get_name());
253 prop->set_value(value);
254 } catch (...) {
255 continue;
256 }
257 }
258
259 for (int i = 0; i < m_intProps.size(); ++i) {
260 Property<int>* prop = static_cast<Property<int>*>(m_intProps[i]);
261 try {
262 const std::string group = groupName(prop->group());
263 if (!file.has_group(group)) continue;
264 if (!file.has_key(group, prop->get_name())) continue;
265 const int value = file.get_integer(group, prop->get_name());
266 prop->set_value(value);
267 } catch (...) {
268 continue;
269 }
270 }
271
272 m_ignoreNotifies = false;
273 }
274
275 #define MACRO_LIST_NAME "srlzl"
276
277 void Settings::loadMacros(std::vector<Serialization::Archive>& macros) {
278 const std::string group = groupName(MACROS);
279 macros.clear();
280 Glib::KeyFile file;
281 try {
282 bool ok = file.load_from_file(configFile());
283 if (!ok) return;
284 } catch (...) {
285 std::cerr << "Could not load gigedit config file '" << configFile() << "'\n" << std::flush;
286 return;
287 }
288 if (!file.has_group(group)) return;
289 if (!file.has_key(group, MACRO_LIST_NAME))
290 return;
291 std::vector<Glib::ustring> v = file.get_string_list(group, MACRO_LIST_NAME);
292 for (int i = 0; i < v.size(); ++i) {
293 Serialization::Archive macro;
294 macro.decode((const uint8_t*)v[i].c_str(), v[i].length());
295 macros.push_back(macro);
296 }
297 }
298
299 void Settings::saveMacros(const std::vector<Serialization::Archive>& macros) {
300 const std::string group = groupName(MACROS);
301 Glib::KeyFile file;
302 try {
303 bool ok = file.load_from_file(configFile());
304 if (!ok) {
305 std::cerr << "Could not load '" << configFile() << "'\n" << std::flush;
306 }
307 } catch (...) {
308 std::cerr << "Could not load '" << configFile() << "'\n" << std::flush;
309 return;
310 }
311
312 std::vector<Glib::ustring> v;
313 for (int i = 0; i < macros.size(); ++i) {
314 const Serialization::RawData& rawData = const_cast<Serialization::Archive&>(macros[i]).rawData();
315 std::string s((const char*)&rawData[0], rawData.size());
316 v.push_back(s);
317 }
318
319 file.set_string_list(group, MACRO_LIST_NAME, v);
320
321 try {
322 #if HAS_GLIB_KEYFILE_SAVE_TO_FILE
323 bool ok = file.save_to_file(configFile());
324 #else
325 bool ok = saveToFile(&file, configFile());
326 #endif
327 if (!ok) {
328 std::cerr << "Failed saving gigedit config to '" << configFile() << "'\n" << std::flush;
329 } else {
330 //std::cout <<"gigedit CONFIG SAVED\n";
331 }
332 } catch (...) {
333 std::cerr << "Failed saving gigedit config to '" << configFile() << "'\n" << std::flush;
334 }
335
336 }

  ViewVC Help
Powered by ViewVC