37#include <wx/progdlg.h>
39#include <wx/statline.h>
40#include <wx/textwrapper.h>
51#include "expand_icon.h"
58#include "androidUTIL.h"
68 Wrap(win, text, widthMax);
70 wxString
const& GetWrapped()
const {
return m_wrapped; }
71 int const GetLineCount()
const {
return m_lineCount; }
74 virtual void OnOutputLine(
const wxString& line) { m_wrapped += line; }
75 virtual void OnNewLine() {
89static ssize_t PlugInIxByName(
const std::string name,
90 const ArrayOfPlugIns* plugins) {
91 for (
unsigned i = 0; i < plugins->GetCount(); i += 1) {
92 if (name == plugins->Item(i)->m_common_name.Lower().ToStdString()) {
101 const ArrayOfPlugIns* plugins) {
102 auto ix = PlugInIxByName(name, plugins);
103 return ix == -1 ? 0 : plugins->Item(ix);
115 : wxPanel(parent), m_plugin_name(plugin_name) {
116 auto size = GetClientSize();
117 auto minsize = GetTextExtent(
"OpenCPN");
118 SetMinClientSize(wxSize(minsize.GetWidth(), size.GetHeight()));
120 Bind(wxEVT_PAINT, &PluginIconPanel::OnPaint,
this);
123 void OnPaint(wxPaintEvent&) {
124 auto size = GetClientSize();
125 int minsize = wxMin(size.GetHeight(), size.GetWidth());
126 auto offset = minsize / 10;
128 LoadIcon(
"packageBox.svg", m_bitmap, 2 * minsize / 3);
130 if (!m_bitmap.IsOk()) {
131 wxLogMessage(
"AddPluginPanel: bitmap is not OK!");
134 dc.DrawBitmap(m_bitmap, offset, offset,
true);
139 const std::string m_plugin_name;
141 void LoadIcon(
const char* plugin_name, wxBitmap& bitmap,
int size = 32) {
142 wxFileName path(g_Platform->GetSharedDataDir(), plugin_name);
143 path.AppendDir(
"uidata");
144 path.AppendDir(
"traditional");
147 if (path.IsFileReadable()) {
148 bitmap =
LoadSVG(path.GetFullPath(), size, size);
153 auto style = g_StyleManager->GetCurrentStyle();
154 bitmap = wxBitmap(style->GetIcon(
"default_pi", size, size));
155 wxLogMessage(
"Icon: %s not found.", path.GetFullPath());
164 : wxPanel(parent), m_metadata(metadata) {
165 auto loader = PluginLoader::GetInstance();
167 PlugInByName(metadata.name, loader->GetPlugInArray());
168 std::string label(_(
"Install"));
170 ((found->m_version_major > 0) || (found->m_version_minor > 0))) {
171 label = getUpdateLabel(found, metadata);
173 auto button =
new wxButton(
this, wxID_ANY, label);
174 auto box =
new wxBoxSizer(wxHORIZONTAL);
177 Bind(wxEVT_COMMAND_BUTTON_CLICKED, &InstallButton::OnClick,
this);
180 void OnClick(wxCommandEvent&) {
181 wxLogMessage(
"Selected update: %s", m_metadata.name.c_str());
182 auto top_parent = GetParent()->GetParent()->GetParent();
184 wxASSERT(dialog != 0);
185 dialog->SetUpdate(m_metadata);
186 dialog->EndModal(wxID_OK);
193 SemanticVersion currentVersion(pic->m_version_major, pic->m_version_minor);
198 if (newVersion > currentVersion) {
200 }
else if (newVersion == currentVersion) {
201 return _(
"Reinstall");
203 return _(
"Downgrade");
212 : wxPanel(parent), m_url(url) {
213 auto vbox =
new wxBoxSizer(wxVERTICAL);
214 auto button =
new wxButton(
this, wxID_ANY, _(
"Website"));
215 button->Enable(strlen(url) > 0);
218 Bind(wxEVT_COMMAND_BUTTON_CLICKED,
219 [=](wxCommandEvent&) { wxLaunchDefaultBrowser(m_url); });
223 const std::string m_url;
231 auto flags = wxSizerFlags().Border();
233 auto vbox =
new wxBoxSizer(wxVERTICAL);
235 flags.DoubleBorder().Top().Right());
236 vbox->Add(1, 1, 1, wxEXPAND);
239 vbox->Add(m_info_btn, flags.DoubleBorder().Right());
244 void HideDetails(
bool hide) {
245 m_info_btn->Show(!hide);
246 GetParent()->Layout();
262 [&](
bool collapsed) { OnClick(collapsed); })),
264 auto flags = wxSizerFlags().Border();
265 auto sum_hbox =
new wxBoxSizer(wxHORIZONTAL);
266 m_widthDescription =
g_options->GetSize().x * 4 / 10;
269 m_summary =
new wxStaticText(
270 this, wxID_ANY,
"", wxDefaultPosition,
271 wxSize(m_widthDescription, -1) );
272 m_summaryText = wxString(plugin->summary.c_str());
273 m_summary->SetLabel(m_summaryText);
274 m_summary->Wrap(m_widthDescription);
278 sum_hbox->Add(m_summary);
279 sum_hbox->AddSpacer(10);
280 sum_hbox->Add(m_more, wxSizerFlags());
282 auto vbox =
new wxBoxSizer(wxVERTICAL);
285 std::string name_reduced = plugin->name;
286 if (plugin->name.size() * GetCharWidth() >
287 (
size_t)m_widthDescription * 7 / 10) {
288 int nc = (m_widthDescription * 7 / 10) / GetCharWidth();
290 name_reduced = plugin->name.substr(0, nc - 3) +
"...";
294 wxString nameText(name_reduced +
" " + plugin->version);
295 if (bshowTuple) nameText +=
" " + plugin->target;
297 auto name = staticText(nameText);
299 m_descr =
new wxStaticText(
300 this, wxID_ANY,
"", wxDefaultPosition,
301 wxSize(m_widthDescription, -1) );
302 m_descText = wxString(plugin->description.c_str());
303 m_descr->SetLabel(m_descText);
304 m_descr->Wrap(m_widthDescription);
306 vbox->Add(name, flags);
307 vbox->Add(sum_hbox, flags);
308 vbox->Add(m_descr, 0);
313 m_descr->SetLabel(m_descText);
314 m_descr->Wrap(m_widthDescription);
315 GetParent()->Layout();
316 m_buttons->HideDetails(!m_descr->IsShown());
318 auto swin =
dynamic_cast<UpdateDialog*
>(GetGrandParent());
320 swin->RecalculateSize();
324 void OnClick(wxMouseEvent&) {
325 m_descr->Show(!m_descr->IsShown());
329 void OnClick(
bool collapsed) {
330 m_descr->Show(!collapsed);
331 m_isDesc = !collapsed;
337 wxStaticText* staticText(
const wxString& text) {
338 return new wxStaticText(
this, wxID_ANY, text, wxDefaultPosition,
339 wxDefaultSize, wxALIGN_LEFT);
342 wxStaticText* m_descr;
344 wxStaticText* m_summary;
346 int m_widthDescription;
348 wxString m_summaryText;
358 const std::vector<PluginMetadata>& updates)
359 : wxScrolledWindow(parent),
361 m_grid(
new wxFlexGridSizer(3, 0, 0)) {
362 auto box =
new wxBoxSizer(wxVERTICAL);
363 populateGrid(m_grid);
364 box->Add(m_grid, wxSizerFlags().Proportion(0).Expand());
365 auto butt_box =
new wxBoxSizer(wxHORIZONTAL);
366 auto cancel_btn =
new wxButton(
this, wxID_CANCEL, _(
"Dismiss"));
367 butt_box->Add(1, 1, 1, wxEXPAND);
368 butt_box->Add(cancel_btn, wxSizerFlags().Border());
369 box->Add(butt_box, wxSizerFlags().Proportion(0).Expand());
372 SetMinSize(GetEffectiveMinSize());
377 void populateGrid(wxFlexGridSizer* grid) {
378 auto flags = wxSizerFlags();
380 grid->AddGrowableCol(2);
381 for (
auto plugin : m_updates) {
384 bool b_show_tuple =
false;
386 b_show_tuple = m_updates.size() > 1;
389 tpanel->m_isDesc =
true;
390 grid->Add(tpanel, flags.Proportion(1).Right());
391 grid->Add(buttons, flags.DoubleBorder());
392 grid->Add(
new wxStaticLine(
this), wxSizerFlags(0).Expand());
393 grid->Add(
new wxStaticLine(
this), wxSizerFlags(0).Expand());
394 grid->Add(
new wxStaticLine(
this), wxSizerFlags(0).Expand());
399 const std::vector<PluginMetadata> m_updates;
400 wxFlexGridSizer* m_grid;
405 const std::vector<PluginMetadata>& updates)
406 : wxDialog(parent, wxID_ANY, _(
"Plugin Manager"), wxDefaultPosition,
407 wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER) {
408 auto vbox =
new wxBoxSizer(wxVERTICAL);
412 vbox->Add(m_scrwin, wxSizerFlags(1).Expand());
418 androidDisableRotation();
422UpdateDialog::~UpdateDialog() {
424 androidEnableRotation();
428void UpdateDialog::RecalculateSize() {
429 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...