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"
164#include "androidUTIL.h"
171typedef __LA_INT64_T la_int64_t;
172enum { CurlThreadId = wxID_HIGHEST + 1 };
174#if wxUSE_XLOCALE || !wxCHECK_VERSION(3, 0, 0)
175extern wxLocale* plocale_def_lang;
180void NotifySetupOptionsPlugin(
const PlugInData* pic);
182WX_DEFINE_LIST(Plugin_WaypointList);
183WX_DEFINE_LIST(Plugin_HyperlinkList);
190 explicit RawKey(
const std::string& key) : m_key(key) {}
191 [[nodiscard]] std::string
GetKey()
const override {
return m_key; }
197static void SendAisJsonMessage(std::shared_ptr<const AisTargetData> pTarget) {
199 if (!GetJSONMessageTargetCount())
return;
204 wxLongLong t = ::wxGetLocalTimeMillis();
206 jMsg[wxS(
"Source")] = wxS(
"AisDecoder");
207 jMsg[
"Type"] =
"Information";
208 jMsg[
"Msg"] = wxS(
"AIS Target");
209 jMsg[
"MsgId"] = t.GetValue();
210 jMsg[wxS(
"lat")] = pTarget->Lat;
211 jMsg[wxS(
"lon")] = pTarget->Lon;
212 jMsg[wxS(
"sog")] = pTarget->SOG;
213 jMsg[wxS(
"cog")] = pTarget->COG;
214 jMsg[wxS(
"hdg")] = pTarget->HDG;
215 jMsg[wxS(
"mmsi")] = pTarget->MMSI;
216 jMsg[wxS(
"class")] = pTarget->Class;
217 jMsg[wxS(
"ownship")] = pTarget->b_OwnShip;
218 jMsg[wxS(
"active")] = pTarget->b_active;
219 jMsg[wxS(
"lost")] = pTarget->b_lost;
220 wxString l_ShipName = wxString::FromUTF8(pTarget->ShipName);
221 for (
size_t i = 0; i < l_ShipName.Len(); i++) {
222 if (l_ShipName.GetChar(i) ==
'@') l_ShipName.SetChar(i,
'\n');
224 jMsg[wxS(
"shipname")] = l_ShipName;
225 wxString l_CallSign = wxString::FromUTF8(pTarget->CallSign);
226 for (
size_t i = 0; i < l_CallSign.Len(); i++) {
227 if (l_CallSign.GetChar(i) ==
'@') l_CallSign.SetChar(i,
'\n');
229 jMsg[wxS(
"callsign")] = l_CallSign;
230 jMsg[wxS(
"removed")] = pTarget->b_removed;
231 SendJSONMessageToAllPlugins(
"AIS", jMsg);
235 return (*p1)->Key().compare((*p2)->Key());
239 auto version = metadata.version;
241 if (version[0] ==
'v') version = version.substr(1);
246 auto imported_version = ParseVersion(metadata);
247 for (
auto& md :
PluginHandler::GetInstance()->GetAvailable()) {
248 if (md.name != metadata.name)
continue;
249 if (md.is_imported)
continue;
251 if (ParseVersion(md) >= imported_version)
return true;
262 void message(
const std::string& message) {
264 m_deferred_messages.push_back(message);
269 void show_deferred_messages() {
270 for (
auto m : m_deferred_messages) show_msg(m);
277 void show_msg(wxString msg) {
278 OCPNMessageBox(NULL, msg, wxString(_(
"OpenCPN Info")),
279 wxICON_INFORMATION | wxOK, 10);
283 std::vector<wxString> m_deferred_messages;
290 Wrap(win, text, widthMax);
292 wxString
const& GetWrapped()
const {
return m_wrapped; }
293 int const GetLineCount()
const {
return m_lineCount; }
294 wxArrayString GetLineArray() {
return m_array; }
297 virtual void OnOutputLine(
const wxString& line) {
301 virtual void OnNewLine() {
309 wxArrayString m_array;
313 template <
typename T>
314 std::size_t operator()(T t)
const {
315 return static_cast<std::size_t
>(t);
322 return _(
"Plugin is a standard system plugin");
324 return _(
"Plugin is managed by OpenCPN");
326 return _(
"Plugin is not managed by OpenCPN");
329 case PluginStatus::Unknown:
330 return _(
"Plugin status unknown");
331 case PluginStatus::LegacyUpdateAvailable:
332 return _(
"Update to managed Plugin is available");
333 case PluginStatus::ManagedInstallAvailable:
334 return _(
"New managed Plugin installation available");
335 case PluginStatus::ManagedInstalledUpdateAvailable:
336 return _(
"Update to installed Plugin is available");
337 case PluginStatus::ManagedInstalledCurrentVersion:
338 return _(
"Plugin is latest available");
339 case PluginStatus::Imported:
340 return _(
"Plugin is imported");
341 case PluginStatus::ManagedInstalledDowngradeAvailable:
343 case PluginStatus::PendingListRemoval:
350static const std::unordered_map<PluginStatus, const char*, EnumClassHash>
356 {PluginStatus::Unknown,
"emblem-unmanaged.svg"},
357 {PluginStatus::LegacyUpdateAvailable,
"emblem-legacy-update.svg"},
358 {PluginStatus::ManagedInstallAvailable,
"emblem-download.svg"},
359 {PluginStatus::ManagedInstalledUpdateAvailable,
360 "emblem-legacy-update.svg"},
361 {PluginStatus::ManagedInstalledCurrentVersion,
"emblem-default.svg"},
362 {PluginStatus::ManagedInstalledDowngradeAvailable,
363 "emblem-default.svg"},
364 {PluginStatus::PendingListRemoval,
"emblem-default.svg"},
365 {PluginStatus::Imported,
"emblem-default.svg"}});
367static const std::unordered_map<PluginStatus, const char*, EnumClassHash>
368 literalstatus_by_status(
373 {PluginStatus::Unknown,
"Unknown"},
374 {PluginStatus::LegacyUpdateAvailable,
"LegacyUpdateAvailable"},
375 {PluginStatus::ManagedInstallAvailable,
"ManagedInstallAvailable"},
376 {PluginStatus::ManagedInstalledUpdateAvailable,
377 "ManagedInstalledUpdateAvailable"},
378 {PluginStatus::ManagedInstalledCurrentVersion,
379 "ManagedInstalledCurrentVersion"},
380 {PluginStatus::ManagedInstalledDowngradeAvailable,
381 "ManagedInstalledDowngradeAvailable"},
382 {PluginStatus::PendingListRemoval,
"PendingListRemoval"},
383 {PluginStatus::Imported,
"Imported"}
391static std::vector<PluginMetadata> getCompatiblePlugins() {
393 struct metadata_compare {
396 return lhs.key() < rhs.key();
400 std::vector<PluginMetadata> returnArray;
402 std::set<PluginMetadata, metadata_compare> unique_plugins;
403 for (
auto plugin :
PluginHandler::GetInstance()->GetAvailable()) {
404 unique_plugins.insert(plugin);
406 for (
auto plugin : unique_plugins) {
408 returnArray.push_back(plugin);
425 std::string installed;
427 if (path ==
"" || !wxFileName::IsFileReadable(path)) {
430 std::ifstream stream;
431 stream.open(path, std::ifstream::in);
440static std::vector<PluginMetadata> getUpdates(
const char* name) {
441 auto updates = getCompatiblePlugins();
443 std::remove_if(updates.begin(), updates.end(),
447 auto inst_vers = getInstalledVersion(name);
448 if (inst_vers.major == -1) {
453 updates.erase(std::remove_if(updates.begin(), updates.end(),
455 return metadata_version(m) == inst_vers;
462static void gui_uninstall(
const PlugInData* pic,
const char* plugin) {
463 g_Platform->ShowBusySpinner();
468 wxLogMessage(
"Uninstalling %s", plugin);
471 g_Platform->HideBusySpinner();
474static bool LoadAllPlugIns(
bool load_enabled,
bool keep_orphans =
false) {
475 g_Platform->ShowBusySpinner();
477 PluginLoader::GetInstance()->
LoadAllPlugIns(load_enabled, keep_orphans);
478 g_Platform->HideBusySpinner();
483static void UninstallPlugin(
const std::string& name) {
485 auto loader = PluginLoader::GetInstance();
486 auto finder = [name](
const PluginMetadata pm) {
return pm.name == name; };
487 const auto& installed = handler->GetInstalled();
488 auto found = std::find_if(installed.begin(), installed.end(), finder);
489 if (found != installed.end()) {
490 for (
size_t i = 0; i < loader->GetPlugInArray()->GetCount(); i++) {
491 auto const& item = loader->GetPlugInArray()->Item(i);
492 if (item->m_common_name.ToStdString() == name) {
493 DEBUG_LOG <<
"Unloading plugin: " << name;
494 loader->UnLoadPlugIn(i);
498 handler->Uninstall(found->name);
499 DEBUG_LOG <<
"Uninstalling: " << found->name;
504 bool uninstall,
const char* name = 0,
505 bool b_forceEnable =
false) {
507 const char* plugin = name == 0 ? pic->
m_common_name.mb_str().data() : name;
508 auto updates = getUpdates(plugin);
509 auto parent_dlg =
dynamic_cast<wxScrolledWindow*
>(parent);
510 wxASSERT(parent_dlg != 0);
512 auto status = dialog.ShowModal();
513 status = dialog.GetReturnCode();
514 if (status != wxID_OK) {
518 auto update = dialog.GetUpdate();
523 wxLogMessage(
"Installing %s", update.name.c_str());
525 g_Platform->ShowBusySpinner();
529 if (uninstall && path !=
"") {
530 gui_uninstall(pic, update.name.c_str());
532 bool cacheResult = pluginHandler->InstallPluginFromCache(update);
535 g_Platform->ShowBusySpinner();
539 std::string tempTarballPath = downloader->run(parent_dlg, uninstall);
541 if (!tempTarballPath.size())
547 if (!isRegularFile(manifestPath.c_str())) {
548 wxLogMessage(
"Installation of %s failed", update.name.c_str());
549 PluginHandler::CleanupFiles(manifestPath, update.name);
555 wxLogMessage(
"Installation of %s successful", update.name.c_str());
556 wxURI uri(wxString(update.tarball_url.c_str()));
557 wxFileName fn(uri.GetPath());
558 std::string basename = fn.GetFullName().ToStdString();
561 wxLogDebug(
"Copied %s to local cache at %s", tempTarballPath.c_str(),
563 remove(tempTarballPath.c_str());
571 wxString pispec =
"_pi.dll";
572#elif defined(__WXOSX__)
573 wxString pispec =
"_pi.dylib";
575 wxString pispec =
"_pi.so";
579 wxTextFile manifest_file(manifestPath);
581 if (manifest_file.Open()) {
583 for (wxString str = manifest_file.GetFirstLine(); !manifest_file.Eof();
584 str = manifest_file.GetNextLine()) {
585 if (str.Contains(pispec)) {
586 if (getenv(
"OCPN_KEEP_PLUGINS")) {
590 auto loader = PluginLoader::GetInstance();
591 if (!loader->CheckPluginCompatibility(str)) {
593 _(
"The plugin is not compatible with this version of OpenCPN, "
594 "and will be uninstalled.");
595 OCPNMessageBox(NULL, msg, wxString(_(
"OpenCPN Info")),
596 wxICON_INFORMATION | wxOK, 10);
598 PluginHandler::CleanupFiles(manifestPath, update.name);
607 if (b_forceEnable && pluginFile.Length()) {
608 wxString config_section = (_T (
"/PlugIns/" ));
609 wxFileName fn(pluginFile);
610 config_section += fn.GetFullName();
611 pConfig->SetPath(config_section);
612 pConfig->Write(_T (
"bEnabled" ),
true);
618 std::remove(handler->ImportedMetadataPath(update.name).c_str());
621 LoadAllPlugIns(
false);
624 g_Platform->HideBusySpinner();
644 pivp.
lat_min = tvp.GetBBox().GetMinLat();
645 pivp.
lat_max = tvp.GetBBox().GetMaxLat();
646 pivp.
lon_min = tvp.GetBBox().GetMinLon();
647 pivp.
lon_max = tvp.GetBBox().GetMaxLon();
649 pivp.
bValid = tvp.IsValid();
670 if (gFrame->GetPrimaryCanvas())
686 void OnPluginUtilAction(wxCommandEvent& event);
688 DECLARE_EVENT_TABLE()
692EVT_BUTTON(ID_CMD_BUTTON_PERFORM_ACTION, pluginUtilHandler::OnPluginUtilAction)
697void pluginUtilHandler::OnPluginUtilAction(wxCommandEvent& event) {
698 auto panel =
static_cast<PluginPanel*
>(
event.GetClientData());
701 wxASSERT(plugin_list_panel != 0);
703 auto actionPIC = panel->GetPlugin();
704 wxString name = actionPIC->m_common_name;
707 switch (panel->GetAction()) {
708 case ActionVerb::UPGRADE_TO_MANAGED_VERSION: {
709 auto loader = PluginLoader::GetInstance();
712 std::string pluginName = actionPIC->m_managed_metadata.name;
714 wxLogMessage(
"Installing managed plugin: %s", pluginName.c_str());
716 new GuiDownloader(plugin_list_panel, actionPIC->m_managed_metadata);
717 downloader->run(plugin_list_panel,
false);
721 if (isRegularFile(manifestPath.c_str())) {
723 for (
unsigned i = 0; i < loader->GetPlugInArray()->GetCount(); i += 1) {
724 if (actionPIC->m_managed_metadata.name ==
725 loader->GetPlugInArray()->Item(i)->m_common_name.ToStdString()) {
726 loader->UnLoadPlugIn(i);
732 LoadAllPlugIns(
false);
734 PluginHandler::CleanupFiles(manifestPath,
735 actionPIC->m_managed_metadata.name);
738 plugin_list_panel->SelectByName(name);
743 case ActionVerb::UPDATE_IMPORTED_VERSION:
744 case ActionVerb::UPGRADE_INSTALLED_MANAGED_VERSION:
745 case ActionVerb::REINSTALL_MANAGED_VERSION:
746 case ActionVerb::DOWNGRADE_INSTALLED_MANAGED_VERSION: {
748 auto metaSave = actionPIC->m_managed_metadata;
749 run_update_dialog(plugin_list_panel, actionPIC,
true,
750 metaSave.name.c_str());
754 case ActionVerb::INSTALL_MANAGED_VERSION: {
755 wxLogMessage(
"Installing new managed plugin.");
756 run_update_dialog(plugin_list_panel, actionPIC,
false);
760 case ActionVerb::UNINSTALL_MANAGED_VERSION: {
763 message.Printf(
"%s %s\n", actionPIC->m_managed_metadata.name.c_str(),
764 actionPIC->m_managed_metadata.version.c_str());
765 message += _(
"successfully un-installed");
767 wxLogMessage(
"Uninstalling %s",
768 actionPIC->m_managed_metadata.name.c_str());
771 actionPIC->m_managed_metadata.name);
774 LoadAllPlugIns(
false);
776 OCPNMessageBox(gFrame, message, _(
"Un-Installation complete"),
777 wxICON_INFORMATION | wxOK);
781 case ActionVerb::NOP:
792const wxEventType wxEVT_OCPN_MSG = wxNewEventType();
794OCPN_MsgEvent::OCPN_MsgEvent(wxEventType commandType,
int id)
795 : wxEvent(id, commandType) {}
797OCPN_MsgEvent::~OCPN_MsgEvent() {}
799wxEvent* OCPN_MsgEvent::Clone()
const {
801 newevent->m_MessageID =
804 newevent->m_MessageText = this->m_MessageText.c_str();
813PlugInToolbarToolContainer::PlugInToolbarToolContainer() {
817 bitmap_Rollover_day = NULL;
818 bitmap_Rollover_dusk = NULL;
819 bitmap_Rollover_night = NULL;
822PlugInToolbarToolContainer::~PlugInToolbarToolContainer() {
826 delete bitmap_Rollover_day;
827 delete bitmap_Rollover_dusk;
828 delete bitmap_Rollover_night;
839#if !defined(__ANDROID__) && defined(OCPN_USE_CURL)
840EVT_CURL_END_PERFORM(CurlThreadId, PlugInManager::OnEndPerformCurlDownload)
841EVT_CURL_DOWNLOAD(CurlThreadId, PlugInManager::OnCurlDownload)
845static
void event_message_box(const wxString& msg) {
846 OCPNMessageBox(NULL, msg, wxString(_(
"OpenCPN Info")),
847 wxICON_INFORMATION | wxOK, 0);
853 if (!pic->m_toolbox_panel) NotifySetupOptionsPlugin(pic);
858PlugInManager::PlugInManager(
MyFrame* parent) {
859#if !defined(__ANDROID__) && defined(OCPN_USE_CURL)
860 m_pCurlThread = NULL;
866 MyFrame* pFrame = GetParentFrame();
868 m_plugin_menu_item_id_next = CanvasMenuHandler::GetNextContextMenuId();
869 m_plugin_tool_id_next = pFrame->GetNextToolbarToolId();
882 new wxRadioBox(pFrame, -1,
"", wxPoint(0, 0), wxSize(-1, -1), as);
888#if !defined(__ANDROID__) && defined(OCPN_USE_CURL)
890 m_last_online =
false;
891 m_last_online_chk = -1;
896 m_blacklist = blacklist_factory();
897 m_blacklist_ui = std::unique_ptr<BlacklistUI>(
new BlacklistUI());
899 wxDEFINE_EVENT(EVT_JSON_TO_ALL_PLUGINS,
ObservedEvt);
901 EVT_JSON_TO_ALL_PLUGINS);
902 Bind(EVT_JSON_TO_ALL_PLUGINS, [&](
ObservedEvt& ev) {
903 auto json = std::static_pointer_cast<const wxJSONValue>(ev.
GetSharedPtr());
904 SendJSONMessageToAllPlugins(ev.GetString(), *json);
907 wxDEFINE_EVENT(EVT_LEGINFO_TO_ALL_PLUGINS,
ObservedEvt);
909 EVT_LEGINFO_TO_ALL_PLUGINS);
910 Bind(EVT_LEGINFO_TO_ALL_PLUGINS, [&](
ObservedEvt& ev) {
911 auto ptr = UnpackEvtPointer<ActiveLegDat>(ev);
912 SendActiveLegInfoToAllPlugIns(ptr.get());
915 HandlePluginLoaderEvents();
921 m_new_msgtype_lstnr.
Init(NavMsgBus::GetInstance().new_msg_event,
924PlugInManager::~PlugInManager() {
925#if !defined(__ANDROID__) && defined(OCPN_USE_CURL)
926 wxCurlBase::Shutdown();
928 delete m_utilHandler;
931void PlugInManager::InitCommListeners() {
935 auto& msgbus = NavMsgBus::GetInstance();
938 m_listener_SignalK.
Listen(sk_msg,
this, EVT_SIGNALK);
945void PlugInManager::OnNewMessageType() {
946 for (
auto msg_key :
NavMsgBus::GetInstance().GetActiveMessages()) {
947 if (m_0183_listeners.find(msg_key) != m_0183_listeners.end())
continue;
948 if (msg_key.find(
"::") == std::string::npos)
continue;
950 if (key_parts.size() < 2)
continue;
955 m_0183_listeners[msg_key] = std::move(ol);
960 assert(n0183_msg->bus == NavAddr::Bus::N0183);
961 const std::string& payload = n0183_msg->payload;
963 if (payload[0] ==
'$') {
964 const auto& drivers = CommDriverRegistry::GetInstance().
GetDrivers();
965 auto& target_driver =
FindDriver(drivers, n0183_msg->source->iface);
969 bool passes_input_filter =
true;
973 passes_input_filter =
974 params.SentencePassesFilter(payload.c_str(), FILTER_INPUT);
977 }
else if (payload[0] ==
'!') {
978 SendAISSentenceToAllPlugIns(payload.c_str());
983 g_ownshipMMSI_SK = sK_msg->context_self;
988 std::string msgTerminated = sK_msg->raw_message;
991 int errors = jsonReader.
Parse(msgTerminated, &root);
992 if (errors == 0) SendJSONMessageToAllPlugins(
"OCPN_CORE_SIGNALK", root);
1001wxDEFINE_EVENT(EVT_PLUGMGR_ROUTEMAN_MSG,
ObservedEvt);
1002wxDEFINE_EVENT(EVT_BLACKLISTED_PLUGIN, wxCommandEvent);
1003wxDEFINE_EVENT(EVT_LOAD_DIRECTORY, wxCommandEvent);
1004wxDEFINE_EVENT(EVT_LOAD_PLUGIN, wxCommandEvent);
1005wxDEFINE_EVENT(EVT_PLUGIN_UNLOAD, wxCommandEvent);
1006wxDEFINE_EVENT(EVT_PLUGLIST_CHANGE, wxCommandEvent);
1007wxDEFINE_EVENT(EVT_UPDATE_CHART_TYPES, wxCommandEvent);
1008wxDEFINE_EVENT(EVT_PLUGIN_LOADALL_FINALIZE, wxCommandEvent);
1010void PlugInManager::HandlePluginLoaderEvents() {
1011 auto loader = PluginLoader::GetInstance();
1013 loader->SetOnActivateCb(
1015 loader->SetOnDeactivateCb(
1018 evt_pluglist_change_listener.
Listen(loader->evt_pluglist_change,
this,
1019 EVT_PLUGLIST_CHANGE);
1020 Bind(EVT_PLUGLIST_CHANGE, [&](wxCommandEvent&) {
1025 evt_load_directory_listener.
Listen(loader->evt_load_directory,
this,
1026 EVT_LOAD_DIRECTORY);
1027 Bind(EVT_LOAD_DIRECTORY, [&](wxCommandEvent&) {
1028 pConfig->SetPath(
"/PlugIns/");
1029 SetPluginOrder(pConfig->Read(
"PluginOrder", wxEmptyString));
1032 evt_load_plugin_listener.
Listen(loader->evt_load_plugin,
this,
1034 Bind(EVT_LOAD_PLUGIN, [&](wxCommandEvent& ev) {
1039 evt_update_chart_types_listener.
Listen(loader->evt_update_chart_types,
this,
1040 EVT_UPDATE_CHART_TYPES);
1041 Bind(EVT_UPDATE_CHART_TYPES,
1042 [&](wxCommandEvent& ev) { UpDateChartDataTypes(); });
1044 evt_plugin_loadall_finalize_listener.
Listen(
1045 loader->evt_plugin_loadall_finalize,
this, EVT_PLUGIN_LOADALL_FINALIZE);
1046 Bind(EVT_PLUGIN_LOADALL_FINALIZE,
1047 [&](wxCommandEvent& ev) { FinalizePluginLoadall(); });
1051 EVT_PLUGMGR_ROUTEMAN_MSG);
1053 auto pTarget = UnpackEvtPointer<AisTargetData>(ev);
1054 SendAisJsonMessage(pTarget);
1056 Bind(EVT_PLUGMGR_ROUTEMAN_MSG, [&](
ObservedEvt& ev) {
1057 auto msg = UnpackEvtPointer<wxJSONValue>(ev);
1058 SendJSONMessageToAllPlugins(ev.GetString(), *msg);
1066wxDEFINE_EVENT(EVT_DOWNLOAD_FAILED, wxCommandEvent);
1067wxDEFINE_EVENT(EVT_DOWNLOAD_OK, wxCommandEvent);
1069void PlugInManager::HandlePluginHandlerEvents() {
1070 auto loader = PluginLoader::GetInstance();
1072 evt_download_failed_listener.
Listen(loader->evt_update_chart_types,
this,
1073 EVT_DOWNLOAD_FAILED);
1074 Bind(EVT_DOWNLOAD_FAILED, [&](wxCommandEvent& ev) {
1075 wxString message = _(
"Please check system log for more info.");
1076 OCPNMessageBox(gFrame, message, _(
"Installation error"),
1077 wxICON_ERROR | wxOK | wxCENTRE);
1080 evt_download_ok_listener.
Listen(loader->evt_update_chart_types,
this,
1082 Bind(EVT_DOWNLOAD_OK, [&](wxCommandEvent& ev) {
1083 wxString message(ev.GetString());
1084 message += _(
" successfully installed from cache");
1085 OCPNMessageBox(gFrame, message, _(
"Installation complete"),
1086 wxICON_INFORMATION | wxOK | wxCENTRE);
1090bool PlugInManager::CallLateInit() {
1093 auto plugin_array = PluginLoader::GetInstance()->
GetPlugInArray();
1094 for (
unsigned int i = 0; i < plugin_array->GetCount(); i++) {
1097 switch (pic->m_api_version) {
1110 ProcessLateInit(pic);
1120 wxString msg(
"PlugInManager: Calling LateInit PlugIn: ");
1125 if (ppi) ppi->LateInit();
1134 if (gFrame->GetPrimaryCanvas()->GetglCanvas()) {
1135 gFrame->GetPrimaryCanvas()->GetglCanvas()->SendJSONConfigMessage();
1136 SendS52ConfigToAllPlugIns(
true);
1151 for (
unsigned int i = 0; i < m_PlugInToolbarTools.GetCount(); i++) {
1154 if (pttc->m_pplugin == pic->m_pplugin) {
1155 m_PlugInToolbarTools.Remove(pttc);
1161 for (
unsigned int i = 0; i < m_PlugInMenuItems.GetCount(); i++) {
1163 if (pimis->m_pplugin == pic->m_pplugin) {
1164 m_PlugInMenuItems.Remove(pimis);
1170bool PlugInManager::IsAnyPlugInChartEnabled() {
1173 auto plugin_array = PluginLoader::GetInstance()->
GetPlugInArray();
1174 for (
unsigned int i = 0; i < plugin_array->GetCount(); i++) {
1176 if (pic->m_enabled && pic->m_init_state) {
1185void PlugInManager::UpdateManagedPlugins() {
1187 PluginLoader::GetInstance()->
SortPlugins(ComparePlugins);
1190 g_options->itemBoxSizerPanelPlugins->Layout();
1193bool PlugInManager::UpDateChartDataTypes() {
1197 auto plugin_array = PluginLoader::GetInstance()->
GetPlugInArray();
1198 for (
unsigned int i = 0; i < plugin_array->GetCount(); i++) {
1201 if (pic->m_init_state) {
1209 if (bret)
ChartData->UpdateChartClassDescriptorArray();
1214void PlugInManager::FinalizePluginLoadall() {
1218 SetColorSchemeForAllPlugIns(global_color_scheme);
1221 SendBaseConfigToAllPlugIns();
1222 SendS52ConfigToAllPlugIns(
true);
1223 SendSKConfigToAllPlugIns();
1228 if (gFrame->GetPrimaryCanvas()->GetglCanvas())
1229 gFrame->GetPrimaryCanvas()->GetglCanvas()->SendJSONConfigMessage();
1237void PlugInManager::SetPluginOrder(wxString serialized_names) {
1238 m_plugin_order.Empty();
1239 wxStringTokenizer tokenizer(serialized_names,
";");
1240 while (tokenizer.HasMoreTokens()) {
1241 m_plugin_order.Add(tokenizer.GetNextToken());
1245wxString PlugInManager::GetPluginOrder() {
1246 wxString plugins = wxEmptyString;
1247 auto plugin_array = PluginLoader::GetInstance()->
GetPlugInArray();
1248 for (
unsigned int i = 0; i < plugin_array->GetCount(); i++) {
1249 plugins.Append(plugin_array->Item(i)->m_common_name);
1250 if (i < plugin_array->GetCount() - 1) plugins.Append(
';');
1255bool PlugInManager::UpdateConfig() {
1259 auto plugin_array = PluginLoader::GetInstance()->
GetPlugInArray();
1260 for (
unsigned int i = 0; i < plugin_array->GetCount(); i++) {
1264 wxString config_section = (_T (
"/PlugIns/" ));
1266 pConfig->SetPath(config_section);
1267 pConfig->Write(_T (
"bEnabled" ), pic->m_enabled);
1274void PlugInManager::ShowDeferredBlacklistMessages() {
1275 m_blacklist_ui->show_deferred_messages();
1278bool PlugInManager::CheckBlacklistedPlugin(
const PluginMetadata plugin) {
1280 return CheckBlacklistedPlugin(wxString(plugin.name), v.major, v.minor);
1283bool PlugInManager::CheckBlacklistedPlugin(
opencpn_plugin* plugin) {
1288 wxString name = wxString::FromAscii(
typeid(*plugin).name());
1289 name.Replace(
"class ", wxEmptyString);
1291 const std::type_info& ti =
typeid(*plugin);
1293 char* realname = abi::__cxa_demangle(ti.name(), 0, 0, &status);
1294 wxString name = wxString::FromAscii(realname);
1297 return CheckBlacklistedPlugin(name, major, minor);
1300bool PlugInManager::CheckBlacklistedPlugin(wxString name,
int major,
1302 auto block_status = m_blacklist->get_status(name.ToStdString(), major, minor);
1303 if (block_status == plug_status::unblocked)
return true;
1304 plug_data data(name.ToStdString(), major, minor);
1305 auto msg = m_blacklist->get_message(block_status, data);
1306 m_blacklist_ui->message(msg);
1310bool PlugInManager::RenderAllCanvasOverlayPlugIns(
ocpnDC& dc,
1314 auto plugin_array = PluginLoader::GetInstance()->
GetPlugInArray();
1315 for (
unsigned int i = 0; i < plugin_array->GetCount(); i++) {
1317 if (pic->m_enabled && pic->m_init_state) {
1321 wxDC* pdc = dc.GetDC();
1324 switch (pic->m_api_version) {
1326 if (priority > 0)
break;
1333 if (priority > 0)
break;
1336 if (ppi) ppi->RenderOverlay(*pdc, &pivp);
1347 if (priority > 0)
break;
1350 if (ppi) ppi->RenderOverlay(*pdc, &pivp);
1355 if (priority > 0)
break;
1359 ppi->RenderOverlay(*pdc, &pivp);
1371 if (priority <= 0) {
1375 ppi->RenderOverlay(*pdc, &pivp);
1391 if (pic->
m_cap_flag & WANTS_OPENGL_OVERLAY_CALLBACK)
continue;
1393 if ((m_cached_overlay_bm.GetWidth() != vp.
pix_width) ||
1394 (m_cached_overlay_bm.GetHeight() != vp.
pix_height))
1398 mdc.SelectObject(m_cached_overlay_bm);
1399 mdc.SetBackground(*wxBLACK_BRUSH);
1402 bool b_rendered =
false;
1404 switch (pic->m_api_version) {
1406 if (priority > 0)
break;
1413 if (priority > 0)
break;
1416 if (ppi) b_rendered = ppi->RenderOverlay(mdc, &pivp);
1427 if (priority > 0)
break;
1430 if (ppi) b_rendered = ppi->RenderOverlay(mdc, &pivp);
1435 if (priority > 0)
break;
1439 b_rendered = ppi->RenderOverlay(mdc, &pivp);
1452 if (priority <= 0) {
1456 b_rendered = ppi->RenderOverlay(mdc, &pivp);
1463 mdc, &pivp, g_canvasConfig, priority);
1472 mdc.SelectObject(wxNullBitmap);
1475 wxMask* p_msk =
new wxMask(m_cached_overlay_bm, wxColour(0, 0, 0));
1476 m_cached_overlay_bm.SetMask(p_msk);
1478 dc.DrawBitmap(m_cached_overlay_bm, 0, 0,
true);
1481 }
else if (pic->
m_cap_flag & WANTS_OPENGL_OVERLAY_CALLBACK) {
1489bool PlugInManager::RenderAllGLCanvasOverlayPlugIns(wxGLContext* pcontext,
1493 auto plugin_array = PluginLoader::GetInstance()->
GetPlugInArray();
1494 for (
unsigned int i = 0; i < plugin_array->GetCount(); i++) {
1496 if (pic->m_enabled && pic->m_init_state) {
1497 if (pic->
m_cap_flag & WANTS_OPENGL_OVERLAY_CALLBACK) {
1500 switch (pic->m_api_version) {
1502 if (priority > 0)
break;
1505 if (ppi) ppi->RenderGLOverlay(pcontext, &pivp);
1517 if (priority > 0)
break;
1525 if (priority > 0)
break;
1542 if (priority <= 0) {
1567void PlugInManager::SendViewPortToRequestingPlugIns(
ViewPort& vp) {
1568 auto plugin_array = PluginLoader::GetInstance()->
GetPlugInArray();
1569 for (
unsigned int i = 0; i < plugin_array->GetCount(); i++) {
1571 if (pic->m_enabled && pic->m_init_state) {
1580void NotifySetupOptionsPlugin(
const PlugInData* pd) {
1581 PluginLoader::GetInstance()->NotifySetupOptionsPlugin(pd);
1584void PlugInManager::NotifySetupOptions() {
1585 auto plugin_array = PluginLoader::GetInstance()->
GetPlugInArray();
1586 for (
unsigned int i = 0; i < plugin_array->GetCount(); i++) {
1588 NotifySetupOptionsPlugin(pic);
1593 int ok_apply_cancel) {
1594 if (pic->m_enabled && pic->m_init_state) {
1597 auto loader = PluginLoader::GetInstance();
1604void PlugInManager::CloseAllPlugInPanels(
int ok_apply_cancel) {
1605 auto plugin_array = PluginLoader::GetInstance()->
GetPlugInArray();
1606 for (
unsigned int i = 0; i < plugin_array->GetCount(); i++) {
1609 ClosePlugInPanel(pic, ok_apply_cancel);
1614int PlugInManager::AddCanvasContextMenuItemPIM(wxMenuItem* pitem,
1619 pmic->pmenu_item = pitem;
1620 pmic->m_pplugin = pplugin;
1621 pmic->id = pitem->GetId() == wxID_SEPARATOR ? wxID_SEPARATOR
1622 : m_plugin_menu_item_id_next;
1624 pmic->b_grey =
false;
1625 pmic->m_in_menu = name;
1626 pmic->extended = is_extended;
1628 m_PlugInMenuItems.Add(pmic);
1630 m_plugin_menu_item_id_next++;
1635void PlugInManager::RemoveCanvasContextMenuItem(
int item,
const char* name) {
1636 for (
unsigned int i = 0; i < m_PlugInMenuItems.GetCount(); i++) {
1639 if (pimis->id == item) {
1640 m_PlugInMenuItems.Remove(pimis);
1648void PlugInManager::SetCanvasContextMenuItemViz(
int item,
bool viz,
1650 for (
unsigned int i = 0; i < m_PlugInMenuItems.GetCount(); i++) {
1653 if (pimis->id == item && !strcmp(name, pimis->m_in_menu)) {
1661void PlugInManager::SetCanvasContextMenuItemGrey(
int item,
bool grey,
1663 for (
unsigned int i = 0; i < m_PlugInMenuItems.GetCount(); i++) {
1666 if (pimis->id == item && !strcmp(name, pimis->m_in_menu)) {
1667 pimis->b_grey = grey;
1674void PlugInManager::SendResizeEventToAllPlugIns(
int x,
int y) {
1675 auto plugin_array = PluginLoader::GetInstance()->
GetPlugInArray();
1676 for (
unsigned int i = 0; i < plugin_array->GetCount(); i++) {
1678 if (pic->m_enabled && pic->m_init_state)
1683void PlugInManager::SetColorSchemeForAllPlugIns(ColorScheme cs) {
1684 auto plugin_array = PluginLoader::GetInstance()->
GetPlugInArray();
1685 for (
unsigned int i = 0; i < plugin_array->GetCount(); i++) {
1687 if (pic->m_enabled && pic->m_init_state)
1692void PlugInManager::PrepareAllPluginContextMenus() {
1693 int canvasIndex = gFrame->GetCanvasIndexUnderMouse();
1694 if (canvasIndex < 0)
return;
1696 auto plugin_array = PluginLoader::GetInstance()->
GetPlugInArray();
1697 for (
unsigned int i = 0; i < plugin_array->GetCount(); i++) {
1699 if (pic->m_enabled && pic->m_init_state) {
1701 switch (pic->m_api_version) {
1721void PlugInManager::SendSKConfigToAllPlugIns() {
1724 v[
"self"] = g_ownshipMMSI_SK;
1728 SendMessageToAllPlugins(wxString(
"OCPN_CORE_SIGNALK"), out);
1731void PlugInManager::SendBaseConfigToAllPlugIns() {
1734 v[
"OpenCPN Version Major"] = VERSION_MAJOR;
1735 v[
"OpenCPN Version Minor"] = VERSION_MINOR;
1736 v[
"OpenCPN Version Patch"] = VERSION_PATCH;
1737 v[
"OpenCPN Version Date"] = VERSION_DATE;
1738 v[
"OpenCPN Version Full"] = VERSION_FULL;
1742 v[
"OpenCPN Toolbar Width"] =
g_MainToolbar->GetToolbarRect().width;
1743 v[
"OpenCPN Toolbar Height"] =
g_MainToolbar->GetToolbarRect().height;
1744 v[
"OpenCPN Toolbar PosnX"] =
g_MainToolbar->GetToolbarRect().x;
1745 v[
"OpenCPN Toolbar PosnY"] =
g_MainToolbar->GetToolbarRect().y;
1749 v[
"OpenCPN Zoom Mod Vector"] = g_chart_zoom_modifier_vector;
1750 v[
"OpenCPN Zoom Mod Other"] = g_chart_zoom_modifier_raster;
1751 v[
"OpenCPN Scale Factor Exp"] =
1752 g_Platform->GetChartScaleFactorExp(g_ChartScaleFactor);
1760 SendMessageToAllPlugins(wxString(
"OpenCPN Config"), out);
1763void PlugInManager::SendS52ConfigToAllPlugIns(
bool bReconfig) {
1766 v[
"OpenCPN Version Major"] = VERSION_MAJOR;
1767 v[
"OpenCPN Version Minor"] = VERSION_MINOR;
1768 v[
"OpenCPN Version Patch"] = VERSION_PATCH;
1769 v[
"OpenCPN Version Date"] = VERSION_DATE;
1770 v[
"OpenCPN Version Full"] = VERSION_FULL;
1778 v[
"OpenCPN S52PLIB ShowAnchorConditions"] = ps52plib->GetAnchorOn();
1779 v[
"OpenCPN S52PLIB ShowQualityOfData"] = ps52plib->GetQualityOfData();
1784 v[
"OpenCPN S52PLIB MetaDisplay"] = ps52plib->m_bShowMeta;
1785 v[
"OpenCPN S52PLIB DeclutterText"] = ps52plib->m_bDeClutterText;
1786 v[
"OpenCPN S52PLIB ShowNationalText"] = ps52plib->m_bShowNationalTexts;
1787 v[
"OpenCPN S52PLIB ShowImportantTextOnly"] =
1788 ps52plib->m_bShowS57ImportantTextOnly;
1789 v[
"OpenCPN S52PLIB UseSCAMIN"] = ps52plib->m_bUseSCAMIN;
1790 v[
"OpenCPN S52PLIB UseSUPER_SCAMIN"] = ps52plib->m_bUseSUPER_SCAMIN;
1791 v[
"OpenCPN S52PLIB SymbolStyle"] = ps52plib->m_nSymbolStyle;
1792 v[
"OpenCPN S52PLIB BoundaryStyle"] = ps52plib->m_nBoundaryStyle;
1793 v[
"OpenCPN S52PLIB ColorShades"] = S52_getMarinerParam(S52_MAR_TWO_SHADES);
1794 v[
"OpenCPN S52PLIB Safety Depth"] =
1795 (double)S52_getMarinerParam(S52_MAR_SAFETY_DEPTH);
1796 v[
"OpenCPN S52PLIB Shallow Contour"] =
1797 (double)S52_getMarinerParam(S52_MAR_SHALLOW_CONTOUR);
1798 v[
"OpenCPN S52PLIB Deep Contour"] =
1799 (double)S52_getMarinerParam(S52_MAR_DEEP_CONTOUR);
1803 v[
"OpenCPN S52PLIB GlobalReconfig"] = bReconfig;
1808 SendMessageToAllPlugins(wxString(
"OpenCPN Config"), out);
1811void PlugInManager::NotifyAuiPlugIns() {
1812 auto plugin_array = PluginLoader::GetInstance()->
GetPlugInArray();
1813 for (
unsigned int i = 0; i < plugin_array->GetCount(); i++) {
1815 if (pic->m_enabled && pic->m_init_state &&
1821int PlugInManager::AddToolbarTool(wxString label, wxBitmap* bitmap,
1822 wxBitmap* bmpRollover, wxItemKind kind,
1823 wxString shortHelp, wxString longHelp,
1824 wxObject* clientData,
int position,
1827 pttc->label = label;
1829 if (!bitmap->IsOk()) {
1831 pttc->bitmap_day =
new wxBitmap(style->GetIcon(
"default_pi"));
1834 pttc->bitmap_day =
new wxBitmap(*bitmap);
1835 pttc->bitmap_day->UnShare();
1838 if (!bmpRollover->IsOk()) {
1840 pttc->bitmap_Rollover_day =
new wxBitmap(style->GetIcon(
"default_pi"));
1843 pttc->bitmap_Rollover_day =
new wxBitmap(*bmpRollover);
1844 pttc->bitmap_Rollover_day->UnShare();
1847 pttc->bitmap_dusk = BuildDimmedToolBitmap(pttc->bitmap_day, 128);
1848 pttc->bitmap_night = BuildDimmedToolBitmap(pttc->bitmap_day, 32);
1849 pttc->bitmap_Rollover_dusk =
1850 BuildDimmedToolBitmap(pttc->bitmap_Rollover_day, 128);
1851 pttc->bitmap_Rollover_night =
1852 BuildDimmedToolBitmap(pttc->bitmap_Rollover_day, 32);
1855 pttc->shortHelp = shortHelp;
1856 pttc->longHelp = longHelp;
1857 pttc->clientData = clientData;
1858 pttc->position = position;
1859 pttc->m_pplugin = pplugin;
1860 pttc->tool_sel = tool_sel;
1862 pttc->b_toggle =
false;
1863 pttc->id = m_plugin_tool_id_next;
1865 m_PlugInToolbarTools.Add(pttc);
1867 m_plugin_tool_id_next++;
1872int PlugInManager::AddToolbarTool(wxString label, wxString SVGfile,
1873 wxString SVGRolloverfile,
1874 wxString SVGToggledfile, wxItemKind kind,
1875 wxString shortHelp, wxString longHelp,
1876 wxObject* clientData,
int position,
1879 pttc->label = label;
1881 pttc->pluginNormalIconSVG = SVGfile;
1882 pttc->pluginRolloverIconSVG = SVGRolloverfile;
1883 pttc->pluginToggledIconSVG = SVGToggledfile;
1888 pttc->bitmap_day =
new wxBitmap(style->GetIcon(
"default_pi"));
1889 pttc->bitmap_dusk = BuildDimmedToolBitmap(pttc->bitmap_day, 128);
1890 pttc->bitmap_night = BuildDimmedToolBitmap(pttc->bitmap_day, 32);
1891 pttc->bitmap_Rollover_day =
new wxBitmap(*pttc->bitmap_day);
1892 pttc->bitmap_Rollover_dusk =
1893 BuildDimmedToolBitmap(pttc->bitmap_Rollover_day, 128);
1894 pttc->bitmap_Rollover_night =
1895 BuildDimmedToolBitmap(pttc->bitmap_Rollover_day, 32);
1898 pttc->shortHelp = shortHelp;
1899 pttc->longHelp = longHelp;
1900 pttc->clientData = clientData;
1901 pttc->position = position;
1902 pttc->m_pplugin = pplugin;
1903 pttc->tool_sel = tool_sel;
1905 pttc->b_toggle =
false;
1906 pttc->id = m_plugin_tool_id_next;
1908 m_PlugInToolbarTools.Add(pttc);
1910 m_plugin_tool_id_next++;
1915void PlugInManager::RemoveToolbarTool(
int tool_id) {
1916 for (
unsigned int i = 0; i < m_PlugInToolbarTools.GetCount(); i++) {
1919 if (pttc->id == tool_id) {
1920 m_PlugInToolbarTools.Remove(pttc);
1926 pParent->RequestNewToolbars();
1929void PlugInManager::SetToolbarToolViz(
int item,
bool viz) {
1930 for (
unsigned int i = 0; i < m_PlugInToolbarTools.GetCount(); i++) {
1933 if (pttc->id == item) {
1935 pParent->RequestNewToolbars();
1942void PlugInManager::SetToolbarItemState(
int item,
bool toggle) {
1943 for (
unsigned int i = 0; i < m_PlugInToolbarTools.GetCount(); i++) {
1946 if (pttc->id == item) {
1947 pttc->b_toggle = toggle;
1948 pParent->SetMasterToolbarItemState(item, toggle);
1955void PlugInManager::SetToolbarItemBitmaps(
int item, wxBitmap* bitmap,
1956 wxBitmap* bmpRollover) {
1957 for (
unsigned int i = 0; i < m_PlugInToolbarTools.GetCount(); i++) {
1960 if (pttc->id == item) {
1961 delete pttc->bitmap_day;
1962 delete pttc->bitmap_dusk;
1963 delete pttc->bitmap_night;
1964 delete pttc->bitmap_Rollover_day;
1966 if (!bitmap->IsOk()) {
1968 pttc->bitmap_day =
new wxBitmap(style->GetIcon(
"default_pi"));
1971 pttc->bitmap_day =
new wxBitmap(*bitmap);
1972 pttc->bitmap_day->UnShare();
1975 if (!bmpRollover->IsOk()) {
1977 pttc->bitmap_Rollover_day =
1978 new wxBitmap(style->GetIcon(
"default_pi"));
1981 pttc->bitmap_Rollover_day =
new wxBitmap(*bmpRollover);
1982 pttc->bitmap_Rollover_day->UnShare();
1985 pttc->bitmap_dusk = BuildDimmedToolBitmap(pttc->bitmap_day, 128);
1986 pttc->bitmap_night = BuildDimmedToolBitmap(pttc->bitmap_day, 32);
1988 pParent->SetToolbarItemBitmaps(item, pttc->bitmap_day,
1989 pttc->bitmap_Rollover_day);
1996void PlugInManager::SetToolbarItemBitmaps(
int item, wxString SVGfile,
1997 wxString SVGfileRollover,
1998 wxString SVGfileToggled) {
1999 for (
unsigned int i = 0; i < m_PlugInToolbarTools.GetCount(); i++) {
2002 if (pttc->id == item) {
2003 pttc->pluginNormalIconSVG = SVGfile;
2004 pttc->pluginRolloverIconSVG = SVGfileRollover;
2005 pttc->pluginToggledIconSVG = SVGfileToggled;
2006 pParent->SetToolbarItemSVG(item, pttc->pluginNormalIconSVG,
2007 pttc->pluginRolloverIconSVG,
2008 pttc->pluginToggledIconSVG);
2016 for (
unsigned int i = 0; i < m_PlugInToolbarTools.GetCount(); i++) {
2018 if (
id == pc->id)
return pc->m_pplugin;
2024wxString PlugInManager::GetToolOwnerCommonName(
const int id) {
2027 auto plugin_array = PluginLoader::GetInstance()->
GetPlugInArray();
2028 for (
unsigned int i = 0; i < plugin_array->GetCount(); i++) {
2030 if (pic && (pic->m_pplugin == ppi))
return pic->
m_common_name;
2034 return wxEmptyString;
2037wxString PlugInManager::GetLastError() {
return m_last_error_string; }
2039wxBitmap* PlugInManager::BuildDimmedToolBitmap(wxBitmap* pbmp_normal,
2040 unsigned char dim_ratio) {
2041 wxImage img_dup = pbmp_normal->ConvertToImage();
2043 if (!img_dup.IsOk())
return NULL;
2045 if (dim_ratio < 200) {
2047 int gimg_width = img_dup.GetWidth();
2048 int gimg_height = img_dup.GetHeight();
2050 double factor = (double)(dim_ratio) / 256.0;
2052 for (
int iy = 0; iy < gimg_height; iy++) {
2053 for (
int ix = 0; ix < gimg_width; ix++) {
2054 if (!img_dup.IsTransparent(ix, iy)) {
2055 wxImage::RGBValue rgb(img_dup.GetRed(ix, iy),
2056 img_dup.GetGreen(ix, iy),
2057 img_dup.GetBlue(ix, iy));
2058 wxImage::HSVValue hsv = wxImage::RGBtoHSV(rgb);
2059 hsv.value = hsv.value * factor;
2060 wxImage::RGBValue nrgb = wxImage::HSVtoRGB(hsv);
2061 img_dup.SetRGB(ix, iy, nrgb.red, nrgb.green, nrgb.blue);
2067 wxBitmap* ptoolBarBitmap;
2070 wxBitmap tbmp(img_dup.GetWidth(), img_dup.GetHeight(), -1);
2072 dwxdc.SelectObject(tbmp);
2074 ptoolBarBitmap =
new wxBitmap(img_dup, (wxDC&)dwxdc);
2076 ptoolBarBitmap =
new wxBitmap(img_dup);
2080 return ptoolBarBitmap;
2083wxArrayString PlugInManager::GetPlugInChartClassNameArray() {
2084 wxArrayString array;
2085 auto plugin_array = PluginLoader::GetInstance()->
GetPlugInArray();
2086 for (
unsigned int i = 0; i < plugin_array->GetCount(); i++) {
2088 if (pic && pic->m_enabled && pic->m_init_state &&
2093 for (
unsigned int j = 0; j < carray.GetCount(); j++) {
2094 array.Add(carray[j]);
2102 while (j < array.GetCount()) {
2103 wxString test = array[j];
2104 unsigned int k = j + 1;
2105 while (k < array.GetCount()) {
2106 if (test == array[k]) {
2124#define DISABLED_SETTINGS_MSG \
2125 _("These settings might destabilize OpenCPN and are by default disabled." \
2126 " To despite the dangers enable them manually add a CatalogExpert=1" \
2127 " line in the [PlugIns] section in the configuration file.")
2132CatalogMgrPanel::CatalogMgrPanel(wxWindow* parent)
2133 : wxPanel(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize),
2135 wxBoxSizer* topSizer =
new wxBoxSizer(wxVERTICAL);
2138 topSizer->Add(
new wxStaticLine(
this), 0, wxGROW | wxLEFT | wxRIGHT, 4);
2140 wxStaticBox* itemStaticBoxSizer4Static =
2141 new wxStaticBox(
this, wxID_ANY, _(
"Plugin Catalog"));
2142 wxStaticBoxSizer* itemStaticBoxSizer4 =
2143 new wxStaticBoxSizer(itemStaticBoxSizer4Static, wxVERTICAL);
2144 topSizer->Add(itemStaticBoxSizer4, 1, wxEXPAND | wxALL, 2);
2148 m_catalogText =
new wxStaticText(
this, wxID_STATIC,
"");
2149 itemStaticBoxSizer4->Add(m_catalogText,
2150 wxSizerFlags().Border().Proportion(1));
2151 m_catalogText->SetLabel(GetCatalogText(
false));
2154 wxBoxSizer* rowSizer2 =
new wxBoxSizer(wxHORIZONTAL);
2155 itemStaticBoxSizer4->Add(rowSizer2,
2156 wxSizerFlags().Expand().Border().Proportion(1));
2158 m_updateButton =
new wxButton(
this, wxID_ANY, _(
"Update Plugin Catalog"),
2159 wxDefaultPosition, wxDefaultSize, 0);
2160 rowSizer2->Add(m_updateButton, 0, wxALIGN_LEFT);
2161 m_updateButton->Bind(wxEVT_COMMAND_BUTTON_CLICKED,
2162 &CatalogMgrPanel::OnUpdateButton,
this);
2163 rowSizer2->AddSpacer(4 * GetCharWidth());
2164 m_tarballButton =
new wxButton(
this, wxID_ANY, _(
"Import plugin..."),
2165 wxDefaultPosition, wxDefaultSize, 0);
2166 rowSizer2->Add(m_tarballButton, 0, wxALIGN_LEFT | wxLEFT, 2 * GetCharWidth());
2167 m_tarballButton->Bind(wxEVT_COMMAND_BUTTON_CLICKED,
2168 &CatalogMgrPanel::OnTarballButton,
this);
2170 rowSizer2->AddSpacer(4 * GetCharWidth());
2171 m_adv_button =
new wxButton(
this, wxID_ANY, _(
"Settings..."),
2172 wxDefaultPosition, wxDefaultSize, 0);
2174 if (expert.Get(
false)) {
2175 m_adv_button->Bind(wxEVT_COMMAND_BUTTON_CLICKED,
2176 &CatalogMgrPanel::OnPluginSettingsButton,
this);
2178 m_adv_button->Bind(wxEVT_COMMAND_BUTTON_CLICKED, [&](wxCommandEvent&) {
2179 wxMessageBox(DISABLED_SETTINGS_MSG, _(
"Disabled"));
2182 rowSizer2->AddSpacer(4 * GetCharWidth());
2183 rowSizer2->Add(m_adv_button, 0, wxALIGN_LEFT);
2185 SetUpdateButtonLabel();
2188 wxBoxSizer* rowSizer3 =
new wxBoxSizer(wxHORIZONTAL);
2189 itemStaticBoxSizer4->Add(rowSizer3, 0, wxEXPAND | wxALL, 4);
2191 SetMinSize(wxSize(m_parent->GetClientSize().x - (4 * GetCharWidth()), -1));
2195 wxDEFINE_EVENT(EVT_CATALOG_CHANGE, wxCommandEvent);
2196 catalog_listener.Listen(catalog,
this, EVT_CATALOG_CHANGE);
2197 Bind(EVT_CATALOG_CHANGE, [&](wxCommandEvent&) { SetUpdateButtonLabel(); });
2200 SetBackgroundColour(wxColour(0x7c, 0xb0, 0xe9));
2202 if (!expert.Get(
false)) {
2204 new wxButton(
this, wxID_ANY, _(
"Update Plugin Catalog: master"),
2205 wxDefaultPosition, wxDefaultSize, 0);
2206 itemStaticBoxSizer4->Add(m_updateButton, 0, wxALIGN_LEFT);
2207 m_updateButton->Bind(wxEVT_COMMAND_BUTTON_CLICKED,
2208 &CatalogMgrPanel::OnUpdateButton,
this);
2209 SetUpdateButtonLabel();
2210 m_tarballButton = NULL;
2211 m_adv_button = NULL;
2214 m_catalogText =
new wxStaticText(
this, wxID_STATIC, GetCatalogText(
false));
2215 itemStaticBoxSizer4->Add(m_catalogText,
2216 wxSizerFlags().Border(wxALL, 5).Proportion(1));
2219 m_updateButton =
new wxButton(
2220 this, wxID_ANY,
"Update Plugin Catalog:master ",
2221 wxDefaultPosition, wxDefaultSize, 0);
2222 itemStaticBoxSizer4->Add(m_updateButton, 0, wxALIGN_LEFT | wxTOP, 5);
2223 m_updateButton->Bind(wxEVT_COMMAND_BUTTON_CLICKED,
2224 &CatalogMgrPanel::OnUpdateButton,
this);
2225 SetUpdateButtonLabel();
2228 m_adv_button =
new wxButton(
this, wxID_ANY, _(
"Settings..."),
2229 wxDefaultPosition, wxDefaultSize, 0);
2230 itemStaticBoxSizer4->Add(m_adv_button, 0, wxALIGN_LEFT | wxTOP,
2232 m_adv_button->Bind(wxEVT_COMMAND_BUTTON_CLICKED,
2233 &CatalogMgrPanel::OnPluginSettingsButton,
this);
2236 m_tarballButton =
new wxButton(
this, wxID_ANY, _(
"Import plugin..."),
2237 wxDefaultPosition, wxDefaultSize, 0);
2238 itemStaticBoxSizer4->Add(m_tarballButton, 0, wxALIGN_LEFT | wxALL,
2239 2 * GetCharWidth());
2240 m_tarballButton->Bind(wxEVT_COMMAND_BUTTON_CLICKED,
2241 &CatalogMgrPanel::OnTarballButton,
this);
2247CatalogMgrPanel::~CatalogMgrPanel() {
2248 m_updateButton->Unbind(wxEVT_COMMAND_BUTTON_CLICKED,
2249 &CatalogMgrPanel::OnUpdateButton,
this);
2250 if (m_tarballButton)
2251 m_tarballButton->Unbind(wxEVT_COMMAND_BUTTON_CLICKED,
2252 &CatalogMgrPanel::OnTarballButton,
this);
2255static const char*
const DOWNLOAD_REPO_PROTO =
2256 "https://raw.githubusercontent.com/OpenCPN/plugins/@branch@/"
2259void CatalogMgrPanel::OnUpdateButton(wxCommandEvent& event) {
2261 std::string catalog(g_catalog_channel ==
"" ?
"master" : g_catalog_channel);
2262 std::string url(g_catalog_custom_url);
2263 if (catalog !=
"custom") {
2264 url = std::string(DOWNLOAD_REPO_PROTO);
2268 std::string filePath =
2269 wxFileName::CreateTempFileName(
"ocpn_dl").ToStdString();
2271 auto catalogHdlr = CatalogHandler::GetInstance();
2273 g_Platform->ShowBusySpinner();
2274 auto status = catalogHdlr->DownloadCatalog(filePath, url);
2275 g_Platform->HideBusySpinner();
2277 std::string message;
2278 if (status != CatalogHandler::ServerStatus::OK) {
2279 message = _(
"Cannot download data from url");
2280 OCPNMessageBox(
this, message, _(
"OpenCPN Catalog update"),
2281 wxICON_ERROR | wxOK);
2287 if (!AndroidSecureCopyFile(wxString(filePath.c_str()),
2289 wxFileName::GetPathSeparator() +
2290 "ocpn-plugins.xml")) {
2291 OCPNMessageBox(
this, _(
"Unable to copy catalog file"),
2292 _(
"OpenCPN Catalog update"), wxICON_ERROR | wxOK);
2297 if (!wxCopyFile(wxString(filePath.c_str()),
2299 wxFileName::GetPathSeparator() +
"ocpn-plugins.xml")) {
2300 OCPNMessageBox(
this, _(
"Unable to copy catalog file"),
2301 _(
"OpenCPN Catalog update"), wxICON_ERROR | wxOK);
2307 if (catalog ==
"master") {
2309 OCPNMessageBox(
this, _(
"Unable to copy catalog file to cache"),
2310 _(
"OpenCPN Catalog update"), wxICON_ERROR | wxOK);
2316 pConfig->SetPath(
"/PlugIns/");
2317 pConfig->Write(
"LatestCatalogDownloaded", catalog.c_str());
2324 pluginHandler->setMetadata(
"");
2328 auto cataloghdlr = CatalogHandler::GetInstance();
2329 cataloghdlr->ClearCatalogData();
2332 LoadAllPlugIns(
false);
2336 m_catalogText->SetLabel(GetCatalogText(
true));
2339 OCPNMessageBox(
this, _(
"Catalog update successful"),
2340 _(
"OpenCPN Catalog update"), wxICON_INFORMATION | wxOK);
2343void CatalogMgrPanel::OnPluginSettingsButton(wxCommandEvent& event) {
2347 androidDisableRotation();
2350 dialog->ShowModal();
2353 androidEnableRotation();
2357void CatalogMgrPanel::OnTarballButton(wxCommandEvent& event) {
2360 int response = g_Platform->DoFileSelectorDialog(
2361 this, &path, _(
"Select tarball file"), GetImportInitDir(),
"",
2362 "tar files (*.tar.gz)|*.tar.gz|All Files (*.*)|*.*");
2364 if (response != wxID_OK) {
2369 bool ok = handler->ExtractMetadata(path.ToStdString(), metadata);
2373 _(
"Error extracting metadata from tarball (missing metadata.xml?)"),
2374 _(
"OpenCPN Plugin Import Error"));
2378 OCPNMessageBox(
this, _(
"Incompatible import plugin detected."),
2379 _(
"OpenCPN Plugin Import Error"));
2380 handler->Uninstall(metadata.name);
2383 UninstallPlugin(metadata.name);
2384 ok = handler->InstallPlugin(metadata, path.ToStdString());
2386 OCPNMessageBox(
this, _(
"Error extracting import plugin tarball."),
2387 _(
"OpenCPN Plugin Import Error"));
2390 metadata.is_imported =
true;
2392 std::ofstream file(metadata_path);
2395 WARNING_LOG <<
"Error saving metadata file: " << metadata_path
2396 <<
" for imported plugin: " << metadata.name;
2398 LoadAllPlugIns(
false,
true);
2401 wxString ws(_(
"Plugin"));
2402 ws += metadata.name + _(
" successfully imported");
2403 OCPNMessageBox(gFrame, ws, _(
"Installation complete"),
2404 wxICON_INFORMATION | wxOK | wxCENTRE);
2407wxString CatalogMgrPanel::GetCatalogText(
bool updated) {
2409 catalog = updated ? _(
"Active Catalog") : _(
"Last Catalog");
2413 pConfig->SetPath(
"/PlugIns/");
2414 wxString latestCatalog = pConfig->Read(
"LatestCatalogDownloaded",
"default");
2415 catalog += latestCatalog;
2421 std::string date = pluginHandler->GetCatalogData()->date;
2423 catalog += wxString(
" ") + _(
"Last change: ") +
" " + date;
2424 if (!updated) catalog +=
" : " + _(
"Please Update Plugin Catalog.");
2430void CatalogMgrPanel::SetUpdateButtonLabel() {
2431 wxString label = _(
"Update Plugin Catalog");
2433 label += g_catalog_channel ==
"" ?
"master" : g_catalog_channel;
2434 m_updateButton->SetLabel(label);
2438wxString CatalogMgrPanel::GetImportInitDir() {
2440 pConfig->SetPath(
"/PlugIns/");
2441 wxString lastImportDir;
2443 pConfig->Read(
"LatestImportDir", g_Platform->GetWritableDocumentsDir());
2444 if (wxDirExists(lastImportDir)) {
2445 return lastImportDir;
2447 return (g_Platform->GetWritableDocumentsDir());
2456 const wxPoint& pos, const wxSize& size)
2457 : wxScrolledWindow(parent,
id, pos, size, wxTAB_TRAVERSAL | wxVSCROLL),
2458 m_PluginSelected(0) {
2459 m_is_loading.clear();
2460 SetSizer(
new wxBoxSizer(wxVERTICAL));
2461 ReloadPluginPanels();
2464void PluginListPanel::SelectByName(wxString& name) {
2465 for (
auto it = GetChildren().GetFirst(); it; it = it->GetNext()) {
2466 auto pluginPanel =
dynamic_cast<PluginPanel*
>(it->GetData());
2468 if (pluginPanel->GetPluginPtr()->m_common_name.IsSameAs(name)) {
2469 pluginPanel->SetSelected(
true);
2470 pluginPanel->Layout();
2471 SelectPlugin(pluginPanel);
2480 std::vector<const PlugInData*> result;
2481 auto loader = PluginLoader::GetInstance();
2482 for (
size_t i = 0; i < loader->GetPlugInArray()->GetCount(); i++) {
2483 auto const item = loader->GetPlugInArray()->Item(i);
2484 if (item->m_managed_metadata.name.empty()) {
2485 const auto name = item->m_common_name.ToStdString();
2489 result.push_back(item);
2492 std::string slhs, srhs;
2493 for (
auto& cl : lhs->
Key()) slhs += toupper(cl);
2494 for (
auto& cr : rhs->Key()) srhs += toupper(cr);
2495 return slhs.compare(srhs) < 0;
2497 std::sort(result.begin(), result.end(), compare);
2502static bool IsPluginLoaded(
const std::string& name) {
2503 if (safe_mode::get_mode()) {
2506 std::find(installed.begin(), installed.end(),
ocpn::tolower(name));
2507 return found != installed.end();
2510 for (
size_t i = 0; i < loaded->GetCount(); i++) {
2511 if (loaded->Item(i)->m_common_name.ToStdString() == name)
return true;
2518 if (m_is_loading.test_and_set()) {
2520 DEBUG_LOG <<
"LoadAllPlugins: recursive invocation";
2525 m_PluginItems.Clear();
2527 wxWindowList kids = GetChildren();
2528 for (
unsigned int i = 0; i < kids.GetCount(); i++) {
2529 wxWindowListNode* node = kids.Item(i);
2530 wxWindow* win = node->GetData();
2532 if (pp) win->Destroy();
2534 GetSizer()->Clear();
2537 m_PluginSelected = 0;
2539 if (safe_mode::get_mode()) {
2542 for (
const auto& name : installed) AddPlugin(name);
2545 auto available = getCompatiblePlugins();
2549 return IsPluginLoaded(md.name);
2551 auto end = std::remove_if(available.begin(), available.end(), predicate);
2552 available.erase(end, available.end());
2558 std::string slhs, srhs;
2559 for (
auto& cl : lhs.name) slhs += toupper(cl);
2560 for (
auto& cr : rhs.name) srhs += toupper(cr);
2561 return slhs.compare(srhs) < 0;
2565 std::set<PluginMetadata, CompSort> unique_sorted_entries(comp_sort);
2566 for (
const auto& p : available) unique_sorted_entries.insert(p);
2572 if (p->m_enabled) AddPlugin(*p);
2576 if (!p->m_enabled) AddPlugin(*p);
2579 for (
const auto& p : unique_sorted_entries) AddPlugin(
PlugInData(p));
2587 m_is_loading.clear();
2590void PluginListPanel::AddPlugin(
const std::string& name) {
2593 panel->SetSelected(
false);
2594 GetSizer()->Add(panel, 0, wxEXPAND);
2595 m_PluginItems.Add(panel);
2596 m_pluginSpacer = g_Platform->GetDisplayDPmm() * 1.0;
2597 GetSizer()->AddSpacer(m_pluginSpacer);
2600void PluginListPanel::AddPlugin(
const PlugInData& pic) {
2602 new PluginPanel(
this, wxID_ANY, wxDefaultPosition, wxDefaultSize, pic);
2603 pPluginPanel->SetSelected(
false);
2604 GetSizer()->Add(pPluginPanel, 0, wxEXPAND);
2605 m_PluginItems.Add(pPluginPanel);
2607 m_pluginSpacer = g_Platform->GetDisplayDPmm() * 1.0;
2608 GetSizer()->AddSpacer(m_pluginSpacer);
2621int PluginListPanel::ComputePluginSpace(ArrayOfPluginPanel plugins,
2622 wxBoxSizer* sizer) {
2624 for (
size_t i = 0; i < plugins.GetCount(); i++) {
2625 auto panel = plugins.Item(i);
2626 bool was_selected = panel->GetSelected();
2627 panel->SetSelected(
false);
2629 wxSize unselected = panel->GetSize();
2631 panel->SetSelected(
true);
2633 wxSize selected = panel->GetSize();
2635 int dy = selected.GetHeight() - unselected.GetHeight();
2636 max_dy = wxMax(max_dy, dy);
2637 panel->SetSelected(was_selected);
2642PluginListPanel::~PluginListPanel() {}
2644void PluginListPanel::UpdateSelections() {
2645 for (
unsigned int i = 0; i < m_PluginItems.GetCount(); i++) {
2648 pPluginPanel->SetSelected(pPluginPanel->GetSelected());
2653void PluginListPanel::SelectPlugin(
PluginPanel* pi) {
2655 GetViewStart(&xs, &ys);
2658 if (m_PluginSelected) {
2659 m_PluginSelected->SetSelected(
false);
2660 m_PluginSelected->Layout();
2663 if (pi == NULL) m_PluginSelected->SetSelected(
false);
2665 m_PluginSelected = pi;
2667 GetSizer()->Layout();
2669 wxSize size = GetBestVirtualSize();
2670 SetVirtualSize(size);
2675 for (
unsigned int i = 0; i < m_PluginItems.GetCount(); i++) {
2677 int yd = pPluginPanel->GetSize().y;
2679 htop += m_pluginSpacer;
2680 if (pPluginPanel == pi) {
2681 int piBottom = htop - (ys *
g_options->GetScrollRate());
2682 if (piBottom > GetClientSize().y) {
2683 ys += (piBottom - GetClientSize().y) /
g_options->GetScrollRate();
2693 int pos = m_PluginItems.Index(pi);
2696 m_PluginItems.RemoveAt(pos);
2699 m_PluginItems.Insert(pi, pos - 1);
2700 wxStaticLine* itemStaticLine =
new wxStaticLine(
2701 this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL);
2706 m_PluginSelected = pi;
2708 GetSizer()->Layout();
2714 int pos = m_PluginItems.Index(pi);
2715 if (pos == (
int)m_PluginItems.Count() -
2718 m_PluginItems.RemoveAt(pos);
2721 m_PluginItems.Insert(pi, pos + 1);
2722 wxStaticLine* itemStaticLine =
new wxStaticLine(
2723 this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL);
2728 m_PluginSelected = pi;
2730 GetSizer()->Layout();
2735static bool canUninstall(std::string name) {
2740 if (plugin.name == name) {
2741 if (safe_mode::get_mode())
2744 return !plugin.readonly;
2751 : wxPanel(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize,
2753 m_is_safe_panel(true) {
2755 wxASSERT(m_PluginListPanel != 0);
2756 wxBoxSizer* top_sizer =
new wxBoxSizer(wxVERTICAL);
2757 SetSizer(top_sizer);
2758 wxBoxSizer* top_horizontal =
new wxBoxSizer(wxHORIZONTAL);
2759 top_sizer->Add(top_horizontal, 0, wxEXPAND);
2761 double iconSize = GetCharWidth() * 4;
2763 int icon_scale = iconSize * dpi_mult;
2765 wxBitmap bitmap(style->GetIcon(
"default_pi", icon_scale, icon_scale));
2766 m_itemStaticBitmap =
new wxStaticBitmap(
this, wxID_ANY, bitmap);
2767 top_horizontal->Add(m_itemStaticBitmap, 0, wxEXPAND | wxALL, 10);
2769 m_pName =
new wxStaticText(
this, wxID_ANY, name);
2770 top_horizontal->Add(m_pName, wxID_ANY, wxALIGN_CENTER_VERTICAL);
2771 m_pVersion =
new wxStaticText(
this, wxID_ANY,
"");
2772 top_horizontal->Add(m_pVersion);
2775 m_pButtons =
new wxBoxSizer(wxHORIZONTAL);
2776 top_horizontal->Add(m_pButtons);
2777 m_info_btn =
new WebsiteButton(
this,
"https:\\opencpn.org");
2778 top_horizontal->Add(m_info_btn);
2779 m_pButtonUninstall =
new wxButton(
this, wxID_ANY, _(
"Uninstall"),
2780 wxDefaultPosition, wxDefaultSize, 0);
2781 top_horizontal->Add(m_pButtonUninstall, 0, wxALIGN_CENTER_VERTICAL | wxALL,
2783 auto uninstall = [&](wxCommandEvent ev) {
2784 auto n = m_pName->GetLabel().ToStdString();
2786 OCPNMessageBox(gFrame, std::string(_(
"Uninstall plugin ")) + n +
"?",
2787 _(
"Un-Installation"), wxICON_QUESTION | wxOK | wxCANCEL);
2788 if (result != wxID_OK)
return;
2792 m_pButtonUninstall->Bind(wxEVT_COMMAND_BUTTON_CLICKED, uninstall);
2796EVT_PAINT(PluginPanel::OnPaint)
2801 : wxPanel(parent,
id, pos, size, wxBORDER_NONE),
2803 m_is_safe_panel(false) {
2806 wxASSERT(m_PluginListPanel != 0);
2808 m_bSelected =
false;
2809 m_penWidthUnselected = g_Platform->GetDisplayDPmm() * .25;
2810 m_penWidthSelected = g_Platform->GetDisplayDPmm() * .5;
2812 wxBoxSizer* topSizer =
new wxBoxSizer(wxVERTICAL);
2815 wxBoxSizer* itemBoxSizer01 =
new wxBoxSizer(wxHORIZONTAL);
2816 topSizer->Add(itemBoxSizer01, 0, wxEXPAND);
2817 Bind(wxEVT_LEFT_DOWN, &PluginPanel::OnPluginSelected,
this);
2818 Bind(wxEVT_LEFT_UP, &PluginPanel::OnPluginSelectedUp,
this);
2820 double iconSize = GetCharWidth() * 4;
2822 int icon_scale = iconSize * dpi_mult;
2824 wxImage plugin_icon;
2826 if (m_plugin.m_bitmap.IsOk()) {
2827 plugin_icon = m_plugin.m_bitmap.ConvertToImage();
2830 if (m_plugin.m_status == PluginStatus::ManagedInstallAvailable) {
2831 wxFileName path(g_Platform->GetSharedDataDir(),
"packageBox.svg");
2832 path.AppendDir(
"uidata");
2833 path.AppendDir(
"traditional");
2834 bitmap =
LoadSVG(path.GetFullPath(), icon_scale, icon_scale);
2835 }
else if (plugin_icon.IsOk()) {
2836 int nowSize = plugin_icon.GetWidth();
2837 plugin_icon.Rescale(icon_scale, icon_scale, wxIMAGE_QUALITY_HIGH);
2838 bitmap = wxBitmap(plugin_icon);
2840 bitmap = wxBitmap(style->GetIcon(
"default_pi", icon_scale, icon_scale));
2842 m_itemStaticBitmap =
new wxStaticBitmap(
this, wxID_ANY, bitmap);
2844 itemBoxSizer01->Add(m_itemStaticBitmap, 0, wxEXPAND | wxALL, 10);
2845 m_itemStaticBitmap->Bind(wxEVT_LEFT_DOWN, &PluginPanel::OnPluginSelected,
2847 m_itemStaticBitmap->Bind(wxEVT_LEFT_UP, &PluginPanel::OnPluginSelectedUp,
2850 wxBoxSizer* itemBoxSizer02 =
new wxBoxSizer(wxVERTICAL);
2851 itemBoxSizer01->Add(itemBoxSizer02, 1, wxEXPAND | wxALL, 0);
2854 int nChars =
g_options->GetSize().x / GetCharWidth();
2855 bool bCompact =
false;
2861 wxString nameString = m_plugin.m_common_name;
2865 dc.GetTextExtent(m_plugin.m_common_name, &nameWidth, NULL);
2866 if (nameWidth > maxWidth) {
2867 nameString = wxControl::Ellipsize(m_plugin.m_common_name, dc,
2868 wxELLIPSIZE_END, maxWidth);
2870 m_pName =
new wxStaticText(
this, wxID_ANY, nameString);
2871 m_pName->Bind(wxEVT_LEFT_DOWN, &PluginPanel::OnPluginSelected,
this);
2872 m_pName->Bind(wxEVT_LEFT_UP, &PluginPanel::OnPluginSelectedUp,
this);
2873 itemBoxSizer02->Add(m_pName, 0, wxALL, 5);
2875 wxFlexGridSizer* sl1 =
new wxFlexGridSizer(2, 0, 0);
2876 sl1->AddGrowableCol(1);
2877 itemBoxSizer02->Add(sl1, 0, wxEXPAND);
2879 m_pVersion =
new wxStaticText(
this, wxID_ANY,
"X.YY.ZZ.AA");
2880 sl1->Add(m_pVersion, 0, wxALL, 5);
2881 if (m_plugin.m_status == PluginStatus::ManagedInstallAvailable) {
2884 m_pVersion->Bind(wxEVT_LEFT_DOWN, &PluginPanel::OnPluginSelected,
this);
2885 m_pVersion->Bind(wxEVT_LEFT_UP, &PluginPanel::OnPluginSelectedUp,
this);
2887 m_cbEnable =
new wxCheckBox(
this, wxID_ANY, _(
"Enabled"));
2888 sl1->Add(m_cbEnable, 1, wxALIGN_RIGHT | wxTOP, 5);
2889 m_cbEnable->Bind(wxEVT_CHECKBOX, &PluginPanel::OnPluginEnableToggle,
this);
2892 wxString descriptionString = m_plugin.m_short_description;
2893 int maxDescriptionWidth = g_Platform->
getDisplaySize().x - (iconSize * 4);
2894 int descriptionWidth;
2895 dc.GetTextExtent(m_plugin.m_short_description, &descriptionWidth, NULL);
2896 if (descriptionWidth > maxDescriptionWidth)
2898 wxControl::Ellipsize(m_plugin.m_short_description, dc,
2899 wxELLIPSIZE_END, maxDescriptionWidth);
2904 new wxStaticText(
this, wxID_ANY, descriptionString, wxDefaultPosition,
2905 wxSize(maxDescriptionWidth, -1), wxST_NO_AUTORESIZE);
2906 itemBoxSizer02->Add(m_pDescription, 0, wxEXPAND | wxALL, 5);
2907 m_pDescription->Bind(wxEVT_LEFT_DOWN, &PluginPanel::OnPluginSelected,
this);
2908 m_pDescription->Bind(wxEVT_LEFT_UP, &PluginPanel::OnPluginSelectedUp,
this);
2911 wxFlexGridSizer* itemBoxSizer03 =
new wxFlexGridSizer(4, 0, 0);
2912 itemBoxSizer03->AddGrowableCol(2);
2913 itemBoxSizer02->Add(itemBoxSizer03, 0, wxEXPAND);
2915 wxString nameString = m_plugin.m_common_name;
2916 m_pName =
new wxStaticText(
this, wxID_ANY, nameString);
2917 m_pName->Bind(wxEVT_LEFT_DOWN, &PluginPanel::OnPluginSelected,
this);
2918 m_pName->Bind(wxEVT_LEFT_UP, &PluginPanel::OnPluginSelectedUp,
this);
2922 wxFont font = GetFont();
2923 font.SetWeight(wxFONTWEIGHT_BOLD);
2924 m_pName->SetFont(font);
2927 itemBoxSizer03->Add(m_pName, 0, wxALL, 10);
2929 m_pVersion =
new wxStaticText(
this, wxID_ANY,
"X.YY.ZZ.AA");
2930 itemBoxSizer03->Add(m_pVersion, 0, wxALL, 10);
2931 if (m_plugin.m_status == PluginStatus::ManagedInstallAvailable ||
2934 !m_plugin.m_managed_metadata.is_orphan)) {
2937 m_pVersion->Bind(wxEVT_LEFT_DOWN, &PluginPanel::OnPluginSelected,
this);
2938 m_pVersion->Bind(wxEVT_LEFT_UP, &PluginPanel::OnPluginSelectedUp,
this);
2940 m_cbEnable =
new wxCheckBox(
this, wxID_ANY, _(
"Enabled"));
2941 itemBoxSizer03->Add(m_cbEnable, 1, wxALIGN_RIGHT | wxTOP, 10);
2942 m_cbEnable->Bind(wxEVT_CHECKBOX, &PluginPanel::OnPluginEnableToggle,
this);
2944 itemBoxSizer03->Add(5 * GetCharWidth(), 1, 0, wxALIGN_RIGHT | wxTOP, 10);
2946 m_pDescription =
new wxStaticText(
2947 this, wxID_ANY, m_plugin.m_short_description, wxDefaultPosition,
2949 itemBoxSizer02->Add(m_pDescription, 1, wxEXPAND | wxALL, 5);
2950 m_pDescription->Bind(wxEVT_LEFT_DOWN, &PluginPanel::OnPluginSelected,
this);
2951 m_pDescription->Bind(wxEVT_LEFT_UP, &PluginPanel::OnPluginSelectedUp,
this);
2955 m_info_btn =
new WebsiteButton(
this,
"https:\\opencpn.org");
2957 itemBoxSizer02->Add(m_info_btn, 0);
2959 m_pButtons =
new wxBoxSizer(wxHORIZONTAL);
2960 itemBoxSizer02->Add(m_pButtons, 0, wxALL, 0);
2961 m_pButtonPreferences =
new wxButton(
this, wxID_ANY, _(
"Preferences"),
2962 wxDefaultPosition, wxDefaultSize, 0);
2963 m_pButtons->Add(m_pButtonPreferences, 0, wxALIGN_LEFT | wxALL, 2);
2965 m_pButtons->AddSpacer(3 * GetCharWidth());
2968 new wxButton(
this, wxID_ANY,
"Upgrade to Version XX.XX.XX",
2969 wxDefaultPosition, wxDefaultSize, 0);
2970 m_pButtons->Add(m_pButtonAction, 0, wxALIGN_LEFT | wxALL, 2);
2972 m_pButtonUninstall =
new wxButton(
this, wxID_ANY, _(
"Uninstall"),
2973 wxDefaultPosition, wxDefaultSize, 0);
2974 m_pButtons->Add(m_pButtonUninstall, 0, wxALIGN_LEFT | wxALL, 2);
2976 m_pButtons =
new wxBoxSizer(wxVERTICAL);
2977 itemBoxSizer02->Add(m_pButtons, 0, wxALL, 0);
2979 wxBoxSizer* tline =
new wxBoxSizer(wxHORIZONTAL);
2980 m_pButtons->Add(tline, 0, wxALL, 2);
2982 m_pButtonPreferences =
new wxButton(
this, wxID_ANY, _(
"Preferences"),
2983 wxDefaultPosition, wxDefaultSize, 0);
2984 tline->Add(m_pButtonPreferences, 0, wxALIGN_LEFT | wxALL, 0);
2986 tline->AddSpacer(3 * GetCharWidth());
2988 m_info_btn =
new WebsiteButton(
this,
"https:\\opencpn.org");
2990 tline->Add(m_info_btn, 0);
2993 new wxButton(
this, wxID_ANY,
"Upgrade to Version XX.XX.XX",
2994 wxDefaultPosition, wxDefaultSize);
2995 m_pButtons->Add(m_pButtonAction, 0, wxALIGN_LEFT | wxALL, 2);
2997 m_pButtonUninstall =
new wxButton(
this, wxID_ANY, _(
"Uninstall"),
2998 wxDefaultPosition, wxDefaultSize, 0);
2999 m_pButtons->Add(m_pButtonUninstall, 0, wxALIGN_LEFT | wxALL, 2);
3002 wxBitmap statusBitmap;
3003 const auto stat = m_plugin.m_status;
3004 auto icon_name = icon_by_status.at(stat);
3005 if (stat == PluginStatus::Imported &&
3006 IsUpdateAvailable(m_plugin.m_managed_metadata)) {
3008 icon_by_status.at(PluginStatus::ManagedInstalledUpdateAvailable);
3011 wxFileName path(g_Platform->GetSharedDataDir(), icon_name);
3012 path.AppendDir(
"uidata");
3013 path.AppendDir(
"traditional");
3015 int bmsize = GetCharWidth() * 3 * dpi_mult;
3016 if (path.IsFileReadable()) {
3017 statusBitmap =
LoadSVG(path.GetFullPath(), bmsize, bmsize);
3018 ok = statusBitmap.IsOk();
3021 auto style = g_StyleManager->GetCurrentStyle();
3022 statusBitmap = wxBitmap(style->GetIcon(
"default_pi", bmsize, bmsize));
3023 wxLogMessage(
"Icon: %s not found.", path.GetFullPath());
3026 m_itemStatusIconBitmap =
new wxStaticBitmap(
this, wxID_ANY, statusBitmap);
3027 m_itemStatusIconBitmap->SetToolTip(message_by_status(stat));
3028 m_itemStatusIconBitmap->Bind(wxEVT_LEFT_DOWN, &PluginPanel::OnPluginSelected,
3030 m_itemStatusIconBitmap->Bind(wxEVT_LEFT_UP, &PluginPanel::OnPluginSelectedUp,
3033 itemBoxSizer01->Add(m_itemStatusIconBitmap, 0, wxEXPAND | wxALL, 20);
3035 itemBoxSizer02->AddSpacer(GetCharWidth());
3037 m_pButtonPreferences->Bind(wxEVT_COMMAND_BUTTON_CLICKED,
3038 &PluginPanel::OnPluginPreferences,
this);
3039 m_pButtonUninstall->Bind(wxEVT_COMMAND_BUTTON_CLICKED,
3040 &PluginPanel::OnPluginUninstall,
this);
3041 m_pButtonAction->Bind(wxEVT_COMMAND_BUTTON_CLICKED,
3042 &PluginPanel::OnPluginAction,
this);
3044 SetSelected(m_bSelected);
3045 SetAutoLayout(
true);
3053PluginPanel::~PluginPanel() {
3054 Unbind(wxEVT_LEFT_DOWN, &PluginPanel::OnPluginSelected,
this);
3055 if (m_is_safe_panel)
return;
3056 m_itemStaticBitmap->Unbind(wxEVT_LEFT_DOWN, &PluginPanel::OnPluginSelected,
3058 m_pName->Unbind(wxEVT_LEFT_DOWN, &PluginPanel::OnPluginSelected,
this);
3059 m_pVersion->Unbind(wxEVT_LEFT_DOWN, &PluginPanel::OnPluginSelected,
this);
3060 m_pDescription->Unbind(wxEVT_LEFT_DOWN, &PluginPanel::OnPluginSelected,
this);
3061 if (m_pButtonAction) {
3062 m_pButtonAction->Unbind(wxEVT_COMMAND_BUTTON_CLICKED,
3063 &PluginPanel::OnPluginAction,
this);
3065 m_pButtonPreferences->Unbind(wxEVT_COMMAND_BUTTON_CLICKED,
3066 &PluginPanel::OnPluginPreferences,
this);
3067 m_cbEnable->Unbind(wxEVT_COMMAND_BUTTON_CLICKED,
3068 &PluginPanel::OnPluginEnableToggle,
this);
3071void PluginPanel::SetActionLabel(wxString& label) {
3072 m_pButtonAction->SetLabel(label);
3076static wxStopWatch swclick;
3077static int downx, downy;
3079void PluginPanel::OnPluginSelected(wxMouseEvent& event) {
3082 event.GetPosition(&downx, &downy);
3088void PluginPanel::OnPluginSelectedUp(wxMouseEvent& event) {
3090 qDebug() << swclick.Time();
3091 if (swclick.Time() < 200) {
3093 event.GetPosition(&upx, &upy);
3094 if ((fabs(upx - downx) < GetCharWidth()) &&
3095 (fabs(upy - downy) < GetCharWidth())) {
3103void PluginPanel::DoPluginSelect() {
3104 if (m_plugin.m_status == PluginStatus::ManagedInstallAvailable) {
3110 run_update_dialog(m_PluginListPanel, &m_plugin,
false, 0,
true);
3111 }
else if (m_bSelected) {
3113 m_PluginListPanel->SelectPlugin(NULL);
3116 m_PluginListPanel->SelectPlugin(
this);
3124static PluginMetadata GetMetadataByName(
const std::string& name) {
3126 auto predicate = [name](
const PluginMetadata& pm) {
return pm.name == name; };
3127 auto found = std::find_if(plugins.begin(), plugins.end(), predicate);
3128 if (found == plugins.end()) {
3129 wxLogDebug(
"Cannot find metadata for %s", name.c_str());
3134void PluginPanel::SetSelected(
bool selected) {
3135 m_bSelected = selected;
3137 m_pVersion->SetLabel(
3141 m_pButtons->Show(
true);
3142 bool unInstallPossible = canUninstall(m_plugin.
m_common_name.ToStdString());
3145 if (m_plugin.m_status == PluginStatus::LegacyUpdateAvailable ||
3148 unInstallPossible =
false;
3151 if (m_plugin.m_managed_metadata.is_orphan) unInstallPossible =
true;
3153 m_pButtonUninstall->Show(unInstallPossible);
3155 if (m_plugin.m_managed_metadata.info_url.size()) {
3156 m_info_btn->SetURL(m_plugin.m_managed_metadata.info_url.c_str());
3160 m_cbEnable->Show(
true);
3165 switch (m_plugin.m_status) {
3166 case PluginStatus::LegacyUpdateAvailable:
3167 label = _(
"Upgrade to Version ");
3168 label += wxString(m_plugin.m_managed_metadata.version.c_str());
3169 m_action = ActionVerb::UPGRADE_TO_MANAGED_VERSION;
3170 m_pButtonAction->Enable();
3173 case PluginStatus::ManagedInstallAvailable:
3174 label = _(
"Install...");
3175 m_action = ActionVerb::INSTALL_MANAGED_VERSION;
3176 m_pButtonAction->Enable();
3179 case PluginStatus::ManagedInstalledUpdateAvailable:
3180 label = _(
"Update to ");
3181 label += wxString(m_plugin.m_managed_metadata.version.c_str());
3182 m_action = ActionVerb::UPGRADE_INSTALLED_MANAGED_VERSION;
3183 m_pButtonAction->Enable();
3186 case PluginStatus::ManagedInstalledCurrentVersion:
3187 label = _(
"Reinstall");
3188 m_action = ActionVerb::REINSTALL_MANAGED_VERSION;
3189 m_pButtonAction->Enable();
3192 case PluginStatus::ManagedInstalledDowngradeAvailable:
3193 label = _(
"Downgrade");
3194 m_action = ActionVerb::DOWNGRADE_INSTALLED_MANAGED_VERSION;
3195 m_pButtonAction->Enable();
3198 case PluginStatus::Imported:
3199 if (IsUpdateAvailable(m_plugin.m_managed_metadata)) {
3200 label = _(
"Update");
3201 m_action = ActionVerb::UPDATE_IMPORTED_VERSION;
3203 m_pButtonAction->Hide();
3204 m_action = ActionVerb::NOP;
3209 m_action = ActionVerb::NOP;
3210 m_pButtonAction->Hide();
3214 m_action = ActionVerb::NOP;
3215 m_pButtonAction->Hide();
3220 m_action = ActionVerb::NOP;
3223 SetActionLabel(label);
3235 m_pButtons->Show(
false);
3238 if (m_plugin.m_status == PluginStatus::ManagedInstallAvailable)
3239 m_cbEnable->Show(
false);
3260 SetEnabled(m_plugin.m_enabled);
3275void PluginPanel::OnPaint(wxPaintEvent& event) {
3278 int penWidth = m_penWidthUnselected;
3283 penWidth = m_penWidthSelected;
3288 wxBrush b(color, wxBRUSHSTYLE_SOLID);
3290 dc.SetPen(wxPen(border, penWidth));
3292 dc.DrawRoundedRectangle(5, 5, GetSize().x - 10, GetSize().y - 10, 5);
3295void PluginPanel::OnPluginPreferences(wxCommandEvent& event) {
3296 if (m_plugin.m_enabled && m_plugin.m_init_state &&
3299 androidDisableRotation();
3310void PluginPanel::OnPluginEnableToggle(wxCommandEvent& event) {
3311 g_Platform->ShowBusySpinner();
3312 SetEnabled(event.IsChecked());
3313 m_pVersion->SetLabel(
3320 g_Platform->HideBusySpinner();
3323void PluginPanel::OnPluginUninstall(wxCommandEvent& event) {
3324 m_action = ActionVerb::UNINSTALL_MANAGED_VERSION;
3327 wxCommandEvent actionEvent(wxEVT_COMMAND_BUTTON_CLICKED);
3328 actionEvent.SetId(ID_CMD_BUTTON_PERFORM_ACTION);
3329 actionEvent.SetClientData(
this);
3330 g_pi_manager->GetUtilHandler()->AddPendingEvent(actionEvent);
3333void PluginPanel::OnPluginAction(wxCommandEvent& event) {
3335 wxCommandEvent actionEvent(wxEVT_COMMAND_BUTTON_CLICKED);
3336 actionEvent.SetId(ID_CMD_BUTTON_PERFORM_ACTION);
3337 actionEvent.SetClientData(
this);
3338 g_pi_manager->GetUtilHandler()->AddPendingEvent(actionEvent);
3343static void SetWindowFontStyle(wxWindow* window, wxFontStyle style) {
3344 auto font = window->GetFont();
3345 font.SetStyle(style);
3346 window->SetFont(font);
3349void PluginPanel::SetEnabled(
bool enabled) {
3350 if (m_is_safe_panel)
return;
3353 if (enabled) NotifySetupOptionsPlugin(&m_plugin);
3354 if (!enabled && !m_bSelected) {
3355 SetWindowFontStyle(m_pName, wxFONTSTYLE_ITALIC);
3356 SetWindowFontStyle(m_pVersion, wxFONTSTYLE_ITALIC);
3357 SetWindowFontStyle(m_pDescription, wxFONTSTYLE_ITALIC);
3360 m_pVersion->Disable();
3361 m_pDescription->Disable();
3364 SetWindowFontStyle(m_pName, wxFONTSTYLE_NORMAL);
3365 SetWindowFontStyle(m_pVersion, wxFONTSTYLE_NORMAL);
3366 SetWindowFontStyle(m_pDescription, wxFONTSTYLE_NORMAL);
3369 m_pVersion->Enable();
3370 m_pDescription->Enable();
3375 m_pName->Enable(enabled || m_bSelected);
3376 m_pVersion->Enable(enabled || m_bSelected);
3377 m_pDescription->Enable(enabled || m_bSelected);
3381 wxString description = m_plugin.m_long_description;
3382 if (description.IsEmpty())
3383 description = wxString(m_plugin.m_managed_metadata.description.c_str());
3387 m_pDescription->SetLabel(wrapper.GetWrapped());
3388 if (m_plugin.m_managed_metadata.info_url.size()) {
3389 m_info_btn->SetURL(m_plugin.m_managed_metadata.info_url.c_str());
3393 wxString description = m_plugin.m_short_description;
3394 if (description.IsEmpty())
3395 description = wxString(m_plugin.m_managed_metadata.summary.c_str());
3398 m_pDescription->SetLabel(wrapper.GetWrapped());
3401 m_pButtonPreferences->Enable(enabled &&
3403 m_cbEnable->SetValue(enabled);
3406void PluginPanel::OnPluginUp(wxCommandEvent& event) {
3407 m_PluginListPanel->MoveUp(
this);
3410void PluginPanel::OnPluginDown(wxCommandEvent& event) {
3411 m_PluginListPanel->MoveDown(
this);
3416 : wxPanel(parent), m_url(url) {
3417 auto vbox =
new wxBoxSizer(wxVERTICAL);
3418 auto button =
new wxButton(
this, wxID_ANY, _(
"Website"));
3419 button->Enable(strlen(url) > 0);
3422 Bind(wxEVT_COMMAND_BUTTON_CLICKED,
3423 [=](wxCommandEvent&) { wxLaunchDefaultBrowser(m_url); });
3431PlugInChartBase::PlugInChartBase() { m_Chart_Error_Factor = 0.; }
3433PlugInChartBase::~PlugInChartBase() {}
3442 bool b_allow_overzoom) {
3454 const wxRegion& Region) {
3455 return wxNullBitmap;
3464 wxRegion* pValidRegion) {}
3477 wxRect* pSourceRect) {}
3494 double* plat,
double* plon) {}
3501PlugInChartBaseGL::PlugInChartBaseGL() {}
3503PlugInChartBaseGL::~PlugInChartBaseGL() {}
3507 const wxRegion& Region,
3508 bool b_use_stencil) {
3534PlugInChartBaseExtended::PlugInChartBaseExtended() {}
3536PlugInChartBaseExtended::~PlugInChartBaseExtended() {}
3540 const wxRegion& Region,
3541 bool b_use_stencil) {
3547 const wxRegion& Region,
bool b_use_stencil) {
3553 const wxRegion& Region,
bool b_use_stencil) {
3559 return wxNullBitmap;
3563 wxMemoryDC& dc,
const PlugIn_ViewPort& VPoint,
const wxRegion& Region) {
3567ListOfPI_S57Obj* PlugInChartBaseExtended::GetObjRuleListAtLatLon(
3572wxString PlugInChartBaseExtended::CreateObjDescriptions(
3573 ListOfPI_S57Obj* obj_list) {
3577int PlugInChartBaseExtended::GetNoCOVREntries() {
return 0; }
3579int PlugInChartBaseExtended::GetNoCOVRTablePoints(
int iTable) {
return 0; }
3581int PlugInChartBaseExtended::GetNoCOVRTablenPoints(
int iTable) {
return 0; }
3583float* PlugInChartBaseExtended::GetNoCOVRTableHead(
int iTable) {
return 0; }
3592PlugInChartBaseExtendedPlus2::PlugInChartBaseExtendedPlus2() {}
3594PlugInChartBaseExtendedPlus2::~PlugInChartBaseExtendedPlus2() {}
3597PlugInChartBaseExtendedPlus2::GetLightsObjRuleListVisibleAtLatLon(
3607PlugInChartBaseGLPlus2::PlugInChartBaseGLPlus2() {}
3609PlugInChartBaseGLPlus2::~PlugInChartBaseGLPlus2() {}
3621ChartPlugInWrapper::ChartPlugInWrapper() {}
3623ChartPlugInWrapper::ChartPlugInWrapper(
const wxString& chart_class) {
3624 m_ppo = ::wxCreateDynamicObject(chart_class);
3628ChartPlugInWrapper::~ChartPlugInWrapper() {
3629 if (m_ppicb)
delete m_ppicb;
3632wxString ChartPlugInWrapper::GetFileSearchMask() {
3639InitReturn ChartPlugInWrapper::Init(
const wxString& name,
3640 ChartInitFlag init_flags) {
3642 wxWindow* pa = wxWindow::FindFocus();
3644 InitReturn ret_val = (InitReturn)m_ppicb->
Init(name, (
int)init_flags);
3648 if (ret_val == INIT_OK) {
3655 m_ID = m_ppicb->
GetID();
3659 m_SE = m_ppicb->
GetSE();
3673 if ((fabs(m_Chart_Skew) < .01) &&
3674 (CHART_FAMILY_RASTER == m_ChartFamily)) {
3676 if (GetChartExtent(&extent)) {
3677 double lon_range = extent.ELON - extent.WLON;
3678 if ((lon_range > 0) &&
3680 m_ppm_avg = GetSize_X() / (lon_range * 1852 * 60);
3684 m_overlayENC =
false;
3686 wxCharBuffer buf = m_FullPath.ToUTF8();
3687 m_overlayENC = s57chart::IsCellOverlayType(buf.data());
3693 m_ChartType = CHART_TYPE_UNKNOWN;
3694 m_ChartFamily = CHART_FAMILY_UNKNOWN;
3700 if (pc) pc->SetFocus();
3704 return INIT_FAIL_REMOVE;
3708int ChartPlugInWrapper::GetCOVREntries() {
3715int ChartPlugInWrapper::GetCOVRTablePoints(
int iTable) {
3722int ChartPlugInWrapper::GetCOVRTablenPoints(
int iTable) {
3729float* ChartPlugInWrapper::GetCOVRTableHead(
int iTable) {
3741int ChartPlugInWrapper::GetNoCOVREntries() {
3751int ChartPlugInWrapper::GetNoCOVRTablePoints(
int iTable) {
3761int ChartPlugInWrapper::GetNoCOVRTablenPoints(
int iTable) {
3771float* ChartPlugInWrapper::GetNoCOVRTableHead(
int iTable) {
3781bool ChartPlugInWrapper::GetChartExtent(
Extent* pext) {
3785 pext->NLAT = xpi.
NLAT;
3786 pext->SLAT = xpi.
SLAT;
3787 pext->ELON = xpi.
ELON;
3788 pext->WLON = xpi.
WLON;
3797ThumbData* ChartPlugInWrapper::GetThumbData(
int tnx,
int tny,
float lat,
3802 if (!pThumbData->pDIBThumb) {
3803 wxBitmap* pBMPOwnedByChart =
3804 m_ppicb->
GetThumbnail(tnx, tny, m_global_color_scheme);
3805 if (pBMPOwnedByChart) {
3806 wxImage img = pBMPOwnedByChart->ConvertToImage();
3807 pThumbData->pDIBThumb =
new wxBitmap(img);
3809 pThumbData->pDIBThumb = NULL;
3812 pThumbData->Thumb_Size_X = tnx;
3813 pThumbData->Thumb_Size_Y = tny;
3840 pThumbData->ShipX = 0;
3841 pThumbData->ShipY = 0;
3848ThumbData* ChartPlugInWrapper::GetThumbData() {
return pThumbData; }
3850bool ChartPlugInWrapper::UpdateThumbData(
double lat,
double lon) {
3854double ChartPlugInWrapper::GetNormalScaleMin(
double canvas_scale_factor,
3855 bool b_allow_overzoom) {
3862double ChartPlugInWrapper::GetNormalScaleMax(
double canvas_scale_factor,
3884void RenderRotateToViewPort(
const ViewPort& VPoint) {
3885#ifndef USE_ANDROID_GLES2
3887 glTranslatef(xt, yt, 0);
3888 glRotatef(VPoint.
rotation * 180. / PI, 0, 0, 1);
3889 glTranslatef(-xt, -yt, 0);
3893void UndoRenderRotateToViewPort(
const ViewPort& VPoint) {
3894#ifndef USE_ANDROID_GLES2
3896 glTranslatef(xt, yt, 0);
3897 glRotatef(-VPoint.
rotation * 180. / PI, 0, 0, 1);
3898 glTranslatef(-xt, -yt, 0);
3902bool ChartPlugInWrapper::RenderRegionViewOnGL(
const wxGLContext& glc,
3905 const LLRegion& Region) {
3914 if (!Region.Empty() && (ppicb_gl || ppicb_x)) {
3915 wxRegion* r = RectRegion.GetNew_wxRegion();
3918 LLRegion chart_region = vp.GetLLRegion(upd.GetRect());
3919 chart_region.Intersect(Region);
3921 if (!chart_region.Empty()) {
3922 ViewPort cvp = glChartCanvas::ClippedViewport(VPoint, chart_region);
3924 glChartCanvas::SetClipRect(cvp, upd.GetRect(),
false);
3928#ifndef USE_ANDROID_GLES2
3931 RenderRotateToViewPort(VPoint);
3936 glChartCanvas::s_b_useStencil);
3939 glChartCanvas::s_b_useStencil);
3940 UndoRenderRotateToViewPort(VPoint);
3942#ifndef USE_ANDROID_GLES2
3945 glChartCanvas::DisableClipRegion();
3959bool ChartPlugInWrapper::RenderRegionViewOnGLNoText(
3960 const wxGLContext& glc,
const ViewPort& VPoint,
3961 const OCPNRegion& RectRegion,
const LLRegion& Region) {
3970 if (!Region.Empty() && ppicb_x) {
3972 glChartCanvas::SetClipRect(VPoint, VPoint.rv_rect,
false);
3973 glChartCanvas::DisableClipRegion();
3976 RenderRotateToViewPort(VPoint);
3979 wxRegion* r = RectRegion.GetNew_wxRegion();
3982 glChartCanvas::s_b_useStencil);
3985 UndoRenderRotateToViewPort(VPoint);
3990 else if (!Region.Empty() &&
3994 wxRegion* r = RectRegion.GetNew_wxRegion();
3997 LLRegion chart_region = vp.GetLLRegion(upd.GetRect());
3998 chart_region.Intersect(Region);
4000 if (!chart_region.Empty()) {
4001 ViewPort cvp = glChartCanvas::ClippedViewport(VPoint, chart_region);
4003 glChartCanvas::SetClipRect(cvp, upd.GetRect(),
false);
4005 RenderRotateToViewPort(VPoint);
4009 glChartCanvas::s_b_useStencil);
4012 UndoRenderRotateToViewPort(VPoint);
4014 glChartCanvas::DisableClipRegion();
4027bool ChartPlugInWrapper::RenderRegionViewOnGLTextOnly(
4034 if (!Region.Empty() && ppicb_x) {
4035 wxRegion* r = Region.GetNew_wxRegion();
4037#ifndef USE_ANDROID_GLES2
4040 RenderRotateToViewPort(VPoint);
4044 glChartCanvas::s_b_useStencil);
4045 UndoRenderRotateToViewPort(VPoint);
4047#ifndef USE_ANDROID_GLES2
4060bool ChartPlugInWrapper::RenderRegionViewOnDC(wxMemoryDC& dc,
4066 if (Region.IsOk()) {
4067 wxRegion* r = Region.GetNew_wxRegion();
4074 wxColour nodat = GetGlobalColor(_T (
"NODTA" ));
4075 wxColour nodat_sub = nodat;
4077#ifdef ocpnUSE_ocpnBitmap
4078 nodat_sub = wxColour(nodat.Blue(), nodat.Green(), nodat.Red());
4080 m_pMask =
new wxMask(obmp, nodat_sub);
4081 obmp.SetMask(m_pMask);
4083 dc.SelectObject(obmp);
4094bool ChartPlugInWrapper::RenderRegionViewOnDCNoText(wxMemoryDC& dc,
4105 if (Region.IsOk() && (pCBx || ppicb)) {
4106 wxRegion* r = Region.GetNew_wxRegion();
4121bool ChartPlugInWrapper::RenderRegionViewOnDCTextOnly(
4124 bool ret_val =
false;
4127 if (Region.IsOk()) {
4128 wxRegion* r = Region.GetNew_wxRegion();
4142void ChartPlugInWrapper::ClearPLIBTextList() {
4150bool ChartPlugInWrapper::AdjustVP(
ViewPort& vp_last,
ViewPort& vp_proposed) {
4154 return m_ppicb->
AdjustVP(pivp_last, pivp_proposed);
4159void ChartPlugInWrapper::GetValidCanvasRegion(
const ViewPort& VPoint,
4174void ChartPlugInWrapper::SetColorScheme(ColorScheme cs,
bool bApplyImmediate) {
4178 m_global_color_scheme = cs;
4180 if (pThumbData) pThumbData->pDIBThumb = NULL;
4184 double target_scale_ppm) {
4191void ChartPlugInWrapper::ComputeSourceRectangle(
const ViewPort& VPoint,
4192 wxRect* pSourceRect) {
4199double ChartPlugInWrapper::GetRasterScaleFactor(
const ViewPort& vp) {
4201 return (wxRound(100000 * GetPPM() / vp.
view_scale_ppm)) / 100000.;
4206bool ChartPlugInWrapper::GetChartBits(wxRect& source,
unsigned char* pPix,
4208 wxCriticalSectionLocker locker(m_critSect);
4217int ChartPlugInWrapper::GetSize_X() {
4224int ChartPlugInWrapper::GetSize_Y() {
4231void ChartPlugInWrapper::latlong_to_chartpix(
double lat,
double lon,
4232 double& pixx,
double& pixy) {
4236void ChartPlugInWrapper::chartpix_to_latlong(
double pixx,
double pixy,
4237 double* plat,
double* plon) {
4252 return toSDMM(NEflag, a, hi_precision);
4256 return GetGlobalColor(colorName);
4260 const wxString& caption,
int style,
int x,
int y) {
4261 return OCPNMessageBox(parent, message, caption, style, 100, x, y);
4269 return g_Platform->GetWritableDocumentsDir();
4274 auto loader = PluginLoader::GetInstance();
4275 for (
unsigned int i = 0; i < loader->GetPlugInArray()->GetCount(); i++) {
4277 if (pic->m_pplugin == pplugin) {
4287ListOfPI_S57Obj* PlugInManager::GetPlugInObjRuleListAtLatLon(
4290 ListOfPI_S57Obj* list = NULL;
4304 list = picbx->GetObjRuleListAtLatLon(zlat, zlon, SelectRadius, &pi_vp);
4314 ListOfPI_S57Obj* rule_list) {
4325 ret_str = picbx->CreateObjDescriptions(rule_list);
4339 return ps52plib->m_nDepthUnitDisplay;
4346 return ps52plib->m_nSymbolStyle;
4353 return ps52plib->m_nBoundaryStyle;
4363 CreateCompatibleS57Object(pObj, &cobj, &ctx);
4365 ViewPort cvp = CreateCompatibleViewport(*vp);
4370 ObjRazRules rzRules;
4371 rzRules.obj = &cobj;
4372 rzRules.LUP = pContext->LUP;
4373 rzRules.sm_transform_parms = 0;
4374 rzRules.child = NULL;
4375 rzRules.next = NULL;
4377 if (pContext->LUP) {
4378 ps52plib->SetVPointCompat(
4382 ps52plib->PrepareForRender();
4384 return ps52plib->ObjectRenderCheck(&rzRules);
4393 return ps52plib->GetStateHash();
4398void CreateCompatibleS57Object(
PI_S57Obj* pObj, S57Obj* cobj,
4399 chart_context* pctx) {
4402 cobj->att_array = pObj->att_array;
4403 cobj->attVal = pObj->attVal;
4404 cobj->n_attr = pObj->n_attr;
4409 cobj->npt = pObj->npt;
4411 cobj->iOBJL = pObj->iOBJL;
4412 cobj->Index = pObj->Index;
4414 cobj->geoPt = (pt*)pObj->geoPt;
4415 cobj->geoPtz = pObj->geoPtz;
4416 cobj->geoPtMulti = pObj->geoPtMulti;
4418 cobj->m_lat = pObj->m_lat;
4419 cobj->m_lon = pObj->m_lon;
4421 cobj->m_DisplayCat = (DisCat)pObj->m_DisplayCat;
4422 cobj->x_rate = pObj->x_rate;
4423 cobj->y_rate = pObj->y_rate;
4424 cobj->x_origin = pObj->x_origin;
4425 cobj->y_origin = pObj->y_origin;
4427 cobj->Scamin = pObj->Scamin;
4428 cobj->nRef = pObj->nRef;
4429 cobj->bIsAton = pObj->bIsAton;
4430 cobj->bIsAssociable = pObj->bIsAssociable;
4432 cobj->m_n_lsindex = pObj->m_n_lsindex;
4433 cobj->m_lsindex_array = pObj->m_lsindex_array;
4434 cobj->m_n_edge_max_points = pObj->m_n_edge_max_points;
4437 cobj->m_ls_list_legacy =
4441 cobj->m_ls_list_legacy = 0;
4442 cobj->m_ls_list = 0;
4445 cobj->m_bcategory_mutable = pObj->m_bcategory_mutable;
4447 cobj->m_bcategory_mutable =
true;
4451 if (pObj->m_DPRI == -1) {
4453 if (pCtx->LUP) cobj->m_DPRI = pCtx->LUP->DPRI -
'0';
4455 cobj->m_DPRI = pObj->m_DPRI;
4458 cobj->pPolyTessGeo = (PolyTessGeo*)pObj->pPolyTessGeo;
4459 cobj->m_chart_context = (chart_context*)pObj->m_chart_context;
4461 if (pObj->auxParm3 != 1234) {
4462 pObj->auxParm3 = 1234;
4463 pObj->auxParm0 = -99;
4466 cobj->auxParm0 = pObj->auxParm0;
4473 if (pContext->bBBObj_valid)
4475 cobj->BBObj.Set(pContext->BBObj.GetMinY(), pContext->BBObj.GetMinX(),
4476 pContext->BBObj.GetMaxY(), pContext->BBObj.GetMaxX());
4478 cobj->CSrules = pContext->CSrules;
4479 cobj->bCS_Added = pContext->bCS_Added;
4481 cobj->FText = pContext->FText;
4482 cobj->bFText_Added = pContext->bFText_Added;
4483 cobj->rText = pContext->rText;
4485 cobj->bIsClone =
true;
4488 cobj->m_chart_context = pctx;
4489 chart_context* ppctx = (chart_context*)pObj->m_chart_context;
4492 cobj->m_chart_context->m_pvc_hash = ppctx->m_pvc_hash;
4493 cobj->m_chart_context->m_pve_hash = ppctx->m_pve_hash;
4494 cobj->m_chart_context->ref_lat = ppctx->ref_lat;
4495 cobj->m_chart_context->ref_lon = ppctx->ref_lon;
4496 cobj->m_chart_context->pFloatingATONArray = ppctx->pFloatingATONArray;
4497 cobj->m_chart_context->pRigidATONArray = ppctx->pRigidATONArray;
4498 cobj->m_chart_context->safety_contour = ppctx->safety_contour;
4499 cobj->m_chart_context->vertex_buffer = ppctx->vertex_buffer;
4501 cobj->m_chart_context->chart =
4503 cobj->m_chart_context->chart_type = S52_CHART_TYPE_PLUGIN;
4517 CreateCompatibleS57Object(pObj, &cobj, NULL);
4519 LUPname LUP_Name = PAPER_CHART;
4522 ctx->CSrules = NULL;
4523 ctx->bCS_Added =
false;
4526 if (ctx->bFText_Added) {
4527 ctx->bFText_Added =
false;
4533 ctx->bBBObj_valid =
true;
4538 switch (cobj.Primitive_type) {
4543 if (PAPER_CHART == ps52plib->m_nSymbolStyle)
4544 LUP_Name = PAPER_CHART;
4546 LUP_Name = SIMPLIFIED;
4555 if (PLAIN_BOUNDARIES == ps52plib->m_nBoundaryStyle)
4556 LUP_Name = PLAIN_BOUNDARIES;
4558 LUP_Name = SYMBOLIZED_BOUNDARIES;
4563 LUPrec* lup = ps52plib->S52_LUPLookup(LUP_Name, cobj.FeatureName, &cobj);
4567 ps52plib->_LUP2rules(lup, &cobj);
4569 ctx->MPSRulesList = NULL;
4577 pContext->bBBObj_valid =
true;
4583void UpdatePIObjectPlibContext(
PI_S57Obj* pObj, S57Obj* cobj,
4584 ObjRazRules* rzRules) {
4588 pContext->CSrules = cobj->CSrules;
4589 pContext->bCS_Added = cobj->bCS_Added;
4591 pContext->FText = cobj->FText;
4592 pContext->bFText_Added = cobj->bFText_Added;
4593 pContext->rText = cobj->rText;
4595 if (cobj->BBObj.GetValid()) {
4598 BoundingBox(cobj->BBObj.GetMinLon(), cobj->BBObj.GetMinLat(),
4599 cobj->BBObj.GetMaxLon(), cobj->BBObj.GetMaxLat());
4600 pContext->bBBObj_valid =
true;
4605 pObj->m_DisplayCat = (
PI_DisCat)cobj->m_DisplayCat;
4609 pContext->ChildRazRules = rzRules->child;
4610 pContext->MPSRulesList = rzRules->mps;
4612 pObj->auxParm0 = cobj->auxParm0;
4616 double* lon_min,
double* lon_max) {
4619 if (lat_min) *lat_min = pContext->BBObj.GetMinY();
4620 if (lat_max) *lat_max = pContext->BBObj.GetMaxY();
4621 if (lon_min) *lon_min = pContext->BBObj.GetMinX();
4622 if (lon_max) *lon_max = pContext->BBObj.GetMaxX();
4623 return pContext->bBBObj_valid;
4631 LUPrec* lup = pContext->LUP;
4640 LUPrec* lup = pContext->LUP;
4650 LUPrec* lup = pContext->LUP;
4656 return S52_getMarinerParam(S52_MAR_SAFETY_CONTOUR);
4663 CreateCompatibleS57Object(pObj, &cobj, &ctx);
4668 ObjRazRules rzRules;
4669 rzRules.obj = &cobj;
4670 rzRules.LUP = pContext->LUP;
4671 rzRules.sm_transform_parms = 0;
4672 rzRules.child = NULL;
4673 rzRules.next = NULL;
4674 rzRules.mps = pContext->MPSRulesList;
4676 if (pContext->LUP) {
4677 ps52plib->SetLineFeaturePriority(&rzRules, prio);
4680 UpdatePIObjectPlibContext(pObj, &cobj, &rzRules);
4686 ps52plib->PrepareForRender();
4687 ps52plib->ClearTextList();
4690 ps52plib->EnableGLLS(
true);
4692 ps52plib->EnableGLLS(
false);
4701 if (pctx->ChildRazRules) {
4702 ObjRazRules* ctop = pctx->ChildRazRules;
4706 if (ps52plib) ps52plib->DestroyLUP(ctop->LUP);
4708 ObjRazRules* cnxx = ctop->next;
4714 if (pctx->MPSRulesList) {
4715 if (ps52plib && pctx->MPSRulesList->cs_rules) {
4716 for (
unsigned int i = 0; i < pctx->MPSRulesList->cs_rules->GetCount();
4718 Rules* top = pctx->MPSRulesList->cs_rules->Item(i);
4719 ps52plib->DestroyRulesChain(top);
4721 delete pctx->MPSRulesList->cs_rules;
4723 free(pctx->MPSRulesList);
4735 CreateCompatibleS57Object(pObj, &cobj, &ctx);
4742 &transform.easting_vp_center, &transform.northing_vp_center);
4745 ObjRazRules rzRules;
4746 rzRules.obj = &cobj;
4747 rzRules.LUP = pContext->LUP;
4748 rzRules.sm_transform_parms = &transform;
4749 rzRules.child = pContext->ChildRazRules;
4750 rzRules.next = NULL;
4751 rzRules.mps = pContext->MPSRulesList;
4753 if (pContext->LUP) {
4754 ViewPort cvp = CreateCompatibleViewport(*vp);
4760 cvp.rv_rect, cvp.GetBBox(), cvp.
ref_scale,
4762 ps52plib->PrepareForRender();
4764 ps52plib->RenderObjectToDC(pdc, &rzRules);
4767 UpdatePIObjectPlibContext(pObj, &cobj, &rzRules);
4774 wxRect rect,
unsigned char* pixbuf) {
4776 render_canvas_parms pb_spec;
4778 pb_spec.depth = BPP;
4779 pb_spec.pb_pitch = ((rect.width * pb_spec.depth / 8));
4780 pb_spec.lclip = rect.x;
4781 pb_spec.rclip = rect.x + rect.width - 1;
4782 pb_spec.pix_buff = pixbuf;
4783 pb_spec.width = rect.width;
4784 pb_spec.height = rect.height;
4787#ifdef ocpnUSE_ocpnBitmap
4788 pb_spec.b_revrgb =
true;
4790 pb_spec.b_revrgb =
false;
4793 pb_spec.b_revrgb =
false;
4798 CreateCompatibleS57Object(pObj, &cobj, &ctx);
4805 &transform.easting_vp_center, &transform.northing_vp_center);
4808 ObjRazRules rzRules;
4809 rzRules.obj = &cobj;
4810 rzRules.LUP = pContext->LUP;
4811 rzRules.sm_transform_parms = &transform;
4812 rzRules.child = pContext->ChildRazRules;
4813 rzRules.next = NULL;
4814 rzRules.mps = pContext->MPSRulesList;
4816 ViewPort cvp = CreateCompatibleViewport(*vp);
4824 if (!tess)
return 1;
4826 PolyTriGroup* ptg =
new PolyTriGroup;
4827 ptg->tri_prim_head =
4828 tess->Get_PolyTriGroup_head()->tri_prim_head;
4829 ptg->bsingle_alloc =
false;
4830 ptg->data_type = DATA_TYPE_DOUBLE;
4831 tess->Set_PolyTriGroup_head(ptg);
4833 double* pd = (
double*)malloc(
sizeof(
double));
4838 if (pContext->LUP) {
4843 cvp.rv_rect, cvp.GetBBox(), cvp.
ref_scale,
4845 ps52plib->PrepareForRender();
4847 ps52plib->RenderAreaToDC(pdc, &rzRules, &pb_spec);
4850 UpdatePIObjectPlibContext(pObj, &cobj, &rzRules);
4862 CreateCompatibleS57Object(pObj, &cobj, &ctx);
4873 if (!tess)
return 1;
4877 ptg->tri_prim_head = tess->Get_PolyTriGroup_head()->tri_prim_head;
4878 ptg->bsingle_alloc =
false;
4879 ptg->data_type = DATA_TYPE_DOUBLE;
4880 tess->Set_PolyTriGroup_head(ptg);
4884 double* pd = (
double*)malloc(
sizeof(
double));
4901 &transform.easting_vp_center, &transform.northing_vp_center);
4904 ObjRazRules rzRules;
4905 rzRules.obj = &cobj;
4906 rzRules.LUP = pContext->LUP;
4907 rzRules.sm_transform_parms = &transform;
4908 rzRules.child = pContext->ChildRazRules;
4909 rzRules.next = NULL;
4910 rzRules.mps = pContext->MPSRulesList;
4912 if (pContext->LUP) {
4913 ViewPort cvp = CreateCompatibleViewport(*vp);
4919 cvp.rv_rect, cvp.GetBBox(), cvp.
ref_scale,
4921 ps52plib->PrepareForRender();
4923 ps52plib->RenderAreaToGL(glcc, &rzRules);
4926 UpdatePIObjectPlibContext(pObj, &cobj, &rzRules);
4938 CreateCompatibleS57Object(pObj, &cobj, &ctx);
4945 &transform.easting_vp_center, &transform.northing_vp_center);
4948 ObjRazRules rzRules;
4949 rzRules.obj = &cobj;
4950 rzRules.LUP = pContext->LUP;
4951 rzRules.sm_transform_parms = &transform;
4952 rzRules.child = pContext->ChildRazRules;
4953 rzRules.next = NULL;
4954 rzRules.mps = pContext->MPSRulesList;
4956 if (pContext->LUP) {
4957 ViewPort cvp = CreateCompatibleViewport(*vp);
4963 cvp.rv_rect, cvp.GetBBox(), cvp.
ref_scale,
4965 ps52plib->PrepareForRender();
4967 ps52plib->RenderObjectToGL(glcc, &rzRules);
4970 UpdatePIObjectPlibContext(pObj, &cobj, &rzRules);
4980OCPN_downloadEvent::OCPN_downloadEvent(wxEventType commandType,
int id)
4981 : wxEvent(id, commandType) {
4984 m_b_complete =
false;
4988OCPN_downloadEvent::~OCPN_downloadEvent() {}
4990wxEvent* OCPN_downloadEvent::Clone()
const {
4992 newevent->m_stat = this->m_stat;
4993 newevent->m_condition = this->m_condition;
4995 newevent->m_totalBytes = this->m_totalBytes;
4996 newevent->m_sofarBytes = this->m_sofarBytes;
4997 newevent->m_b_complete = this->m_b_complete;
5003DECL_EXP wxEventType wxEVT_DOWNLOAD_EVENT = wxNewEventType();
5008#define DL_EVENT_TIMER 4388
5016 void setBackgroundMode(
long ID, wxEvtHandler* handler);
5017 void clearBackgroundMode();
5018 void onTimerEvent(wxTimerEvent& event);
5021 wxTimer m_eventTimer;
5022 wxEvtHandler* m_download_evHandler;
5028PI_DLEvtHandler::PI_DLEvtHandler() {
5032 m_download_evHandler = NULL;
5038PI_DLEvtHandler::~PI_DLEvtHandler() {
5039 m_eventTimer.Stop();
5042 (wxObjectEventFunction)(wxEventFunction)&PI_DLEvtHandler::onTimerEvent);
5049 g_download_status =
event.getDLEventStatus();
5050 g_download_condition =
event.getDLEventCondition();
5053 if (m_download_evHandler &&
5056 ev.setComplete(
true);
5057 ev.setTransferred(m_sofarBytes);
5058 ev.setTotal(m_totalBytes);
5060 ev.setDLEventStatus(event.getDLEventStatus());
5063 m_download_evHandler->AddPendingEvent(ev);
5064 m_eventTimer.Stop();
5066 finishAndroidFileDownload();
5073void PI_DLEvtHandler::setBackgroundMode(
long ID, wxEvtHandler* handler) {
5075 m_download_evHandler = handler;
5077 m_eventTimer.SetOwner(
this, DL_EVENT_TIMER);
5081 (wxObjectEventFunction)(wxEventFunction)&PI_DLEvtHandler::onTimerEvent);
5082 m_eventTimer.Start(1000, wxTIMER_CONTINUOUS);
5085void PI_DLEvtHandler::clearBackgroundMode() {
5086 m_download_evHandler = NULL;
5087 m_eventTimer.Stop();
5090void PI_DLEvtHandler::onTimerEvent(wxTimerEvent& event) {
5096 int stat = queryAndroidFileDownload(m_id, &sstat);
5099 long sofarBytes = 0;
5100 long totalBytes = -1;
5104 qDebug() <<
"Error on queryAndroidFileDownload, ending download";
5105 ev.setComplete(
true);
5106 ev.setTransferred(sofarBytes);
5107 ev.setTotal(totalBytes);
5112 wxStringTokenizer tk(sstat,
";");
5113 if (tk.HasMoreTokens()) {
5114 wxString token = tk.GetNextToken();
5115 token.ToLong(&state);
5116 token = tk.GetNextToken();
5117 token.ToLong(&sofarBytes);
5118 token = tk.GetNextToken();
5119 token.ToLong(&totalBytes);
5122 qDebug() << state << sofarBytes << totalBytes;
5124 m_sofarBytes = sofarBytes;
5125 m_totalBytes = totalBytes;
5127 ev.setTransferred(sofarBytes);
5128 ev.setTotal(totalBytes);
5131 qDebug() <<
"Event OCPN_DL_FAILED/OCPN_DL_EVENT_TYPE_END";
5132 ev.setComplete(
true);
5135 }
else if (state == 8) {
5136 qDebug() <<
"Event OCPN_DL_NO_ERROR/OCPN_DL_EVENT_TYPE_END";
5137 ev.setComplete(
true);
5141 ev.setComplete(
false);
5149 if (m_download_evHandler) {
5151 m_download_evHandler->AddPendingEvent(ev);
5156 m_eventTimer.Stop();
5157 finishAndroidFileDownload();
5167 const wxString& outputFile,
5168 const wxString& title,
const wxString& message,
5169 const wxBitmap& bitmap, wxWindow* parent,
5170 long style,
int timeout_secs) {
5173 wxString msg =
"Downloading file synchronously: ";
5180 int vres = validateAndroidWriteLocation(outputFile);
5192 g_piEventHandler->Connect(
5193 wxEVT_DOWNLOAD_EVENT,
5194 (wxObjectEventFunction)(wxEventFunction)&PI_DLEvtHandler::onDLEvent);
5199 wxString fURI = outputFile;
5200 if (!fURI.StartsWith(
"file://")) {
5201 fURI.Prepend(
"file://");
5204 int res = startAndroidFileDownload(url, fURI, g_piEventHandler, &dl_ID);
5207 finishAndroidFileDownload();
5208 g_piEventHandler->Disconnect(
5209 wxEVT_DOWNLOAD_EVENT,
5210 (wxObjectEventFunction)(wxEventFunction)&PI_DLEvtHandler::onDLEvent);
5215 wxDateTime dl_start_time = wxDateTime::Now();
5219 wxTimeSpan dt = wxDateTime::Now() - dl_start_time;
5220 qDebug() <<
"Spin.." << dt.GetSeconds().GetLo();
5222 if (dt.GetSeconds() > timeout_secs) {
5223 qDebug() <<
"USER_TIMOUT";
5224 finishAndroidFileDownload();
5225 g_piEventHandler->Disconnect(
5226 wxEVT_DOWNLOAD_EVENT,
5227 (wxObjectEventFunction)(wxEventFunction)&PI_DLEvtHandler::onDLEvent);
5235 finishAndroidFileDownload();
5236 g_piEventHandler->Disconnect(
5237 wxEVT_DOWNLOAD_EVENT,
5241 qDebug() <<
"RETURN DL_END" << (int)ss;
5247 int stat = queryAndroidFileDownload(dl_ID, &sstat);
5249 qDebug() <<
"Error on queryAndroidFileDownload";
5250 finishAndroidFileDownload();
5251 g_piEventHandler->Disconnect(
5252 wxEVT_DOWNLOAD_EVENT,
5253 (wxObjectEventFunction)(wxEventFunction)&PI_DLEvtHandler::onDLEvent);
5263#elif defined(OCPN_USE_CURL)
5264 wxFileName tfn = wxFileName::CreateTempFileName(outputFile);
5265 wxFileOutputStream output(tfn.GetFullPath());
5267 wxCurlDownloadDialog ddlg(url, &output, title, message + url, bitmap, parent,
5269 wxCurlDialogReturnFlag ret = ddlg.RunModal();
5275 case wxCDRF_SUCCESS: {
5276 if (wxCopyFile(tfn.GetFullPath(), outputFile))
5282 case wxCDRF_FAILED: {
5286 case wxCDRF_USER_ABORTED: {
5294 if (wxFileExists(tfn.GetFullPath())) wxRemoveFile(tfn.GetFullPath());
5304 return ocpn::toUsrDateTimeFormat(date_time,
options);
5309 const wxString& outputFile,
5310 wxEvtHandler* handler,
5313 wxString msg =
"Downloading file asynchronously: ";
5325 int res = startAndroidFileDownload(url, outputFile, NULL ,
5329 finishAndroidFileDownload();
5334 g_piEventHandler->setBackgroundMode(dl_ID, handler);
5336 if (handle) *handle = dl_ID;
5340#elif defined(OCPN_USE_CURL)
5347 bool http = (url.StartsWith(wxS(
"http:")) || url.StartsWith(wxS(
"https:")));
5350 dynamic_cast<wxCurlHTTP*
>(
g_pi_manager->m_pCurl.get())) {
5357 bool failed =
false;
5366 new wxFileOutputStream(outputFile)),
5374 wxCurlThreadError err =
g_pi_manager->m_pCurlThread->Download();
5375 if (err != wxCTE_NO_ERROR) {
5389 delete (
g_pi_manager->m_pCurlThread->GetOutputStream());
5407 cancelAndroidFileDownload(handle);
5408 finishAndroidFileDownload();
5409 if (g_piEventHandler) g_piEventHandler->clearBackgroundMode();
5413 delete (
g_pi_manager->m_pCurlThread->GetOutputStream());
5424 const wxString& parameters, wxString& result,
5427 wxString lparms = parameters;
5428 wxString postResult = doAndroidPOST(url, lparms, timeout_secs * 1000);
5431 result = postResult;
5434#elif defined(OCPN_USE_CURL)
5436 post.SetOpt(CURLOPT_TIMEOUT, timeout_secs);
5437 size_t res = post.Post(parameters.ToAscii(), parameters.Len(), url);
5440 result = wxString(post.GetResponseBody().c_str(), wxConvUTF8);
5443 result = wxEmptyString;
5454 return androidCheckOnline();
5457#if !defined(__ANDROID__) && defined(OCPN_USE_CURL)
5458 if (wxDateTime::GetTimeNow() >
5459 g_pi_manager->m_last_online_chk + ONLINE_CHECK_RETRY) {
5461 get.Head(
"http://yahoo.com/");
5462 g_pi_manager->m_last_online = get.GetResponseCode() > 0;
5464 g_pi_manager->m_last_online_chk = wxDateTime::GetTimeNow();
5472#if !defined(__ANDROID__) && defined(OCPN_USE_CURL)
5473void PlugInManager::OnEndPerformCurlDownload(wxCurlEndPerformEvent& ev) {
5475 if (ev.IsSuccessful()) {
5482 event.setComplete(
true);
5484 if (m_download_evHandler) {
5485 m_download_evHandler->AddPendingEvent(event);
5486 m_download_evHandler = NULL;
5487 m_downloadHandle = NULL;
5490 if (m_pCurlThread) {
5491 m_pCurlThread->Wait();
5492 if (!m_pCurlThread->IsAborting()) {
5493 delete (m_pCurlThread->GetOutputStream());
5494 wxDELETE(m_pCurlThread);
5499void PlugInManager::OnCurlDownload(wxCurlDownloadEvent& ev) {
5503 event.setTotal(ev.GetTotalBytes());
5504 event.setTransferred(ev.GetDownloadedBytes());
5505 event.setComplete(
false);
5507 if (m_download_evHandler) {
5508 m_download_evHandler->AddPendingEvent(event);
5512bool PlugInManager::HandleCurlThreadError(wxCurlThreadError err,
5513 wxCurlBaseThread* p,
5514 const wxString& url) {
5516 case wxCTE_NO_ERROR:
5519 case wxCTE_NO_RESOURCE:
5521 wxS(
"Insufficient resources for correct execution of the program."));
5524 case wxCTE_ALREADY_RUNNING:
5528 case wxCTE_INVALID_PROTOCOL:
5529 wxLogError(wxS(
"The URL '%s' uses an unsupported protocol."),
5533 case wxCTE_NO_VALID_STREAM:
5540 case wxCTE_CURL_ERROR: {
5541 wxString ws = wxS(
"unknown");
5542 if (p->GetCurlSession())
5544 wxString(p->GetCurlSession()->GetErrorString().c_str(), wxConvUTF8);
5545 wxLogError(wxS(
"Network error: %s"), ws.c_str());
5550 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.