From 746b7cfcaef4fbd26b850eb1fd418266503786ea Mon Sep 17 00:00:00 2001 From: "Charles J. Cliffe" Date: Mon, 12 Dec 2016 23:47:05 -0500 Subject: [PATCH] Bookmarks now save on exit; not loaded on startup yet. --- src/AppFrame.cpp | 1 + src/BookmarkMgr.cpp | 33 +++++++++++++++++++++++- src/forms/Bookmark/BookmarkView.cpp | 2 +- src/util/DataTree.cpp | 39 +++++++++++++++++++++++++++++ src/util/DataTree.h | 4 +++ 5 files changed, 77 insertions(+), 2 deletions(-) diff --git a/src/AppFrame.cpp b/src/AppFrame.cpp index 5bbac12..0ddb5ea 100644 --- a/src/AppFrame.cpp +++ b/src/AppFrame.cpp @@ -1300,6 +1300,7 @@ void AppFrame::OnClose(wxCloseEvent& event) { wxGetApp().getConfig()->setRigFollowModem(rigFollowModemMenuItem->IsChecked()); #endif wxGetApp().getConfig()->save(); + wxGetApp().getBookmarkMgr().saveToFile("bookmarks.xml"); event.Skip(); } diff --git a/src/BookmarkMgr.cpp b/src/BookmarkMgr.cpp index b2cdf1b..0abf79f 100644 --- a/src/BookmarkMgr.cpp +++ b/src/BookmarkMgr.cpp @@ -2,10 +2,41 @@ #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 = s.rootNode()->newChild("recent"); + DataNode *recent_modems = recent->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); + } + + s.SaveToFileXML(wxFileName(wxGetApp().getConfig()->getConfigDir(), bookmarkFn).GetFullPath(wxPATH_NATIVE).ToStdString()); } @@ -178,7 +209,7 @@ void BookmarkMgr::updateBookmarks(std::string group) { void BookmarkMgr::addRecent(DemodulatorInstance *demod) { std::lock_guard < std::mutex > lock(busy_lock); recents.push_back(demodToBookmarkEntry(demod)); - if (recents.size() > 10) { + if (recents.size() > BOOKMARK_RECENTS_MAX) { delete *(recents.begin()); recents.erase(recents.begin(), recents.begin()+1); } diff --git a/src/forms/Bookmark/BookmarkView.cpp b/src/forms/Bookmark/BookmarkView.cpp index bf1d920..45c1fef 100644 --- a/src/forms/Bookmark/BookmarkView.cpp +++ b/src/forms/Bookmark/BookmarkView.cpp @@ -507,7 +507,7 @@ void BookmarkView::onBookmarkChoice( wxCommandEvent &event ) { if (recentSel) { doBookmarkRecent(groupSel, recentSel); } - if (bookmarkSel) { + if (bookmarkSel && groupSel != "") { doMoveBookmark(bookmarkSel, groupSel); } } diff --git a/src/util/DataTree.cpp b/src/util/DataTree.cpp index ee3d469..095f46a 100755 --- a/src/util/DataTree.cpp +++ b/src/util/DataTree.cpp @@ -41,6 +41,14 @@ using namespace std; DataElement::DataElement() : data_type(DATA_NULL), data_size(0), unit_size(0), data_val(NULL) { } +DataElement::DataElement(DataElement &cloneFrom) : data_type(cloneFrom.getDataType()), unit_size(cloneFrom.getUnitSize()) { + data_val = NULL; + data_init(cloneFrom.getDataSize()); + if (data_size) { + memcpy(data_val, cloneFrom.getDataPointer(), data_size); + } +} + DataElement::~DataElement() { if (data_val) { delete[] data_val; @@ -482,6 +490,12 @@ DataNode::DataNode(const char *name_in): parentNode(NULL), ptr(0) { data_elem = new DataElement(); } + +DataNode::DataNode(const char *name_in, DataElement &cloneFrom): parentNode(NULL), ptr(0) { + node_name = name_in; + data_elem = new DataElement(cloneFrom); +} + DataNode::~DataNode() { while (children.size()) { DataNode *del = children.back(); @@ -510,6 +524,31 @@ DataNode *DataNode::newChild(const char *name_in) { return children.back(); } +DataNode *DataNode::newChild(const char *name_in, DataNode *otherNode) { + children.push_back(otherNode); + childmap[name_in].push_back(children.back()); + + children.back()->setParentNode(*this); + + return children.back(); +} + +DataNode *DataNode::newChildCloneFrom(const char *name_in, DataNode *cloneFrom) { + DataNode *cloneNode = new DataNode(name_in, *cloneFrom->element()); + + children.push_back(cloneNode); + childmap[name_in].push_back(children.back()); + children.back()->setParentNode(*this); + + while (cloneFrom->hasAnother()) { + DataNode *cNode = cloneFrom->getNext(); + cloneNode->newChildCloneFrom(cNode->getName().c_str(), cNode); + } + + return children.back(); +} + + DataNode *DataNode::child(const char *name_in, int index) { DataNode *child_ret; diff --git a/src/util/DataTree.h b/src/util/DataTree.h index dad6947..4cea1c8 100755 --- a/src/util/DataTree.h +++ b/src/util/DataTree.h @@ -128,6 +128,7 @@ private: public: DataElement(); + DataElement(DataElement &cloneFrom); ~DataElement(); int getDataType(); @@ -235,6 +236,7 @@ private: public: DataNode(); DataNode(const char *name_in); + DataNode(const char *name_in, DataElement &cloneFrom); ~DataNode(); @@ -250,6 +252,8 @@ public: DataElement *element(); /* DataElement at this node */ DataNode *newChild(const char *name_in); + DataNode *newChild(const char *name_in, DataNode *otherNode); + DataNode *newChildCloneFrom(const char *name_in, DataNode *cloneFrom); DataNode *child(const char *name_in, int index = 0); DataNode *child(int index);