35#include <unordered_map>
58#if defined(__linux__) && !defined(__ANDROID__)
63#include <archive_entry.h>
69#include <wx/aui/aui.h>
72#include <wx/filename.h>
73#include <wx/hashmap.h>
74#include <wx/hashset.h>
75#include <wx/jsonreader.h>
76#include <wx/jsonval.h>
77#include <wx/listimpl.cpp>
78#include <wx/platinfo.h>
79#include <wx/popupwin.h>
80#include <wx/progdlg.h>
81#include <wx/statline.h>
82#include <wx/tarstrm.h>
83#include <wx/textwrapper.h>
84#include <wx/tokenzr.h>
85#include <wx/tooltip.h>
88#include <wx/zipstrm.h>
89#include <wx/zstream.h>
94#include "o_sound/o_sound.h"
113#include "model/nav_object_database.h"
165#include "androidUTIL.h"
172typedef __LA_INT64_T la_int64_t;
173enum { CurlThreadId = wxID_HIGHEST + 1 };
175#if wxUSE_XLOCALE || !wxCHECK_VERSION(3, 0, 0)
176extern wxLocale* plocale_def_lang;
181void NotifySetupOptionsPlugin(
const PlugInData* pic);
183WX_DEFINE_LIST(Plugin_WaypointList);
184WX_DEFINE_LIST(Plugin_HyperlinkList);
191 explicit RawKey(
const std::string& key) : m_key(key) {}
192 [[nodiscard]] std::string
GetKey()
const override {
return m_key; }
198static void SendAisJsonMessage(std::shared_ptr<const AisTargetData> pTarget) {
200 if (!GetJSONMessageTargetCount())
return;
205 wxLongLong t = ::wxGetLocalTimeMillis();
207 jMsg[wxS(
"Source")] = wxS(
"AisDecoder");
208 jMsg[
"Type"] =
"Information";
209 jMsg[
"Msg"] = wxS(
"AIS Target");
210 jMsg[
"MsgId"] = t.GetValue();
211 jMsg[wxS(
"lat")] = pTarget->Lat;
212 jMsg[wxS(
"lon")] = pTarget->Lon;
213 jMsg[wxS(
"sog")] = pTarget->SOG;
214 jMsg[wxS(
"cog")] = pTarget->COG;
215 jMsg[wxS(
"hdg")] = pTarget->HDG;
216 jMsg[wxS(
"mmsi")] = pTarget->MMSI;
217 jMsg[wxS(
"class")] = pTarget->Class;
218 jMsg[wxS(
"ownship")] = pTarget->b_OwnShip;
219 jMsg[wxS(
"active")] = pTarget->b_active;
220 jMsg[wxS(
"lost")] = pTarget->b_lost;
221 wxString l_ShipName = wxString::FromUTF8(pTarget->ShipName);
222 for (
size_t i = 0; i < l_ShipName.Len(); i++) {
223 if (l_ShipName.GetChar(i) ==
'@') l_ShipName.SetChar(i,
'\n');
225 jMsg[wxS(
"shipname")] = l_ShipName;
226 wxString l_CallSign = wxString::FromUTF8(pTarget->CallSign);
227 for (
size_t i = 0; i < l_CallSign.Len(); i++) {
228 if (l_CallSign.GetChar(i) ==
'@') l_CallSign.SetChar(i,
'\n');
230 jMsg[wxS(
"callsign")] = l_CallSign;
231 jMsg[wxS(
"removed")] = pTarget->b_removed;
232 SendJSONMessageToAllPlugins(
"AIS", jMsg);
236 return (*p1)->Key().compare((*p2)->Key());
240 auto version = metadata.version;
242 if (version[0] ==
'v') version = version.substr(1);
247 auto imported_version = ParseVersion(metadata);
248 for (
auto& md :
PluginHandler::GetInstance()->GetAvailable()) {
249 if (md.name != metadata.name)
continue;
250 if (md.is_imported)
continue;
252 if (ParseVersion(md) >= imported_version)
return true;
263 void message(
const std::string& message) {
265 m_deferred_messages.push_back(message);
270 void show_deferred_messages() {
271 for (
auto m : m_deferred_messages) show_msg(m);
278 void show_msg(wxString msg) {
279 OCPNMessageBox(NULL, msg, wxString(_(
"OpenCPN Info")),
280 wxICON_INFORMATION | wxOK, 10);
284 std::vector<wxString> m_deferred_messages;
291 Wrap(win, text, widthMax);
293 wxString
const& GetWrapped()
const {
return m_wrapped; }
294 int const GetLineCount()
const {
return m_lineCount; }
295 wxArrayString GetLineArray() {
return m_array; }
298 virtual void OnOutputLine(
const wxString& line) {
302 virtual void OnNewLine() {
310 wxArrayString m_array;
314 template <
typename T>
315 std::size_t operator()(T t)
const {
316 return static_cast<std::size_t
>(t);
323 return _(
"Plugin is a standard system plugin");
325 return _(
"Plugin is managed by OpenCPN");
327 return _(
"Plugin is not managed by OpenCPN");
330 case PluginStatus::Unknown:
331 return _(
"Plugin status unknown");
332 case PluginStatus::LegacyUpdateAvailable:
333 return _(
"Update to managed Plugin is available");
334 case PluginStatus::ManagedInstallAvailable:
335 return _(
"New managed Plugin installation available");
336 case PluginStatus::ManagedInstalledUpdateAvailable:
337 return _(
"Update to installed Plugin is available");
338 case PluginStatus::ManagedInstalledCurrentVersion:
339 return _(
"Plugin is latest available");
340 case PluginStatus::Imported:
341 return _(
"Plugin is imported");
342 case PluginStatus::ManagedInstalledDowngradeAvailable:
344 case PluginStatus::PendingListRemoval:
351static const std::unordered_map<PluginStatus, const char*, EnumClassHash>
357 {PluginStatus::Unknown,
"emblem-unmanaged.svg"},
358 {PluginStatus::LegacyUpdateAvailable,
"emblem-legacy-update.svg"},
359 {PluginStatus::ManagedInstallAvailable,
"emblem-download.svg"},
360 {PluginStatus::ManagedInstalledUpdateAvailable,
361 "emblem-legacy-update.svg"},
362 {PluginStatus::ManagedInstalledCurrentVersion,
"emblem-default.svg"},
363 {PluginStatus::ManagedInstalledDowngradeAvailable,
364 "emblem-default.svg"},
365 {PluginStatus::PendingListRemoval,
"emblem-default.svg"},
366 {PluginStatus::Imported,
"emblem-default.svg"}});
368static const std::unordered_map<PluginStatus, const char*, EnumClassHash>
369 literalstatus_by_status(
374 {PluginStatus::Unknown,
"Unknown"},
375 {PluginStatus::LegacyUpdateAvailable,
"LegacyUpdateAvailable"},
376 {PluginStatus::ManagedInstallAvailable,
"ManagedInstallAvailable"},
377 {PluginStatus::ManagedInstalledUpdateAvailable,
378 "ManagedInstalledUpdateAvailable"},
379 {PluginStatus::ManagedInstalledCurrentVersion,
380 "ManagedInstalledCurrentVersion"},
381 {PluginStatus::ManagedInstalledDowngradeAvailable,
382 "ManagedInstalledDowngradeAvailable"},
383 {PluginStatus::PendingListRemoval,
"PendingListRemoval"},
384 {PluginStatus::Imported,
"Imported"}
392static std::vector<PluginMetadata> getCompatiblePlugins() {
394 struct metadata_compare {
397 return lhs.key() < rhs.key();
401 std::vector<PluginMetadata> returnArray;
403 std::set<PluginMetadata, metadata_compare> unique_plugins;
404 for (
auto plugin :
PluginHandler::GetInstance()->GetAvailable()) {
405 unique_plugins.insert(plugin);
407 for (
auto plugin : unique_plugins) {
409 returnArray.push_back(plugin);
426 std::string installed;
428 if (path ==
"" || !wxFileName::IsFileReadable(path)) {
431 std::ifstream stream;
432 stream.open(path, std::ifstream::in);
441static std::vector<PluginMetadata> getUpdates(
const char* name) {
442 auto updates = getCompatiblePlugins();
444 std::remove_if(updates.begin(), updates.end(),
448 auto inst_vers = getInstalledVersion(name);
449 if (inst_vers.major == -1) {
454 updates.erase(std::remove_if(updates.begin(), updates.end(),
456 return metadata_version(m) == inst_vers;
463static void gui_uninstall(
const PlugInData* pic,
const char* plugin) {
464 g_Platform->ShowBusySpinner();
469 wxLogMessage(
"Uninstalling %s", plugin);
472 g_Platform->HideBusySpinner();
475static bool LoadAllPlugIns(
bool load_enabled,
bool keep_orphans =
false) {
476 g_Platform->ShowBusySpinner();
478 PluginLoader::GetInstance()->
LoadAllPlugIns(load_enabled, keep_orphans);
479 g_Platform->HideBusySpinner();
484static void UninstallPlugin(
const std::string& name) {
486 auto loader = PluginLoader::GetInstance();
487 auto finder = [name](
const PluginMetadata pm) {
return pm.name == name; };
488 const auto& installed = handler->GetInstalled();
489 auto found = std::find_if(installed.begin(), installed.end(), finder);
490 if (found != installed.end()) {
491 for (
size_t i = 0; i < loader->GetPlugInArray()->GetCount(); i++) {
492 auto const& item = loader->GetPlugInArray()->Item(i);
493 if (item->m_common_name.ToStdString() == name) {
494 DEBUG_LOG <<
"Unloading plugin: " << name;
495 loader->UnLoadPlugIn(i);
499 handler->Uninstall(found->name);
500 DEBUG_LOG <<
"Uninstalling: " << found->name;
505 bool uninstall,
const char* name = 0,
506 bool b_forceEnable =
false) {
508 const char* plugin = name == 0 ? pic->
m_common_name.mb_str().data() : name;
509 auto updates = getUpdates(plugin);
510 auto parent_dlg =
dynamic_cast<wxScrolledWindow*
>(parent);
511 wxASSERT(parent_dlg != 0);
513 auto status = dialog.ShowModal();
514 status = dialog.GetReturnCode();
515 if (status != wxID_OK) {
519 auto update = dialog.GetUpdate();
524 wxLogMessage(
"Installing %s", update.name.c_str());
526 g_Platform->ShowBusySpinner();
530 if (uninstall && path !=
"") {
531 gui_uninstall(pic, update.name.c_str());
533 bool cacheResult = pluginHandler->InstallPluginFromCache(update);
536 g_Platform->ShowBusySpinner();
540 std::string tempTarballPath = downloader->run(parent_dlg, uninstall);
542 if (!tempTarballPath.size())
548 if (!isRegularFile(manifestPath.c_str())) {
549 wxLogMessage(
"Installation of %s failed", update.name.c_str());
550 PluginHandler::CleanupFiles(manifestPath, update.name);
556 wxLogMessage(
"Installation of %s successful", update.name.c_str());
557 wxURI uri(wxString(update.tarball_url.c_str()));
558 wxFileName fn(uri.GetPath());
559 std::string basename = fn.GetFullName().ToStdString();
562 wxLogDebug(
"Copied %s to local cache at %s", tempTarballPath.c_str(),
564 remove(tempTarballPath.c_str());
572 wxString pispec =
"_pi.dll";
573#elif defined(__WXOSX__)
574 wxString pispec =
"_pi.dylib";
576 wxString pispec =
"_pi.so";
580 wxTextFile manifest_file(manifestPath);
582 if (manifest_file.Open()) {
584 for (wxString str = manifest_file.GetFirstLine(); !manifest_file.Eof();
585 str = manifest_file.GetNextLine()) {
586 if (str.Contains(pispec)) {
587 if (getenv(
"OCPN_KEEP_PLUGINS")) {
591 auto loader = PluginLoader::GetInstance();
592 if (!loader->CheckPluginCompatibility(str)) {
594 _(
"The plugin is not compatible with this version of OpenCPN, "
595 "and will be uninstalled.");
596 OCPNMessageBox(NULL, msg, wxString(_(
"OpenCPN Info")),
597 wxICON_INFORMATION | wxOK, 10);
599 PluginHandler::CleanupFiles(manifestPath, update.name);
608 if (b_forceEnable && pluginFile.Length()) {
609 wxString config_section = (_T (
"/PlugIns/" ));
610 wxFileName fn(pluginFile);
611 config_section += fn.GetFullName();
612 pConfig->SetPath(config_section);
613 pConfig->Write(_T (
"bEnabled" ),
true);
619 std::remove(handler->ImportedMetadataPath(update.name).c_str());
622 LoadAllPlugIns(
false);
625 g_Platform->HideBusySpinner();
645 pivp.
lat_min = tvp.GetBBox().GetMinLat();
646 pivp.
lat_max = tvp.GetBBox().GetMaxLat();
647 pivp.
lon_min = tvp.GetBBox().GetMinLon();
648 pivp.
lon_max = tvp.GetBBox().GetMaxLon();
650 pivp.
bValid = tvp.IsValid();
671 if (gFrame->GetPrimaryCanvas())
687 void OnPluginUtilAction(wxCommandEvent& event);
689 DECLARE_EVENT_TABLE()
693EVT_BUTTON(ID_CMD_BUTTON_PERFORM_ACTION, pluginUtilHandler::OnPluginUtilAction)
698void pluginUtilHandler::OnPluginUtilAction(wxCommandEvent& event) {
699 auto panel =
static_cast<PluginPanel*
>(
event.GetClientData());
702 wxASSERT(plugin_list_panel != 0);
704 auto actionPIC = panel->GetPlugin();
705 wxString name = actionPIC->m_common_name;
708 switch (panel->GetAction()) {
709 case ActionVerb::UPGRADE_TO_MANAGED_VERSION: {
710 auto loader = PluginLoader::GetInstance();
713 std::string pluginName = actionPIC->m_managed_metadata.name;
715 wxLogMessage(
"Installing managed plugin: %s", pluginName.c_str());
717 new GuiDownloader(plugin_list_panel, actionPIC->m_managed_metadata);
718 downloader->run(plugin_list_panel,
false);
722 if (isRegularFile(manifestPath.c_str())) {
724 for (
unsigned i = 0; i < loader->GetPlugInArray()->GetCount(); i += 1) {
725 if (actionPIC->m_managed_metadata.name ==
726 loader->GetPlugInArray()->Item(i)->m_common_name.ToStdString()) {
727 loader->UnLoadPlugIn(i);
733 LoadAllPlugIns(
false);
735 PluginHandler::CleanupFiles(manifestPath,
736 actionPIC->m_managed_metadata.name);
739 plugin_list_panel->SelectByName(name);
744 case ActionVerb::UPDATE_IMPORTED_VERSION:
745 case ActionVerb::UPGRADE_INSTALLED_MANAGED_VERSION:
746 case ActionVerb::REINSTALL_MANAGED_VERSION:
747 case ActionVerb::DOWNGRADE_INSTALLED_MANAGED_VERSION: {
749 auto metaSave = actionPIC->m_managed_metadata;
750 run_update_dialog(plugin_list_panel, actionPIC,
true,
751 metaSave.name.c_str());
755 case ActionVerb::INSTALL_MANAGED_VERSION: {
756 wxLogMessage(
"Installing new managed plugin.");
757 run_update_dialog(plugin_list_panel, actionPIC,
false);
761 case ActionVerb::UNINSTALL_MANAGED_VERSION: {
764 message.Printf(
"%s %s\n", actionPIC->m_managed_metadata.name.c_str(),
765 actionPIC->m_managed_metadata.version.c_str());
766 message += _(
"successfully un-installed");
768 wxLogMessage(
"Uninstalling %s",
769 actionPIC->m_managed_metadata.name.c_str());
772 actionPIC->m_managed_metadata.name);
775 LoadAllPlugIns(
false);
777 OCPNMessageBox(gFrame, message, _(
"Un-Installation complete"),
778 wxICON_INFORMATION | wxOK);
782 case ActionVerb::NOP:
793const wxEventType wxEVT_OCPN_MSG = wxNewEventType();
795OCPN_MsgEvent::OCPN_MsgEvent(wxEventType commandType,
int id)
796 : wxEvent(id, commandType) {}
798OCPN_MsgEvent::~OCPN_MsgEvent() {}
800wxEvent* OCPN_MsgEvent::Clone()
const {
802 newevent->m_MessageID =
805 newevent->m_MessageText = this->m_MessageText.c_str();
814PlugInToolbarToolContainer::PlugInToolbarToolContainer() {
818 bitmap_Rollover_day = NULL;
819 bitmap_Rollover_dusk = NULL;
820 bitmap_Rollover_night = NULL;
823PlugInToolbarToolContainer::~PlugInToolbarToolContainer() {
827 delete bitmap_Rollover_day;
828 delete bitmap_Rollover_dusk;
829 delete bitmap_Rollover_night;
840#if !defined(__ANDROID__) && defined(OCPN_USE_CURL)
841EVT_CURL_END_PERFORM(CurlThreadId, PlugInManager::OnEndPerformCurlDownload)
842EVT_CURL_DOWNLOAD(CurlThreadId, PlugInManager::OnCurlDownload)
846static
void event_message_box(const wxString& msg) {
847 OCPNMessageBox(NULL, msg, wxString(_(
"OpenCPN Info")),
848 wxICON_INFORMATION | wxOK, 0);
854 if (!pic->m_toolbox_panel) NotifySetupOptionsPlugin(pic);
859PlugInManager::PlugInManager(
MyFrame* parent) {
860#if !defined(__ANDROID__) && defined(OCPN_USE_CURL)
861 m_pCurlThread = NULL;
867 MyFrame* pFrame = GetParentFrame();
869 m_plugin_menu_item_id_next = CanvasMenuHandler::GetNextContextMenuId();
870 m_plugin_tool_id_next = pFrame->GetNextToolbarToolId();
883 new wxRadioBox(pFrame, -1,
"", wxPoint(0, 0), wxSize(-1, -1), as);
889#if !defined(__ANDROID__) && defined(OCPN_USE_CURL)
891 m_last_online =
false;
892 m_last_online_chk = -1;
897 m_blacklist = blacklist_factory();
898 m_blacklist_ui = std::unique_ptr<BlacklistUI>(
new BlacklistUI());
900 wxDEFINE_EVENT(EVT_JSON_TO_ALL_PLUGINS,
ObservedEvt);
902 EVT_JSON_TO_ALL_PLUGINS);
903 Bind(EVT_JSON_TO_ALL_PLUGINS, [&](
ObservedEvt& ev) {
904 auto json = std::static_pointer_cast<const wxJSONValue>(ev.
GetSharedPtr());
905 SendJSONMessageToAllPlugins(ev.GetString(), *json);
908 wxDEFINE_EVENT(EVT_LEGINFO_TO_ALL_PLUGINS,
ObservedEvt);
910 EVT_LEGINFO_TO_ALL_PLUGINS);
911 Bind(EVT_LEGINFO_TO_ALL_PLUGINS, [&](
ObservedEvt& ev) {
912 auto ptr = UnpackEvtPointer<ActiveLegDat>(ev);
913 SendActiveLegInfoToAllPlugIns(ptr.get());
916 HandlePluginLoaderEvents();
922 m_new_msgtype_lstnr.
Init(NavMsgBus::GetInstance().new_msg_event,
925PlugInManager::~PlugInManager() {
926#if !defined(__ANDROID__) && defined(OCPN_USE_CURL)
927 wxCurlBase::Shutdown();
929 delete m_utilHandler;
932void PlugInManager::InitCommListeners() {
936 auto& msgbus = NavMsgBus::GetInstance();
939 m_listener_SignalK.
Listen(sk_msg,
this, EVT_SIGNALK);
946void PlugInManager::OnNewMessageType() {
947 for (
auto msg_key :
NavMsgBus::GetInstance().GetActiveMessages()) {
948 if (m_0183_listeners.find(msg_key) != m_0183_listeners.end())
continue;
949 if (msg_key.find(
"::") == std::string::npos)
continue;
951 if (key_parts.size() < 2)
continue;
956 m_0183_listeners[msg_key] = std::move(ol);
961 assert(n0183_msg->bus == NavAddr::Bus::N0183);
962 const std::string& payload = n0183_msg->payload;
964 if (payload[0] ==
'$') {
965 const auto& drivers = CommDriverRegistry::GetInstance().
GetDrivers();
966 auto& target_driver =
FindDriver(drivers, n0183_msg->source->iface);
970 bool passes_input_filter =
true;
974 passes_input_filter =
975 params.SentencePassesFilter(payload.c_str(), FILTER_INPUT);
978 }
else if (payload[0] ==
'!') {
979 SendAISSentenceToAllPlugIns(payload.c_str());
984 g_ownshipMMSI_SK = sK_msg->context_self;
989 std::string msgTerminated = sK_msg->raw_message;
992 int errors = jsonReader.
Parse(msgTerminated, &root);
993 if (errors == 0) SendJSONMessageToAllPlugins(
"OCPN_CORE_SIGNALK", root);
1002wxDEFINE_EVENT(EVT_PLUGMGR_ROUTEMAN_MSG,
ObservedEvt);
1003wxDEFINE_EVENT(EVT_BLACKLISTED_PLUGIN, wxCommandEvent);
1004wxDEFINE_EVENT(EVT_LOAD_DIRECTORY, wxCommandEvent);
1005wxDEFINE_EVENT(EVT_LOAD_PLUGIN, wxCommandEvent);
1006wxDEFINE_EVENT(EVT_PLUGIN_UNLOAD, wxCommandEvent);
1007wxDEFINE_EVENT(EVT_PLUGLIST_CHANGE, wxCommandEvent);
1008wxDEFINE_EVENT(EVT_UPDATE_CHART_TYPES, wxCommandEvent);
1009wxDEFINE_EVENT(EVT_PLUGIN_LOADALL_FINALIZE, wxCommandEvent);
1011void PlugInManager::HandlePluginLoaderEvents() {
1012 auto loader = PluginLoader::GetInstance();
1014 loader->SetOnActivateCb(
1016 loader->SetOnDeactivateCb(
1019 evt_pluglist_change_listener.
Listen(loader->evt_pluglist_change,
this,
1020 EVT_PLUGLIST_CHANGE);
1021 Bind(EVT_PLUGLIST_CHANGE, [&](wxCommandEvent&) {
1026 evt_load_directory_listener.
Listen(loader->evt_load_directory,
this,
1027 EVT_LOAD_DIRECTORY);
1028 Bind(EVT_LOAD_DIRECTORY, [&](wxCommandEvent&) {
1029 pConfig->SetPath(
"/PlugIns/");
1030 SetPluginOrder(pConfig->Read(
"PluginOrder", wxEmptyString));
1033 evt_load_plugin_listener.
Listen(loader->evt_load_plugin,
this,
1035 Bind(EVT_LOAD_PLUGIN, [&](wxCommandEvent& ev) {
1040 evt_update_chart_types_listener.
Listen(loader->evt_update_chart_types,
this,
1041 EVT_UPDATE_CHART_TYPES);
1042 Bind(EVT_UPDATE_CHART_TYPES,
1043 [&](wxCommandEvent& ev) { UpDateChartDataTypes(); });
1045 evt_plugin_loadall_finalize_listener.
Listen(
1046 loader->evt_plugin_loadall_finalize,
this, EVT_PLUGIN_LOADALL_FINALIZE);
1047 Bind(EVT_PLUGIN_LOADALL_FINALIZE,
1048 [&](wxCommandEvent& ev) { FinalizePluginLoadall(); });
1052 EVT_PLUGMGR_ROUTEMAN_MSG);
1054 auto pTarget = UnpackEvtPointer<AisTargetData>(ev);
1055 SendAisJsonMessage(pTarget);
1057 Bind(EVT_PLUGMGR_ROUTEMAN_MSG, [&](
ObservedEvt& ev) {
1058 auto msg = UnpackEvtPointer<wxJSONValue>(ev);
1059 SendJSONMessageToAllPlugins(ev.GetString(), *msg);
1067wxDEFINE_EVENT(EVT_DOWNLOAD_FAILED, wxCommandEvent);
1068wxDEFINE_EVENT(EVT_DOWNLOAD_OK, wxCommandEvent);
1070void PlugInManager::HandlePluginHandlerEvents() {
1071 auto loader = PluginLoader::GetInstance();
1073 evt_download_failed_listener.
Listen(loader->evt_update_chart_types,
this,
1074 EVT_DOWNLOAD_FAILED);
1075 Bind(EVT_DOWNLOAD_FAILED, [&](wxCommandEvent& ev) {
1076 wxString message = _(
"Please check system log for more info.");
1077 OCPNMessageBox(gFrame, message, _(
"Installation error"),
1078 wxICON_ERROR | wxOK | wxCENTRE);
1081 evt_download_ok_listener.
Listen(loader->evt_update_chart_types,
this,
1083 Bind(EVT_DOWNLOAD_OK, [&](wxCommandEvent& ev) {
1084 wxString message(ev.GetString());
1085 message += _(
" successfully installed from cache");
1086 OCPNMessageBox(gFrame, message, _(
"Installation complete"),
1087 wxICON_INFORMATION | wxOK | wxCENTRE);
1091bool PlugInManager::CallLateInit() {
1094 auto plugin_array = PluginLoader::GetInstance()->
GetPlugInArray();
1095 for (
unsigned int i = 0; i < plugin_array->GetCount(); i++) {
1098 switch (pic->m_api_version) {
1111 ProcessLateInit(pic);
1121 wxString msg(
"PlugInManager: Calling LateInit PlugIn: ");
1126 if (ppi) ppi->LateInit();
1135 if (gFrame->GetPrimaryCanvas()->GetglCanvas()) {
1136 gFrame->GetPrimaryCanvas()->GetglCanvas()->SendJSONConfigMessage();
1137 SendS52ConfigToAllPlugIns(
true);
1152 for (
unsigned int i = 0; i < m_PlugInToolbarTools.GetCount(); i++) {
1155 if (pttc->m_pplugin == pic->m_pplugin) {
1156 m_PlugInToolbarTools.Remove(pttc);
1162 for (
unsigned int i = 0; i < m_PlugInMenuItems.GetCount(); i++) {
1164 if (pimis->m_pplugin == pic->m_pplugin) {
1165 m_PlugInMenuItems.Remove(pimis);
1171bool PlugInManager::IsAnyPlugInChartEnabled() {
1174 auto plugin_array = PluginLoader::GetInstance()->
GetPlugInArray();
1175 for (
unsigned int i = 0; i < plugin_array->GetCount(); i++) {
1177 if (pic->m_enabled && pic->m_init_state) {
1186void PlugInManager::UpdateManagedPlugins() {
1188 PluginLoader::GetInstance()->
SortPlugins(ComparePlugins);
1191 g_options->itemBoxSizerPanelPlugins->Layout();
1194bool PlugInManager::UpDateChartDataTypes() {
1198 auto plugin_array = PluginLoader::GetInstance()->
GetPlugInArray();
1199 for (
unsigned int i = 0; i < plugin_array->GetCount(); i++) {
1202 if (pic->m_init_state) {
1210 if (bret)
ChartData->UpdateChartClassDescriptorArray();
1215void PlugInManager::FinalizePluginLoadall() {
1219 SetColorSchemeForAllPlugIns(global_color_scheme);
1222 SendBaseConfigToAllPlugIns();
1223 SendS52ConfigToAllPlugIns(
true);
1224 SendSKConfigToAllPlugIns();
1229 if (gFrame->GetPrimaryCanvas()->GetglCanvas())
1230 gFrame->GetPrimaryCanvas()->GetglCanvas()->SendJSONConfigMessage();
1238void PlugInManager::SetPluginOrder(wxString serialized_names) {
1239 m_plugin_order.Empty();
1240 wxStringTokenizer tokenizer(serialized_names,
";");
1241 while (tokenizer.HasMoreTokens()) {
1242 m_plugin_order.Add(tokenizer.GetNextToken());
1246wxString PlugInManager::GetPluginOrder() {
1247 wxString plugins = wxEmptyString;
1248 auto plugin_array = PluginLoader::GetInstance()->
GetPlugInArray();
1249 for (
unsigned int i = 0; i < plugin_array->GetCount(); i++) {
1250 plugins.Append(plugin_array->Item(i)->m_common_name);
1251 if (i < plugin_array->GetCount() - 1) plugins.Append(
';');
1256bool PlugInManager::UpdateConfig() {
1260 auto plugin_array = PluginLoader::GetInstance()->
GetPlugInArray();
1261 for (
unsigned int i = 0; i < plugin_array->GetCount(); i++) {
1265 wxString config_section = (_T (
"/PlugIns/" ));
1267 pConfig->SetPath(config_section);
1268 pConfig->Write(_T (
"bEnabled" ), pic->m_enabled);
1275void PlugInManager::ShowDeferredBlacklistMessages() {
1276 m_blacklist_ui->show_deferred_messages();
1279bool PlugInManager::CheckBlacklistedPlugin(
const PluginMetadata plugin) {
1281 return CheckBlacklistedPlugin(wxString(plugin.name), v.major, v.minor);
1284bool PlugInManager::CheckBlacklistedPlugin(
opencpn_plugin* plugin) {
1289 wxString name = wxString::FromAscii(
typeid(*plugin).name());
1290 name.Replace(
"class ", wxEmptyString);
1292 const std::type_info& ti =
typeid(*plugin);
1294 char* realname = abi::__cxa_demangle(ti.name(), 0, 0, &status);
1295 wxString name = wxString::FromAscii(realname);
1298 return CheckBlacklistedPlugin(name, major, minor);
1301bool PlugInManager::CheckBlacklistedPlugin(wxString name,
int major,
1303 auto block_status = m_blacklist->get_status(name.ToStdString(), major, minor);
1304 if (block_status == plug_status::unblocked)
return true;
1305 plug_data data(name.ToStdString(), major, minor);
1306 auto msg = m_blacklist->get_message(block_status, data);
1307 m_blacklist_ui->message(msg);
1311bool PlugInManager::RenderAllCanvasOverlayPlugIns(
ocpnDC& dc,
1315 auto plugin_array = PluginLoader::GetInstance()->
GetPlugInArray();
1316 for (
unsigned int i = 0; i < plugin_array->GetCount(); i++) {
1318 if (pic->m_enabled && pic->m_init_state) {
1322 wxDC* pdc = dc.GetDC();
1325 switch (pic->m_api_version) {
1327 if (priority > 0)
break;
1334 if (priority > 0)
break;
1337 if (ppi) ppi->RenderOverlay(*pdc, &pivp);
1348 if (priority > 0)
break;
1351 if (ppi) ppi->RenderOverlay(*pdc, &pivp);
1356 if (priority > 0)
break;
1360 ppi->RenderOverlay(*pdc, &pivp);
1372 if (priority <= 0) {
1376 ppi->RenderOverlay(*pdc, &pivp);
1392 if (pic->
m_cap_flag & WANTS_OPENGL_OVERLAY_CALLBACK)
continue;
1394 if ((m_cached_overlay_bm.GetWidth() != vp.
pix_width) ||
1395 (m_cached_overlay_bm.GetHeight() != vp.
pix_height))
1399 mdc.SelectObject(m_cached_overlay_bm);
1400 mdc.SetBackground(*wxBLACK_BRUSH);
1403 bool b_rendered =
false;
1405 switch (pic->m_api_version) {
1407 if (priority > 0)
break;
1414 if (priority > 0)
break;
1417 if (ppi) b_rendered = ppi->RenderOverlay(mdc, &pivp);
1428 if (priority > 0)
break;
1431 if (ppi) b_rendered = ppi->RenderOverlay(mdc, &pivp);
1436 if (priority > 0)
break;
1440 b_rendered = ppi->RenderOverlay(mdc, &pivp);
1453 if (priority <= 0) {
1457 b_rendered = ppi->RenderOverlay(mdc, &pivp);
1464 mdc, &pivp, g_canvasConfig, priority);
1473 mdc.SelectObject(wxNullBitmap);
1476 wxMask* p_msk =
new wxMask(m_cached_overlay_bm, wxColour(0, 0, 0));
1477 m_cached_overlay_bm.SetMask(p_msk);
1479 dc.DrawBitmap(m_cached_overlay_bm, 0, 0,
true);
1482 }
else if (pic->
m_cap_flag & WANTS_OPENGL_OVERLAY_CALLBACK) {
1490bool PlugInManager::RenderAllGLCanvasOverlayPlugIns(wxGLContext* pcontext,
1494 auto plugin_array = PluginLoader::GetInstance()->
GetPlugInArray();
1495 for (
unsigned int i = 0; i < plugin_array->GetCount(); i++) {
1497 if (pic->m_enabled && pic->m_init_state) {
1498 if (pic->
m_cap_flag & WANTS_OPENGL_OVERLAY_CALLBACK) {
1501 switch (pic->m_api_version) {
1503 if (priority > 0)
break;
1506 if (ppi) ppi->RenderGLOverlay(pcontext, &pivp);
1518 if (priority > 0)
break;
1526 if (priority > 0)
break;
1543 if (priority <= 0) {
1568void PlugInManager::SendViewPortToRequestingPlugIns(
ViewPort& vp) {
1569 auto plugin_array = PluginLoader::GetInstance()->
GetPlugInArray();
1570 for (
unsigned int i = 0; i < plugin_array->GetCount(); i++) {
1572 if (pic->m_enabled && pic->m_init_state) {
1581void NotifySetupOptionsPlugin(
const PlugInData* pd) {
1582 PluginLoader::GetInstance()->NotifySetupOptionsPlugin(pd);
1585void PlugInManager::NotifySetupOptions() {
1586 auto plugin_array = PluginLoader::GetInstance()->
GetPlugInArray();
1587 for (
unsigned int i = 0; i < plugin_array->GetCount(); i++) {
1589 NotifySetupOptionsPlugin(pic);
1594 int ok_apply_cancel) {
1595 if (pic->m_enabled && pic->m_init_state) {
1598 auto loader = PluginLoader::GetInstance();
1605void PlugInManager::CloseAllPlugInPanels(
int ok_apply_cancel) {
1606 auto plugin_array = PluginLoader::GetInstance()->
GetPlugInArray();
1607 for (
unsigned int i = 0; i < plugin_array->GetCount(); i++) {
1610 ClosePlugInPanel(pic, ok_apply_cancel);
1615int PlugInManager::AddCanvasContextMenuItemPIM(wxMenuItem* pitem,
1620 pmic->pmenu_item = pitem;
1621 pmic->m_pplugin = pplugin;
1622 pmic->id = pitem->GetId() == wxID_SEPARATOR ? wxID_SEPARATOR
1623 : m_plugin_menu_item_id_next;
1625 pmic->b_grey =
false;
1626 pmic->m_in_menu = name;
1627 pmic->extended = is_extended;
1629 m_PlugInMenuItems.Add(pmic);
1631 m_plugin_menu_item_id_next++;
1636void PlugInManager::RemoveCanvasContextMenuItem(
int item,
const char* name) {
1637 for (
unsigned int i = 0; i < m_PlugInMenuItems.GetCount(); i++) {
1640 if (pimis->id == item) {
1641 m_PlugInMenuItems.Remove(pimis);
1649void PlugInManager::SetCanvasContextMenuItemViz(
int item,
bool viz,
1651 for (
unsigned int i = 0; i < m_PlugInMenuItems.GetCount(); i++) {
1654 if (pimis->id == item && !strcmp(name, pimis->m_in_menu)) {
1662void PlugInManager::SetCanvasContextMenuItemGrey(
int item,
bool grey,
1664 for (
unsigned int i = 0; i < m_PlugInMenuItems.GetCount(); i++) {
1667 if (pimis->id == item && !strcmp(name, pimis->m_in_menu)) {
1668 pimis->b_grey = grey;
1675void PlugInManager::SendResizeEventToAllPlugIns(
int x,
int y) {
1676 auto plugin_array = PluginLoader::GetInstance()->
GetPlugInArray();
1677 for (
unsigned int i = 0; i < plugin_array->GetCount(); i++) {
1679 if (pic->m_enabled && pic->m_init_state)
1684void PlugInManager::SetColorSchemeForAllPlugIns(ColorScheme cs) {
1685 auto plugin_array = PluginLoader::GetInstance()->
GetPlugInArray();
1686 for (
unsigned int i = 0; i < plugin_array->GetCount(); i++) {
1688 if (pic->m_enabled && pic->m_init_state)
1693void PlugInManager::PrepareAllPluginContextMenus() {
1694 int canvasIndex = gFrame->GetCanvasIndexUnderMouse();
1695 if (canvasIndex < 0)
return;
1697 auto plugin_array = PluginLoader::GetInstance()->
GetPlugInArray();
1698 for (
unsigned int i = 0; i < plugin_array->GetCount(); i++) {
1700 if (pic->m_enabled && pic->m_init_state) {
1702 switch (pic->m_api_version) {
1722void PlugInManager::SendSKConfigToAllPlugIns() {
1725 v[
"self"] = g_ownshipMMSI_SK;
1729 SendMessageToAllPlugins(wxString(
"OCPN_CORE_SIGNALK"), out);
1732void PlugInManager::SendBaseConfigToAllPlugIns() {
1735 v[
"OpenCPN Version Major"] = VERSION_MAJOR;
1736 v[
"OpenCPN Version Minor"] = VERSION_MINOR;
1737 v[
"OpenCPN Version Patch"] = VERSION_PATCH;
1738 v[
"OpenCPN Version Date"] = VERSION_DATE;
1739 v[
"OpenCPN Version Full"] = VERSION_FULL;
1743 v[
"OpenCPN Toolbar Width"] =
g_MainToolbar->GetToolbarRect().width;
1744 v[
"OpenCPN Toolbar Height"] =
g_MainToolbar->GetToolbarRect().height;
1745 v[
"OpenCPN Toolbar PosnX"] =
g_MainToolbar->GetToolbarRect().x;
1746 v[
"OpenCPN Toolbar PosnY"] =
g_MainToolbar->GetToolbarRect().y;
1750 v[
"OpenCPN Zoom Mod Vector"] = g_chart_zoom_modifier_vector;
1751 v[
"OpenCPN Zoom Mod Other"] = g_chart_zoom_modifier_raster;
1752 v[
"OpenCPN Scale Factor Exp"] =
1753 g_Platform->GetChartScaleFactorExp(g_ChartScaleFactor);
1761 SendMessageToAllPlugins(wxString(
"OpenCPN Config"), out);
1764void PlugInManager::SendS52ConfigToAllPlugIns(
bool bReconfig) {
1767 v[
"OpenCPN Version Major"] = VERSION_MAJOR;
1768 v[
"OpenCPN Version Minor"] = VERSION_MINOR;
1769 v[
"OpenCPN Version Patch"] = VERSION_PATCH;
1770 v[
"OpenCPN Version Date"] = VERSION_DATE;
1771 v[
"OpenCPN Version Full"] = VERSION_FULL;
1779 v[
"OpenCPN S52PLIB ShowAnchorConditions"] = ps52plib->GetAnchorOn();
1780 v[
"OpenCPN S52PLIB ShowQualityOfData"] = ps52plib->GetQualityOfData();
1785 v[
"OpenCPN S52PLIB MetaDisplay"] = ps52plib->m_bShowMeta;
1786 v[
"OpenCPN S52PLIB DeclutterText"] = ps52plib->m_bDeClutterText;
1787 v[
"OpenCPN S52PLIB ShowNationalText"] = ps52plib->m_bShowNationalTexts;
1788 v[
"OpenCPN S52PLIB ShowImportantTextOnly"] =
1789 ps52plib->m_bShowS57ImportantTextOnly;
1790 v[
"OpenCPN S52PLIB UseSCAMIN"] = ps52plib->m_bUseSCAMIN;
1791 v[
"OpenCPN S52PLIB UseSUPER_SCAMIN"] = ps52plib->m_bUseSUPER_SCAMIN;
1792 v[
"OpenCPN S52PLIB SymbolStyle"] = ps52plib->m_nSymbolStyle;
1793 v[
"OpenCPN S52PLIB BoundaryStyle"] = ps52plib->m_nBoundaryStyle;
1794 v[
"OpenCPN S52PLIB ColorShades"] = S52_getMarinerParam(S52_MAR_TWO_SHADES);
1795 v[
"OpenCPN S52PLIB Safety Depth"] =
1796 (double)S52_getMarinerParam(S52_MAR_SAFETY_DEPTH);
1797 v[
"OpenCPN S52PLIB Shallow Contour"] =
1798 (double)S52_getMarinerParam(S52_MAR_SHALLOW_CONTOUR);
1799 v[
"OpenCPN S52PLIB Deep Contour"] =
1800 (double)S52_getMarinerParam(S52_MAR_DEEP_CONTOUR);
1804 v[
"OpenCPN S52PLIB GlobalReconfig"] = bReconfig;
1809 SendMessageToAllPlugins(wxString(
"OpenCPN Config"), out);
1812void PlugInManager::NotifyAuiPlugIns() {
1813 auto plugin_array = PluginLoader::GetInstance()->
GetPlugInArray();
1814 for (
unsigned int i = 0; i < plugin_array->GetCount(); i++) {
1816 if (pic->m_enabled && pic->m_init_state &&
1822int PlugInManager::AddToolbarTool(wxString label, wxBitmap* bitmap,
1823 wxBitmap* bmpRollover, wxItemKind kind,
1824 wxString shortHelp, wxString longHelp,
1825 wxObject* clientData,
int position,
1828 pttc->label = label;
1830 if (!bitmap->IsOk()) {
1832 pttc->bitmap_day =
new wxBitmap(style->GetIcon(
"default_pi"));
1835 pttc->bitmap_day =
new wxBitmap(*bitmap);
1836 pttc->bitmap_day->UnShare();
1839 if (!bmpRollover->IsOk()) {
1841 pttc->bitmap_Rollover_day =
new wxBitmap(style->GetIcon(
"default_pi"));
1844 pttc->bitmap_Rollover_day =
new wxBitmap(*bmpRollover);
1845 pttc->bitmap_Rollover_day->UnShare();
1848 pttc->bitmap_dusk = BuildDimmedToolBitmap(pttc->bitmap_day, 128);
1849 pttc->bitmap_night = BuildDimmedToolBitmap(pttc->bitmap_day, 32);
1850 pttc->bitmap_Rollover_dusk =
1851 BuildDimmedToolBitmap(pttc->bitmap_Rollover_day, 128);
1852 pttc->bitmap_Rollover_night =
1853 BuildDimmedToolBitmap(pttc->bitmap_Rollover_day, 32);
1856 pttc->shortHelp = shortHelp;
1857 pttc->longHelp = longHelp;
1858 pttc->clientData = clientData;
1859 pttc->position = position;
1860 pttc->m_pplugin = pplugin;
1861 pttc->tool_sel = tool_sel;
1863 pttc->b_toggle =
false;
1864 pttc->id = m_plugin_tool_id_next;
1866 m_PlugInToolbarTools.Add(pttc);
1868 m_plugin_tool_id_next++;
1873int PlugInManager::AddToolbarTool(wxString label, wxString SVGfile,
1874 wxString SVGRolloverfile,
1875 wxString SVGToggledfile, wxItemKind kind,
1876 wxString shortHelp, wxString longHelp,
1877 wxObject* clientData,
int position,
1880 pttc->label = label;
1882 pttc->pluginNormalIconSVG = SVGfile;
1883 pttc->pluginRolloverIconSVG = SVGRolloverfile;
1884 pttc->pluginToggledIconSVG = SVGToggledfile;
1889 pttc->bitmap_day =
new wxBitmap(style->GetIcon(
"default_pi"));
1890 pttc->bitmap_dusk = BuildDimmedToolBitmap(pttc->bitmap_day, 128);
1891 pttc->bitmap_night = BuildDimmedToolBitmap(pttc->bitmap_day, 32);
1892 pttc->bitmap_Rollover_day =
new wxBitmap(*pttc->bitmap_day);
1893 pttc->bitmap_Rollover_dusk =
1894 BuildDimmedToolBitmap(pttc->bitmap_Rollover_day, 128);
1895 pttc->bitmap_Rollover_night =
1896 BuildDimmedToolBitmap(pttc->bitmap_Rollover_day, 32);
1899 pttc->shortHelp = shortHelp;
1900 pttc->longHelp = longHelp;
1901 pttc->clientData = clientData;
1902 pttc->position = position;
1903 pttc->m_pplugin = pplugin;
1904 pttc->tool_sel = tool_sel;
1906 pttc->b_toggle =
false;
1907 pttc->id = m_plugin_tool_id_next;
1909 m_PlugInToolbarTools.Add(pttc);
1911 m_plugin_tool_id_next++;
1916void PlugInManager::RemoveToolbarTool(
int tool_id) {
1917 for (
unsigned int i = 0; i < m_PlugInToolbarTools.GetCount(); i++) {
1920 if (pttc->id == tool_id) {
1921 m_PlugInToolbarTools.Remove(pttc);
1927 pParent->RequestNewToolbars();
1930void PlugInManager::SetToolbarToolViz(
int item,
bool viz) {
1931 for (
unsigned int i = 0; i < m_PlugInToolbarTools.GetCount(); i++) {
1934 if (pttc->id == item) {
1936 pParent->RequestNewToolbars();
1943void PlugInManager::SetToolbarItemState(
int item,
bool toggle) {
1944 for (
unsigned int i = 0; i < m_PlugInToolbarTools.GetCount(); i++) {
1947 if (pttc->id == item) {
1948 pttc->b_toggle = toggle;
1949 pParent->SetMasterToolbarItemState(item, toggle);
1956void PlugInManager::SetToolbarItemBitmaps(
int item, wxBitmap* bitmap,
1957 wxBitmap* bmpRollover) {
1958 for (
unsigned int i = 0; i < m_PlugInToolbarTools.GetCount(); i++) {
1961 if (pttc->id == item) {
1962 delete pttc->bitmap_day;
1963 delete pttc->bitmap_dusk;
1964 delete pttc->bitmap_night;
1965 delete pttc->bitmap_Rollover_day;
1967 if (!bitmap->IsOk()) {
1969 pttc->bitmap_day =
new wxBitmap(style->GetIcon(
"default_pi"));
1972 pttc->bitmap_day =
new wxBitmap(*bitmap);
1973 pttc->bitmap_day->UnShare();
1976 if (!bmpRollover->IsOk()) {
1978 pttc->bitmap_Rollover_day =
1979 new wxBitmap(style->GetIcon(
"default_pi"));
1982 pttc->bitmap_Rollover_day =
new wxBitmap(*bmpRollover);
1983 pttc->bitmap_Rollover_day->UnShare();
1986 pttc->bitmap_dusk = BuildDimmedToolBitmap(pttc->bitmap_day, 128);
1987 pttc->bitmap_night = BuildDimmedToolBitmap(pttc->bitmap_day, 32);
1989 pParent->SetToolbarItemBitmaps(item, pttc->bitmap_day,
1990 pttc->bitmap_Rollover_day);
1997void PlugInManager::SetToolbarItemBitmaps(
int item, wxString SVGfile,
1998 wxString SVGfileRollover,
1999 wxString SVGfileToggled) {
2000 for (
unsigned int i = 0; i < m_PlugInToolbarTools.GetCount(); i++) {
2003 if (pttc->id == item) {
2004 pttc->pluginNormalIconSVG = SVGfile;
2005 pttc->pluginRolloverIconSVG = SVGfileRollover;
2006 pttc->pluginToggledIconSVG = SVGfileToggled;
2007 pParent->SetToolbarItemSVG(item, pttc->pluginNormalIconSVG,
2008 pttc->pluginRolloverIconSVG,
2009 pttc->pluginToggledIconSVG);
2017 for (
unsigned int i = 0; i < m_PlugInToolbarTools.GetCount(); i++) {
2019 if (
id == pc->id)
return pc->m_pplugin;
2025wxString PlugInManager::GetToolOwnerCommonName(
const int id) {
2028 auto plugin_array = PluginLoader::GetInstance()->
GetPlugInArray();
2029 for (
unsigned int i = 0; i < plugin_array->GetCount(); i++) {
2031 if (pic && (pic->m_pplugin == ppi))
return pic->
m_common_name;
2035 return wxEmptyString;
2038wxString PlugInManager::GetLastError() {
return m_last_error_string; }
2040wxBitmap* PlugInManager::BuildDimmedToolBitmap(wxBitmap* pbmp_normal,
2041 unsigned char dim_ratio) {
2042 wxImage img_dup = pbmp_normal->ConvertToImage();
2044 if (!img_dup.IsOk())
return NULL;
2046 if (dim_ratio < 200) {
2048 int gimg_width = img_dup.GetWidth();
2049 int gimg_height = img_dup.GetHeight();
2051 double factor = (double)(dim_ratio) / 256.0;
2053 for (
int iy = 0; iy < gimg_height; iy++) {
2054 for (
int ix = 0; ix < gimg_width; ix++) {
2055 if (!img_dup.IsTransparent(ix, iy)) {
2056 wxImage::RGBValue rgb(img_dup.GetRed(ix, iy),
2057 img_dup.GetGreen(ix, iy),
2058 img_dup.GetBlue(ix, iy));
2059 wxImage::HSVValue hsv = wxImage::RGBtoHSV(rgb);
2060 hsv.value = hsv.value * factor;
2061 wxImage::RGBValue nrgb = wxImage::HSVtoRGB(hsv);
2062 img_dup.SetRGB(ix, iy, nrgb.red, nrgb.green, nrgb.blue);
2068 wxBitmap* ptoolBarBitmap;
2071 wxBitmap tbmp(img_dup.GetWidth(), img_dup.GetHeight(), -1);
2073 dwxdc.SelectObject(tbmp);
2075 ptoolBarBitmap =
new wxBitmap(img_dup, (wxDC&)dwxdc);
2077 ptoolBarBitmap =
new wxBitmap(img_dup);
2081 return ptoolBarBitmap;
2084wxArrayString PlugInManager::GetPlugInChartClassNameArray() {
2085 wxArrayString array;
2086 auto plugin_array = PluginLoader::GetInstance()->
GetPlugInArray();
2087 for (
unsigned int i = 0; i < plugin_array->GetCount(); i++) {
2089 if (pic && pic->m_enabled && pic->m_init_state &&
2094 for (
unsigned int j = 0; j < carray.GetCount(); j++) {
2095 array.Add(carray[j]);
2103 while (j < array.GetCount()) {
2104 wxString test = array[j];
2105 unsigned int k = j + 1;
2106 while (k < array.GetCount()) {
2107 if (test == array[k]) {
2125#define DISABLED_SETTINGS_MSG \
2126 _("These settings might destabilize OpenCPN and are by default disabled." \
2127 " To despite the dangers enable them manually add a CatalogExpert=1" \
2128 " line in the [PlugIns] section in the configuration file.")
2133CatalogMgrPanel::CatalogMgrPanel(wxWindow* parent)
2134 : wxPanel(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize),
2136 wxBoxSizer* topSizer =
new wxBoxSizer(wxVERTICAL);
2139 topSizer->Add(
new wxStaticLine(
this), 0, wxGROW | wxLEFT | wxRIGHT, 4);
2141 wxStaticBox* itemStaticBoxSizer4Static =
2142 new wxStaticBox(
this, wxID_ANY, _(
"Plugin Catalog"));
2143 wxStaticBoxSizer* itemStaticBoxSizer4 =
2144 new wxStaticBoxSizer(itemStaticBoxSizer4Static, wxVERTICAL);
2145 topSizer->Add(itemStaticBoxSizer4, 1, wxEXPAND | wxALL, 2);
2149 m_catalogText =
new wxStaticText(
this, wxID_STATIC,
"");
2150 itemStaticBoxSizer4->Add(m_catalogText,
2151 wxSizerFlags().Border().Proportion(1));
2152 m_catalogText->SetLabel(GetCatalogText(
false));
2155 wxBoxSizer* rowSizer2 =
new wxBoxSizer(wxHORIZONTAL);
2156 itemStaticBoxSizer4->Add(rowSizer2,
2157 wxSizerFlags().Expand().Border().Proportion(1));
2159 m_updateButton =
new wxButton(
this, wxID_ANY, _(
"Update Plugin Catalog"),
2160 wxDefaultPosition, wxDefaultSize, 0);
2161 rowSizer2->Add(m_updateButton, 0, wxALIGN_LEFT);
2162 m_updateButton->Bind(wxEVT_COMMAND_BUTTON_CLICKED,
2163 &CatalogMgrPanel::OnUpdateButton,
this);
2164 rowSizer2->AddSpacer(4 * GetCharWidth());
2165 m_tarballButton =
new wxButton(
this, wxID_ANY, _(
"Import plugin..."),
2166 wxDefaultPosition, wxDefaultSize, 0);
2167 rowSizer2->Add(m_tarballButton, 0, wxALIGN_LEFT | wxLEFT, 2 * GetCharWidth());
2168 m_tarballButton->Bind(wxEVT_COMMAND_BUTTON_CLICKED,
2169 &CatalogMgrPanel::OnTarballButton,
this);
2171 rowSizer2->AddSpacer(4 * GetCharWidth());
2172 m_adv_button =
new wxButton(
this, wxID_ANY, _(
"Settings..."),
2173 wxDefaultPosition, wxDefaultSize, 0);
2175 if (expert.Get(
false)) {
2176 m_adv_button->Bind(wxEVT_COMMAND_BUTTON_CLICKED,
2177 &CatalogMgrPanel::OnPluginSettingsButton,
this);
2179 m_adv_button->Bind(wxEVT_COMMAND_BUTTON_CLICKED, [&](wxCommandEvent&) {
2180 wxMessageBox(DISABLED_SETTINGS_MSG, _(
"Disabled"));
2183 rowSizer2->AddSpacer(4 * GetCharWidth());
2184 rowSizer2->Add(m_adv_button, 0, wxALIGN_LEFT);
2186 SetUpdateButtonLabel();
2189 wxBoxSizer* rowSizer3 =
new wxBoxSizer(wxHORIZONTAL);
2190 itemStaticBoxSizer4->Add(rowSizer3, 0, wxEXPAND | wxALL, 4);
2192 SetMinSize(wxSize(m_parent->GetClientSize().x - (4 * GetCharWidth()), -1));
2196 wxDEFINE_EVENT(EVT_CATALOG_CHANGE, wxCommandEvent);
2197 catalog_listener.Listen(catalog,
this, EVT_CATALOG_CHANGE);
2198 Bind(EVT_CATALOG_CHANGE, [&](wxCommandEvent&) { SetUpdateButtonLabel(); });
2201 SetBackgroundColour(wxColour(0x7c, 0xb0, 0xe9));
2203 if (!expert.Get(
false)) {
2205 new wxButton(
this, wxID_ANY, _(
"Update Plugin Catalog: master"),
2206 wxDefaultPosition, wxDefaultSize, 0);
2207 itemStaticBoxSizer4->Add(m_updateButton, 0, wxALIGN_LEFT);
2208 m_updateButton->Bind(wxEVT_COMMAND_BUTTON_CLICKED,
2209 &CatalogMgrPanel::OnUpdateButton,
this);
2210 SetUpdateButtonLabel();
2211 m_tarballButton = NULL;
2212 m_adv_button = NULL;
2215 m_catalogText =
new wxStaticText(
this, wxID_STATIC, GetCatalogText(
false));
2216 itemStaticBoxSizer4->Add(m_catalogText,
2217 wxSizerFlags().Border(wxALL, 5).Proportion(1));
2220 m_updateButton =
new wxButton(
2221 this, wxID_ANY,
"Update Plugin Catalog:master ",
2222 wxDefaultPosition, wxDefaultSize, 0);
2223 itemStaticBoxSizer4->Add(m_updateButton, 0, wxALIGN_LEFT | wxTOP, 5);
2224 m_updateButton->Bind(wxEVT_COMMAND_BUTTON_CLICKED,
2225 &CatalogMgrPanel::OnUpdateButton,
this);
2226 SetUpdateButtonLabel();
2229 m_adv_button =
new wxButton(
this, wxID_ANY, _(
"Settings..."),
2230 wxDefaultPosition, wxDefaultSize, 0);
2231 itemStaticBoxSizer4->Add(m_adv_button, 0, wxALIGN_LEFT | wxTOP,
2233 m_adv_button->Bind(wxEVT_COMMAND_BUTTON_CLICKED,
2234 &CatalogMgrPanel::OnPluginSettingsButton,
this);
2237 m_tarballButton =
new wxButton(
this, wxID_ANY, _(
"Import plugin..."),
2238 wxDefaultPosition, wxDefaultSize, 0);
2239 itemStaticBoxSizer4->Add(m_tarballButton, 0, wxALIGN_LEFT | wxALL,
2240 2 * GetCharWidth());
2241 m_tarballButton->Bind(wxEVT_COMMAND_BUTTON_CLICKED,
2242 &CatalogMgrPanel::OnTarballButton,
this);
2248CatalogMgrPanel::~CatalogMgrPanel() {
2249 m_updateButton->Unbind(wxEVT_COMMAND_BUTTON_CLICKED,
2250 &CatalogMgrPanel::OnUpdateButton,
this);
2251 if (m_tarballButton)
2252 m_tarballButton->Unbind(wxEVT_COMMAND_BUTTON_CLICKED,
2253 &CatalogMgrPanel::OnTarballButton,
this);
2256static const char*
const DOWNLOAD_REPO_PROTO =
2257 "https://raw.githubusercontent.com/OpenCPN/plugins/@branch@/"
2260void CatalogMgrPanel::OnUpdateButton(wxCommandEvent& event) {
2262 std::string catalog(g_catalog_channel ==
"" ?
"master" : g_catalog_channel);
2263 std::string url(g_catalog_custom_url);
2264 if (catalog !=
"custom") {
2265 url = std::string(DOWNLOAD_REPO_PROTO);
2269 std::string filePath =
2270 wxFileName::CreateTempFileName(
"ocpn_dl").ToStdString();
2272 auto catalogHdlr = CatalogHandler::GetInstance();
2274 g_Platform->ShowBusySpinner();
2275 auto status = catalogHdlr->DownloadCatalog(filePath, url);
2276 g_Platform->HideBusySpinner();
2278 std::string message;
2279 if (status != CatalogHandler::ServerStatus::OK) {
2280 message = _(
"Cannot download data from url");
2281 OCPNMessageBox(
this, message, _(
"OpenCPN Catalog update"),
2282 wxICON_ERROR | wxOK);
2288 if (!AndroidSecureCopyFile(wxString(filePath.c_str()),
2290 wxFileName::GetPathSeparator() +
2291 "ocpn-plugins.xml")) {
2292 OCPNMessageBox(
this, _(
"Unable to copy catalog file"),
2293 _(
"OpenCPN Catalog update"), wxICON_ERROR | wxOK);
2298 if (!wxCopyFile(wxString(filePath.c_str()),
2300 wxFileName::GetPathSeparator() +
"ocpn-plugins.xml")) {
2301 OCPNMessageBox(
this, _(
"Unable to copy catalog file"),
2302 _(
"OpenCPN Catalog update"), wxICON_ERROR | wxOK);
2308 if (catalog ==
"master") {
2310 OCPNMessageBox(
this, _(
"Unable to copy catalog file to cache"),
2311 _(
"OpenCPN Catalog update"), wxICON_ERROR | wxOK);
2317 pConfig->SetPath(
"/PlugIns/");
2318 pConfig->Write(
"LatestCatalogDownloaded", catalog.c_str());
2325 pluginHandler->setMetadata(
"");
2329 auto cataloghdlr = CatalogHandler::GetInstance();
2330 cataloghdlr->ClearCatalogData();
2333 LoadAllPlugIns(
false);
2337 m_catalogText->SetLabel(GetCatalogText(
true));
2340 OCPNMessageBox(
this, _(
"Catalog update successful"),
2341 _(
"OpenCPN Catalog update"), wxICON_INFORMATION | wxOK);
2344void CatalogMgrPanel::OnPluginSettingsButton(wxCommandEvent& event) {
2348 androidDisableRotation();
2351 dialog->ShowModal();
2354 androidEnableRotation();
2358void CatalogMgrPanel::OnTarballButton(wxCommandEvent& event) {
2361 int response = g_Platform->DoFileSelectorDialog(
2362 this, &path, _(
"Select tarball file"), GetImportInitDir(),
"",
2363 "tar files (*.tar.gz)|*.tar.gz|All Files (*.*)|*.*");
2365 if (response != wxID_OK) {
2370 bool ok = handler->ExtractMetadata(path.ToStdString(), metadata);
2374 _(
"Error extracting metadata from tarball (missing metadata.xml?)"),
2375 _(
"OpenCPN Plugin Import Error"));
2379 OCPNMessageBox(
this, _(
"Incompatible import plugin detected."),
2380 _(
"OpenCPN Plugin Import Error"));
2381 handler->Uninstall(metadata.name);
2384 UninstallPlugin(metadata.name);
2385 ok = handler->InstallPlugin(metadata, path.ToStdString());
2387 OCPNMessageBox(
this, _(
"Error extracting import plugin tarball."),
2388 _(
"OpenCPN Plugin Import Error"));
2391 metadata.is_imported =
true;
2393 std::ofstream file(metadata_path);
2396 WARNING_LOG <<
"Error saving metadata file: " << metadata_path
2397 <<
" for imported plugin: " << metadata.name;
2399 LoadAllPlugIns(
false,
true);
2402 wxString ws(_(
"Plugin"));
2403 ws += metadata.name + _(
" successfully imported");
2404 OCPNMessageBox(gFrame, ws, _(
"Installation complete"),
2405 wxICON_INFORMATION | wxOK | wxCENTRE);
2408wxString CatalogMgrPanel::GetCatalogText(
bool updated) {
2410 catalog = updated ? _(
"Active Catalog") : _(
"Last Catalog");
2414 pConfig->SetPath(
"/PlugIns/");
2415 wxString latestCatalog = pConfig->Read(
"LatestCatalogDownloaded",
"default");
2416 catalog += latestCatalog;
2422 std::string date = pluginHandler->GetCatalogData()->date;
2424 catalog += wxString(
" ") + _(
"Last change: ") +
" " + date;
2425 if (!updated) catalog +=
" : " + _(
"Please Update Plugin Catalog.");
2431void CatalogMgrPanel::SetUpdateButtonLabel() {
2432 wxString label = _(
"Update Plugin Catalog");
2434 label += g_catalog_channel ==
"" ?
"master" : g_catalog_channel;
2435 m_updateButton->SetLabel(label);
2439wxString CatalogMgrPanel::GetImportInitDir() {
2441 pConfig->SetPath(
"/PlugIns/");
2442 wxString lastImportDir;
2444 pConfig->Read(
"LatestImportDir", g_Platform->GetWritableDocumentsDir());
2445 if (wxDirExists(lastImportDir)) {
2446 return lastImportDir;
2448 return (g_Platform->GetWritableDocumentsDir());
2457 const wxPoint& pos, const wxSize& size)
2458 : wxScrolledWindow(parent,
id, pos, size, wxTAB_TRAVERSAL | wxVSCROLL),
2459 m_PluginSelected(0) {
2460 m_is_loading.clear();
2461 SetSizer(
new wxBoxSizer(wxVERTICAL));
2462 ReloadPluginPanels();
2465void PluginListPanel::SelectByName(wxString& name) {
2466 for (
auto it = GetChildren().GetFirst(); it; it = it->GetNext()) {
2467 auto pluginPanel =
dynamic_cast<PluginPanel*
>(it->GetData());
2469 if (pluginPanel->GetPluginPtr()->m_common_name.IsSameAs(name)) {
2470 pluginPanel->SetSelected(
true);
2471 pluginPanel->Layout();
2472 SelectPlugin(pluginPanel);
2481 std::vector<const PlugInData*> result;
2482 auto loader = PluginLoader::GetInstance();
2483 for (
size_t i = 0; i < loader->GetPlugInArray()->GetCount(); i++) {
2484 auto const item = loader->GetPlugInArray()->Item(i);
2485 if (item->m_managed_metadata.name.empty()) {
2486 const auto name = item->m_common_name.ToStdString();
2490 result.push_back(item);
2493 std::string slhs, srhs;
2494 for (
auto& cl : lhs->
Key()) slhs += toupper(cl);
2495 for (
auto& cr : rhs->Key()) srhs += toupper(cr);
2496 return slhs.compare(srhs) < 0;
2498 std::sort(result.begin(), result.end(), compare);
2503static bool IsPluginLoaded(
const std::string& name) {
2504 if (safe_mode::get_mode()) {
2507 std::find(installed.begin(), installed.end(),
ocpn::tolower(name));
2508 return found != installed.end();
2511 for (
size_t i = 0; i < loaded->GetCount(); i++) {
2512 if (loaded->Item(i)->m_common_name.ToStdString() == name)
return true;
2519 if (m_is_loading.test_and_set()) {
2521 DEBUG_LOG <<
"LoadAllPlugins: recursive invocation";
2526 m_PluginItems.Clear();
2528 wxWindowList kids = GetChildren();
2529 for (
unsigned int i = 0; i < kids.GetCount(); i++) {
2530 wxWindowListNode* node = kids.Item(i);
2531 wxWindow* win = node->GetData();
2533 if (pp) win->Destroy();
2535 GetSizer()->Clear();
2538 m_PluginSelected = 0;
2540 if (safe_mode::get_mode()) {
2543 for (
const auto& name : installed) AddPlugin(name);
2546 auto available = getCompatiblePlugins();
2550 return IsPluginLoaded(md.name);
2552 auto end = std::remove_if(available.begin(), available.end(), predicate);
2553 available.erase(end, available.end());
2559 std::string slhs, srhs;
2560 for (
auto& cl : lhs.name) slhs += toupper(cl);
2561 for (
auto& cr : rhs.name) srhs += toupper(cr);
2562 return slhs.compare(srhs) < 0;
2566 std::set<PluginMetadata, CompSort> unique_sorted_entries(comp_sort);
2567 for (
const auto& p : available) unique_sorted_entries.insert(p);
2573 if (p->m_enabled) AddPlugin(*p);
2577 if (!p->m_enabled) AddPlugin(*p);
2580 for (
const auto& p : unique_sorted_entries) AddPlugin(
PlugInData(p));
2588 m_is_loading.clear();
2591void PluginListPanel::AddPlugin(
const std::string& name) {
2594 panel->SetSelected(
false);
2595 GetSizer()->Add(panel, 0, wxEXPAND);
2596 m_PluginItems.Add(panel);
2597 m_pluginSpacer = g_Platform->GetDisplayDPmm() * 1.0;
2598 GetSizer()->AddSpacer(m_pluginSpacer);
2601void PluginListPanel::AddPlugin(
const PlugInData& pic) {
2603 new PluginPanel(
this, wxID_ANY, wxDefaultPosition, wxDefaultSize, pic);
2604 pPluginPanel->SetSelected(
false);
2605 GetSizer()->Add(pPluginPanel, 0, wxEXPAND);
2606 m_PluginItems.Add(pPluginPanel);
2608 m_pluginSpacer = g_Platform->GetDisplayDPmm() * 1.0;
2609 GetSizer()->AddSpacer(m_pluginSpacer);
2622int PluginListPanel::ComputePluginSpace(ArrayOfPluginPanel plugins,
2623 wxBoxSizer* sizer) {
2625 for (
size_t i = 0; i < plugins.GetCount(); i++) {
2626 auto panel = plugins.Item(i);
2627 bool was_selected = panel->GetSelected();
2628 panel->SetSelected(
false);
2630 wxSize unselected = panel->GetSize();
2632 panel->SetSelected(
true);
2634 wxSize selected = panel->GetSize();
2636 int dy = selected.GetHeight() - unselected.GetHeight();
2637 max_dy = wxMax(max_dy, dy);
2638 panel->SetSelected(was_selected);
2643PluginListPanel::~PluginListPanel() {}
2645void PluginListPanel::UpdateSelections() {
2646 for (
unsigned int i = 0; i < m_PluginItems.GetCount(); i++) {
2649 pPluginPanel->SetSelected(pPluginPanel->GetSelected());
2654void PluginListPanel::SelectPlugin(
PluginPanel* pi) {
2656 GetViewStart(&xs, &ys);
2659 if (m_PluginSelected) {
2660 m_PluginSelected->SetSelected(
false);
2661 m_PluginSelected->Layout();
2664 if (pi == NULL) m_PluginSelected->SetSelected(
false);
2666 m_PluginSelected = pi;
2668 GetSizer()->Layout();
2670 wxSize size = GetBestVirtualSize();
2671 SetVirtualSize(size);
2676 for (
unsigned int i = 0; i < m_PluginItems.GetCount(); i++) {
2678 int yd = pPluginPanel->GetSize().y;
2680 htop += m_pluginSpacer;
2681 if (pPluginPanel == pi) {
2682 int piBottom = htop - (ys *
g_options->GetScrollRate());
2683 if (piBottom > GetClientSize().y) {
2684 ys += (piBottom - GetClientSize().y) /
g_options->GetScrollRate();
2694 int pos = m_PluginItems.Index(pi);
2697 m_PluginItems.RemoveAt(pos);
2700 m_PluginItems.Insert(pi, pos - 1);
2701 wxStaticLine* itemStaticLine =
new wxStaticLine(
2702 this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL);
2707 m_PluginSelected = pi;
2709 GetSizer()->Layout();
2715 int pos = m_PluginItems.Index(pi);
2716 if (pos == (
int)m_PluginItems.Count() -
2719 m_PluginItems.RemoveAt(pos);
2722 m_PluginItems.Insert(pi, pos + 1);
2723 wxStaticLine* itemStaticLine =
new wxStaticLine(
2724 this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL);
2729 m_PluginSelected = pi;
2731 GetSizer()->Layout();
2736static bool canUninstall(std::string name) {
2741 if (plugin.name == name) {
2742 if (safe_mode::get_mode())
2745 return !plugin.readonly;
2752 : wxPanel(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize,
2754 m_is_safe_panel(true) {
2756 wxASSERT(m_PluginListPanel != 0);
2757 wxBoxSizer* top_sizer =
new wxBoxSizer(wxVERTICAL);
2758 SetSizer(top_sizer);
2759 wxBoxSizer* top_horizontal =
new wxBoxSizer(wxHORIZONTAL);
2760 top_sizer->Add(top_horizontal, 0, wxEXPAND);
2762 double iconSize = GetCharWidth() * 4;
2764 int icon_scale = iconSize * dpi_mult;
2766 wxBitmap bitmap(style->GetIcon(
"default_pi", icon_scale, icon_scale));
2767 m_itemStaticBitmap =
new wxStaticBitmap(
this, wxID_ANY, bitmap);
2768 top_horizontal->Add(m_itemStaticBitmap, 0, wxEXPAND | wxALL, 10);
2770 m_pName =
new wxStaticText(
this, wxID_ANY, name);
2771 top_horizontal->Add(m_pName, wxID_ANY, wxALIGN_CENTER_VERTICAL);
2772 m_pVersion =
new wxStaticText(
this, wxID_ANY,
"");
2773 top_horizontal->Add(m_pVersion);
2776 m_pButtons =
new wxBoxSizer(wxHORIZONTAL);
2777 top_horizontal->Add(m_pButtons);
2778 m_info_btn =
new WebsiteButton(
this,
"https:\\opencpn.org");
2779 top_horizontal->Add(m_info_btn);
2780 m_pButtonUninstall =
new wxButton(
this, wxID_ANY, _(
"Uninstall"),
2781 wxDefaultPosition, wxDefaultSize, 0);
2782 top_horizontal->Add(m_pButtonUninstall, 0, wxALIGN_CENTER_VERTICAL | wxALL,
2784 auto uninstall = [&](wxCommandEvent ev) {
2785 auto n = m_pName->GetLabel().ToStdString();
2787 OCPNMessageBox(gFrame, std::string(_(
"Uninstall plugin ")) + n +
"?",
2788 _(
"Un-Installation"), wxICON_QUESTION | wxOK | wxCANCEL);
2789 if (result != wxID_OK)
return;
2793 m_pButtonUninstall->Bind(wxEVT_COMMAND_BUTTON_CLICKED, uninstall);
2797EVT_PAINT(PluginPanel::OnPaint)
2802 : wxPanel(parent,
id, pos, size, wxBORDER_NONE),
2804 m_is_safe_panel(false) {
2807 wxASSERT(m_PluginListPanel != 0);
2809 m_bSelected =
false;
2810 m_penWidthUnselected = g_Platform->GetDisplayDPmm() * .25;
2811 m_penWidthSelected = g_Platform->GetDisplayDPmm() * .5;
2813 wxBoxSizer* topSizer =
new wxBoxSizer(wxVERTICAL);
2816 wxBoxSizer* itemBoxSizer01 =
new wxBoxSizer(wxHORIZONTAL);
2817 topSizer->Add(itemBoxSizer01, 0, wxEXPAND);
2818 Bind(wxEVT_LEFT_DOWN, &PluginPanel::OnPluginSelected,
this);
2819 Bind(wxEVT_LEFT_UP, &PluginPanel::OnPluginSelectedUp,
this);
2821 double iconSize = GetCharWidth() * 4;
2823 int icon_scale = iconSize * dpi_mult;
2825 wxImage plugin_icon;
2827 if (m_plugin.m_bitmap.IsOk()) {
2828 plugin_icon = m_plugin.m_bitmap.ConvertToImage();
2831 if (m_plugin.m_status == PluginStatus::ManagedInstallAvailable) {
2832 wxFileName path(g_Platform->GetSharedDataDir(),
"packageBox.svg");
2833 path.AppendDir(
"uidata");
2834 path.AppendDir(
"traditional");
2835 bitmap =
LoadSVG(path.GetFullPath(), icon_scale, icon_scale);
2836 }
else if (plugin_icon.IsOk()) {
2837 int nowSize = plugin_icon.GetWidth();
2838 plugin_icon.Rescale(icon_scale, icon_scale, wxIMAGE_QUALITY_HIGH);
2839 bitmap = wxBitmap(plugin_icon);
2841 bitmap = wxBitmap(style->GetIcon(
"default_pi", icon_scale, icon_scale));
2843 m_itemStaticBitmap =
new wxStaticBitmap(
this, wxID_ANY, bitmap);
2845 itemBoxSizer01->Add(m_itemStaticBitmap, 0, wxEXPAND | wxALL, 10);
2846 m_itemStaticBitmap->Bind(wxEVT_LEFT_DOWN, &PluginPanel::OnPluginSelected,
2848 m_itemStaticBitmap->Bind(wxEVT_LEFT_UP, &PluginPanel::OnPluginSelectedUp,
2851 wxBoxSizer* itemBoxSizer02 =
new wxBoxSizer(wxVERTICAL);
2852 itemBoxSizer01->Add(itemBoxSizer02, 1, wxEXPAND | wxALL, 0);
2855 int nChars =
g_options->GetSize().x / GetCharWidth();
2856 bool bCompact =
false;
2862 wxString nameString = m_plugin.m_common_name;
2866 dc.GetTextExtent(m_plugin.m_common_name, &nameWidth, NULL);
2867 if (nameWidth > maxWidth) {
2868 nameString = wxControl::Ellipsize(m_plugin.m_common_name, dc,
2869 wxELLIPSIZE_END, maxWidth);
2871 m_pName =
new wxStaticText(
this, wxID_ANY, nameString);
2872 m_pName->Bind(wxEVT_LEFT_DOWN, &PluginPanel::OnPluginSelected,
this);
2873 m_pName->Bind(wxEVT_LEFT_UP, &PluginPanel::OnPluginSelectedUp,
this);
2874 itemBoxSizer02->Add(m_pName, 0, wxALL, 5);
2876 wxFlexGridSizer* sl1 =
new wxFlexGridSizer(2, 0, 0);
2877 sl1->AddGrowableCol(1);
2878 itemBoxSizer02->Add(sl1, 0, wxEXPAND);
2880 m_pVersion =
new wxStaticText(
this, wxID_ANY,
"X.YY.ZZ.AA");
2881 sl1->Add(m_pVersion, 0, wxALL, 5);
2882 if (m_plugin.m_status == PluginStatus::ManagedInstallAvailable) {
2885 m_pVersion->Bind(wxEVT_LEFT_DOWN, &PluginPanel::OnPluginSelected,
this);
2886 m_pVersion->Bind(wxEVT_LEFT_UP, &PluginPanel::OnPluginSelectedUp,
this);
2888 m_cbEnable =
new wxCheckBox(
this, wxID_ANY, _(
"Enabled"));
2889 sl1->Add(m_cbEnable, 1, wxALIGN_RIGHT | wxTOP, 5);
2890 m_cbEnable->Bind(wxEVT_CHECKBOX, &PluginPanel::OnPluginEnableToggle,
this);
2893 wxString descriptionString = m_plugin.m_short_description;
2894 int maxDescriptionWidth = g_Platform->
getDisplaySize().x - (iconSize * 4);
2895 int descriptionWidth;
2896 dc.GetTextExtent(m_plugin.m_short_description, &descriptionWidth, NULL);
2897 if (descriptionWidth > maxDescriptionWidth)
2899 wxControl::Ellipsize(m_plugin.m_short_description, dc,
2900 wxELLIPSIZE_END, maxDescriptionWidth);
2905 new wxStaticText(
this, wxID_ANY, descriptionString, wxDefaultPosition,
2906 wxSize(maxDescriptionWidth, -1), wxST_NO_AUTORESIZE);
2907 itemBoxSizer02->Add(m_pDescription, 0, wxEXPAND | wxALL, 5);
2908 m_pDescription->Bind(wxEVT_LEFT_DOWN, &PluginPanel::OnPluginSelected,
this);
2909 m_pDescription->Bind(wxEVT_LEFT_UP, &PluginPanel::OnPluginSelectedUp,
this);
2912 wxFlexGridSizer* itemBoxSizer03 =
new wxFlexGridSizer(4, 0, 0);
2913 itemBoxSizer03->AddGrowableCol(2);
2914 itemBoxSizer02->Add(itemBoxSizer03, 0, wxEXPAND);
2916 wxString nameString = m_plugin.m_common_name;
2917 m_pName =
new wxStaticText(
this, wxID_ANY, nameString);
2918 m_pName->Bind(wxEVT_LEFT_DOWN, &PluginPanel::OnPluginSelected,
this);
2919 m_pName->Bind(wxEVT_LEFT_UP, &PluginPanel::OnPluginSelectedUp,
this);
2923 wxFont font = GetFont();
2924 font.SetWeight(wxFONTWEIGHT_BOLD);
2925 m_pName->SetFont(font);
2928 itemBoxSizer03->Add(m_pName, 0, wxALL, 10);
2930 m_pVersion =
new wxStaticText(
this, wxID_ANY,
"X.YY.ZZ.AA");
2931 itemBoxSizer03->Add(m_pVersion, 0, wxALL, 10);
2932 if (m_plugin.m_status == PluginStatus::ManagedInstallAvailable ||
2935 !m_plugin.m_managed_metadata.is_orphan)) {
2938 m_pVersion->Bind(wxEVT_LEFT_DOWN, &PluginPanel::OnPluginSelected,
this);
2939 m_pVersion->Bind(wxEVT_LEFT_UP, &PluginPanel::OnPluginSelectedUp,
this);
2941 m_cbEnable =
new wxCheckBox(
this, wxID_ANY, _(
"Enabled"));
2942 itemBoxSizer03->Add(m_cbEnable, 1, wxALIGN_RIGHT | wxTOP, 10);
2943 m_cbEnable->Bind(wxEVT_CHECKBOX, &PluginPanel::OnPluginEnableToggle,
this);
2945 itemBoxSizer03->Add(5 * GetCharWidth(), 1, 0, wxALIGN_RIGHT | wxTOP, 10);
2947 m_pDescription =
new wxStaticText(
2948 this, wxID_ANY, m_plugin.m_short_description, wxDefaultPosition,
2950 itemBoxSizer02->Add(m_pDescription, 1, wxEXPAND | wxALL, 5);
2951 m_pDescription->Bind(wxEVT_LEFT_DOWN, &PluginPanel::OnPluginSelected,
this);
2952 m_pDescription->Bind(wxEVT_LEFT_UP, &PluginPanel::OnPluginSelectedUp,
this);
2956 m_info_btn =
new WebsiteButton(
this,
"https:\\opencpn.org");
2958 itemBoxSizer02->Add(m_info_btn, 0);
2960 m_pButtons =
new wxBoxSizer(wxHORIZONTAL);
2961 itemBoxSizer02->Add(m_pButtons, 0, wxALL, 0);
2962 m_pButtonPreferences =
new wxButton(
this, wxID_ANY, _(
"Preferences"),
2963 wxDefaultPosition, wxDefaultSize, 0);
2964 m_pButtons->Add(m_pButtonPreferences, 0, wxALIGN_LEFT | wxALL, 2);
2966 m_pButtons->AddSpacer(3 * GetCharWidth());
2969 new wxButton(
this, wxID_ANY,
"Upgrade to Version XX.XX.XX",
2970 wxDefaultPosition, wxDefaultSize, 0);
2971 m_pButtons->Add(m_pButtonAction, 0, wxALIGN_LEFT | wxALL, 2);
2973 m_pButtonUninstall =
new wxButton(
this, wxID_ANY, _(
"Uninstall"),
2974 wxDefaultPosition, wxDefaultSize, 0);
2975 m_pButtons->Add(m_pButtonUninstall, 0, wxALIGN_LEFT | wxALL, 2);
2977 m_pButtons =
new wxBoxSizer(wxVERTICAL);
2978 itemBoxSizer02->Add(m_pButtons, 0, wxALL, 0);
2980 wxBoxSizer* tline =
new wxBoxSizer(wxHORIZONTAL);
2981 m_pButtons->Add(tline, 0, wxALL, 2);
2983 m_pButtonPreferences =
new wxButton(
this, wxID_ANY, _(
"Preferences"),
2984 wxDefaultPosition, wxDefaultSize, 0);
2985 tline->Add(m_pButtonPreferences, 0, wxALIGN_LEFT | wxALL, 0);
2987 tline->AddSpacer(3 * GetCharWidth());
2989 m_info_btn =
new WebsiteButton(
this,
"https:\\opencpn.org");
2991 tline->Add(m_info_btn, 0);
2994 new wxButton(
this, wxID_ANY,
"Upgrade to Version XX.XX.XX",
2995 wxDefaultPosition, wxDefaultSize);
2996 m_pButtons->Add(m_pButtonAction, 0, wxALIGN_LEFT | wxALL, 2);
2998 m_pButtonUninstall =
new wxButton(
this, wxID_ANY, _(
"Uninstall"),
2999 wxDefaultPosition, wxDefaultSize, 0);
3000 m_pButtons->Add(m_pButtonUninstall, 0, wxALIGN_LEFT | wxALL, 2);
3003 wxBitmap statusBitmap;
3004 const auto stat = m_plugin.m_status;
3005 auto icon_name = icon_by_status.at(stat);
3006 if (stat == PluginStatus::Imported &&
3007 IsUpdateAvailable(m_plugin.m_managed_metadata)) {
3009 icon_by_status.at(PluginStatus::ManagedInstalledUpdateAvailable);
3012 wxFileName path(g_Platform->GetSharedDataDir(), icon_name);
3013 path.AppendDir(
"uidata");
3014 path.AppendDir(
"traditional");
3016 int bmsize = GetCharWidth() * 3 * dpi_mult;
3017 if (path.IsFileReadable()) {
3018 statusBitmap =
LoadSVG(path.GetFullPath(), bmsize, bmsize);
3019 ok = statusBitmap.IsOk();
3022 auto style = g_StyleManager->GetCurrentStyle();
3023 statusBitmap = wxBitmap(style->GetIcon(
"default_pi", bmsize, bmsize));
3024 wxLogMessage(
"Icon: %s not found.", path.GetFullPath());
3027 m_itemStatusIconBitmap =
new wxStaticBitmap(
this, wxID_ANY, statusBitmap);
3028 m_itemStatusIconBitmap->SetToolTip(message_by_status(stat));
3029 m_itemStatusIconBitmap->Bind(wxEVT_LEFT_DOWN, &PluginPanel::OnPluginSelected,
3031 m_itemStatusIconBitmap->Bind(wxEVT_LEFT_UP, &PluginPanel::OnPluginSelectedUp,
3034 itemBoxSizer01->Add(m_itemStatusIconBitmap, 0, wxEXPAND | wxALL, 20);
3036 itemBoxSizer02->AddSpacer(GetCharWidth());
3038 m_pButtonPreferences->Bind(wxEVT_COMMAND_BUTTON_CLICKED,
3039 &PluginPanel::OnPluginPreferences,
this);
3040 m_pButtonUninstall->Bind(wxEVT_COMMAND_BUTTON_CLICKED,
3041 &PluginPanel::OnPluginUninstall,
this);
3042 m_pButtonAction->Bind(wxEVT_COMMAND_BUTTON_CLICKED,
3043 &PluginPanel::OnPluginAction,
this);
3045 SetSelected(m_bSelected);
3046 SetAutoLayout(
true);
3054PluginPanel::~PluginPanel() {
3055 Unbind(wxEVT_LEFT_DOWN, &PluginPanel::OnPluginSelected,
this);
3056 if (m_is_safe_panel)
return;
3057 m_itemStaticBitmap->Unbind(wxEVT_LEFT_DOWN, &PluginPanel::OnPluginSelected,
3059 m_pName->Unbind(wxEVT_LEFT_DOWN, &PluginPanel::OnPluginSelected,
this);
3060 m_pVersion->Unbind(wxEVT_LEFT_DOWN, &PluginPanel::OnPluginSelected,
this);
3061 m_pDescription->Unbind(wxEVT_LEFT_DOWN, &PluginPanel::OnPluginSelected,
this);
3062 if (m_pButtonAction) {
3063 m_pButtonAction->Unbind(wxEVT_COMMAND_BUTTON_CLICKED,
3064 &PluginPanel::OnPluginAction,
this);
3066 m_pButtonPreferences->Unbind(wxEVT_COMMAND_BUTTON_CLICKED,
3067 &PluginPanel::OnPluginPreferences,
this);
3068 m_cbEnable->Unbind(wxEVT_COMMAND_BUTTON_CLICKED,
3069 &PluginPanel::OnPluginEnableToggle,
this);
3072void PluginPanel::SetActionLabel(wxString& label) {
3073 m_pButtonAction->SetLabel(label);
3077static wxStopWatch swclick;
3078static int downx, downy;
3080void PluginPanel::OnPluginSelected(wxMouseEvent& event) {
3083 event.GetPosition(&downx, &downy);
3089void PluginPanel::OnPluginSelectedUp(wxMouseEvent& event) {
3091 qDebug() << swclick.Time();
3092 if (swclick.Time() < 200) {
3094 event.GetPosition(&upx, &upy);
3095 if ((fabs(upx - downx) < GetCharWidth()) &&
3096 (fabs(upy - downy) < GetCharWidth())) {
3104void PluginPanel::DoPluginSelect() {
3105 if (m_plugin.m_status == PluginStatus::ManagedInstallAvailable) {
3111 run_update_dialog(m_PluginListPanel, &m_plugin,
false, 0,
true);
3112 }
else if (m_bSelected) {
3114 m_PluginListPanel->SelectPlugin(NULL);
3117 m_PluginListPanel->SelectPlugin(
this);
3125static PluginMetadata GetMetadataByName(
const std::string& name) {
3127 auto predicate = [name](
const PluginMetadata& pm) {
return pm.name == name; };
3128 auto found = std::find_if(plugins.begin(), plugins.end(), predicate);
3129 if (found == plugins.end()) {
3130 wxLogDebug(
"Cannot find metadata for %s", name.c_str());
3135void PluginPanel::SetSelected(
bool selected) {
3136 m_bSelected = selected;
3138 m_pVersion->SetLabel(
3142 m_pButtons->Show(
true);
3143 bool unInstallPossible = canUninstall(m_plugin.
m_common_name.ToStdString());
3146 if (m_plugin.m_status == PluginStatus::LegacyUpdateAvailable ||
3149 unInstallPossible =
false;
3152 if (m_plugin.m_managed_metadata.is_orphan) unInstallPossible =
true;
3154 m_pButtonUninstall->Show(unInstallPossible);
3156 if (m_plugin.m_managed_metadata.info_url.size()) {
3157 m_info_btn->SetURL(m_plugin.m_managed_metadata.info_url.c_str());
3161 m_cbEnable->Show(
true);
3166 switch (m_plugin.m_status) {
3167 case PluginStatus::LegacyUpdateAvailable:
3168 label = _(
"Upgrade to Version ");
3169 label += wxString(m_plugin.m_managed_metadata.version.c_str());
3170 m_action = ActionVerb::UPGRADE_TO_MANAGED_VERSION;
3171 m_pButtonAction->Enable();
3174 case PluginStatus::ManagedInstallAvailable:
3175 label = _(
"Install...");
3176 m_action = ActionVerb::INSTALL_MANAGED_VERSION;
3177 m_pButtonAction->Enable();
3180 case PluginStatus::ManagedInstalledUpdateAvailable:
3181 label = _(
"Update to ");
3182 label += wxString(m_plugin.m_managed_metadata.version.c_str());
3183 m_action = ActionVerb::UPGRADE_INSTALLED_MANAGED_VERSION;
3184 m_pButtonAction->Enable();
3187 case PluginStatus::ManagedInstalledCurrentVersion:
3188 label = _(
"Reinstall");
3189 m_action = ActionVerb::REINSTALL_MANAGED_VERSION;
3190 m_pButtonAction->Enable();
3193 case PluginStatus::ManagedInstalledDowngradeAvailable:
3194 label = _(
"Downgrade");
3195 m_action = ActionVerb::DOWNGRADE_INSTALLED_MANAGED_VERSION;
3196 m_pButtonAction->Enable();
3199 case PluginStatus::Imported:
3200 if (IsUpdateAvailable(m_plugin.m_managed_metadata)) {
3201 label = _(
"Update");
3202 m_action = ActionVerb::UPDATE_IMPORTED_VERSION;
3204 m_pButtonAction->Hide();
3205 m_action = ActionVerb::NOP;
3210 m_action = ActionVerb::NOP;
3211 m_pButtonAction->Hide();
3215 m_action = ActionVerb::NOP;
3216 m_pButtonAction->Hide();
3221 m_action = ActionVerb::NOP;
3224 SetActionLabel(label);
3236 m_pButtons->Show(
false);
3239 if (m_plugin.m_status == PluginStatus::ManagedInstallAvailable)
3240 m_cbEnable->Show(
false);
3261 SetEnabled(m_plugin.m_enabled);
3276void PluginPanel::OnPaint(wxPaintEvent& event) {
3279 int penWidth = m_penWidthUnselected;
3284 penWidth = m_penWidthSelected;
3289 wxBrush b(color, wxBRUSHSTYLE_SOLID);
3291 dc.SetPen(wxPen(border, penWidth));
3293 dc.DrawRoundedRectangle(5, 5, GetSize().x - 10, GetSize().y - 10, 5);
3296void PluginPanel::OnPluginPreferences(wxCommandEvent& event) {
3297 if (m_plugin.m_enabled && m_plugin.m_init_state &&
3300 androidDisableRotation();
3311void PluginPanel::OnPluginEnableToggle(wxCommandEvent& event) {
3312 g_Platform->ShowBusySpinner();
3313 SetEnabled(event.IsChecked());
3314 m_pVersion->SetLabel(
3321 g_Platform->HideBusySpinner();
3324void PluginPanel::OnPluginUninstall(wxCommandEvent& event) {
3325 m_action = ActionVerb::UNINSTALL_MANAGED_VERSION;
3328 wxCommandEvent actionEvent(wxEVT_COMMAND_BUTTON_CLICKED);
3329 actionEvent.SetId(ID_CMD_BUTTON_PERFORM_ACTION);
3330 actionEvent.SetClientData(
this);
3331 g_pi_manager->GetUtilHandler()->AddPendingEvent(actionEvent);
3334void PluginPanel::OnPluginAction(wxCommandEvent& event) {
3336 wxCommandEvent actionEvent(wxEVT_COMMAND_BUTTON_CLICKED);
3337 actionEvent.SetId(ID_CMD_BUTTON_PERFORM_ACTION);
3338 actionEvent.SetClientData(
this);
3339 g_pi_manager->GetUtilHandler()->AddPendingEvent(actionEvent);
3344static void SetWindowFontStyle(wxWindow* window, wxFontStyle style) {
3345 auto font = window->GetFont();
3346 font.SetStyle(style);
3347 window->SetFont(font);
3350void PluginPanel::SetEnabled(
bool enabled) {
3351 if (m_is_safe_panel)
return;
3354 if (enabled) NotifySetupOptionsPlugin(&m_plugin);
3355 if (!enabled && !m_bSelected) {
3356 SetWindowFontStyle(m_pName, wxFONTSTYLE_ITALIC);
3357 SetWindowFontStyle(m_pVersion, wxFONTSTYLE_ITALIC);
3358 SetWindowFontStyle(m_pDescription, wxFONTSTYLE_ITALIC);
3361 m_pVersion->Disable();
3362 m_pDescription->Disable();
3365 SetWindowFontStyle(m_pName, wxFONTSTYLE_NORMAL);
3366 SetWindowFontStyle(m_pVersion, wxFONTSTYLE_NORMAL);
3367 SetWindowFontStyle(m_pDescription, wxFONTSTYLE_NORMAL);
3370 m_pVersion->Enable();
3371 m_pDescription->Enable();
3376 m_pName->Enable(enabled || m_bSelected);
3377 m_pVersion->Enable(enabled || m_bSelected);
3378 m_pDescription->Enable(enabled || m_bSelected);
3382 wxString description = m_plugin.m_long_description;
3383 if (description.IsEmpty())
3384 description = wxString(m_plugin.m_managed_metadata.description.c_str());
3388 m_pDescription->SetLabel(wrapper.GetWrapped());
3389 if (m_plugin.m_managed_metadata.info_url.size()) {
3390 m_info_btn->SetURL(m_plugin.m_managed_metadata.info_url.c_str());
3394 wxString description = m_plugin.m_short_description;
3395 if (description.IsEmpty())
3396 description = wxString(m_plugin.m_managed_metadata.summary.c_str());
3399 m_pDescription->SetLabel(wrapper.GetWrapped());
3402 m_pButtonPreferences->Enable(enabled &&
3404 m_cbEnable->SetValue(enabled);
3407void PluginPanel::OnPluginUp(wxCommandEvent& event) {
3408 m_PluginListPanel->MoveUp(
this);
3411void PluginPanel::OnPluginDown(wxCommandEvent& event) {
3412 m_PluginListPanel->MoveDown(
this);
3417 : wxPanel(parent), m_url(url) {
3418 auto vbox =
new wxBoxSizer(wxVERTICAL);
3419 auto button =
new wxButton(
this, wxID_ANY, _(
"Website"));
3420 button->Enable(strlen(url) > 0);
3423 Bind(wxEVT_COMMAND_BUTTON_CLICKED,
3424 [=](wxCommandEvent&) { wxLaunchDefaultBrowser(m_url); });
3432PlugInChartBase::PlugInChartBase() { m_Chart_Error_Factor = 0.; }
3434PlugInChartBase::~PlugInChartBase() {}
3443 bool b_allow_overzoom) {
3455 const wxRegion& Region) {
3456 return wxNullBitmap;
3465 wxRegion* pValidRegion) {}
3478 wxRect* pSourceRect) {}
3495 double* plat,
double* plon) {}
3502PlugInChartBaseGL::PlugInChartBaseGL() {}
3504PlugInChartBaseGL::~PlugInChartBaseGL() {}
3508 const wxRegion& Region,
3509 bool b_use_stencil) {
3535PlugInChartBaseExtended::PlugInChartBaseExtended() {}
3537PlugInChartBaseExtended::~PlugInChartBaseExtended() {}
3541 const wxRegion& Region,
3542 bool b_use_stencil) {
3548 const wxRegion& Region,
bool b_use_stencil) {
3554 const wxRegion& Region,
bool b_use_stencil) {
3560 return wxNullBitmap;
3564 wxMemoryDC& dc,
const PlugIn_ViewPort& VPoint,
const wxRegion& Region) {
3568ListOfPI_S57Obj* PlugInChartBaseExtended::GetObjRuleListAtLatLon(
3573wxString PlugInChartBaseExtended::CreateObjDescriptions(
3574 ListOfPI_S57Obj* obj_list) {
3578int PlugInChartBaseExtended::GetNoCOVREntries() {
return 0; }
3580int PlugInChartBaseExtended::GetNoCOVRTablePoints(
int iTable) {
return 0; }
3582int PlugInChartBaseExtended::GetNoCOVRTablenPoints(
int iTable) {
return 0; }
3584float* PlugInChartBaseExtended::GetNoCOVRTableHead(
int iTable) {
return 0; }
3593PlugInChartBaseExtendedPlus2::PlugInChartBaseExtendedPlus2() {}
3595PlugInChartBaseExtendedPlus2::~PlugInChartBaseExtendedPlus2() {}
3598PlugInChartBaseExtendedPlus2::GetLightsObjRuleListVisibleAtLatLon(
3608PlugInChartBaseGLPlus2::PlugInChartBaseGLPlus2() {}
3610PlugInChartBaseGLPlus2::~PlugInChartBaseGLPlus2() {}
3622ChartPlugInWrapper::ChartPlugInWrapper() {}
3624ChartPlugInWrapper::ChartPlugInWrapper(
const wxString& chart_class) {
3625 m_ppo = ::wxCreateDynamicObject(chart_class);
3629ChartPlugInWrapper::~ChartPlugInWrapper() {
3630 if (m_ppicb)
delete m_ppicb;
3633wxString ChartPlugInWrapper::GetFileSearchMask() {
3640InitReturn ChartPlugInWrapper::Init(
const wxString& name,
3641 ChartInitFlag init_flags) {
3643 wxWindow* pa = wxWindow::FindFocus();
3645 InitReturn ret_val = (InitReturn)m_ppicb->
Init(name, (
int)init_flags);
3649 if (ret_val == INIT_OK) {
3656 m_ID = m_ppicb->
GetID();
3660 m_SE = m_ppicb->
GetSE();
3674 if ((fabs(m_Chart_Skew) < .01) &&
3675 (CHART_FAMILY_RASTER == m_ChartFamily)) {
3677 if (GetChartExtent(&extent)) {
3678 double lon_range = extent.ELON - extent.WLON;
3679 if ((lon_range > 0) &&
3681 m_ppm_avg = GetSize_X() / (lon_range * 1852 * 60);
3685 m_overlayENC =
false;
3687 wxCharBuffer buf = m_FullPath.ToUTF8();
3688 m_overlayENC = s57chart::IsCellOverlayType(buf.data());
3694 m_ChartType = CHART_TYPE_UNKNOWN;
3695 m_ChartFamily = CHART_FAMILY_UNKNOWN;
3701 if (pc) pc->SetFocus();
3705 return INIT_FAIL_REMOVE;
3709int ChartPlugInWrapper::GetCOVREntries() {
3716int ChartPlugInWrapper::GetCOVRTablePoints(
int iTable) {
3723int ChartPlugInWrapper::GetCOVRTablenPoints(
int iTable) {
3730float* ChartPlugInWrapper::GetCOVRTableHead(
int iTable) {
3742int ChartPlugInWrapper::GetNoCOVREntries() {
3752int ChartPlugInWrapper::GetNoCOVRTablePoints(
int iTable) {
3762int ChartPlugInWrapper::GetNoCOVRTablenPoints(
int iTable) {
3772float* ChartPlugInWrapper::GetNoCOVRTableHead(
int iTable) {
3782bool ChartPlugInWrapper::GetChartExtent(
Extent* pext) {
3786 pext->NLAT = xpi.
NLAT;
3787 pext->SLAT = xpi.
SLAT;
3788 pext->ELON = xpi.
ELON;
3789 pext->WLON = xpi.
WLON;
3798ThumbData* ChartPlugInWrapper::GetThumbData(
int tnx,
int tny,
float lat,
3803 if (!pThumbData->pDIBThumb) {
3804 wxBitmap* pBMPOwnedByChart =
3805 m_ppicb->
GetThumbnail(tnx, tny, m_global_color_scheme);
3806 if (pBMPOwnedByChart) {
3807 wxImage img = pBMPOwnedByChart->ConvertToImage();
3808 pThumbData->pDIBThumb =
new wxBitmap(img);
3810 pThumbData->pDIBThumb = NULL;
3813 pThumbData->Thumb_Size_X = tnx;
3814 pThumbData->Thumb_Size_Y = tny;
3841 pThumbData->ShipX = 0;
3842 pThumbData->ShipY = 0;
3849ThumbData* ChartPlugInWrapper::GetThumbData() {
return pThumbData; }
3851bool ChartPlugInWrapper::UpdateThumbData(
double lat,
double lon) {
3855double ChartPlugInWrapper::GetNormalScaleMin(
double canvas_scale_factor,
3856 bool b_allow_overzoom) {
3863double ChartPlugInWrapper::GetNormalScaleMax(
double canvas_scale_factor,
3885void RenderRotateToViewPort(
const ViewPort& VPoint) {
3886#ifndef USE_ANDROID_GLES2
3888 glTranslatef(xt, yt, 0);
3889 glRotatef(VPoint.
rotation * 180. / PI, 0, 0, 1);
3890 glTranslatef(-xt, -yt, 0);
3894void UndoRenderRotateToViewPort(
const ViewPort& VPoint) {
3895#ifndef USE_ANDROID_GLES2
3897 glTranslatef(xt, yt, 0);
3898 glRotatef(-VPoint.
rotation * 180. / PI, 0, 0, 1);
3899 glTranslatef(-xt, -yt, 0);
3903bool ChartPlugInWrapper::RenderRegionViewOnGL(
const wxGLContext& glc,
3906 const LLRegion& Region) {
3915 if (!Region.Empty() && (ppicb_gl || ppicb_x)) {
3916 wxRegion* r = RectRegion.GetNew_wxRegion();
3919 LLRegion chart_region = vp.GetLLRegion(upd.GetRect());
3920 chart_region.Intersect(Region);
3922 if (!chart_region.Empty()) {
3923 ViewPort cvp = glChartCanvas::ClippedViewport(VPoint, chart_region);
3925 glChartCanvas::SetClipRect(cvp, upd.GetRect(),
false);
3929#ifndef USE_ANDROID_GLES2
3932 RenderRotateToViewPort(VPoint);
3937 glChartCanvas::s_b_useStencil);
3940 glChartCanvas::s_b_useStencil);
3941 UndoRenderRotateToViewPort(VPoint);
3943#ifndef USE_ANDROID_GLES2
3946 glChartCanvas::DisableClipRegion();
3960bool ChartPlugInWrapper::RenderRegionViewOnGLNoText(
3961 const wxGLContext& glc,
const ViewPort& VPoint,
3962 const OCPNRegion& RectRegion,
const LLRegion& Region) {
3971 if (!Region.Empty() && ppicb_x) {
3973 glChartCanvas::SetClipRect(VPoint, VPoint.rv_rect,
false);
3974 glChartCanvas::DisableClipRegion();
3977 RenderRotateToViewPort(VPoint);
3980 wxRegion* r = RectRegion.GetNew_wxRegion();
3983 glChartCanvas::s_b_useStencil);
3986 UndoRenderRotateToViewPort(VPoint);
3991 else if (!Region.Empty() &&
3995 wxRegion* r = RectRegion.GetNew_wxRegion();
3998 LLRegion chart_region = vp.GetLLRegion(upd.GetRect());
3999 chart_region.Intersect(Region);
4001 if (!chart_region.Empty()) {
4002 ViewPort cvp = glChartCanvas::ClippedViewport(VPoint, chart_region);
4004 glChartCanvas::SetClipRect(cvp, upd.GetRect(),
false);
4006 RenderRotateToViewPort(VPoint);
4010 glChartCanvas::s_b_useStencil);
4013 UndoRenderRotateToViewPort(VPoint);
4015 glChartCanvas::DisableClipRegion();
4028bool ChartPlugInWrapper::RenderRegionViewOnGLTextOnly(
4035 if (!Region.Empty() && ppicb_x) {
4036 wxRegion* r = Region.GetNew_wxRegion();
4038#ifndef USE_ANDROID_GLES2
4041 RenderRotateToViewPort(VPoint);
4045 glChartCanvas::s_b_useStencil);
4046 UndoRenderRotateToViewPort(VPoint);
4048#ifndef USE_ANDROID_GLES2
4061bool ChartPlugInWrapper::RenderRegionViewOnDC(wxMemoryDC& dc,
4067 if (Region.IsOk()) {
4068 wxRegion* r = Region.GetNew_wxRegion();
4075 wxColour nodat = GetGlobalColor(_T (
"NODTA" ));
4076 wxColour nodat_sub = nodat;
4078#ifdef ocpnUSE_ocpnBitmap
4079 nodat_sub = wxColour(nodat.Blue(), nodat.Green(), nodat.Red());
4081 m_pMask =
new wxMask(obmp, nodat_sub);
4082 obmp.SetMask(m_pMask);
4084 dc.SelectObject(obmp);
4095bool ChartPlugInWrapper::RenderRegionViewOnDCNoText(wxMemoryDC& dc,
4106 if (Region.IsOk() && (pCBx || ppicb)) {
4107 wxRegion* r = Region.GetNew_wxRegion();
4122bool ChartPlugInWrapper::RenderRegionViewOnDCTextOnly(
4125 bool ret_val =
false;
4128 if (Region.IsOk()) {
4129 wxRegion* r = Region.GetNew_wxRegion();
4143void ChartPlugInWrapper::ClearPLIBTextList() {
4151bool ChartPlugInWrapper::AdjustVP(
ViewPort& vp_last,
ViewPort& vp_proposed) {
4155 return m_ppicb->
AdjustVP(pivp_last, pivp_proposed);
4160void ChartPlugInWrapper::GetValidCanvasRegion(
const ViewPort& VPoint,
4175void ChartPlugInWrapper::SetColorScheme(ColorScheme cs,
bool bApplyImmediate) {
4179 m_global_color_scheme = cs;
4181 if (pThumbData) pThumbData->pDIBThumb = NULL;
4185 double target_scale_ppm) {
4192void ChartPlugInWrapper::ComputeSourceRectangle(
const ViewPort& VPoint,
4193 wxRect* pSourceRect) {
4200double ChartPlugInWrapper::GetRasterScaleFactor(
const ViewPort& vp) {
4202 return (wxRound(100000 * GetPPM() / vp.
view_scale_ppm)) / 100000.;
4207bool ChartPlugInWrapper::GetChartBits(wxRect& source,
unsigned char* pPix,
4209 wxCriticalSectionLocker locker(m_critSect);
4218int ChartPlugInWrapper::GetSize_X() {
4225int ChartPlugInWrapper::GetSize_Y() {
4232void ChartPlugInWrapper::latlong_to_chartpix(
double lat,
double lon,
4233 double& pixx,
double& pixy) {
4237void ChartPlugInWrapper::chartpix_to_latlong(
double pixx,
double pixy,
4238 double* plat,
double* plon) {
4253 return toSDMM(NEflag, a, hi_precision);
4257 return GetGlobalColor(colorName);
4261 const wxString& caption,
int style,
int x,
int y) {
4262 return OCPNMessageBox(parent, message, caption, style, 100, x, y);
4270 return g_Platform->GetWritableDocumentsDir();
4275 auto loader = PluginLoader::GetInstance();
4276 for (
unsigned int i = 0; i < loader->GetPlugInArray()->GetCount(); i++) {
4278 if (pic->m_pplugin == pplugin) {
4288ListOfPI_S57Obj* PlugInManager::GetPlugInObjRuleListAtLatLon(
4291 ListOfPI_S57Obj* list = NULL;
4305 list = picbx->GetObjRuleListAtLatLon(zlat, zlon, SelectRadius, &pi_vp);
4315 ListOfPI_S57Obj* rule_list) {
4326 ret_str = picbx->CreateObjDescriptions(rule_list);
4340 return ps52plib->m_nDepthUnitDisplay;
4347 return ps52plib->m_nSymbolStyle;
4354 return ps52plib->m_nBoundaryStyle;
4364 CreateCompatibleS57Object(pObj, &cobj, &ctx);
4366 ViewPort cvp = CreateCompatibleViewport(*vp);
4371 ObjRazRules rzRules;
4372 rzRules.obj = &cobj;
4373 rzRules.LUP = pContext->LUP;
4374 rzRules.sm_transform_parms = 0;
4375 rzRules.child = NULL;
4376 rzRules.next = NULL;
4378 if (pContext->LUP) {
4379 ps52plib->SetVPointCompat(
4383 ps52plib->PrepareForRender();
4385 return ps52plib->ObjectRenderCheck(&rzRules);
4394 return ps52plib->GetStateHash();
4399void CreateCompatibleS57Object(
PI_S57Obj* pObj, S57Obj* cobj,
4400 chart_context* pctx) {
4403 cobj->att_array = pObj->att_array;
4404 cobj->attVal = pObj->attVal;
4405 cobj->n_attr = pObj->n_attr;
4410 cobj->npt = pObj->npt;
4412 cobj->iOBJL = pObj->iOBJL;
4413 cobj->Index = pObj->Index;
4415 cobj->geoPt = (pt*)pObj->geoPt;
4416 cobj->geoPtz = pObj->geoPtz;
4417 cobj->geoPtMulti = pObj->geoPtMulti;
4419 cobj->m_lat = pObj->m_lat;
4420 cobj->m_lon = pObj->m_lon;
4422 cobj->m_DisplayCat = (DisCat)pObj->m_DisplayCat;
4423 cobj->x_rate = pObj->x_rate;
4424 cobj->y_rate = pObj->y_rate;
4425 cobj->x_origin = pObj->x_origin;
4426 cobj->y_origin = pObj->y_origin;
4428 cobj->Scamin = pObj->Scamin;
4429 cobj->nRef = pObj->nRef;
4430 cobj->bIsAton = pObj->bIsAton;
4431 cobj->bIsAssociable = pObj->bIsAssociable;
4433 cobj->m_n_lsindex = pObj->m_n_lsindex;
4434 cobj->m_lsindex_array = pObj->m_lsindex_array;
4435 cobj->m_n_edge_max_points = pObj->m_n_edge_max_points;
4438 cobj->m_ls_list_legacy =
4442 cobj->m_ls_list_legacy = 0;
4443 cobj->m_ls_list = 0;
4446 cobj->m_bcategory_mutable = pObj->m_bcategory_mutable;
4448 cobj->m_bcategory_mutable =
true;
4452 if (pObj->m_DPRI == -1) {
4454 if (pCtx->LUP) cobj->m_DPRI = pCtx->LUP->DPRI -
'0';
4456 cobj->m_DPRI = pObj->m_DPRI;
4459 cobj->pPolyTessGeo = (PolyTessGeo*)pObj->pPolyTessGeo;
4460 cobj->m_chart_context = (chart_context*)pObj->m_chart_context;
4462 if (pObj->auxParm3 != 1234) {
4463 pObj->auxParm3 = 1234;
4464 pObj->auxParm0 = -99;
4467 cobj->auxParm0 = pObj->auxParm0;
4474 if (pContext->bBBObj_valid)
4476 cobj->BBObj.Set(pContext->BBObj.GetMinY(), pContext->BBObj.GetMinX(),
4477 pContext->BBObj.GetMaxY(), pContext->BBObj.GetMaxX());
4479 cobj->CSrules = pContext->CSrules;
4480 cobj->bCS_Added = pContext->bCS_Added;
4482 cobj->FText = pContext->FText;
4483 cobj->bFText_Added = pContext->bFText_Added;
4484 cobj->rText = pContext->rText;
4486 cobj->bIsClone =
true;
4489 cobj->m_chart_context = pctx;
4490 chart_context* ppctx = (chart_context*)pObj->m_chart_context;
4493 cobj->m_chart_context->m_pvc_hash = ppctx->m_pvc_hash;
4494 cobj->m_chart_context->m_pve_hash = ppctx->m_pve_hash;
4495 cobj->m_chart_context->ref_lat = ppctx->ref_lat;
4496 cobj->m_chart_context->ref_lon = ppctx->ref_lon;
4497 cobj->m_chart_context->pFloatingATONArray = ppctx->pFloatingATONArray;
4498 cobj->m_chart_context->pRigidATONArray = ppctx->pRigidATONArray;
4499 cobj->m_chart_context->safety_contour = ppctx->safety_contour;
4500 cobj->m_chart_context->vertex_buffer = ppctx->vertex_buffer;
4502 cobj->m_chart_context->chart =
4504 cobj->m_chart_context->chart_type = S52_CHART_TYPE_PLUGIN;
4518 CreateCompatibleS57Object(pObj, &cobj, NULL);
4520 LUPname LUP_Name = PAPER_CHART;
4523 ctx->CSrules = NULL;
4524 ctx->bCS_Added =
false;
4527 if (ctx->bFText_Added) {
4528 ctx->bFText_Added =
false;
4534 ctx->bBBObj_valid =
true;
4539 switch (cobj.Primitive_type) {
4544 if (PAPER_CHART == ps52plib->m_nSymbolStyle)
4545 LUP_Name = PAPER_CHART;
4547 LUP_Name = SIMPLIFIED;
4556 if (PLAIN_BOUNDARIES == ps52plib->m_nBoundaryStyle)
4557 LUP_Name = PLAIN_BOUNDARIES;
4559 LUP_Name = SYMBOLIZED_BOUNDARIES;
4564 LUPrec* lup = ps52plib->S52_LUPLookup(LUP_Name, cobj.FeatureName, &cobj);
4568 ps52plib->_LUP2rules(lup, &cobj);
4570 ctx->MPSRulesList = NULL;
4578 pContext->bBBObj_valid =
true;
4584void UpdatePIObjectPlibContext(
PI_S57Obj* pObj, S57Obj* cobj,
4585 ObjRazRules* rzRules) {
4589 pContext->CSrules = cobj->CSrules;
4590 pContext->bCS_Added = cobj->bCS_Added;
4592 pContext->FText = cobj->FText;
4593 pContext->bFText_Added = cobj->bFText_Added;
4594 pContext->rText = cobj->rText;
4596 if (cobj->BBObj.GetValid()) {
4599 BoundingBox(cobj->BBObj.GetMinLon(), cobj->BBObj.GetMinLat(),
4600 cobj->BBObj.GetMaxLon(), cobj->BBObj.GetMaxLat());
4601 pContext->bBBObj_valid =
true;
4606 pObj->m_DisplayCat = (
PI_DisCat)cobj->m_DisplayCat;
4610 pContext->ChildRazRules = rzRules->child;
4611 pContext->MPSRulesList = rzRules->mps;
4613 pObj->auxParm0 = cobj->auxParm0;
4617 double* lon_min,
double* lon_max) {
4620 if (lat_min) *lat_min = pContext->BBObj.GetMinY();
4621 if (lat_max) *lat_max = pContext->BBObj.GetMaxY();
4622 if (lon_min) *lon_min = pContext->BBObj.GetMinX();
4623 if (lon_max) *lon_max = pContext->BBObj.GetMaxX();
4624 return pContext->bBBObj_valid;
4632 LUPrec* lup = pContext->LUP;
4641 LUPrec* lup = pContext->LUP;
4651 LUPrec* lup = pContext->LUP;
4657 return S52_getMarinerParam(S52_MAR_SAFETY_CONTOUR);
4664 CreateCompatibleS57Object(pObj, &cobj, &ctx);
4669 ObjRazRules rzRules;
4670 rzRules.obj = &cobj;
4671 rzRules.LUP = pContext->LUP;
4672 rzRules.sm_transform_parms = 0;
4673 rzRules.child = NULL;
4674 rzRules.next = NULL;
4675 rzRules.mps = pContext->MPSRulesList;
4677 if (pContext->LUP) {
4678 ps52plib->SetLineFeaturePriority(&rzRules, prio);
4681 UpdatePIObjectPlibContext(pObj, &cobj, &rzRules);
4687 ps52plib->PrepareForRender();
4688 ps52plib->ClearTextList();
4691 ps52plib->EnableGLLS(
true);
4693 ps52plib->EnableGLLS(
false);
4702 if (pctx->ChildRazRules) {
4703 ObjRazRules* ctop = pctx->ChildRazRules;
4707 if (ps52plib) ps52plib->DestroyLUP(ctop->LUP);
4709 ObjRazRules* cnxx = ctop->next;
4715 if (pctx->MPSRulesList) {
4716 if (ps52plib && pctx->MPSRulesList->cs_rules) {
4717 for (
unsigned int i = 0; i < pctx->MPSRulesList->cs_rules->GetCount();
4719 Rules* top = pctx->MPSRulesList->cs_rules->Item(i);
4720 ps52plib->DestroyRulesChain(top);
4722 delete pctx->MPSRulesList->cs_rules;
4724 free(pctx->MPSRulesList);
4736 CreateCompatibleS57Object(pObj, &cobj, &ctx);
4743 &transform.easting_vp_center, &transform.northing_vp_center);
4746 ObjRazRules rzRules;
4747 rzRules.obj = &cobj;
4748 rzRules.LUP = pContext->LUP;
4749 rzRules.sm_transform_parms = &transform;
4750 rzRules.child = pContext->ChildRazRules;
4751 rzRules.next = NULL;
4752 rzRules.mps = pContext->MPSRulesList;
4754 if (pContext->LUP) {
4755 ViewPort cvp = CreateCompatibleViewport(*vp);
4761 cvp.rv_rect, cvp.GetBBox(), cvp.
ref_scale,
4763 ps52plib->PrepareForRender();
4765 ps52plib->RenderObjectToDC(pdc, &rzRules);
4768 UpdatePIObjectPlibContext(pObj, &cobj, &rzRules);
4775 wxRect rect,
unsigned char* pixbuf) {
4777 render_canvas_parms pb_spec;
4779 pb_spec.depth = BPP;
4780 pb_spec.pb_pitch = ((rect.width * pb_spec.depth / 8));
4781 pb_spec.lclip = rect.x;
4782 pb_spec.rclip = rect.x + rect.width - 1;
4783 pb_spec.pix_buff = pixbuf;
4784 pb_spec.width = rect.width;
4785 pb_spec.height = rect.height;
4788#ifdef ocpnUSE_ocpnBitmap
4789 pb_spec.b_revrgb =
true;
4791 pb_spec.b_revrgb =
false;
4794 pb_spec.b_revrgb =
false;
4799 CreateCompatibleS57Object(pObj, &cobj, &ctx);
4806 &transform.easting_vp_center, &transform.northing_vp_center);
4809 ObjRazRules rzRules;
4810 rzRules.obj = &cobj;
4811 rzRules.LUP = pContext->LUP;
4812 rzRules.sm_transform_parms = &transform;
4813 rzRules.child = pContext->ChildRazRules;
4814 rzRules.next = NULL;
4815 rzRules.mps = pContext->MPSRulesList;
4817 ViewPort cvp = CreateCompatibleViewport(*vp);
4825 if (!tess)
return 1;
4827 PolyTriGroup* ptg =
new PolyTriGroup;
4828 ptg->tri_prim_head =
4829 tess->Get_PolyTriGroup_head()->tri_prim_head;
4830 ptg->bsingle_alloc =
false;
4831 ptg->data_type = DATA_TYPE_DOUBLE;
4832 tess->Set_PolyTriGroup_head(ptg);
4834 double* pd = (
double*)malloc(
sizeof(
double));
4839 if (pContext->LUP) {
4844 cvp.rv_rect, cvp.GetBBox(), cvp.
ref_scale,
4846 ps52plib->PrepareForRender();
4848 ps52plib->RenderAreaToDC(pdc, &rzRules, &pb_spec);
4851 UpdatePIObjectPlibContext(pObj, &cobj, &rzRules);
4863 CreateCompatibleS57Object(pObj, &cobj, &ctx);
4874 if (!tess)
return 1;
4878 ptg->tri_prim_head = tess->Get_PolyTriGroup_head()->tri_prim_head;
4879 ptg->bsingle_alloc =
false;
4880 ptg->data_type = DATA_TYPE_DOUBLE;
4881 tess->Set_PolyTriGroup_head(ptg);
4885 double* pd = (
double*)malloc(
sizeof(
double));
4902 &transform.easting_vp_center, &transform.northing_vp_center);
4905 ObjRazRules rzRules;
4906 rzRules.obj = &cobj;
4907 rzRules.LUP = pContext->LUP;
4908 rzRules.sm_transform_parms = &transform;
4909 rzRules.child = pContext->ChildRazRules;
4910 rzRules.next = NULL;
4911 rzRules.mps = pContext->MPSRulesList;
4913 if (pContext->LUP) {
4914 ViewPort cvp = CreateCompatibleViewport(*vp);
4920 cvp.rv_rect, cvp.GetBBox(), cvp.
ref_scale,
4922 ps52plib->PrepareForRender();
4924 ps52plib->RenderAreaToGL(glcc, &rzRules);
4927 UpdatePIObjectPlibContext(pObj, &cobj, &rzRules);
4939 CreateCompatibleS57Object(pObj, &cobj, &ctx);
4946 &transform.easting_vp_center, &transform.northing_vp_center);
4949 ObjRazRules rzRules;
4950 rzRules.obj = &cobj;
4951 rzRules.LUP = pContext->LUP;
4952 rzRules.sm_transform_parms = &transform;
4953 rzRules.child = pContext->ChildRazRules;
4954 rzRules.next = NULL;
4955 rzRules.mps = pContext->MPSRulesList;
4957 if (pContext->LUP) {
4958 ViewPort cvp = CreateCompatibleViewport(*vp);
4964 cvp.rv_rect, cvp.GetBBox(), cvp.
ref_scale,
4966 ps52plib->PrepareForRender();
4968 ps52plib->RenderObjectToGL(glcc, &rzRules);
4971 UpdatePIObjectPlibContext(pObj, &cobj, &rzRules);
4981OCPN_downloadEvent::OCPN_downloadEvent(wxEventType commandType,
int id)
4982 : wxEvent(id, commandType) {
4985 m_b_complete =
false;
4989OCPN_downloadEvent::~OCPN_downloadEvent() {}
4991wxEvent* OCPN_downloadEvent::Clone()
const {
4993 newevent->m_stat = this->m_stat;
4994 newevent->m_condition = this->m_condition;
4996 newevent->m_totalBytes = this->m_totalBytes;
4997 newevent->m_sofarBytes = this->m_sofarBytes;
4998 newevent->m_b_complete = this->m_b_complete;
5004DECL_EXP wxEventType wxEVT_DOWNLOAD_EVENT = wxNewEventType();
5009#define DL_EVENT_TIMER 4388
5017 void setBackgroundMode(
long ID, wxEvtHandler* handler);
5018 void clearBackgroundMode();
5019 void onTimerEvent(wxTimerEvent& event);
5022 wxTimer m_eventTimer;
5023 wxEvtHandler* m_download_evHandler;
5029PI_DLEvtHandler::PI_DLEvtHandler() {
5033 m_download_evHandler = NULL;
5039PI_DLEvtHandler::~PI_DLEvtHandler() {
5040 m_eventTimer.Stop();
5043 (wxObjectEventFunction)(wxEventFunction)&PI_DLEvtHandler::onTimerEvent);
5050 g_download_status =
event.getDLEventStatus();
5051 g_download_condition =
event.getDLEventCondition();
5054 if (m_download_evHandler &&
5057 ev.setComplete(
true);
5058 ev.setTransferred(m_sofarBytes);
5059 ev.setTotal(m_totalBytes);
5061 ev.setDLEventStatus(event.getDLEventStatus());
5064 m_download_evHandler->AddPendingEvent(ev);
5065 m_eventTimer.Stop();
5067 finishAndroidFileDownload();
5074void PI_DLEvtHandler::setBackgroundMode(
long ID, wxEvtHandler* handler) {
5076 m_download_evHandler = handler;
5078 m_eventTimer.SetOwner(
this, DL_EVENT_TIMER);
5082 (wxObjectEventFunction)(wxEventFunction)&PI_DLEvtHandler::onTimerEvent);
5083 m_eventTimer.Start(1000, wxTIMER_CONTINUOUS);
5086void PI_DLEvtHandler::clearBackgroundMode() {
5087 m_download_evHandler = NULL;
5088 m_eventTimer.Stop();
5091void PI_DLEvtHandler::onTimerEvent(wxTimerEvent& event) {
5097 int stat = queryAndroidFileDownload(m_id, &sstat);
5100 long sofarBytes = 0;
5101 long totalBytes = -1;
5105 qDebug() <<
"Error on queryAndroidFileDownload, ending download";
5106 ev.setComplete(
true);
5107 ev.setTransferred(sofarBytes);
5108 ev.setTotal(totalBytes);
5113 wxStringTokenizer tk(sstat,
";");
5114 if (tk.HasMoreTokens()) {
5115 wxString token = tk.GetNextToken();
5116 token.ToLong(&state);
5117 token = tk.GetNextToken();
5118 token.ToLong(&sofarBytes);
5119 token = tk.GetNextToken();
5120 token.ToLong(&totalBytes);
5123 qDebug() << state << sofarBytes << totalBytes;
5125 m_sofarBytes = sofarBytes;
5126 m_totalBytes = totalBytes;
5128 ev.setTransferred(sofarBytes);
5129 ev.setTotal(totalBytes);
5132 qDebug() <<
"Event OCPN_DL_FAILED/OCPN_DL_EVENT_TYPE_END";
5133 ev.setComplete(
true);
5136 }
else if (state == 8) {
5137 qDebug() <<
"Event OCPN_DL_NO_ERROR/OCPN_DL_EVENT_TYPE_END";
5138 ev.setComplete(
true);
5142 ev.setComplete(
false);
5150 if (m_download_evHandler) {
5152 m_download_evHandler->AddPendingEvent(ev);
5157 m_eventTimer.Stop();
5158 finishAndroidFileDownload();
5168 const wxString& outputFile,
5169 const wxString& title,
const wxString& message,
5170 const wxBitmap& bitmap, wxWindow* parent,
5171 long style,
int timeout_secs) {
5174 wxString msg =
"Downloading file synchronously: ";
5181 int vres = validateAndroidWriteLocation(outputFile);
5193 g_piEventHandler->Connect(
5194 wxEVT_DOWNLOAD_EVENT,
5195 (wxObjectEventFunction)(wxEventFunction)&PI_DLEvtHandler::onDLEvent);
5200 wxString fURI = outputFile;
5201 if (!fURI.StartsWith(
"file://")) {
5202 fURI.Prepend(
"file://");
5205 int res = startAndroidFileDownload(url, fURI, g_piEventHandler, &dl_ID);
5208 finishAndroidFileDownload();
5209 g_piEventHandler->Disconnect(
5210 wxEVT_DOWNLOAD_EVENT,
5211 (wxObjectEventFunction)(wxEventFunction)&PI_DLEvtHandler::onDLEvent);
5216 wxDateTime dl_start_time = wxDateTime::Now();
5220 wxTimeSpan dt = wxDateTime::Now() - dl_start_time;
5221 qDebug() <<
"Spin.." << dt.GetSeconds().GetLo();
5223 if (dt.GetSeconds() > timeout_secs) {
5224 qDebug() <<
"USER_TIMOUT";
5225 finishAndroidFileDownload();
5226 g_piEventHandler->Disconnect(
5227 wxEVT_DOWNLOAD_EVENT,
5228 (wxObjectEventFunction)(wxEventFunction)&PI_DLEvtHandler::onDLEvent);
5236 finishAndroidFileDownload();
5237 g_piEventHandler->Disconnect(
5238 wxEVT_DOWNLOAD_EVENT,
5242 qDebug() <<
"RETURN DL_END" << (int)ss;
5248 int stat = queryAndroidFileDownload(dl_ID, &sstat);
5250 qDebug() <<
"Error on queryAndroidFileDownload";
5251 finishAndroidFileDownload();
5252 g_piEventHandler->Disconnect(
5253 wxEVT_DOWNLOAD_EVENT,
5254 (wxObjectEventFunction)(wxEventFunction)&PI_DLEvtHandler::onDLEvent);
5264#elif defined(OCPN_USE_CURL)
5265 wxFileName tfn = wxFileName::CreateTempFileName(outputFile);
5266 wxFileOutputStream output(tfn.GetFullPath());
5268 wxCurlDownloadDialog ddlg(url, &output, title, message + url, bitmap, parent,
5270 wxCurlDialogReturnFlag ret = ddlg.RunModal();
5276 case wxCDRF_SUCCESS: {
5277 if (wxCopyFile(tfn.GetFullPath(), outputFile))
5283 case wxCDRF_FAILED: {
5287 case wxCDRF_USER_ABORTED: {
5295 if (wxFileExists(tfn.GetFullPath())) wxRemoveFile(tfn.GetFullPath());
5305 return ocpn::toUsrDateTimeFormat(date_time,
options);
5310 const wxString& outputFile,
5311 wxEvtHandler* handler,
5314 wxString msg =
"Downloading file asynchronously: ";
5326 int res = startAndroidFileDownload(url, outputFile, NULL ,
5330 finishAndroidFileDownload();
5335 g_piEventHandler->setBackgroundMode(dl_ID, handler);
5337 if (handle) *handle = dl_ID;
5341#elif defined(OCPN_USE_CURL)
5348 bool http = (url.StartsWith(wxS(
"http:")) || url.StartsWith(wxS(
"https:")));
5351 dynamic_cast<wxCurlHTTP*
>(
g_pi_manager->m_pCurl.get())) {
5358 bool failed =
false;
5367 new wxFileOutputStream(outputFile)),
5375 wxCurlThreadError err =
g_pi_manager->m_pCurlThread->Download();
5376 if (err != wxCTE_NO_ERROR) {
5390 delete (
g_pi_manager->m_pCurlThread->GetOutputStream());
5408 cancelAndroidFileDownload(handle);
5409 finishAndroidFileDownload();
5410 if (g_piEventHandler) g_piEventHandler->clearBackgroundMode();
5414 delete (
g_pi_manager->m_pCurlThread->GetOutputStream());
5425 const wxString& parameters, wxString& result,
5428 wxString lparms = parameters;
5429 wxString postResult = doAndroidPOST(url, lparms, timeout_secs * 1000);
5432 result = postResult;
5435#elif defined(OCPN_USE_CURL)
5437 post.SetOpt(CURLOPT_TIMEOUT, timeout_secs);
5438 size_t res = post.Post(parameters.ToAscii(), parameters.Len(), url);
5441 result = wxString(post.GetResponseBody().c_str(), wxConvUTF8);
5444 result = wxEmptyString;
5455 return androidCheckOnline();
5458#if !defined(__ANDROID__) && defined(OCPN_USE_CURL)
5459 if (wxDateTime::GetTimeNow() >
5460 g_pi_manager->m_last_online_chk + ONLINE_CHECK_RETRY) {
5462 get.Head(
"http://yahoo.com/");
5463 g_pi_manager->m_last_online = get.GetResponseCode() > 0;
5465 g_pi_manager->m_last_online_chk = wxDateTime::GetTimeNow();
5473#if !defined(__ANDROID__) && defined(OCPN_USE_CURL)
5474void PlugInManager::OnEndPerformCurlDownload(wxCurlEndPerformEvent& ev) {
5476 if (ev.IsSuccessful()) {
5483 event.setComplete(
true);
5485 if (m_download_evHandler) {
5486 m_download_evHandler->AddPendingEvent(event);
5487 m_download_evHandler = NULL;
5488 m_downloadHandle = NULL;
5491 if (m_pCurlThread) {
5492 m_pCurlThread->Wait();
5493 if (!m_pCurlThread->IsAborting()) {
5494 delete (m_pCurlThread->GetOutputStream());
5495 wxDELETE(m_pCurlThread);
5500void PlugInManager::OnCurlDownload(wxCurlDownloadEvent& ev) {
5504 event.setTotal(ev.GetTotalBytes());
5505 event.setTransferred(ev.GetDownloadedBytes());
5506 event.setComplete(
false);
5508 if (m_download_evHandler) {
5509 m_download_evHandler->AddPendingEvent(event);
5513bool PlugInManager::HandleCurlThreadError(wxCurlThreadError err,
5514 wxCurlBaseThread* p,
5515 const wxString& url) {
5517 case wxCTE_NO_ERROR:
5520 case wxCTE_NO_RESOURCE:
5522 wxS(
"Insufficient resources for correct execution of the program."));
5525 case wxCTE_ALREADY_RUNNING:
5529 case wxCTE_INVALID_PROTOCOL:
5530 wxLogError(wxS(
"The URL '%s' uses an unsupported protocol."),
5534 case wxCTE_NO_VALID_STREAM:
5541 case wxCTE_CURL_ERROR: {
5542 wxString ws = wxS(
"unknown");
5543 if (p->GetCurlSession())
5545 wxString(p->GetCurlSession()->GetErrorString().c_str(), wxConvUTF8);
5546 wxLogError(wxS(
"Network error: %s"), ws.c_str());
5551 if (p->IsAlive()) p->Abort();
AisDecoder * g_pAIS
Global instance.
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
Basic chart info storage.
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.
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.
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.
void SetBoxes()
Computes the bounding box coordinates for the current viewport.
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.
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.
Variables maintained by comm stack, read-only access for others.
double g_display_size_mm
Physical display width (mm)
Global variables stored in configuration file.
Generic GUI downloads tool.
Handle downloading of files from remote urls.
OpenGL chart rendering canvas.
GSHHS Chart Object (Global Self-consistent, Hierarchical, High-resolution Shoreline) Derived from htt...
Miscellaneous globals primarely used by gui layer, not persisted in configuration file.
JSON event definition used in internal communications to/from plugins.
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.
Navigation Utility Functions without GUI dependencies.
Notify()/Listen() configuration variable wrapper.
Global variables Listen()/Notify() wrapper.
Optimized wxBitmap Object.
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
Color schemes for different lighting conditions.
#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.
Layer to use wxDC or opengl.
options * g_options
Global instance.
Downloaded plugins cache.
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.
_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.
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.
PlugInManager * g_pi_manager
Global instance.
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.
void PI_PLIBPrepareForNewRender()
Prepares PLIB for new rendering pass.
PI_DisCat PI_GetObjectDisplayCategory(PI_S57Obj *pObj)
Gets display category for object.
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.
_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.
wxString GetOCPN_ExePath()
Gets OpenCPN executable path.
_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.
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.
wxString GetWritableDocumentsDir()
Returns the platform-specific default documents directory.
PlugInManager and helper classes – Mostly gui parts (dialogs) and plugin API stuff.
PlugInManager * g_pi_manager
Global instance.
Routeman * g_pRouteMan
Global instance.
Safe mode non-gui handling.
Selected route, segment, waypoint, etc.
Semantic version encode/decode object.
Versions uses a modified semantic versioning scheme: major.minor.revision.post-tag+build.
static SemanticVersion parse(std::string s)
Parse a version string, sets major == -1 on errors.
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.
wxBitmap LoadSVG(const wxString filename, const unsigned int width, const unsigned int height, wxBitmap *default_bitmap, bool use_cache)
Load SVG file and return it's bitmap representation of requested size In case file can't be loaded an...
Recorded track abstraction.
WaypointMan drawing stuff.