#include #include "bookmarks_dialog.h" #include "filezillaapp.h" #include "sitemanager.h" #include "ipcmutex.h" #include "themeprovider.h" #include "xmlfunctions.h" #include "xrc_helper.h" BEGIN_EVENT_TABLE(CNewBookmarkDialog, wxDialogEx) EVT_BUTTON(XRCID("wxID_OK"), CNewBookmarkDialog::OnOK) EVT_BUTTON(XRCID("ID_BROWSE"), CNewBookmarkDialog::OnBrowse) END_EVENT_TABLE() BEGIN_EVENT_TABLE(CBookmarksDialog, wxDialogEx) EVT_TREE_SEL_CHANGING(XRCID("ID_TREE"), CBookmarksDialog::OnSelChanging) EVT_TREE_SEL_CHANGED(XRCID("ID_TREE"), CBookmarksDialog::OnSelChanged) EVT_BUTTON(XRCID("wxID_OK"), CBookmarksDialog::OnOK) EVT_BUTTON(XRCID("ID_BOOKMARK_BROWSE"), CBookmarksDialog::OnBrowse) EVT_BUTTON(XRCID("ID_NEW"), CBookmarksDialog::OnNewBookmark) EVT_BUTTON(XRCID("ID_RENAME"), CBookmarksDialog::OnRename) EVT_BUTTON(XRCID("ID_DELETE"), CBookmarksDialog::OnDelete) EVT_BUTTON(XRCID("ID_COPY"), CBookmarksDialog::OnCopy) EVT_TREE_BEGIN_LABEL_EDIT(XRCID("ID_TREE"), CBookmarksDialog::OnBeginLabelEdit) EVT_TREE_END_LABEL_EDIT(XRCID("ID_TREE"), CBookmarksDialog::OnEndLabelEdit) END_EVENT_TABLE() CNewBookmarkDialog::CNewBookmarkDialog(wxWindow* parent, wxString& site_path, const CServer* server) : m_parent(parent) , m_site_path(site_path) , m_server(server) { } int CNewBookmarkDialog::Run(const wxString &local_path, const CServerPath &remote_path) { if (!Load(m_parent, _T("ID_NEWBOOKMARK"))) return wxID_CANCEL; xrc_call(*this, "ID_LOCALPATH", &wxTextCtrl::ChangeValue, local_path); if (!remote_path.empty()) xrc_call(*this, "ID_REMOTEPATH", &wxTextCtrl::ChangeValue, remote_path.GetPath()); if (!m_server) xrc_call(*this, "ID_TYPE_SITE", &wxRadioButton::Enable, false); return ShowModal(); } void CNewBookmarkDialog::OnOK(wxCommandEvent&) { bool const global = xrc_call(*this, "ID_TYPE_GLOBAL", &wxRadioButton::GetValue); wxString const name = xrc_call(*this, "ID_NAME", &wxTextCtrl::GetValue); if (name.empty()) { wxMessageBoxEx(_("You need to enter a name for the bookmark."), _("New bookmark"), wxICON_EXCLAMATION, this); return; } wxString const local_path = xrc_call(*this, "ID_LOCALPATH", &wxTextCtrl::GetValue); wxString remote_path_raw = xrc_call(*this, "ID_REMOTEPATH", &wxTextCtrl::GetValue); CServerPath remote_path; if (!remote_path_raw.empty()) { if (!global && m_server) remote_path.SetType(m_server->GetType()); if (!remote_path.SetPath(remote_path_raw)) { wxMessageBoxEx(_("Could not parse remote path."), _("New bookmark"), wxICON_EXCLAMATION); return; } } if (local_path.empty() && remote_path_raw.empty()) { wxMessageBoxEx(_("You need to enter at least one path, empty bookmarks are not supported."), _("New bookmark"), wxICON_EXCLAMATION, this); return; } bool const sync = xrc_call(*this, "ID_SYNC", &wxCheckBox::GetValue); if (sync && (local_path.empty() || remote_path_raw.empty())) { wxMessageBoxEx(_("You need to enter both a local and a remote path to enable synchronized browsing for this bookmark."), _("New bookmark"), wxICON_EXCLAMATION, this); return; } bool const comparison = xrc_call(*this, "ID_COMPARISON", &wxCheckBox::GetValue); if (!global && m_server) { std::list bookmarks; if (m_site_path.empty() || !CSiteManager::GetBookmarks(m_site_path, bookmarks)) { if (wxMessageBoxEx(_("Site-specific bookmarks require the server to be stored in the Site Manager.\nAdd current connection to the site manager?"), _("New bookmark"), wxYES_NO | wxICON_QUESTION, this) != wxYES) return; m_site_path = CSiteManager::AddServer(*m_server); if (m_site_path.empty()) { wxMessageBoxEx(_("Could not add connection to Site Manager"), _("New bookmark"), wxICON_EXCLAMATION, this); EndModal(wxID_CANCEL); return; } } for (std::list::const_iterator iter = bookmarks.begin(); iter != bookmarks.end(); ++iter) { if (*iter == name) { wxMessageBoxEx(_("A bookmark with the entered name already exists. Please enter an unused name."), _("New bookmark"), wxICON_EXCLAMATION, this); return; } } CSiteManager::AddBookmark(m_site_path, name, local_path, remote_path, sync, comparison); EndModal(wxID_OK); } else { if (!CBookmarksDialog::AddBookmark(name, local_path, remote_path, sync, comparison)) return; EndModal(wxID_OK); } } void CNewBookmarkDialog::OnBrowse(wxCommandEvent&) { wxTextCtrl *const pText = XRCCTRL(*this, "ID_LOCALPATH", wxTextCtrl); wxDirDialog dlg(this, _("Choose the local directory"), pText->GetValue(), wxDD_NEW_DIR_BUTTON); if (dlg.ShowModal() == wxID_OK) { pText->ChangeValue(dlg.GetPath()); } } class CBookmarkItemData : public wxTreeItemData { public: CBookmarkItemData() { } CBookmarkItemData(const wxString& local_dir, const CServerPath& remote_dir, bool sync, bool comparison) : m_local_dir(local_dir), m_remote_dir(remote_dir), m_sync(sync) , m_comparison(comparison) { } wxString m_local_dir; CServerPath m_remote_dir; bool m_sync{}; bool m_comparison{}; }; CBookmarksDialog::CBookmarksDialog(wxWindow* parent, wxString& site_path, const CServer* server) : m_parent(parent) , m_site_path(site_path) , m_server(server) , m_pTree() { } void CBookmarksDialog::LoadGlobalBookmarks() { CInterProcessMutex mutex(MUTEX_GLOBALBOOKMARKS); CXmlFile file(wxGetApp().GetSettingsFile(_T("bookmarks"))); auto element = file.Load(); if (!element) { wxMessageBoxEx(file.GetError(), _("Error loading xml file"), wxICON_ERROR); return; } for (auto bookmark = element.child("Bookmark"); bookmark; bookmark = bookmark.next_sibling("Bookmark")) { wxString name; wxString local_dir; wxString remote_dir_raw; CServerPath remote_dir; name = GetTextElement(bookmark, "Name"); if (name.empty()) continue; local_dir = GetTextElement(bookmark, "LocalDir"); remote_dir_raw = GetTextElement(bookmark, "RemoteDir"); if (!remote_dir_raw.empty()) { if (!remote_dir.SetSafePath(remote_dir_raw)) continue; } if (local_dir.empty() && remote_dir.empty()) continue; bool sync; if (local_dir.empty() || remote_dir.empty()) sync = false; else sync = GetTextElementBool(bookmark, "SyncBrowsing"); bool const comparison = GetTextElementBool(bookmark, "DirectoryComparison"); CBookmarkItemData *data = new CBookmarkItemData(local_dir, remote_dir, sync, comparison); m_pTree->AppendItem(m_bookmarks_global, name, 1, 1, data); } m_pTree->SortChildren(m_bookmarks_global); } void CBookmarksDialog::LoadSiteSpecificBookmarks() { if (m_site_path.empty()) return; std::list bookmarks; if (!CSiteManager::GetBookmarks(m_site_path, bookmarks)) return; for (std::list::const_iterator iter = bookmarks.begin(); iter != bookmarks.end(); ++iter) { wxString path = *iter; path.Replace(_T("\\"), _T("\\\\")); path.Replace(_T("/"), _T("\\/")); path = m_site_path + _T("/") + path; std::unique_ptr data = CSiteManager::GetSiteByPath(path); if (data) { CBookmarkItemData* new_data = new CBookmarkItemData(data->m_localDir, data->m_remoteDir, data->m_sync, data->m_comparison); m_pTree->AppendItem(m_bookmarks_site, *iter, 1, 1, new_data); } } m_pTree->SortChildren(m_bookmarks_site); } int CBookmarksDialog::Run() { if (!Load(m_parent, _T("ID_BOOKMARKS"))) return wxID_CANCEL; // Now create the imagelist for the site tree m_pTree = XRCCTRL(*this, "ID_TREE", wxTreeCtrl); if (!m_pTree) return false; wxSize s = CThemeProvider::GetIconSize(iconSizeSmall); wxImageList* pImageList = new wxImageList(s.x, s.y); pImageList->Add(wxArtProvider::GetBitmap(_T("ART_FOLDER"), wxART_OTHER, CThemeProvider::GetIconSize(iconSizeSmall))); pImageList->Add(wxArtProvider::GetBitmap(_T("ART_BOOKMARK"), wxART_OTHER, CThemeProvider::GetIconSize(iconSizeSmall))); m_pTree->AssignImageList(pImageList); wxTreeItemId root = m_pTree->AddRoot(_T("")); m_bookmarks_global = m_pTree->AppendItem(root, _("Global bookmarks"), 0, 0); LoadGlobalBookmarks(); m_pTree->Expand(m_bookmarks_global); if (m_server) { m_bookmarks_site = m_pTree->AppendItem(root, _("Site-specific bookmarks"), 0, 0); LoadSiteSpecificBookmarks(); m_pTree->Expand(m_bookmarks_site); } wxNotebook *pBook = XRCCTRL(*this, "ID_NOTEBOOK", wxNotebook); wxPanel* pPanel = new wxPanel; wxXmlResource::Get()->LoadPanel(pPanel, pBook, _T("ID_SITEMANAGER_BOOKMARK_PANEL")); pBook->AddPage(pPanel, _("Bookmark")); xrc_call(*this, "ID_BOOKMARK_LOCALDIR", &wxTextCtrl::GetContainingSizer)->GetItem((size_t)0)->SetMinSize(200, -1); GetSizer()->Fit(this); wxSize minSize = GetSizer()->GetMinSize(); wxSize size = GetSize(); wxSize clientSize = GetClientSize(); SetMinSize(GetSizer()->GetMinSize() + size - clientSize); SetClientSize(minSize); m_pTree->SelectItem(m_bookmarks_global); return ShowModal(); } void CBookmarksDialog::SaveGlobalBookmarks() { CInterProcessMutex mutex(MUTEX_GLOBALBOOKMARKS); CXmlFile file(wxGetApp().GetSettingsFile(_T("bookmarks"))); auto element = file.Load(); if (!element) { wxString msg = file.GetError() + _T("\n\n") + _("The global bookmarks could not be saved."); wxMessageBoxEx(msg, _("Error loading xml file"), wxICON_ERROR); return; } { auto bookmark = element.child("Bookmark"); while (bookmark) { element.remove_child(bookmark); bookmark = element.child("Bookmark"); } } wxTreeItemIdValue cookie; for (wxTreeItemId child = m_pTree->GetFirstChild(m_bookmarks_global, cookie); child.IsOk(); child = m_pTree->GetNextChild(m_bookmarks_global, cookie)) { CBookmarkItemData *data = (CBookmarkItemData *)m_pTree->GetItemData(child); wxASSERT(data); auto bookmark = element.append_child("Bookmark"); AddTextElement(bookmark, "Name", m_pTree->GetItemText(child)); if (!data->m_local_dir.empty()) AddTextElement(bookmark, "LocalDir", data->m_local_dir); if (!data->m_remote_dir.empty()) AddTextElement(bookmark, "RemoteDir", data->m_remote_dir.GetSafePath()); if (data->m_sync) AddTextElementRaw(bookmark, "SyncBrowsing", "1"); if (data->m_comparison) AddTextElementRaw(bookmark, "DirectoryComparison", "1"); } if (!file.Save(false)) { wxString msg = wxString::Format(_("Could not write \"%s\", the global bookmarks could no be saved: %s"), file.GetFileName(), file.GetError()); wxMessageBoxEx(msg, _("Error writing xml file"), wxICON_ERROR); } } void CBookmarksDialog::SaveSiteSpecificBookmarks() { if (m_site_path.empty()) return; if (!CSiteManager::ClearBookmarks(m_site_path)) return; wxTreeItemIdValue cookie; for (wxTreeItemId child = m_pTree->GetFirstChild(m_bookmarks_site, cookie); child.IsOk(); child = m_pTree->GetNextChild(m_bookmarks_site, cookie)) { CBookmarkItemData *data = (CBookmarkItemData *)m_pTree->GetItemData(child); wxASSERT(data); if (!CSiteManager::AddBookmark(m_site_path, m_pTree->GetItemText(child), data->m_local_dir, data->m_remote_dir, data->m_sync, data->m_comparison)) return; } } void CBookmarksDialog::OnOK(wxCommandEvent&) { if (!Verify()) return; UpdateBookmark(); SaveGlobalBookmarks(); SaveSiteSpecificBookmarks(); EndModal(wxID_OK); } void CBookmarksDialog::OnBrowse(wxCommandEvent&) { wxTreeItemId item = m_pTree->GetSelection(); if (!item) return; CBookmarkItemData *data = (CBookmarkItemData *)m_pTree->GetItemData(item); if (!data) return; wxTextCtrl *pText = XRCCTRL(*this, "ID_BOOKMARK_LOCALDIR", wxTextCtrl); wxDirDialog dlg(this, _("Choose the local directory"), pText->GetValue(), wxDD_NEW_DIR_BUTTON); if (dlg.ShowModal() == wxID_OK) { pText->ChangeValue(dlg.GetPath()); } } void CBookmarksDialog::OnSelChanging(wxTreeEvent& event) { if (m_is_deleting) return; if (!Verify()) { event.Veto(); return; } UpdateBookmark(); } void CBookmarksDialog::OnSelChanged(wxTreeEvent&) { DisplayBookmark(); } bool CBookmarksDialog::Verify() { wxTreeItemId item = m_pTree->GetSelection(); if (!item) return true; CBookmarkItemData *data = (CBookmarkItemData *)m_pTree->GetItemData(item); if (!data) return true; const CServer *server; if (m_pTree->GetItemParent(item) == m_bookmarks_site) server = m_server; else server = 0; wxString const remotePathRaw = xrc_call(*this, "ID_BOOKMARK_REMOTEDIR", &wxTextCtrl::GetValue); if (!remotePathRaw.empty()) { CServerPath remotePath; if (server) remotePath.SetType(server->GetType()); if (!remotePath.SetPath(remotePathRaw)) { xrc_call(*this, "ID_BOOKMARK_REMOTEDIR", &wxTextCtrl::SetFocus); if (server) { wxString msg; if (server->GetType() != DEFAULT) msg = wxString::Format(_("Remote path cannot be parsed. Make sure it is a valid absolute path and is supported by the current site's servertype (%s)."), server->GetNameFromServerType(server->GetType())); else msg = _("Remote path cannot be parsed. Make sure it is a valid absolute path."); wxMessageBoxEx(msg); } else wxMessageBoxEx(_("Remote path cannot be parsed. Make sure it is a valid absolute path.")); return false; } } wxString const localPath = xrc_call(*this, "ID_BOOKMARK_LOCALDIR", &wxTextCtrl::GetValue); if (remotePathRaw.empty() && localPath.empty()) { xrc_call(*this, "ID_BOOKMARK_LOCALDIR", &wxTextCtrl::SetFocus); wxMessageBoxEx(_("You need to enter at least one path, empty bookmarks are not supported.")); return false; } bool const sync = xrc_call(*this, "ID_BOOKMARK_SYNC", &wxCheckBox::GetValue); if (sync && (localPath.empty() || remotePathRaw.empty())) { wxMessageBoxEx(_("You need to enter both a local and a remote path to enable synchronized browsing for this bookmark."), _("New bookmark"), wxICON_EXCLAMATION, this); return false; } return true; } void CBookmarksDialog::UpdateBookmark() { wxTreeItemId item = m_pTree->GetSelection(); if (!item) return; CBookmarkItemData *data = (CBookmarkItemData *)m_pTree->GetItemData(item); if (!data) return; const CServer *server; if (m_pTree->GetItemParent(item) == m_bookmarks_site) server = m_server; else server = 0; wxString const remotePathRaw = xrc_call(*this, "ID_BOOKMARK_REMOTEDIR", &wxTextCtrl::GetValue); if (!remotePathRaw.empty()) { if (server) data->m_remote_dir.SetType(server->GetType()); data->m_remote_dir.SetPath(remotePathRaw); } data->m_local_dir = xrc_call(*this, "ID_BOOKMARK_LOCALDIR", &wxTextCtrl::GetValue); data->m_sync = xrc_call(*this, "ID_BOOKMARK_SYNC", &wxCheckBox::GetValue); data->m_comparison = xrc_call(*this, "ID_BOOKMARK_COMPARISON", &wxCheckBox::GetValue); } void CBookmarksDialog::DisplayBookmark() { wxTreeItemId item = m_pTree->GetSelection(); if (!item) { xrc_call(*this, "ID_BOOKMARK_REMOTEDIR", &wxTextCtrl::ChangeValue, _T("")); xrc_call(*this, "ID_BOOKMARK_LOCALDIR", &wxTextCtrl::ChangeValue, _T("")); xrc_call(*this, "ID_DELETE", &wxButton::Enable, false); xrc_call(*this, "ID_RENAME", &wxButton::Enable, false); xrc_call(*this, "ID_COPY", &wxButton::Enable, false); xrc_call(*this, "ID_NOTEBOOK", &wxNotebook::Enable, false); return; } CBookmarkItemData *data = (CBookmarkItemData *)m_pTree->GetItemData(item); if (!data) { xrc_call(*this, "ID_BOOKMARK_REMOTEDIR", &wxTextCtrl::ChangeValue, _T("")); xrc_call(*this, "ID_BOOKMARK_LOCALDIR", &wxTextCtrl::ChangeValue, _T("")); xrc_call(*this, "ID_DELETE", &wxButton::Enable, false); xrc_call(*this, "ID_RENAME", &wxButton::Enable, false); xrc_call(*this, "ID_COPY", &wxButton::Enable, false); xrc_call(*this, "ID_NOTEBOOK", &wxNotebook::Enable, false); return; } xrc_call(*this, "ID_DELETE", &wxButton::Enable, true); xrc_call(*this, "ID_RENAME", &wxButton::Enable, true); xrc_call(*this, "ID_COPY", &wxButton::Enable, true); xrc_call(*this, "ID_NOTEBOOK", &wxNotebook::Enable, true); xrc_call(*this, "ID_BOOKMARK_REMOTEDIR", &wxTextCtrl::ChangeValue, data->m_remote_dir.GetPath()); xrc_call(*this, "ID_BOOKMARK_LOCALDIR", &wxTextCtrl::ChangeValue, data->m_local_dir); xrc_call(*this, "ID_BOOKMARK_SYNC", &wxCheckBox::SetValue, data->m_sync); xrc_call(*this, "ID_BOOKMARK_COMPARISON", &wxCheckBox::SetValue, data->m_comparison); } void CBookmarksDialog::OnNewBookmark(wxCommandEvent&) { if (!Verify()) return; UpdateBookmark(); wxTreeItemId item = m_pTree->GetSelection(); if (!item) item = m_bookmarks_global; if (m_pTree->GetItemData(item)) item = m_pTree->GetItemParent(item); if (item == m_bookmarks_site) { std::list bookmarks; if (m_site_path.empty() || !CSiteManager::GetBookmarks(m_site_path, bookmarks)) { if (wxMessageBoxEx(_("Site-specific bookmarks require the server to be stored in the Site Manager.\nAdd current connection to the site manager?"), _("New bookmark"), wxYES_NO | wxICON_QUESTION, this) != wxYES) return; m_site_path = CSiteManager::AddServer(*m_server); if (m_site_path.empty()) { wxMessageBoxEx(_("Could not add connection to Site Manager"), _("New bookmark"), wxICON_EXCLAMATION, this); return; } } } wxString newName = _("New bookmark"); int index = 2; for (;;) { wxTreeItemId child; wxTreeItemIdValue cookie; child = m_pTree->GetFirstChild(item, cookie); bool found = false; while (child.IsOk()) { wxString name = m_pTree->GetItemText(child); int cmp = name.CmpNoCase(newName); if (!cmp) { found = true; break; } child = m_pTree->GetNextChild(item, cookie); } if (!found) break; newName = _("New bookmark") + wxString::Format(_T(" %d"), index++); } wxTreeItemId child = m_pTree->AppendItem(item, newName, 1, 1, new CBookmarkItemData); m_pTree->SortChildren(item); m_pTree->SelectItem(child); m_pTree->EditLabel(child); } void CBookmarksDialog::OnRename(wxCommandEvent&) { wxTreeItemId item = m_pTree->GetSelection(); if (!item || item == m_bookmarks_global || item == m_bookmarks_site) return; m_pTree->EditLabel(item); } void CBookmarksDialog::OnDelete(wxCommandEvent&) { wxTreeItemId item = m_pTree->GetSelection(); if (!item || item == m_bookmarks_global || item == m_bookmarks_site) return; wxTreeItemId parent = m_pTree->GetItemParent(item); m_is_deleting = true; m_pTree->Delete(item); m_pTree->SelectItem(parent); m_is_deleting = false; } void CBookmarksDialog::OnCopy(wxCommandEvent&) { wxTreeItemId item = m_pTree->GetSelection(); if (!item.IsOk()) return; if (!Verify()) return; CBookmarkItemData* data = static_cast(m_pTree->GetItemData(item)); if (!data) return; UpdateBookmark(); wxTreeItemId parent = m_pTree->GetItemParent(item); const wxString oldName = m_pTree->GetItemText(item); wxString newName = wxString::Format(_("Copy of %s"), oldName); int index = 2; for (;;) { wxTreeItemId child; wxTreeItemIdValue cookie; child = m_pTree->GetFirstChild(parent, cookie); bool found = false; while (child.IsOk()) { wxString name = m_pTree->GetItemText(child); int cmp = name.CmpNoCase(newName); if (!cmp) { found = true; break; } child = m_pTree->GetNextChild(parent, cookie); } if (!found) break; newName = wxString::Format(_("Copy (%d) of %s"), index++, oldName); } CBookmarkItemData* newData = new CBookmarkItemData(*data); wxTreeItemId newItem = m_pTree->AppendItem(parent, newName, 1, 1, newData); m_pTree->SortChildren(parent); m_pTree->SelectItem(newItem); m_pTree->EditLabel(newItem); } void CBookmarksDialog::OnBeginLabelEdit(wxTreeEvent& event) { wxTreeItemId item = event.GetItem(); if (item != m_pTree->GetSelection()) { if (!Verify()) { event.Veto(); return; } } if (!item || item == m_bookmarks_global || item == m_bookmarks_site) { event.Veto(); return; } } void CBookmarksDialog::OnEndLabelEdit(wxTreeEvent& event) { if (event.IsEditCancelled()) return; wxTreeItemId item = event.GetItem(); if (item != m_pTree->GetSelection()) { if (!Verify()) { event.Veto(); return; } } if (!item || item == m_bookmarks_global || item == m_bookmarks_site) { event.Veto(); return; } wxString name = event.GetLabel(); wxTreeItemId parent = m_pTree->GetItemParent(item); wxTreeItemIdValue cookie; for (wxTreeItemId child = m_pTree->GetFirstChild(parent, cookie); child.IsOk(); child = m_pTree->GetNextChild(parent, cookie)) { if (child == item) continue; if (!name.CmpNoCase(m_pTree->GetItemText(child))) { wxMessageBoxEx(_("Name already exists"), _("Cannot rename entry"), wxICON_EXCLAMATION, this); event.Veto(); return; } } m_pTree->SortChildren(parent); } bool CBookmarksDialog::GetBookmarks(std::list &bookmarks) { CInterProcessMutex mutex(MUTEX_GLOBALBOOKMARKS); CXmlFile file(wxGetApp().GetSettingsFile(_T("bookmarks"))); auto element = file.Load(); if (!element) { wxMessageBoxEx(file.GetError(), _("Error loading xml file"), wxICON_ERROR); return false; } for (auto bookmark = element.child("Bookmark"); bookmark; bookmark = bookmark.next_sibling("Bookmark")) { wxString name; wxString local_dir; wxString remote_dir_raw; CServerPath remote_dir; name = GetTextElement(bookmark, "Name"); if (name.empty()) continue; local_dir = GetTextElement(bookmark, "LocalDir"); remote_dir_raw = GetTextElement(bookmark, "RemoteDir"); if (!remote_dir_raw.empty()) { if (!remote_dir.SetSafePath(remote_dir_raw)) continue; } if (local_dir.empty() && remote_dir.empty()) continue; bookmarks.push_back(name); } return true; } bool CBookmarksDialog::GetBookmark(const wxString &name, wxString &local_dir, CServerPath &remote_dir, bool &sync, bool &comparison) { CInterProcessMutex mutex(MUTEX_GLOBALBOOKMARKS); CXmlFile file(wxGetApp().GetSettingsFile(_T("bookmarks"))); auto element = file.Load(); if (!element) { wxMessageBoxEx(file.GetError(), _("Error loading xml file"), wxICON_ERROR); return false; } for (auto bookmark = element.child("Bookmark"); bookmark; bookmark = bookmark.next_sibling("Bookmark")) { wxString remote_dir_raw; if (name != GetTextElement(bookmark, "Name")) continue; local_dir = GetTextElement(bookmark, "LocalDir"); remote_dir_raw = GetTextElement(bookmark, "RemoteDir"); if (!remote_dir_raw.empty()) { if (!remote_dir.SetSafePath(remote_dir_raw)) return false; } if (local_dir.empty() && remote_dir_raw.empty()) return false; if (local_dir.empty() || remote_dir_raw.empty()) sync = false; else sync = GetTextElementBool(bookmark, "SyncBrowsing", false); comparison = GetTextElementBool(bookmark, "DirectoryComparison", false); return true; } return false; } bool CBookmarksDialog::AddBookmark(const wxString &name, const wxString &local_dir, const CServerPath &remote_dir, bool sync, bool comparison) { if (local_dir.empty() && remote_dir.empty()) return false; if ((local_dir.empty() || remote_dir.empty()) && sync) return false; CInterProcessMutex mutex(MUTEX_GLOBALBOOKMARKS); CXmlFile file(wxGetApp().GetSettingsFile(_T("bookmarks"))); auto element = file.Load(); if (!element) { wxString msg = file.GetError() + _T("\n\n") + _("The bookmark could not be added."); wxMessageBoxEx(msg, _("Error loading xml file"), wxICON_ERROR); return false; } pugi::xml_node bookmark, insertBefore; for (bookmark = element.child("Bookmark"); bookmark; bookmark = bookmark.next_sibling("Bookmark")) { wxString remote_dir_raw; wxString old_name = GetTextElement(bookmark, "Name"); if (!name.CmpNoCase(old_name)) { wxMessageBoxEx(_("Name of bookmark already exists."), _("New bookmark"), wxICON_EXCLAMATION); return false; } if (name < old_name && !insertBefore) insertBefore = bookmark; } if (insertBefore) bookmark = element.insert_child_before("Bookmark", insertBefore); else bookmark = element.append_child("Bookmark"); AddTextElement(bookmark, "Name", name); if (!local_dir.empty()) AddTextElement(bookmark, "LocalDir", local_dir); if (!remote_dir.empty()) AddTextElement(bookmark, "RemoteDir", remote_dir.GetSafePath()); if (sync) AddTextElementRaw(bookmark, "SyncBrowsing", "1"); if (comparison) AddTextElementRaw(bookmark, "DirectoryComparison", "1"); if (!file.Save(false)) { wxString msg = wxString::Format(_("Could not write \"%s\", the bookmark could not be added: %s"), file.GetFileName(), file.GetError()); wxMessageBoxEx(msg, _("Error writing xml file"), wxICON_ERROR); return false; } return true; }