OpenCPN Partial API docs
cat_settings.cpp
1 /******************************************************************************
2  *
3  * Project: OpenCPN
4  *
5  ***************************************************************************
6  * Copyright (C) 2019 Alec Leamas *
7  * *
8  * This program is free software; you can redistribute it and/or modify *
9  * it under the terms of the GNU General Public License as published by *
10  * the Free Software Foundation; either version 2 of the License, or *
11  * (at your option) any later version. *
12  * *
13  * This program is distributed in the hope that it will be useful, *
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16  * GNU General Public License for more details. *
17  * *
18  * You should have received a copy of the GNU General Public License *
19  * along with this program; if not, write to the *
20  * Free Software Foundation, Inc., *
21  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
22  ***************************************************************************
23  */
24 
25 #include <map>
26 #include <sstream>
27 #include <string>
28 
29 #include <wx/button.h>
30 #include <wx/choice.h>
31 #include <wx/log.h>
32 #include <wx/sizer.h>
33 #include <wx/stattext.h>
34 #include <wx/textctrl.h>
35 
36 #include "cat_settings.h"
37 #include "observable_globvar.h"
38 #include "model/config_vars.h"
39 #include "model/ocpn_utils.h"
40 #include "model/plugin_cache.h"
41 #include "model/plugin_handler.h"
42 
44 class CustomCatalogCtrl : public wxTextCtrl {
45 public:
46  CustomCatalogCtrl(wxWindow* parent) : wxTextCtrl(parent, wxID_ANY, "") {
47  SetValue(g_catalog_custom_url);
48  Bind(wxEVT_TEXT,
49  [&](wxCommandEvent&) { g_catalog_custom_url = GetValue(); });
50  }
51 };
52 
54 class PlatformChoice : public wxChoice {
55 public:
56  PlatformChoice(wxWindow* parent, wxStaticText* selected)
57  : wxChoice(), m_selected(selected) {
58  Bind(wxEVT_CHOICE, &PlatformChoice::OnChoice, this);
59  Create(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, getLabels());
60  SetSelection(0);
61  Layout();
62  }
63 
64 private:
65  wxStaticText* m_selected;
66 
67  void OnChoice(wxCommandEvent&) {
68  GlobalVar<wxString> compat_os(&g_compatOS);
69  if (GetSelection() == 0) {
70  // "Select new flavour"
71  return;
72  }
73  if (GetSelection() == 1) {
74  // "Default Setting"
75  g_compatOsVersion = "";
76  compat_os.Set("");
77  auto newOS = CompatOs::getInstance();
78  m_selected->SetLabel(newOS->name() + ":" + newOS->version());
79  } else {
80  auto current = GetString(GetSelection());
81  auto os = ocpn::split(current, " ")[0];
82  m_selected->SetLabel(os);
83  compat_os.Set(ocpn::split(os.c_str(), ":")[0]);
84  g_compatOsVersion = ocpn::split(os.c_str(), ":")[1];
85  }
86  }
87 
88  wxArrayString getLabels() {
89  auto plug_handler = PluginHandler::getInstance();
90  wxArrayString labels;
91  labels.Add(_("Select new flavour"));
92  labels.Add(_("Default setting"));
93  for (const auto& c : plug_handler->getCountByTarget()) {
94  std::stringstream ss;
95  ss << c.first << " (" << c.second << ")";
96  labels.Add(ss.str());
97  }
98  return labels;
99  }
100 };
101 
103 class CatalogChoice : public wxChoice {
104 public:
105  CatalogChoice(wxWindow* parent, wxTextCtrl* custom_ctrl)
106  : wxChoice(), m_custom_ctrl(custom_ctrl) {
107  static const std::vector<std::string> labels(
108  {"master", "Beta", "Alpha", "custom"});
109  wxArrayString wxLabels;
110  for (const auto& l : labels) wxLabels.Add(l);
111  Create(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLabels);
112 
113 #ifdef __OCPN__ANDROID__
114  SetMinSize(wxSize(12 * GetCharWidth(), -1));
115 #endif
116 
117  m_custom_ctrl->Enable(false);
118  for (auto l = labels.begin(); l != labels.end(); l++) {
119  if (g_catalog_channel == *l) {
120  SetSelection(l - labels.begin());
121  }
122  }
123  wxCommandEvent ev;
124  OnChoice(ev);
125  Layout();
126  Bind(wxEVT_CHOICE, &CatalogChoice::OnChoice, this);
127  }
128 
129 private:
130  wxTextCtrl* m_custom_ctrl;
131 
132  void OnChoice(wxCommandEvent&) {
133  auto selected = GetString(GetSelection());
134  m_custom_ctrl->Enable(selected == "custom");
135  if (selected == "custom") {
136  m_custom_ctrl->Show();
137  GetParent()->Layout();
138  m_custom_ctrl->SetFocus();
139  g_catalog_custom_url = m_custom_ctrl->GetValue();
140  } else {
141  m_custom_ctrl->Hide();
142  }
143  GlobalVar<wxString> catalog(&g_catalog_channel);
144  catalog.Set(selected);
145  Layout();
146  }
147 };
148 
150 class CompatText : public wxStaticText {
151 public:
152  CompatText(wxWindow* parent) : wxStaticText(parent, wxID_ANY, "") {
153  auto compatOs = CompatOs::getInstance();
154  SetLabel(compatOs->name() + ":" + compatOs->version());
155  }
156 };
157 
159 class CatalogSizer : public wxStaticBoxSizer {
160 public:
161  CatalogSizer(wxWindow* parent)
162  : wxStaticBoxSizer(wxHORIZONTAL, parent, _("Active catalog")) {
163  auto flags = wxSizerFlags().Border(wxALL, parent->GetCharWidth());
164  Add(new wxStaticText(parent, wxID_ANY, _("Select plugin catalog")), flags);
165  auto custom_ctrl = new CustomCatalogCtrl(parent);
166  Add(new CatalogChoice(parent, custom_ctrl), flags);
167  Add(custom_ctrl, flags.Expand().Proportion(1));
168  Layout();
169  }
170 };
171 
173 class CompatSizer : public wxStaticBoxSizer {
174 public:
175  CompatSizer(wxWindow* parent)
176  : wxStaticBoxSizer(wxHORIZONTAL, parent, _("Compatibility")) {
177  auto flags = wxSizerFlags().Border();
178  Add(new wxStaticText(parent, wxID_ANY, _("Active setting:")),
179  flags.Center());
180  auto status_text = new CompatText(parent);
181  Add(status_text, flags.Center().Proportion(1));
182  Add(new PlatformChoice(parent, status_text), flags);
183  }
184 };
185 
186 /* Cache panel, size feedback and clear button. */
187 class CacheSizer : public wxStaticBoxSizer {
188 public:
189  CacheSizer(wxWindow* parent)
190  : wxStaticBoxSizer(wxHORIZONTAL, parent, _("Cache")) {
191  using CmdEvt = wxCommandEvent;
192 
193  auto flags = wxSizerFlags().Border();
194  m_label = new wxStaticText(parent, wxID_ANY, "");
195  update_label();
196  Add(m_label, flags.Center().Proportion(1));
197 
198  Add(1, 1, 1, wxEXPAND); // Expanding spacer
199  m_clear_button = new wxButton(parent, wxID_ANY, _("Clear cache"));
200  Add(m_clear_button, flags);
201  m_clear_button->Bind(wxEVT_COMMAND_BUTTON_CLICKED,
202  [=](CmdEvt& e) { on_clear_btn_clicked(); });
203  }
204 
205 private:
206  wxButton* m_clear_button;
207  wxStaticText* m_label;
208 
209  void on_clear_btn_clicked() {
211  update_label();
212  }
213 
214  void update_label() {
215  char buf[128];
216  snprintf(buf, sizeof(buf), _("Size: %d MB in %d files"), ocpn::cache_size(),
218  m_label->SetLabel(buf);
219  }
220 };
221 
223 class ButtonsSizer : public wxStdDialogButtonSizer {
224 public:
225  ButtonsSizer(wxWindow* parent) : wxStdDialogButtonSizer() {
226  auto button = new wxButton(parent, wxID_OK, "LongLabel", wxDefaultPosition,
227  wxSize(10 * parent->GetCharWidth(), -1));
228  button->SetLabel(_("Done"));
229  SetAffirmativeButton(button);
230  Realize();
231  }
232 };
233 
236  : wxDialog(parent, wxID_ANY, _("Plugin Catalog Settings"),
237  wxDefaultPosition, wxDefaultSize,
238  wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER) {
239 #ifdef __OCPN__ANDROID__
240  SetBackgroundColour(wxColour(0x7c, 0xb0, 0xe9)); // light blue
241 #endif
242  auto vbox = new wxBoxSizer(wxVERTICAL);
243 
244  vbox->Add(new CatalogSizer(this), wxSizerFlags().Expand().DoubleBorder());
245 #ifndef __OCPN__ANDROID__
246  vbox->Add(new CompatSizer(this), wxSizerFlags().Expand().DoubleBorder());
247 #endif
248  vbox->Add(new CacheSizer(this), wxSizerFlags().Expand().DoubleBorder());
249  vbox->Add(new ButtonsSizer(this), wxSizerFlags().Expand().DoubleBorder());
250 
251  SetSizer(vbox);
252  Fit();
253  Layout();
254  SetMinSize(GetSize());
255 }
The Done button.
Select master, beta, alpha, custom drop-down.
CatalogSettingsDialog(wxWindow *parent)
Top-level plugin settings dialog.
Catalog channel selection panel.
Plugin compatibility panel.
Current selected compatibility.
The custom URL text entry.
Wrapper for global variable, supports notification events when value changes.
Select compatibility drop-down.
void cache_clear()
Remove all files in cache:
unsigned cache_file_count()
Return number of files in cache.
unsigned long cache_size()
Return total size of files in cache in kbytes.