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

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

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 2773 by schoenebeck, Fri Jun 12 17:57:52 2015 UTC revision 3202 by persson, Mon May 22 18:58:46 2017 UTC
# Line 1  Line 1 
1  /*  /*
2      Copyright (c) 2014-2015 Christian Schoenebeck      Copyright (c) 2014-2017 Christian Schoenebeck
3            
4      This file is part of "gigedit" and released under the terms of the      This file is part of "gigedit" and released under the terms of the
5      GNU General Public License version 2.      GNU General Public License version 2.
6  */  */
7    
8    #include "global.h"
9  #include "Settings.h"  #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  static Settings _instance;  #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() {  Settings* Settings::singleton() {
72      return &_instance;      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  Settings::Settings() {  void Settings::load() {
234      warnUserOnExtensions = true;      Glib::KeyFile file;
235      syncSamplerInstrumentSelection = true;      try {
236      moveRootNoteWithRegionMoved = true;          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  }  }

Legend:
Removed from v.2773  
changed lines
  Added in v.3202

  ViewVC Help
Powered by ViewVC