37#include <wx/progdlg.h>
39#include <wx/statline.h>
40#include <wx/textwrapper.h>
44#include "libgui/expand_icon.h"
59#include "androidUTIL.h"
69 Wrap(win, text, widthMax);
71 wxString
const& GetWrapped()
const {
return m_wrapped; }
72 int const GetLineCount()
const {
return m_lineCount; }
75 virtual void OnOutputLine(
const wxString& line) { m_wrapped += line; }
76 virtual void OnNewLine() {
90static ssize_t PlugInIxByName(
const std::string name,
91 const ArrayOfPlugIns* plugins) {
92 for (
unsigned i = 0; i < plugins->GetCount(); i += 1) {
93 if (name == plugins->Item(i)->m_common_name.Lower().ToStdString()) {
102 const ArrayOfPlugIns* plugins) {
103 auto ix = PlugInIxByName(name, plugins);
104 return ix == -1 ? 0 : plugins->Item(ix);
116 : wxPanel(parent), m_plugin_name(plugin_name) {
117 auto size = GetClientSize();
118 auto minsize = GetTextExtent(
"OpenCPN");
119 SetMinClientSize(wxSize(minsize.GetWidth(), size.GetHeight()));
121 Bind(wxEVT_PAINT, &PluginIconPanel::OnPaint,
this);
124 void OnPaint(wxPaintEvent&) {
125 auto size = GetClientSize();
126 int minsize = wxMin(size.GetHeight(), size.GetWidth());
127 auto offset = minsize / 10;
129 LoadIcon(
"packageBox.svg", m_bitmap, 2 * minsize / 3);
131 if (!m_bitmap.IsOk()) {
132 wxLogMessage(
"AddPluginPanel: bitmap is not OK!");
135 dc.DrawBitmap(m_bitmap, offset, offset,
true);
140 const std::string m_plugin_name;
142 void LoadIcon(
const char* plugin_name, wxBitmap& bitmap,
int size = 32) {
143 wxFileName path(g_Platform->GetSharedDataDir(), plugin_name);
144 path.AppendDir(
"uidata");
145 path.AppendDir(
"traditional");
148 if (path.IsFileReadable()) {
149 bitmap =
LoadSVG(path.GetFullPath(), size, size);
154 auto style = g_StyleManager->GetCurrentStyle();
155 bitmap = wxBitmap(style->GetIcon(
"default_pi", size, size));
156 wxLogMessage(
"Icon: %s not found.", path.GetFullPath());
165 : wxPanel(parent), m_metadata(metadata) {
166 auto loader = PluginLoader::GetInstance();
168 PlugInByName(metadata.name, loader->GetPlugInArray());
169 std::string label(_(
"Install"));
171 ((found->m_version_major > 0) || (found->m_version_minor > 0))) {
172 label = getUpdateLabel(found, metadata);
174 auto button =
new wxButton(
this, wxID_ANY, label);
175 auto box =
new wxBoxSizer(wxHORIZONTAL);
178 Bind(wxEVT_COMMAND_BUTTON_CLICKED, &InstallButton::OnClick,
this);
181 void OnClick(wxCommandEvent&) {
182 wxLogMessage(
"Selected update: %s", m_metadata.name.c_str());
183 auto top_parent = GetParent()->GetParent()->GetParent();
185 wxASSERT(dialog != 0);
186 dialog->SetUpdate(m_metadata);
187 dialog->EndModal(wxID_OK);
194 SemanticVersion currentVersion(pic->m_version_major, pic->m_version_minor);
199 if (newVersion > currentVersion) {
201 }
else if (newVersion == currentVersion) {
202 return _(
"Reinstall");
204 return _(
"Downgrade");
213 : wxPanel(parent), m_url(url) {
214 auto vbox =
new wxBoxSizer(wxVERTICAL);
215 auto button =
new wxButton(
this, wxID_ANY, _(
"Website"));
216 button->Enable(strlen(url) > 0);
219 Bind(wxEVT_COMMAND_BUTTON_CLICKED,
220 [=](wxCommandEvent&) { wxLaunchDefaultBrowser(m_url); });
224 const std::string m_url;
232 auto flags = wxSizerFlags().Border();
234 auto vbox =
new wxBoxSizer(wxVERTICAL);
236 flags.DoubleBorder().Top().Right());
237 vbox->Add(1, 1, 1, wxEXPAND);
240 vbox->Add(m_info_btn, flags.DoubleBorder().Right());
245 void HideDetails(
bool hide) {
246 m_info_btn->Show(!hide);
247 GetParent()->Layout();
263 [&](
bool collapsed) { OnClick(collapsed); })),
265 auto flags = wxSizerFlags().Border();
266 auto sum_hbox =
new wxBoxSizer(wxHORIZONTAL);
267 m_widthDescription =
g_options->GetSize().x * 4 / 10;
270 m_summary =
new wxStaticText(
271 this, wxID_ANY,
"", wxDefaultPosition,
272 wxSize(m_widthDescription, -1) );
273 m_summaryText = wxString(plugin->summary.c_str());
274 m_summary->SetLabel(m_summaryText);
275 m_summary->Wrap(m_widthDescription);
279 sum_hbox->Add(m_summary);
280 sum_hbox->AddSpacer(10);
281 sum_hbox->Add(m_more, wxSizerFlags());
283 auto vbox =
new wxBoxSizer(wxVERTICAL);
286 std::string name_reduced = plugin->name;
287 if (plugin->name.size() * GetCharWidth() >
288 (
size_t)m_widthDescription * 7 / 10) {
289 int nc = (m_widthDescription * 7 / 10) / GetCharWidth();
291 name_reduced = plugin->name.substr(0, nc - 3) +
"...";
295 wxString nameText(name_reduced +
" " + plugin->version);
296 if (bshowTuple) nameText +=
" " + plugin->target;
298 auto name = staticText(nameText);
300 m_descr =
new wxStaticText(
301 this, wxID_ANY,
"", wxDefaultPosition,
302 wxSize(m_widthDescription, -1) );
303 m_descText = wxString(plugin->description.c_str());
304 m_descr->SetLabel(m_descText);
305 m_descr->Wrap(m_widthDescription);
307 vbox->Add(name, flags);
308 vbox->Add(sum_hbox, flags);
309 vbox->Add(m_descr, 0);
314 m_descr->SetLabel(m_descText);
315 m_descr->Wrap(m_widthDescription);
316 GetParent()->Layout();
317 m_buttons->HideDetails(!m_descr->IsShown());
319 auto swin =
dynamic_cast<UpdateDialog*
>(GetGrandParent());
321 swin->RecalculateSize();
325 void OnClick(wxMouseEvent&) {
326 m_descr->Show(!m_descr->IsShown());
330 void OnClick(
bool collapsed) {
331 m_descr->Show(!collapsed);
332 m_isDesc = !collapsed;
338 wxStaticText* staticText(
const wxString& text) {
339 return new wxStaticText(
this, wxID_ANY, text, wxDefaultPosition,
340 wxDefaultSize, wxALIGN_LEFT);
343 wxStaticText* m_descr;
345 wxStaticText* m_summary;
347 int m_widthDescription;
349 wxString m_summaryText;
359 const std::vector<PluginMetadata>& updates)
360 : wxScrolledWindow(parent),
362 m_grid(
new wxFlexGridSizer(3, 0, 0)) {
363 auto box =
new wxBoxSizer(wxVERTICAL);
364 populateGrid(m_grid);
365 box->Add(m_grid, wxSizerFlags().Proportion(0).Expand());
366 auto butt_box =
new wxBoxSizer(wxHORIZONTAL);
367 auto cancel_btn =
new wxButton(
this, wxID_CANCEL, _(
"Dismiss"));
368 butt_box->Add(1, 1, 1, wxEXPAND);
369 butt_box->Add(cancel_btn, wxSizerFlags().Border());
370 box->Add(butt_box, wxSizerFlags().Proportion(0).Expand());
373 SetMinSize(GetEffectiveMinSize());
378 void populateGrid(wxFlexGridSizer* grid) {
379 auto flags = wxSizerFlags();
381 grid->AddGrowableCol(2);
382 for (
auto plugin : m_updates) {
385 bool b_show_tuple =
false;
387 b_show_tuple = m_updates.size() > 1;
390 tpanel->m_isDesc =
true;
391 grid->Add(tpanel, flags.Proportion(1).Right());
392 grid->Add(buttons, flags.DoubleBorder());
393 grid->Add(
new wxStaticLine(
this), wxSizerFlags(0).Expand());
394 grid->Add(
new wxStaticLine(
this), wxSizerFlags(0).Expand());
395 grid->Add(
new wxStaticLine(
this), wxSizerFlags(0).Expand());
400 const std::vector<PluginMetadata> m_updates;
401 wxFlexGridSizer* m_grid;
406 const std::vector<PluginMetadata>& updates)
407 : wxDialog(parent, wxID_ANY, _(
"Plugin Manager"), wxDefaultPosition,
408 wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER) {
409 auto vbox =
new wxBoxSizer(wxVERTICAL);
413 vbox->Add(m_scrwin, wxSizerFlags(1).Expand());
419 androidDisableRotation();
423UpdateDialog::~UpdateDialog() {
425 androidEnableRotation();
429void UpdateDialog::RecalculateSize() {
430 m_scrwin->SetMinClientSize(m_scrwin->GetSizer()->GetMinSize());
Catalog options dialog, by default disabled.
Simple panel showing either an "expand" or "collapse" icon, state switches when clicked.
Data for a loaded plugin, including dl-loaded library.
wxString m_version_str
Complete version as of semantic_vers.
A plugin icon, scaled to about 2/3 of available space.
Plugin name, version, summary + an optionally shown description.
Modal dialog, displays available updates (possibly just one) and lets user select and eventually conf...
UpdateDialog(wxWindow *parent, const std::vector< PluginMetadata > &updates)
Top-level install plugins dialog.
Handle downloading of files from remote urls.
options * g_options
Global instance.
Plugin remote repositories installation and Uninstall/list operations.
Low level code to load plugins from disk, notably the PluginLoader class.
PlugInManager and helper classes – Mostly gui parts (dialogs) and plugin API stuff.
Semantic version encode/decode object.
Versions uses a modified semantic versioning scheme: major.minor.revision.post-tag+build.
static SemanticVersion parse(std::string s)
Parse a version string, sets major == -1 on errors.
wxBitmap LoadSVG(const wxString filename, const unsigned int width, const unsigned int height, wxBitmap *default_bitmap, bool use_cache)
Load SVG file and return it's bitmap representation of requested size In case file can't be loaded an...