1 // samplv1_config.cpp
2 //
3 /****************************************************************************
4    Copyright (C) 2012-2020, rncbc aka Rui Nuno Capela. All rights reserved.
5 
6    This program is free software; you can redistribute it and/or
7    modify it under the terms of the GNU General Public License
8    as published by the Free Software Foundation; either version 2
9    of the License, or (at your option) any later version.
10 
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15 
16    You should have received a copy of the GNU General Public License along
17    with this program; if not, write to the Free Software Foundation, Inc.,
18    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 
20 *****************************************************************************/
21 
22 #include "samplv1_config.h"
23 
24 #include "samplv1_programs.h"
25 #include "samplv1_controls.h"
26 
27 #include <QFileInfo>
28 
29 
30 //-------------------------------------------------------------------------
31 // samplv1_config - Prototype settings structure (pseudo-singleton).
32 //
33 
34 // Singleton instance accessor (static).
35 samplv1_config *samplv1_config::g_pSettings = nullptr;
36 
getInstance(void)37 samplv1_config *samplv1_config::getInstance (void)
38 {
39 	return g_pSettings;
40 }
41 
42 
43 // Constructor.
samplv1_config(void)44 samplv1_config::samplv1_config (void)
45 	: QSettings(SAMPLV1_DOMAIN, SAMPLV1_TITLE)
46 {
47 	g_pSettings = this;
48 
49 	load();
50 }
51 
52 
53 // Default destructor.
~samplv1_config(void)54 samplv1_config::~samplv1_config (void)
55 {
56 	save();
57 
58 	g_pSettings = nullptr;
59 }
60 
61 
62 // Preset utility methods.
presetGroup(void) const63 QString samplv1_config::presetGroup (void) const
64 {
65 	return "/Presets/";
66 }
67 
68 
presetFile(const QString & sPreset)69 QString samplv1_config::presetFile ( const QString& sPreset )
70 {
71 	QSettings::beginGroup(presetGroup());
72 	const QString sPresetFile(QSettings::value(sPreset).toString());
73 	QSettings::endGroup();
74 	return sPresetFile;
75 }
76 
77 
setPresetFile(const QString & sPreset,const QString & sPresetFile)78 void samplv1_config::setPresetFile (
79 	const QString& sPreset, const QString& sPresetFile )
80 {
81 	QSettings::beginGroup(presetGroup());
82 	QSettings::setValue(sPreset, sPresetFile);
83 	QSettings::endGroup();
84 }
85 
86 
removePreset(const QString & sPreset)87 void samplv1_config::removePreset ( const QString& sPreset )
88 {
89 	QSettings::beginGroup(presetGroup());
90 	const QString& sPresetFile = QSettings::value(sPreset).toString();
91 	if (QFileInfo(sPresetFile).exists())
92 		QFile(sPresetFile).remove();
93 	QSettings::remove(sPreset);
94 	QSettings::endGroup();
95 }
96 
97 
presetList(void)98 QStringList samplv1_config::presetList (void)
99 {
100 	QStringList list;
101 	QSettings::beginGroup(presetGroup());
102 	QStringListIterator iter(QSettings::childKeys());
103 	while (iter.hasNext()) {
104 		const QString& sPreset = iter.next();
105 		if (QFileInfo(QSettings::value(sPreset).toString()).exists())
106 			list.append(sPreset);
107 	}
108 	QSettings::endGroup();
109 	return list;
110 }
111 
112 
113 // Programs utility methods.
programsGroup(void) const114 QString samplv1_config::programsGroup (void) const
115 {
116 	return "/Programs";
117 }
118 
bankPrefix(void) const119 QString samplv1_config::bankPrefix (void) const
120 {
121 	return "/Bank_";
122 }
123 
124 
loadPrograms(samplv1_programs * pPrograms)125 void samplv1_config::loadPrograms ( samplv1_programs *pPrograms )
126 {
127 	pPrograms->clear_banks();
128 
129 	QSettings::beginGroup(programsGroup());
130 
131 	const QStringList& bank_keys = QSettings::childKeys();
132 	QStringListIterator bank_iter(bank_keys);
133 	while (bank_iter.hasNext()) {
134 		const QString& bank_key = bank_iter.next();
135 		uint16_t bank_id = bank_key.toInt();
136 		const QString& bank_name
137 			= QSettings::value(bank_key).toString();
138 		samplv1_programs::Bank *pBank = pPrograms->add_bank(bank_id, bank_name);
139 		QSettings::beginGroup(bankPrefix() + bank_key);
140 		const QStringList& prog_keys = QSettings::childKeys();
141 		QStringListIterator prog_iter(prog_keys);
142 		while (prog_iter.hasNext()) {
143 			const QString& prog_key = prog_iter.next();
144 			uint16_t prog_id = prog_key.toInt();
145 			const QString& prog_name
146 				= QSettings::value(prog_key).toString();
147 			pBank->add_prog(prog_id, prog_name);
148 		}
149 		QSettings::endGroup();
150 	}
151 
152 	QSettings::endGroup();
153 
154 	pPrograms->enabled(bProgramsEnabled);
155 }
156 
157 
savePrograms(samplv1_programs * pPrograms)158 void samplv1_config::savePrograms ( samplv1_programs *pPrograms )
159 {
160 	bProgramsEnabled = pPrograms->enabled();
161 
162 	clearPrograms();
163 
164 	QSettings::beginGroup(programsGroup());
165 
166 	const samplv1_programs::Banks& banks = pPrograms->banks();
167 	samplv1_programs::Banks::ConstIterator bank_iter = banks.constBegin();
168 	const samplv1_programs::Banks::ConstIterator& bank_end = banks.constEnd();
169 	for ( ; bank_iter != bank_end; ++bank_iter) {
170 		samplv1_programs::Bank *pBank = bank_iter.value();
171 		const QString& bank_key = QString::number(pBank->id());
172 		const QString& bank_name = pBank->name();
173 		QSettings::setValue(bank_key, bank_name);
174 		QSettings::beginGroup(bankPrefix() + bank_key);
175 		const samplv1_programs::Progs& progs = pBank->progs();
176 		samplv1_programs::Progs::ConstIterator prog_iter = progs.constBegin();
177 		const samplv1_programs::Progs::ConstIterator& prog_end = progs.constEnd();
178 		for ( ; prog_iter != prog_end; ++prog_iter) {
179 			samplv1_programs::Prog *pProg = prog_iter.value();
180 			const QString& prog_key = QString::number(pProg->id());
181 			const QString& prog_name = pProg->name();
182 			QSettings::setValue(prog_key, prog_name);
183 		}
184 		QSettings::endGroup();
185 	}
186 
187 	QSettings::endGroup();
188 	QSettings::sync();
189 }
190 
191 
clearPrograms(void)192 void samplv1_config::clearPrograms (void)
193 {
194 	QSettings::beginGroup(programsGroup());
195 
196 	const QStringList& bank_keys = QSettings::childKeys();
197 	QStringListIterator bank_iter(bank_keys);
198 	while (bank_iter.hasNext()) {
199 		const QString& bank_key = bank_iter.next();
200 		QSettings::beginGroup(bankPrefix() + bank_key);
201 		const QStringList& prog_keys = QSettings::childKeys();
202 		QStringListIterator prog_iter(prog_keys);
203 		while (prog_iter.hasNext()) {
204 			const QString& prog_key = prog_iter.next();
205 			QSettings::remove(prog_key);
206 		}
207 		QSettings::endGroup();
208 		QSettings::remove(bank_key);
209 	}
210 
211 	QSettings::endGroup();
212 }
213 
214 
215 // Programs utility methods.
controlsGroup(void) const216 QString samplv1_config::controlsGroup (void) const
217 {
218 	return "/Controllers";
219 }
220 
controlPrefix(void) const221 QString samplv1_config::controlPrefix (void) const
222 {
223 	return "/Control";
224 }
225 
226 
loadControls(samplv1_controls * pControls)227 void samplv1_config::loadControls ( samplv1_controls *pControls )
228 {
229 	pControls->clear();
230 
231 	QSettings::beginGroup(controlsGroup());
232 
233 	const QStringList& keys = QSettings::childKeys();
234 	QStringListIterator iter(keys);
235 	while (iter.hasNext()) {
236 		const QString& sKey = '/' + iter.next();
237 		const QStringList& clist = sKey.split('_');
238 		if (clist.at(0) == controlPrefix()) {
239 			const unsigned short channel
240 				= clist.at(1).toInt();
241 			const samplv1_controls::Type ctype
242 				= samplv1_controls::typeFromText(clist.at(2));
243 			samplv1_controls::Key key;
244 			key.status = ctype | (channel & 0x1f);
245 			key.param = clist.at(3).toInt();
246 			const QStringList& vlist
247 				= QSettings::value(sKey).toStringList();
248 			samplv1_controls::Data data;
249 			data.index = vlist.at(0).toInt();
250 			if (vlist.count() > 1)
251 				data.flags = vlist.at(1).toInt();
252 			pControls->add_control(key, data);
253 		}
254 	}
255 
256 	QSettings::endGroup();
257 
258 	pControls->enabled(bControlsEnabled);
259 }
260 
261 
saveControls(samplv1_controls * pControls)262 void samplv1_config::saveControls ( samplv1_controls *pControls )
263 {
264 	bControlsEnabled = pControls->enabled();
265 
266 	clearControls();
267 
268 	QSettings::beginGroup(controlsGroup());
269 
270 	const samplv1_controls::Map& map = pControls->map();
271 	samplv1_controls::Map::ConstIterator iter = map.constBegin();
272 	const samplv1_controls::Map::ConstIterator& iter_end = map.constEnd();
273 	for ( ; iter != iter_end; ++iter) {
274 		const samplv1_controls::Key& key = iter.key();
275 		QString sKey = controlPrefix();
276 		sKey += '_' + QString::number(key.channel());
277 		sKey += '_' + samplv1_controls::textFromType(key.type());
278 		sKey += '_' + QString::number(key.param);
279 		const samplv1_controls::Data& data = iter.value();
280 		QStringList vlist;
281 		vlist.append(QString::number(data.index));
282 		vlist.append(QString::number(data.flags));
283 		QSettings::setValue(sKey, vlist);
284 	}
285 
286 	QSettings::endGroup();
287 	QSettings::sync();
288 }
289 
290 
clearControls(void)291 void samplv1_config::clearControls (void)
292 {
293 	QSettings::beginGroup(controlsGroup());
294 
295 	const QStringList& keys = QSettings::childKeys();
296 	QStringListIterator iter(keys);
297 	while (iter.hasNext()) {
298 		const QString& key = iter.next();
299 		QSettings::remove(key);
300 	}
301 
302 	QSettings::endGroup();
303 }
304 
305 
306 // Explicit I/O methods.
load(void)307 void samplv1_config::load (void)
308 {
309 	QSettings::beginGroup("/Default");
310 	sPreset = QSettings::value("/Preset").toString();
311 	sPresetDir = QSettings::value("/PresetDir").toString();
312 	sSampleDir = QSettings::value("/SampleDir").toString();
313 	iKnobDialMode = QSettings::value("/KnobDialMode", 0).toInt();
314 	iKnobEditMode = QSettings::value("/KnobEditMode", 0).toInt();
315 	iFrameTimeFormat = QSettings::value("/FrameTimeFormat", 0).toInt();
316 	fRandomizePercent = QSettings::value("/RandomizePercent", 20.0f).toFloat();
317 	iPitchShiftType  = QSettings::value("/PitchShiftType", 0).toInt();
318 	bControlsEnabled = QSettings::value("/ControlsEnabled", false).toBool();
319 	bProgramsEnabled = QSettings::value("/ProgramsEnabled", false).toBool();
320 	QSettings::endGroup();
321 
322 	QSettings::beginGroup("/Dialogs");
323 	bProgramsPreview = QSettings::value("/ProgramsPreview", false).toBool();
324 	bUseNativeDialogs = QSettings::value("/UseNativeDialogs", false).toBool();
325 	// Run-time special non-persistent options.
326 	bDontUseNativeDialogs = !bUseNativeDialogs;
327 	QSettings::endGroup();
328 
329 	QSettings::beginGroup("/Custom");
330 	sCustomColorTheme = QSettings::value("/ColorTheme").toString();
331 	sCustomStyleTheme = QSettings::value("/StyleTheme").toString();
332 	QSettings::endGroup();
333 
334 	// Micro-tuning options.
335 	QSettings::beginGroup("/Tuning");
336 	bTuningEnabled = QSettings::value("/Enabled", false).toBool();
337 	fTuningRefPitch = float(QSettings::value("/RefPitch", 440.0).toDouble());
338 	iTuningRefNote = QSettings::value("/RefNote", 69).toInt();
339 	sTuningScaleDir = QSettings::value("/ScaleDir").toString();
340 	sTuningScaleFile = QSettings::value("/ScaleFile").toString();
341 	sTuningKeyMapDir = QSettings::value("/KeyMapDir").toString();
342 	sTuningKeyMapFile = QSettings::value("/KeyMapFile").toString();
343 	QSettings::endGroup();
344 }
345 
346 
save(void)347 void samplv1_config::save (void)
348 {
349 	QSettings::beginGroup("/Program");
350 	QSettings::setValue("/Version", CONFIG_BUILD_VERSION);
351 	QSettings::endGroup();
352 
353 	QSettings::beginGroup("/Default");
354 	QSettings::setValue("/Preset", sPreset);
355 	QSettings::setValue("/PresetDir", sPresetDir);
356 	QSettings::setValue("/SampleDir", sSampleDir);
357 	QSettings::setValue("/KnobDialMode", iKnobDialMode);
358 	QSettings::setValue("/KnobEditMode", iKnobEditMode);
359 	QSettings::setValue("/FrameTimeFormat", iFrameTimeFormat);
360 	QSettings::setValue("/RandomizePercent", fRandomizePercent);
361 	QSettings::setValue("/PitchShiftType", iPitchShiftType);
362 	QSettings::setValue("/ControlsEnabled", bControlsEnabled);
363 	QSettings::setValue("/ProgramsEnabled", bProgramsEnabled);
364 	QSettings::endGroup();
365 
366 	QSettings::beginGroup("/Dialogs");
367 	QSettings::setValue("/ProgramsPreview", bProgramsPreview);
368 	QSettings::setValue("/UseNativeDialogs", bUseNativeDialogs);
369 	QSettings::endGroup();
370 
371 	QSettings::beginGroup("/Custom");
372 	QSettings::setValue("/ColorTheme", sCustomColorTheme);
373 	QSettings::setValue("/StyleTheme", sCustomStyleTheme);
374 	QSettings::endGroup();
375 
376 	// Micro-tuning options.
377 	QSettings::beginGroup("/Tuning");
378 	QSettings::setValue("/Enabled", bTuningEnabled);
379 	QSettings::setValue("/RefPitch", double(fTuningRefPitch));
380 	QSettings::setValue("/RefNote", iTuningRefNote);
381 	QSettings::setValue("/ScaleDir", sTuningScaleDir);
382 	QSettings::setValue("/ScaleFile", sTuningScaleFile);
383 	QSettings::setValue("/KeyMapDir", sTuningKeyMapDir);
384 	QSettings::setValue("/KeyMapFile", sTuningKeyMapFile);
385 	QSettings::endGroup();
386 
387 	QSettings::sync();
388 }
389 
390 
391 // end of samplv1_config.cpp
392 
393