36#include <wx/progdlg.h>
38#include <wx/statline.h>
39#include <wx/textwrapper.h>
50#include "expand_icon.h"
57#include "androidUTIL.h"
67 Wrap(win, text, widthMax);
69 wxString
const& GetWrapped()
const {
return m_wrapped; }
70 int const GetLineCount()
const {
return m_lineCount; }
73 virtual void OnOutputLine(
const wxString& line) { m_wrapped += line; }
74 virtual void OnNewLine() {
88static ssize_t PlugInIxByName(
const std::string name,
89 const ArrayOfPlugIns* plugins) {
90 for (
unsigned i = 0; i < plugins->GetCount(); i += 1) {
91 if (name == plugins->Item(i)->m_common_name.Lower().ToStdString()) {
100 const ArrayOfPlugIns* plugins) {
101 auto ix = PlugInIxByName(name, plugins);
102 return ix == -1 ? 0 : plugins->Item(ix);
114 : wxPanel(parent), m_plugin_name(plugin_name) {
115 auto size = GetClientSize();
116 auto minsize = GetTextExtent(
"OpenCPN");
117 SetMinClientSize(wxSize(minsize.GetWidth(), size.GetHeight()));
119 Bind(wxEVT_PAINT, &PluginIconPanel::OnPaint,
this);
122 void OnPaint(wxPaintEvent&) {
123 auto size = GetClientSize();
124 int minsize = wxMin(size.GetHeight(), size.GetWidth());
125 auto offset = minsize / 10;
127 LoadIcon(
"packageBox.svg", m_bitmap, 2 * minsize / 3);
129 if (!m_bitmap.IsOk()) {
130 wxLogMessage(
"AddPluginPanel: bitmap is not OK!");
133 dc.DrawBitmap(m_bitmap, offset, offset,
true);
138 const std::string m_plugin_name;
140 void LoadIcon(
const char* plugin_name, wxBitmap& bitmap,
int size = 32) {
141 wxFileName path(g_Platform->GetSharedDataDir(), plugin_name);
142 path.AppendDir(
"uidata");
143 path.AppendDir(
"traditional");
146 if (path.IsFileReadable()) {
147 bitmap =
LoadSVG(path.GetFullPath(), size, size);
152 auto style = g_StyleManager->GetCurrentStyle();
153 bitmap = wxBitmap(style->GetIcon(
"default_pi", size, size));
154 wxLogMessage(
"Icon: %s not found.", path.GetFullPath());
163 : wxPanel(parent), m_metadata(metadata) {
164 auto loader = PluginLoader::GetInstance();
166 PlugInByName(metadata.name, loader->GetPlugInArray());
167 std::string label(_(
"Install"));
169 ((found->m_version_major > 0) || (found->m_version_minor > 0))) {
170 label = getUpdateLabel(found, metadata);
172 auto button =
new wxButton(
this, wxID_ANY, label);
173 auto box =
new wxBoxSizer(wxHORIZONTAL);
176 Bind(wxEVT_COMMAND_BUTTON_CLICKED, &InstallButton::OnClick,
this);
179 void OnClick(wxCommandEvent&) {
180 wxLogMessage(
"Selected update: %s", m_metadata.name.c_str());
181 auto top_parent = GetParent()->GetParent()->GetParent();
183 wxASSERT(dialog != 0);
184 dialog->SetUpdate(m_metadata);
185 dialog->EndModal(wxID_OK);
192 SemanticVersion currentVersion(pic->m_version_major, pic->m_version_minor);
197 if (newVersion > currentVersion) {
199 }
else if (newVersion == currentVersion) {
200 return _(
"Reinstall");
202 return _(
"Downgrade");
211 : wxPanel(parent), m_url(url) {
212 auto vbox =
new wxBoxSizer(wxVERTICAL);
213 auto button =
new wxButton(
this, wxID_ANY, _(
"Website"));
214 button->Enable(strlen(url) > 0);
217 Bind(wxEVT_COMMAND_BUTTON_CLICKED,
218 [=](wxCommandEvent&) { wxLaunchDefaultBrowser(m_url); });
222 const std::string m_url;
230 auto flags = wxSizerFlags().Border();
232 auto vbox =
new wxBoxSizer(wxVERTICAL);
234 flags.DoubleBorder().Top().Right());
235 vbox->Add(1, 1, 1, wxEXPAND);
238 vbox->Add(m_info_btn, flags.DoubleBorder().Right());
243 void HideDetails(
bool hide) {
244 m_info_btn->Show(!hide);
245 GetParent()->Layout();
261 [&](
bool collapsed) { OnClick(collapsed); })),
263 auto flags = wxSizerFlags().Border();
264 auto sum_hbox =
new wxBoxSizer(wxHORIZONTAL);
265 m_widthDescription =
g_options->GetSize().x * 4 / 10;
268 m_summary =
new wxStaticText(
269 this, wxID_ANY,
"", wxDefaultPosition,
270 wxSize(m_widthDescription, -1) );
271 m_summaryText = wxString(plugin->summary.c_str());
272 m_summary->SetLabel(m_summaryText);
273 m_summary->Wrap(m_widthDescription);
277 sum_hbox->Add(m_summary);
278 sum_hbox->AddSpacer(10);
279 sum_hbox->Add(m_more, wxSizerFlags());
281 auto vbox =
new wxBoxSizer(wxVERTICAL);
284 std::string name_reduced = plugin->name;
285 if (plugin->name.size() * GetCharWidth() >
286 (
size_t)m_widthDescription * 7 / 10) {
287 int nc = (m_widthDescription * 7 / 10) / GetCharWidth();
289 name_reduced = plugin->name.substr(0, nc - 3) +
"...";
293 wxString nameText(name_reduced +
" " + plugin->version);
294 if (bshowTuple) nameText +=
" " + plugin->target;
296 auto name = staticText(nameText);
298 m_descr =
new wxStaticText(
299 this, wxID_ANY,
"", wxDefaultPosition,
300 wxSize(m_widthDescription, -1) );
301 m_descText = wxString(plugin->description.c_str());
302 m_descr->SetLabel(m_descText);
303 m_descr->Wrap(m_widthDescription);
305 vbox->Add(name, flags);
306 vbox->Add(sum_hbox, flags);
307 vbox->Add(m_descr, 0);
312 m_descr->SetLabel(m_descText);
313 m_descr->Wrap(m_widthDescription);
314 GetParent()->Layout();
315 m_buttons->HideDetails(!m_descr->IsShown());
317 auto swin =
dynamic_cast<UpdateDialog*
>(GetGrandParent());
319 swin->RecalculateSize();
323 void OnClick(wxMouseEvent&) {
324 m_descr->Show(!m_descr->IsShown());
328 void OnClick(
bool collapsed) {
329 m_descr->Show(!collapsed);
330 m_isDesc = !collapsed;
336 wxStaticText* staticText(
const wxString& text) {
337 return new wxStaticText(
this, wxID_ANY, text, wxDefaultPosition,
338 wxDefaultSize, wxALIGN_LEFT);
341 wxStaticText* m_descr;
343 wxStaticText* m_summary;
345 int m_widthDescription;
347 wxString m_summaryText;
357 const std::vector<PluginMetadata>& updates)
358 : wxScrolledWindow(parent),
360 m_grid(
new wxFlexGridSizer(3, 0, 0)) {
361 auto box =
new wxBoxSizer(wxVERTICAL);
362 populateGrid(m_grid);
363 box->Add(m_grid, wxSizerFlags().Proportion(0).Expand());
364 auto butt_box =
new wxBoxSizer(wxHORIZONTAL);
365 auto cancel_btn =
new wxButton(
this, wxID_CANCEL, _(
"Dismiss"));
366 butt_box->Add(1, 1, 1, wxEXPAND);
367 butt_box->Add(cancel_btn, wxSizerFlags().Border());
368 box->Add(butt_box, wxSizerFlags().Proportion(0).Expand());
371 SetMinSize(GetEffectiveMinSize());
376 void populateGrid(wxFlexGridSizer* grid) {
377 auto flags = wxSizerFlags();
379 grid->AddGrowableCol(2);
380 for (
auto plugin : m_updates) {
383 bool b_show_tuple =
false;
385 b_show_tuple = m_updates.size() > 1;
388 tpanel->m_isDesc =
true;
389 grid->Add(tpanel, flags.Proportion(1).Right());
390 grid->Add(buttons, flags.DoubleBorder());
391 grid->Add(
new wxStaticLine(
this), wxSizerFlags(0).Expand());
392 grid->Add(
new wxStaticLine(
this), wxSizerFlags(0).Expand());
393 grid->Add(
new wxStaticLine(
this), wxSizerFlags(0).Expand());
398 const std::vector<PluginMetadata> m_updates;
399 wxFlexGridSizer* m_grid;
404 const std::vector<PluginMetadata>& updates)
405 : wxDialog(parent, wxID_ANY, _(
"Plugin Manager"), wxDefaultPosition,
406 wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER) {
407 auto vbox =
new wxBoxSizer(wxVERTICAL);
411 vbox->Add(m_scrwin, wxSizerFlags(1).Expand());
417 androidDisableRotation();
421UpdateDialog::~UpdateDialog() {
423 androidEnableRotation();
427void UpdateDialog::RecalculateSize() {
428 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...