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 "gl_headers.h" // Must come before anything using GL stuff
29
30#include <wx/button.h>
31#include <wx/debug.h>
32#include <wx/filename.h>
33#include <wx/log.h>
34#include <wx/msgdlg.h>
35#include <wx/panel.h>
36#include <wx/progdlg.h>
37#include <wx/sizer.h>
38#include <wx/statline.h>
39
41#include "catalog_mgr.h"
42#include "model/downloader.h"
43#include "model/ocpn_utils.h"
44#include "ocpn_platform.h"
46#include "download_mgr.h"
47
49wxDEFINE_EVENT(CHANNELS_DL_DONE, wxCommandEvent);
50wxDEFINE_EVENT(CHANNELS_PARSE_DONE, wxCommandEvent);
51wxDEFINE_EVENT(CATALOG_DL_DONE, wxCommandEvent);
52wxDEFINE_EVENT(CATALOG_PARSE_DONE, wxCommandEvent);
53
55wxDEFINE_EVENT(CATALOG_DLG_CLOSE, wxCommandEvent);
56
57#ifdef _WIN32
58static const std::string SEP("\\");
59#else
60static const std::string SEP("/");
61#endif
62
63namespace catalog_mgr {
64
65class Helpers {
66public:
67 Helpers(wxWindow* _parent) : parent(_parent) {}
68
69 wxStaticText* staticText(const char* text) {
70 return new wxStaticText(parent, wxID_ANY, text);
71 }
72
73 wxButton* makeButton(const char* label, int id = wxID_ANY) {
74 return new wxButton(parent, wxID_ANY, label);
75 }
76
77private:
78 wxWindow* parent;
79};
80
82class CatalogUpdate : public wxDialog, Helpers {
83protected:
84 struct UrlEdit; // forward
85 struct ActiveCatalogGrid; // forward
86
87public:
88 CatalogUpdate(wxWindow* parent)
89 : wxDialog(parent, wxID_ANY, _("Manage Plugin Catalog"),
90 wxDefaultPosition, wxDefaultSize,
91 wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER | wxSTAY_ON_TOP),
92 Helpers(this),
93 m_show_edit(true) {
94 HIDE = "<span foreground=\'blue\'>";
95 HIDE += _("Hide");
96 HIDE += " &lt;&lt;&lt;</span>";
97 ADVANCED = "<span foreground=\'blue\'>";
98 ADVANCED += _("Ultra advanced");
99 ADVANCED += " &gt;&gt;&gt;</span>";
100
101 auto sizer = new wxBoxSizer(wxVERTICAL);
102 auto flags = wxSizerFlags().Expand().Border();
103
104 m_catalog_grid = new ActiveCatalogGrid(this);
105 sizer->Add(new UrlStatus(this), flags);
106 sizer->Add(new UrlChannel(this, m_catalog_grid), flags);
107 sizer->Add(new wxStaticLine(this), flags);
108
109 sizer->Add(m_catalog_grid, flags);
110 sizer->Add(new wxStaticLine(this), flags);
111
112 m_advanced = new wxStaticText(this, wxID_ANY, "");
113 m_advanced->Bind(wxEVT_LEFT_DOWN,
114 [=](wxMouseEvent& e) { toggleUrlEdit(); });
115 sizer->Add(m_advanced, flags);
116
117 m_url_box = new wxBoxSizer(wxVERTICAL);
118 m_url_edit = new UrlEdit(this);
119 m_url_box->Add(m_url_edit, flags);
120 m_url_box->Add(new Buttons(this, m_catalog_grid),
121 wxSizerFlags().Border().Right());
122 sizer->Add(m_url_box, flags);
123 sizer->Add(new wxStaticLine(this), flags);
124
125 auto done = makeButton(_("Done"));
126 sizer->Add(done, wxSizerFlags().Border().Right());
127 done->Bind(wxEVT_COMMAND_BUTTON_CLICKED, [=](wxCommandEvent e) {
128 EndModal(wxID_OK);
129 wxCommandEvent evt(CATALOG_DLG_CLOSE);
130 wxPostEvent(GetParent(), evt);
131 e.Skip();
132 });
133 toggleUrlEdit();
134
135 Bind(wxEVT_CLOSE_WINDOW, [=](wxCloseEvent& e) {
136 EndModal(wxID_OK);
137 wxCommandEvent cmd_evt(CATALOG_DLG_CLOSE);
138 wxPostEvent(GetParent(), cmd_evt);
139 e.Skip();
140 });
141
142 SetSizer(sizer);
143 auto size = getWindowSize();
144 size.SetHeight(1);
145 SetMinClientSize(size);
146 Fit();
147 ShowModal();
148 }
149
150protected:
151 wxString HIDE, ADVANCED;
152
153 wxBoxSizer* m_url_box;
154 ActiveCatalogGrid* m_catalog_grid;
155 UrlEdit* m_url_edit;
156 wxStaticText* m_advanced;
157 bool m_show_edit;
158
164 wxSize getWindowSize() {
165 auto uri = CatalogHandler::GetInstance()->GetDefaultUrl();
166 auto size = GetTextExtent(uri);
167 size.SetWidth(size.GetWidth() * 120 / 100);
168 size.SetHeight(size.GetHeight() * 130 / 100);
169 return size;
170 }
171
172 void toggleUrlEdit() {
173 m_show_edit = !m_show_edit;
174 m_url_box->GetItem((size_t)0)->GetWindow()->Show(m_show_edit);
175 m_url_box->GetItem((size_t)1)->GetWindow()->Show(m_show_edit);
176 m_advanced->SetLabelMarkup(m_show_edit ? HIDE : ADVANCED);
177 Fit();
178 }
179
181 struct UrlStatus : public wxPanel, public Helpers {
182 UrlStatus(wxWindow* parent) : wxPanel(parent), Helpers(this) {
183 auto sizer = new wxBoxSizer(wxHORIZONTAL);
184 auto flags =
185 wxSizerFlags().Expand().Border().Align(wxALIGN_CENTER_VERTICAL);
186 sizer->Add(staticText(_("Catalog URL status: ")), flags);
187 auto catalog = CatalogHandler::GetInstance();
188 int channels = catalog->GetChannels().size();
189 auto text = staticText(channels > 0 ? _("OK") : _("Error"));
190 sizer->Add(text, flags);
191
192 SetSizer(sizer);
193 Fit();
194 Show();
195 }
196 };
197
202 struct ActiveCatalogGrid : public wxPanel, public Helpers {
203 ActiveCatalogGrid(wxWindow* parent) : wxPanel(parent), Helpers(this) {
204 using CmdEvt = wxCommandEvent;
205
206 auto grid = new wxFlexGridSizer(4, 0, 0);
207 auto plugin_handler = PluginHandler::GetInstance();
208 grid->AddGrowableCol(0);
209 grid->AddGrowableCol(1);
210 grid->AddGrowableCol(2);
211 grid->AddGrowableCol(3);
212 auto flags = wxSizerFlags().Align(wxALIGN_CENTER_VERTICAL);
213 flags = flags.DoubleBorder();
214
215 /* Cell 0..3 */
216 CatalogData catalog_data =
217 CatalogHandler::GetInstance()->UserCatalogData();
218 grid->Add(staticText(_("Current active plugin catalog")), flags);
219 grid->Add(staticText(""), flags);
220 grid->Add(staticText(""), flags);
221 grid->Add(staticText(""), flags);
222
223 /* Cell 4..7 */
224 catalog_data = CatalogHandler::GetInstance()->DefaultCatalogData();
225 grid->Add(staticText(_("Default catalog")), flags);
226 grid->Add(staticText(""), flags);
227 grid->Add(staticText(""), flags);
228 auto use_default = makeButton(_("Use as active catalog"));
229 grid->Add(use_default, wxSizerFlags().Border());
230 use_default->Bind(wxEVT_COMMAND_BUTTON_CLICKED,
231 [=](CmdEvt& e) { useDefaultCatalog(); });
232
233 /* Cell 8..11 */
234 catalog_data = CatalogHandler::GetInstance()->LatestCatalogData();
235 grid->Add(staticText(_("Latest available catalog:")), flags);
236 grid->Add(staticText(""), flags);
237 grid->Add(staticText(""), flags);
238 auto use_latest = makeButton(_("Use as active catalog"));
239 use_latest->Bind(wxEVT_COMMAND_BUTTON_CLICKED,
240 [=](CmdEvt& e) { UseLatestCatalog(); });
241
242 grid->Add(use_latest, wxSizerFlags().Border());
243
244 SetSizer(grid);
246 Fit();
247 Show();
248 }
249
250 void UpdateVersion(wxSizer* grid, CatalogData data, size_t ix) {
251 auto version =
252 dynamic_cast<wxStaticText*>(grid->GetItem(ix)->GetWindow());
253 version->SetLabel(data.version);
254 auto date =
255 dynamic_cast<wxStaticText*>(grid->GetItem(ix + 1)->GetWindow());
256 date->SetLabel(data.date);
257 }
258
264 CatalogData data = CatalogHandler::GetInstance()->UserCatalogData();
265 auto grid = dynamic_cast<wxSizer*>(GetSizer());
266 UpdateVersion(grid, data, 1);
267 data = CatalogHandler::GetInstance()->DefaultCatalogData();
268 UpdateVersion(grid, data, 5);
269 data = CatalogHandler::GetInstance()->LatestCatalogData();
270 UpdateVersion(grid, data, 9);
271 Refresh(true);
272 Update();
273 }
274
275 std::string GetDefaultCatalogPath() {
276 std::string path = g_Platform->GetSharedDataDir().ToStdString();
277 path += SEP;
278 path += "ocpn-plugins.xml";
279 return path;
280 }
281
282 void ReloadAvailableVersion() {
283 auto handler = CatalogHandler::GetInstance();
284 std::ostringstream xml;
285 auto status = handler->DownloadCatalog(&xml);
286 std::string message;
287 if (status != CatalogHandler::ServerStatus::OK) {
288 message = _("Cannot download data from url");
289 }
290 status = handler->ParseCatalog(xml.str(), true);
291 if (status != CatalogHandler::ServerStatus::OK) {
292 message = _("Cannot parse downloaded data");
293 }
294 if (message != "") {
295 wxMessageBox(message, _("Catalog update problem"), wxICON_ERROR);
296 } else {
298 }
299 }
300
301 std::string GetPrivateCatalogPath() {
302 auto plugin_handler = PluginHandler::GetInstance();
303 std::string path = g_Platform->GetPrivateDataDir().ToStdString();
304 path += SEP + "ocpn-plugins.xml";
305 return path;
306 }
307
308 void useDefaultCatalog() {
309 auto src = GetDefaultCatalogPath();
310 auto dest = GetPrivateCatalogPath();
311 ocpn::copy_file(src, dest);
312 CatalogHandler::GetInstance()->ClearCatalogData();
314 }
315
316 void UseLatestCatalog() {
317 auto catalog = CatalogHandler::GetInstance();
318 std::ofstream dest(GetPrivateCatalogPath());
319 catalog->DownloadCatalog(&dest);
320 dest.close();
321 catalog->ClearCatalogData();
323 }
324 };
325
327 struct Buttons : public wxPanel, public Helpers {
328 Buttons(wxWindow* parent, ActiveCatalogGrid* catalog_grid)
329 : wxPanel(parent),
330 Helpers(this),
331 m_catalog_grid(catalog_grid),
332 m_parent(dynamic_cast<CatalogUpdate*>(GetParent())) {
333 auto sizer = new wxBoxSizer(wxHORIZONTAL);
334 auto flags = wxSizerFlags().Right().Bottom().Border();
335
336 auto clear = makeButton(_("Clear"));
337 clear->Bind(wxEVT_COMMAND_BUTTON_CLICKED,
338 [=](wxCommandEvent& ev) { clearUrl(); });
339 sizer->Add(clear, flags);
340
341 auto use_default = makeButton(_("Use default location"));
342 use_default->Bind(wxEVT_COMMAND_BUTTON_CLICKED,
343 [=](wxCommandEvent& ev) { useDefaultUrl(); });
344 sizer->Add(use_default, flags);
345
346 auto update = makeButton(_("Save"));
347 sizer->Add(update, flags);
348 update->Bind(wxEVT_COMMAND_BUTTON_CLICKED,
349 [=](wxCommandEvent& ev) { updateUrl(); });
350
351 SetSizer(sizer);
352 Fit();
353 Show();
354 }
355
356 void useDefaultUrl() {
357 auto url = CatalogHandler::GetInstance()->GetDefaultUrl();
358 m_parent->m_url_edit->setText(url);
359 }
360
361 void clearUrl() { m_parent->m_url_edit->clear(); }
362
363 void updateUrl() {
364 auto text = m_parent->m_url_edit->getText();
365 CatalogHandler::GetInstance()->SetCustomUrl(text.c_str());
366 m_catalog_grid->ReloadAvailableVersion();
367 }
368
369 ActiveCatalogGrid* m_catalog_grid;
370 CatalogUpdate* m_parent;
371 };
372
374 struct UrlChannel : public wxPanel, public Helpers {
375 UrlChannel(wxWindow* parent, ActiveCatalogGrid* catalog_grid)
376 : wxPanel(parent), Helpers(this), m_catalog_grid(catalog_grid) {
377 auto sizer = new wxBoxSizer(wxHORIZONTAL);
378 auto flags =
379 wxSizerFlags().Expand().Border().Align(wxALIGN_CENTER_VERTICAL);
380 sizer->Add(staticText(_("Catalog channel: ")), flags);
381 auto catalog = CatalogHandler::GetInstance();
382 wxArrayString channel_list;
383 for (auto channel : catalog->GetChannels()) {
384 channel_list.Add(channel.c_str());
385 }
386 auto channels = new wxChoice(this, wxID_ANY, wxDefaultPosition,
387 wxDefaultSize, channel_list);
388 auto current = CatalogHandler::GetInstance()->GetActiveChannel();
389 int ix = channels->FindString(current.c_str());
390 channels->SetSelection(ix != wxNOT_FOUND ? ix : 0);
391 channels->Bind(wxEVT_CHOICE,
392 [=](wxCommandEvent& e) { onChannelChange(e); });
393 sizer->Add(channels, flags);
394 SetSizer(sizer);
395 Fit();
396 Show();
397 }
398
399 void onChannelChange(wxCommandEvent& ev) {
400 CatalogHandler::GetInstance()->SetActiveChannel(ev.GetString());
401 m_catalog_grid->ReloadAvailableVersion();
402 };
403
404 std::string m_active_channel;
405 ActiveCatalogGrid* m_catalog_grid;
406 };
407
409 struct UrlEdit : public wxPanel, public Helpers {
410 UrlEdit(wxWindow* parent) : wxPanel(parent), Helpers(this) {
411 auto sizer = new wxBoxSizer(wxVERTICAL);
412 auto url_location = new wxBoxSizer(wxHORIZONTAL);
413 auto flags = wxSizerFlags().Align(wxALIGN_CENTER_VERTICAL);
414 url_location->Add(staticText(_("Custom catalog URL: ")), flags);
415 flags = wxSizerFlags().Expand().Border();
416 sizer->Add(url_location, flags);
417
418 auto url_edit = new wxBoxSizer(wxHORIZONTAL);
419 auto uri = CatalogHandler::GetInstance()->GetCustomUrl();
420 m_url_ctrl = new wxTextCtrl(this, wxID_ANY, uri);
421 auto the_parent = dynamic_cast<CatalogUpdate*>(GetParent());
422 m_url_ctrl->SetMinClientSize(the_parent->getWindowSize());
423 url_edit->Add(m_url_ctrl, wxSizerFlags().Expand());
424
425 sizer->Add(url_edit, flags);
426 SetSizer(sizer);
427 Fit();
428 Show();
429 }
430
431 void setText(std::string text) {
432 m_url_ctrl->Clear();
433 *m_url_ctrl << text;
434 m_url_ctrl->Refresh();
435 }
436
437 void clear() { m_url_ctrl->Clear(); }
438
439 std::string getText() {
440 return std::string(m_url_ctrl->GetLineText(0).ToStdString());
441 }
442
443 wxTextCtrl* m_url_ctrl;
444 };
445};
446
448class CatalogLoad : public wxPanel, public Helpers {
449public:
450 struct DialogGrid; // forward
451
452 CatalogLoad(wxWindow* parent, bool use_latest = false)
453 : wxPanel(parent), Helpers(this), m_simple(use_latest) {
454 auto sizer = new wxBoxSizer(wxVERTICAL);
455 auto flags = wxSizerFlags().Expand().Border();
456 m_grid = new DialogGrid(this);
457 sizer->Add(m_grid, flags);
458 sizer->Add(1, 1, 1, wxEXPAND); // Expanding spacer
459 if (m_simple) {
460 m_buttons = new Buttons(this);
461 sizer->Add(m_buttons, flags.Bottom().Right());
462 }
463 auto size = GetTextExtent(_("Check latest release..."));
464 size.SetHeight(size.GetHeight() * 10);
465 size.SetWidth(size.GetWidth() * 5 / 2);
466 SetMinClientSize(size);
467 std::thread worker([=]() { Worker(); });
468 worker.detach();
469
470 SetSizer(sizer);
471 Fit();
472 Show();
473
474 Bind(CHANNELS_DL_DONE,
475 [=](wxCommandEvent& ev) { m_grid->CellDone(ev, 1); });
476 Bind(CHANNELS_PARSE_DONE,
477 [=](wxCommandEvent& ev) { m_grid->CellDone(ev, 3); });
478 Bind(CATALOG_DL_DONE, [=](wxCommandEvent& ev) { m_grid->CellDone(ev, 5); });
479 Bind(CATALOG_PARSE_DONE, [=](wxCommandEvent& ev) { workerDone(ev); });
480 }
481
482 void PostEvent(int evt_id, catalog_status status, std::string message) {
483 wxCommandEvent evt(evt_id);
484 evt.SetInt(static_cast<int>(status));
485 evt.SetString(message);
486 wxPostEvent(this, evt);
487 }
488
490 void workerDone(wxCommandEvent& ev) {
491 m_grid->CellDone(ev, 5);
492 if (m_simple) {
493 std::string message = _("Catalog updated").ToStdString();
494 std::string path = g_Platform->GetPrivateDataDir().ToStdString();
495 path += SEP;
496 path += "ocpn-plugins.xml";
497 std::ofstream stream;
498 stream.open(path, std::ios::out);
499 if (stream.is_open()) {
500 stream << m_xml.str();
501 stream.close();
502 ev.SetString("Catalog updated");
503 ev.SetInt(static_cast<int>(catalog_status::OK_MSG));
504 } else {
505 ev.SetString("Update error (cannot writé to file)");
506 ev.SetInt(static_cast<int>(catalog_status::OS_ERROR));
507 wxLogMessage("Update error: Cannot write to %s", path.c_str());
508 }
509 m_grid->CellDone(ev, 6);
510 m_buttons->ActivateOk();
511 } else {
512 CatalogData catalog_data;
513 auto handler = CatalogHandler::GetInstance();
514 catalog_data = handler->LatestCatalogData();
515 Hide();
516 Refresh(true);
517 Update();
518 new CatalogUpdate(this);
519 }
520 }
521
523 void Worker() {
524 auto catalog = CatalogHandler::GetInstance();
525 std::ostringstream json;
526
527 auto status = catalog->LoadChannels(&json);
528 PostEvent(CHANNELS_DL_DONE, status, catalog->LastErrorMsg());
529
530 status = catalog->LoadChannels(json.str());
531 PostEvent(CHANNELS_PARSE_DONE, status, catalog->LastErrorMsg());
532
533 if (status == catalog_status::OK) {
534 auto channel = catalog->GetActiveChannel();
535 status = catalog_status::OK_MSG;
536 PostEvent(CHANNELS_PARSE_DONE, status, channel);
537 }
538 m_xml.clear();
539 status = catalog->DownloadCatalog(&m_xml);
540 PostEvent(CATALOG_DL_DONE, status, catalog->LastErrorMsg());
541
542 status = catalog->ParseCatalog(m_xml.str(), true);
543 if (status == catalog_status::OK) {
544 PostEvent(CATALOG_PARSE_DONE, catalog_status::OK_MSG,
545 catalog->LatestCatalogData().version);
546 } else {
547 PostEvent(CATALOG_PARSE_DONE, status, catalog->LastErrorMsg());
548 }
549 }
550
552 struct DialogGrid : public wxPanel, public Helpers {
553 DialogGrid(wxWindow* parent) : wxPanel(parent), Helpers(this) {
554 auto grid = new wxFlexGridSizer(2, 0, 0);
555 auto flags =
556 wxSizerFlags().Expand().Border().Align(wxALIGN_CENTER_VERTICAL);
557 grid->Add(staticText(_("Server is reachable...")), flags);
558 grid->Add(staticText(""), flags);
559 grid->Add(staticText(_("Check channel...")), flags);
560 grid->Add(staticText(""), flags);
561 grid->Add(staticText(_("Check latest release...")), flags);
562 grid->Add(staticText(""), flags);
563 grid->Add(staticText(""), flags);
564 grid->Add(staticText(""), flags);
565 auto url = CatalogHandler::GetInstance()->GetCustomUrl();
566 if (url != "") {
567 grid->Add(staticText(_("Custom URL")), flags);
568 grid->Add(staticText(url.c_str()), flags);
569 }
570 SetSizer(grid);
571 Fit();
572 Show();
573 }
574
575 /* Update status values in grid. */
576 void CellDone(const wxCommandEvent& event, size_t index) {
577 // wxLogMessage("CellDone: event %d", event.GetInt());
578 auto cell = GetSizer()->GetItem(index)->GetWindow();
579 auto code = static_cast<catalog_status>(event.GetInt());
580 if (code == catalog_status::OK) {
581 cell->SetLabel(_("OK"));
582 } else if (code == catalog_status::OK_MSG) {
583 cell->SetLabel(event.GetString().ToStdString());
584 } else {
585 auto msg = std::string(_("Fail: ")) + event.GetString().ToStdString();
586 cell->SetLabel(msg.c_str());
587 }
588 Fit();
589 }
590 };
591
593 struct Buttons : public wxPanel {
594 Buttons(wxWindow* parent) : wxPanel(parent) {
595 using CmdEvt = wxCommandEvent;
596
597 auto sizer = new wxBoxSizer(wxHORIZONTAL);
598 auto flags = wxSizerFlags().Right().Bottom().Border();
599 sizer->Add(1, 1, 100, wxEXPAND); // Expanding spacer
600 auto cancel = new wxButton(this, wxID_CANCEL, _("Cancel"));
601 sizer->Add(cancel, flags);
602 m_ok = new wxButton(this, wxID_OK, _("OK"));
603 m_ok->Enable(false);
604 sizer->Add(m_ok, flags);
605 SetSizer(sizer);
606 Fit();
607 SetFocus();
608 Show();
609 }
610
611 void ActivateOk() { m_ok->Enable(true); }
612
613 wxButton* m_ok;
614 };
615
616 std::ostringstream m_xml;
617 DialogGrid* m_grid;
618 Buttons* m_buttons;
619 const bool m_simple; // Simple means just install, no advanced dialog
620};
621
622} // namespace catalog_mgr
623
626 : wxFrame(parent, wxID_ANY, _("Catalog Manager"), wxDefaultPosition,
627 wxDefaultSize, wxDEFAULT_FRAME_STYLE | wxRESIZE_BORDER) {
628 auto vbox = new wxBoxSizer(wxHORIZONTAL);
629 vbox->Add(new catalog_mgr::CatalogLoad(this, false),
630 wxSizerFlags(1).Expand());
631 Bind(wxEVT_CLOSE_WINDOW, [this](wxCloseEvent&) {
632 wxCommandEvent evt(EVT_PLUGINS_RELOAD);
633 wxPostEvent(GetParent(), evt);
634 Destroy();
635 });
636 Bind(CATALOG_DLG_CLOSE, [this](wxCommandEvent&) {
637 wxCommandEvent evt(EVT_PLUGINS_RELOAD);
638 wxPostEvent(GetParent(), evt);
639 Destroy();
640 });
641 SetSizer(vbox);
642
643 Fit();
644 Center();
645 Raise();
646 SetFocus();
647 Show();
648}
649
651 : wxDialog(parent, wxID_ANY, _("Catalog Manager"), wxDefaultPosition,
652 wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER) {
653 auto vbox = new wxBoxSizer(wxHORIZONTAL);
654 vbox->Add(new catalog_mgr::CatalogLoad(this, true), wxSizerFlags(1).Expand());
655 Bind(wxEVT_CLOSE_WINDOW, [&](wxCloseEvent& e) { EndModal(wxID_OK); });
656 Bind(CATALOG_DLG_CLOSE, [&](wxCommandEvent& ev) { EndModal(wxID_OK); });
657 SetSizer(vbox);
658
659 Fit();
660 ShowModal();
661 Destroy();
662}
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.
Generic GUI downloads tool.
Handle downloading of files from remote urls.
Platform independent GL includes.
void copy_file(const std::string &src_path, const std::string &dest_path)
Copy file contents in path src_path to dest_path.
OpenCPN Platform specific support utilities.
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.