1 // Copyright (c) Charles J. Cliffe
2 // SPDX-License-Identifier: GPL-2.0+
3
4 #include "AppConfig.h"
5 #include "CubicSDR.h"
6
7 #include <wx/msgdlg.h>
8
DeviceConfig()9 DeviceConfig::DeviceConfig() {
10 ppm.store(0);
11 offset.store(0);
12 agcMode.store(true);
13 sampleRate.store(0);
14 }
15
DeviceConfig(std::string deviceId_in)16 DeviceConfig::DeviceConfig(std::string deviceId_in) : DeviceConfig() {
17 deviceId = deviceId_in;
18 }
19
setPPM(int ppm_in)20 void DeviceConfig::setPPM(int ppm_in) {
21 ppm.store(ppm_in);
22 }
23
getPPM()24 int DeviceConfig::getPPM() {
25 return ppm.load();
26 }
27
setOffset(long long offset_in)28 void DeviceConfig::setOffset(long long offset_in) {
29 offset.store(offset_in);
30 }
31
getOffset()32 long long DeviceConfig::getOffset() {
33 return offset.load();
34 }
35
setSampleRate(long sampleRate_in)36 void DeviceConfig::setSampleRate(long sampleRate_in) {
37 sampleRate.store(sampleRate_in);
38 }
39
getSampleRate()40 long DeviceConfig::getSampleRate() {
41 return sampleRate.load();
42 }
43
setAntennaName(const std::string & name)44 void DeviceConfig::setAntennaName(const std::string& name) {
45 antennaName = name;
46 }
47
getAntennaName()48 const std::string& DeviceConfig::getAntennaName() {
49 return antennaName;
50 }
51
setAGCMode(bool agcMode_in)52 void DeviceConfig::setAGCMode(bool agcMode_in) {
53 agcMode.store(agcMode_in);
54 }
55
getAGCMode()56 bool DeviceConfig::getAGCMode() {
57 return agcMode.load();
58 }
59
60
setDeviceId(std::string deviceId_in)61 void DeviceConfig::setDeviceId(std::string deviceId_in) {
62 std::lock_guard < std::mutex > lock(busy_lock);
63 deviceId = deviceId_in;
64
65 }
66
getDeviceId()67 std::string DeviceConfig::getDeviceId() {
68 std::string tmp;
69
70 std::lock_guard < std::mutex > lock(busy_lock);
71 tmp = deviceId;
72
73
74 return tmp;
75 }
76
setDeviceName(std::string deviceName_in)77 void DeviceConfig::setDeviceName(std::string deviceName_in) {
78 std::lock_guard < std::mutex > lock(busy_lock);
79 deviceName = deviceName_in;
80 }
81
getDeviceName()82 std::string DeviceConfig::getDeviceName() {
83 std::string tmp;
84
85 std::lock_guard < std::mutex > lock(busy_lock);
86 tmp = deviceName.empty()?deviceId:deviceName;
87
88 return tmp;
89 }
90
save(DataNode * node)91 void DeviceConfig::save(DataNode *node) {
92
93 std::lock_guard < std::mutex > lock(busy_lock);
94
95 *node->newChild("id") = deviceId;
96 *node->newChild("name") = deviceName;
97 *node->newChild("ppm") = ppm.load();
98 *node->newChild("offset") = offset.load();
99 *node->newChild("sample_rate") = sampleRate.load();
100 *node->newChild("agc_mode") = agcMode.load()?1:0;
101
102 if (!antennaName.empty()) {
103 *node->newChild("antenna") = antennaName;
104 }
105
106 if (!streamOpts.empty()) {
107 DataNode *streamOptsNode = node->newChild("streamOpts");
108 for (ConfigSettings::const_iterator opt_i = streamOpts.begin(); opt_i != streamOpts.end(); opt_i++) {
109 *streamOptsNode->newChild(opt_i->first.c_str()) = opt_i->second;
110 }
111 }
112 if (!settings.empty()) {
113 DataNode *settingsNode = node->newChild("settings");
114 for (ConfigSettings::const_iterator set_i = settings.begin(); set_i != settings.end(); set_i++) {
115 *settingsNode->newChild(set_i->first.c_str()) = set_i->second;
116 }
117 }
118 if (!rigIF.empty()) {
119 DataNode *rigIFs = node->newChild("rig_ifs");
120 for (std::map<int, long long>::const_iterator rigIF_i = rigIF.begin(); rigIF_i != rigIF.end(); rigIF_i++) {
121 DataNode *ifNode = rigIFs->newChild("rig_if");
122 *ifNode->newChild("model") = rigIF_i->first;
123 *ifNode->newChild("sdr_if") = rigIF_i->second;
124 }
125 }
126 if (!gains.empty()) {
127 DataNode *gainsNode = node->newChild("gains");
128 for (ConfigGains::const_iterator gain_i = gains.begin(); gain_i != gains.end(); gain_i++) {
129 DataNode *gainNode = gainsNode->newChild("gain");
130 *gainNode->newChild("id") = gain_i->first;
131 *gainNode->newChild("value") = gain_i->second;
132 }
133 }
134
135 }
136
load(DataNode * node)137 void DeviceConfig::load(DataNode *node) {
138 std::lock_guard < std::mutex > lock(busy_lock);
139 if (node->hasAnother("name")) {
140 deviceName = node->getNext("name")->element()->toString();
141 }
142 if (node->hasAnother("ppm")) {
143 DataNode *ppm_node = node->getNext("ppm");
144 int ppmValue = 0;
145 ppm_node->element()->get(ppmValue);
146 setPPM(ppmValue);
147 }
148 if (node->hasAnother("offset")) {
149 DataNode *offset_node = node->getNext("offset");
150 long long offsetValue = 0;
151 offset_node->element()->get(offsetValue);
152 setOffset(offsetValue);
153 }
154 if (node->hasAnother("agc_mode")) {
155 DataNode *agc_node = node->getNext("agc_mode");
156 int agcModeValue = 0;
157 agc_node->element()->get(agcModeValue);
158 setAGCMode(agcModeValue != 0);
159 }
160 if (node->hasAnother("sample_rate")) {
161 DataNode *sample_rate_node = node->getNext("sample_rate");
162 long sampleRateValue = 0;
163 sample_rate_node->element()->get(sampleRateValue);
164 setSampleRate(sampleRateValue);
165 }
166 if (node->hasAnother("antenna")) {
167 DataNode *antenna_node = node->getNext("antenna");
168 std::string antennaNameValue;
169 antenna_node->element()->get(antennaNameValue);
170 setAntennaName(antennaNameValue);
171 }
172 if (node->hasAnother("streamOpts")) {
173 DataNode *streamOptsNode = node->getNext("streamOpts");
174 for (int i = 0, iMax = streamOptsNode->numChildren(); i<iMax; i++) {
175 DataNode *streamOptNode = streamOptsNode->child(i);
176 std::string keyName = streamOptNode->getName();
177 std::string strSettingValue = streamOptNode->element()->toString();
178
179 if (!keyName.empty()) {
180 setStreamOpt(keyName, strSettingValue);
181 }
182 }
183 }
184 if (node->hasAnother("settings")) {
185 DataNode *settingsNode = node->getNext("settings");
186 for (int i = 0, iMax = settingsNode->numChildren(); i<iMax; i++) {
187 DataNode *settingNode = settingsNode->child(i);
188 std::string keyName = settingNode->getName();
189 std::string strSettingValue = settingNode->element()->toString();
190
191 if (!keyName.empty()) {
192 setSetting(keyName, strSettingValue);
193 }
194 }
195 }
196 if (node->hasAnother("rig_ifs")) {
197 DataNode *rigIFNodes = node->getNext("rig_ifs");
198 while (rigIFNodes->hasAnother("rig_if")) {
199 DataNode *rigIFNode = rigIFNodes->getNext("rig_if");
200 if (rigIFNode->hasAnother("model") && rigIFNode->hasAnother("sdr_if")) {
201 int load_model;
202 long long load_freq = 0;
203
204 rigIFNode->getNext("model")->element()->get(load_model);
205 rigIFNode->getNext("sdr_if")->element()->get(load_freq);
206
207 rigIF[load_model] = load_freq;
208 }
209 }
210 }
211 if (node->hasAnother("gains")) {
212 DataNode *gainsNode = node->getNext("gains");
213 while (gainsNode->hasAnother("gain")) {
214 DataNode *gainNode = gainsNode->getNext("gain");
215 std::string keyName;
216 float fltSettingValue = 0;
217
218 gainNode->getNext("id")->element()->get(keyName);
219 gainNode->getNext("value")->element()->get(fltSettingValue);
220
221 if (!keyName.empty() && !(fltSettingValue!=fltSettingValue)) {
222 setGain(keyName, fltSettingValue);
223 }
224 }
225 }
226
227 }
228
setStreamOpts(ConfigSettings opts)229 void DeviceConfig::setStreamOpts(ConfigSettings opts) {
230 streamOpts = opts;
231 }
232
getStreamOpts()233 ConfigSettings DeviceConfig::getStreamOpts() {
234 return streamOpts;
235 }
236
setStreamOpt(const std::string & key,std::string value)237 void DeviceConfig::setStreamOpt(const std::string& key, std::string value) {
238 streamOpts[key] = value;
239 }
240
getStreamOpt(const std::string & key,std::string defaultValue)241 std::string DeviceConfig::getStreamOpt(const std::string& key, std::string defaultValue) {
242 if (streamOpts.find(key) == streamOpts.end()) {
243 return defaultValue;
244 }
245
246 return streamOpts[key];
247 }
248
setSettings(ConfigSettings settings_in)249 void DeviceConfig::setSettings(ConfigSettings settings_in) {
250 settings = settings_in;
251 }
252
setSetting(const std::string & key,std::string value)253 void DeviceConfig::setSetting(const std::string& key, std::string value) {
254 settings[key] = value;
255 }
256
getSetting(const std::string & key,std::string defaultValue)257 std::string DeviceConfig::getSetting(const std::string& key, std::string defaultValue) {
258 if (settings.find(key) == settings.end()) {
259 return defaultValue;
260 }
261 return settings[key];
262 }
263
getSettings()264 ConfigSettings DeviceConfig::getSettings() {
265 return settings;
266 }
267
268
setGains(ConfigGains gains_in)269 void DeviceConfig::setGains(ConfigGains gains_in) {
270 gains = gains_in;
271 }
272
getGains()273 ConfigGains DeviceConfig::getGains() {
274 return gains;
275 }
276
setGain(const std::string & key,float value)277 void DeviceConfig::setGain(const std::string& key, float value) {
278 gains[key] = value;
279 }
280
getGain(const std::string & key,float defaultValue)281 float DeviceConfig::getGain(const std::string& key, float defaultValue) {
282 if (gains.find(key) != gains.end()) {
283 return gains[key];
284 }
285 return defaultValue;
286 }
287
288
setRigIF(int rigType,long long freq)289 void DeviceConfig::setRigIF(int rigType, long long freq) {
290 rigIF[rigType] = freq;
291 }
292
getRigIF(int rigType)293 long long DeviceConfig::getRigIF(int rigType) {
294 if (rigIF.find(rigType) != rigIF.end()) {
295 return rigIF[rigType];
296 }
297 return 0;
298 }
299
AppConfig()300 AppConfig::AppConfig() {
301 winX.store(0);
302 winY.store(0);
303 winW.store(0);
304 winH.store(0);
305 winMax.store(false);
306 showTips.store(true);
307 perfMode.store(PERF_NORMAL);
308 themeId.store(0);
309 fontScale.store(0);
310 snap.store(1);
311 centerFreq.store(100000000);
312 waterfallLinesPerSec.store(DEFAULT_WATERFALL_LPS);
313 spectrumAvgSpeed.store(0.65f);
314 dbOffset.store(0);
315 modemPropsCollapsed.store(false);
316 mainSplit = -1;
317 visSplit = -1;
318 bookmarkSplit = 200;
319 #ifdef CUBICSDR_DEFAULT_HIDE_BOOKMARKS
320 bookmarksVisible.store(false);
321 #else
322 bookmarksVisible.store(true);
323 #endif
324
325 #ifdef USE_HAMLIB
326 rigEnabled.store(false);
327 rigModel.store(1);
328 rigRate.store(57600);
329 rigPort = "/dev/ttyUSB0";
330 rigControlMode.store(true);
331 rigFollowMode.store(true);
332 #endif
333 }
334
getDevice(const std::string & deviceId)335 DeviceConfig *AppConfig::getDevice(const std::string& deviceId) {
336 if (deviceConfig.find(deviceId) == deviceConfig.end()) {
337 deviceConfig[deviceId] = new DeviceConfig();
338 }
339 DeviceConfig *conf = deviceConfig[deviceId];
340 conf->setDeviceId(deviceId);
341 return conf;
342 }
343
getConfigDir()344 std::string AppConfig::getConfigDir() {
345 std::string dataDir = wxStandardPaths::Get().GetUserDataDir().ToStdString();
346
347 bool mkStatus = false;
348
349 if (!wxDir::Exists(dataDir)) {
350 mkStatus = wxDir::Make(dataDir);
351 } else {
352 mkStatus = true;
353 }
354
355 if (!mkStatus) {
356 std::cout << "Warning, unable to initialize user data directory." << std::endl;
357 }
358
359 return dataDir;
360 }
361
362
setWindow(wxPoint winXY,wxSize winWH)363 void AppConfig::setWindow(wxPoint winXY, wxSize winWH) {
364 winX.store(winXY.x);
365 winY.store(winXY.y);
366 winW.store(winWH.x);
367 winH.store(winWH.y);
368 }
369
setWindowMaximized(bool max)370 void AppConfig::setWindowMaximized(bool max) {
371 winMax.store(max);
372 }
373
getWindowMaximized()374 bool AppConfig::getWindowMaximized() {
375 return winMax.load();
376 }
377
setModemPropsCollapsed(bool collapse)378 void AppConfig::setModemPropsCollapsed(bool collapse) {
379 modemPropsCollapsed.store(collapse);
380 }
381
getModemPropsCollapsed()382 bool AppConfig::getModemPropsCollapsed() {
383 return modemPropsCollapsed.load();
384 }
385
setShowTips(bool show)386 void AppConfig::setShowTips(bool show) {
387 showTips.store(show);
388 }
389
getShowTips()390 bool AppConfig::getShowTips() {
391 return showTips.load();
392 }
393
setPerfMode(PerfModeEnum show)394 void AppConfig::setPerfMode(PerfModeEnum show) {
395 perfMode.store(show);
396 }
397
getPerfMode()398 AppConfig::PerfModeEnum AppConfig::getPerfMode() {
399 return perfMode.load();
400 }
401
getWindow()402 wxRect *AppConfig::getWindow() {
403 wxRect *r = nullptr;
404 if (winH.load() && winW.load()) {
405 r = new wxRect(winX.load(),winY.load(),winW.load(),winH.load());
406 }
407 return r;
408 }
409
setTheme(int themeId_in)410 void AppConfig::setTheme(int themeId_in) {
411 themeId.store(themeId_in);
412 }
413
getTheme()414 int AppConfig::getTheme() {
415 return themeId.load();
416 }
417
setFontScale(int fontScale_in)418 void AppConfig::setFontScale(int fontScale_in) {
419 fontScale.store(fontScale_in);
420 }
421
getFontScale()422 int AppConfig::getFontScale() {
423 return fontScale.load();
424 }
425
426
setSnap(long long snapVal)427 void AppConfig::setSnap(long long snapVal) {
428 this->snap.store(snapVal);
429 }
430
getSnap()431 long long AppConfig::getSnap() {
432 return snap.load();
433 }
434
setCenterFreq(long long freqVal)435 void AppConfig::setCenterFreq(long long freqVal) {
436 centerFreq.store(freqVal);
437 }
438
getCenterFreq()439 long long AppConfig::getCenterFreq() {
440 return centerFreq.load();
441 }
442
443
setWaterfallLinesPerSec(int lps)444 void AppConfig::setWaterfallLinesPerSec(int lps) {
445 waterfallLinesPerSec.store(lps);
446 }
447
getWaterfallLinesPerSec()448 int AppConfig::getWaterfallLinesPerSec() {
449 return waterfallLinesPerSec.load();
450 }
451
setSpectrumAvgSpeed(float avgSpeed)452 void AppConfig::setSpectrumAvgSpeed(float avgSpeed) {
453 spectrumAvgSpeed.store(avgSpeed);
454 }
455
getSpectrumAvgSpeed()456 float AppConfig::getSpectrumAvgSpeed() {
457 return spectrumAvgSpeed.load();
458 }
459
setDBOffset(int offset)460 void AppConfig::setDBOffset(int offset) {
461 this->dbOffset.store(offset);
462 }
463
getDBOffset()464 int AppConfig::getDBOffset() {
465 return dbOffset.load();
466 }
467
setManualDevices(std::vector<SDRManualDef> manuals)468 void AppConfig::setManualDevices(std::vector<SDRManualDef> manuals) {
469 manualDevices = manuals;
470 }
471
getManualDevices()472 std::vector<SDRManualDef> AppConfig::getManualDevices() {
473 return manualDevices;
474 }
475
setMainSplit(float value)476 void AppConfig::setMainSplit(float value) {
477 mainSplit.store(value);
478 }
479
getMainSplit()480 float AppConfig::getMainSplit() {
481 return mainSplit.load();
482 }
483
setVisSplit(float value)484 void AppConfig::setVisSplit(float value) {
485 visSplit.store(value);
486 }
487
getVisSplit()488 float AppConfig::getVisSplit() {
489 return visSplit.load();
490 }
491
setBookmarkSplit(float value)492 void AppConfig::setBookmarkSplit(float value) {
493 bookmarkSplit.store(value);
494 }
495
getBookmarkSplit()496 float AppConfig::getBookmarkSplit() {
497 return bookmarkSplit.load();
498 }
499
setBookmarksVisible(bool state)500 void AppConfig::setBookmarksVisible(bool state) {
501 bookmarksVisible.store(state);
502 }
503
getBookmarksVisible()504 bool AppConfig::getBookmarksVisible() {
505 return bookmarksVisible.load();
506 }
507
setRecordingPath(std::string recPath)508 void AppConfig::setRecordingPath(std::string recPath) {
509 recordingPath = recPath;
510 }
511
getRecordingPath()512 std::string AppConfig::getRecordingPath() {
513 return recordingPath;
514 }
515
verifyRecordingPath()516 bool AppConfig::verifyRecordingPath() {
517 string recPathStr = wxGetApp().getConfig()->getRecordingPath();
518
519 if (recPathStr.empty()) {
520 wxMessageBox( wxT("Recording path is not set. Please use 'Set Recording Path' from the 'Recording' Menu."), wxT("Recording Path Error"), wxICON_INFORMATION);
521
522 return false;
523 }
524
525 wxFileName recPath(recPathStr);
526
527 if (!recPath.Exists() || !recPath.IsDirWritable()) {
528 wxMessageBox( wxT("Recording path does not exist or is not writable. Please use 'Set Recording Path' from the 'Recording' Menu."), wxT("Recording Path Error"), wxICON_INFORMATION);
529
530 return false;
531 }
532
533 return true;
534 }
535
536
setRecordingSquelchOption(int enumChoice)537 void AppConfig::setRecordingSquelchOption(int enumChoice) {
538 recordingSquelchOption = enumChoice;
539 }
540
getRecordingSquelchOption() const541 int AppConfig::getRecordingSquelchOption() const {
542 return recordingSquelchOption;
543 }
544
setRecordingFileTimeLimit(int nbSeconds)545 void AppConfig::setRecordingFileTimeLimit(int nbSeconds) {
546 recordingFileTimeLimitSeconds = nbSeconds;
547 }
548
getRecordingFileTimeLimit() const549 int AppConfig::getRecordingFileTimeLimit() const {
550 return recordingFileTimeLimitSeconds;
551 }
552
553
setConfigName(std::string configName_in)554 void AppConfig::setConfigName(std::string configName_in) {
555 configName = configName_in;
556 }
557
getConfigFileName(bool ignoreName)558 std::string AppConfig::getConfigFileName(bool ignoreName) {
559 std::string cfgFileDir = getConfigDir();
560
561 wxFileName cfgFile;
562 if (configName.length() && !ignoreName) {
563 std::string tempFn("config-");
564 tempFn.append(configName);
565 tempFn.append(".xml");
566 cfgFile = wxFileName(cfgFileDir, tempFn);
567 } else {
568 cfgFile = wxFileName(cfgFileDir, "config.xml");
569 }
570
571 std::string cfgFileName = cfgFile.GetFullPath(wxPATH_NATIVE).ToStdString();
572
573 return cfgFileName;
574 }
575
save()576 bool AppConfig::save() {
577 DataTree cfg;
578
579 cfg.rootNode()->setName("cubicsdr_config");
580
581 if (winW.load() && winH.load()) {
582 DataNode *window_node = cfg.rootNode()->newChild("window");
583
584 *window_node->newChild("x") = winX.load();
585 *window_node->newChild("y") = winY.load();
586 *window_node->newChild("w") = winW.load();
587 *window_node->newChild("h") = winH.load();
588
589 *window_node->newChild("max") = winMax.load();
590 *window_node->newChild("tips") = showTips.load();
591 *window_node->newChild("perf_mode") = (int)perfMode.load();
592 *window_node->newChild("theme") = themeId.load();
593 *window_node->newChild("font_scale") = fontScale.load();
594 *window_node->newChild("snap") = snap.load();
595 *window_node->newChild("center_freq") = centerFreq.load();
596 *window_node->newChild("waterfall_lps") = waterfallLinesPerSec.load();
597 *window_node->newChild("spectrum_avg") = spectrumAvgSpeed.load();
598 *window_node->newChild("modemprops_collapsed") = modemPropsCollapsed.load();
599 *window_node->newChild("db_offset") = dbOffset.load();
600
601 *window_node->newChild("main_split") = mainSplit.load();
602 *window_node->newChild("vis_split") = visSplit.load();
603 *window_node->newChild("bookmark_split") = bookmarkSplit.load();
604 *window_node->newChild("bookmark_visible") = bookmarksVisible.load();
605 }
606
607 //Recording settings:
608 DataNode *rec_node = cfg.rootNode()->newChild("recording");
609 *rec_node->newChild("path") = recordingPath;
610 *rec_node->newChild("squelch") = recordingSquelchOption;
611 *rec_node->newChild("file_time_limit") = recordingFileTimeLimitSeconds;
612
613 DataNode *devices_node = cfg.rootNode()->newChild("devices");
614
615 std::map<std::string, DeviceConfig *>::iterator device_config_i;
616 for (device_config_i = deviceConfig.begin(); device_config_i != deviceConfig.end(); device_config_i++) {
617 DataNode *device_node = devices_node->newChild("device");
618 device_config_i->second->save(device_node);
619 }
620
621 if (!manualDevices.empty()) {
622 DataNode *manual_node = cfg.rootNode()->newChild("manual_devices");
623 for (const auto & manualDevice : manualDevices) {
624 DataNode *rig_node = manual_node->newChild("device");
625 *rig_node->newChild("factory") = manualDevice.factory;
626 *rig_node->newChild("params") = manualDevice.params;
627 }
628 }
629
630 #ifdef USE_HAMLIB
631 DataNode *rig_node = cfg.rootNode()->newChild("rig");
632 *rig_node->newChild("enabled") = rigEnabled.load()?1:0;
633 *rig_node->newChild("model") = rigModel.load();
634 *rig_node->newChild("rate") = rigRate.load();
635 *rig_node->newChild("port") = rigPort;
636 *rig_node->newChild("control") = rigControlMode.load()?1:0;
637 *rig_node->newChild("follow") = rigFollowMode.load()?1:0;
638 *rig_node->newChild("center_lock") = rigCenterLock.load()?1:0;
639 *rig_node->newChild("follow_modem") = rigFollowModem.load()?1:0;
640 #endif
641
642 std::string cfgFileName = getConfigFileName();
643
644 if (!cfg.SaveToFileXML(cfgFileName)) {
645 std::cout << "Error saving :: configuration file '" << cfgFileName << "' is not writable!" << std::endl;
646 return false;
647 }
648
649 return true;
650 }
651
load()652 bool AppConfig::load() {
653 DataTree cfg;
654 std::string cfgFileDir = getConfigDir();
655
656 std::string cfgFileName = getConfigFileName();
657 wxFileName cfgFile = wxFileName(cfgFileName);
658
659 if (!cfgFile.Exists()) {
660 if (configName.length()) {
661 wxFileName baseConfig = wxFileName(getConfigFileName(true));
662 if (baseConfig.Exists()) {
663 std::string baseConfigFileName = baseConfig.GetFullPath(wxPATH_NATIVE).ToStdString();
664 std::cout << "Creating new configuration file '" << cfgFileName << "' by copying '" << baseConfigFileName << "'..";
665 wxCopyFile(baseConfigFileName, cfgFileName);
666 if (!cfgFile.Exists()) {
667 std::cout << "failed." << std::endl;
668 return true;
669 }
670 std::cout << "ok." << std::endl;
671 } else {
672 return true;
673 }
674 } else {
675 return true;
676 }
677 }
678
679 if (cfgFile.IsFileReadable()) {
680 std::cout << "Loading:: configuration file '" << cfgFileName << "'" << std::endl;
681
682 cfg.LoadFromFileXML(cfgFileName);
683 } else {
684 std::cout << "Error loading:: configuration file '" << cfgFileName << "' is not readable!" << std::endl;
685 return false;
686 }
687
688 if (cfg.rootNode()->hasAnother("window")) {
689 int x = 0 ,y = 0 ,w = 0 ,h = 0;
690 int max = 0 ,tips = 0 ,perf_mode = 0 ,mpc = 0;
691
692 DataNode *win_node = cfg.rootNode()->getNext("window");
693
694 if (win_node->hasAnother("w") && win_node->hasAnother("h") && win_node->hasAnother("x") && win_node->hasAnother("y")) {
695
696 win_node->getNext("x")->element()->get(x);
697 win_node->getNext("y")->element()->get(y);
698 win_node->getNext("w")->element()->get(w);
699 win_node->getNext("h")->element()->get(h);
700
701 winX.store(x);
702 winY.store(y);
703 winW.store(w);
704 winH.store(h);
705 }
706
707 if (win_node->hasAnother("max")) {
708 win_node->getNext("max")->element()->get(max);
709 winMax.store(max != 0);
710 }
711
712 if (win_node->hasAnother("tips")) {
713 win_node->getNext("tips")->element()->get(tips);
714 showTips.store(tips != 0);
715 }
716
717 // default:
718 perfMode.store(PERF_NORMAL);
719
720 if (win_node->hasAnother("perf_mode")) {
721 win_node->getNext("perf_mode")->element()->get(perf_mode);
722
723 if (perf_mode == (int)PERF_LOW) {
724 perfMode.store(PERF_LOW);
725 } else if (perf_mode == (int)PERF_HIGH) {
726 perfMode.store(PERF_HIGH);
727 }
728 }
729
730 if (win_node->hasAnother("theme")) {
731 int theme = 0;
732 win_node->getNext("theme")->element()->get(theme);
733 themeId.store(theme);
734 }
735
736 if (win_node->hasAnother("font_scale")) {
737 int fscale = 0;
738 win_node->getNext("font_scale")->element()->get(fscale);
739 fontScale.store(fscale);
740 }
741
742 if (win_node->hasAnother("snap")) {
743 long long snapVal = 0;
744 win_node->getNext("snap")->element()->get(snapVal);
745 snap.store(snapVal);
746 }
747
748 if (win_node->hasAnother("center_freq")) {
749 long long freqVal = 0;
750 win_node->getNext("center_freq")->element()->get(freqVal);
751 centerFreq.store(freqVal);
752 }
753
754 if (win_node->hasAnother("waterfall_lps")) {
755 int lpsVal = 30;
756 win_node->getNext("waterfall_lps")->element()->get(lpsVal);
757 waterfallLinesPerSec.store(lpsVal);
758 }
759
760 if (win_node->hasAnother("spectrum_avg")) {
761 float avgVal;
762 win_node->getNext("spectrum_avg")->element()->get(avgVal);
763 spectrumAvgSpeed.store(avgVal);
764 }
765
766 if (win_node->hasAnother("modemprops_collapsed")) {
767 win_node->getNext("modemprops_collapsed")->element()->get(mpc);
768 modemPropsCollapsed.store(mpc != 0);
769 }
770
771 if (win_node->hasAnother("db_offset")) {
772 DataNode *offset_node = win_node->getNext("db_offset");
773 int offsetValue = 0;
774 offset_node->element()->get(offsetValue);
775 setDBOffset(offsetValue);
776 }
777
778 if (win_node->hasAnother("main_split")) {
779 float gVal;
780 win_node->getNext("main_split")->element()->get(gVal);
781 mainSplit.store(gVal);
782 }
783
784 if (win_node->hasAnother("vis_split")) {
785 float gVal;
786 win_node->getNext("vis_split")->element()->get(gVal);
787 visSplit.store(gVal);
788 }
789
790 if (win_node->hasAnother("bookmark_split")) {
791 float gVal;
792 win_node->getNext("bookmark_split")->element()->get(gVal);
793 bookmarkSplit.store(gVal);
794 }
795
796 if (win_node->hasAnother("bookmark_visible")) {
797 int bVal;
798 win_node->getNext("bookmark_visible")->element()->get(bVal);
799 bookmarksVisible.store(bVal);
800 }
801 }
802
803 //Recording settings:
804 if (cfg.rootNode()->hasAnother("recording")) {
805 DataNode *rec_node = cfg.rootNode()->getNext("recording");
806
807 if (rec_node->hasAnother("path")) {
808 DataNode *rec_path = rec_node->getNext("path");
809 recordingPath = rec_path->element()->toString();
810 }
811
812 if (rec_node->hasAnother("squelch")) {
813 DataNode *rec_squelch = rec_node->getNext("squelch");
814 rec_squelch->element()->get(recordingSquelchOption);
815 }
816
817 if (rec_node->hasAnother("file_time_limit")) {
818 DataNode *rec_file_time_limit = rec_node->getNext("file_time_limit");
819 rec_file_time_limit->element()->get(recordingFileTimeLimitSeconds);
820 }
821 }
822
823 if (cfg.rootNode()->hasAnother("devices")) {
824 DataNode *devices_node = cfg.rootNode()->getNext("devices");
825
826 while (devices_node->hasAnother("device")) {
827 DataNode *device_node = devices_node->getNext("device");
828 if (device_node->hasAnother("id")) {
829 std::string deviceId = device_node->getNext("id")->element()->toString();
830
831 getDevice(deviceId)->load(device_node);
832 }
833 }
834 }
835
836 if (cfg.rootNode()->hasAnother("manual_devices")) {
837 DataNode *manuals_node = cfg.rootNode()->getNext("manual_devices");
838
839 while (manuals_node->hasAnother("device")) {
840 DataNode *manual_node = manuals_node->getNext("device");
841 if (manual_node->hasAnother("factory") && manual_node->hasAnother("params")) {
842 SDRManualDef mdef;
843
844 mdef.factory = manual_node->getNext("factory")->element()->toString();
845 mdef.params = manual_node->getNext("params")->element()->toString();
846
847 manualDevices.push_back(mdef);
848 }
849 }
850 }
851
852 #ifdef USE_HAMLIB
853 if (cfg.rootNode()->hasAnother("rig")) {
854 DataNode *rig_node = cfg.rootNode()->getNext("rig");
855
856 if (rig_node->hasAnother("enabled")) {
857 int loadEnabled;
858 rig_node->getNext("enabled")->element()->get(loadEnabled);
859 rigEnabled.store(loadEnabled != 0);
860 }
861 if (rig_node->hasAnother("model")) {
862 int loadModel;
863 rig_node->getNext("model")->element()->get(loadModel);
864 rigModel.store(loadModel?loadModel:1);
865 }
866 if (rig_node->hasAnother("rate")) {
867 int loadRate;
868 rig_node->getNext("rate")->element()->get(loadRate);
869 rigRate.store(loadRate?loadRate:57600);
870 }
871 if (rig_node->hasAnother("port")) {
872 rigPort = rig_node->getNext("port")->element()->toString();
873 }
874 if (rig_node->hasAnother("control")) {
875 int loadControl;
876 rig_node->getNext("control")->element()->get(loadControl);
877 rigControlMode.store(loadControl != 0);
878 }
879 if (rig_node->hasAnother("follow")) {
880 int loadFollow;
881 rig_node->getNext("follow")->element()->get(loadFollow);
882 rigFollowMode.store(loadFollow != 0);
883 }
884 if (rig_node->hasAnother("center_lock")) {
885 int loadCenterLock;
886 rig_node->getNext("center_lock")->element()->get(loadCenterLock);
887 rigCenterLock.store(loadCenterLock != 0);
888 }
889 if (rig_node->hasAnother("follow_modem")) {
890 int loadFollow;
891 rig_node->getNext("follow_modem")->element()->get(loadFollow);
892 rigFollowModem.store(loadFollow != 0);
893 }
894 }
895 #endif
896
897
898 return true;
899 }
900
reset()901 bool AppConfig::reset() {
902
903 return true;
904 }
905
906
907 #if USE_HAMLIB
908
getRigModel()909 int AppConfig::getRigModel() {
910 return rigModel.load();
911 }
912
setRigModel(int rigModel_in)913 void AppConfig::setRigModel(int rigModel_in) {
914 rigModel.store(rigModel_in);
915 }
916
getRigRate()917 int AppConfig::getRigRate() {
918 return rigRate.load();
919 }
920
setRigRate(int rigRate_in)921 void AppConfig::setRigRate(int rigRate_in) {
922 rigRate.store(rigRate_in);
923 }
924
getRigPort()925 std::string AppConfig::getRigPort() {
926 return rigPort;
927 }
928
setRigPort(std::string rigPort_in)929 void AppConfig::setRigPort(std::string rigPort_in) {
930 rigPort = rigPort_in;
931 }
932
setRigControlMode(bool cMode)933 void AppConfig::setRigControlMode(bool cMode) {
934 rigControlMode.store(cMode);
935 }
936
getRigControlMode()937 bool AppConfig::getRigControlMode() {
938 return rigControlMode.load();
939 }
940
setRigFollowMode(bool fMode)941 void AppConfig::setRigFollowMode(bool fMode) {
942 rigFollowMode.store(fMode);
943 }
944
getRigFollowMode()945 bool AppConfig::getRigFollowMode() {
946 return rigFollowMode.load();
947 }
948
setRigCenterLock(bool cLock)949 void AppConfig::setRigCenterLock(bool cLock) {
950 rigCenterLock.store(cLock);
951 }
952
getRigCenterLock()953 bool AppConfig::getRigCenterLock() {
954 return rigCenterLock.load();
955 }
956
setRigFollowModem(bool fMode)957 void AppConfig::setRigFollowModem(bool fMode) {
958 rigFollowModem.store(fMode);
959 }
960
getRigFollowModem()961 bool AppConfig::getRigFollowModem() {
962 return rigFollowModem.load();
963 }
964
setRigEnabled(bool enabled)965 void AppConfig::setRigEnabled(bool enabled) {
966 rigEnabled.store(enabled);
967 }
968
getRigEnabled()969 bool AppConfig::getRigEnabled() {
970 return rigEnabled.load();
971 }
972
973 #endif
974