Quit when requested from the menu
[ladish.git] / gui / StateManager.cpp
blob05b68b3bc8e2e0abc212456019f6c03e924829b0
1 /* -*- Mode: C ; c-basic-offset: 2 -*- */
2 /*
3 * LADI Session Handler (ladish)
5 * Copyright (C) 2007 Dave Robillard <http://drobilla.net>
7 **************************************************************************
8 * This file contains implementation of the StateManager class
9 **************************************************************************
11 * LADI Session Handler is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * LADI Session Handler is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with LADI Session Handler. If not, see <http://www.gnu.org/licenses/>
23 * or write to the Free Software Foundation, Inc.,
24 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
27 #include "common.h"
29 #include <stdexcept>
30 #include <stdlib.h>
31 #include <iostream>
32 #include <fstream>
33 #include "StateManager.hpp"
34 #include "Patchage.hpp"
36 StateManager::StateManager()
37 : _window_location(0, 0)
38 , _window_size(640, 480)
39 , _zoom(1.0)
44 bool
45 StateManager::get_module_location(const std::string& name, ModuleType type, Coord& loc)
47 std::map<std::string, ModuleSettings>::const_iterator i = _module_settings.find(name);
48 if (i == _module_settings.end())
49 return false;
51 const ModuleSettings& settings = (*i).second;
53 switch (type) {
54 case Input:
55 if (settings.input_location) {
56 loc = *settings.input_location;
57 return true;
59 break;
60 case Output:
61 if (settings.output_location) {
62 loc = *settings.output_location;
63 return true;
65 break;
66 case InputOutput:
67 if (settings.inout_location) {
68 loc = *settings.inout_location;
69 return true;
71 break;
72 default:
73 throw std::runtime_error("Invalid module type");
76 return false;
80 void
81 StateManager::set_module_location(const std::string& name, ModuleType type, Coord loc)
83 retry:
84 std::map<std::string, ModuleSettings>::iterator i = _module_settings.find(name);
85 if (i == _module_settings.end()) {
86 // no mapping exists, insert new element and set its split type, then retry to retrieve reference to it
87 _module_settings[name].split = type != InputOutput;
88 goto retry;
91 ModuleSettings& settings_ref = (*i).second;
93 switch (type) {
94 case Input:
95 settings_ref.input_location = loc;
96 break;
97 case Output:
98 settings_ref.output_location = loc;
99 break;
100 case InputOutput:
101 settings_ref.inout_location = loc;
102 break;
103 default:
104 throw std::runtime_error("Invalid module type");
109 /** Returns whether or not this module should be split.
111 * If nothing is known about the given module, @a default_val is returned (this is
112 * to allow driver's to request terminal ports get split by default).
114 bool
115 StateManager::get_module_split(const std::string& name, bool default_val) const
117 std::map<std::string, ModuleSettings>::const_iterator i = _module_settings.find(name);
118 if (i == _module_settings.end())
119 return default_val;
121 return (*i).second.split;
125 void
126 StateManager::set_module_split(const std::string& name, bool split)
128 _module_settings[name].split = split;
132 void
133 StateManager::load(const std::string& filename)
135 _module_settings.clear();
137 std::cerr << "Loading configuration file " << filename << std::endl;
139 std::ifstream is;
140 is.open(filename.c_str(), std::ios::in);
142 if ( ! is.good()) {
143 std::cerr << "Unable to load file " << filename << "!" << std::endl;
144 return;
147 std::string s;
149 is >> s;
150 if (s == "window_location") {
151 is >> s;
152 _window_location.x = atoi(s.c_str());
153 is >> s;
154 _window_location.y = atoi(s.c_str());
157 is >> s;
158 if (s == "window_size") {
159 is >> s;
160 _window_size.x = atoi(s.c_str());
161 is >> s;
162 _window_size.y = atoi(s.c_str());
165 is >> s;
166 if (s != "zoom_level") {
167 std::string msg = "Corrupt settings file: expected \"zoom_level\", found \"";
168 msg.append(s).append("\"");
169 throw std::runtime_error(msg);
172 is >> s;
173 _zoom = atof(s.c_str());
175 Coord loc;
176 ModuleType type;
177 std::string name;
179 while (1) {
180 is >> s;
181 if (is.eof()) break;
183 // Old versions didn't quote, so need to support both :/
184 if (s[0] == '\"') {
185 if (s.length() > 1 && s[s.length()-1] == '\"') {
186 name = s.substr(1, s.length()-2);
187 } else {
188 name = s.substr(1);
189 is >> s;
190 while (s[s.length()-1] != '\"') {
191 name.append(" ").append(s);
192 is >> s;
194 name.append(" ").append(s.substr(0, s.length()-1));
196 } else {
197 name = s;
200 is >> s;
201 if (s == "input") type = Input;
202 else if (s == "output") type = Output;
203 else if (s == "inputoutput") type = InputOutput;
204 else throw std::runtime_error("Corrupt settings file.");
206 is >> s;
207 loc.x = atoi(s.c_str());
208 is >> s;
209 loc.y = atoi(s.c_str());
211 set_module_location(name, type, loc);
214 is.close();
217 static inline void
218 write_module_settings_entry(
219 std::ofstream& os,
220 const std::string& name,
221 const char * type,
222 const Coord& loc)
224 os << "\"" << name << "\"" << " " << type << " " << loc.x << " " << loc.y << std::endl;
227 void
228 StateManager::save(const std::string& filename)
230 std::ofstream os;
231 os.open(filename.c_str(), std::ios::out);
233 os << "window_location " << _window_location.x << " " << _window_location.y << std::endl;
234 os << "window_size " << _window_size.x << " " << _window_size.y << std::endl;
235 os << "zoom_level " << _zoom << std::endl;
238 for (std::map<std::string, ModuleSettings>::iterator i = _module_settings.begin(); i != _module_settings.end(); ++i) {
239 const ModuleSettings& settings = (*i).second;
240 const std::string& name = (*i).first;
242 if (settings.split) {
243 write_module_settings_entry(os, name, "input", *settings.input_location);
244 write_module_settings_entry(os, name, "output", *settings.output_location);
245 } else {
246 write_module_settings_entry(os, name, "inputoutput", *settings.inout_location);
250 os.close();
252 std::cerr << "Saved configuration file " << filename << std::endl;
256 float
257 StateManager::get_zoom()
259 return _zoom;
263 void
264 StateManager::set_zoom(float zoom)
266 _zoom = zoom;
271 StateManager::get_port_color(PortType type)
273 // Darkest tango palette colour, with S -= 6, V -= 6, w/ transparency
275 if (type == JACK_AUDIO)
276 return 0x244678C0;
277 else if (type == JACK_MIDI)
278 return 0x960909C0;
279 // else if (type == ALSA_MIDI)
280 // return 0x4A8A0EC0;
281 else
282 return 0xFF0000FF;