2017-01-02 21:27:08 -05:00
|
|
|
// Copyright (c) Charles J. Cliffe
|
|
|
|
// SPDX-License-Identifier: GPL-2.0+
|
|
|
|
|
2016-09-14 19:46:57 -04:00
|
|
|
#include "BookmarkMgr.h"
|
2016-09-14 22:10:27 -04:00
|
|
|
#include "CubicSDR.h"
|
|
|
|
#include "DataTree.h"
|
2018-01-08 13:23:01 -05:00
|
|
|
#include <wx/string.h>
|
2016-09-14 19:46:57 -04:00
|
|
|
|
2016-12-12 23:47:05 -05:00
|
|
|
#define BOOKMARK_RECENTS_MAX 25
|
|
|
|
|
2017-03-20 20:20:17 -04:00
|
|
|
BookmarkEntry::~BookmarkEntry() {
|
|
|
|
delete node;
|
|
|
|
}
|
|
|
|
|
2016-12-27 00:06:25 -05:00
|
|
|
BookmarkMgr::BookmarkMgr() {
|
|
|
|
rangesSorted = false;
|
|
|
|
}
|
2016-09-14 19:46:57 -04:00
|
|
|
|
2017-04-01 13:38:08 -04:00
|
|
|
//represents an empty BookMarkList that is returned by reference by some functions.
|
|
|
|
const BookmarkList BookmarkMgr::emptyResults;
|
|
|
|
|
2018-01-06 04:22:14 -05:00
|
|
|
void BookmarkMgr::saveToFile(std::string bookmarkFn, bool backup, bool useFullpath) {
|
|
|
|
|
2016-12-12 23:47:05 -05:00
|
|
|
DataTree s("cubicsdr_bookmarks");
|
|
|
|
DataNode *header = s.rootNode()->newChild("header");
|
|
|
|
header->newChild("version")->element()->set(wxString(CUBICSDR_VERSION).ToStdWstring());
|
2016-12-27 00:46:12 -05:00
|
|
|
|
2016-12-27 13:01:19 -05:00
|
|
|
DataNode *branches = s.rootNode()->newChild("branches");
|
|
|
|
|
|
|
|
*branches->newChild("active") = wxGetApp().getAppFrame()->getBookmarkView()->getExpandState("active")?1:0;
|
|
|
|
*branches->newChild("range") = wxGetApp().getAppFrame()->getBookmarkView()->getExpandState("range")?1:0;
|
|
|
|
*branches->newChild("bookmark") = wxGetApp().getAppFrame()->getBookmarkView()->getExpandState("bookmark")?1:0;
|
|
|
|
*branches->newChild("recent") = wxGetApp().getAppFrame()->getBookmarkView()->getExpandState("recent")?1:0;
|
|
|
|
|
2016-12-27 00:46:12 -05:00
|
|
|
DataNode *view_ranges = s.rootNode()->newChild("ranges");
|
|
|
|
|
|
|
|
for (auto re_i : ranges) {
|
|
|
|
DataNode *range = view_ranges->newChild("range");
|
|
|
|
*range->newChild("label") = re_i->label;
|
|
|
|
*range->newChild("freq") = re_i->freq;
|
|
|
|
*range->newChild("start") = re_i->startFreq;
|
|
|
|
*range->newChild("end") = re_i->endFreq;
|
|
|
|
}
|
|
|
|
|
2016-12-12 23:47:05 -05:00
|
|
|
DataNode *modems = s.rootNode()->newChild("modems");
|
2016-09-14 19:46:57 -04:00
|
|
|
|
2016-12-12 23:47:05 -05:00
|
|
|
for (auto &bmd_i : bmData) {
|
|
|
|
DataNode *group = modems->newChild("group");
|
|
|
|
*group->newChild("@name") = bmd_i.first;
|
2016-12-27 00:59:51 -05:00
|
|
|
*group->newChild("@expanded") = (getExpandState(bmd_i.first)?std::string("true"):std::string("false"));
|
2016-12-12 23:47:05 -05:00
|
|
|
|
|
|
|
for (auto &bm_i : bmd_i.second ) {
|
2018-01-08 13:23:01 -05:00
|
|
|
|
|
|
|
//if a matching demodulator exists, use its data instead to be be saved, because output_device could have been
|
|
|
|
//modified by the user. So, save that "live" version instead.
|
|
|
|
auto matchingDemod = wxGetApp().getDemodMgr().getLastDemodulatorWith(bm_i->type,
|
|
|
|
bm_i->label,
|
|
|
|
bm_i->frequency,
|
|
|
|
bm_i->bandwidth);
|
|
|
|
|
|
|
|
if (matchingDemod != nullptr) {
|
|
|
|
|
|
|
|
wxGetApp().getDemodMgr().saveInstance(group->newChild("modem"), matchingDemod);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
group->newChildCloneFrom("modem", bm_i->node);
|
|
|
|
}
|
2016-12-12 23:47:05 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-12-13 21:09:44 -05:00
|
|
|
DataNode *recent_modems = s.rootNode()->newChild("recent_modems");
|
2016-12-12 23:47:05 -05:00
|
|
|
|
|
|
|
for (auto demod : wxGetApp().getDemodMgr().getDemodulators()) {
|
|
|
|
wxGetApp().getDemodMgr().saveInstance(recent_modems->newChild("modem"),demod);
|
|
|
|
}
|
|
|
|
|
|
|
|
for (auto &r_i : this->recents) {
|
|
|
|
recent_modems->newChildCloneFrom("modem", r_i->node);
|
|
|
|
}
|
|
|
|
|
2018-01-06 04:22:14 -05:00
|
|
|
wxFileName saveFile;
|
|
|
|
wxFileName saveFileBackup;
|
|
|
|
|
|
|
|
if (useFullpath) {
|
|
|
|
saveFile.Assign(bookmarkFn);
|
|
|
|
saveFileBackup.Assign(bookmarkFn + ".backup");
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
saveFile.Assign(wxGetApp().getConfig()->getConfigDir(), bookmarkFn);
|
|
|
|
saveFileBackup.Assign(wxGetApp().getConfig()->getConfigDir(), bookmarkFn + ".backup");
|
|
|
|
}
|
|
|
|
|
2016-12-13 21:09:44 -05:00
|
|
|
if (saveFile.IsDirWritable()) {
|
|
|
|
// Hopefully leave at least a readable backup in case of failure..
|
2016-12-27 13:01:19 -05:00
|
|
|
if (backup && saveFile.FileExists() && (!saveFileBackup.FileExists() || saveFileBackup.IsFileWritable())) {
|
2016-12-13 21:09:44 -05:00
|
|
|
wxCopyFile(saveFile.GetFullPath(wxPATH_NATIVE).ToStdString(), saveFileBackup.GetFullPath(wxPATH_NATIVE).ToStdString());
|
|
|
|
}
|
|
|
|
s.SaveToFileXML(saveFile.GetFullPath(wxPATH_NATIVE).ToStdString());
|
|
|
|
}
|
2016-09-14 19:46:57 -04:00
|
|
|
}
|
|
|
|
|
2018-01-06 04:22:14 -05:00
|
|
|
bool BookmarkMgr::loadFromFile(std::string bookmarkFn, bool backup, bool useFullpath) {
|
|
|
|
|
|
|
|
wxFileName loadFile;
|
|
|
|
wxFileName failFile;
|
|
|
|
wxFileName lastLoaded;
|
|
|
|
wxFileName backupFile;
|
|
|
|
|
|
|
|
if (useFullpath) {
|
|
|
|
loadFile.Assign(bookmarkFn);
|
|
|
|
failFile.Assign(bookmarkFn + ".failedload");
|
|
|
|
lastLoaded.Assign(bookmarkFn + ".lastloaded");
|
|
|
|
backupFile.Assign(bookmarkFn + ".backup");
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
loadFile.Assign(wxGetApp().getConfig()->getConfigDir(), bookmarkFn);
|
|
|
|
failFile.Assign(wxGetApp().getConfig()->getConfigDir(), bookmarkFn + ".failedload");
|
|
|
|
lastLoaded.Assign(wxGetApp().getConfig()->getConfigDir(), bookmarkFn + ".lastloaded");
|
|
|
|
backupFile.Assign(wxGetApp().getConfig()->getConfigDir(), bookmarkFn + ".backup");
|
|
|
|
}
|
2016-12-13 21:09:44 -05:00
|
|
|
|
|
|
|
DataTree s;
|
2016-12-27 13:01:19 -05:00
|
|
|
bool loadStatusOk = true;
|
|
|
|
|
|
|
|
// File exists but is not readable
|
|
|
|
if (loadFile.FileExists() && !loadFile.IsFileReadable()) {
|
|
|
|
return false;
|
2016-12-13 21:09:44 -05:00
|
|
|
}
|
|
|
|
|
2016-12-27 13:01:19 -05:00
|
|
|
// New instance of bookmark savefiles
|
|
|
|
if (backup && !loadFile.FileExists() && !lastLoaded.FileExists() && !backupFile.FileExists()) {
|
|
|
|
wxGetApp().getAppFrame()->getBookmarkView()->loadDefaultRanges();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Attempt to load file
|
2016-12-13 21:09:44 -05:00
|
|
|
if (!s.LoadFromFileXML(loadFile.GetFullPath(wxPATH_NATIVE).ToStdString())) {
|
2016-12-27 13:01:19 -05:00
|
|
|
return false;
|
2016-12-13 21:09:44 -05:00
|
|
|
}
|
2018-01-06 04:22:14 -05:00
|
|
|
|
|
|
|
//Check if it is a bookmark file, read the root node.
|
|
|
|
if (s.rootNode()->getName() != "cubicsdr_bookmarks") {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Clear any active data
|
|
|
|
bmData.clear();
|
|
|
|
clearRecents();
|
|
|
|
clearRanges();
|
|
|
|
bmDataSorted.clear();
|
2016-12-27 13:01:19 -05:00
|
|
|
|
|
|
|
if (s.rootNode()->hasAnother("branches")) {
|
|
|
|
DataNode *branches = s.rootNode()->getNext("branches");
|
|
|
|
int bActive = 1, bRange = 0, bBookmark = 1, bRecent = 1;
|
|
|
|
if (branches->hasAnother("active")) branches->getNext("active")->element()->get(bActive);
|
|
|
|
if (branches->hasAnother("range")) branches->getNext("range")->element()->get(bRange);
|
|
|
|
if (branches->hasAnother("bookmark")) branches->getNext("bookmark")->element()->get(bBookmark);
|
|
|
|
if (branches->hasAnother("recent")) branches->getNext("recent")->element()->get(bRecent);
|
|
|
|
wxGetApp().getAppFrame()->getBookmarkView()->setExpandState("active", bActive?true:false);
|
|
|
|
wxGetApp().getAppFrame()->getBookmarkView()->setExpandState("range", bRange?true:false);
|
|
|
|
wxGetApp().getAppFrame()->getBookmarkView()->setExpandState("bookmark", bBookmark?true:false);
|
|
|
|
wxGetApp().getAppFrame()->getBookmarkView()->setExpandState("recent", bRecent?true:false);
|
|
|
|
}
|
|
|
|
|
2016-12-27 00:46:12 -05:00
|
|
|
if (s.rootNode()->hasAnother("ranges")) {
|
|
|
|
DataNode *view_ranges = s.rootNode()->getNext("ranges");
|
|
|
|
while (view_ranges->hasAnother("range")) {
|
|
|
|
DataNode *range = view_ranges->getNext("range");
|
|
|
|
|
2017-02-28 12:58:54 -05:00
|
|
|
BookmarkRangeEntryPtr re(new BookmarkRangeEntry);
|
2016-12-27 00:46:12 -05:00
|
|
|
|
2016-12-27 13:01:19 -05:00
|
|
|
if (range->hasAnother("label")) range->getNext("label")->element()->get(re->label);
|
|
|
|
if (range->hasAnother("freq")) range->getNext("freq")->element()->get(re->freq);
|
|
|
|
if (range->hasAnother("start")) range->getNext("start")->element()->get(re->startFreq);
|
|
|
|
if (range->hasAnother("end")) range->getNext("end")->element()->get(re->endFreq);
|
2016-12-27 00:46:12 -05:00
|
|
|
|
|
|
|
addRange(re);
|
|
|
|
}
|
|
|
|
}
|
2016-12-13 21:09:44 -05:00
|
|
|
|
|
|
|
if (s.rootNode()->hasAnother("modems")) {
|
|
|
|
DataNode *modems = s.rootNode()->getNext("modems");
|
|
|
|
while (modems->hasAnother("group")) {
|
|
|
|
DataNode *group = modems->getNext("group");
|
2016-12-27 00:59:51 -05:00
|
|
|
std::string expandState = "true";
|
2016-12-13 21:09:44 -05:00
|
|
|
std::string groupName = "Unnamed";
|
|
|
|
if (group->hasAnother("@name")) {
|
|
|
|
groupName = group->getNext("@name")->element()->toString();
|
|
|
|
}
|
2016-12-27 00:59:51 -05:00
|
|
|
if (group->hasAnother("@expanded")) {
|
|
|
|
expandState = group->getNext("@expanded")->element()->toString();
|
|
|
|
}
|
|
|
|
setExpandState(groupName, (expandState == "true"));
|
2016-12-13 21:09:44 -05:00
|
|
|
while (group->hasAnother("modem")) {
|
|
|
|
DataNode *modem = group->getNext("modem");
|
2017-05-29 14:08:45 -04:00
|
|
|
BookmarkEntryPtr be = nodeToBookmark(modem);
|
2016-12-13 21:09:44 -05:00
|
|
|
if (be) {
|
|
|
|
addBookmark(groupName.c_str(), be);
|
|
|
|
} else {
|
|
|
|
std::cout << "error loading bookmarked modem.." << std::endl;
|
2016-12-27 13:01:19 -05:00
|
|
|
loadStatusOk = false;
|
2016-12-13 21:09:44 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2016-09-14 19:46:57 -04:00
|
|
|
|
2016-12-13 21:09:44 -05:00
|
|
|
if (s.rootNode()->hasAnother("recent_modems")) {
|
|
|
|
DataNode *recent_modems = s.rootNode()->getNext("recent_modems");
|
|
|
|
|
|
|
|
while (recent_modems->hasAnother("modem")) {
|
|
|
|
DataNode *modem = recent_modems->getNext("modem");
|
2017-05-29 14:08:45 -04:00
|
|
|
BookmarkEntryPtr be = nodeToBookmark(modem);
|
2016-12-13 21:09:44 -05:00
|
|
|
if (be) {
|
|
|
|
addRecent(be);
|
|
|
|
} else {
|
|
|
|
std::cout << "error loading recent modem.." << std::endl;
|
2016-12-27 13:01:19 -05:00
|
|
|
loadStatusOk = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (backup) {
|
|
|
|
if (loadStatusOk) { // Loaded OK; keep a copy
|
|
|
|
if (loadFile.IsDirWritable()) {
|
|
|
|
if (loadFile.FileExists() && (!lastLoaded.FileExists() || lastLoaded.IsFileWritable())) {
|
|
|
|
wxCopyFile(loadFile.GetFullPath(wxPATH_NATIVE).ToStdString(), lastLoaded.GetFullPath(wxPATH_NATIVE).ToStdString());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else if (!loadStatusOk) {
|
|
|
|
if (loadFile.IsDirWritable()) { // Load failed; keep a copy of the failed bookmark file for analysis?
|
|
|
|
if (loadFile.FileExists() && (!failFile.FileExists() || failFile.IsFileWritable())) {
|
|
|
|
wxCopyFile(loadFile.GetFullPath(wxPATH_NATIVE).ToStdString(), failFile.GetFullPath(wxPATH_NATIVE).ToStdString());
|
|
|
|
}
|
2016-12-13 21:09:44 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2016-12-27 13:01:19 -05:00
|
|
|
|
|
|
|
return loadStatusOk;
|
|
|
|
}
|
|
|
|
|
2018-01-12 13:17:04 -05:00
|
|
|
void BookmarkMgr::resetBookmarks() {
|
|
|
|
|
|
|
|
// Clear any active data
|
|
|
|
bmData.clear();
|
|
|
|
clearRecents();
|
|
|
|
clearRanges();
|
|
|
|
bmDataSorted.clear();
|
|
|
|
|
|
|
|
wxGetApp().getAppFrame()->getBookmarkView()->loadDefaultRanges();
|
|
|
|
|
|
|
|
}
|
2016-12-27 13:01:19 -05:00
|
|
|
|
|
|
|
bool BookmarkMgr::hasLastLoad(std::string bookmarkFn) {
|
|
|
|
wxFileName lastLoaded(wxGetApp().getConfig()->getConfigDir(), bookmarkFn + ".lastloaded");
|
|
|
|
return lastLoaded.FileExists() && lastLoaded.IsFileReadable();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool BookmarkMgr::hasBackup(std::string bookmarkFn) {
|
|
|
|
wxFileName backupFile(wxGetApp().getConfig()->getConfigDir(), bookmarkFn + ".backup");
|
|
|
|
return backupFile.FileExists() && backupFile.IsFileReadable();
|
2016-09-14 19:46:57 -04:00
|
|
|
}
|
|
|
|
|
2017-08-27 05:11:30 -04:00
|
|
|
void BookmarkMgr::addBookmark(std::string group, DemodulatorInstancePtr demod) {
|
2017-04-01 13:38:08 -04:00
|
|
|
std::lock_guard < std::recursive_mutex > lock(busy_lock);
|
2016-09-14 22:10:27 -04:00
|
|
|
|
2017-04-01 13:38:08 -04:00
|
|
|
//Create a BookmarkEntry from demod data, saving its
|
|
|
|
//characteristics in be->node.
|
2017-02-28 12:58:54 -05:00
|
|
|
BookmarkEntryPtr be = demodToBookmarkEntry(demod);
|
2017-04-01 13:38:08 -04:00
|
|
|
|
2016-11-21 20:12:10 -05:00
|
|
|
bmData[group].push_back(be);
|
|
|
|
bmDataSorted[group] = false;
|
2016-09-14 22:10:27 -04:00
|
|
|
}
|
2016-09-14 19:46:57 -04:00
|
|
|
|
2017-02-28 12:58:54 -05:00
|
|
|
void BookmarkMgr::addBookmark(std::string group, BookmarkEntryPtr be) {
|
2017-04-01 13:38:08 -04:00
|
|
|
std::lock_guard < std::recursive_mutex > lock(busy_lock);
|
2016-10-13 00:41:35 -04:00
|
|
|
|
2016-11-21 20:12:10 -05:00
|
|
|
bmData[group].push_back(be);
|
|
|
|
bmDataSorted[group] = false;
|
2016-10-13 00:41:35 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-02-28 12:58:54 -05:00
|
|
|
void BookmarkMgr::removeBookmark(std::string group, BookmarkEntryPtr be) {
|
2017-04-01 13:38:08 -04:00
|
|
|
std::lock_guard < std::recursive_mutex > lockData(busy_lock);
|
2016-09-14 22:10:27 -04:00
|
|
|
std::lock_guard < std::mutex > lockEnt(be->busy_lock);
|
2016-11-21 20:12:10 -05:00
|
|
|
|
|
|
|
if (bmData.find(group) == bmData.end()) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
BookmarkList::iterator i = std::find(bmData[group].begin(), bmData[group].end(), be);
|
2016-09-14 22:10:27 -04:00
|
|
|
|
2016-11-21 20:12:10 -05:00
|
|
|
if (i != bmData[group].end()) {
|
2017-02-28 12:58:54 -05:00
|
|
|
|
2016-11-21 20:12:10 -05:00
|
|
|
bmData[group].erase(i);
|
|
|
|
}
|
2016-09-14 19:46:57 -04:00
|
|
|
}
|
|
|
|
|
2017-02-28 12:58:54 -05:00
|
|
|
void BookmarkMgr::removeBookmark(BookmarkEntryPtr be) {
|
2017-04-01 13:38:08 -04:00
|
|
|
std::lock_guard < std::recursive_mutex > lockData(busy_lock);
|
2016-11-10 21:48:57 -05:00
|
|
|
std::lock_guard < std::mutex > lockEnt(be->busy_lock);
|
|
|
|
|
|
|
|
for (auto &bmd_i : bmData) {
|
2016-11-21 20:12:10 -05:00
|
|
|
BookmarkList::iterator i = std::find(bmd_i.second.begin(), bmd_i.second.end(), be);
|
|
|
|
if (i != bmd_i.second.end()) {
|
|
|
|
bmd_i.second.erase(i);
|
2016-11-10 21:48:57 -05:00
|
|
|
}
|
|
|
|
}
|
2016-11-25 22:19:19 -05:00
|
|
|
}
|
2016-11-10 21:48:57 -05:00
|
|
|
|
2017-02-28 12:58:54 -05:00
|
|
|
void BookmarkMgr::moveBookmark(BookmarkEntryPtr be, std::string group) {
|
2017-04-01 13:38:08 -04:00
|
|
|
std::lock_guard < std::recursive_mutex > lockData(busy_lock);
|
2016-11-25 22:19:19 -05:00
|
|
|
std::lock_guard < std::mutex > lockEnt(be->busy_lock);
|
|
|
|
|
|
|
|
for (auto &bmd_i : bmData) {
|
|
|
|
BookmarkList::iterator i = std::find(bmd_i.second.begin(), bmd_i.second.end(), be);
|
|
|
|
if (i != bmd_i.second.end()) {
|
2016-12-12 20:17:47 -05:00
|
|
|
if (bmd_i.first == group) {
|
|
|
|
return;
|
|
|
|
}
|
2016-11-25 22:19:19 -05:00
|
|
|
bmData[group].push_back(*i);
|
|
|
|
bmd_i.second.erase(i);
|
|
|
|
bmDataSorted[group] = false;
|
|
|
|
bmDataSorted[bmd_i.first] = false;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
2016-11-10 21:48:57 -05:00
|
|
|
}
|
2016-09-14 22:10:27 -04:00
|
|
|
|
2016-11-21 20:47:16 -05:00
|
|
|
|
|
|
|
void BookmarkMgr::addGroup(std::string group) {
|
2017-04-01 13:38:08 -04:00
|
|
|
std::lock_guard < std::recursive_mutex > lock(busy_lock);
|
2016-11-21 20:47:16 -05:00
|
|
|
|
|
|
|
if (bmData.find(group) == bmData.end()) {
|
|
|
|
BookmarkList dummy = bmData[group];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-11-25 22:19:19 -05:00
|
|
|
void BookmarkMgr::removeGroup(std::string group) {
|
2017-04-01 13:38:08 -04:00
|
|
|
std::lock_guard < std::recursive_mutex > lock(busy_lock);
|
2016-11-25 22:19:19 -05:00
|
|
|
|
|
|
|
BookmarkMap::iterator i = bmData.find(group);
|
|
|
|
|
|
|
|
if (i != bmData.end()) {
|
2017-02-28 12:58:54 -05:00
|
|
|
|
2016-11-25 22:19:19 -05:00
|
|
|
bmData.erase(group);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void BookmarkMgr::renameGroup(std::string group, std::string ngroup) {
|
2016-12-15 21:53:51 -05:00
|
|
|
if (group == ngroup) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2017-04-01 13:38:08 -04:00
|
|
|
std::lock_guard < std::recursive_mutex > lock(busy_lock);
|
2016-11-25 22:19:19 -05:00
|
|
|
|
|
|
|
BookmarkMap::iterator i = bmData.find(group);
|
2016-12-12 20:17:47 -05:00
|
|
|
BookmarkMap::iterator it = bmData.find(ngroup);
|
2016-11-25 22:19:19 -05:00
|
|
|
|
|
|
|
if (i != bmData.end() && it != bmData.end()) {
|
|
|
|
for (auto ii : bmData[group]) {
|
|
|
|
bmData[ngroup].push_back(ii);
|
|
|
|
}
|
|
|
|
bmData.erase(group);
|
|
|
|
} else if (i != bmData.end()) {
|
|
|
|
bmData[ngroup] = bmData[group];
|
|
|
|
bmData.erase(group);
|
|
|
|
}
|
|
|
|
}
|
2016-11-21 20:47:16 -05:00
|
|
|
|
2017-04-01 13:38:08 -04:00
|
|
|
const BookmarkList& BookmarkMgr::getBookmarks(std::string group) {
|
|
|
|
std::lock_guard < std::recursive_mutex > lock(busy_lock);
|
2016-09-14 19:46:57 -04:00
|
|
|
|
2016-11-21 20:12:10 -05:00
|
|
|
if (bmData.find(group) == bmData.end()) {
|
2017-04-01 13:38:08 -04:00
|
|
|
return emptyResults;
|
2016-11-21 20:12:10 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!bmDataSorted[group]) {
|
|
|
|
std::sort(bmData[group].begin(), bmData[group].end(), BookmarkEntryCompare());
|
|
|
|
bmDataSorted[group] = true;
|
2016-09-14 22:10:27 -04:00
|
|
|
}
|
2016-09-14 19:46:57 -04:00
|
|
|
|
2016-09-29 20:47:38 -04:00
|
|
|
return bmData[group];
|
|
|
|
}
|
|
|
|
|
2016-11-21 20:47:16 -05:00
|
|
|
|
2016-11-21 20:12:10 -05:00
|
|
|
void BookmarkMgr::getGroups(BookmarkNames &arr) {
|
2017-04-01 13:38:08 -04:00
|
|
|
std::lock_guard < std::recursive_mutex > lockData(busy_lock);
|
2017-03-02 16:10:17 -05:00
|
|
|
|
2016-09-29 20:47:38 -04:00
|
|
|
for (BookmarkMap::iterator i = bmData.begin(); i!= bmData.end(); ++i) {
|
2016-11-21 20:12:10 -05:00
|
|
|
arr.push_back(i->first);
|
2016-09-29 20:47:38 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-11-20 23:26:38 -05:00
|
|
|
void BookmarkMgr::getGroups(wxArrayString &arr) {
|
2017-04-01 13:38:08 -04:00
|
|
|
std::lock_guard < std::recursive_mutex > lockData(busy_lock);
|
2017-03-02 16:10:17 -05:00
|
|
|
|
2016-11-20 23:26:38 -05:00
|
|
|
for (BookmarkMap::iterator i = bmData.begin(); i!= bmData.end(); ++i) {
|
|
|
|
arr.push_back(i->first);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-09-29 20:47:38 -04:00
|
|
|
|
2016-12-26 21:56:19 -05:00
|
|
|
void BookmarkMgr::setExpandState(std::string groupName, bool state) {
|
|
|
|
expandState[groupName] = state;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool BookmarkMgr::getExpandState(std::string groupName) {
|
|
|
|
if (expandState.find(groupName) == expandState.end()) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return expandState[groupName];
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-09-22 20:40:07 -04:00
|
|
|
void BookmarkMgr::updateActiveList() {
|
2017-03-02 16:10:17 -05:00
|
|
|
|
2017-10-12 00:07:05 -04:00
|
|
|
std::lock_guard < std::recursive_mutex > lockData(busy_lock);
|
|
|
|
|
|
|
|
if (wxGetApp().isShuttingDown()) {
|
|
|
|
return;
|
|
|
|
}
|
2017-04-01 13:38:08 -04:00
|
|
|
|
|
|
|
BookmarkView *bmv = wxGetApp().getAppFrame()->getBookmarkView();
|
2016-09-22 20:40:07 -04:00
|
|
|
|
|
|
|
if (bmv) {
|
|
|
|
bmv->updateActiveList();
|
|
|
|
}
|
2016-10-05 19:10:01 -04:00
|
|
|
}
|
|
|
|
|
2016-10-06 22:27:12 -04:00
|
|
|
void BookmarkMgr::updateBookmarks() {
|
2017-03-02 16:10:17 -05:00
|
|
|
|
2017-04-01 13:38:08 -04:00
|
|
|
std::lock_guard < std::recursive_mutex > lockData(busy_lock);
|
2017-03-02 16:10:17 -05:00
|
|
|
|
2016-10-06 22:27:12 -04:00
|
|
|
BookmarkView *bmv = wxGetApp().getAppFrame()->getBookmarkView();
|
|
|
|
|
|
|
|
if (bmv) {
|
|
|
|
bmv->updateBookmarks();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void BookmarkMgr::updateBookmarks(std::string group) {
|
2017-03-02 16:10:17 -05:00
|
|
|
|
2017-04-01 13:38:08 -04:00
|
|
|
std::lock_guard < std::recursive_mutex > lockData(busy_lock);
|
2017-03-02 16:10:17 -05:00
|
|
|
|
2016-10-06 22:27:12 -04:00
|
|
|
BookmarkView *bmv = wxGetApp().getAppFrame()->getBookmarkView();
|
|
|
|
|
|
|
|
if (bmv) {
|
|
|
|
bmv->updateBookmarks(group);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-08-27 05:11:30 -04:00
|
|
|
void BookmarkMgr::addRecent(DemodulatorInstancePtr demod) {
|
2017-04-01 13:38:08 -04:00
|
|
|
std::lock_guard < std::recursive_mutex > lock(busy_lock);
|
2017-03-02 16:10:17 -05:00
|
|
|
|
2016-10-05 19:10:01 -04:00
|
|
|
recents.push_back(demodToBookmarkEntry(demod));
|
2016-12-13 21:09:44 -05:00
|
|
|
|
|
|
|
trimRecents();
|
2016-10-05 19:10:01 -04:00
|
|
|
}
|
|
|
|
|
2017-02-28 12:58:54 -05:00
|
|
|
void BookmarkMgr::addRecent(BookmarkEntryPtr be) {
|
2017-04-01 13:38:08 -04:00
|
|
|
std::lock_guard < std::recursive_mutex > lock(busy_lock);
|
2016-12-13 21:09:44 -05:00
|
|
|
|
|
|
|
recents.push_back(be);
|
|
|
|
|
|
|
|
trimRecents();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-10-05 19:10:01 -04:00
|
|
|
|
2017-02-28 12:58:54 -05:00
|
|
|
void BookmarkMgr::removeRecent(BookmarkEntryPtr be) {
|
2017-04-01 13:38:08 -04:00
|
|
|
std::lock_guard < std::recursive_mutex > lock(busy_lock);
|
2016-10-13 00:41:35 -04:00
|
|
|
|
|
|
|
BookmarkList::iterator bm_i = std::find(recents.begin(),recents.end(), be);
|
2017-02-28 12:58:54 -05:00
|
|
|
|
2016-10-13 00:41:35 -04:00
|
|
|
if (bm_i != recents.end()) {
|
|
|
|
recents.erase(bm_i);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-04-01 13:38:08 -04:00
|
|
|
const BookmarkList& BookmarkMgr::getRecents() {
|
|
|
|
std::lock_guard < std::recursive_mutex > lockData(busy_lock);
|
|
|
|
return recents;
|
2016-10-05 19:10:01 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-12-17 21:14:13 -05:00
|
|
|
void BookmarkMgr::clearRecents() {
|
2017-04-01 13:38:08 -04:00
|
|
|
std::lock_guard < std::recursive_mutex > lock(busy_lock);
|
2017-02-28 12:58:54 -05:00
|
|
|
|
|
|
|
recents.clear();
|
2016-12-17 21:14:13 -05:00
|
|
|
}
|
|
|
|
|
2016-12-13 21:09:44 -05:00
|
|
|
|
|
|
|
void BookmarkMgr::trimRecents() {
|
|
|
|
if (recents.size() > BOOKMARK_RECENTS_MAX) {
|
2017-02-28 12:58:54 -05:00
|
|
|
|
2016-12-13 21:09:44 -05:00
|
|
|
recents.erase(recents.begin(), recents.begin()+1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-12-27 00:06:25 -05:00
|
|
|
|
2017-02-28 12:58:54 -05:00
|
|
|
void BookmarkMgr::addRange(BookmarkRangeEntryPtr re) {
|
2017-04-01 13:38:08 -04:00
|
|
|
std::lock_guard < std::recursive_mutex > lock(busy_lock);
|
2016-12-27 00:06:25 -05:00
|
|
|
|
|
|
|
ranges.push_back(re);
|
|
|
|
rangesSorted = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2017-02-28 12:58:54 -05:00
|
|
|
void BookmarkMgr::removeRange(BookmarkRangeEntryPtr re) {
|
2017-04-01 13:38:08 -04:00
|
|
|
std::lock_guard < std::recursive_mutex > lock(busy_lock);
|
2016-12-27 00:06:25 -05:00
|
|
|
|
|
|
|
BookmarkRangeList::iterator re_i = std::find(ranges.begin(), ranges.end(), re);
|
|
|
|
|
|
|
|
if (re_i != ranges.end()) {
|
2017-02-28 12:58:54 -05:00
|
|
|
|
2016-12-27 00:06:25 -05:00
|
|
|
ranges.erase(re_i);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-04-01 13:38:08 -04:00
|
|
|
const BookmarkRangeList& BookmarkMgr::getRanges() {
|
|
|
|
std::lock_guard < std::recursive_mutex > lock(busy_lock);
|
2016-12-27 00:06:25 -05:00
|
|
|
|
|
|
|
if (!rangesSorted) {
|
|
|
|
std::sort(ranges.begin(), ranges.end(), BookmarkRangeEntryCompare());
|
|
|
|
rangesSorted = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return ranges;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void BookmarkMgr::clearRanges() {
|
2017-04-01 13:38:08 -04:00
|
|
|
std::lock_guard < std::recursive_mutex > lock(busy_lock);
|
2017-02-28 12:58:54 -05:00
|
|
|
|
|
|
|
ranges.clear();
|
2016-12-27 00:06:25 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-08-27 05:11:30 -04:00
|
|
|
BookmarkEntryPtr BookmarkMgr::demodToBookmarkEntry(DemodulatorInstancePtr demod) {
|
2017-02-28 12:58:54 -05:00
|
|
|
|
|
|
|
BookmarkEntryPtr be(new BookmarkEntry);
|
2016-10-05 19:10:01 -04:00
|
|
|
|
|
|
|
be->bandwidth = demod->getBandwidth();
|
|
|
|
be->type = demod->getDemodulatorType();
|
2016-11-14 23:52:50 -05:00
|
|
|
be->label = demod->getDemodulatorUserLabel();
|
2016-10-05 19:10:01 -04:00
|
|
|
be->frequency = demod->getFrequency();
|
|
|
|
|
2017-03-07 12:30:33 -05:00
|
|
|
//fine to do so here, so long nobody overrides be->node, DataNode will be
|
|
|
|
//deleted at last BookmarkEntryPtr be ref.
|
2016-10-05 19:10:01 -04:00
|
|
|
be->node = new DataNode;
|
|
|
|
wxGetApp().getDemodMgr().saveInstance(be->node, demod);
|
|
|
|
|
|
|
|
return be;
|
|
|
|
}
|
2016-12-13 21:09:44 -05:00
|
|
|
|
2017-05-29 14:08:45 -04:00
|
|
|
BookmarkEntryPtr BookmarkMgr::nodeToBookmark(DataNode *node) {
|
2016-12-13 21:09:44 -05:00
|
|
|
if (!node->hasAnother("frequency") || !node->hasAnother("type") || !node->hasAnother("bandwidth")) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2017-02-28 12:58:54 -05:00
|
|
|
BookmarkEntryPtr be(new BookmarkEntry());
|
|
|
|
|
2016-12-13 21:09:44 -05:00
|
|
|
node->getNext("frequency")->element()->get(be->frequency);
|
|
|
|
node->getNext("type")->element()->get(be->type);
|
|
|
|
node->getNext("bandwidth")->element()->get(be->bandwidth);
|
|
|
|
|
|
|
|
if (node->hasAnother("user_label")) {
|
|
|
|
node->getNext("user_label")->element()->get(be->label);
|
|
|
|
}
|
2016-12-27 13:01:19 -05:00
|
|
|
|
|
|
|
node->rewindAll();
|
|
|
|
|
2017-03-07 12:30:33 -05:00
|
|
|
//fine to do so here, so long nobody overrides be->node, DataNode will be
|
|
|
|
//deleted at last BookmarkEntryPtr be ref.
|
|
|
|
//copy data from *node.
|
2016-12-13 21:09:44 -05:00
|
|
|
be->node = new DataNode("node",*node);
|
|
|
|
|
|
|
|
return be;
|
|
|
|
}
|
|
|
|
|
2016-12-23 18:45:25 -05:00
|
|
|
|
2017-02-28 12:58:54 -05:00
|
|
|
std::wstring BookmarkMgr::getBookmarkEntryDisplayName(BookmarkEntryPtr bmEnt) {
|
2016-12-23 18:45:25 -05:00
|
|
|
std::wstring dispName = bmEnt->label;
|
|
|
|
|
2018-01-08 13:23:01 -05:00
|
|
|
if (dispName == L"") {
|
2016-12-23 18:45:25 -05:00
|
|
|
std::string freqStr = frequencyToStr(bmEnt->frequency) + " " + bmEnt->type;
|
2018-01-08 13:23:01 -05:00
|
|
|
|
|
|
|
dispName = wxString(freqStr).ToStdWstring();
|
2016-12-23 18:45:25 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
return dispName;
|
|
|
|
}
|
|
|
|
|
2017-08-27 05:11:30 -04:00
|
|
|
std::wstring BookmarkMgr::getActiveDisplayName(DemodulatorInstancePtr demod) {
|
2016-12-23 18:45:25 -05:00
|
|
|
std::wstring activeName = demod->getDemodulatorUserLabel();
|
|
|
|
|
2018-01-08 13:23:01 -05:00
|
|
|
if (activeName == L"") {
|
2016-12-23 18:45:25 -05:00
|
|
|
std::string wstr = frequencyToStr(demod->getFrequency()) + " " + demod->getDemodulatorType();
|
2018-01-08 13:23:01 -05:00
|
|
|
|
|
|
|
activeName = wxString(wstr).ToStdWstring();
|
2016-12-23 18:45:25 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
return activeName;
|
|
|
|
}
|
|
|
|
|
2017-08-27 05:11:30 -04:00
|
|
|
void BookmarkMgr::removeActive(DemodulatorInstancePtr demod) {
|
2017-04-01 13:38:08 -04:00
|
|
|
|
|
|
|
std::lock_guard < std::recursive_mutex > lock(busy_lock);
|
|
|
|
|
|
|
|
if (demod == nullptr) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
//Delete demodulator
|
|
|
|
wxGetApp().getDemodMgr().setActiveDemodulator(nullptr, true);
|
|
|
|
wxGetApp().getDemodMgr().setActiveDemodulator(nullptr, false);
|
|
|
|
wxGetApp().removeDemodulator(demod);
|
|
|
|
wxGetApp().getDemodMgr().deleteThread(demod);
|
|
|
|
}
|
|
|
|
|