38#include <unordered_map>
46#if defined(__linux__) && !defined(__ANDROID__)
52#include <wx/filename.h>
53#include <wx/aui/aui.h>
54#include <wx/platinfo.h>
55#include <wx/popupwin.h>
56#include <wx/progdlg.h>
57#include <wx/statline.h>
58#include <wx/tokenzr.h>
59#include <wx/tooltip.h>
61#include <wx/hashset.h>
62#include <wx/hashmap.h>
63#include <wx/jsonval.h>
64#include <wx/jsonreader.h>
66#include <wx/zipstrm.h>
67#include <wx/zstream.h>
68#include <wx/tarstrm.h>
69#include <wx/textwrapper.h>
76#include <archive_entry.h>
77typedef __LA_INT64_T la_int64_t;
87#include "model/ais_target_data.h"
91#include "model/comm_drv_n2k.h"
94#include "model/comm_vars.h"
96#include "model/datetime.h"
97#include "model/downloader.h"
98#include "model/georef.h"
99#include "model/json_event.h"
102#include "model/nav_object_database.h"
103#include "model/navutil_base.h"
105#include "model/plugin_cache.h"
110#include "model/route.h"
111#include "model/routeman.h"
112#include "model/safe_mode.h"
113#include "model/select.h"
114#include "model/semantic_vers.h"
115#include "model/track.h"
125#include "download_mgr.h"
135#include "OCPN_AUIManager.h"
137#include "ocpn_frame.h"
138#include "ocpn_pixel.h"
139#include "OCPNPlatform.h"
140#include "OCPNRegion.h"
144#include "routemanagerdialog.h"
145#include "routeman_gui.h"
148#include "SoundFactory.h"
151#include "SystemCmdSound.h"
153#include "update_mgr.h"
154#include "waypointman_gui.h"
158#include "androidUTIL.h"
162#include "glChartCanvas.h"
168#if wxUSE_XLOCALE || !wxCHECK_VERSION(3, 0, 0)
169extern wxLocale* plocale_def_lang;
178extern bool g_bShowChartBar;
182extern RouteList* pRouteList;
183extern std::vector<Track*> g_TrackList;
185extern s52plib* ps52plib;
186extern wxString ChartListFileName;
188extern ColorScheme global_color_scheme;
189extern wxArrayString g_locale_catalog_array;
190extern int g_GUIScaleFactor;
191extern int g_ChartScaleFactor;
192extern wxString g_locale;
195extern int g_chart_zoom_modifier_raster;
196extern int g_chart_zoom_modifier_vector;
198extern bool g_bopengl;
201extern unsigned int g_canvasConfig;
203extern wxString g_CmdSoundString;
205extern unsigned int gs_plib_flags;
208extern bool g_bquiting;
210WX_DEFINE_ARRAY_PTR(
ChartCanvas*, arrayofCanvasPtr);
211extern arrayofCanvasPtr g_canvasArray;
215void NotifySetupOptionsPlugin(
const PlugInData* pic);
217enum { CurlThreadId = wxID_HIGHEST + 1 };
219#include <wx/listimpl.cpp>
220WX_DEFINE_LIST(Plugin_WaypointList);
221WX_DEFINE_LIST(Plugin_HyperlinkList);
228 explicit RawKey(
const std::string& key) : m_key(key) {}
229 [[nodiscard]] std::string
GetKey()
const override {
return m_key; }
235static void SendAisJsonMessage(std::shared_ptr<const AisTargetData> pTarget) {
237 if (!GetJSONMessageTargetCount())
return;
242 wxLongLong t = ::wxGetLocalTimeMillis();
244 jMsg[wxS(
"Source")] = wxS(
"AisDecoder");
245 jMsg[
"Type"] =
"Information";
246 jMsg[
"Msg"] = wxS(
"AIS Target");
247 jMsg[
"MsgId"] = t.GetValue();
248 jMsg[wxS(
"lat")] = pTarget->Lat;
249 jMsg[wxS(
"lon")] = pTarget->Lon;
250 jMsg[wxS(
"sog")] = pTarget->SOG;
251 jMsg[wxS(
"cog")] = pTarget->COG;
252 jMsg[wxS(
"hdg")] = pTarget->HDG;
253 jMsg[wxS(
"mmsi")] = pTarget->MMSI;
254 jMsg[wxS(
"class")] = pTarget->Class;
255 jMsg[wxS(
"ownship")] = pTarget->b_OwnShip;
256 jMsg[wxS(
"active")] = pTarget->b_active;
257 jMsg[wxS(
"lost")] = pTarget->b_lost;
258 wxString l_ShipName = wxString::FromUTF8(pTarget->ShipName);
259 for (
size_t i = 0; i < l_ShipName.Len(); i++) {
260 if (l_ShipName.GetChar(i) ==
'@') l_ShipName.SetChar(i,
'\n');
262 jMsg[wxS(
"shipname")] = l_ShipName;
263 wxString l_CallSign = wxString::FromUTF8(pTarget->CallSign);
264 for (
size_t i = 0; i < l_CallSign.Len(); i++) {
265 if (l_CallSign.GetChar(i) ==
'@') l_CallSign.SetChar(i,
'\n');
267 jMsg[wxS(
"callsign")] = l_CallSign;
268 jMsg[wxS(
"removed")] = pTarget->b_removed;
269 SendJSONMessageToAllPlugins(
"AIS", jMsg);
273 return (*p1)->Key().compare((*p2)->Key());
277 auto version = metadata.version;
279 if (version[0] ==
'v') version = version.substr(1);
284 auto imported_version = ParseVersion(metadata);
285 for (
auto& md :
PluginHandler::GetInstance()->GetAvailable()) {
286 if (md.name != metadata.name)
continue;
287 if (md.is_imported)
continue;
289 if (ParseVersion(md) >= imported_version)
return true;
300 void message(
const std::string& message) {
302 m_deferred_messages.push_back(message);
307 void show_deferred_messages() {
308 for (
auto m : m_deferred_messages) show_msg(m);
315 void show_msg(wxString msg) {
316 OCPNMessageBox(NULL, msg, wxString(_(
"OpenCPN Info")),
317 wxICON_INFORMATION | wxOK, 10);
321 std::vector<wxString> m_deferred_messages;
328 Wrap(win, text, widthMax);
330 wxString
const& GetWrapped()
const {
return m_wrapped; }
331 int const GetLineCount()
const {
return m_lineCount; }
332 wxArrayString GetLineArray() {
return m_array; }
335 virtual void OnOutputLine(
const wxString& line) {
339 virtual void OnNewLine() {
347 wxArrayString m_array;
351 template <
typename T>
352 std::size_t operator()(T t)
const {
353 return static_cast<std::size_t
>(t);
360 return _(
"Plugin is a standard system plugin");
362 return _(
"Plugin is managed by OpenCPN");
364 return _(
"Plugin is not managed by OpenCPN");
367 case PluginStatus::Unknown:
368 return _(
"Plugin status unknown");
369 case PluginStatus::LegacyUpdateAvailable:
370 return _(
"Update to managed Plugin is available");
371 case PluginStatus::ManagedInstallAvailable:
372 return _(
"New managed Plugin installation available");
373 case PluginStatus::ManagedInstalledUpdateAvailable:
374 return _(
"Update to installed Plugin is available");
375 case PluginStatus::ManagedInstalledCurrentVersion:
376 return _(
"Plugin is latest available");
377 case PluginStatus::Imported:
378 return _(
"Plugin is imported");
379 case PluginStatus::ManagedInstalledDowngradeAvailable:
381 case PluginStatus::PendingListRemoval:
388static const std::unordered_map<PluginStatus, const char*, EnumClassHash>
394 {PluginStatus::Unknown,
"emblem-unmanaged.svg"},
395 {PluginStatus::LegacyUpdateAvailable,
"emblem-legacy-update.svg"},
396 {PluginStatus::ManagedInstallAvailable,
"emblem-download.svg"},
397 {PluginStatus::ManagedInstalledUpdateAvailable,
398 "emblem-legacy-update.svg"},
399 {PluginStatus::ManagedInstalledCurrentVersion,
"emblem-default.svg"},
400 {PluginStatus::ManagedInstalledDowngradeAvailable,
401 "emblem-default.svg"},
402 {PluginStatus::PendingListRemoval,
"emblem-default.svg"},
403 {PluginStatus::Imported,
"emblem-default.svg"}});
405static const std::unordered_map<PluginStatus, const char*, EnumClassHash>
406 literalstatus_by_status(
411 {PluginStatus::Unknown,
"Unknown"},
412 {PluginStatus::LegacyUpdateAvailable,
"LegacyUpdateAvailable"},
413 {PluginStatus::ManagedInstallAvailable,
"ManagedInstallAvailable"},
414 {PluginStatus::ManagedInstalledUpdateAvailable,
415 "ManagedInstalledUpdateAvailable"},
416 {PluginStatus::ManagedInstalledCurrentVersion,
417 "ManagedInstalledCurrentVersion"},
418 {PluginStatus::ManagedInstalledDowngradeAvailable,
419 "ManagedInstalledDowngradeAvailable"},
420 {PluginStatus::PendingListRemoval,
"PendingListRemoval"},
421 {PluginStatus::Imported,
"Imported"}
429static std::vector<PluginMetadata> getCompatiblePlugins() {
431 struct metadata_compare {
434 return lhs.key() < rhs.key();
438 std::vector<PluginMetadata> returnArray;
440 std::set<PluginMetadata, metadata_compare> unique_plugins;
441 for (
auto plugin :
PluginHandler::GetInstance()->GetAvailable()) {
442 unique_plugins.insert(plugin);
444 for (
auto plugin : unique_plugins) {
446 returnArray.push_back(plugin);
463 std::string installed;
465 if (path ==
"" || !wxFileName::IsFileReadable(path)) {
468 std::ifstream stream;
469 stream.open(path, std::ifstream::in);
478static std::vector<PluginMetadata> getUpdates(
const char* name) {
479 auto updates = getCompatiblePlugins();
481 std::remove_if(updates.begin(), updates.end(),
485 auto inst_vers = getInstalledVersion(name);
486 if (inst_vers.major == -1) {
491 updates.erase(std::remove_if(updates.begin(), updates.end(),
493 return metadata_version(m) == inst_vers;
500static void gui_uninstall(
const PlugInData* pic,
const char* plugin) {
501 g_Platform->ShowBusySpinner();
506 wxLogMessage(
"Uninstalling %s", plugin);
509 g_Platform->HideBusySpinner();
512static bool LoadAllPlugIns(
bool load_enabled,
bool keep_orphans =
false) {
513 g_Platform->ShowBusySpinner();
515 PluginLoader::GetInstance()->
LoadAllPlugIns(load_enabled, keep_orphans);
516 g_Platform->HideBusySpinner();
521static void UninstallPlugin(
const std::string& name) {
523 auto loader = PluginLoader::GetInstance();
524 auto finder = [name](
const PluginMetadata pm) {
return pm.name == name; };
525 const auto& installed = handler->GetInstalled();
526 auto found = std::find_if(installed.begin(), installed.end(), finder);
527 if (found != installed.end()) {
528 for (
size_t i = 0; i < loader->GetPlugInArray()->GetCount(); i++) {
529 auto const& item = loader->GetPlugInArray()->Item(i);
530 if (item->m_common_name.ToStdString() == name) {
531 DEBUG_LOG <<
"Unloading plugin: " << name;
532 loader->UnLoadPlugIn(i);
536 handler->Uninstall(found->name);
537 DEBUG_LOG <<
"Uninstalling: " << found->name;
542 bool uninstall,
const char* name = 0,
543 bool b_forceEnable =
false) {
545 const char* plugin = name == 0 ? pic->
m_common_name.mb_str().data() : name;
546 auto updates = getUpdates(plugin);
547 auto parent_dlg =
dynamic_cast<wxScrolledWindow*
>(parent);
548 wxASSERT(parent_dlg != 0);
550 auto status = dialog.ShowModal();
551 status = dialog.GetReturnCode();
552 if (status != wxID_OK) {
556 auto update = dialog.GetUpdate();
561 wxLogMessage(
"Installing %s", update.name.c_str());
563 g_Platform->ShowBusySpinner();
567 if (uninstall && path !=
"") {
568 gui_uninstall(pic, update.name.c_str());
570 bool cacheResult = pluginHandler->InstallPluginFromCache(update);
573 g_Platform->ShowBusySpinner();
577 std::string tempTarballPath = downloader->run(parent_dlg, uninstall);
579 if (!tempTarballPath.size())
585 if (!isRegularFile(manifestPath.c_str())) {
586 wxLogMessage(
"Installation of %s failed", update.name.c_str());
587 PluginHandler::CleanupFiles(manifestPath, update.name);
593 wxLogMessage(
"Installation of %s successful", update.name.c_str());
594 wxURI uri(wxString(update.tarball_url.c_str()));
595 wxFileName fn(uri.GetPath());
596 std::string basename = fn.GetFullName().ToStdString();
599 wxLogDebug(
"Copied %s to local cache at %s", tempTarballPath.c_str(),
601 remove(tempTarballPath.c_str());
609 wxString pispec =
"_pi.dll";
610#elif defined(__WXOSX__)
611 wxString pispec =
"_pi.dylib";
613 wxString pispec =
"_pi.so";
617 wxTextFile manifest_file(manifestPath);
619 if (manifest_file.Open()) {
621 for (wxString str = manifest_file.GetFirstLine(); !manifest_file.Eof();
622 str = manifest_file.GetNextLine()) {
623 if (str.Contains(pispec)) {
624 if (getenv(
"OCPN_KEEP_PLUGINS")) {
628 auto loader = PluginLoader::GetInstance();
629 if (!loader->CheckPluginCompatibility(str)) {
631 _(
"The plugin is not compatible with this version of OpenCPN, "
632 "and will be uninstalled.");
633 OCPNMessageBox(NULL, msg, wxString(_(
"OpenCPN Info")),
634 wxICON_INFORMATION | wxOK, 10);
636 PluginHandler::CleanupFiles(manifestPath, update.name);
645 if (b_forceEnable && pluginFile.Length()) {
646 wxString config_section = (_T (
"/PlugIns/" ));
647 wxFileName fn(pluginFile);
648 config_section += fn.GetFullName();
649 pConfig->SetPath(config_section);
650 pConfig->Write(_T (
"bEnabled" ),
true);
656 std::remove(handler->ImportedMetadataPath(update.name).c_str());
659 LoadAllPlugIns(
false);
662 g_Platform->HideBusySpinner();
682 pivp.
lat_min = tvp.GetBBox().GetMinLat();
683 pivp.
lat_max = tvp.GetBBox().GetMaxLat();
684 pivp.
lon_min = tvp.GetBBox().GetMinLon();
685 pivp.
lon_max = tvp.GetBBox().GetMaxLon();
687 pivp.
bValid = tvp.IsValid();
708 if (gFrame->GetPrimaryCanvas())
709 vp.
ref_scale = gFrame->GetPrimaryCanvas()->GetVP().ref_scale;
724 void OnPluginUtilAction(wxCommandEvent& event);
726 DECLARE_EVENT_TABLE()
730EVT_BUTTON(ID_CMD_BUTTON_PERFORM_ACTION, pluginUtilHandler::OnPluginUtilAction)
735void pluginUtilHandler::OnPluginUtilAction(wxCommandEvent& event) {
736 auto panel =
static_cast<PluginPanel*
>(
event.GetClientData());
739 wxASSERT(plugin_list_panel != 0);
741 auto actionPIC = panel->GetPlugin();
742 wxString name = actionPIC->m_common_name;
745 switch (panel->GetAction()) {
746 case ActionVerb::UPGRADE_TO_MANAGED_VERSION: {
747 auto loader = PluginLoader::GetInstance();
750 std::string pluginName = actionPIC->m_managed_metadata.name;
752 wxLogMessage(
"Installing managed plugin: %s", pluginName.c_str());
754 new GuiDownloader(plugin_list_panel, actionPIC->m_managed_metadata);
755 downloader->run(plugin_list_panel,
false);
759 if (isRegularFile(manifestPath.c_str())) {
761 for (
unsigned i = 0; i < loader->GetPlugInArray()->GetCount(); i += 1) {
762 if (actionPIC->m_managed_metadata.name ==
763 loader->GetPlugInArray()->Item(i)->m_common_name.ToStdString()) {
764 loader->UnLoadPlugIn(i);
770 LoadAllPlugIns(
false);
772 PluginHandler::CleanupFiles(manifestPath,
773 actionPIC->m_managed_metadata.name);
776 plugin_list_panel->SelectByName(name);
781 case ActionVerb::UPDATE_IMPORTED_VERSION:
782 case ActionVerb::UPGRADE_INSTALLED_MANAGED_VERSION:
783 case ActionVerb::REINSTALL_MANAGED_VERSION:
784 case ActionVerb::DOWNGRADE_INSTALLED_MANAGED_VERSION: {
786 auto metaSave = actionPIC->m_managed_metadata;
787 run_update_dialog(plugin_list_panel, actionPIC,
true,
788 metaSave.name.c_str());
792 case ActionVerb::INSTALL_MANAGED_VERSION: {
793 wxLogMessage(
"Installing new managed plugin.");
794 run_update_dialog(plugin_list_panel, actionPIC,
false);
798 case ActionVerb::UNINSTALL_MANAGED_VERSION: {
801 message.Printf(
"%s %s\n", actionPIC->m_managed_metadata.name.c_str(),
802 actionPIC->m_managed_metadata.version.c_str());
803 message += _(
"successfully un-installed");
805 wxLogMessage(
"Uninstalling %s",
806 actionPIC->m_managed_metadata.name.c_str());
809 actionPIC->m_managed_metadata.name);
812 LoadAllPlugIns(
false);
814 OCPNMessageBox(gFrame, message, _(
"Un-Installation complete"),
815 wxICON_INFORMATION | wxOK);
819 case ActionVerb::NOP:
830const wxEventType wxEVT_OCPN_MSG = wxNewEventType();
832OCPN_MsgEvent::OCPN_MsgEvent(wxEventType commandType,
int id)
833 : wxEvent(id, commandType) {}
835OCPN_MsgEvent::~OCPN_MsgEvent() {}
837wxEvent* OCPN_MsgEvent::Clone()
const {
839 newevent->m_MessageID =
842 newevent->m_MessageText = this->m_MessageText.c_str();
851PlugInToolbarToolContainer::PlugInToolbarToolContainer() {
855 bitmap_Rollover_day = NULL;
856 bitmap_Rollover_dusk = NULL;
857 bitmap_Rollover_night = NULL;
860PlugInToolbarToolContainer::~PlugInToolbarToolContainer() {
864 delete bitmap_Rollover_day;
865 delete bitmap_Rollover_dusk;
866 delete bitmap_Rollover_night;
877#if !defined(__ANDROID__) && defined(OCPN_USE_CURL)
878EVT_CURL_END_PERFORM(CurlThreadId, PlugInManager::OnEndPerformCurlDownload)
879EVT_CURL_DOWNLOAD(CurlThreadId, PlugInManager::OnCurlDownload)
883static
void event_message_box(const wxString& msg) {
884 OCPNMessageBox(NULL, msg, wxString(_(
"OpenCPN Info")),
885 wxICON_INFORMATION | wxOK, 0);
891 if (!pic->m_toolbox_panel) NotifySetupOptionsPlugin(pic);
896PlugInManager::PlugInManager(
MyFrame* parent) {
897#if !defined(__ANDROID__) && defined(OCPN_USE_CURL)
898 m_pCurlThread = NULL;
904 MyFrame* pFrame = GetParentFrame();
906 m_plugin_menu_item_id_next = CanvasMenuHandler::GetNextContextMenuId();
907 m_plugin_tool_id_next = pFrame->GetNextToolbarToolId();
920 new wxRadioBox(pFrame, -1,
"", wxPoint(0, 0), wxSize(-1, -1), as);
926#if !defined(__ANDROID__) && defined(OCPN_USE_CURL)
928 m_last_online =
false;
929 m_last_online_chk = -1;
934 m_blacklist = blacklist_factory();
935 m_blacklist_ui = std::unique_ptr<BlacklistUI>(
new BlacklistUI());
937 wxDEFINE_EVENT(EVT_JSON_TO_ALL_PLUGINS,
ObservedEvt);
938 evt_json_to_all_plugins_listener.
Listen(g_pRouteMan->
json_msg,
this,
939 EVT_JSON_TO_ALL_PLUGINS);
940 Bind(EVT_JSON_TO_ALL_PLUGINS, [&](
ObservedEvt& ev) {
941 auto json = std::static_pointer_cast<const wxJSONValue>(ev.
GetSharedPtr());
942 SendJSONMessageToAllPlugins(ev.GetString(), *json);
945 wxDEFINE_EVENT(EVT_LEGINFO_TO_ALL_PLUGINS,
ObservedEvt);
947 EVT_LEGINFO_TO_ALL_PLUGINS);
948 Bind(EVT_LEGINFO_TO_ALL_PLUGINS, [&](
ObservedEvt& ev) {
949 auto ptr = UnpackEvtPointer<ActiveLegDat>(ev);
950 SendActiveLegInfoToAllPlugIns(ptr.get());
953 HandlePluginLoaderEvents();
959 m_new_msgtype_lstnr.
Init(NavMsgBus::GetInstance().new_msg_event,
962PlugInManager::~PlugInManager() {
963#if !defined(__ANDROID__) && defined(OCPN_USE_CURL)
964 wxCurlBase::Shutdown();
966 delete m_utilHandler;
969void PlugInManager::InitCommListeners(
void) {
973 auto& msgbus = NavMsgBus::GetInstance();
976 m_listener_SignalK.
Listen(sk_msg,
this, EVT_SIGNALK);
983void PlugInManager::OnNewMessageType() {
984 for (
auto msg_key :
NavMsgBus::GetInstance().GetActiveMessages()) {
985 if (m_0183_listeners.find(msg_key) != m_0183_listeners.end())
continue;
986 if (msg_key.find(
"::") == std::string::npos)
continue;
988 if (key_parts.size() < 2)
continue;
993 m_0183_listeners[msg_key] = std::move(ol);
998 assert(n0183_msg->bus == NavAddr::Bus::N0183);
999 const std::string& payload = n0183_msg->payload;
1001 if (payload[0] ==
'$') {
1002 const auto& drivers = CommDriverRegistry::GetInstance().
GetDrivers();
1003 auto& target_driver =
FindDriver(drivers, n0183_msg->source->iface);
1007 bool passes_input_filter =
true;
1011 passes_input_filter =
1012 params.SentencePassesFilter(payload.c_str(), FILTER_INPUT);
1015 }
else if (payload[0] ==
'!') {
1016 SendAISSentenceToAllPlugIns(payload.c_str());
1021 g_ownshipMMSI_SK = sK_msg->context_self;
1026 std::string msgTerminated = sK_msg->raw_message;
1029 int errors = jsonReader.
Parse(msgTerminated, &root);
1030 if (errors == 0) SendJSONMessageToAllPlugins(
"OCPN_CORE_SIGNALK", root);
1039wxDEFINE_EVENT(EVT_PLUGMGR_ROUTEMAN_MSG,
ObservedEvt);
1040wxDEFINE_EVENT(EVT_BLACKLISTED_PLUGIN, wxCommandEvent);
1041wxDEFINE_EVENT(EVT_LOAD_DIRECTORY, wxCommandEvent);
1042wxDEFINE_EVENT(EVT_LOAD_PLUGIN, wxCommandEvent);
1043wxDEFINE_EVENT(EVT_PLUGIN_UNLOAD, wxCommandEvent);
1044wxDEFINE_EVENT(EVT_PLUGLIST_CHANGE, wxCommandEvent);
1045wxDEFINE_EVENT(EVT_UPDATE_CHART_TYPES, wxCommandEvent);
1046wxDEFINE_EVENT(EVT_PLUGIN_LOADALL_FINALIZE, wxCommandEvent);
1048void PlugInManager::HandlePluginLoaderEvents() {
1049 auto loader = PluginLoader::GetInstance();
1051 loader->SetOnActivateCb(
1053 loader->SetOnDeactivateCb(
1056 evt_pluglist_change_listener.
Listen(loader->evt_pluglist_change,
this,
1057 EVT_PLUGLIST_CHANGE);
1058 Bind(EVT_PLUGLIST_CHANGE, [&](wxCommandEvent&) {
1060 if (g_options) g_options->itemBoxSizerPanelPlugins->Layout();
1063 evt_load_directory_listener.
Listen(loader->evt_load_directory,
this,
1064 EVT_LOAD_DIRECTORY);
1065 Bind(EVT_LOAD_DIRECTORY, [&](wxCommandEvent&) {
1066 pConfig->SetPath(
"/PlugIns/");
1067 SetPluginOrder(pConfig->Read(
"PluginOrder", wxEmptyString));
1070 evt_load_plugin_listener.
Listen(loader->evt_load_plugin,
this,
1072 Bind(EVT_LOAD_PLUGIN, [&](wxCommandEvent& ev) {
1077 evt_update_chart_types_listener.
Listen(loader->evt_update_chart_types,
this,
1078 EVT_UPDATE_CHART_TYPES);
1079 Bind(EVT_UPDATE_CHART_TYPES,
1080 [&](wxCommandEvent& ev) { UpDateChartDataTypes(); });
1082 evt_plugin_loadall_finalize_listener.
Listen(
1083 loader->evt_plugin_loadall_finalize,
this, EVT_PLUGIN_LOADALL_FINALIZE);
1084 Bind(EVT_PLUGIN_LOADALL_FINALIZE,
1085 [&](wxCommandEvent& ev) { FinalizePluginLoadall(); });
1087 evt_ais_json_listener.
Listen(g_pAIS->
plugin_msg,
this, EVT_PLUGMGR_AIS_MSG);
1089 EVT_PLUGMGR_ROUTEMAN_MSG);
1091 auto pTarget = UnpackEvtPointer<AisTargetData>(ev);
1092 SendAisJsonMessage(pTarget);
1094 Bind(EVT_PLUGMGR_ROUTEMAN_MSG, [&](
ObservedEvt& ev) {
1095 auto msg = UnpackEvtPointer<wxJSONValue>(ev);
1096 SendJSONMessageToAllPlugins(ev.GetString(), *msg);
1104wxDEFINE_EVENT(EVT_DOWNLOAD_FAILED, wxCommandEvent);
1105wxDEFINE_EVENT(EVT_DOWNLOAD_OK, wxCommandEvent);
1107void PlugInManager::HandlePluginHandlerEvents() {
1108 auto loader = PluginLoader::GetInstance();
1110 evt_download_failed_listener.
Listen(loader->evt_update_chart_types,
this,
1111 EVT_DOWNLOAD_FAILED);
1112 Bind(EVT_DOWNLOAD_FAILED, [&](wxCommandEvent& ev) {
1113 wxString message = _(
"Please check system log for more info.");
1114 OCPNMessageBox(gFrame, message, _(
"Installation error"),
1115 wxICON_ERROR | wxOK | wxCENTRE);
1118 evt_download_ok_listener.
Listen(loader->evt_update_chart_types,
this,
1120 Bind(EVT_DOWNLOAD_OK, [&](wxCommandEvent& ev) {
1121 wxString message(ev.GetString());
1122 message += _(
" successfully installed from cache");
1123 OCPNMessageBox(gFrame, message, _(
"Installation complete"),
1124 wxICON_INFORMATION | wxOK | wxCENTRE);
1128bool PlugInManager::CallLateInit(
void) {
1131 auto plugin_array = PluginLoader::GetInstance()->
GetPlugInArray();
1132 for (
unsigned int i = 0; i < plugin_array->GetCount(); i++) {
1135 switch (pic->m_api_version) {
1148 ProcessLateInit(pic);
1158 wxString msg(
"PlugInManager: Calling LateInit PlugIn: ");
1163 if (ppi) ppi->LateInit();
1172 if (gFrame->GetPrimaryCanvas()->GetglCanvas()) {
1173 gFrame->GetPrimaryCanvas()->GetglCanvas()->SendJSONConfigMessage();
1174 SendS52ConfigToAllPlugIns(
true);
1189 for (
unsigned int i = 0; i < m_PlugInToolbarTools.GetCount(); i++) {
1192 if (pttc->m_pplugin == pic->m_pplugin) {
1193 m_PlugInToolbarTools.Remove(pttc);
1199 for (
unsigned int i = 0; i < m_PlugInMenuItems.GetCount(); i++) {
1201 if (pimis->m_pplugin == pic->m_pplugin) {
1202 m_PlugInMenuItems.Remove(pimis);
1208bool PlugInManager::IsAnyPlugInChartEnabled() {
1211 auto plugin_array = PluginLoader::GetInstance()->
GetPlugInArray();
1212 for (
unsigned int i = 0; i < plugin_array->GetCount(); i++) {
1214 if (pic->m_enabled && pic->m_init_state) {
1223void PlugInManager::UpdateManagedPlugins() {
1225 PluginLoader::GetInstance()->
SortPlugins(ComparePlugins);
1228 g_options->itemBoxSizerPanelPlugins->Layout();
1231bool PlugInManager::UpDateChartDataTypes() {
1235 auto plugin_array = PluginLoader::GetInstance()->
GetPlugInArray();
1236 for (
unsigned int i = 0; i < plugin_array->GetCount(); i++) {
1239 if (pic->m_init_state) {
1247 if (bret)
ChartData->UpdateChartClassDescriptorArray();
1252void PlugInManager::FinalizePluginLoadall() {
1256 SetColorSchemeForAllPlugIns(global_color_scheme);
1259 SendBaseConfigToAllPlugIns();
1260 SendS52ConfigToAllPlugIns(
true);
1261 SendSKConfigToAllPlugIns();
1266 if (gFrame->GetPrimaryCanvas()->GetglCanvas())
1267 gFrame->GetPrimaryCanvas()->GetglCanvas()->SendJSONConfigMessage();
1275void PlugInManager::SetPluginOrder(wxString serialized_names) {
1276 m_plugin_order.Empty();
1277 wxStringTokenizer tokenizer(serialized_names,
";");
1278 while (tokenizer.HasMoreTokens()) {
1279 m_plugin_order.Add(tokenizer.GetNextToken());
1283wxString PlugInManager::GetPluginOrder() {
1284 wxString plugins = wxEmptyString;
1285 auto plugin_array = PluginLoader::GetInstance()->
GetPlugInArray();
1286 for (
unsigned int i = 0; i < plugin_array->GetCount(); i++) {
1287 plugins.Append(plugin_array->Item(i)->m_common_name);
1288 if (i < plugin_array->GetCount() - 1) plugins.Append(
';');
1293bool PlugInManager::UpdateConfig() {
1297 auto plugin_array = PluginLoader::GetInstance()->
GetPlugInArray();
1298 for (
unsigned int i = 0; i < plugin_array->GetCount(); i++) {
1302 wxString config_section = (_T (
"/PlugIns/" ));
1304 pConfig->SetPath(config_section);
1305 pConfig->Write(_T (
"bEnabled" ), pic->m_enabled);
1312void PlugInManager::ShowDeferredBlacklistMessages() {
1313 m_blacklist_ui->show_deferred_messages();
1316bool PlugInManager::CheckBlacklistedPlugin(
const PluginMetadata plugin) {
1318 return CheckBlacklistedPlugin(wxString(plugin.name), v.major, v.minor);
1321bool PlugInManager::CheckBlacklistedPlugin(
opencpn_plugin* plugin) {
1326 wxString name = wxString::FromAscii(
typeid(*plugin).name());
1327 name.Replace(
"class ", wxEmptyString);
1329 const std::type_info& ti =
typeid(*plugin);
1331 char* realname = abi::__cxa_demangle(ti.name(), 0, 0, &status);
1332 wxString name = wxString::FromAscii(realname);
1335 return CheckBlacklistedPlugin(name, major, minor);
1338bool PlugInManager::CheckBlacklistedPlugin(wxString name,
int major,
1340 auto block_status = m_blacklist->get_status(name.ToStdString(), major, minor);
1341 if (block_status == plug_status::unblocked)
return true;
1342 plug_data data(name.ToStdString(), major, minor);
1343 auto msg = m_blacklist->get_message(block_status, data);
1344 m_blacklist_ui->message(msg);
1348bool PlugInManager::RenderAllCanvasOverlayPlugIns(
ocpnDC& dc,
1352 auto plugin_array = PluginLoader::GetInstance()->
GetPlugInArray();
1353 for (
unsigned int i = 0; i < plugin_array->GetCount(); i++) {
1355 if (pic->m_enabled && pic->m_init_state) {
1359 wxDC* pdc = dc.GetDC();
1362 switch (pic->m_api_version) {
1364 if (priority > 0)
break;
1371 if (priority > 0)
break;
1374 if (ppi) ppi->RenderOverlay(*pdc, &pivp);
1385 if (priority > 0)
break;
1388 if (ppi) ppi->RenderOverlay(*pdc, &pivp);
1393 if (priority > 0)
break;
1397 ppi->RenderOverlay(*pdc, &pivp);
1409 if (priority <= 0) {
1413 ppi->RenderOverlay(*pdc, &pivp);
1429 if (pic->
m_cap_flag & WANTS_OPENGL_OVERLAY_CALLBACK)
continue;
1431 if ((m_cached_overlay_bm.GetWidth() != vp.
pix_width) ||
1432 (m_cached_overlay_bm.GetHeight() != vp.
pix_height))
1436 mdc.SelectObject(m_cached_overlay_bm);
1437 mdc.SetBackground(*wxBLACK_BRUSH);
1440 bool b_rendered =
false;
1442 switch (pic->m_api_version) {
1444 if (priority > 0)
break;
1451 if (priority > 0)
break;
1454 if (ppi) b_rendered = ppi->RenderOverlay(mdc, &pivp);
1465 if (priority > 0)
break;
1468 if (ppi) b_rendered = ppi->RenderOverlay(mdc, &pivp);
1473 if (priority > 0)
break;
1477 b_rendered = ppi->RenderOverlay(mdc, &pivp);
1490 if (priority <= 0) {
1494 b_rendered = ppi->RenderOverlay(mdc, &pivp);
1501 mdc, &pivp, g_canvasConfig, priority);
1510 mdc.SelectObject(wxNullBitmap);
1513 wxMask* p_msk =
new wxMask(m_cached_overlay_bm, wxColour(0, 0, 0));
1514 m_cached_overlay_bm.SetMask(p_msk);
1516 dc.DrawBitmap(m_cached_overlay_bm, 0, 0,
true);
1519 }
else if (pic->
m_cap_flag & WANTS_OPENGL_OVERLAY_CALLBACK) {
1527bool PlugInManager::RenderAllGLCanvasOverlayPlugIns(wxGLContext* pcontext,
1531 auto plugin_array = PluginLoader::GetInstance()->
GetPlugInArray();
1532 for (
unsigned int i = 0; i < plugin_array->GetCount(); i++) {
1534 if (pic->m_enabled && pic->m_init_state) {
1535 if (pic->
m_cap_flag & WANTS_OPENGL_OVERLAY_CALLBACK) {
1538 switch (pic->m_api_version) {
1540 if (priority > 0)
break;
1543 if (ppi) ppi->RenderGLOverlay(pcontext, &pivp);
1555 if (priority > 0)
break;
1563 if (priority > 0)
break;
1580 if (priority <= 0) {
1605void PlugInManager::SendViewPortToRequestingPlugIns(
ViewPort& vp) {
1606 auto plugin_array = PluginLoader::GetInstance()->
GetPlugInArray();
1607 for (
unsigned int i = 0; i < plugin_array->GetCount(); i++) {
1609 if (pic->m_enabled && pic->m_init_state) {
1618void NotifySetupOptionsPlugin(
const PlugInData* pd) {
1619 PluginLoader::GetInstance()->NotifySetupOptionsPlugin(pd);
1622void PlugInManager::NotifySetupOptions() {
1623 auto plugin_array = PluginLoader::GetInstance()->
GetPlugInArray();
1624 for (
unsigned int i = 0; i < plugin_array->GetCount(); i++) {
1626 NotifySetupOptionsPlugin(pic);
1631 int ok_apply_cancel) {
1632 if (pic->m_enabled && pic->m_init_state) {
1635 auto loader = PluginLoader::GetInstance();
1642void PlugInManager::CloseAllPlugInPanels(
int ok_apply_cancel) {
1643 auto plugin_array = PluginLoader::GetInstance()->
GetPlugInArray();
1644 for (
unsigned int i = 0; i < plugin_array->GetCount(); i++) {
1647 ClosePlugInPanel(pic, ok_apply_cancel);
1652int PlugInManager::AddCanvasContextMenuItemPIM(wxMenuItem* pitem,
1657 pmic->pmenu_item = pitem;
1658 pmic->m_pplugin = pplugin;
1659 pmic->id = pitem->GetId() == wxID_SEPARATOR ? wxID_SEPARATOR
1660 : m_plugin_menu_item_id_next;
1662 pmic->b_grey =
false;
1663 pmic->m_in_menu = name;
1664 pmic->extended = is_extended;
1666 m_PlugInMenuItems.Add(pmic);
1668 m_plugin_menu_item_id_next++;
1673void PlugInManager::RemoveCanvasContextMenuItem(
int item,
const char* name) {
1674 for (
unsigned int i = 0; i < m_PlugInMenuItems.GetCount(); i++) {
1677 if (pimis->id == item) {
1678 m_PlugInMenuItems.Remove(pimis);
1686void PlugInManager::SetCanvasContextMenuItemViz(
int item,
bool viz,
1688 for (
unsigned int i = 0; i < m_PlugInMenuItems.GetCount(); i++) {
1691 if (pimis->id == item && !strcmp(name, pimis->m_in_menu)) {
1699void PlugInManager::SetCanvasContextMenuItemGrey(
int item,
bool grey,
1701 for (
unsigned int i = 0; i < m_PlugInMenuItems.GetCount(); i++) {
1704 if (pimis->id == item && !strcmp(name, pimis->m_in_menu)) {
1705 pimis->b_grey = grey;
1712void PlugInManager::SendResizeEventToAllPlugIns(
int x,
int y) {
1713 auto plugin_array = PluginLoader::GetInstance()->
GetPlugInArray();
1714 for (
unsigned int i = 0; i < plugin_array->GetCount(); i++) {
1716 if (pic->m_enabled && pic->m_init_state)
1721void PlugInManager::SetColorSchemeForAllPlugIns(ColorScheme cs) {
1722 auto plugin_array = PluginLoader::GetInstance()->
GetPlugInArray();
1723 for (
unsigned int i = 0; i < plugin_array->GetCount(); i++) {
1725 if (pic->m_enabled && pic->m_init_state)
1730void PlugInManager::PrepareAllPluginContextMenus() {
1731 int canvasIndex = gFrame->GetCanvasIndexUnderMouse();
1732 if (canvasIndex < 0)
return;
1734 auto plugin_array = PluginLoader::GetInstance()->
GetPlugInArray();
1735 for (
unsigned int i = 0; i < plugin_array->GetCount(); i++) {
1737 if (pic->m_enabled && pic->m_init_state) {
1739 switch (pic->m_api_version) {
1759void PlugInManager::SendSKConfigToAllPlugIns() {
1762 v[
"self"] = g_ownshipMMSI_SK;
1766 SendMessageToAllPlugins(wxString(
"OCPN_CORE_SIGNALK"), out);
1769void PlugInManager::SendBaseConfigToAllPlugIns() {
1772 v[
"OpenCPN Version Major"] = VERSION_MAJOR;
1773 v[
"OpenCPN Version Minor"] = VERSION_MINOR;
1774 v[
"OpenCPN Version Patch"] = VERSION_PATCH;
1775 v[
"OpenCPN Version Date"] = VERSION_DATE;
1776 v[
"OpenCPN Version Full"] = VERSION_FULL;
1779 if (g_MainToolbar) {
1780 v[
"OpenCPN Toolbar Width"] = g_MainToolbar->GetToolbarRect().width;
1781 v[
"OpenCPN Toolbar Height"] = g_MainToolbar->GetToolbarRect().height;
1782 v[
"OpenCPN Toolbar PosnX"] = g_MainToolbar->GetToolbarRect().x;
1783 v[
"OpenCPN Toolbar PosnY"] = g_MainToolbar->GetToolbarRect().y;
1787 v[
"OpenCPN Zoom Mod Vector"] = g_chart_zoom_modifier_vector;
1788 v[
"OpenCPN Zoom Mod Other"] = g_chart_zoom_modifier_raster;
1789 v[
"OpenCPN Scale Factor Exp"] =
1790 g_Platform->GetChartScaleFactorExp(g_ChartScaleFactor);
1798 SendMessageToAllPlugins(wxString(
"OpenCPN Config"), out);
1801void PlugInManager::SendS52ConfigToAllPlugIns(
bool bReconfig) {
1804 v[
"OpenCPN Version Major"] = VERSION_MAJOR;
1805 v[
"OpenCPN Version Minor"] = VERSION_MINOR;
1806 v[
"OpenCPN Version Patch"] = VERSION_PATCH;
1807 v[
"OpenCPN Version Date"] = VERSION_DATE;
1808 v[
"OpenCPN Version Full"] = VERSION_FULL;
1816 v[
"OpenCPN S52PLIB ShowAnchorConditions"] = ps52plib->GetAnchorOn();
1817 v[
"OpenCPN S52PLIB ShowQualityOfData"] = ps52plib->GetQualityOfData();
1822 v[
"OpenCPN S52PLIB MetaDisplay"] = ps52plib->m_bShowMeta;
1823 v[
"OpenCPN S52PLIB DeclutterText"] = ps52plib->m_bDeClutterText;
1824 v[
"OpenCPN S52PLIB ShowNationalText"] = ps52plib->m_bShowNationalTexts;
1825 v[
"OpenCPN S52PLIB ShowImportantTextOnly"] =
1826 ps52plib->m_bShowS57ImportantTextOnly;
1827 v[
"OpenCPN S52PLIB UseSCAMIN"] = ps52plib->m_bUseSCAMIN;
1828 v[
"OpenCPN S52PLIB UseSUPER_SCAMIN"] = ps52plib->m_bUseSUPER_SCAMIN;
1829 v[
"OpenCPN S52PLIB SymbolStyle"] = ps52plib->m_nSymbolStyle;
1830 v[
"OpenCPN S52PLIB BoundaryStyle"] = ps52plib->m_nBoundaryStyle;
1831 v[
"OpenCPN S52PLIB ColorShades"] = S52_getMarinerParam(S52_MAR_TWO_SHADES);
1832 v[
"OpenCPN S52PLIB Safety Depth"] =
1833 (double)S52_getMarinerParam(S52_MAR_SAFETY_DEPTH);
1834 v[
"OpenCPN S52PLIB Shallow Contour"] =
1835 (double)S52_getMarinerParam(S52_MAR_SHALLOW_CONTOUR);
1836 v[
"OpenCPN S52PLIB Deep Contour"] =
1837 (double)S52_getMarinerParam(S52_MAR_DEEP_CONTOUR);
1841 v[
"OpenCPN S52PLIB GlobalReconfig"] = bReconfig;
1846 SendMessageToAllPlugins(wxString(
"OpenCPN Config"), out);
1849void PlugInManager::NotifyAuiPlugIns(
void) {
1850 auto plugin_array = PluginLoader::GetInstance()->
GetPlugInArray();
1851 for (
unsigned int i = 0; i < plugin_array->GetCount(); i++) {
1853 if (pic->m_enabled && pic->m_init_state &&
1859int PlugInManager::AddToolbarTool(wxString label, wxBitmap* bitmap,
1860 wxBitmap* bmpRollover, wxItemKind kind,
1861 wxString shortHelp, wxString longHelp,
1862 wxObject* clientData,
int position,
1865 pttc->label = label;
1867 if (!bitmap->IsOk()) {
1869 pttc->bitmap_day =
new wxBitmap(style->GetIcon(
"default_pi"));
1872 pttc->bitmap_day =
new wxBitmap(*bitmap);
1873 pttc->bitmap_day->UnShare();
1876 if (!bmpRollover->IsOk()) {
1878 pttc->bitmap_Rollover_day =
new wxBitmap(style->GetIcon(
"default_pi"));
1881 pttc->bitmap_Rollover_day =
new wxBitmap(*bmpRollover);
1882 pttc->bitmap_Rollover_day->UnShare();
1885 pttc->bitmap_dusk = BuildDimmedToolBitmap(pttc->bitmap_day, 128);
1886 pttc->bitmap_night = BuildDimmedToolBitmap(pttc->bitmap_day, 32);
1887 pttc->bitmap_Rollover_dusk =
1888 BuildDimmedToolBitmap(pttc->bitmap_Rollover_day, 128);
1889 pttc->bitmap_Rollover_night =
1890 BuildDimmedToolBitmap(pttc->bitmap_Rollover_day, 32);
1893 pttc->shortHelp = shortHelp;
1894 pttc->longHelp = longHelp;
1895 pttc->clientData = clientData;
1896 pttc->position = position;
1897 pttc->m_pplugin = pplugin;
1898 pttc->tool_sel = tool_sel;
1900 pttc->b_toggle =
false;
1901 pttc->id = m_plugin_tool_id_next;
1903 m_PlugInToolbarTools.Add(pttc);
1905 m_plugin_tool_id_next++;
1910int PlugInManager::AddToolbarTool(wxString label, wxString SVGfile,
1911 wxString SVGRolloverfile,
1912 wxString SVGToggledfile, wxItemKind kind,
1913 wxString shortHelp, wxString longHelp,
1914 wxObject* clientData,
int position,
1917 pttc->label = label;
1919 pttc->pluginNormalIconSVG = SVGfile;
1920 pttc->pluginRolloverIconSVG = SVGRolloverfile;
1921 pttc->pluginToggledIconSVG = SVGToggledfile;
1926 pttc->bitmap_day =
new wxBitmap(style->GetIcon(
"default_pi"));
1927 pttc->bitmap_dusk = BuildDimmedToolBitmap(pttc->bitmap_day, 128);
1928 pttc->bitmap_night = BuildDimmedToolBitmap(pttc->bitmap_day, 32);
1929 pttc->bitmap_Rollover_day =
new wxBitmap(*pttc->bitmap_day);
1930 pttc->bitmap_Rollover_dusk =
1931 BuildDimmedToolBitmap(pttc->bitmap_Rollover_day, 128);
1932 pttc->bitmap_Rollover_night =
1933 BuildDimmedToolBitmap(pttc->bitmap_Rollover_day, 32);
1936 pttc->shortHelp = shortHelp;
1937 pttc->longHelp = longHelp;
1938 pttc->clientData = clientData;
1939 pttc->position = position;
1940 pttc->m_pplugin = pplugin;
1941 pttc->tool_sel = tool_sel;
1943 pttc->b_toggle =
false;
1944 pttc->id = m_plugin_tool_id_next;
1946 m_PlugInToolbarTools.Add(pttc);
1948 m_plugin_tool_id_next++;
1953void PlugInManager::RemoveToolbarTool(
int tool_id) {
1954 for (
unsigned int i = 0; i < m_PlugInToolbarTools.GetCount(); i++) {
1957 if (pttc->id == tool_id) {
1958 m_PlugInToolbarTools.Remove(pttc);
1964 pParent->RequestNewToolbars();
1967void PlugInManager::SetToolbarToolViz(
int item,
bool viz) {
1968 for (
unsigned int i = 0; i < m_PlugInToolbarTools.GetCount(); i++) {
1971 if (pttc->id == item) {
1973 pParent->RequestNewToolbars();
1980void PlugInManager::SetToolbarItemState(
int item,
bool toggle) {
1981 for (
unsigned int i = 0; i < m_PlugInToolbarTools.GetCount(); i++) {
1984 if (pttc->id == item) {
1985 pttc->b_toggle = toggle;
1986 pParent->SetMasterToolbarItemState(item, toggle);
1993void PlugInManager::SetToolbarItemBitmaps(
int item, wxBitmap* bitmap,
1994 wxBitmap* bmpRollover) {
1995 for (
unsigned int i = 0; i < m_PlugInToolbarTools.GetCount(); i++) {
1998 if (pttc->id == item) {
1999 delete pttc->bitmap_day;
2000 delete pttc->bitmap_dusk;
2001 delete pttc->bitmap_night;
2002 delete pttc->bitmap_Rollover_day;
2004 if (!bitmap->IsOk()) {
2006 pttc->bitmap_day =
new wxBitmap(style->GetIcon(
"default_pi"));
2009 pttc->bitmap_day =
new wxBitmap(*bitmap);
2010 pttc->bitmap_day->UnShare();
2013 if (!bmpRollover->IsOk()) {
2015 pttc->bitmap_Rollover_day =
2016 new wxBitmap(style->GetIcon(
"default_pi"));
2019 pttc->bitmap_Rollover_day =
new wxBitmap(*bmpRollover);
2020 pttc->bitmap_Rollover_day->UnShare();
2023 pttc->bitmap_dusk = BuildDimmedToolBitmap(pttc->bitmap_day, 128);
2024 pttc->bitmap_night = BuildDimmedToolBitmap(pttc->bitmap_day, 32);
2026 pParent->SetToolbarItemBitmaps(item, pttc->bitmap_day,
2027 pttc->bitmap_Rollover_day);
2034void PlugInManager::SetToolbarItemBitmaps(
int item, wxString SVGfile,
2035 wxString SVGfileRollover,
2036 wxString SVGfileToggled) {
2037 for (
unsigned int i = 0; i < m_PlugInToolbarTools.GetCount(); i++) {
2040 if (pttc->id == item) {
2041 pttc->pluginNormalIconSVG = SVGfile;
2042 pttc->pluginRolloverIconSVG = SVGfileRollover;
2043 pttc->pluginToggledIconSVG = SVGfileToggled;
2044 pParent->SetToolbarItemSVG(item, pttc->pluginNormalIconSVG,
2045 pttc->pluginRolloverIconSVG,
2046 pttc->pluginToggledIconSVG);
2054 for (
unsigned int i = 0; i < m_PlugInToolbarTools.GetCount(); i++) {
2056 if (
id == pc->id)
return pc->m_pplugin;
2062wxString PlugInManager::GetToolOwnerCommonName(
const int id) {
2065 auto plugin_array = PluginLoader::GetInstance()->
GetPlugInArray();
2066 for (
unsigned int i = 0; i < plugin_array->GetCount(); i++) {
2068 if (pic && (pic->m_pplugin == ppi))
return pic->
m_common_name;
2072 return wxEmptyString;
2075wxString PlugInManager::GetLastError() {
return m_last_error_string; }
2077wxBitmap* PlugInManager::BuildDimmedToolBitmap(wxBitmap* pbmp_normal,
2078 unsigned char dim_ratio) {
2079 wxImage img_dup = pbmp_normal->ConvertToImage();
2081 if (!img_dup.IsOk())
return NULL;
2083 if (dim_ratio < 200) {
2085 int gimg_width = img_dup.GetWidth();
2086 int gimg_height = img_dup.GetHeight();
2088 double factor = (double)(dim_ratio) / 256.0;
2090 for (
int iy = 0; iy < gimg_height; iy++) {
2091 for (
int ix = 0; ix < gimg_width; ix++) {
2092 if (!img_dup.IsTransparent(ix, iy)) {
2093 wxImage::RGBValue rgb(img_dup.GetRed(ix, iy),
2094 img_dup.GetGreen(ix, iy),
2095 img_dup.GetBlue(ix, iy));
2096 wxImage::HSVValue hsv = wxImage::RGBtoHSV(rgb);
2097 hsv.value = hsv.value * factor;
2098 wxImage::RGBValue nrgb = wxImage::HSVtoRGB(hsv);
2099 img_dup.SetRGB(ix, iy, nrgb.red, nrgb.green, nrgb.blue);
2105 wxBitmap* ptoolBarBitmap;
2108 wxBitmap tbmp(img_dup.GetWidth(), img_dup.GetHeight(), -1);
2110 dwxdc.SelectObject(tbmp);
2112 ptoolBarBitmap =
new wxBitmap(img_dup, (wxDC&)dwxdc);
2114 ptoolBarBitmap =
new wxBitmap(img_dup);
2118 return ptoolBarBitmap;
2121wxArrayString PlugInManager::GetPlugInChartClassNameArray(
void) {
2122 wxArrayString array;
2123 auto plugin_array = PluginLoader::GetInstance()->
GetPlugInArray();
2124 for (
unsigned int i = 0; i < plugin_array->GetCount(); i++) {
2126 if (pic && pic->m_enabled && pic->m_init_state &&
2131 for (
unsigned int j = 0; j < carray.GetCount(); j++) {
2132 array.Add(carray[j]);
2140 while (j < array.GetCount()) {
2141 wxString test = array[j];
2142 unsigned int k = j + 1;
2143 while (k < array.GetCount()) {
2144 if (test == array[k]) {
2162#define DISABLED_SETTINGS_MSG \
2163 _("These settings might destabilize OpenCPN and are by default disabled." \
2164 " To despite the dangers enable them manually add a CatalogExpert=1" \
2165 " line in the [PlugIns] section in the configuration file.")
2170CatalogMgrPanel::CatalogMgrPanel(wxWindow* parent)
2171 : wxPanel(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize),
2173 wxBoxSizer* topSizer =
new wxBoxSizer(wxVERTICAL);
2176 topSizer->Add(
new wxStaticLine(
this), 0, wxGROW | wxLEFT | wxRIGHT, 4);
2178 wxStaticBox* itemStaticBoxSizer4Static =
2179 new wxStaticBox(
this, wxID_ANY, _(
"Plugin Catalog"));
2180 wxStaticBoxSizer* itemStaticBoxSizer4 =
2181 new wxStaticBoxSizer(itemStaticBoxSizer4Static, wxVERTICAL);
2182 topSizer->Add(itemStaticBoxSizer4, 1, wxEXPAND | wxALL, 2);
2186 m_catalogText =
new wxStaticText(
this, wxID_STATIC,
"");
2187 itemStaticBoxSizer4->Add(m_catalogText,
2188 wxSizerFlags().Border().Proportion(1));
2189 m_catalogText->SetLabel(GetCatalogText(
false));
2192 wxBoxSizer* rowSizer2 =
new wxBoxSizer(wxHORIZONTAL);
2193 itemStaticBoxSizer4->Add(rowSizer2,
2194 wxSizerFlags().Expand().Border().Proportion(1));
2196 m_updateButton =
new wxButton(
this, wxID_ANY, _(
"Update Plugin Catalog"),
2197 wxDefaultPosition, wxDefaultSize, 0);
2198 rowSizer2->Add(m_updateButton, 0, wxALIGN_LEFT);
2199 m_updateButton->Bind(wxEVT_COMMAND_BUTTON_CLICKED,
2200 &CatalogMgrPanel::OnUpdateButton,
this);
2201 rowSizer2->AddSpacer(4 * GetCharWidth());
2202 m_tarballButton =
new wxButton(
this, wxID_ANY, _(
"Import plugin..."),
2203 wxDefaultPosition, wxDefaultSize, 0);
2204 rowSizer2->Add(m_tarballButton, 0, wxALIGN_LEFT | wxLEFT, 2 * GetCharWidth());
2205 m_tarballButton->Bind(wxEVT_COMMAND_BUTTON_CLICKED,
2206 &CatalogMgrPanel::OnTarballButton,
this);
2208 rowSizer2->AddSpacer(4 * GetCharWidth());
2209 m_adv_button =
new wxButton(
this, wxID_ANY, _(
"Settings..."),
2210 wxDefaultPosition, wxDefaultSize, 0);
2212 if (expert.Get(
false)) {
2213 m_adv_button->Bind(wxEVT_COMMAND_BUTTON_CLICKED,
2214 &CatalogMgrPanel::OnPluginSettingsButton,
this);
2216 m_adv_button->Bind(wxEVT_COMMAND_BUTTON_CLICKED, [&](wxCommandEvent&) {
2217 wxMessageBox(DISABLED_SETTINGS_MSG, _(
"Disabled"));
2220 rowSizer2->AddSpacer(4 * GetCharWidth());
2221 rowSizer2->Add(m_adv_button, 0, wxALIGN_LEFT);
2223 SetUpdateButtonLabel();
2226 wxBoxSizer* rowSizer3 =
new wxBoxSizer(wxHORIZONTAL);
2227 itemStaticBoxSizer4->Add(rowSizer3, 0, wxEXPAND | wxALL, 4);
2229 SetMinSize(wxSize(m_parent->GetClientSize().x - (4 * GetCharWidth()), -1));
2233 wxDEFINE_EVENT(EVT_CATALOG_CHANGE, wxCommandEvent);
2234 catalog_listener.Listen(catalog,
this, EVT_CATALOG_CHANGE);
2235 Bind(EVT_CATALOG_CHANGE, [&](wxCommandEvent&) { SetUpdateButtonLabel(); });
2238 SetBackgroundColour(wxColour(0x7c, 0xb0, 0xe9));
2240 if (!expert.Get(
false)) {
2242 new wxButton(
this, wxID_ANY, _(
"Update Plugin Catalog: master"),
2243 wxDefaultPosition, wxDefaultSize, 0);
2244 itemStaticBoxSizer4->Add(m_updateButton, 0, wxALIGN_LEFT);
2245 m_updateButton->Bind(wxEVT_COMMAND_BUTTON_CLICKED,
2246 &CatalogMgrPanel::OnUpdateButton,
this);
2247 SetUpdateButtonLabel();
2248 m_tarballButton = NULL;
2249 m_adv_button = NULL;
2252 m_catalogText =
new wxStaticText(
this, wxID_STATIC, GetCatalogText(
false));
2253 itemStaticBoxSizer4->Add(m_catalogText,
2254 wxSizerFlags().Border(wxALL, 5).Proportion(1));
2257 m_updateButton =
new wxButton(
2258 this, wxID_ANY,
"Update Plugin Catalog:master ",
2259 wxDefaultPosition, wxDefaultSize, 0);
2260 itemStaticBoxSizer4->Add(m_updateButton, 0, wxALIGN_LEFT | wxTOP, 5);
2261 m_updateButton->Bind(wxEVT_COMMAND_BUTTON_CLICKED,
2262 &CatalogMgrPanel::OnUpdateButton,
this);
2263 SetUpdateButtonLabel();
2266 m_adv_button =
new wxButton(
this, wxID_ANY, _(
"Settings..."),
2267 wxDefaultPosition, wxDefaultSize, 0);
2268 itemStaticBoxSizer4->Add(m_adv_button, 0, wxALIGN_LEFT | wxTOP,
2270 m_adv_button->Bind(wxEVT_COMMAND_BUTTON_CLICKED,
2271 &CatalogMgrPanel::OnPluginSettingsButton,
this);
2274 m_tarballButton =
new wxButton(
this, wxID_ANY, _(
"Import plugin..."),
2275 wxDefaultPosition, wxDefaultSize, 0);
2276 itemStaticBoxSizer4->Add(m_tarballButton, 0, wxALIGN_LEFT | wxALL,
2277 2 * GetCharWidth());
2278 m_tarballButton->Bind(wxEVT_COMMAND_BUTTON_CLICKED,
2279 &CatalogMgrPanel::OnTarballButton,
this);
2285CatalogMgrPanel::~CatalogMgrPanel() {
2286 m_updateButton->Unbind(wxEVT_COMMAND_BUTTON_CLICKED,
2287 &CatalogMgrPanel::OnUpdateButton,
this);
2288 if (m_tarballButton)
2289 m_tarballButton->Unbind(wxEVT_COMMAND_BUTTON_CLICKED,
2290 &CatalogMgrPanel::OnTarballButton,
this);
2293static const char*
const DOWNLOAD_REPO_PROTO =
2294 "https://raw.githubusercontent.com/OpenCPN/plugins/@branch@/"
2297void CatalogMgrPanel::OnUpdateButton(wxCommandEvent& event) {
2299 std::string catalog(g_catalog_channel ==
"" ?
"master" : g_catalog_channel);
2300 std::string url(g_catalog_custom_url);
2301 if (catalog !=
"custom") {
2302 url = std::string(DOWNLOAD_REPO_PROTO);
2306 std::string filePath =
2307 wxFileName::CreateTempFileName(
"ocpn_dl").ToStdString();
2309 auto catalogHdlr = CatalogHandler::GetInstance();
2311 g_Platform->ShowBusySpinner();
2312 auto status = catalogHdlr->DownloadCatalog(filePath, url);
2313 g_Platform->HideBusySpinner();
2315 std::string message;
2316 if (status != CatalogHandler::ServerStatus::OK) {
2317 message = _(
"Cannot download data from url");
2318 OCPNMessageBox(
this, message, _(
"OpenCPN Catalog update"),
2319 wxICON_ERROR | wxOK);
2325 if (!AndroidSecureCopyFile(wxString(filePath.c_str()),
2327 wxFileName::GetPathSeparator() +
2328 "ocpn-plugins.xml")) {
2329 OCPNMessageBox(
this, _(
"Unable to copy catalog file"),
2330 _(
"OpenCPN Catalog update"), wxICON_ERROR | wxOK);
2335 if (!wxCopyFile(wxString(filePath.c_str()),
2337 wxFileName::GetPathSeparator() +
"ocpn-plugins.xml")) {
2338 OCPNMessageBox(
this, _(
"Unable to copy catalog file"),
2339 _(
"OpenCPN Catalog update"), wxICON_ERROR | wxOK);
2345 if (catalog ==
"master") {
2347 OCPNMessageBox(
this, _(
"Unable to copy catalog file to cache"),
2348 _(
"OpenCPN Catalog update"), wxICON_ERROR | wxOK);
2354 pConfig->SetPath(
"/PlugIns/");
2355 pConfig->Write(
"LatestCatalogDownloaded", catalog.c_str());
2362 pluginHandler->setMetadata(
"");
2366 auto cataloghdlr = CatalogHandler::GetInstance();
2367 cataloghdlr->ClearCatalogData();
2370 LoadAllPlugIns(
false);
2374 m_catalogText->SetLabel(GetCatalogText(
true));
2377 OCPNMessageBox(
this, _(
"Catalog update successful"),
2378 _(
"OpenCPN Catalog update"), wxICON_INFORMATION | wxOK);
2381void CatalogMgrPanel::OnPluginSettingsButton(wxCommandEvent& event) {
2385 androidDisableRotation();
2388 dialog->ShowModal();
2391 androidEnableRotation();
2395void CatalogMgrPanel::OnTarballButton(wxCommandEvent& event) {
2398 int response = g_Platform->DoFileSelectorDialog(
2399 this, &path, _(
"Select tarball file"), GetImportInitDir(),
"",
2400 "tar files (*.tar.gz)|*.tar.gz|All Files (*.*)|*.*");
2402 if (response != wxID_OK) {
2407 bool ok = handler->ExtractMetadata(path.ToStdString(), metadata);
2411 _(
"Error extracting metadata from tarball (missing metadata.xml?)"),
2412 _(
"OpenCPN Plugin Import Error"));
2416 OCPNMessageBox(
this, _(
"Incompatible import plugin detected."),
2417 _(
"OpenCPN Plugin Import Error"));
2418 handler->Uninstall(metadata.name);
2421 UninstallPlugin(metadata.name);
2422 ok = handler->InstallPlugin(metadata, path.ToStdString());
2424 OCPNMessageBox(
this, _(
"Error extracting import plugin tarball."),
2425 _(
"OpenCPN Plugin Import Error"));
2428 metadata.is_imported =
true;
2430 std::ofstream file(metadata_path);
2433 WARNING_LOG <<
"Error saving metadata file: " << metadata_path
2434 <<
" for imported plugin: " << metadata.name;
2436 LoadAllPlugIns(
false,
true);
2439 wxString ws(_(
"Plugin"));
2440 ws += metadata.name + _(
" successfully imported");
2441 OCPNMessageBox(gFrame, ws, _(
"Installation complete"),
2442 wxICON_INFORMATION | wxOK | wxCENTRE);
2445wxString CatalogMgrPanel::GetCatalogText(
bool updated) {
2447 catalog = updated ? _(
"Active Catalog") : _(
"Last Catalog");
2451 pConfig->SetPath(
"/PlugIns/");
2452 wxString latestCatalog = pConfig->Read(
"LatestCatalogDownloaded",
"default");
2453 catalog += latestCatalog;
2459 std::string date = pluginHandler->GetCatalogData()->date;
2461 catalog += wxString(
" ") + _(
"Last change: ") +
" " + date;
2462 if (!updated) catalog +=
" : " + _(
"Please Update Plugin Catalog.");
2468void CatalogMgrPanel::SetUpdateButtonLabel() {
2469 wxString label = _(
"Update Plugin Catalog");
2471 label += g_catalog_channel ==
"" ?
"master" : g_catalog_channel;
2472 m_updateButton->SetLabel(label);
2476wxString CatalogMgrPanel::GetImportInitDir() {
2478 pConfig->SetPath(
"/PlugIns/");
2479 wxString lastImportDir;
2481 pConfig->Read(
"LatestImportDir", g_Platform->GetWritableDocumentsDir());
2482 if (wxDirExists(lastImportDir)) {
2483 return lastImportDir;
2485 return (g_Platform->GetWritableDocumentsDir());
2494 const wxPoint& pos, const wxSize& size)
2495 : wxScrolledWindow(parent,
id, pos, size, wxTAB_TRAVERSAL | wxVSCROLL),
2496 m_PluginSelected(0) {
2497 m_is_loading.clear();
2498 SetSizer(
new wxBoxSizer(wxVERTICAL));
2499 ReloadPluginPanels();
2502void PluginListPanel::SelectByName(wxString& name) {
2503 for (
auto it = GetChildren().GetFirst(); it; it = it->GetNext()) {
2504 auto pluginPanel =
dynamic_cast<PluginPanel*
>(it->GetData());
2506 if (pluginPanel->GetPluginPtr()->m_common_name.IsSameAs(name)) {
2507 pluginPanel->SetSelected(
true);
2508 pluginPanel->Layout();
2509 SelectPlugin(pluginPanel);
2518 std::vector<const PlugInData*> result;
2519 auto loader = PluginLoader::GetInstance();
2520 for (
size_t i = 0; i < loader->GetPlugInArray()->GetCount(); i++) {
2521 auto const item = loader->GetPlugInArray()->Item(i);
2522 if (item->m_managed_metadata.name.empty()) {
2523 const auto name = item->m_common_name.ToStdString();
2527 result.push_back(item);
2530 std::string slhs, srhs;
2531 for (
auto& cl : lhs->
Key()) slhs += toupper(cl);
2532 for (
auto& cr : rhs->Key()) srhs += toupper(cr);
2533 return slhs.compare(srhs) < 0;
2535 std::sort(result.begin(), result.end(), compare);
2540static bool IsPluginLoaded(
const std::string& name) {
2541 if (safe_mode::get_mode()) {
2544 std::find(installed.begin(), installed.end(),
ocpn::tolower(name));
2545 return found != installed.end();
2548 for (
size_t i = 0; i < loaded->GetCount(); i++) {
2549 if (loaded->Item(i)->m_common_name.ToStdString() == name)
return true;
2556 if (m_is_loading.test_and_set()) {
2558 DEBUG_LOG <<
"LoadAllPlugins: recursive invocation";
2563 m_PluginItems.Clear();
2565 wxWindowList kids = GetChildren();
2566 for (
unsigned int i = 0; i < kids.GetCount(); i++) {
2567 wxWindowListNode* node = kids.Item(i);
2568 wxWindow* win = node->GetData();
2570 if (pp) win->Destroy();
2572 GetSizer()->Clear();
2575 m_PluginSelected = 0;
2577 if (safe_mode::get_mode()) {
2580 for (
const auto& name : installed) AddPlugin(name);
2583 auto available = getCompatiblePlugins();
2587 return IsPluginLoaded(md.name);
2589 auto end = std::remove_if(available.begin(), available.end(), predicate);
2590 available.erase(end, available.end());
2596 std::string slhs, srhs;
2597 for (
auto& cl : lhs.name) slhs += toupper(cl);
2598 for (
auto& cr : rhs.name) srhs += toupper(cr);
2599 return slhs.compare(srhs) < 0;
2603 std::set<PluginMetadata, CompSort> unique_sorted_entries(comp_sort);
2604 for (
const auto& p : available) unique_sorted_entries.insert(p);
2610 if (p->m_enabled) AddPlugin(*p);
2614 if (!p->m_enabled) AddPlugin(*p);
2617 for (
const auto& p : unique_sorted_entries) AddPlugin(
PlugInData(p));
2625 m_is_loading.clear();
2628void PluginListPanel::AddPlugin(
const std::string& name) {
2631 panel->SetSelected(
false);
2632 GetSizer()->Add(panel, 0, wxEXPAND);
2633 m_PluginItems.Add(panel);
2634 m_pluginSpacer = g_Platform->GetDisplayDPmm() * 1.0;
2635 GetSizer()->AddSpacer(m_pluginSpacer);
2638void PluginListPanel::AddPlugin(
const PlugInData& pic) {
2640 new PluginPanel(
this, wxID_ANY, wxDefaultPosition, wxDefaultSize, pic);
2641 pPluginPanel->SetSelected(
false);
2642 GetSizer()->Add(pPluginPanel, 0, wxEXPAND);
2643 m_PluginItems.Add(pPluginPanel);
2645 m_pluginSpacer = g_Platform->GetDisplayDPmm() * 1.0;
2646 GetSizer()->AddSpacer(m_pluginSpacer);
2659int PluginListPanel::ComputePluginSpace(ArrayOfPluginPanel plugins,
2660 wxBoxSizer* sizer) {
2662 for (
size_t i = 0; i < plugins.GetCount(); i++) {
2663 auto panel = plugins.Item(i);
2664 bool was_selected = panel->GetSelected();
2665 panel->SetSelected(
false);
2667 wxSize unselected = panel->GetSize();
2669 panel->SetSelected(
true);
2671 wxSize selected = panel->GetSize();
2673 int dy = selected.GetHeight() - unselected.GetHeight();
2674 max_dy = wxMax(max_dy, dy);
2675 panel->SetSelected(was_selected);
2680PluginListPanel::~PluginListPanel() {}
2682void PluginListPanel::UpdateSelections() {
2683 for (
unsigned int i = 0; i < m_PluginItems.GetCount(); i++) {
2686 pPluginPanel->SetSelected(pPluginPanel->GetSelected());
2691void PluginListPanel::SelectPlugin(
PluginPanel* pi) {
2693 GetViewStart(&xs, &ys);
2696 if (m_PluginSelected) {
2697 m_PluginSelected->SetSelected(
false);
2698 m_PluginSelected->Layout();
2701 if (pi == NULL) m_PluginSelected->SetSelected(
false);
2703 m_PluginSelected = pi;
2705 GetSizer()->Layout();
2707 wxSize size = GetBestVirtualSize();
2708 SetVirtualSize(size);
2713 for (
unsigned int i = 0; i < m_PluginItems.GetCount(); i++) {
2715 int yd = pPluginPanel->GetSize().y;
2717 htop += m_pluginSpacer;
2718 if (pPluginPanel == pi) {
2719 int piBottom = htop - (ys * g_options->GetScrollRate());
2720 if (piBottom > GetClientSize().y) {
2721 ys += (piBottom - GetClientSize().y) / g_options->GetScrollRate();
2731 int pos = m_PluginItems.Index(pi);
2734 m_PluginItems.RemoveAt(pos);
2737 m_PluginItems.Insert(pi, pos - 1);
2738 wxStaticLine* itemStaticLine =
new wxStaticLine(
2739 this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL);
2744 m_PluginSelected = pi;
2746 GetSizer()->Layout();
2752 int pos = m_PluginItems.Index(pi);
2753 if (pos == (
int)m_PluginItems.Count() -
2756 m_PluginItems.RemoveAt(pos);
2759 m_PluginItems.Insert(pi, pos + 1);
2760 wxStaticLine* itemStaticLine =
new wxStaticLine(
2761 this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL);
2766 m_PluginSelected = pi;
2768 GetSizer()->Layout();
2773static bool canUninstall(std::string name) {
2778 if (plugin.name == name) {
2779 if (safe_mode::get_mode())
2782 return !plugin.readonly;
2789 : wxPanel(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize,
2791 m_is_safe_panel(true) {
2793 wxASSERT(m_PluginListPanel != 0);
2794 wxBoxSizer* top_sizer =
new wxBoxSizer(wxVERTICAL);
2795 SetSizer(top_sizer);
2796 wxBoxSizer* top_horizontal =
new wxBoxSizer(wxHORIZONTAL);
2797 top_sizer->Add(top_horizontal, 0, wxEXPAND);
2799 double iconSize = GetCharWidth() * 4;
2801 int icon_scale = iconSize * dpi_mult;
2803 wxBitmap bitmap(style->GetIcon(
"default_pi", icon_scale, icon_scale));
2804 m_itemStaticBitmap =
new wxStaticBitmap(
this, wxID_ANY, bitmap);
2805 top_horizontal->Add(m_itemStaticBitmap, 0, wxEXPAND | wxALL, 10);
2807 m_pName =
new wxStaticText(
this, wxID_ANY, name);
2808 top_horizontal->Add(m_pName, wxID_ANY, wxALIGN_CENTER_VERTICAL);
2809 m_pVersion =
new wxStaticText(
this, wxID_ANY,
"");
2810 top_horizontal->Add(m_pVersion);
2813 m_pButtons =
new wxBoxSizer(wxHORIZONTAL);
2814 top_horizontal->Add(m_pButtons);
2815 m_info_btn =
new WebsiteButton(
this,
"https:\\opencpn.org");
2816 top_horizontal->Add(m_info_btn);
2817 m_pButtonUninstall =
new wxButton(
this, wxID_ANY, _(
"Uninstall"),
2818 wxDefaultPosition, wxDefaultSize, 0);
2819 top_horizontal->Add(m_pButtonUninstall, 0, wxALIGN_CENTER_VERTICAL | wxALL,
2821 auto uninstall = [&](wxCommandEvent ev) {
2822 auto n = m_pName->GetLabel().ToStdString();
2824 OCPNMessageBox(gFrame, std::string(_(
"Uninstall plugin ")) + n +
"?",
2825 _(
"Un-Installation"), wxICON_QUESTION | wxOK | wxCANCEL);
2826 if (result != wxID_OK)
return;
2830 m_pButtonUninstall->Bind(wxEVT_COMMAND_BUTTON_CLICKED, uninstall);
2834EVT_PAINT(PluginPanel::OnPaint)
2839 : wxPanel(parent,
id, pos, size, wxBORDER_NONE),
2841 m_is_safe_panel(false) {
2844 wxASSERT(m_PluginListPanel != 0);
2846 m_bSelected =
false;
2847 m_penWidthUnselected = g_Platform->GetDisplayDPmm() * .25;
2848 m_penWidthSelected = g_Platform->GetDisplayDPmm() * .5;
2850 wxBoxSizer* topSizer =
new wxBoxSizer(wxVERTICAL);
2853 wxBoxSizer* itemBoxSizer01 =
new wxBoxSizer(wxHORIZONTAL);
2854 topSizer->Add(itemBoxSizer01, 0, wxEXPAND);
2855 Bind(wxEVT_LEFT_DOWN, &PluginPanel::OnPluginSelected,
this);
2856 Bind(wxEVT_LEFT_UP, &PluginPanel::OnPluginSelectedUp,
this);
2858 double iconSize = GetCharWidth() * 4;
2860 int icon_scale = iconSize * dpi_mult;
2862 wxImage plugin_icon;
2864 if (m_plugin.m_bitmap.IsOk()) {
2865 plugin_icon = m_plugin.m_bitmap.ConvertToImage();
2868 if (m_plugin.m_status == PluginStatus::ManagedInstallAvailable) {
2869 wxFileName path(g_Platform->GetSharedDataDir(),
"packageBox.svg");
2870 path.AppendDir(
"uidata");
2871 path.AppendDir(
"traditional");
2872 bitmap = LoadSVG(path.GetFullPath(), icon_scale, icon_scale);
2873 }
else if (plugin_icon.IsOk()) {
2874 int nowSize = plugin_icon.GetWidth();
2875 plugin_icon.Rescale(icon_scale, icon_scale, wxIMAGE_QUALITY_HIGH);
2876 bitmap = wxBitmap(plugin_icon);
2878 bitmap = wxBitmap(style->GetIcon(
"default_pi", icon_scale, icon_scale));
2880 m_itemStaticBitmap =
new wxStaticBitmap(
this, wxID_ANY, bitmap);
2882 itemBoxSizer01->Add(m_itemStaticBitmap, 0, wxEXPAND | wxALL, 10);
2883 m_itemStaticBitmap->Bind(wxEVT_LEFT_DOWN, &PluginPanel::OnPluginSelected,
2885 m_itemStaticBitmap->Bind(wxEVT_LEFT_UP, &PluginPanel::OnPluginSelectedUp,
2888 wxBoxSizer* itemBoxSizer02 =
new wxBoxSizer(wxVERTICAL);
2889 itemBoxSizer01->Add(itemBoxSizer02, 1, wxEXPAND | wxALL, 0);
2892 int nChars = g_options->GetSize().x / GetCharWidth();
2893 bool bCompact =
false;
2899 wxString nameString = m_plugin.m_common_name;
2903 dc.GetTextExtent(m_plugin.m_common_name, &nameWidth, NULL);
2904 if (nameWidth > maxWidth) {
2905 nameString = wxControl::Ellipsize(m_plugin.m_common_name, dc,
2906 wxELLIPSIZE_END, maxWidth);
2908 m_pName =
new wxStaticText(
this, wxID_ANY, nameString);
2909 m_pName->Bind(wxEVT_LEFT_DOWN, &PluginPanel::OnPluginSelected,
this);
2910 m_pName->Bind(wxEVT_LEFT_UP, &PluginPanel::OnPluginSelectedUp,
this);
2911 itemBoxSizer02->Add(m_pName, 0, wxALL, 5);
2913 wxFlexGridSizer* sl1 =
new wxFlexGridSizer(2, 0, 0);
2914 sl1->AddGrowableCol(1);
2915 itemBoxSizer02->Add(sl1, 0, wxEXPAND);
2917 m_pVersion =
new wxStaticText(
this, wxID_ANY,
"X.YY.ZZ.AA");
2918 sl1->Add(m_pVersion, 0, wxALL, 5);
2919 if (m_plugin.m_status == PluginStatus::ManagedInstallAvailable) {
2922 m_pVersion->Bind(wxEVT_LEFT_DOWN, &PluginPanel::OnPluginSelected,
this);
2923 m_pVersion->Bind(wxEVT_LEFT_UP, &PluginPanel::OnPluginSelectedUp,
this);
2925 m_cbEnable =
new wxCheckBox(
this, wxID_ANY, _(
"Enabled"));
2926 sl1->Add(m_cbEnable, 1, wxALIGN_RIGHT | wxTOP, 5);
2927 m_cbEnable->Bind(wxEVT_CHECKBOX, &PluginPanel::OnPluginEnableToggle,
this);
2930 wxString descriptionString = m_plugin.m_short_description;
2931 int maxDescriptionWidth = g_Platform->
getDisplaySize().x - (iconSize * 4);
2932 int descriptionWidth;
2933 dc.GetTextExtent(m_plugin.m_short_description, &descriptionWidth, NULL);
2934 if (descriptionWidth > maxDescriptionWidth)
2936 wxControl::Ellipsize(m_plugin.m_short_description, dc,
2937 wxELLIPSIZE_END, maxDescriptionWidth);
2942 new wxStaticText(
this, wxID_ANY, descriptionString, wxDefaultPosition,
2943 wxSize(maxDescriptionWidth, -1), wxST_NO_AUTORESIZE);
2944 itemBoxSizer02->Add(m_pDescription, 0, wxEXPAND | wxALL, 5);
2945 m_pDescription->Bind(wxEVT_LEFT_DOWN, &PluginPanel::OnPluginSelected,
this);
2946 m_pDescription->Bind(wxEVT_LEFT_UP, &PluginPanel::OnPluginSelectedUp,
this);
2949 wxFlexGridSizer* itemBoxSizer03 =
new wxFlexGridSizer(4, 0, 0);
2950 itemBoxSizer03->AddGrowableCol(2);
2951 itemBoxSizer02->Add(itemBoxSizer03, 0, wxEXPAND);
2953 wxString nameString = m_plugin.m_common_name;
2954 m_pName =
new wxStaticText(
this, wxID_ANY, nameString);
2955 m_pName->Bind(wxEVT_LEFT_DOWN, &PluginPanel::OnPluginSelected,
this);
2956 m_pName->Bind(wxEVT_LEFT_UP, &PluginPanel::OnPluginSelectedUp,
this);
2960 wxFont font = GetFont();
2961 font.SetWeight(wxFONTWEIGHT_BOLD);
2962 m_pName->SetFont(font);
2965 itemBoxSizer03->Add(m_pName, 0, wxALL, 10);
2967 m_pVersion =
new wxStaticText(
this, wxID_ANY,
"X.YY.ZZ.AA");
2968 itemBoxSizer03->Add(m_pVersion, 0, wxALL, 10);
2969 if (m_plugin.m_status == PluginStatus::ManagedInstallAvailable ||
2972 !m_plugin.m_managed_metadata.is_orphan)) {
2975 m_pVersion->Bind(wxEVT_LEFT_DOWN, &PluginPanel::OnPluginSelected,
this);
2976 m_pVersion->Bind(wxEVT_LEFT_UP, &PluginPanel::OnPluginSelectedUp,
this);
2978 m_cbEnable =
new wxCheckBox(
this, wxID_ANY, _(
"Enabled"));
2979 itemBoxSizer03->Add(m_cbEnable, 1, wxALIGN_RIGHT | wxTOP, 10);
2980 m_cbEnable->Bind(wxEVT_CHECKBOX, &PluginPanel::OnPluginEnableToggle,
this);
2982 itemBoxSizer03->Add(5 * GetCharWidth(), 1, 0, wxALIGN_RIGHT | wxTOP, 10);
2984 m_pDescription =
new wxStaticText(
2985 this, wxID_ANY, m_plugin.m_short_description, wxDefaultPosition,
2987 itemBoxSizer02->Add(m_pDescription, 1, wxEXPAND | wxALL, 5);
2988 m_pDescription->Bind(wxEVT_LEFT_DOWN, &PluginPanel::OnPluginSelected,
this);
2989 m_pDescription->Bind(wxEVT_LEFT_UP, &PluginPanel::OnPluginSelectedUp,
this);
2993 m_info_btn =
new WebsiteButton(
this,
"https:\\opencpn.org");
2995 itemBoxSizer02->Add(m_info_btn, 0);
2997 m_pButtons =
new wxBoxSizer(wxHORIZONTAL);
2998 itemBoxSizer02->Add(m_pButtons, 0, wxALL, 0);
2999 m_pButtonPreferences =
new wxButton(
this, wxID_ANY, _(
"Preferences"),
3000 wxDefaultPosition, wxDefaultSize, 0);
3001 m_pButtons->Add(m_pButtonPreferences, 0, wxALIGN_LEFT | wxALL, 2);
3003 m_pButtons->AddSpacer(3 * GetCharWidth());
3006 new wxButton(
this, wxID_ANY,
"Upgrade to Version XX.XX.XX",
3007 wxDefaultPosition, wxDefaultSize, 0);
3008 m_pButtons->Add(m_pButtonAction, 0, wxALIGN_LEFT | wxALL, 2);
3010 m_pButtonUninstall =
new wxButton(
this, wxID_ANY, _(
"Uninstall"),
3011 wxDefaultPosition, wxDefaultSize, 0);
3012 m_pButtons->Add(m_pButtonUninstall, 0, wxALIGN_LEFT | wxALL, 2);
3014 m_pButtons =
new wxBoxSizer(wxVERTICAL);
3015 itemBoxSizer02->Add(m_pButtons, 0, wxALL, 0);
3017 wxBoxSizer* tline =
new wxBoxSizer(wxHORIZONTAL);
3018 m_pButtons->Add(tline, 0, wxALL, 2);
3020 m_pButtonPreferences =
new wxButton(
this, wxID_ANY, _(
"Preferences"),
3021 wxDefaultPosition, wxDefaultSize, 0);
3022 tline->Add(m_pButtonPreferences, 0, wxALIGN_LEFT | wxALL, 0);
3024 tline->AddSpacer(3 * GetCharWidth());
3026 m_info_btn =
new WebsiteButton(
this,
"https:\\opencpn.org");
3028 tline->Add(m_info_btn, 0);
3031 new wxButton(
this, wxID_ANY,
"Upgrade to Version XX.XX.XX",
3032 wxDefaultPosition, wxDefaultSize);
3033 m_pButtons->Add(m_pButtonAction, 0, wxALIGN_LEFT | wxALL, 2);
3035 m_pButtonUninstall =
new wxButton(
this, wxID_ANY, _(
"Uninstall"),
3036 wxDefaultPosition, wxDefaultSize, 0);
3037 m_pButtons->Add(m_pButtonUninstall, 0, wxALIGN_LEFT | wxALL, 2);
3040 wxBitmap statusBitmap;
3041 const auto stat = m_plugin.m_status;
3042 auto icon_name = icon_by_status.at(stat);
3043 if (stat == PluginStatus::Imported &&
3044 IsUpdateAvailable(m_plugin.m_managed_metadata)) {
3046 icon_by_status.at(PluginStatus::ManagedInstalledUpdateAvailable);
3049 wxFileName path(g_Platform->GetSharedDataDir(), icon_name);
3050 path.AppendDir(
"uidata");
3051 path.AppendDir(
"traditional");
3053 int bmsize = GetCharWidth() * 3 * dpi_mult;
3054 if (path.IsFileReadable()) {
3055 statusBitmap = LoadSVG(path.GetFullPath(), bmsize, bmsize);
3056 ok = statusBitmap.IsOk();
3059 auto style = g_StyleManager->GetCurrentStyle();
3060 statusBitmap = wxBitmap(style->GetIcon(
"default_pi", bmsize, bmsize));
3061 wxLogMessage(
"Icon: %s not found.", path.GetFullPath());
3064 m_itemStatusIconBitmap =
new wxStaticBitmap(
this, wxID_ANY, statusBitmap);
3065 m_itemStatusIconBitmap->SetToolTip(message_by_status(stat));
3066 m_itemStatusIconBitmap->Bind(wxEVT_LEFT_DOWN, &PluginPanel::OnPluginSelected,
3068 m_itemStatusIconBitmap->Bind(wxEVT_LEFT_UP, &PluginPanel::OnPluginSelectedUp,
3071 itemBoxSizer01->Add(m_itemStatusIconBitmap, 0, wxEXPAND | wxALL, 20);
3073 itemBoxSizer02->AddSpacer(GetCharWidth());
3075 m_pButtonPreferences->Bind(wxEVT_COMMAND_BUTTON_CLICKED,
3076 &PluginPanel::OnPluginPreferences,
this);
3077 m_pButtonUninstall->Bind(wxEVT_COMMAND_BUTTON_CLICKED,
3078 &PluginPanel::OnPluginUninstall,
this);
3079 m_pButtonAction->Bind(wxEVT_COMMAND_BUTTON_CLICKED,
3080 &PluginPanel::OnPluginAction,
this);
3082 SetSelected(m_bSelected);
3083 SetAutoLayout(
true);
3091PluginPanel::~PluginPanel() {
3092 Unbind(wxEVT_LEFT_DOWN, &PluginPanel::OnPluginSelected,
this);
3093 if (m_is_safe_panel)
return;
3094 m_itemStaticBitmap->Unbind(wxEVT_LEFT_DOWN, &PluginPanel::OnPluginSelected,
3096 m_pName->Unbind(wxEVT_LEFT_DOWN, &PluginPanel::OnPluginSelected,
this);
3097 m_pVersion->Unbind(wxEVT_LEFT_DOWN, &PluginPanel::OnPluginSelected,
this);
3098 m_pDescription->Unbind(wxEVT_LEFT_DOWN, &PluginPanel::OnPluginSelected,
this);
3099 if (m_pButtonAction) {
3100 m_pButtonAction->Unbind(wxEVT_COMMAND_BUTTON_CLICKED,
3101 &PluginPanel::OnPluginAction,
this);
3103 m_pButtonPreferences->Unbind(wxEVT_COMMAND_BUTTON_CLICKED,
3104 &PluginPanel::OnPluginPreferences,
this);
3105 m_cbEnable->Unbind(wxEVT_COMMAND_BUTTON_CLICKED,
3106 &PluginPanel::OnPluginEnableToggle,
this);
3109void PluginPanel::SetActionLabel(wxString& label) {
3110 m_pButtonAction->SetLabel(label);
3114static wxStopWatch swclick;
3115static int downx, downy;
3117void PluginPanel::OnPluginSelected(wxMouseEvent& event) {
3120 event.GetPosition(&downx, &downy);
3126void PluginPanel::OnPluginSelectedUp(wxMouseEvent& event) {
3128 qDebug() << swclick.Time();
3129 if (swclick.Time() < 200) {
3131 event.GetPosition(&upx, &upy);
3132 if ((fabs(upx - downx) < GetCharWidth()) &&
3133 (fabs(upy - downy) < GetCharWidth())) {
3141void PluginPanel::DoPluginSelect() {
3142 if (m_plugin.m_status == PluginStatus::ManagedInstallAvailable) {
3148 run_update_dialog(m_PluginListPanel, &m_plugin,
false, 0,
true);
3149 }
else if (m_bSelected) {
3151 m_PluginListPanel->SelectPlugin(NULL);
3154 m_PluginListPanel->SelectPlugin(
this);
3162static PluginMetadata GetMetadataByName(
const std::string& name) {
3164 auto predicate = [name](
const PluginMetadata& pm) {
return pm.name == name; };
3165 auto found = std::find_if(plugins.begin(), plugins.end(), predicate);
3166 if (found == plugins.end()) {
3167 wxLogDebug(
"Cannot find metadata for %s", name.c_str());
3172void PluginPanel::SetSelected(
bool selected) {
3173 m_bSelected = selected;
3175 m_pVersion->SetLabel(
3179 m_pButtons->Show(
true);
3180 bool unInstallPossible = canUninstall(m_plugin.
m_common_name.ToStdString());
3183 if (m_plugin.m_status == PluginStatus::LegacyUpdateAvailable ||
3186 unInstallPossible =
false;
3189 if (m_plugin.m_managed_metadata.is_orphan) unInstallPossible =
true;
3191 m_pButtonUninstall->Show(unInstallPossible);
3193 if (m_plugin.m_managed_metadata.info_url.size()) {
3194 m_info_btn->SetURL(m_plugin.m_managed_metadata.info_url.c_str());
3198 m_cbEnable->Show(
true);
3203 switch (m_plugin.m_status) {
3204 case PluginStatus::LegacyUpdateAvailable:
3205 label = _(
"Upgrade to Version ");
3206 label += wxString(m_plugin.m_managed_metadata.version.c_str());
3207 m_action = ActionVerb::UPGRADE_TO_MANAGED_VERSION;
3208 m_pButtonAction->Enable();
3211 case PluginStatus::ManagedInstallAvailable:
3212 label = _(
"Install...");
3213 m_action = ActionVerb::INSTALL_MANAGED_VERSION;
3214 m_pButtonAction->Enable();
3217 case PluginStatus::ManagedInstalledUpdateAvailable:
3218 label = _(
"Update to ");
3219 label += wxString(m_plugin.m_managed_metadata.version.c_str());
3220 m_action = ActionVerb::UPGRADE_INSTALLED_MANAGED_VERSION;
3221 m_pButtonAction->Enable();
3224 case PluginStatus::ManagedInstalledCurrentVersion:
3225 label = _(
"Reinstall");
3226 m_action = ActionVerb::REINSTALL_MANAGED_VERSION;
3227 m_pButtonAction->Enable();
3230 case PluginStatus::ManagedInstalledDowngradeAvailable:
3231 label = _(
"Downgrade");
3232 m_action = ActionVerb::DOWNGRADE_INSTALLED_MANAGED_VERSION;
3233 m_pButtonAction->Enable();
3236 case PluginStatus::Imported:
3237 if (IsUpdateAvailable(m_plugin.m_managed_metadata)) {
3238 label = _(
"Update");
3239 m_action = ActionVerb::UPDATE_IMPORTED_VERSION;
3241 m_pButtonAction->Hide();
3242 m_action = ActionVerb::NOP;
3247 m_action = ActionVerb::NOP;
3248 m_pButtonAction->Hide();
3252 m_action = ActionVerb::NOP;
3253 m_pButtonAction->Hide();
3258 m_action = ActionVerb::NOP;
3261 SetActionLabel(label);
3273 m_pButtons->Show(
false);
3276 if (m_plugin.m_status == PluginStatus::ManagedInstallAvailable)
3277 m_cbEnable->Show(
false);
3298 SetEnabled(m_plugin.m_enabled);
3313void PluginPanel::OnPaint(wxPaintEvent& event) {
3316 int penWidth = m_penWidthUnselected;
3321 penWidth = m_penWidthSelected;
3326 wxBrush b(color, wxBRUSHSTYLE_SOLID);
3328 dc.SetPen(wxPen(border, penWidth));
3330 dc.DrawRoundedRectangle(5, 5, GetSize().x - 10, GetSize().y - 10, 5);
3333void PluginPanel::OnPluginPreferences(wxCommandEvent& event) {
3334 if (m_plugin.m_enabled && m_plugin.m_init_state &&
3337 androidDisableRotation();
3348void PluginPanel::OnPluginEnableToggle(wxCommandEvent& event) {
3349 g_Platform->ShowBusySpinner();
3350 SetEnabled(event.IsChecked());
3351 m_pVersion->SetLabel(
3358 g_Platform->HideBusySpinner();
3361void PluginPanel::OnPluginUninstall(wxCommandEvent& event) {
3362 m_action = ActionVerb::UNINSTALL_MANAGED_VERSION;
3365 wxCommandEvent actionEvent(wxEVT_COMMAND_BUTTON_CLICKED);
3366 actionEvent.SetId(ID_CMD_BUTTON_PERFORM_ACTION);
3367 actionEvent.SetClientData(
this);
3368 g_pi_manager->GetUtilHandler()->AddPendingEvent(actionEvent);
3371void PluginPanel::OnPluginAction(wxCommandEvent& event) {
3373 wxCommandEvent actionEvent(wxEVT_COMMAND_BUTTON_CLICKED);
3374 actionEvent.SetId(ID_CMD_BUTTON_PERFORM_ACTION);
3375 actionEvent.SetClientData(
this);
3376 g_pi_manager->GetUtilHandler()->AddPendingEvent(actionEvent);
3381static void SetWindowFontStyle(wxWindow* window, wxFontStyle style) {
3382 auto font = window->GetFont();
3383 font.SetStyle(style);
3384 window->SetFont(font);
3387void PluginPanel::SetEnabled(
bool enabled) {
3388 if (m_is_safe_panel)
return;
3391 if (enabled) NotifySetupOptionsPlugin(&m_plugin);
3392 if (!enabled && !m_bSelected) {
3393 SetWindowFontStyle(m_pName, wxFONTSTYLE_ITALIC);
3394 SetWindowFontStyle(m_pVersion, wxFONTSTYLE_ITALIC);
3395 SetWindowFontStyle(m_pDescription, wxFONTSTYLE_ITALIC);
3398 m_pVersion->Disable();
3399 m_pDescription->Disable();
3402 SetWindowFontStyle(m_pName, wxFONTSTYLE_NORMAL);
3403 SetWindowFontStyle(m_pVersion, wxFONTSTYLE_NORMAL);
3404 SetWindowFontStyle(m_pDescription, wxFONTSTYLE_NORMAL);
3407 m_pVersion->Enable();
3408 m_pDescription->Enable();
3413 m_pName->Enable(enabled || m_bSelected);
3414 m_pVersion->Enable(enabled || m_bSelected);
3415 m_pDescription->Enable(enabled || m_bSelected);
3419 wxString description = m_plugin.m_long_description;
3420 if (description.IsEmpty())
3421 description = wxString(m_plugin.m_managed_metadata.description.c_str());
3424 g_options->GetSize().x * 7 / 10);
3425 m_pDescription->SetLabel(wrapper.GetWrapped());
3426 if (m_plugin.m_managed_metadata.info_url.size()) {
3427 m_info_btn->SetURL(m_plugin.m_managed_metadata.info_url.c_str());
3431 wxString description = m_plugin.m_short_description;
3432 if (description.IsEmpty())
3433 description = wxString(m_plugin.m_managed_metadata.summary.c_str());
3435 g_options->GetSize().x * 7 / 10);
3436 m_pDescription->SetLabel(wrapper.GetWrapped());
3439 m_pButtonPreferences->Enable(enabled &&
3441 m_cbEnable->SetValue(enabled);
3444void PluginPanel::OnPluginUp(wxCommandEvent& event) {
3445 m_PluginListPanel->MoveUp(
this);
3448void PluginPanel::OnPluginDown(wxCommandEvent& event) {
3449 m_PluginListPanel->MoveDown(
this);
3454 : wxPanel(parent), m_url(url) {
3455 auto vbox =
new wxBoxSizer(wxVERTICAL);
3456 auto button =
new wxButton(
this, wxID_ANY, _(
"Website"));
3457 button->Enable(strlen(url) > 0);
3460 Bind(wxEVT_COMMAND_BUTTON_CLICKED,
3461 [=](wxCommandEvent&) { wxLaunchDefaultBrowser(m_url); });
3469PlugInChartBase::PlugInChartBase() { m_Chart_Error_Factor = 0.; }
3471PlugInChartBase::~PlugInChartBase() {}
3480 bool b_allow_overzoom) {
3492 const wxRegion& Region) {
3493 return wxNullBitmap;
3502 wxRegion* pValidRegion) {}
3515 wxRect* pSourceRect) {}
3532 double* plat,
double* plon) {}
3539PlugInChartBaseGL::PlugInChartBaseGL() {}
3541PlugInChartBaseGL::~PlugInChartBaseGL() {}
3545 const wxRegion& Region,
3546 bool b_use_stencil) {
3572PlugInChartBaseExtended::PlugInChartBaseExtended() {}
3574PlugInChartBaseExtended::~PlugInChartBaseExtended() {}
3578 const wxRegion& Region,
3579 bool b_use_stencil) {
3585 const wxRegion& Region,
bool b_use_stencil) {
3591 const wxRegion& Region,
bool b_use_stencil) {
3597 return wxNullBitmap;
3601 wxMemoryDC& dc,
const PlugIn_ViewPort& VPoint,
const wxRegion& Region) {
3605ListOfPI_S57Obj* PlugInChartBaseExtended::GetObjRuleListAtLatLon(
3610wxString PlugInChartBaseExtended::CreateObjDescriptions(
3611 ListOfPI_S57Obj* obj_list) {
3615int PlugInChartBaseExtended::GetNoCOVREntries() {
return 0; }
3617int PlugInChartBaseExtended::GetNoCOVRTablePoints(
int iTable) {
return 0; }
3619int PlugInChartBaseExtended::GetNoCOVRTablenPoints(
int iTable) {
return 0; }
3621float* PlugInChartBaseExtended::GetNoCOVRTableHead(
int iTable) {
return 0; }
3630PlugInChartBaseExtendedPlus2::PlugInChartBaseExtendedPlus2() {}
3632PlugInChartBaseExtendedPlus2::~PlugInChartBaseExtendedPlus2() {}
3635PlugInChartBaseExtendedPlus2::GetLightsObjRuleListVisibleAtLatLon(
3645PlugInChartBaseGLPlus2::PlugInChartBaseGLPlus2() {}
3647PlugInChartBaseGLPlus2::~PlugInChartBaseGLPlus2() {}
3659ChartPlugInWrapper::ChartPlugInWrapper() {}
3661ChartPlugInWrapper::ChartPlugInWrapper(
const wxString& chart_class) {
3662 m_ppo = ::wxCreateDynamicObject(chart_class);
3666ChartPlugInWrapper::~ChartPlugInWrapper() {
3667 if (m_ppicb)
delete m_ppicb;
3670wxString ChartPlugInWrapper::GetFileSearchMask(
void) {
3677InitReturn ChartPlugInWrapper::Init(
const wxString& name,
3678 ChartInitFlag init_flags) {
3680 wxWindow* pa = wxWindow::FindFocus();
3682 InitReturn ret_val = (InitReturn)m_ppicb->
Init(name, (
int)init_flags);
3686 if (ret_val == INIT_OK) {
3693 m_ID = m_ppicb->
GetID();
3697 m_SE = m_ppicb->
GetSE();
3711 if ((fabs(m_Chart_Skew) < .01) &&
3712 (CHART_FAMILY_RASTER == m_ChartFamily)) {
3714 if (GetChartExtent(&extent)) {
3715 double lon_range = extent.ELON - extent.WLON;
3716 if ((lon_range > 0) &&
3718 m_ppm_avg = GetSize_X() / (lon_range * 1852 * 60);
3722 m_overlayENC =
false;
3724 wxCharBuffer buf = m_FullPath.ToUTF8();
3725 m_overlayENC = s57chart::IsCellOverlayType(buf.data());
3731 m_ChartType = CHART_TYPE_UNKNOWN;
3732 m_ChartFamily = CHART_FAMILY_UNKNOWN;
3738 if (pc) pc->SetFocus();
3742 return INIT_FAIL_REMOVE;
3746int ChartPlugInWrapper::GetCOVREntries() {
3753int ChartPlugInWrapper::GetCOVRTablePoints(
int iTable) {
3760int ChartPlugInWrapper::GetCOVRTablenPoints(
int iTable) {
3767float* ChartPlugInWrapper::GetCOVRTableHead(
int iTable) {
3779int ChartPlugInWrapper::GetNoCOVREntries() {
3789int ChartPlugInWrapper::GetNoCOVRTablePoints(
int iTable) {
3799int ChartPlugInWrapper::GetNoCOVRTablenPoints(
int iTable) {
3809float* ChartPlugInWrapper::GetNoCOVRTableHead(
int iTable) {
3819bool ChartPlugInWrapper::GetChartExtent(
Extent* pext) {
3823 pext->NLAT = xpi.
NLAT;
3824 pext->SLAT = xpi.
SLAT;
3825 pext->ELON = xpi.
ELON;
3826 pext->WLON = xpi.
WLON;
3835ThumbData* ChartPlugInWrapper::GetThumbData(
int tnx,
int tny,
float lat,
3840 if (!pThumbData->pDIBThumb) {
3841 wxBitmap* pBMPOwnedByChart =
3842 m_ppicb->
GetThumbnail(tnx, tny, m_global_color_scheme);
3843 if (pBMPOwnedByChart) {
3844 wxImage img = pBMPOwnedByChart->ConvertToImage();
3845 pThumbData->pDIBThumb =
new wxBitmap(img);
3847 pThumbData->pDIBThumb = NULL;
3850 pThumbData->Thumb_Size_X = tnx;
3851 pThumbData->Thumb_Size_Y = tny;
3878 pThumbData->ShipX = 0;
3879 pThumbData->ShipY = 0;
3886ThumbData* ChartPlugInWrapper::GetThumbData() {
return pThumbData; }
3888bool ChartPlugInWrapper::UpdateThumbData(
double lat,
double lon) {
3892double ChartPlugInWrapper::GetNormalScaleMin(
double canvas_scale_factor,
3893 bool b_allow_overzoom) {
3900double ChartPlugInWrapper::GetNormalScaleMax(
double canvas_scale_factor,
3922void RenderRotateToViewPort(
const ViewPort& VPoint) {
3923#ifndef USE_ANDROID_GLES2
3925 glTranslatef(xt, yt, 0);
3926 glRotatef(VPoint.
rotation * 180. / PI, 0, 0, 1);
3927 glTranslatef(-xt, -yt, 0);
3931void UndoRenderRotateToViewPort(
const ViewPort& VPoint) {
3932#ifndef USE_ANDROID_GLES2
3934 glTranslatef(xt, yt, 0);
3935 glRotatef(-VPoint.
rotation * 180. / PI, 0, 0, 1);
3936 glTranslatef(-xt, -yt, 0);
3940bool ChartPlugInWrapper::RenderRegionViewOnGL(
const wxGLContext& glc,
3943 const LLRegion& Region) {
3952 if (!Region.Empty() && (ppicb_gl || ppicb_x)) {
3953 wxRegion* r = RectRegion.GetNew_wxRegion();
3956 LLRegion chart_region = vp.GetLLRegion(upd.GetRect());
3957 chart_region.Intersect(Region);
3959 if (!chart_region.Empty()) {
3960 ViewPort cvp = glChartCanvas::ClippedViewport(VPoint, chart_region);
3962 glChartCanvas::SetClipRect(cvp, upd.GetRect(),
false);
3966#ifndef USE_ANDROID_GLES2
3969 RenderRotateToViewPort(VPoint);
3974 glChartCanvas::s_b_useStencil);
3977 glChartCanvas::s_b_useStencil);
3978 UndoRenderRotateToViewPort(VPoint);
3980#ifndef USE_ANDROID_GLES2
3983 glChartCanvas::DisableClipRegion();
3997bool ChartPlugInWrapper::RenderRegionViewOnGLNoText(
3998 const wxGLContext& glc,
const ViewPort& VPoint,
3999 const OCPNRegion& RectRegion,
const LLRegion& Region) {
4008 if (!Region.Empty() && ppicb_x) {
4010 glChartCanvas::SetClipRect(VPoint, VPoint.rv_rect,
false);
4011 glChartCanvas::DisableClipRegion();
4014 RenderRotateToViewPort(VPoint);
4017 wxRegion* r = RectRegion.GetNew_wxRegion();
4020 glChartCanvas::s_b_useStencil);
4023 UndoRenderRotateToViewPort(VPoint);
4028 else if (!Region.Empty() &&
4032 wxRegion* r = RectRegion.GetNew_wxRegion();
4035 LLRegion chart_region = vp.GetLLRegion(upd.GetRect());
4036 chart_region.Intersect(Region);
4038 if (!chart_region.Empty()) {
4039 ViewPort cvp = glChartCanvas::ClippedViewport(VPoint, chart_region);
4041 glChartCanvas::SetClipRect(cvp, upd.GetRect(),
false);
4043 RenderRotateToViewPort(VPoint);
4047 glChartCanvas::s_b_useStencil);
4050 UndoRenderRotateToViewPort(VPoint);
4052 glChartCanvas::DisableClipRegion();
4065bool ChartPlugInWrapper::RenderRegionViewOnGLTextOnly(
4072 if (!Region.Empty() && ppicb_x) {
4073 wxRegion* r = Region.GetNew_wxRegion();
4075#ifndef USE_ANDROID_GLES2
4078 RenderRotateToViewPort(VPoint);
4082 glChartCanvas::s_b_useStencil);
4083 UndoRenderRotateToViewPort(VPoint);
4085#ifndef USE_ANDROID_GLES2
4098bool ChartPlugInWrapper::RenderRegionViewOnDC(wxMemoryDC& dc,
4104 if (Region.IsOk()) {
4105 wxRegion* r = Region.GetNew_wxRegion();
4112 wxColour nodat = GetGlobalColor(_T (
"NODTA" ));
4113 wxColour nodat_sub = nodat;
4115#ifdef ocpnUSE_ocpnBitmap
4116 nodat_sub = wxColour(nodat.Blue(), nodat.Green(), nodat.Red());
4118 m_pMask =
new wxMask(obmp, nodat_sub);
4119 obmp.SetMask(m_pMask);
4121 dc.SelectObject(obmp);
4132bool ChartPlugInWrapper::RenderRegionViewOnDCNoText(wxMemoryDC& dc,
4143 if (Region.IsOk() && (pCBx || ppicb)) {
4144 wxRegion* r = Region.GetNew_wxRegion();
4159bool ChartPlugInWrapper::RenderRegionViewOnDCTextOnly(
4162 bool ret_val =
false;
4165 if (Region.IsOk()) {
4166 wxRegion* r = Region.GetNew_wxRegion();
4180void ChartPlugInWrapper::ClearPLIBTextList() {
4188bool ChartPlugInWrapper::AdjustVP(
ViewPort& vp_last,
ViewPort& vp_proposed) {
4192 return m_ppicb->
AdjustVP(pivp_last, pivp_proposed);
4197void ChartPlugInWrapper::GetValidCanvasRegion(
const ViewPort& VPoint,
4212void ChartPlugInWrapper::SetColorScheme(ColorScheme cs,
bool bApplyImmediate) {
4216 m_global_color_scheme = cs;
4218 if (pThumbData) pThumbData->pDIBThumb = NULL;
4222 double target_scale_ppm) {
4229void ChartPlugInWrapper::ComputeSourceRectangle(
const ViewPort& VPoint,
4230 wxRect* pSourceRect) {
4237double ChartPlugInWrapper::GetRasterScaleFactor(
const ViewPort& vp) {
4239 return (wxRound(100000 * GetPPM() / vp.
view_scale_ppm)) / 100000.;
4244bool ChartPlugInWrapper::GetChartBits(wxRect& source,
unsigned char* pPix,
4246 wxCriticalSectionLocker locker(m_critSect);
4255int ChartPlugInWrapper::GetSize_X() {
4262int ChartPlugInWrapper::GetSize_Y() {
4269void ChartPlugInWrapper::latlong_to_chartpix(
double lat,
double lon,
4270 double& pixx,
double& pixy) {
4274void ChartPlugInWrapper::chartpix_to_latlong(
double pixx,
double pixy,
4275 double* plat,
double* plon) {
4290 return toSDMM(NEflag, a, hi_precision);
4294 return GetGlobalColor(colorName);
4298 const wxString& caption,
int style,
int x,
int y) {
4299 return OCPNMessageBox(parent, message, caption, style, 100, x, y);
4307 return g_Platform->GetWritableDocumentsDir();
4312 auto loader = PluginLoader::GetInstance();
4313 for (
unsigned int i = 0; i < loader->GetPlugInArray()->GetCount(); i++) {
4315 if (pic->m_pplugin == pplugin) {
4325ListOfPI_S57Obj* PlugInManager::GetPlugInObjRuleListAtLatLon(
4328 ListOfPI_S57Obj* list = NULL;
4342 list = picbx->GetObjRuleListAtLatLon(zlat, zlon, SelectRadius, &pi_vp);
4352 ListOfPI_S57Obj* rule_list) {
4363 ret_str = picbx->CreateObjDescriptions(rule_list);
4377 return ps52plib->m_nDepthUnitDisplay;
4384 return ps52plib->m_nSymbolStyle;
4391 return ps52plib->m_nBoundaryStyle;
4401 CreateCompatibleS57Object(pObj, &cobj, &ctx);
4403 ViewPort cvp = CreateCompatibleViewport(*vp);
4408 ObjRazRules rzRules;
4409 rzRules.obj = &cobj;
4410 rzRules.LUP = pContext->LUP;
4411 rzRules.sm_transform_parms = 0;
4412 rzRules.child = NULL;
4413 rzRules.next = NULL;
4415 if (pContext->LUP) {
4416 ps52plib->SetVPointCompat(
4420 ps52plib->PrepareForRender();
4422 return ps52plib->ObjectRenderCheck(&rzRules);
4431 return ps52plib->GetStateHash();
4436void CreateCompatibleS57Object(
PI_S57Obj* pObj, S57Obj* cobj,
4437 chart_context* pctx) {
4440 cobj->att_array = pObj->att_array;
4441 cobj->attVal = pObj->attVal;
4442 cobj->n_attr = pObj->n_attr;
4447 cobj->npt = pObj->npt;
4449 cobj->iOBJL = pObj->iOBJL;
4450 cobj->Index = pObj->Index;
4452 cobj->geoPt = (pt*)pObj->geoPt;
4453 cobj->geoPtz = pObj->geoPtz;
4454 cobj->geoPtMulti = pObj->geoPtMulti;
4456 cobj->m_lat = pObj->m_lat;
4457 cobj->m_lon = pObj->m_lon;
4459 cobj->m_DisplayCat = (DisCat)pObj->m_DisplayCat;
4460 cobj->x_rate = pObj->x_rate;
4461 cobj->y_rate = pObj->y_rate;
4462 cobj->x_origin = pObj->x_origin;
4463 cobj->y_origin = pObj->y_origin;
4465 cobj->Scamin = pObj->Scamin;
4466 cobj->nRef = pObj->nRef;
4467 cobj->bIsAton = pObj->bIsAton;
4468 cobj->bIsAssociable = pObj->bIsAssociable;
4470 cobj->m_n_lsindex = pObj->m_n_lsindex;
4471 cobj->m_lsindex_array = pObj->m_lsindex_array;
4472 cobj->m_n_edge_max_points = pObj->m_n_edge_max_points;
4475 cobj->m_ls_list_legacy =
4479 cobj->m_ls_list_legacy = 0;
4480 cobj->m_ls_list = 0;
4483 cobj->m_bcategory_mutable = pObj->m_bcategory_mutable;
4485 cobj->m_bcategory_mutable =
true;
4489 if (pObj->m_DPRI == -1) {
4491 if (pCtx->LUP) cobj->m_DPRI = pCtx->LUP->DPRI -
'0';
4493 cobj->m_DPRI = pObj->m_DPRI;
4496 cobj->pPolyTessGeo = (PolyTessGeo*)pObj->pPolyTessGeo;
4497 cobj->m_chart_context = (chart_context*)pObj->m_chart_context;
4499 if (pObj->auxParm3 != 1234) {
4500 pObj->auxParm3 = 1234;
4501 pObj->auxParm0 = -99;
4504 cobj->auxParm0 = pObj->auxParm0;
4511 if (pContext->bBBObj_valid)
4513 cobj->BBObj.Set(pContext->BBObj.GetMinY(), pContext->BBObj.GetMinX(),
4514 pContext->BBObj.GetMaxY(), pContext->BBObj.GetMaxX());
4516 cobj->CSrules = pContext->CSrules;
4517 cobj->bCS_Added = pContext->bCS_Added;
4519 cobj->FText = pContext->FText;
4520 cobj->bFText_Added = pContext->bFText_Added;
4521 cobj->rText = pContext->rText;
4523 cobj->bIsClone =
true;
4526 cobj->m_chart_context = pctx;
4527 chart_context* ppctx = (chart_context*)pObj->m_chart_context;
4530 cobj->m_chart_context->m_pvc_hash = ppctx->m_pvc_hash;
4531 cobj->m_chart_context->m_pve_hash = ppctx->m_pve_hash;
4532 cobj->m_chart_context->ref_lat = ppctx->ref_lat;
4533 cobj->m_chart_context->ref_lon = ppctx->ref_lon;
4534 cobj->m_chart_context->pFloatingATONArray = ppctx->pFloatingATONArray;
4535 cobj->m_chart_context->pRigidATONArray = ppctx->pRigidATONArray;
4536 cobj->m_chart_context->safety_contour = ppctx->safety_contour;
4537 cobj->m_chart_context->vertex_buffer = ppctx->vertex_buffer;
4539 cobj->m_chart_context->chart =
4541 cobj->m_chart_context->chart_type = S52_CHART_TYPE_PLUGIN;
4555 CreateCompatibleS57Object(pObj, &cobj, NULL);
4557 LUPname LUP_Name = PAPER_CHART;
4560 ctx->CSrules = NULL;
4561 ctx->bCS_Added =
false;
4564 if (ctx->bFText_Added) {
4565 ctx->bFText_Added =
false;
4571 ctx->bBBObj_valid =
true;
4576 switch (cobj.Primitive_type) {
4581 if (PAPER_CHART == ps52plib->m_nSymbolStyle)
4582 LUP_Name = PAPER_CHART;
4584 LUP_Name = SIMPLIFIED;
4593 if (PLAIN_BOUNDARIES == ps52plib->m_nBoundaryStyle)
4594 LUP_Name = PLAIN_BOUNDARIES;
4596 LUP_Name = SYMBOLIZED_BOUNDARIES;
4601 LUPrec* lup = ps52plib->S52_LUPLookup(LUP_Name, cobj.FeatureName, &cobj);
4605 ps52plib->_LUP2rules(lup, &cobj);
4607 ctx->MPSRulesList = NULL;
4615 pContext->bBBObj_valid =
true;
4621void UpdatePIObjectPlibContext(
PI_S57Obj* pObj, S57Obj* cobj,
4622 ObjRazRules* rzRules) {
4626 pContext->CSrules = cobj->CSrules;
4627 pContext->bCS_Added = cobj->bCS_Added;
4629 pContext->FText = cobj->FText;
4630 pContext->bFText_Added = cobj->bFText_Added;
4631 pContext->rText = cobj->rText;
4633 if (cobj->BBObj.GetValid()) {
4636 BoundingBox(cobj->BBObj.GetMinLon(), cobj->BBObj.GetMinLat(),
4637 cobj->BBObj.GetMaxLon(), cobj->BBObj.GetMaxLat());
4638 pContext->bBBObj_valid =
true;
4643 pObj->m_DisplayCat = (
PI_DisCat)cobj->m_DisplayCat;
4647 pContext->ChildRazRules = rzRules->child;
4648 pContext->MPSRulesList = rzRules->mps;
4650 pObj->auxParm0 = cobj->auxParm0;
4654 double* lon_min,
double* lon_max) {
4657 if (lat_min) *lat_min = pContext->BBObj.GetMinY();
4658 if (lat_max) *lat_max = pContext->BBObj.GetMaxY();
4659 if (lon_min) *lon_min = pContext->BBObj.GetMinX();
4660 if (lon_max) *lon_max = pContext->BBObj.GetMaxX();
4661 return pContext->bBBObj_valid;
4669 LUPrec* lup = pContext->LUP;
4678 LUPrec* lup = pContext->LUP;
4688 LUPrec* lup = pContext->LUP;
4694 return S52_getMarinerParam(S52_MAR_SAFETY_CONTOUR);
4701 CreateCompatibleS57Object(pObj, &cobj, &ctx);
4706 ObjRazRules rzRules;
4707 rzRules.obj = &cobj;
4708 rzRules.LUP = pContext->LUP;
4709 rzRules.sm_transform_parms = 0;
4710 rzRules.child = NULL;
4711 rzRules.next = NULL;
4712 rzRules.mps = pContext->MPSRulesList;
4714 if (pContext->LUP) {
4715 ps52plib->SetLineFeaturePriority(&rzRules, prio);
4718 UpdatePIObjectPlibContext(pObj, &cobj, &rzRules);
4724 ps52plib->PrepareForRender();
4725 ps52plib->ClearTextList();
4728 ps52plib->EnableGLLS(
true);
4730 ps52plib->EnableGLLS(
false);
4739 if (pctx->ChildRazRules) {
4740 ObjRazRules* ctop = pctx->ChildRazRules;
4744 if (ps52plib) ps52plib->DestroyLUP(ctop->LUP);
4746 ObjRazRules* cnxx = ctop->next;
4752 if (pctx->MPSRulesList) {
4753 if (ps52plib && pctx->MPSRulesList->cs_rules) {
4754 for (
unsigned int i = 0; i < pctx->MPSRulesList->cs_rules->GetCount();
4756 Rules* top = pctx->MPSRulesList->cs_rules->Item(i);
4757 ps52plib->DestroyRulesChain(top);
4759 delete pctx->MPSRulesList->cs_rules;
4761 free(pctx->MPSRulesList);
4773 CreateCompatibleS57Object(pObj, &cobj, &ctx);
4780 &transform.easting_vp_center, &transform.northing_vp_center);
4783 ObjRazRules rzRules;
4784 rzRules.obj = &cobj;
4785 rzRules.LUP = pContext->LUP;
4786 rzRules.sm_transform_parms = &transform;
4787 rzRules.child = pContext->ChildRazRules;
4788 rzRules.next = NULL;
4789 rzRules.mps = pContext->MPSRulesList;
4791 if (pContext->LUP) {
4792 ViewPort cvp = CreateCompatibleViewport(*vp);
4798 cvp.rv_rect, cvp.GetBBox(), cvp.
ref_scale,
4800 ps52plib->PrepareForRender();
4802 ps52plib->RenderObjectToDC(pdc, &rzRules);
4805 UpdatePIObjectPlibContext(pObj, &cobj, &rzRules);
4812 wxRect rect,
unsigned char* pixbuf) {
4814 render_canvas_parms pb_spec;
4816 pb_spec.depth = BPP;
4817 pb_spec.pb_pitch = ((rect.width * pb_spec.depth / 8));
4818 pb_spec.lclip = rect.x;
4819 pb_spec.rclip = rect.x + rect.width - 1;
4820 pb_spec.pix_buff = pixbuf;
4821 pb_spec.width = rect.width;
4822 pb_spec.height = rect.height;
4825#ifdef ocpnUSE_ocpnBitmap
4826 pb_spec.b_revrgb =
true;
4828 pb_spec.b_revrgb =
false;
4831 pb_spec.b_revrgb =
false;
4836 CreateCompatibleS57Object(pObj, &cobj, &ctx);
4843 &transform.easting_vp_center, &transform.northing_vp_center);
4846 ObjRazRules rzRules;
4847 rzRules.obj = &cobj;
4848 rzRules.LUP = pContext->LUP;
4849 rzRules.sm_transform_parms = &transform;
4850 rzRules.child = pContext->ChildRazRules;
4851 rzRules.next = NULL;
4852 rzRules.mps = pContext->MPSRulesList;
4854 ViewPort cvp = CreateCompatibleViewport(*vp);
4862 if (!tess)
return 1;
4864 PolyTriGroup* ptg =
new PolyTriGroup;
4865 ptg->tri_prim_head =
4866 tess->Get_PolyTriGroup_head()->tri_prim_head;
4867 ptg->bsingle_alloc =
false;
4868 ptg->data_type = DATA_TYPE_DOUBLE;
4869 tess->Set_PolyTriGroup_head(ptg);
4871 double* pd = (
double*)malloc(
sizeof(
double));
4876 if (pContext->LUP) {
4881 cvp.rv_rect, cvp.GetBBox(), cvp.
ref_scale,
4883 ps52plib->PrepareForRender();
4885 ps52plib->RenderAreaToDC(pdc, &rzRules, &pb_spec);
4888 UpdatePIObjectPlibContext(pObj, &cobj, &rzRules);
4900 CreateCompatibleS57Object(pObj, &cobj, &ctx);
4911 if (!tess)
return 1;
4915 ptg->tri_prim_head = tess->Get_PolyTriGroup_head()->tri_prim_head;
4916 ptg->bsingle_alloc =
false;
4917 ptg->data_type = DATA_TYPE_DOUBLE;
4918 tess->Set_PolyTriGroup_head(ptg);
4922 double* pd = (
double*)malloc(
sizeof(
double));
4939 &transform.easting_vp_center, &transform.northing_vp_center);
4942 ObjRazRules rzRules;
4943 rzRules.obj = &cobj;
4944 rzRules.LUP = pContext->LUP;
4945 rzRules.sm_transform_parms = &transform;
4946 rzRules.child = pContext->ChildRazRules;
4947 rzRules.next = NULL;
4948 rzRules.mps = pContext->MPSRulesList;
4950 if (pContext->LUP) {
4951 ViewPort cvp = CreateCompatibleViewport(*vp);
4957 cvp.rv_rect, cvp.GetBBox(), cvp.
ref_scale,
4959 ps52plib->PrepareForRender();
4961 ps52plib->RenderAreaToGL(glcc, &rzRules);
4964 UpdatePIObjectPlibContext(pObj, &cobj, &rzRules);
4976 CreateCompatibleS57Object(pObj, &cobj, &ctx);
4983 &transform.easting_vp_center, &transform.northing_vp_center);
4986 ObjRazRules rzRules;
4987 rzRules.obj = &cobj;
4988 rzRules.LUP = pContext->LUP;
4989 rzRules.sm_transform_parms = &transform;
4990 rzRules.child = pContext->ChildRazRules;
4991 rzRules.next = NULL;
4992 rzRules.mps = pContext->MPSRulesList;
4994 if (pContext->LUP) {
4995 ViewPort cvp = CreateCompatibleViewport(*vp);
5001 cvp.rv_rect, cvp.GetBBox(), cvp.
ref_scale,
5003 ps52plib->PrepareForRender();
5005 ps52plib->RenderObjectToGL(glcc, &rzRules);
5008 UpdatePIObjectPlibContext(pObj, &cobj, &rzRules);
5018OCPN_downloadEvent::OCPN_downloadEvent(wxEventType commandType,
int id)
5019 : wxEvent(id, commandType) {
5022 m_b_complete =
false;
5026OCPN_downloadEvent::~OCPN_downloadEvent() {}
5028wxEvent* OCPN_downloadEvent::Clone()
const {
5030 newevent->m_stat = this->m_stat;
5031 newevent->m_condition = this->m_condition;
5033 newevent->m_totalBytes = this->m_totalBytes;
5034 newevent->m_sofarBytes = this->m_sofarBytes;
5035 newevent->m_b_complete = this->m_b_complete;
5041DECL_EXP wxEventType wxEVT_DOWNLOAD_EVENT = wxNewEventType();
5046#define DL_EVENT_TIMER 4388
5054 void setBackgroundMode(
long ID, wxEvtHandler* handler);
5055 void clearBackgroundMode();
5056 void onTimerEvent(wxTimerEvent& event);
5059 wxTimer m_eventTimer;
5060 wxEvtHandler* m_download_evHandler;
5066PI_DLEvtHandler::PI_DLEvtHandler() {
5070 m_download_evHandler = NULL;
5076PI_DLEvtHandler::~PI_DLEvtHandler() {
5077 m_eventTimer.Stop();
5080 (wxObjectEventFunction)(wxEventFunction)&PI_DLEvtHandler::onTimerEvent);
5087 g_download_status =
event.getDLEventStatus();
5088 g_download_condition =
event.getDLEventCondition();
5091 if (m_download_evHandler &&
5094 ev.setComplete(
true);
5095 ev.setTransferred(m_sofarBytes);
5096 ev.setTotal(m_totalBytes);
5098 ev.setDLEventStatus(event.getDLEventStatus());
5101 m_download_evHandler->AddPendingEvent(ev);
5102 m_eventTimer.Stop();
5104 finishAndroidFileDownload();
5111void PI_DLEvtHandler::setBackgroundMode(
long ID, wxEvtHandler* handler) {
5113 m_download_evHandler = handler;
5115 m_eventTimer.SetOwner(
this, DL_EVENT_TIMER);
5119 (wxObjectEventFunction)(wxEventFunction)&PI_DLEvtHandler::onTimerEvent);
5120 m_eventTimer.Start(1000, wxTIMER_CONTINUOUS);
5123void PI_DLEvtHandler::clearBackgroundMode() {
5124 m_download_evHandler = NULL;
5125 m_eventTimer.Stop();
5128void PI_DLEvtHandler::onTimerEvent(wxTimerEvent& event) {
5134 int stat = queryAndroidFileDownload(m_id, &sstat);
5137 long sofarBytes = 0;
5138 long totalBytes = -1;
5142 qDebug() <<
"Error on queryAndroidFileDownload, ending download";
5143 ev.setComplete(
true);
5144 ev.setTransferred(sofarBytes);
5145 ev.setTotal(totalBytes);
5150 wxStringTokenizer tk(sstat,
";");
5151 if (tk.HasMoreTokens()) {
5152 wxString token = tk.GetNextToken();
5153 token.ToLong(&state);
5154 token = tk.GetNextToken();
5155 token.ToLong(&sofarBytes);
5156 token = tk.GetNextToken();
5157 token.ToLong(&totalBytes);
5160 qDebug() << state << sofarBytes << totalBytes;
5162 m_sofarBytes = sofarBytes;
5163 m_totalBytes = totalBytes;
5165 ev.setTransferred(sofarBytes);
5166 ev.setTotal(totalBytes);
5169 qDebug() <<
"Event OCPN_DL_FAILED/OCPN_DL_EVENT_TYPE_END";
5170 ev.setComplete(
true);
5173 }
else if (state == 8) {
5174 qDebug() <<
"Event OCPN_DL_NO_ERROR/OCPN_DL_EVENT_TYPE_END";
5175 ev.setComplete(
true);
5179 ev.setComplete(
false);
5187 if (m_download_evHandler) {
5189 m_download_evHandler->AddPendingEvent(ev);
5194 m_eventTimer.Stop();
5195 finishAndroidFileDownload();
5205 const wxString& outputFile,
5206 const wxString& title,
const wxString& message,
5207 const wxBitmap& bitmap, wxWindow* parent,
5208 long style,
int timeout_secs) {
5211 wxString msg =
"Downloading file synchronously: ";
5218 int vres = validateAndroidWriteLocation(outputFile);
5230 g_piEventHandler->Connect(
5231 wxEVT_DOWNLOAD_EVENT,
5232 (wxObjectEventFunction)(wxEventFunction)&PI_DLEvtHandler::onDLEvent);
5237 wxString fURI = outputFile;
5238 if (!fURI.StartsWith(
"file://")) {
5239 fURI.Prepend(
"file://");
5242 int res = startAndroidFileDownload(url, fURI, g_piEventHandler, &dl_ID);
5245 finishAndroidFileDownload();
5246 g_piEventHandler->Disconnect(
5247 wxEVT_DOWNLOAD_EVENT,
5248 (wxObjectEventFunction)(wxEventFunction)&PI_DLEvtHandler::onDLEvent);
5253 wxDateTime dl_start_time = wxDateTime::Now();
5257 wxTimeSpan dt = wxDateTime::Now() - dl_start_time;
5258 qDebug() <<
"Spin.." << dt.GetSeconds().GetLo();
5260 if (dt.GetSeconds() > timeout_secs) {
5261 qDebug() <<
"USER_TIMOUT";
5262 finishAndroidFileDownload();
5263 g_piEventHandler->Disconnect(
5264 wxEVT_DOWNLOAD_EVENT,
5265 (wxObjectEventFunction)(wxEventFunction)&PI_DLEvtHandler::onDLEvent);
5273 finishAndroidFileDownload();
5274 g_piEventHandler->Disconnect(
5275 wxEVT_DOWNLOAD_EVENT,
5279 qDebug() <<
"RETURN DL_END" << (int)ss;
5285 int stat = queryAndroidFileDownload(dl_ID, &sstat);
5287 qDebug() <<
"Error on queryAndroidFileDownload";
5288 finishAndroidFileDownload();
5289 g_piEventHandler->Disconnect(
5290 wxEVT_DOWNLOAD_EVENT,
5291 (wxObjectEventFunction)(wxEventFunction)&PI_DLEvtHandler::onDLEvent);
5301#elif defined(OCPN_USE_CURL)
5302 wxFileName tfn = wxFileName::CreateTempFileName(outputFile);
5303 wxFileOutputStream output(tfn.GetFullPath());
5305 wxCurlDownloadDialog ddlg(url, &output, title, message + url, bitmap, parent,
5307 wxCurlDialogReturnFlag ret = ddlg.RunModal();
5313 case wxCDRF_SUCCESS: {
5314 if (wxCopyFile(tfn.GetFullPath(), outputFile))
5320 case wxCDRF_FAILED: {
5324 case wxCDRF_USER_ABORTED: {
5332 if (wxFileExists(tfn.GetFullPath())) wxRemoveFile(tfn.GetFullPath());
5342 return ocpn::toUsrDateTimeFormat(date_time,
options);
5347 const wxString& outputFile,
5348 wxEvtHandler* handler,
5351 wxString msg =
"Downloading file asynchronously: ";
5363 int res = startAndroidFileDownload(url, outputFile, NULL ,
5367 finishAndroidFileDownload();
5372 g_piEventHandler->setBackgroundMode(dl_ID, handler);
5374 if (handle) *handle = dl_ID;
5378#elif defined(OCPN_USE_CURL)
5385 bool http = (url.StartsWith(wxS(
"http:")) || url.StartsWith(wxS(
"https:")));
5388 dynamic_cast<wxCurlHTTP*
>(
g_pi_manager->m_pCurl.get())) {
5395 bool failed =
false;
5404 new wxFileOutputStream(outputFile)),
5412 wxCurlThreadError err =
g_pi_manager->m_pCurlThread->Download();
5413 if (err != wxCTE_NO_ERROR) {
5427 delete (
g_pi_manager->m_pCurlThread->GetOutputStream());
5445 cancelAndroidFileDownload(handle);
5446 finishAndroidFileDownload();
5447 if (g_piEventHandler) g_piEventHandler->clearBackgroundMode();
5451 delete (
g_pi_manager->m_pCurlThread->GetOutputStream());
5462 const wxString& parameters, wxString& result,
5465 wxString lparms = parameters;
5466 wxString postResult = doAndroidPOST(url, lparms, timeout_secs * 1000);
5469 result = postResult;
5472#elif defined(OCPN_USE_CURL)
5474 post.SetOpt(CURLOPT_TIMEOUT, timeout_secs);
5475 size_t res = post.Post(parameters.ToAscii(), parameters.Len(), url);
5478 result = wxString(post.GetResponseBody().c_str(), wxConvUTF8);
5481 result = wxEmptyString;
5492 return androidCheckOnline();
5495#if !defined(__ANDROID__) && defined(OCPN_USE_CURL)
5496 if (wxDateTime::GetTimeNow() >
5497 g_pi_manager->m_last_online_chk + ONLINE_CHECK_RETRY) {
5499 get.Head(
"http://yahoo.com/");
5500 g_pi_manager->m_last_online = get.GetResponseCode() > 0;
5502 g_pi_manager->m_last_online_chk = wxDateTime::GetTimeNow();
5510#if !defined(__ANDROID__) && defined(OCPN_USE_CURL)
5511void PlugInManager::OnEndPerformCurlDownload(wxCurlEndPerformEvent& ev) {
5513 if (ev.IsSuccessful()) {
5520 event.setComplete(
true);
5522 if (m_download_evHandler) {
5523 m_download_evHandler->AddPendingEvent(event);
5524 m_download_evHandler = NULL;
5525 m_downloadHandle = NULL;
5528 if (m_pCurlThread) {
5529 m_pCurlThread->Wait();
5530 if (!m_pCurlThread->IsAborting()) {
5531 delete (m_pCurlThread->GetOutputStream());
5532 wxDELETE(m_pCurlThread);
5537void PlugInManager::OnCurlDownload(wxCurlDownloadEvent& ev) {
5541 event.setTotal(ev.GetTotalBytes());
5542 event.setTransferred(ev.GetDownloadedBytes());
5543 event.setComplete(
false);
5545 if (m_download_evHandler) {
5546 m_download_evHandler->AddPendingEvent(event);
5550bool PlugInManager::HandleCurlThreadError(wxCurlThreadError err,
5551 wxCurlBaseThread* p,
5552 const wxString& url) {
5554 case wxCTE_NO_ERROR:
5557 case wxCTE_NO_RESOURCE:
5559 wxS(
"Insufficient resources for correct execution of the program."));
5562 case wxCTE_ALREADY_RUNNING:
5566 case wxCTE_INVALID_PROTOCOL:
5567 wxLogError(wxS(
"The URL '%s' uses an unsupported protocol."),
5571 case wxCTE_NO_VALID_STREAM:
5578 case wxCTE_CURL_ERROR: {
5579 wxString ws = wxS(
"unknown");
5580 if (p->GetCurlSession())
5582 wxString(p->GetCurlSession()->GetErrorString().c_str(), wxConvUTF8);
5583 wxLogError(wxS(
"Network error: %s"), ws.c_str());
5588 if (p->IsAlive()) p->Abort();
Class AisDecoder and helpers.
Plugin catalog settings dialog.
Plugin catalog management: Build the runtime catalog, handling downloads as required.
General chart base definitions.
ChartDB * ChartData
Global instance.
Charts database management
ChartGroupArray * g_pGroupArray
Global instance.
Basic chart info storage.
ChartCanvas * g_overlayCanvas
Global instance.
Generic Chart canvas base.
EventVar plugin_msg
A JSON message should be sent.
Handle messages for blacklisted plugins.
Modal dialog for plugin catalog settings.
ChartCanvas - Main chart display and interaction component.
Manages the chart database and provides access to chart data.
Wrapper class for plugin-based charts.
virtual double GetNearestPreferredScalePPM(double target_scale_ppm)
Find the nearest preferred viewport scale (in pixels/meter) for this chart.
NMEA0183 basic parsing common parts:
const std::vector< DriverPtr > & GetDrivers() const
Wrapper for configuration variables which lives in a wxBaseConfig object.
void Notify() override
Notify all listeners, no data supplied.
Wrapper for global variable, supports notification events when value changes.
Downloader with progress and final message dialogs.
Interface implemented by classes which listens.
Handle logging and forwarding of incoming n0183/n2k messages.
The raw message layer, a singleton.
static NavAddr::Bus GetBusByKey(const std::string &key)
Return bus corresponding to given key.
An iterator class for OCPNRegion.
A wrapper class for wxRegion with additional functionality.
Define an action to be performed when a KeyProvider is notified.
void Init(const KeyProvider &kp, const std::function< void(ObservedEvt &ev)> &action)
Initiate an object yet not listening.
void Listen(const std::string &key, wxEvtHandler *listener, wxEventType evt)
Set object to send wxEventType ev to listener on changes in key.
Custom event class for OpenCPN's notification system.
std::shared_ptr< const void > GetSharedPtr() const
Gets the event's payload data.
Class representing an S-57 chart object.
double lon_max
Bounding box maximum longitude.
double lon_min
Bounding box minimum longitude.
double lat_max
Bounding box maximum latitude.
int auxParm0
Auxiliary parameter 0.
void * pPolyTessGeo
Tesselated polygon geometry.
double chart_ref_lon
Chart reference longitude.
double * geoPtMulti
Lat/lon pairs for decomposed points.
void * S52_Context
S52 presentation data.
double chart_ref_lat
Chart reference latitude.
char FeatureName[8]
S-57 feature type code (e.g., "DEPARE")
double lat_min
Bounding box minimum latitude.
int Primitive_type
Geometry type (point, line, area)
Represents a line segment element for efficient vector chart rendering.
Extended chart base class with separated text rendering.
virtual wxBitmap & RenderRegionViewOnDCNoText(const PlugIn_ViewPort &VPoint, const wxRegion &Region)
Standard DC rendering without text.
virtual bool RenderRegionViewOnDCTextOnly(wxMemoryDC &dc, const PlugIn_ViewPort &VPoint, const wxRegion &Region)
Standard DC text-only rendering.
virtual void ClearPLIBTextList()
Clears any cached text elements.
virtual int RenderRegionViewOnGLNoText(const wxGLContext &glc, const PlugIn_ViewPort &VPoint, const wxRegion &Region, bool b_use_stencil)
OpenGL rendering without text.
virtual int RenderRegionViewOnGLTextOnly(const wxGLContext &glc, const PlugIn_ViewPort &VPoint, const wxRegion &Region, bool b_use_stencil)
OpenGL text-only rendering.
virtual int RenderRegionViewOnGL(const wxGLContext &glc, const PlugIn_ViewPort &VPoint, const wxRegion &Region, bool b_use_stencil)
OpenGL rendering with combined text and graphics.
virtual ListOfPI_S57Obj * GetLightsObjRuleListVisibleAtLatLon(float lat, float lon, PlugIn_ViewPort *VPoint)
Gets list of visible light objects at specified position.
OpenGL-optimized chart base class for plugin chart types.
virtual int GetNoCOVRTablenPoints(int iTable)
Alternative to GetNoCOVRTablePoints().
virtual int GetNoCOVREntries()
Gets number of no-coverage areas in chart.
virtual int GetNoCOVRTablePoints(int iTable)
Gets number of points in no-coverage area boundary.
virtual wxString CreateObjDescriptions(ListOfPI_S57Obj *obj_list)
Creates description text for chart objects.
virtual float * GetNoCOVRTableHead(int iTable)
Gets coordinate data for no-coverage area boundary.
virtual int RenderRegionViewOnGL(const wxGLContext &glc, const PlugIn_ViewPort &VPoint, const wxRegion &Region, bool b_use_stencil)
Renders chart content using OpenGL.
virtual ListOfPI_S57Obj * GetObjRuleListAtLatLon(float lat, float lon, float select_radius, PlugIn_ViewPort *VPoint)
Gets chart objects near specified position.
Base class for implementing custom chart types in OpenCPN plugins.
virtual void SetColorScheme(int cs, bool bApplyImmediate)
Sets the color scheme for chart display.
virtual bool GetChartExtent(ExtentPI *pext)
Gets the geographic boundaries of the chart.
virtual void chartpix_to_latlong(double pixx, double pixy, double *plat, double *plon)
Converts chart pixel coordinates to geographic coordinates.
virtual double GetNearestPreferredScalePPM(double target_scale_ppm)
Returns the nearest preferred scale value for this chart.
virtual double GetNormalScaleMin(double canvas_scale_factor, bool b_allow_overzoom)
Returns the minimum recommended scale for this chart.
virtual wxBitmap & RenderRegionView(const PlugIn_ViewPort &VPoint, const wxRegion &Region)
Renders a region of the chart for display.
virtual ChartFamilyEnumPI GetChartFamily()
Returns the chart family classification.
virtual wxString GetID()
Returns a unique identifier for the chart.
virtual wxString GetDatumString()
Returns the horizontal geodetic datum of the chart.
virtual wxString GetName()
Returns the chart's name or title.
virtual double GetRasterScaleFactor()
Returns the scale factor for raster chart rendering.
virtual wxDateTime GetEditionDate(void)
Returns the edition date of the chart.
virtual int GetCOVRTablenPoints(int iTable)
Alternative method to get the number of points in a coverage table entry.
virtual bool GetChartBits(wxRect &source, unsigned char *pPix, int sub_samp)
Gets pixel data for a portion of a raster chart.
virtual int GetCOVREntries()
Returns the number of coverage table entries for this chart.
virtual double GetNormalScaleMax(double canvas_scale_factor, int canvas_width)
Returns the maximum recommended scale for this chart.
virtual wxString GetSoundingsDatum()
Returns the vertical datum used for soundings in the chart.
virtual wxString GetExtraInfo()
Returns additional information about the chart.
virtual int GetSize_X()
Gets the width of the chart in pixels.
virtual wxString GetFullPath() const
Returns the full file path of the chart.
virtual wxString GetSE()
Returns the chart's source edition identifier.
virtual bool IsReadyToRender()
Indicates whether the chart is ready for rendering.
virtual int GetNativeScale()
Returns the native scale of the chart.
virtual double GetChartSkew()
Returns the skew/rotation angle of the chart.
virtual wxString GetDepthUnits()
Returns the depth units used in the chart.
virtual int Init(const wxString &full_path, int init_flags)
Initializes a chart instance from a file.
virtual wxString GetFileSearchMask(void)
Returns file pattern(s) for chart files this plugin can handle.
virtual int GetSize_Y()
Gets the height of the chart in pixels.
virtual void latlong_to_chartpix(double lat, double lon, double &pixx, double &pixy)
Converts geographic coordinates to chart pixel coordinates.
virtual void ComputeSourceRectangle(const PlugIn_ViewPort &vp, wxRect *pSourceRect)
Computes the source rectangle for the chart based on a given viewport.
virtual float * GetCOVRTableHead(int iTable)
Returns a pointer to the coverage table data for a specific entry.
virtual double GetChartErrorFactor()
Returns the error factor for the chart.
virtual OcpnProjTypePI GetChartProjection()
Returns the projection type used by the chart.
virtual wxBitmap * GetThumbnail(int tnx, int tny, int cs)
Generates a thumbnail image of the chart.
virtual ChartTypeEnumPI GetChartType()
Returns the chart type identifier.
virtual void GetValidCanvasRegion(const PlugIn_ViewPort &VPoint, wxRegion *pValidRegion)
Determines the valid display area for this chart.
virtual bool AdjustVP(PlugIn_ViewPort &vp_last, PlugIn_ViewPort &vp_proposed)
Adjusts viewport parameters for chart-specific requirements.
virtual int GetCOVRTablePoints(int iTable)
Returns the number of points in a specific coverage table entry.
virtual ChartDepthUnitTypePI GetDepthUnitId()
Returns the depth unit type identifier.
Data for a loaded plugin, including dl-loaded library.
Basic data for a loaded plugin, trivially copyable.
wxString m_plugin_filename
The short file path.
wxString m_plugin_file
The full file path.
int m_cap_flag
PlugIn Capabilities descriptor.
wxString m_common_name
A common name string for the plugin.
std::string Key() const
sort key.
void HandleN0183(std::shared_ptr< const Nmea0183Msg > n0183_msg)
Process incoming NMEA 0183 messages from the message bus.
void HandleSignalK(std::shared_ptr< const SignalkMsg > sK_msg)
Process incoming SignalK messages from the message bus.
Contains view parameters and status information for a chart display viewport.
double view_scale_ppm
Display scale in pixels per meter.
wxRect rv_rect
Rectangle defining the rendered view area.
int pix_width
Viewport width in pixels.
double lon_max
Maximum longitude of the viewport.
double clon
Center longitude of the viewport in decimal degrees.
double lat_max
Maximum latitude of the viewport.
int pix_height
Viewport height in pixels.
double clat
Center latitude of the viewport in decimal degrees.
double skew
Display skew angle in radians.
double rotation
Display rotation angle in radians.
bool bValid
True if this viewport is valid and can be used for rendering.
double lon_min
Minimum longitude of the viewport.
double lat_min
Minimum latitude of the viewport.
int m_projection_type
Chart projection type (PROJECTION_MERCATOR, etc.)
bool b_quilt
True if the viewport is in quilt mode (showing multiple charts)
float chart_scale
Conventional chart displayed scale (e.g., 1:50000)
Handle plugin install from remote repositories and local operations to Uninstall and list plugins.
bool Uninstall(const std::string plugin)
Uninstall an installed and loaded plugin.
const std::vector< PluginMetadata > GetInstalled()
Return list of all installed and loaded plugins.
static std::string ImportedMetadataPath(std::string name)
Return path to imported metadata for given plugin.
static std::string VersionPath(std::string name)
Return path to file containing version for given plugin.
std::vector< std::string > GetInstalldataPlugins()
Return list of installed plugins lower case names, not necessarily loaded.
bool ClearInstallData(const std::string plugin_name)
Remove installation data for not loaded plugin.
static bool IsCompatible(const PluginMetadata &metadata, const char *os=PKG_TARGET, const char *os_version=PKG_TARGET_VERSION)
Return true if given plugin is loadable on given os/version.
static std::string FileListPath(std::string name)
Return path to installation manifest for given plugin.
void SetInstalledMetadata(const PluginMetadata &pm)
Set metadata for an installed plugin.
static PluginHandler * GetInstance()
Singleton factory.
void ReloadPluginPanels()
Complete reload from plugins array.
bool LoadAllPlugIns(bool enabled_plugins, bool keep_orphans=false)
Update catalog with imported metadata and load all plugin library files.
void UpdateManagedPlugins(bool keep_orphans)
Update all managed plugins i.
EventVar evt_pluglist_change
Notified without data when the GetPlugInArray() list is changed.
static std::string GetPluginVersion(const PlugInData pd, std::function< const PluginMetadata(const std::string &)> get_metadata)
Return version string for a plugin, possibly with an "Imported" suffix.
void SortPlugins(int(*cmp_func)(PlugInContainer **, PlugInContainer **))
Sort GetPluginArray().
static void UpdatePlugin(PlugInContainer *plugin, const PluginMetadata &md)
Update PlugInContainer status using data from PluginMetadata and manifest.
void SetEnabled(const wxString &common_name, bool enabled)
Update enabled/disabled state for plugin with given name.
static PluginMetadata MetadataByName(const std::string &name)
Find metadata for given plugin.
bool DeactivatePlugIn(PlugInContainer *pic)
Deactivate given plugin.
bool UpdatePlugIns()
Update the GetPlugInArray() list by reloading all plugins from disk.
void ShowPreferencesDialog(const PlugInData &pd, wxWindow *parent)
Display the preferences dialog for a plugin.
const ArrayOfPlugIns * GetPlugInArray()
Return list of currently loaded plugins.
PluginPanel(wxPanel *parent, wxWindowID id, const wxPoint &pos, const wxSize &size, const PlugInData plugin)
An entry in the list of plugins presented by Options | Plugins.
KeyProvider wrapper for a plain key string.
std::string GetKey() const override
Get the Key object from the Key Provider.
EventVar json_msg
Notified with message targeting all plugins.
EventVar json_leg_info
Notified with a shared_ptr<ActiveLegDat>, leg info to all plugins.
EventVar on_message_sent
Notified when a message available as GetString() is sent to garmin.
A parsed SignalK message over ipv4.
Modal dialog, displays available updates (possibly just one) and lets user select and eventually conf...
ViewPort - Core geographic projection and coordinate transformation engine.
double view_scale_ppm
Requested view scale in physical pixels per meter (ppm), before applying projections.
double ref_scale
The nominal scale of the "reference chart" for this view.
int pix_height
Height of the viewport in physical pixels.
void SetBoxes(void)
Computes the bounding box coordinates for the current viewport.
double rotation
Rotation angle of the viewport in radians.
int pix_width
Width of the viewport in physical pixels.
double skew
Angular distortion (shear transform) applied to the viewport in radians.
double clon
Center longitude of the viewport in degrees.
double clat
Center latitude of the viewport in degrees.
double chart_scale
Chart scale denominator (e.g., 50000 for a 1:50000 scale).
Device context class that can use either wxDC or OpenGL for drawing.
virtual void PrepareContextMenu(int canvasIndex)
Prepares plugin context menu items.
virtual bool RenderOverlayMultiCanvas(wxDC &dc, PlugIn_ViewPort *vp, int canvasIndex)
Renders plugin overlay graphics in standard DC mode for multi-canvas support.
virtual bool RenderGLOverlayMultiCanvas(wxGLContext *pcontext, PlugIn_ViewPort *vp, int canvasIndex)
Renders plugin overlay graphics in OpenGL mode for multi-canvas support.
virtual bool RenderGLOverlayMultiCanvas(wxGLContext *pcontext, PlugIn_ViewPort *vp, int canvasIndex, int priority)
Renders plugin overlay graphics in OpenGL mode with priority control.
virtual bool RenderOverlayMultiCanvas(wxDC &dc, PlugIn_ViewPort *vp, int canvas_ix, int priority)
Renders plugin overlay graphics in standard DC mode with priority control.
virtual bool RenderOverlay(wxDC &dc, PlugIn_ViewPort *vp)
Renders plugin overlay graphics in standard DC mode for single canvas.
virtual bool RenderGLOverlay(wxGLContext *pcontext, PlugIn_ViewPort *vp)
Renders plugin overlay graphics in OpenGL mode for single canvas.
Base class for OpenCPN plugins.
virtual void OnCloseToolboxPanel(int page_sel, int ok_apply_cancel)
Handles preference page closure.
virtual void SetCurrentViewPort(PlugIn_ViewPort &vp)
Notifies plugin of viewport changes.
virtual void UpdateAuiStatus(void)
Updates AUI manager status.
virtual void SetColorScheme(PI_ColorScheme cs)
Updates plugin color scheme.
virtual wxArrayString GetDynamicChartClassNameArray(void)
Returns array of dynamically loaded chart class names.
virtual int GetPlugInVersionMajor()
Returns the major version number of the plugin itself.
virtual bool RenderOverlay(wxMemoryDC *pmdc, PlugIn_ViewPort *vp)
Render plugin overlay graphics using standard device context.
virtual void ProcessParentResize(int x, int y)
Handles parent window resize events.
virtual int GetPlugInVersionMinor()
Returns the minor version number of the plugin itself.
int Parse(const wxString &doc, wxJSONValue *val)
Parse the JSON document.
The JSON value class implementation.
The JSON document writer.
void Write(const wxJSONValue &value, wxString &str)
Write the JSONvalue object to a JSON text.
wxColour GetDialogColor(DialogColor color)
Retrieves a dialog color based on its role in the application's dialogs.
@ DLG_SELECTED_ACCENT
Accent color for selected items.
@ DLG_SELECTED_BACKGROUND
Background color for selected items.
@ DLG_UNSELECTED_ACCENT
Accent color for unselected items.
@ DLG_UNSELECTED_BACKGROUND
Background color for unselected items.
DriverPtr & FindDriver(const std::vector< DriverPtr > &drivers, const std::string &iface, const NavAddr::Bus _bus)
Search list of drivers for a driver with given interface string.
Driver registration container, a singleton.
Raw messages layer, supports sending and recieving navmsg messages.
double g_display_size_mm
Physical display width (mm)
Global variables stored in configuration file.
Enhanced logging interface on top of wx/log.h.
Multiplexer class and helpers.
bool replace(std::string &str, const std::string &from, const std::string &to)
Perform in place substitution in str, replacing "from" with "to".
std::string lookup_tarball(const char *uri)
Get path to tarball in cache for given filename.
std::string tolower(const std::string &input)
Return copy of s with all characters converted to lower case.
std::vector< std::string > split(const char *token_string, const std::string &delimiter)
Return vector of items in s separated by delimiter.
bool store_metadata(const char *path)
Store metadata in metadata cache, return success/fail.
bool store_tarball(const char *path, const char *basename)
Store a tarball in tarball cache, return success/fail.
Notify()/Listen() configuration variable wrapper.
Global variables Listen()/Notify() wrapper.
enum _PI_DisCat PI_DisCat
Display categories for S52 chart features.
#define INSTALLS_PLUGIN_CHART
Plugin provides new chart type for standard (non-GL) view.
enum _PI_DisPrio PI_DisPrio
Display priority levels for S52 chart objects.
#define PLIB_CAPS_OBJCATMUTATE
Support for object category mutation Allows dynamic changes to object display categories.
#define INSTALLS_CONTEXTMENU_ITEMS
Plugin will add items to chart context menu.
#define WANTS_LATE_INIT
Delay full plugin initialization until system is ready.
_OCPN_DLCondition
Event types for HTTP file download operations.
@ OCPN_DL_EVENT_TYPE_UNKNOWN
Unknown event type.
@ OCPN_DL_EVENT_TYPE_PROGRESS
Download progress update.
@ OCPN_DL_EVENT_TYPE_END
Download has completed.
PI_ColorScheme
Enumeration of color schemes.
#define PLIB_CAPS_SINGLEGEO_BUFFER
Support for single geometry buffers Allows combining multiple geometries into a single buffer.
#define PLIB_CAPS_LINE_BUFFER
Support for line vertex buffers Enables batched line rendering using vertex buffers.
_OCPN_DLStatus
Status codes for HTTP file download operations.
@ OCPN_DL_NO_ERROR
Download completed successfully.
@ OCPN_DL_USER_TIMEOUT
Download timed out waiting for user action.
@ OCPN_DL_STARTED
Download has begun but not yet complete.
@ OCPN_DL_FAILED
Download failed (general error)
@ OCPN_DL_UNKNOWN
Unknown or uninitialized status.
@ OCPN_DL_ABORTED
Download was cancelled by user.
@ PI_CHART_FAMILY_VECTOR
Vector chart formats (S-57, CM93, etc.)
#define INSTALLS_TOOLBOX_PAGE
Plugin will add pages to the toolbox/settings dialog.
enum _PI_LUPname PI_LUPname
Name identifiers for S57 lookup table sets.
#define USES_AUI_MANAGER
Plugin uses wxAuiManager for window management.
#define PLIB_CAPS_OBJSEGLIST
Support for object segment lists Enables breaking complex geometries into optimized segments.
#define INSTALLS_PLUGIN_CHART_GL
Plugin provides new chart type for OpenGL view.
#define WANTS_ONPAINT_VIEWPORT
Receive callbacks during chart viewport painting.
#define WANTS_PREFERENCES
Plugin will add page(s) to global preferences dialog.
#define WANTS_OVERLAY_CALLBACK
Receive callbacks to render custom overlay graphics on the chart.
wxWindow * GetOCPNCanvasWindow()
Gets OpenCPN's main canvas window.
double OCPN_GetDisplayContentScaleFactor()
Gets content scaling factor for current display.
double OCPN_GetWinDIPScaleFactor()
Gets Windows-specific DPI scaling factor.
Miscellaneous utilities, many of which string related.
void SendNMEASentenceToAllPlugIns(const wxString &sentence)
Distribute a NMEA 0183 sentence to all plugins that have registered interest by setting the WANTS_NME...
Tools to send data to plugins.
PLugin remote repositories installation and Uninstall/list operations.
Low level code to load plugins from disk, notably the PluginLoader class.
@ Ghost
Managed, shadowing another (packaged?) plugin.
@ Unmanaged
Unmanaged, probably a package.
@ Managed
Managed by installer.
@ System
One of the four system plugins, unmanaged.
Plugin installation and data paths support.
wxString toSDMM_PlugIn(int NEflag, double a, bool hi_precision)
Convert decimal degrees to a formatted string.
bool PI_GetObjectRenderBox(PI_S57Obj *pObj, double *lat_min, double *lat_max, double *lon_min, double *lon_max)
Gets geographic bounding box of S57 object.
void PI_PLIBFreeContext(void *pContext)
Frees S52 PLIB context.
ChartCanvas * g_focusCanvas
Global instance.
_OCPN_DLStatus OCPN_postDataHttp(const wxString &url, const wxString ¶meters, wxString &result, int timeout_secs)
Performs HTTP POST request.
int PI_GetPLIBSymbolStyle()
Gets configured S52 symbol style.
void OCPN_cancelDownloadFileBackground(long handle)
Cancels a background download.
wxString GetPlugInPath(opencpn_plugin *pplugin)
Gets the installation path for a specific plugin.
int PI_GetPLIBStateHash()
Gets hash value representing current PLIB state.
OCPN_AUIManager * g_pauimgr
Global instance.
int PI_PLIBRenderAreaToDC(wxDC *pdc, PI_S57Obj *pObj, PlugIn_ViewPort *vp, wxRect rect, unsigned char *pixbuf)
Renders an S57 area object using standard device context.
wxColour GetBaseGlobalColor(wxString colorName)
Gets a global system color.
wxString PI_GetPLIBColorScheme()
Gets current color scheme used by S52 PLIB.
double PI_GetPLIBMarinerSafetyContour()
Gets configured safety contour depth.
bool PI_PLIBObjectRenderCheck(PI_S57Obj *pObj, PlugIn_ViewPort *vp)
Checks if object should be rendered.
wxString GetWritableDocumentsDir(void)
Returns the platform-specific default documents directory.
PlugInManager * g_pi_manager
Updates install and optional selection dialog.
std::vector< const PlugInData * > GetInstalled()
Return sorted list of all installed plugins.
int PI_GetPLIBDepthUnitInt()
Gets configured depth unit for S52 display.
bool PI_PLIBSetContext(PI_S57Obj *pObj)
Sets S52 PLIB rendering context for an object.
void PI_PLIBSetLineFeaturePriority(PI_S57Obj *pObj, int prio)
Sets rendering priority for line feature.
ChartDB * ChartData
Global instance.
PI_DisCat PI_GetObjectDisplayCategory(PI_S57Obj *pObj)
Gets display category for object.
void PI_PLIBPrepareForNewRender(void)
Prepares PLIB for new rendering pass.
PI_LUPname PI_GetObjectLUPName(PI_S57Obj *pObj)
Gets Look-Up Table (LUP) name for object.
int OCPNMessageBox_PlugIn(wxWindow *parent, const wxString &message, const wxString &caption, int style, int x, int y)
Shows a message box dialog.
int PI_PLIBRenderObjectToGL(const wxGLContext &glcc, PI_S57Obj *pObj, PlugIn_ViewPort *vp, wxRect &render_rect)
Renders any S57 object using OpenGL.
int PI_PLIBRenderAreaToGL(const wxGLContext &glcc, PI_S57Obj *pObj, PlugIn_ViewPort *vp, wxRect &render_rect)
Renders an S57 area object using OpenGL.
Select * pSelect
Global instance.
_OCPN_DLStatus OCPN_downloadFileBackground(const wxString &url, const wxString &outputFile, wxEvtHandler *handler, long *handle)
Asynchronously downloads a file in the background.
wxString toUsrDateTimeFormat_Plugin(const wxDateTime date_time, const DateTimeFormatOptions &options)
Format a date/time to a localized string representation, conforming to the global date/time format an...
int PI_PLIBRenderObjectToDC(wxDC *pdc, PI_S57Obj *pObj, PlugIn_ViewPort *vp)
Renders an S57 object using standard device context.
void PI_UpdateContext(PI_S57Obj *pObj)
Updates rendering context for S57 object.
_OCPN_DLStatus OCPN_downloadFile(const wxString &url, const wxString &outputFile, const wxString &title, const wxString &message, const wxBitmap &bitmap, wxWindow *parent, long style, int timeout_secs)
Synchronously download a file with progress dialog.
wxString * GetpPlugInLocation()
Gets plugins directory location.
int PI_GetPLIBBoundaryStyle()
Gets configured S52 boundary style.
wxString GetOCPN_ExePath(void)
Gets OpenCPN executable path.
bool OCPN_isOnline()
Checks internet connectivity.
void PI_PLIBSetRenderCaps(unsigned int flags)
Sets rendering capability flags.
PI_DisPrio PI_GetObjectDisplayPriority(PI_S57Obj *pObj)
Gets display priority for object.
double g_display_size_mm
Physical display width (mm)
PlugInManager and helper classes – Mostly gui parts (dialogs) and plugin API stuff.
PlugInManager * g_pi_manager
Global instance.
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.
Geographic extent structure defining a bounding box.
double NLAT
Northern latitude boundary in decimal degrees.
double WLON
Western longitude boundary in decimal degrees.
double SLAT
Southern latitude boundary in decimal degrees.
double ELON
Eastern longitude boundary in decimal degrees.