CubicSDR/src/BookmarkMgr.cpp

367 lines
10 KiB
C++

#include "BookmarkMgr.h"
#include "CubicSDR.h"
#include "DataTree.h"
#define BOOKMARK_RECENTS_MAX 25
void BookmarkMgr::saveToFile(std::string bookmarkFn) {
DataTree s("cubicsdr_bookmarks");
DataNode *header = s.rootNode()->newChild("header");
header->newChild("version")->element()->set(wxString(CUBICSDR_VERSION).ToStdWstring());
DataNode *modems = s.rootNode()->newChild("modems");
std::lock_guard < std::mutex > lockData(busy_lock);
for (auto &bmd_i : bmData) {
DataNode *group = modems->newChild("group");
*group->newChild("@name") = bmd_i.first;
for (auto &bm_i : bmd_i.second ) {
std::lock_guard < std::mutex > lockEnt(bm_i->busy_lock);
group->newChildCloneFrom("modem", bm_i->node);
}
}
DataNode *recent_modems = s.rootNode()->newChild("recent_modems");
for (auto demod : wxGetApp().getDemodMgr().getDemodulators()) {
wxGetApp().getDemodMgr().saveInstance(recent_modems->newChild("modem"),demod);
}
for (auto &r_i : this->recents) {
std::lock_guard < std::mutex > lockEnt(r_i->busy_lock);
recent_modems->newChildCloneFrom("modem", r_i->node);
}
wxFileName saveFile(wxGetApp().getConfig()->getConfigDir(), bookmarkFn);
wxFileName saveFileBackup(wxGetApp().getConfig()->getConfigDir(), bookmarkFn + ".backup");
if (saveFile.IsDirWritable()) {
// Hopefully leave at least a readable backup in case of failure..
if (saveFile.FileExists() && (!saveFileBackup.FileExists() || saveFileBackup.IsFileWritable())) {
wxCopyFile(saveFile.GetFullPath(wxPATH_NATIVE).ToStdString(), saveFileBackup.GetFullPath(wxPATH_NATIVE).ToStdString());
}
s.SaveToFileXML(saveFile.GetFullPath(wxPATH_NATIVE).ToStdString());
}
}
void BookmarkMgr::loadFromFile(std::string bookmarkFn) {
wxFileName loadFile(wxGetApp().getConfig()->getConfigDir(), bookmarkFn);
DataTree s;
if (!loadFile.IsFileReadable()) {
return;
}
if (!s.LoadFromFileXML(loadFile.GetFullPath(wxPATH_NATIVE).ToStdString())) {
// TODO: if exists; inform user & optionally load backup
return;
}
if (s.rootNode()->hasAnother("modems")) {
DataNode *modems = s.rootNode()->getNext("modems");
while (modems->hasAnother("group")) {
DataNode *group = modems->getNext("group");
std::string groupName = "Unnamed";
if (group->hasAnother("@name")) {
groupName = group->getNext("@name")->element()->toString();
}
while (group->hasAnother("modem")) {
DataNode *modem = group->getNext("modem");
BookmarkEntry *be = nodeToBookmark("modem", modem);
if (be) {
addBookmark(groupName.c_str(), be);
} else {
std::cout << "error loading bookmarked modem.." << std::endl;
}
}
}
}
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");
BookmarkEntry *be = nodeToBookmark("modem", modem);
if (be) {
addRecent(be);
} else {
std::cout << "error loading recent modem.." << std::endl;
}
}
}
}
void BookmarkMgr::addBookmark(std::string group, DemodulatorInstance *demod) {
std::lock_guard < std::mutex > lock(busy_lock);
BookmarkEntry *be = demodToBookmarkEntry(demod);
wxGetApp().getDemodMgr().saveInstance(be->node, demod);
bmData[group].push_back(be);
bmDataSorted[group] = false;
}
void BookmarkMgr::addBookmark(std::string group, BookmarkEntry *be) {
std::lock_guard < std::mutex > lock(busy_lock);
bmData[group].push_back(be);
bmDataSorted[group] = false;
}
void BookmarkMgr::removeBookmark(std::string group, BookmarkEntry *be) {
std::lock_guard < std::mutex > lockData(busy_lock);
std::lock_guard < std::mutex > lockEnt(be->busy_lock);
if (bmData.find(group) == bmData.end()) {
return;
}
BookmarkList::iterator i = std::find(bmData[group].begin(), bmData[group].end(), be);
if (i != bmData[group].end()) {
delete *i;
bmData[group].erase(i);
}
}
void BookmarkMgr::removeBookmark(BookmarkEntry *be) {
std::lock_guard < std::mutex > lockData(busy_lock);
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()) {
bmd_i.second.erase(i);
}
}
}
void BookmarkMgr::moveBookmark(BookmarkEntry *be, std::string group) {
std::lock_guard < std::mutex > lockData(busy_lock);
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()) {
if (bmd_i.first == group) {
return;
}
bmData[group].push_back(*i);
bmd_i.second.erase(i);
bmDataSorted[group] = false;
bmDataSorted[bmd_i.first] = false;
return;
}
}
}
void BookmarkMgr::addGroup(std::string group) {
std::lock_guard < std::mutex > lock(busy_lock);
if (bmData.find(group) == bmData.end()) {
BookmarkList dummy = bmData[group];
}
}
void BookmarkMgr::removeGroup(std::string group) {
std::lock_guard < std::mutex > lock(busy_lock);
BookmarkMap::iterator i = bmData.find(group);
if (i != bmData.end()) {
for (auto ii : bmData[group]) {
delete ii;
}
bmData.erase(group);
}
}
void BookmarkMgr::renameGroup(std::string group, std::string ngroup) {
if (group == ngroup) {
return;
}
std::lock_guard < std::mutex > lock(busy_lock);
BookmarkMap::iterator i = bmData.find(group);
BookmarkMap::iterator it = bmData.find(ngroup);
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);
}
}
BookmarkList BookmarkMgr::getBookmarks(std::string group) {
std::lock_guard < std::mutex > lock(busy_lock);
if (bmData.find(group) == bmData.end()) {
BookmarkList results;
return results;
}
if (!bmDataSorted[group]) {
std::sort(bmData[group].begin(), bmData[group].end(), BookmarkEntryCompare());
bmDataSorted[group] = true;
}
return bmData[group];
}
void BookmarkMgr::getGroups(BookmarkNames &arr) {
for (BookmarkMap::iterator i = bmData.begin(); i!= bmData.end(); ++i) {
arr.push_back(i->first);
}
}
void BookmarkMgr::getGroups(wxArrayString &arr) {
for (BookmarkMap::iterator i = bmData.begin(); i!= bmData.end(); ++i) {
arr.push_back(i->first);
}
}
void BookmarkMgr::updateActiveList() {
BookmarkView *bmv = wxGetApp().getAppFrame()->getBookmarkView();
if (bmv) {
bmv->updateActiveList();
}
}
void BookmarkMgr::updateBookmarks() {
BookmarkView *bmv = wxGetApp().getAppFrame()->getBookmarkView();
if (bmv) {
bmv->updateBookmarks();
}
}
void BookmarkMgr::updateBookmarks(std::string group) {
BookmarkView *bmv = wxGetApp().getAppFrame()->getBookmarkView();
if (bmv) {
bmv->updateBookmarks(group);
}
}
void BookmarkMgr::addRecent(DemodulatorInstance *demod) {
std::lock_guard < std::mutex > lock(busy_lock);
recents.push_back(demodToBookmarkEntry(demod));
trimRecents();
}
void BookmarkMgr::addRecent(BookmarkEntry *be) {
std::lock_guard < std::mutex > lock(busy_lock);
recents.push_back(be);
trimRecents();
}
void BookmarkMgr::removeRecent(BookmarkEntry *be) {
std::lock_guard < std::mutex > lock(busy_lock);
BookmarkList::iterator bm_i = std::find(recents.begin(),recents.end(), be);
if (bm_i != recents.end()) {
recents.erase(bm_i);
}
}
BookmarkList BookmarkMgr::getRecents() {
return recents;
}
void BookmarkMgr::clearRecents() {
std::lock_guard < std::mutex > lock(busy_lock);
recents.erase(recents.begin(),recents.end());
}
void BookmarkMgr::trimRecents() {
if (recents.size() > BOOKMARK_RECENTS_MAX) {
delete *(recents.begin());
recents.erase(recents.begin(), recents.begin()+1);
}
}
BookmarkEntry *BookmarkMgr::demodToBookmarkEntry(DemodulatorInstance *demod) {
BookmarkEntry *be = new BookmarkEntry;
be->bandwidth = demod->getBandwidth();
be->type = demod->getDemodulatorType();
be->label = demod->getDemodulatorUserLabel();
be->frequency = demod->getFrequency();
be->node = new DataNode;
wxGetApp().getDemodMgr().saveInstance(be->node, demod);
return be;
}
BookmarkEntry *BookmarkMgr::nodeToBookmark(const char *name_in, DataNode *node) {
if (!node->hasAnother("frequency") || !node->hasAnother("type") || !node->hasAnother("bandwidth")) {
return nullptr;
}
BookmarkEntry *be = new BookmarkEntry();
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);
}
be->node = new DataNode("node",*node);
return be;
}
std::wstring BookmarkMgr::getBookmarkEntryDisplayName(BookmarkEntry *bmEnt) {
std::wstring dispName = bmEnt->label;
if (dispName == "") {
std::string freqStr = frequencyToStr(bmEnt->frequency) + " " + bmEnt->type;
dispName = wstring(freqStr.begin(),freqStr.end());
}
return dispName;
}
std::wstring BookmarkMgr::getActiveDisplayName(DemodulatorInstance *demod) {
std::wstring activeName = demod->getDemodulatorUserLabel();
if (activeName == "") {
std::string wstr = frequencyToStr(demod->getFrequency()) + " " + demod->getDemodulatorType();
activeName = std::wstring(wstr.begin(),wstr.end());
}
return activeName;
}