OpenCPN Partial API docs
Loading...
Searching...
No Matches
catalog_mgr.cpp
Go to the documentation of this file.
1/**************************************************************************
2 * Copyright (C) 2019 Alec Leamas *
3 * *
4 * This program is free software; you can redistribute it and/or modify *
5 * it under the terms of the GNU General Public License as published by *
6 * the Free Software Foundation; either version 2 of the License, or *
7 * (at your option) any later version. *
8 * *
9 * This program is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12 * GNU General Public License for more details. *
13 * *
14 * You should have received a copy of the GNU General Public License *
15 * along with this program; if not, see <https://www.gnu.org/licenses/>. *
16 ***************************************************************************/
17
24#include <fstream>
25#include <sstream>
26#include <thread>
27
28#include <wx/button.h>
29#include <wx/debug.h>
30#include <wx/filename.h>
31#include <wx/log.h>
32#include <wx/msgdlg.h>
33#include <wx/panel.h>
34#include <wx/progdlg.h>
35#include <wx/sizer.h>
36#include <wx/statline.h>
37
39#include "catalog_mgr.h"
40#include "model/downloader.h"
41#include "model/ocpn_utils.h"
42#include "OCPNPlatform.h"
44#include "download_mgr.h"
45
47wxDEFINE_EVENT(CHANNELS_DL_DONE, wxCommandEvent);
48wxDEFINE_EVENT(CHANNELS_PARSE_DONE, wxCommandEvent);
49wxDEFINE_EVENT(CATALOG_DL_DONE, wxCommandEvent);
50wxDEFINE_EVENT(CATALOG_PARSE_DONE, wxCommandEvent);
51
53wxDEFINE_EVENT(CATALOG_DLG_CLOSE, wxCommandEvent);
54
55#ifdef _WIN32
56static const std::string SEP("\\");
57#else
58static const std::string SEP("/");
59#endif
60
61namespace catalog_mgr {
62
63class Helpers {
64public:
65 Helpers(wxWindow* _parent) : parent(_parent) {}
66
67 wxStaticText* staticText(const char* text) {
68 return new wxStaticText(parent, wxID_ANY, text);
69 }
70
71 wxButton* makeButton(const char* label, int id = wxID_ANY) {
72 return new wxButton(parent, wxID_ANY, label);
73 }
74
75private:
76 wxWindow* parent;
77};
78
80class CatalogUpdate : public wxDialog, Helpers {
81protected:
82 struct UrlEdit; // forward
83 struct ActiveCatalogGrid; // forward
84
85public:
86 CatalogUpdate(wxWindow* parent)
87 : wxDialog(parent, wxID_ANY, _("Manage Plugin Catalog"),
88 wxDefaultPosition, wxDefaultSize,
89 wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER | wxSTAY_ON_TOP),
90 Helpers(this),
91 m_show_edit(true) {
92 HIDE = "<span foreground=\'blue\'>";
93 HIDE += _("Hide");
94 HIDE += " &lt;&lt;&lt;</span>";
95 ADVANCED = "<span foreground=\'blue\'>";
96 ADVANCED += _("Ultra advanced");
97 ADVANCED += " &gt;&gt;&gt;</span>";
98
99 auto sizer = new wxBoxSizer(wxVERTICAL);
100 auto flags = wxSizerFlags().Expand().Border();
101
102 m_catalog_grid = new ActiveCatalogGrid(this);
103 sizer->Add(new UrlStatus(this), flags);
104 sizer->Add(new UrlChannel(this, m_catalog_grid), flags);
105 sizer->Add(new wxStaticLine(this), flags);
106
107 sizer->Add(m_catalog_grid, flags);
108 sizer->Add(new wxStaticLine(this), flags);
109
110 m_advanced = new wxStaticText(this, wxID_ANY, "");
111 m_advanced->Bind(wxEVT_LEFT_DOWN,
112 [=](wxMouseEvent& e) { toggleUrlEdit(); });
113 sizer->Add(m_advanced, flags);
114
115 m_url_box = new wxBoxSizer(wxVERTICAL);
116 m_url_edit = new UrlEdit(this);
117 m_url_box->Add(m_url_edit, flags);
118 m_url_box->Add(new Buttons(this, m_catalog_grid),
119 wxSizerFlags().Border().Right());
120 sizer->Add(m_url_box, flags);
121 sizer->Add(new wxStaticLine(this), flags);
122
123 auto done = makeButton(_("Done"));
124 sizer->Add(done, wxSizerFlags().Border().Right());
125 done->Bind(wxEVT_COMMAND_BUTTON_CLICKED, [=](wxCommandEvent e) {
126 EndModal(wxID_OK);
127 wxCommandEvent evt(CATALOG_DLG_CLOSE);
128 wxPostEvent(GetParent(), evt);
129 e.Skip();
130 });
131 toggleUrlEdit();
132
133 Bind(wxEVT_CLOSE_WINDOW, [=](wxCloseEvent& e) {
134 EndModal(wxID_OK);
135 wxCommandEvent cmd_evt(CATALOG_DLG_CLOSE);
136 wxPostEvent(GetParent(), cmd_evt);
137 e.Skip();
138 });
139
140 SetSizer(sizer);
141 auto size = getWindowSize();
142 size.SetHeight(1);
143 SetMinClientSize(size);
144 Fit();
145 ShowModal();
146 }
147
148protected:
149 wxString HIDE, ADVANCED;
150
151 wxBoxSizer* m_url_box;
152 ActiveCatalogGrid* m_catalog_grid;
153 UrlEdit* m_url_edit;
154 wxStaticText* m_advanced;
155 bool m_show_edit;
156
162 wxSize getWindowSize() {
163 auto uri = CatalogHandler::GetInstance()->GetDefaultUrl();
164 auto size = GetTextExtent(uri);
165 size.SetWidth(size.GetWidth() * 120 / 100);
166 size.SetHeight(size.GetHeight() * 130 / 100);
167 return size;
168 }
169
170 void toggleUrlEdit() {
171 m_show_edit = !m_show_edit;
172 m_url_box->GetItem((size_t)0)->GetWindow()->Show(m_show_edit);
173 m_url_box->GetItem((size_t)1)->GetWindow()->Show(m_show_edit);
174 m_advanced->SetLabelMarkup(m_show_edit ? HIDE : ADVANCED);
175 Fit();
176 }
177
179 struct UrlStatus : public wxPanel, public Helpers {
180 UrlStatus(wxWindow* parent) : wxPanel(parent), Helpers(this) {
181 auto sizer = new wxBoxSizer(wxHORIZONTAL);
182 auto flags =
183 wxSizerFlags().Expand().Border().Align(wxALIGN_CENTER_VERTICAL);
184 sizer->Add(staticText(_("Catalog URL status: ")), flags);
185 auto catalog = CatalogHandler::GetInstance();
186 int channels = catalog->GetChannels().size();
187 auto text = staticText(channels > 0 ? _("OK") : _("Error"));
188 sizer->Add(text, flags);
189
190 SetSizer(sizer);
191 Fit();
192 Show();
193 }
194 };
195
200 struct ActiveCatalogGrid : public wxPanel, public Helpers {
201 ActiveCatalogGrid(wxWindow* parent) : wxPanel(parent), Helpers(this) {
202 using CmdEvt = wxCommandEvent;
203
204 auto grid = new wxFlexGridSizer(4, 0, 0);
205 auto plugin_handler = PluginHandler::GetInstance();
206 grid->AddGrowableCol(0);
207 grid->AddGrowableCol(1);
208 grid->AddGrowableCol(2);
209 grid->AddGrowableCol(3);
210 auto flags = wxSizerFlags().Align(wxALIGN_CENTER_VERTICAL);
211 flags = flags.DoubleBorder();
212
213 /* Cell 0..3 */
214 CatalogData catalog_data =
215 CatalogHandler::GetInstance()->UserCatalogData();
216 grid->Add(staticText(_("Current active plugin catalog")), flags);
217 grid->Add(staticText(""), flags);
218 grid->Add(staticText(""), flags);
219 grid->Add(staticText(""), flags);
220
221 /* Cell 4..7 */
222 catalog_data = CatalogHandler::GetInstance()->DefaultCatalogData();
223 grid->Add(staticText(_("Default catalog")), flags);
224 grid->Add(staticText(""), flags);
225 grid->Add(staticText(""), flags);
226 auto use_default = makeButton(_("Use as active catalog"));
227 grid->Add(use_default, wxSizerFlags().Border());
228 use_default->Bind(wxEVT_COMMAND_BUTTON_CLICKED,
229 [=](CmdEvt& e) { useDefaultCatalog(); });
230
231 /* Cell 8..11 */
232 catalog_data = CatalogHandler::GetInstance()->LatestCatalogData();
233 grid->Add(staticText(_("Latest available catalog:")), flags);
234 grid->Add(staticText(""), flags);
235 grid->Add(staticText(""), flags);
236 auto use_latest = makeButton(_("Use as active catalog"));
237 use_latest->Bind(wxEVT_COMMAND_BUTTON_CLICKED,
238 [=](CmdEvt& e) { UseLatestCatalog(); });
239
240 grid->Add(use_latest, wxSizerFlags().Border());
241
242 SetSizer(grid);
244 Fit();
245 Show();
246 }
247
248 void UpdateVersion(wxSizer* grid, CatalogData data, size_t ix) {
249 auto version =
250 dynamic_cast<wxStaticText*>(grid->GetItem(ix)->GetWindow());
251 version->SetLabel(data.version);
252 auto date =
253 dynamic_cast<wxStaticText*>(grid->GetItem(ix + 1)->GetWindow());
254 date->SetLabel(data.date);
255 }
256
262 CatalogData data = CatalogHandler::GetInstance()->UserCatalogData();
263 auto grid = dynamic_cast<wxSizer*>(GetSizer());
264 UpdateVersion(grid, data, 1);
265 data = CatalogHandler::GetInstance()->DefaultCatalogData();
266 UpdateVersion(grid, data, 5);
267 data = CatalogHandler::GetInstance()->LatestCatalogData();
268 UpdateVersion(grid, data, 9);
269 Refresh(true);
270 Update();
271 }
272
273 std::string GetDefaultCatalogPath() {
274 std::string path = g_Platform->GetSharedDataDir().ToStdString();
275 path += SEP;
276 path += "ocpn-plugins.xml";
277 return path;
278 }
279
280 void ReloadAvailableVersion() {
281 auto handler = CatalogHandler::GetInstance();
282 std::ostringstream xml;
283 auto status = handler->DownloadCatalog(&xml);
284 std::string message;
285 if (status != CatalogHandler::ServerStatus::OK) {
286 message = _("Cannot download data from url");
287 }
288 status = handler->ParseCatalog(xml.str(), true);
289 if (status != CatalogHandler::ServerStatus::OK) {
290 message = _("Cannot parse downloaded data");
291 }
292 if (message != "") {
293 wxMessageBox(message, _("Catalog update problem"), wxICON_ERROR);
294 } else {
296 }
297 }
298
299 std::string GetPrivateCatalogPath() {
300 auto plugin_handler = PluginHandler::GetInstance();
301 std::string path = g_Platform->GetPrivateDataDir().ToStdString();
302 path += SEP + "ocpn-plugins.xml";
303 return path;
304 }
305
306 void useDefaultCatalog() {
307 auto src = GetDefaultCatalogPath();
308 auto dest = GetPrivateCatalogPath();
309 ocpn::copy_file(src, dest);
310 CatalogHandler::GetInstance()->ClearCatalogData();
312 }
313
314 void UseLatestCatalog() {
315 auto catalog = CatalogHandler::GetInstance();
316 std::ofstream dest(GetPrivateCatalogPath());
317 catalog->DownloadCatalog(&dest);
318 dest.close();
319 catalog->ClearCatalogData();
321 }
322 };
323
325 struct Buttons : public wxPanel, public Helpers {
326 Buttons(wxWindow* parent, ActiveCatalogGrid* catalog_grid)
327 : wxPanel(parent),
328 Helpers(this),
329 m_catalog_grid(catalog_grid),
330 m_parent(dynamic_cast<CatalogUpdate*>(GetParent())) {
331 auto sizer = new wxBoxSizer(wxHORIZONTAL);
332 auto flags = wxSizerFlags().Right().Bottom().Border();
333
334 auto clear = makeButton(_("Clear"));
335 clear->Bind(wxEVT_COMMAND_BUTTON_CLICKED,
336 [=](wxCommandEvent& ev) { clearUrl(); });
337 sizer->Add(clear, flags);
338
339 auto use_default = makeButton(_("Use default location"));
340 use_default->Bind(wxEVT_COMMAND_BUTTON_CLICKED,
341 [=](wxCommandEvent& ev) { useDefaultUrl(); });
342 sizer->Add(use_default, flags);
343
344 auto update = makeButton(_("Save"));
345 sizer->Add(update, flags);
346 update->Bind(wxEVT_COMMAND_BUTTON_CLICKED,
347 [=](wxCommandEvent& ev) { updateUrl(); });
348
349 SetSizer(sizer);
350 Fit();
351 Show();
352 }
353
354 void useDefaultUrl() {
355 auto url = CatalogHandler::GetInstance()->GetDefaultUrl();
356 m_parent->m_url_edit->setText(url);
357 }
358
359 void clearUrl() { m_parent->m_url_edit->clear(); }
360
361 void updateUrl() {
362 auto text = m_parent->m_url_edit->getText();
363 CatalogHandler::GetInstance()->SetCustomUrl(text.c_str());
364 m_catalog_grid->ReloadAvailableVersion();
365 }
366
367 ActiveCatalogGrid* m_catalog_grid;
368 CatalogUpdate* m_parent;
369 };
370
372 struct UrlChannel : public wxPanel, public Helpers {
373 UrlChannel(wxWindow* parent, ActiveCatalogGrid* catalog_grid)
374 : wxPanel(parent), Helpers(this), m_catalog_grid(catalog_grid) {
375 auto sizer = new wxBoxSizer(wxHORIZONTAL);
376 auto flags =
377 wxSizerFlags().Expand().Border().Align(wxALIGN_CENTER_VERTICAL);
378 sizer->Add(staticText(_("Catalog channel: ")), flags);
379 auto catalog = CatalogHandler::GetInstance();
380 wxArrayString channel_list;
381 for (auto channel : catalog->GetChannels()) {
382 channel_list.Add(channel.c_str());
383 }
384 auto channels = new wxChoice(this, wxID_ANY, wxDefaultPosition,
385 wxDefaultSize, channel_list);
386 auto current = CatalogHandler::GetInstance()->GetActiveChannel();
387 int ix = channels->FindString(current.c_str());
388 channels->SetSelection(ix != wxNOT_FOUND ? ix : 0);
389 channels->Bind(wxEVT_CHOICE,
390 [=](wxCommandEvent& e) { onChannelChange(e); });
391 sizer->Add(channels, flags);
392 SetSizer(sizer);
393 Fit();
394 Show();
395 }
396
397 void onChannelChange(wxCommandEvent& ev) {
398 CatalogHandler::GetInstance()->SetActiveChannel(ev.GetString());
399 m_catalog_grid->ReloadAvailableVersion();
400 };
401
402 std::string m_active_channel;
403 ActiveCatalogGrid* m_catalog_grid;
404 };
405
407 struct UrlEdit : public wxPanel, public Helpers {
408 UrlEdit(wxWindow* parent) : wxPanel(parent), Helpers(this) {
409 auto sizer = new wxBoxSizer(wxVERTICAL);
410 auto url_location = new wxBoxSizer(wxHORIZONTAL);
411 auto flags = wxSizerFlags().Align(wxALIGN_CENTER_VERTICAL);
412 url_location->Add(staticText(_("Custom catalog URL: ")), flags);
413 flags = wxSizerFlags().Expand().Border();
414 sizer->Add(url_location, flags);
415
416 auto url_edit = new wxBoxSizer(wxHORIZONTAL);
417 auto uri = CatalogHandler::GetInstance()->GetCustomUrl();
418 m_url_ctrl = new wxTextCtrl(this, wxID_ANY, uri);
419 auto the_parent = dynamic_cast<CatalogUpdate*>(GetParent());
420 m_url_ctrl->SetMinClientSize(the_parent->getWindowSize());
421 url_edit->Add(m_url_ctrl, wxSizerFlags().Expand());
422
423 sizer->Add(url_edit, flags);
424 SetSizer(sizer);
425 Fit();
426 Show();
427 }
428
429 void setText(std::string text) {
430 m_url_ctrl->Clear();
431 *m_url_ctrl << text;
432 m_url_ctrl->Refresh();
433 }
434
435 void clear() { m_url_ctrl->Clear(); }
436
437 std::string getText() {
438 return std::string(m_url_ctrl->GetLineText(0).ToStdString());
439 }
440
441 wxTextCtrl* m_url_ctrl;
442 };
443};
444
446class CatalogLoad : public wxPanel, public Helpers {
447public:
448 struct DialogGrid; // forward
449
450 CatalogLoad(wxWindow* parent, bool use_latest = false)
451 : wxPanel(parent), Helpers(this), m_simple(use_latest) {
452 auto sizer = new wxBoxSizer(wxVERTICAL);
453 auto flags = wxSizerFlags().Expand().Border();
454 m_grid = new DialogGrid(this);
455 sizer->Add(m_grid, flags);
456 sizer->Add(1, 1, 1, wxEXPAND); // Expanding spacer
457 if (m_simple) {
458 m_buttons = new Buttons(this);
459 sizer->Add(m_buttons, flags.Bottom().Right());
460 }
461 auto size = GetTextExtent(_("Check latest release..."));
462 size.SetHeight(size.GetHeight() * 10);
463 size.SetWidth(size.GetWidth() * 5 / 2);
464 SetMinClientSize(size);
465 std::thread worker([=]() { Worker(); });
466 worker.detach();
467
468 SetSizer(sizer);
469 Fit();
470 Show();
471
472 Bind(CHANNELS_DL_DONE,
473 [=](wxCommandEvent& ev) { m_grid->CellDone(ev, 1); });
474 Bind(CHANNELS_PARSE_DONE,
475 [=](wxCommandEvent& ev) { m_grid->CellDone(ev, 3); });
476 Bind(CATALOG_DL_DONE, [=](wxCommandEvent& ev) { m_grid->CellDone(ev, 5); });
477 Bind(CATALOG_PARSE_DONE, [=](wxCommandEvent& ev) { workerDone(ev); });
478 }
479
480 void PostEvent(int evt_id, catalog_status status, std::string message) {
481 wxCommandEvent evt(evt_id);
482 evt.SetInt(static_cast<int>(status));
483 evt.SetString(message);
484 wxPostEvent(this, evt);
485 }
486
488 void workerDone(wxCommandEvent& ev) {
489 m_grid->CellDone(ev, 5);
490 if (m_simple) {
491 std::string message = _("Catalog updated").ToStdString();
492 std::string path = g_Platform->GetPrivateDataDir().ToStdString();
493 path += SEP;
494 path += "ocpn-plugins.xml";
495 std::ofstream stream;
496 stream.open(path, std::ios::out);
497 if (stream.is_open()) {
498 stream << m_xml.str();
499 stream.close();
500 ev.SetString("Catalog updated");
501 ev.SetInt(static_cast<int>(catalog_status::OK_MSG));
502 } else {
503 ev.SetString("Update error (cannot writé to file)");
504 ev.SetInt(static_cast<int>(catalog_status::OS_ERROR));
505 wxLogMessage("Update error: Cannot write to %s", path.c_str());
506 }
507 m_grid->CellDone(ev, 6);
508 m_buttons->ActivateOk();
509 } else {
510 CatalogData catalog_data;
511 auto handler = CatalogHandler::GetInstance();
512 catalog_data = handler->LatestCatalogData();
513 Hide();
514 Refresh(true);
515 Update();
516 new CatalogUpdate(this);
517 }
518 }
519
521 void Worker() {
522 auto catalog = CatalogHandler::GetInstance();
523 std::ostringstream json;
524
525 auto status = catalog->LoadChannels(&json);
526 PostEvent(CHANNELS_DL_DONE, status, catalog->LastErrorMsg());
527
528 status = catalog->LoadChannels(json.str());
529 PostEvent(CHANNELS_PARSE_DONE, status, catalog->LastErrorMsg());
530
531 if (status == catalog_status::OK) {
532 auto channel = catalog->GetActiveChannel();
533 status = catalog_status::OK_MSG;
534 PostEvent(CHANNELS_PARSE_DONE, status, channel);
535 }
536 m_xml.clear();
537 status = catalog->DownloadCatalog(&m_xml);
538 PostEvent(CATALOG_DL_DONE, status, catalog->LastErrorMsg());
539
540 status = catalog->ParseCatalog(m_xml.str(), true);
541 if (status == catalog_status::OK) {
542 PostEvent(CATALOG_PARSE_DONE, catalog_status::OK_MSG,
543 catalog->LatestCatalogData().version);
544 } else {
545 PostEvent(CATALOG_PARSE_DONE, status, catalog->LastErrorMsg());
546 }
547 }
548
550 struct DialogGrid : public wxPanel, public Helpers {
551 DialogGrid(wxWindow* parent) : wxPanel(parent), Helpers(this) {
552 auto grid = new wxFlexGridSizer(2, 0, 0);
553 auto flags =
554 wxSizerFlags().Expand().Border().Align(wxALIGN_CENTER_VERTICAL);
555 grid->Add(staticText(_("Server is reachable...")), flags);
556 grid->Add(staticText(""), flags);
557 grid->Add(staticText(_("Check channel...")), flags);
558 grid->Add(staticText(""), flags);
559 grid->Add(staticText(_("Check latest release...")), flags);
560 grid->Add(staticText(""), flags);
561 grid->Add(staticText(""), flags);
562 grid->Add(staticText(""), flags);
563 auto url = CatalogHandler::GetInstance()->GetCustomUrl();
564 if (url != "") {
565 grid->Add(staticText(_("Custom URL")), flags);
566 grid->Add(staticText(url.c_str()), flags);
567 }
568 SetSizer(grid);
569 Fit();
570 Show();
571 }
572
573 /* Update status values in grid. */
574 void CellDone(const wxCommandEvent& event, size_t index) {
575 // wxLogMessage("CellDone: event %d", event.GetInt());
576 auto cell = GetSizer()->GetItem(index)->GetWindow();
577 auto code = static_cast<catalog_status>(event.GetInt());
578 if (code == catalog_status::OK) {
579 cell->SetLabel(_("OK"));
580 } else if (code == catalog_status::OK_MSG) {
581 cell->SetLabel(event.GetString().ToStdString());
582 } else {
583 auto msg = std::string(_("Fail: ")) + event.GetString().ToStdString();
584 cell->SetLabel(msg.c_str());
585 }
586 Fit();
587 }
588 };
589
591 struct Buttons : public wxPanel {
592 Buttons(wxWindow* parent) : wxPanel(parent) {
593 using CmdEvt = wxCommandEvent;
594
595 auto sizer = new wxBoxSizer(wxHORIZONTAL);
596 auto flags = wxSizerFlags().Right().Bottom().Border();
597 sizer->Add(1, 1, 100, wxEXPAND); // Expanding spacer
598 auto cancel = new wxButton(this, wxID_CANCEL, _("Cancel"));
599 sizer->Add(cancel, flags);
600 m_ok = new wxButton(this, wxID_OK, _("OK"));
601 m_ok->Enable(false);
602 sizer->Add(m_ok, flags);
603 SetSizer(sizer);
604 Fit();
605 SetFocus();
606 Show();
607 }
608
609 void ActivateOk() { m_ok->Enable(true); }
610
611 wxButton* m_ok;
612 };
613
614 std::ostringstream m_xml;
615 DialogGrid* m_grid;
616 Buttons* m_buttons;
617 const bool m_simple; // Simple means just install, no advanced dialog
618};
619
620} // namespace catalog_mgr
621
624 : wxFrame(parent, wxID_ANY, _("Catalog Manager"), wxDefaultPosition,
625 wxDefaultSize, wxDEFAULT_FRAME_STYLE | wxRESIZE_BORDER) {
626 auto vbox = new wxBoxSizer(wxHORIZONTAL);
627 vbox->Add(new catalog_mgr::CatalogLoad(this, false),
628 wxSizerFlags(1).Expand());
629 Bind(wxEVT_CLOSE_WINDOW, [this](wxCloseEvent&) {
630 wxCommandEvent evt(EVT_PLUGINS_RELOAD);
631 wxPostEvent(GetParent(), evt);
632 Destroy();
633 });
634 Bind(CATALOG_DLG_CLOSE, [this](wxCommandEvent&) {
635 wxCommandEvent evt(EVT_PLUGINS_RELOAD);
636 wxPostEvent(GetParent(), evt);
637 Destroy();
638 });
639 SetSizer(vbox);
640
641 Fit();
642 Center();
643 Raise();
644 SetFocus();
645 Show();
646}
647
649 : wxDialog(parent, wxID_ANY, _("Catalog Manager"), wxDefaultPosition,
650 wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER) {
651 auto vbox = new wxBoxSizer(wxHORIZONTAL);
652 vbox->Add(new catalog_mgr::CatalogLoad(this, true), wxSizerFlags(1).Expand());
653 Bind(wxEVT_CLOSE_WINDOW, [&](wxCloseEvent& e) { EndModal(wxID_OK); });
654 Bind(CATALOG_DLG_CLOSE, [&](wxCommandEvent& ev) { EndModal(wxID_OK); });
655 SetSizer(vbox);
656
657 Fit();
658 ShowModal();
659 Destroy();
660}
Plugin catalog management: Build the runtime catalog, handling downloads as required.
wxDEFINE_EVENT(CHANNELS_DL_DONE, wxCommandEvent)
Posted by Worker() in CatalogLoad, consumed by CatalogLoad::DialogGrid.
Catalog options dialog, by default disabled.
wxString & GetPrivateDataDir()
Return dir path for opencpn.log, etc., respecting -c cli option.
AdvancedCatalogDialog(wxWindow *parent)
Invoke the advanced catalog dialog after a status check.
CatalogData DefaultCatalogData()
Data for default version, installed with main opencpn.
std::string GetDefaultUrl()
Get the default URL, with actual channel included.
CatalogData LatestCatalogData()
Data for latest parsed data marked as latest.
CatalogData UserCatalogData()
Data for user catalog which overrides the default one.
std::string GetActiveChannel()
Get the branch (a.
void SetCustomUrl(const char *url)
Set a custom url, overrides also channel settings.
void ClearCatalogData()
Invalidate *CatalogData caches.
std::string GetCustomUrl()
Get the custom url set by SetCustomUrl.
bool SetActiveChannel(const char *channel)
Set the active channel used when downloading catalog.
static PluginHandler * GetInstance()
Singleton factory.
SimpleCatalogDialog(wxWindow *parent)
Perform a simple catalog update without options.
Download status/progress window, always shown at start-up.
void Worker()
Runs in separate, detached thread, started from ctor.
void workerDone(wxCommandEvent &ev)
Last part of initial Worker() call, in main thread.
The advanced dialog showing channels, possible updates, rollback etc.
wxSize getWindowSize()
The window width is determined by the normally hidden custom url text control.
void copy_file(const std::string &src_path, const std::string &dest_path)
Copy file contents in path src_path to dest_path.
Miscellaneous utilities, many of which string related.
PLugin remote repositories installation and Uninstall/list operations.
Overall metadata for the set of plugins used.
OK/Cancel buttons for the download progress window.
Grid with Server is Reachable..., Check channel... etc.
Active catalog: The current active, the default and latest downloaded + buttons to use default or lat...
void UpdateVersions()
Update version and date for default, latest and active catalog.
The buttons below custom url: Use Default and Update.
Combobox where user selects active catalog channel.
Custom url edit control, a text line.
The Url Status line at top.