source: filezilla/trunk/fuentes/src/interface/bookmarks_dialog.cpp @ 130

Last change on this file since 130 was 130, checked in by jrpelegrina, 4 years ago

First release to xenial

File size: 23.8 KB
Line 
1#include <filezilla.h>
2#include "bookmarks_dialog.h"
3#include "filezillaapp.h"
4#include "sitemanager.h"
5#include "ipcmutex.h"
6#include "themeprovider.h"
7#include "xmlfunctions.h"
8#include "xrc_helper.h"
9
10BEGIN_EVENT_TABLE(CNewBookmarkDialog, wxDialogEx)
11EVT_BUTTON(XRCID("wxID_OK"), CNewBookmarkDialog::OnOK)
12EVT_BUTTON(XRCID("ID_BROWSE"), CNewBookmarkDialog::OnBrowse)
13END_EVENT_TABLE()
14
15BEGIN_EVENT_TABLE(CBookmarksDialog, wxDialogEx)
16EVT_TREE_SEL_CHANGING(XRCID("ID_TREE"), CBookmarksDialog::OnSelChanging)
17EVT_TREE_SEL_CHANGED(XRCID("ID_TREE"), CBookmarksDialog::OnSelChanged)
18EVT_BUTTON(XRCID("wxID_OK"), CBookmarksDialog::OnOK)
19EVT_BUTTON(XRCID("ID_BOOKMARK_BROWSE"), CBookmarksDialog::OnBrowse)
20EVT_BUTTON(XRCID("ID_NEW"), CBookmarksDialog::OnNewBookmark)
21EVT_BUTTON(XRCID("ID_RENAME"), CBookmarksDialog::OnRename)
22EVT_BUTTON(XRCID("ID_DELETE"), CBookmarksDialog::OnDelete)
23EVT_BUTTON(XRCID("ID_COPY"), CBookmarksDialog::OnCopy)
24EVT_TREE_BEGIN_LABEL_EDIT(XRCID("ID_TREE"), CBookmarksDialog::OnBeginLabelEdit)
25EVT_TREE_END_LABEL_EDIT(XRCID("ID_TREE"), CBookmarksDialog::OnEndLabelEdit)
26END_EVENT_TABLE()
27
28CNewBookmarkDialog::CNewBookmarkDialog(wxWindow* parent, wxString& site_path, const CServer* server)
29        : m_parent(parent)
30        , m_site_path(site_path)
31        , m_server(server)
32{
33}
34
35int CNewBookmarkDialog::Run(const wxString &local_path, const CServerPath &remote_path)
36{
37        if (!Load(m_parent, _T("ID_NEWBOOKMARK")))
38                return wxID_CANCEL;
39
40        xrc_call(*this, "ID_LOCALPATH", &wxTextCtrl::ChangeValue, local_path);
41        if (!remote_path.empty())
42                xrc_call(*this, "ID_REMOTEPATH", &wxTextCtrl::ChangeValue, remote_path.GetPath());
43
44        if (!m_server)
45                xrc_call(*this, "ID_TYPE_SITE", &wxRadioButton::Enable, false);
46
47        return ShowModal();
48}
49
50void CNewBookmarkDialog::OnOK(wxCommandEvent&)
51{
52        bool const global = xrc_call(*this, "ID_TYPE_GLOBAL", &wxRadioButton::GetValue);
53
54        wxString const name = xrc_call(*this, "ID_NAME", &wxTextCtrl::GetValue);
55        if (name.empty()) {
56                wxMessageBoxEx(_("You need to enter a name for the bookmark."), _("New bookmark"), wxICON_EXCLAMATION, this);
57                return;
58        }
59
60        wxString const local_path = xrc_call(*this, "ID_LOCALPATH", &wxTextCtrl::GetValue);
61        wxString remote_path_raw = xrc_call(*this, "ID_REMOTEPATH", &wxTextCtrl::GetValue);
62
63        CServerPath remote_path;
64        if (!remote_path_raw.empty()) {
65                if (!global && m_server)
66                        remote_path.SetType(m_server->GetType());
67                if (!remote_path.SetPath(remote_path_raw))
68                {
69                        wxMessageBoxEx(_("Could not parse remote path."), _("New bookmark"), wxICON_EXCLAMATION);
70                        return;
71                }
72        }
73
74        if (local_path.empty() && remote_path_raw.empty()) {
75                wxMessageBoxEx(_("You need to enter at least one path, empty bookmarks are not supported."), _("New bookmark"), wxICON_EXCLAMATION, this);
76                return;
77        }
78
79        bool const sync = xrc_call(*this, "ID_SYNC", &wxCheckBox::GetValue);
80        if (sync && (local_path.empty() || remote_path_raw.empty())) {
81                wxMessageBoxEx(_("You need to enter both a local and a remote path to enable synchronized browsing for this bookmark."), _("New bookmark"), wxICON_EXCLAMATION, this);
82                return;
83        }
84
85        bool const comparison = xrc_call(*this, "ID_COMPARISON", &wxCheckBox::GetValue);
86
87        if (!global && m_server) {
88                std::list<wxString> bookmarks;
89
90                if (m_site_path.empty() || !CSiteManager::GetBookmarks(m_site_path, bookmarks)) {
91                        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)
92                                return;
93
94                        m_site_path = CSiteManager::AddServer(*m_server);
95                        if (m_site_path.empty()) {
96                                wxMessageBoxEx(_("Could not add connection to Site Manager"), _("New bookmark"), wxICON_EXCLAMATION, this);
97                                EndModal(wxID_CANCEL);
98                                return;
99                        }
100                }
101                for (std::list<wxString>::const_iterator iter = bookmarks.begin(); iter != bookmarks.end(); ++iter) {
102                        if (*iter == name) {
103                                wxMessageBoxEx(_("A bookmark with the entered name already exists. Please enter an unused name."), _("New bookmark"), wxICON_EXCLAMATION, this);
104                                return;
105                        }
106                }
107
108                CSiteManager::AddBookmark(m_site_path, name, local_path, remote_path, sync, comparison);
109
110                EndModal(wxID_OK);
111        }
112        else {
113                if (!CBookmarksDialog::AddBookmark(name, local_path, remote_path, sync, comparison))
114                        return;
115
116                EndModal(wxID_OK);
117        }
118}
119
120void CNewBookmarkDialog::OnBrowse(wxCommandEvent&)
121{
122        wxTextCtrl *const pText = XRCCTRL(*this, "ID_LOCALPATH", wxTextCtrl);
123
124        wxDirDialog dlg(this, _("Choose the local directory"), pText->GetValue(), wxDD_NEW_DIR_BUTTON);
125        if (dlg.ShowModal() == wxID_OK) {
126                pText->ChangeValue(dlg.GetPath());
127        }
128}
129
130class CBookmarkItemData : public wxTreeItemData
131{
132public:
133        CBookmarkItemData()
134        {
135        }
136
137        CBookmarkItemData(const wxString& local_dir, const CServerPath& remote_dir, bool sync, bool comparison)
138                : m_local_dir(local_dir), m_remote_dir(remote_dir), m_sync(sync)
139                , m_comparison(comparison)
140        {
141        }
142
143        wxString m_local_dir;
144        CServerPath m_remote_dir;
145        bool m_sync{};
146        bool m_comparison{};
147};
148
149CBookmarksDialog::CBookmarksDialog(wxWindow* parent, wxString& site_path, const CServer* server)
150        : m_parent(parent)
151        , m_site_path(site_path)
152        , m_server(server)
153        , m_pTree()
154{
155}
156
157void CBookmarksDialog::LoadGlobalBookmarks()
158{
159        CInterProcessMutex mutex(MUTEX_GLOBALBOOKMARKS);
160
161        CXmlFile file(wxGetApp().GetSettingsFile(_T("bookmarks")));
162        auto element = file.Load();
163        if (!element) {
164                wxMessageBoxEx(file.GetError(), _("Error loading xml file"), wxICON_ERROR);
165
166                return;
167        }
168
169        for (auto bookmark = element.child("Bookmark"); bookmark; bookmark = bookmark.next_sibling("Bookmark")) {
170                wxString name;
171                wxString local_dir;
172                wxString remote_dir_raw;
173                CServerPath remote_dir;
174
175                name = GetTextElement(bookmark, "Name");
176                if (name.empty())
177                        continue;
178
179                local_dir = GetTextElement(bookmark, "LocalDir");
180                remote_dir_raw = GetTextElement(bookmark, "RemoteDir");
181                if (!remote_dir_raw.empty()) {
182                        if (!remote_dir.SetSafePath(remote_dir_raw))
183                                continue;
184                }
185                if (local_dir.empty() && remote_dir.empty())
186                        continue;
187
188                bool sync;
189                if (local_dir.empty() || remote_dir.empty())
190                        sync = false;
191                else
192                        sync = GetTextElementBool(bookmark, "SyncBrowsing");
193
194                bool const comparison = GetTextElementBool(bookmark, "DirectoryComparison");
195
196                CBookmarkItemData *data = new CBookmarkItemData(local_dir, remote_dir, sync, comparison);
197                m_pTree->AppendItem(m_bookmarks_global, name, 1, 1, data);
198        }
199
200        m_pTree->SortChildren(m_bookmarks_global);
201}
202
203void CBookmarksDialog::LoadSiteSpecificBookmarks()
204{
205        if (m_site_path.empty())
206                return;
207
208        std::list<wxString> bookmarks;
209
210        if (!CSiteManager::GetBookmarks(m_site_path, bookmarks))
211                return;
212
213        for (std::list<wxString>::const_iterator iter = bookmarks.begin(); iter != bookmarks.end(); ++iter) {
214                wxString path = *iter;
215                path.Replace(_T("\\"), _T("\\\\"));
216                path.Replace(_T("/"), _T("\\/"));
217                path = m_site_path + _T("/") + path;
218
219                std::unique_ptr<CSiteManagerItemData_Site> data = CSiteManager::GetSiteByPath(path);
220                if (data) {
221                        CBookmarkItemData* new_data = new CBookmarkItemData(data->m_localDir, data->m_remoteDir, data->m_sync, data->m_comparison);
222                        m_pTree->AppendItem(m_bookmarks_site, *iter, 1, 1, new_data);
223                }
224        }
225
226        m_pTree->SortChildren(m_bookmarks_site);
227}
228
229int CBookmarksDialog::Run()
230{
231        if (!Load(m_parent, _T("ID_BOOKMARKS")))
232                return wxID_CANCEL;
233
234        // Now create the imagelist for the site tree
235        m_pTree = XRCCTRL(*this, "ID_TREE", wxTreeCtrl);
236        if (!m_pTree)
237                return false;
238
239        wxSize s = CThemeProvider::GetIconSize(iconSizeSmall);
240        wxImageList* pImageList = new wxImageList(s.x, s.y);
241
242        pImageList->Add(wxArtProvider::GetBitmap(_T("ART_FOLDER"), wxART_OTHER, CThemeProvider::GetIconSize(iconSizeSmall)));
243        pImageList->Add(wxArtProvider::GetBitmap(_T("ART_BOOKMARK"), wxART_OTHER, CThemeProvider::GetIconSize(iconSizeSmall)));
244
245        m_pTree->AssignImageList(pImageList);
246
247        wxTreeItemId root = m_pTree->AddRoot(_T(""));
248        m_bookmarks_global = m_pTree->AppendItem(root, _("Global bookmarks"), 0, 0);
249        LoadGlobalBookmarks();
250        m_pTree->Expand(m_bookmarks_global);
251        if (m_server) {
252                m_bookmarks_site = m_pTree->AppendItem(root, _("Site-specific bookmarks"), 0, 0);
253                LoadSiteSpecificBookmarks();
254                m_pTree->Expand(m_bookmarks_site);
255        }
256
257        wxNotebook *pBook = XRCCTRL(*this, "ID_NOTEBOOK", wxNotebook);
258
259        wxPanel* pPanel = new wxPanel;
260        wxXmlResource::Get()->LoadPanel(pPanel, pBook, _T("ID_SITEMANAGER_BOOKMARK_PANEL"));
261        pBook->AddPage(pPanel, _("Bookmark"));
262
263        xrc_call(*this, "ID_BOOKMARK_LOCALDIR", &wxTextCtrl::GetContainingSizer)->GetItem((size_t)0)->SetMinSize(200, -1);
264
265        GetSizer()->Fit(this);
266
267        wxSize minSize = GetSizer()->GetMinSize();
268        wxSize size = GetSize();
269        wxSize clientSize = GetClientSize();
270        SetMinSize(GetSizer()->GetMinSize() + size - clientSize);
271        SetClientSize(minSize);
272
273        m_pTree->SelectItem(m_bookmarks_global);
274
275        return ShowModal();
276}
277
278void CBookmarksDialog::SaveGlobalBookmarks()
279{
280        CInterProcessMutex mutex(MUTEX_GLOBALBOOKMARKS);
281
282        CXmlFile file(wxGetApp().GetSettingsFile(_T("bookmarks")));
283        auto element = file.Load();
284        if (!element) {
285                wxString msg = file.GetError() + _T("\n\n") + _("The global bookmarks could not be saved.");
286                wxMessageBoxEx(msg, _("Error loading xml file"), wxICON_ERROR);
287
288                return;
289        }
290
291        {
292                auto bookmark = element.child("Bookmark");
293                while (bookmark) {
294                        element.remove_child(bookmark);
295                        bookmark = element.child("Bookmark");
296                }
297        }
298
299        wxTreeItemIdValue cookie;
300        for (wxTreeItemId child = m_pTree->GetFirstChild(m_bookmarks_global, cookie); child.IsOk(); child = m_pTree->GetNextChild(m_bookmarks_global, cookie)) {
301                CBookmarkItemData *data = (CBookmarkItemData *)m_pTree->GetItemData(child);
302                wxASSERT(data);
303
304                auto bookmark = element.append_child("Bookmark");
305                AddTextElement(bookmark, "Name", m_pTree->GetItemText(child));
306                if (!data->m_local_dir.empty())
307                        AddTextElement(bookmark, "LocalDir", data->m_local_dir);
308                if (!data->m_remote_dir.empty())
309                        AddTextElement(bookmark, "RemoteDir", data->m_remote_dir.GetSafePath());
310                if (data->m_sync)
311                        AddTextElementRaw(bookmark, "SyncBrowsing", "1");
312                if (data->m_comparison)
313                        AddTextElementRaw(bookmark, "DirectoryComparison", "1");
314        }
315
316        if (!file.Save(false)) {
317                wxString msg = wxString::Format(_("Could not write \"%s\", the global bookmarks could no be saved: %s"), file.GetFileName(), file.GetError());
318                wxMessageBoxEx(msg, _("Error writing xml file"), wxICON_ERROR);
319        }
320}
321
322void CBookmarksDialog::SaveSiteSpecificBookmarks()
323{
324        if (m_site_path.empty())
325                return;
326
327        if (!CSiteManager::ClearBookmarks(m_site_path))
328                        return;
329
330        wxTreeItemIdValue cookie;
331        for (wxTreeItemId child = m_pTree->GetFirstChild(m_bookmarks_site, cookie); child.IsOk(); child = m_pTree->GetNextChild(m_bookmarks_site, cookie)) {
332                CBookmarkItemData *data = (CBookmarkItemData *)m_pTree->GetItemData(child);
333                wxASSERT(data);
334
335                if (!CSiteManager::AddBookmark(m_site_path, m_pTree->GetItemText(child), data->m_local_dir, data->m_remote_dir, data->m_sync, data->m_comparison))
336                        return;
337        }
338}
339
340void CBookmarksDialog::OnOK(wxCommandEvent&)
341{
342        if (!Verify())
343                return;
344        UpdateBookmark();
345
346        SaveGlobalBookmarks();
347        SaveSiteSpecificBookmarks();
348
349        EndModal(wxID_OK);
350}
351
352void CBookmarksDialog::OnBrowse(wxCommandEvent&)
353{
354        wxTreeItemId item = m_pTree->GetSelection();
355        if (!item)
356                return;
357
358        CBookmarkItemData *data = (CBookmarkItemData *)m_pTree->GetItemData(item);
359        if (!data)
360                return;
361
362        wxTextCtrl *pText = XRCCTRL(*this, "ID_BOOKMARK_LOCALDIR", wxTextCtrl);
363
364        wxDirDialog dlg(this, _("Choose the local directory"), pText->GetValue(), wxDD_NEW_DIR_BUTTON);
365        if (dlg.ShowModal() == wxID_OK) {
366                pText->ChangeValue(dlg.GetPath());
367        }
368}
369
370void CBookmarksDialog::OnSelChanging(wxTreeEvent& event)
371{
372        if (m_is_deleting)
373                return;
374
375        if (!Verify()) {
376                event.Veto();
377                return;
378        }
379
380        UpdateBookmark();
381}
382
383void CBookmarksDialog::OnSelChanged(wxTreeEvent&)
384{
385        DisplayBookmark();
386}
387
388bool CBookmarksDialog::Verify()
389{
390        wxTreeItemId item = m_pTree->GetSelection();
391        if (!item)
392                return true;
393
394        CBookmarkItemData *data = (CBookmarkItemData *)m_pTree->GetItemData(item);
395        if (!data)
396                return true;
397
398        const CServer *server;
399        if (m_pTree->GetItemParent(item) == m_bookmarks_site)
400                server = m_server;
401        else
402                server = 0;
403
404        wxString const remotePathRaw = xrc_call(*this, "ID_BOOKMARK_REMOTEDIR", &wxTextCtrl::GetValue);
405        if (!remotePathRaw.empty()) {
406                CServerPath remotePath;
407                if (server)
408                        remotePath.SetType(server->GetType());
409                if (!remotePath.SetPath(remotePathRaw)) {
410                        xrc_call(*this, "ID_BOOKMARK_REMOTEDIR", &wxTextCtrl::SetFocus);
411                        if (server) {
412                                wxString msg;
413                                if (server->GetType() != DEFAULT)
414                                        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()));
415                                else
416                                        msg = _("Remote path cannot be parsed. Make sure it is a valid absolute path.");
417                                wxMessageBoxEx(msg);
418                        }
419                        else
420                                wxMessageBoxEx(_("Remote path cannot be parsed. Make sure it is a valid absolute path."));
421                        return false;
422                }
423        }
424
425        wxString const localPath = xrc_call(*this, "ID_BOOKMARK_LOCALDIR", &wxTextCtrl::GetValue);
426
427        if (remotePathRaw.empty() && localPath.empty()) {
428                xrc_call(*this, "ID_BOOKMARK_LOCALDIR", &wxTextCtrl::SetFocus);
429                wxMessageBoxEx(_("You need to enter at least one path, empty bookmarks are not supported."));
430                return false;
431        }
432
433        bool const sync = xrc_call(*this, "ID_BOOKMARK_SYNC", &wxCheckBox::GetValue);
434        if (sync && (localPath.empty() || remotePathRaw.empty())) {
435                wxMessageBoxEx(_("You need to enter both a local and a remote path to enable synchronized browsing for this bookmark."), _("New bookmark"), wxICON_EXCLAMATION, this);
436                return false;
437        }
438
439        return true;
440}
441
442void CBookmarksDialog::UpdateBookmark()
443{
444        wxTreeItemId item = m_pTree->GetSelection();
445        if (!item)
446                return;
447
448        CBookmarkItemData *data = (CBookmarkItemData *)m_pTree->GetItemData(item);
449        if (!data)
450                return;
451
452        const CServer *server;
453        if (m_pTree->GetItemParent(item) == m_bookmarks_site)
454                server = m_server;
455        else
456                server = 0;
457
458        wxString const remotePathRaw = xrc_call(*this, "ID_BOOKMARK_REMOTEDIR", &wxTextCtrl::GetValue);
459        if (!remotePathRaw.empty()) {
460                if (server)
461                        data->m_remote_dir.SetType(server->GetType());
462                data->m_remote_dir.SetPath(remotePathRaw);
463        }
464
465        data->m_local_dir = xrc_call(*this, "ID_BOOKMARK_LOCALDIR", &wxTextCtrl::GetValue);
466
467        data->m_sync = xrc_call(*this, "ID_BOOKMARK_SYNC", &wxCheckBox::GetValue);
468        data->m_comparison = xrc_call(*this, "ID_BOOKMARK_COMPARISON", &wxCheckBox::GetValue);
469}
470
471void CBookmarksDialog::DisplayBookmark()
472{
473        wxTreeItemId item = m_pTree->GetSelection();
474        if (!item) {
475                xrc_call(*this, "ID_BOOKMARK_REMOTEDIR", &wxTextCtrl::ChangeValue, _T(""));
476                xrc_call(*this, "ID_BOOKMARK_LOCALDIR", &wxTextCtrl::ChangeValue, _T(""));
477                xrc_call(*this, "ID_DELETE", &wxButton::Enable, false);
478                xrc_call(*this, "ID_RENAME", &wxButton::Enable, false);
479                xrc_call(*this, "ID_COPY", &wxButton::Enable, false);
480                xrc_call(*this, "ID_NOTEBOOK", &wxNotebook::Enable, false);
481                return;
482        }
483
484        CBookmarkItemData *data = (CBookmarkItemData *)m_pTree->GetItemData(item);
485        if (!data) {
486                xrc_call(*this, "ID_BOOKMARK_REMOTEDIR", &wxTextCtrl::ChangeValue, _T(""));
487                xrc_call(*this, "ID_BOOKMARK_LOCALDIR", &wxTextCtrl::ChangeValue, _T(""));
488                xrc_call(*this, "ID_DELETE", &wxButton::Enable, false);
489                xrc_call(*this, "ID_RENAME", &wxButton::Enable, false);
490                xrc_call(*this, "ID_COPY", &wxButton::Enable, false);
491                xrc_call(*this, "ID_NOTEBOOK", &wxNotebook::Enable, false);
492                return;
493        }
494
495        xrc_call(*this, "ID_DELETE", &wxButton::Enable, true);
496        xrc_call(*this, "ID_RENAME", &wxButton::Enable, true);
497        xrc_call(*this, "ID_COPY", &wxButton::Enable, true);
498        xrc_call(*this, "ID_NOTEBOOK", &wxNotebook::Enable, true);
499
500        xrc_call(*this, "ID_BOOKMARK_REMOTEDIR", &wxTextCtrl::ChangeValue, data->m_remote_dir.GetPath());
501        xrc_call(*this, "ID_BOOKMARK_LOCALDIR", &wxTextCtrl::ChangeValue, data->m_local_dir);
502
503        xrc_call(*this, "ID_BOOKMARK_SYNC", &wxCheckBox::SetValue, data->m_sync);
504        xrc_call(*this, "ID_BOOKMARK_COMPARISON", &wxCheckBox::SetValue, data->m_comparison);
505}
506
507void CBookmarksDialog::OnNewBookmark(wxCommandEvent&)
508{
509        if (!Verify())
510                return;
511        UpdateBookmark();
512
513        wxTreeItemId item = m_pTree->GetSelection();
514        if (!item)
515                item = m_bookmarks_global;
516
517        if (m_pTree->GetItemData(item))
518                item = m_pTree->GetItemParent(item);
519
520        if (item == m_bookmarks_site) {
521                std::list<wxString> bookmarks;
522
523                if (m_site_path.empty() || !CSiteManager::GetBookmarks(m_site_path, bookmarks)) {
524                        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)
525                                return;
526
527                        m_site_path = CSiteManager::AddServer(*m_server);
528                        if (m_site_path.empty()) {
529                                wxMessageBoxEx(_("Could not add connection to Site Manager"), _("New bookmark"), wxICON_EXCLAMATION, this);
530                                return;
531                        }
532                }
533        }
534
535        wxString newName = _("New bookmark");
536        int index = 2;
537        for (;;) {
538                wxTreeItemId child;
539                wxTreeItemIdValue cookie;
540                child = m_pTree->GetFirstChild(item, cookie);
541                bool found = false;
542                while (child.IsOk()) {
543                        wxString name = m_pTree->GetItemText(child);
544                        int cmp = name.CmpNoCase(newName);
545                        if (!cmp) {
546                                found = true;
547                                break;
548                        }
549
550                        child = m_pTree->GetNextChild(item, cookie);
551                }
552                if (!found)
553                        break;
554
555                newName = _("New bookmark") + wxString::Format(_T(" %d"), index++);
556        }
557
558        wxTreeItemId child = m_pTree->AppendItem(item, newName, 1, 1, new CBookmarkItemData);
559        m_pTree->SortChildren(item);
560        m_pTree->SelectItem(child);
561        m_pTree->EditLabel(child);
562}
563
564void CBookmarksDialog::OnRename(wxCommandEvent&)
565{
566        wxTreeItemId item = m_pTree->GetSelection();
567        if (!item || item == m_bookmarks_global || item == m_bookmarks_site)
568                return;
569
570        m_pTree->EditLabel(item);
571}
572
573void CBookmarksDialog::OnDelete(wxCommandEvent&)
574{
575        wxTreeItemId item = m_pTree->GetSelection();
576        if (!item || item == m_bookmarks_global || item == m_bookmarks_site)
577                return;
578
579        wxTreeItemId parent = m_pTree->GetItemParent(item);
580
581        m_is_deleting = true;
582        m_pTree->Delete(item);
583        m_pTree->SelectItem(parent);
584        m_is_deleting = false;
585}
586
587void CBookmarksDialog::OnCopy(wxCommandEvent&)
588{
589        wxTreeItemId item = m_pTree->GetSelection();
590        if (!item.IsOk())
591                return;
592
593        if (!Verify())
594                return;
595
596        CBookmarkItemData* data = static_cast<CBookmarkItemData *>(m_pTree->GetItemData(item));
597        if (!data)
598                return;
599
600        UpdateBookmark();
601
602        wxTreeItemId parent = m_pTree->GetItemParent(item);
603
604        const wxString oldName = m_pTree->GetItemText(item);
605        wxString newName = wxString::Format(_("Copy of %s"), oldName);
606        int index = 2;
607        for (;;) {
608                wxTreeItemId child;
609                wxTreeItemIdValue cookie;
610                child = m_pTree->GetFirstChild(parent, cookie);
611                bool found = false;
612                while (child.IsOk()) {
613                        wxString name = m_pTree->GetItemText(child);
614                        int cmp = name.CmpNoCase(newName);
615                        if (!cmp) {
616                                found = true;
617                                break;
618                        }
619
620                        child = m_pTree->GetNextChild(parent, cookie);
621                }
622                if (!found)
623                        break;
624
625                newName = wxString::Format(_("Copy (%d) of %s"), index++, oldName);
626        }
627
628        CBookmarkItemData* newData = new CBookmarkItemData(*data);
629        wxTreeItemId newItem = m_pTree->AppendItem(parent, newName, 1, 1, newData);
630
631        m_pTree->SortChildren(parent);
632        m_pTree->SelectItem(newItem);
633        m_pTree->EditLabel(newItem);
634}
635
636void CBookmarksDialog::OnBeginLabelEdit(wxTreeEvent& event)
637{
638        wxTreeItemId item = event.GetItem();
639        if (item != m_pTree->GetSelection()) {
640                if (!Verify()) {
641                        event.Veto();
642                        return;
643                }
644        }
645
646        if (!item || item == m_bookmarks_global || item == m_bookmarks_site) {
647                event.Veto();
648                return;
649        }
650}
651
652void CBookmarksDialog::OnEndLabelEdit(wxTreeEvent& event)
653{
654        if (event.IsEditCancelled())
655                return;
656
657        wxTreeItemId item = event.GetItem();
658        if (item != m_pTree->GetSelection()) {
659                if (!Verify()) {
660                        event.Veto();
661                        return;
662                }
663        }
664
665        if (!item || item == m_bookmarks_global || item == m_bookmarks_site) {
666                event.Veto();
667                return;
668        }
669
670        wxString name = event.GetLabel();
671
672        wxTreeItemId parent = m_pTree->GetItemParent(item);
673
674        wxTreeItemIdValue cookie;
675        for (wxTreeItemId child = m_pTree->GetFirstChild(parent, cookie); child.IsOk(); child = m_pTree->GetNextChild(parent, cookie)) {
676                if (child == item)
677                        continue;
678                if (!name.CmpNoCase(m_pTree->GetItemText(child))) {
679                        wxMessageBoxEx(_("Name already exists"), _("Cannot rename entry"), wxICON_EXCLAMATION, this);
680                        event.Veto();
681                        return;
682                }
683        }
684
685        m_pTree->SortChildren(parent);
686}
687
688bool CBookmarksDialog::GetBookmarks(std::list<wxString> &bookmarks)
689{
690        CInterProcessMutex mutex(MUTEX_GLOBALBOOKMARKS);
691
692        CXmlFile file(wxGetApp().GetSettingsFile(_T("bookmarks")));
693        auto element = file.Load();
694        if (!element) {
695                wxMessageBoxEx(file.GetError(), _("Error loading xml file"), wxICON_ERROR);
696
697                return false;
698        }
699
700        for (auto bookmark = element.child("Bookmark"); bookmark; bookmark = bookmark.next_sibling("Bookmark")) {
701                wxString name;
702                wxString local_dir;
703                wxString remote_dir_raw;
704                CServerPath remote_dir;
705
706                name = GetTextElement(bookmark, "Name");
707                if (name.empty())
708                        continue;
709
710                local_dir = GetTextElement(bookmark, "LocalDir");
711                remote_dir_raw = GetTextElement(bookmark, "RemoteDir");
712                if (!remote_dir_raw.empty()) {
713                        if (!remote_dir.SetSafePath(remote_dir_raw))
714                                continue;
715                }
716                if (local_dir.empty() && remote_dir.empty())
717                        continue;
718
719                bookmarks.push_back(name);
720        }
721
722        return true;
723}
724
725bool CBookmarksDialog::GetBookmark(const wxString &name, wxString &local_dir, CServerPath &remote_dir, bool &sync, bool &comparison)
726{
727        CInterProcessMutex mutex(MUTEX_GLOBALBOOKMARKS);
728
729        CXmlFile file(wxGetApp().GetSettingsFile(_T("bookmarks")));
730        auto element = file.Load();
731        if (!element) {
732                wxMessageBoxEx(file.GetError(), _("Error loading xml file"), wxICON_ERROR);
733
734                return false;
735        }
736
737        for (auto bookmark = element.child("Bookmark"); bookmark; bookmark = bookmark.next_sibling("Bookmark")) {
738                wxString remote_dir_raw;
739
740                if (name != GetTextElement(bookmark, "Name"))
741                        continue;
742
743                local_dir = GetTextElement(bookmark, "LocalDir");
744                remote_dir_raw = GetTextElement(bookmark, "RemoteDir");
745                if (!remote_dir_raw.empty()) {
746                        if (!remote_dir.SetSafePath(remote_dir_raw))
747                                return false;
748                }
749                if (local_dir.empty() && remote_dir_raw.empty())
750                        return false;
751
752                if (local_dir.empty() || remote_dir_raw.empty())
753                        sync = false;
754                else
755                        sync = GetTextElementBool(bookmark, "SyncBrowsing", false);
756
757                comparison = GetTextElementBool(bookmark, "DirectoryComparison", false);
758                return true;
759        }
760
761        return false;
762}
763
764
765bool CBookmarksDialog::AddBookmark(const wxString &name, const wxString &local_dir, const CServerPath &remote_dir, bool sync, bool comparison)
766{
767        if (local_dir.empty() && remote_dir.empty())
768                return false;
769        if ((local_dir.empty() || remote_dir.empty()) && sync)
770                return false;
771
772        CInterProcessMutex mutex(MUTEX_GLOBALBOOKMARKS);
773
774        CXmlFile file(wxGetApp().GetSettingsFile(_T("bookmarks")));
775        auto element = file.Load();
776        if (!element) {
777                wxString msg = file.GetError() + _T("\n\n") + _("The bookmark could not be added.");
778                wxMessageBoxEx(msg, _("Error loading xml file"), wxICON_ERROR);
779
780                return false;
781        }
782
783        pugi::xml_node bookmark, insertBefore;
784        for (bookmark = element.child("Bookmark"); bookmark; bookmark = bookmark.next_sibling("Bookmark")) {
785                wxString remote_dir_raw;
786
787                wxString old_name = GetTextElement(bookmark, "Name");
788
789                if (!name.CmpNoCase(old_name)) {
790                        wxMessageBoxEx(_("Name of bookmark already exists."), _("New bookmark"), wxICON_EXCLAMATION);
791                        return false;
792                }
793                if (name < old_name && !insertBefore)
794                        insertBefore = bookmark;
795        }
796
797        if (insertBefore)
798                bookmark = element.insert_child_before("Bookmark", insertBefore);
799        else
800                bookmark = element.append_child("Bookmark");
801        AddTextElement(bookmark, "Name", name);
802        if (!local_dir.empty())
803                AddTextElement(bookmark, "LocalDir", local_dir);
804        if (!remote_dir.empty())
805                AddTextElement(bookmark, "RemoteDir", remote_dir.GetSafePath());
806        if (sync)
807                AddTextElementRaw(bookmark, "SyncBrowsing", "1");
808        if (comparison)
809                AddTextElementRaw(bookmark, "DirectoryComparison", "1");
810
811        if (!file.Save(false)) {
812                wxString msg = wxString::Format(_("Could not write \"%s\", the bookmark could not be added: %s"), file.GetFileName(), file.GetError());
813                wxMessageBoxEx(msg, _("Error writing xml file"), wxICON_ERROR);
814                return false;
815        }
816
817        return true;
818}
Note: See TracBrowser for help on using the repository browser.