39 #include <unordered_map>
49 #if defined(__linux__) && !defined(__ANDROID__)
55 #include <wx/filename.h>
56 #include <wx/aui/aui.h>
57 #include <wx/platinfo.h>
58 #include <wx/popupwin.h>
59 #include <wx/progdlg.h>
60 #include <wx/statline.h>
61 #include <wx/tokenzr.h>
62 #include <wx/tooltip.h>
64 #include <wx/hashset.h>
65 #include <wx/hashmap.h>
66 #include <wx/jsonval.h>
68 #include <wx/zipstrm.h>
69 #include <wx/zstream.h>
70 #include <wx/tarstrm.h>
71 #include <wx/textwrapper.h>
78 #include <archive_entry.h>
79 typedef __LA_INT64_T la_int64_t;
89 #include "model/ais_target_data.h"
90 #include "model/catalog_handler.h"
91 #include "model/comm_drv_n0183_net.h"
93 #include "model/comm_drv_n2k.h"
94 #include "model/comm_drv_registry.h"
95 #include "model/comm_navmsg_bus.h"
96 #include "model/comm_vars.h"
97 #include "model/config_vars.h"
98 #include "model/downloader.h"
99 #include "model/georef.h"
100 #include "model/json_event.h"
101 #include "model/logger.h"
102 #include "model/multiplexer.h"
103 #include "model/nav_object_database.h"
104 #include "model/navutil_base.h"
105 #include "model/ocpn_utils.h"
106 #include "model/plugin_cache.h"
107 #include "model/plugin_handler.h"
108 #include "model/plugin_loader.h"
109 #include "model/plugin_paths.h"
110 #include "model/route.h"
111 #include "model/routeman.h"
112 #include "model/safe_mode.h"
113 #include "model/select.h"
114 #include "model/semantic_vers.h"
115 #include "model/track.h"
118 #include "canvasMenu.h"
119 #include "cat_settings.h"
120 #include "chartbase.h"
122 #include "chartdbs.h"
125 #include "download_mgr.h"
129 #include "model/ais_decoder.h"
132 #include "observable_confvar.h"
133 #include "observable_globvar.h"
134 #include "ocpn_app.h"
135 #include "OCPN_AUIManager.h"
137 #include "ocpn_frame.h"
138 #include "ocpn_pixel.h"
139 #include "OCPNPlatform.h"
140 #include "OCPNRegion.h"
143 #include "pluginmanager.h"
144 #include "routemanagerdialog.h"
145 #include "routeman_gui.h"
147 #include "s52utils.h"
148 #include "SoundFactory.h"
150 #include "svg_utils.h"
151 #include "SystemCmdSound.h"
153 #include "update_mgr.h"
154 #include "waypointman_gui.h"
158 #include "androidUTIL.h"
162 #include "glChartCanvas.h"
169 struct sigaction sa_all_PIM;
170 struct sigaction sa_all_PIM_previous;
174 void catch_signals_PIM(
int signo) {
177 siglongjmp(env_PIM, 1);
190 #if wxUSE_XLOCALE || !wxCHECK_VERSION(3, 0, 0)
191 extern wxLocale* plocale_def_lang;
200 extern bool g_bShowChartBar;
204 extern RouteList* pRouteList;
205 extern std::vector<Track*> g_TrackList;
207 extern s52plib* ps52plib;
208 extern wxString ChartListFileName;
209 extern bool g_boptionsactive;
211 extern ColorScheme global_color_scheme;
212 extern wxArrayString g_locale_catalog_array;
213 extern int g_GUIScaleFactor;
214 extern int g_ChartScaleFactor;
215 extern wxString g_locale;
218 extern int g_chart_zoom_modifier_raster;
219 extern int g_chart_zoom_modifier_vector;
220 extern double g_display_size_mm;
221 extern bool g_bopengl;
223 extern ChartGroupArray* g_pGroupArray;
224 extern unsigned int g_canvasConfig;
226 extern wxString g_CmdSoundString;
228 unsigned int gs_plib_flags;
229 wxString g_lastPluginMessage;
232 extern bool g_bquiting;
234 WX_DEFINE_ARRAY_PTR(
ChartCanvas*, arrayofCanvasPtr);
235 extern arrayofCanvasPtr g_canvasArray;
237 void NotifySetupOptionsPlugin(
const PlugInData* pic);
239 enum { CurlThreadId = wxID_HIGHEST + 1 };
241 #include <wx/listimpl.cpp>
242 WX_DEFINE_LIST(Plugin_WaypointList);
243 WX_DEFINE_LIST(Plugin_HyperlinkList);
248 static void SendAisJsonMessage(std::shared_ptr<const AisTargetData> pTarget) {
250 if (!g_pi_manager->GetJSONMessageTargetCount())
return;
255 wxLongLong t = ::wxGetLocalTimeMillis();
257 jMsg[wxS(
"Source")] = wxS(
"AisDecoder");
258 jMsg[wxT(
"Type")] = wxT(
"Information");
259 jMsg[wxT(
"Msg")] = wxS(
"AIS Target");
260 jMsg[wxT(
"MsgId")] = t.GetValue();
261 jMsg[wxS(
"lat")] = pTarget->Lat;
262 jMsg[wxS(
"lon")] = pTarget->Lon;
263 jMsg[wxS(
"sog")] = pTarget->SOG;
264 jMsg[wxS(
"cog")] = pTarget->COG;
265 jMsg[wxS(
"hdg")] = pTarget->HDG;
266 jMsg[wxS(
"mmsi")] = pTarget->MMSI;
267 jMsg[wxS(
"class")] = pTarget->Class;
268 jMsg[wxS(
"ownship")] = pTarget->b_OwnShip;
269 jMsg[wxS(
"active")] = pTarget->b_active;
270 jMsg[wxS(
"lost")] = pTarget->b_lost;
271 wxString l_ShipName = wxString::FromUTF8(pTarget->ShipName);
272 for (
size_t i = 0; i < l_ShipName.Len(); i++) {
273 if (l_ShipName.GetChar(i) ==
'@') l_ShipName.SetChar(i,
'\n');
275 jMsg[wxS(
"shipname")] = l_ShipName;
276 wxString l_CallSign = wxString::FromUTF8(pTarget->CallSign);
277 for (
size_t i = 0; i < l_CallSign.Len(); i++) {
278 if (l_CallSign.GetChar(i) ==
'@') l_CallSign.SetChar(i,
'\n');
280 jMsg[wxS(
"callsign")] = l_CallSign;
281 jMsg[wxS(
"removed")] = pTarget->b_removed;
282 g_pi_manager->SendJSONMessageToAllPlugins(wxT(
"AIS"), jMsg);
286 return (*p1)->Key().compare((*p2)->Key());
295 void message(
const std::string& message) {
297 m_deferred_messages.push_back(message);
302 void show_deferred_messages() {
303 for (
auto m : m_deferred_messages) show_msg(m);
310 void show_msg(wxString msg) {
311 OCPNMessageBox(NULL, msg, wxString(_(
"OpenCPN Info")),
312 wxICON_INFORMATION | wxOK, 10);
316 std::vector<wxString> m_deferred_messages;
323 Wrap(win, text, widthMax);
325 wxString
const& GetWrapped()
const {
return m_wrapped; }
326 int const GetLineCount()
const {
return m_lineCount; }
327 wxArrayString GetLineArray() {
return m_array; }
330 virtual void OnOutputLine(
const wxString& line) {
334 virtual void OnNewLine() {
342 wxArrayString m_array;
346 template <
typename T>
347 std::size_t operator()(T t)
const {
348 return static_cast<std::size_t
>(t);
352 wxString message_by_status(PluginStatus stat) {
354 case PluginStatus::System:
355 return _(
"Plugin is a standard system plugin");
356 case PluginStatus::Managed:
357 return _(
"Plugin is managed by OpenCPN");
358 case PluginStatus::Unmanaged:
359 return _(
"Plugin is not managed by OpenCPN");
360 case PluginStatus::Ghost:
362 case PluginStatus::Unknown:
363 return _(
"Plugin status unknown");
364 case PluginStatus::LegacyUpdateAvailable:
365 return _(
"Update to managed Plugin is available");
366 case PluginStatus::ManagedInstallAvailable:
367 return _(
"New managed Plugin installation available");
368 case PluginStatus::ManagedInstalledUpdateAvailable:
369 return _(
"Update to installed Plugin is available");
370 case PluginStatus::ManagedInstalledCurrentVersion:
371 return _(
"Plugin is latest available");
372 case PluginStatus::ManagedInstalledDowngradeAvailable:
374 case PluginStatus::PendingListRemoval:
381 static const std::unordered_map<PluginStatus, const char*, EnumClassHash>
383 {{PluginStatus::System,
"emblem-default.svg"},
384 {PluginStatus::Managed,
"emblem-default.svg"},
385 {PluginStatus::Unmanaged,
"emblem-unmanaged.svg"},
386 {PluginStatus::Ghost,
"ghost.svg"},
387 {PluginStatus::Unknown,
"emblem-unmanaged.svg"},
388 {PluginStatus::LegacyUpdateAvailable,
"emblem-legacy-update.svg"},
389 {PluginStatus::ManagedInstallAvailable,
"emblem-download.svg"},
390 {PluginStatus::ManagedInstalledUpdateAvailable,
391 "emblem-legacy-update.svg"},
392 {PluginStatus::ManagedInstalledCurrentVersion,
"emblem-default.svg"},
393 {PluginStatus::ManagedInstalledDowngradeAvailable,
394 "emblem-default.svg"},
395 {PluginStatus::PendingListRemoval,
"emblem-default.svg"}
399 static const std::unordered_map<PluginStatus, const char*, EnumClassHash>
400 literalstatus_by_status(
401 {{PluginStatus::System,
"System"},
402 {PluginStatus::Managed,
"Managed"},
403 {PluginStatus::Unmanaged,
"Unmanaged"},
404 {PluginStatus::Ghost,
"Ghost"},
405 {PluginStatus::Unknown,
"Unknown"},
406 {PluginStatus::LegacyUpdateAvailable,
"LegacyUpdateAvailable"},
407 {PluginStatus::ManagedInstallAvailable,
"ManagedInstallAvailable"},
408 {PluginStatus::ManagedInstalledUpdateAvailable,
409 "ManagedInstalledUpdateAvailable"},
410 {PluginStatus::ManagedInstalledCurrentVersion,
411 "ManagedInstalledCurrentVersion"},
412 {PluginStatus::ManagedInstalledDowngradeAvailable,
413 "ManagedInstalledDowngradeAvailable"},
414 {PluginStatus::PendingListRemoval,
"PendingListRemoval"}
422 static std::vector<PluginMetadata> getCompatiblePlugins() {
424 struct metadata_compare {
427 return lhs.key() < rhs.key();
431 std::vector<PluginMetadata> returnArray;
433 std::set<PluginMetadata, metadata_compare> unique_plugins;
434 for (
auto plugin : PluginHandler::getInstance()->getAvailable()) {
435 unique_plugins.insert(plugin);
437 for (
auto plugin : unique_plugins) {
439 returnArray.push_back(plugin);
456 std::string installed;
458 if (path ==
"" || !wxFileName::IsFileReadable(path)) {
461 std::ifstream stream;
462 stream.open(path, std::ifstream::in);
471 static std::vector<PluginMetadata> getUpdates(
const char* name) {
472 auto updates = getCompatiblePlugins();
474 std::remove_if(updates.begin(), updates.end(),
478 auto inst_vers = getInstalledVersion(name);
479 if (inst_vers.major == -1) {
484 updates.erase(std::remove_if(updates.begin(), updates.end(),
486 return metadata_version(m) == inst_vers;
493 static void gui_uninstall(
const PlugInData* pic,
const char* plugin) {
494 g_Platform->ShowBusySpinner();
495 PluginLoader::getInstance()->DeactivatePlugIn(*pic);
497 PluginLoader::getInstance()->UpdatePlugIns();
499 wxLogMessage(
"Uninstalling %s", plugin);
500 PluginHandler::getInstance()->
uninstall(plugin);
501 PluginLoader::getInstance()->UpdatePlugIns();
502 g_Platform->HideBusySpinner();
505 static bool LoadAllPlugIns(
bool load_enabled,
bool keep_orphans =
false) {
506 g_Platform->ShowBusySpinner();
507 bool b = PluginLoader::getInstance()->
LoadAllPlugIns(load_enabled,
509 g_Platform->HideBusySpinner();
514 static void UninstallPlugin(
const std::string& name) {
515 auto handler = PluginHandler::getInstance();
516 auto loader = PluginLoader::getInstance();
517 auto finder = [name](
const PluginMetadata pm) {
return pm.name == name; };
518 const auto& installed = handler->getInstalled();
519 auto found = std::find_if(installed.begin(), installed.end(), finder);
520 if (found != installed.end()) {
521 for (
size_t i = 0; i < loader->GetPlugInArray()->GetCount(); i++) {
522 auto const& item = loader->GetPlugInArray()->Item(i);
523 if (item->m_common_name.ToStdString() == name) {
524 DEBUG_LOG <<
"Unloading plugin: " << name;
525 loader->UnLoadPlugIn(i);
529 handler->uninstall(found->name);
530 DEBUG_LOG <<
"Uninstalling: " << found->name;
535 bool uninstall,
const char* name = 0,
536 bool b_forceEnable =
false) {
538 const char* plugin = name == 0 ? pic->
m_common_name.mb_str().data() : name;
539 auto updates = getUpdates(plugin);
540 auto parent_dlg =
dynamic_cast<wxScrolledWindow*
>(parent);
541 wxASSERT(parent_dlg != 0);
543 auto status = dialog.ShowModal();
544 status = dialog.GetReturnCode();
545 if (status != wxID_OK) {
549 auto update = dialog.GetUpdate();
550 if (!g_pi_manager->CheckBlacklistedPlugin(update)) {
554 wxLogMessage(
"Installing %s", update.name.c_str());
556 auto pluginHandler = PluginHandler::getInstance();
558 if (uninstall && path !=
"") {
559 gui_uninstall(pic, update.name.c_str());
561 bool cacheResult = pluginHandler->installPluginFromCache(update);
564 g_Platform->ShowBusySpinner();
568 std::string tempTarballPath = downloader->run(parent_dlg, uninstall);
570 if (!tempTarballPath.size())
576 if (!isRegularFile(manifestPath.c_str())) {
577 wxLogMessage(
"Installation of %s failed", update.name.c_str());
578 PluginHandler::cleanupFiles(manifestPath, update.name);
584 wxLogMessage(
"Installation of %s successful", update.name.c_str());
585 wxURI uri(wxString(update.tarball_url.c_str()));
586 wxFileName fn(uri.GetPath());
587 std::string basename = fn.GetFullName().ToStdString();
590 wxLogDebug(
"Copied %s to local cache at %s", tempTarballPath.c_str(),
592 remove(tempTarballPath.c_str());
600 wxString pispec = _T(
"_pi.dll");
601 #elif defined(__WXOSX__)
602 wxString pispec = _T(
"_pi.dylib");
604 wxString pispec = _T(
"_pi.so");
608 wxTextFile manifest_file(manifestPath);
610 if (manifest_file.Open()) {
612 for (wxString str = manifest_file.GetFirstLine(); !manifest_file.Eof();
613 str = manifest_file.GetNextLine()) {
614 if (str.Contains(pispec)) {
615 if (getenv(
"OCPN_KEEP_PLUGINS")) {
619 auto loader = PluginLoader::getInstance();
620 if (!loader->CheckPluginCompatibility(str)) {
622 _(
"The plugin is not compatible with this version of OpenCPN, "
623 "and will be uninstalled.");
624 OCPNMessageBox(NULL, msg, wxString(_(
"OpenCPN Info")),
625 wxICON_INFORMATION | wxOK, 10);
627 PluginHandler::cleanupFiles(manifestPath, update.name);
636 if (b_forceEnable && pluginFile.Length()) {
637 wxString config_section = (_T (
"/PlugIns/" ));
638 wxFileName fn(pluginFile);
639 config_section += fn.GetFullName();
640 pConfig->SetPath(config_section);
641 pConfig->Write(_T (
"bEnabled" ),
true);
646 auto handler = PluginHandler::getInstance();
647 std::remove(handler->ImportedMetadataPath(update.name).c_str());
650 LoadAllPlugIns(
false);
660 pivp.clat = tvp.clat;
661 pivp.clon = tvp.clon;
662 pivp.view_scale_ppm = tvp.view_scale_ppm;
663 pivp.skew = tvp.skew;
664 pivp.rotation = tvp.rotation;
665 pivp.chart_scale = tvp.chart_scale;
666 pivp.pix_width = tvp.pix_width;
667 pivp.pix_height = tvp.pix_height;
668 pivp.rv_rect = tvp.rv_rect;
669 pivp.b_quilt = tvp.b_quilt;
670 pivp.m_projection_type = tvp.m_projection_type;
672 pivp.lat_min = tvp.GetBBox().GetMinLat();
673 pivp.lat_max = tvp.GetBBox().GetMaxLat();
674 pivp.lon_min = tvp.GetBBox().GetMinLon();
675 pivp.lon_max = tvp.GetBBox().GetMaxLon();
677 pivp.bValid = tvp.IsValid();
688 vp.view_scale_ppm = pivp.view_scale_ppm;
690 vp.rotation = pivp.rotation;
691 vp.chart_scale = pivp.chart_scale;
692 vp.pix_width = pivp.pix_width;
693 vp.pix_height = pivp.pix_height;
694 vp.rv_rect = pivp.rv_rect;
695 vp.b_quilt = pivp.b_quilt;
696 vp.m_projection_type = pivp.m_projection_type;
698 if (gFrame->GetPrimaryCanvas())
699 vp.ref_scale = gFrame->GetPrimaryCanvas()->GetVP().ref_scale;
701 vp.ref_scale = vp.chart_scale;
714 void OnPluginUtilAction(wxCommandEvent& event);
716 DECLARE_EVENT_TABLE()
720 EVT_BUTTON(ID_CMD_BUTTON_PERFORM_ACTION, pluginUtilHandler::OnPluginUtilAction)
725 void pluginUtilHandler::OnPluginUtilAction(wxCommandEvent& event) {
726 auto panel =
static_cast<PluginPanel*
>(
event.GetClientData());
729 wxASSERT(plugin_list_panel != 0);
731 auto actionPIC = panel->GetPlugin();
732 wxString name = actionPIC->m_common_name;
735 switch (panel->GetAction()) {
736 case ActionVerb::UPGRADE_TO_MANAGED_VERSION: {
737 auto loader = PluginLoader::getInstance();
740 std::string pluginName = actionPIC->m_managed_metadata.name;
742 wxLogMessage(
"Installing managed plugin: %s", pluginName.c_str());
744 new GuiDownloader(plugin_list_panel, actionPIC->m_managed_metadata);
745 downloader->run(plugin_list_panel,
false);
749 if (isRegularFile(manifestPath.c_str())) {
751 for (
unsigned i = 0; i < loader->GetPlugInArray()->GetCount(); i += 1) {
752 if (actionPIC->m_managed_metadata.name ==
753 loader->GetPlugInArray()->Item(i)->m_common_name.ToStdString()) {
754 loader->UnLoadPlugIn(i);
760 LoadAllPlugIns(
false);
762 PluginHandler::cleanupFiles(manifestPath,
763 actionPIC->m_managed_metadata.name);
766 plugin_list_panel->SelectByName(name);
771 case ActionVerb::UPGRADE_INSTALLED_MANAGED_VERSION:
772 case ActionVerb::REINSTALL_MANAGED_VERSION:
773 case ActionVerb::DOWNGRADE_INSTALLED_MANAGED_VERSION: {
775 auto metaSave = actionPIC->m_managed_metadata;
776 run_update_dialog(plugin_list_panel, actionPIC,
true,
777 metaSave.name.c_str());
781 case ActionVerb::INSTALL_MANAGED_VERSION: {
782 wxLogMessage(
"Installing new managed plugin.");
783 run_update_dialog(plugin_list_panel, actionPIC,
false);
787 case ActionVerb::UNINSTALL_MANAGED_VERSION: {
788 PluginLoader::getInstance()->DeactivatePlugIn(*actionPIC);
792 message.Printf(
"%s %s\n", actionPIC->m_managed_metadata.name.c_str(),
793 actionPIC->m_managed_metadata.version.c_str());
794 message += _(
"successfully un-installed");
796 wxLogMessage(
"Uninstalling %s",
797 actionPIC->m_managed_metadata.name.c_str());
800 actionPIC->m_managed_metadata.name);
803 auto loader = PluginLoader::getInstance();
804 LoadAllPlugIns(
false);
807 OCPNMessageBox(gFrame, message, _(
"Un-Installation complete"),
808 wxICON_INFORMATION | wxOK);
813 case ActionVerb::NOP:
824 const wxEventType wxEVT_OCPN_MSG = wxNewEventType();
826 OCPN_MsgEvent::OCPN_MsgEvent(wxEventType commandType,
int id)
827 : wxEvent(id, commandType) {}
829 OCPN_MsgEvent::~OCPN_MsgEvent() {}
831 wxEvent* OCPN_MsgEvent::Clone()
const {
833 newevent->m_MessageID =
836 newevent->m_MessageText = this->m_MessageText.c_str();
845 PlugInToolbarToolContainer::PlugInToolbarToolContainer() {
849 bitmap_Rollover_day = NULL;
850 bitmap_Rollover_dusk = NULL;
851 bitmap_Rollover_night = NULL;
854 PlugInToolbarToolContainer::~PlugInToolbarToolContainer() {
858 delete bitmap_Rollover_day;
859 delete bitmap_Rollover_dusk;
860 delete bitmap_Rollover_night;
871 #if !defined(__ANDROID__) && defined(OCPN_USE_CURL)
872 EVT_CURL_END_PERFORM(CurlThreadId, PlugInManager::OnEndPerformCurlDownload)
873 EVT_CURL_DOWNLOAD(CurlThreadId, PlugInManager::OnCurlDownload)
877 static
void event_message_box(const wxString& msg) {
878 OCPNMessageBox(NULL, msg, wxString(_(
"OpenCPN Info")),
879 wxICON_INFORMATION | wxOK, 0);
884 if ((pic->
m_cap_flag & INSTALLS_TOOLBOX_PAGE)) {
885 if (!pic->m_toolbox_panel) NotifySetupOptionsPlugin(pic);
890 PlugInManager::PlugInManager(
MyFrame* parent) {
891 #if !defined(__ANDROID__) && defined(OCPN_USE_CURL)
892 m_pCurlThread = NULL;
898 MyFrame* pFrame = GetParentFrame();
900 m_plugin_menu_item_id_next = CanvasMenuHandler::GetNextContextMenuId();
901 m_plugin_tool_id_next = pFrame->GetNextToolbarToolId();
914 new wxRadioBox(pFrame, -1, _T(
""), wxPoint(0, 0), wxSize(-1, -1), as);
920 #if !defined(__ANDROID__) && defined(OCPN_USE_CURL)
922 m_last_online =
false;
923 m_last_online_chk = -1;
928 m_blacklist = blacklist_factory();
929 m_blacklist_ui = std::unique_ptr<BlacklistUI>(
new BlacklistUI());
932 evt_json_to_all_plugins_listener.
Listen(g_pRouteMan->
json_msg,
this,
933 EVT_JSON_TO_ALL_PLUGINS);
934 Bind(EVT_JSON_TO_ALL_PLUGINS, [&](
ObservedEvt& ev) {
935 auto json = std::static_pointer_cast<const wxJSONValue>(ev.GetSharedPtr());
936 SendJSONMessageToAllPlugins(ev.GetString(), *json);
941 EVT_LEGINFO_TO_ALL_PLUGINS);
942 Bind(EVT_LEGINFO_TO_ALL_PLUGINS, [&](
ObservedEvt& ev) {
943 auto ptr = UnpackEvtPointer<ActiveLegDat>(ev);
944 SendActiveLegInfoToAllPlugIns(ptr.get());
947 HandlePluginLoaderEvents();
950 SendNMEASentenceToAllPlugIns(ev.GetString()); };
953 PlugInManager::~PlugInManager() {
954 #if !defined(__ANDROID__) && defined(OCPN_USE_CURL)
955 wxCurlBase::Shutdown();
957 delete m_utilHandler;
960 void PlugInManager::InitCommListeners(
void) {
964 auto& msgbus = NavMsgBus::GetInstance();
969 auto ptr = ev.GetSharedPtr();
970 auto n0183_msg = std::static_pointer_cast<const Nmea0183Msg>(ptr);
971 HandleN0183(n0183_msg);
975 m_listener_SignalK.
Listen(sk_msg,
this, EVT_SIGNALK);
978 HandleSignalK(UnpackEvtPointer<SignalkMsg>(ev));
982 void PlugInManager::HandleN0183(std::shared_ptr<const Nmea0183Msg> n0183_msg) {
983 std::string s = n0183_msg->payload;
984 wxString sentence(s.c_str());
987 const auto& drivers = CommDriverRegistry::GetInstance().
GetDrivers();
988 auto target_driver = FindDriver(drivers, n0183_msg->source->iface);
990 bool bpass_input_filter =
true;
995 std::dynamic_pointer_cast<CommDriverN0183Serial>(target_driver);
997 params = drv_serial->GetParams();
1000 std::dynamic_pointer_cast<CommDriverN0183Net>(target_driver);
1002 params = drv_net->GetParams();
1007 bpass_input_filter = params.SentencePassesFilter(sentence, FILTER_INPUT);
1009 if (bpass_input_filter) SendNMEASentenceToAllPlugIns(sentence);
1010 }
else if (s[0] ==
'!') {
1012 SendAISSentenceToAllPlugIns(sentence);
1016 void PlugInManager::HandleSignalK(std::shared_ptr<const SignalkMsg> sK_msg) {
1017 g_ownshipMMSI_SK = sK_msg->context_self;
1019 wxJSONReader jsonReader;
1022 std::string msgTerminated = sK_msg->raw_message;
1025 int errors = jsonReader.Parse(msgTerminated, &root);
1026 if (errors == 0) SendJSONMessageToAllPlugins(wxT(
"OCPN_CORE_SIGNALK"), root);
1044 void PlugInManager::HandlePluginLoaderEvents() {
1045 auto loader = PluginLoader::getInstance();
1047 evt_blacklisted_plugin_listener.
Listen(loader->evt_blacklisted_plugin,
this,
1048 EVT_BLACKLISTED_PLUGIN);
1049 Bind(EVT_BLACKLISTED_PLUGIN, [&](wxCommandEvent& ev) {
1050 m_blacklist_ui->message(ev.GetString().ToStdString());
1053 loader->SetOnDeactivateCb(
1055 evt_pluglist_change_listener.
Listen(loader->evt_pluglist_change,
this,
1056 EVT_PLUGLIST_CHANGE);
1057 Bind(EVT_PLUGLIST_CHANGE, [&](wxCommandEvent&) {
1059 if (g_options) g_options->itemBoxSizerPanelPlugins->Layout();
1062 evt_load_directory_listener.
Listen(loader->evt_load_directory,
this,
1063 EVT_LOAD_DIRECTORY);
1064 Bind(EVT_LOAD_DIRECTORY, [&](wxCommandEvent&) {
1065 pConfig->SetPath(
"/PlugIns/");
1066 SetPluginOrder(pConfig->Read(
"PluginOrder", wxEmptyString));
1069 evt_load_plugin_listener.
Listen(loader->evt_load_plugin,
this,
1071 Bind(EVT_LOAD_PLUGIN, [&](wxCommandEvent& ev) {
1076 evt_update_chart_types_listener.
Listen(loader->evt_update_chart_types,
this,
1077 EVT_UPDATE_CHART_TYPES);
1078 Bind(EVT_UPDATE_CHART_TYPES,
1079 [&](wxCommandEvent& ev) { UpDateChartDataTypes(); });
1081 evt_plugin_loadall_finalize_listener.
Listen(
1082 loader->evt_plugin_loadall_finalize,
this, EVT_PLUGIN_LOADALL_FINALIZE);
1083 Bind(EVT_PLUGIN_LOADALL_FINALIZE,
1084 [&](wxCommandEvent& ev) { FinalizePluginLoadall(); });
1086 evt_ais_json_listener.
Listen(g_pAIS->
plugin_msg,
this, EVT_PLUGMGR_AIS_MSG);
1088 EVT_PLUGMGR_ROUTEMAN_MSG);
1090 auto pTarget = UnpackEvtPointer<AisTargetData>(ev);
1091 SendAisJsonMessage(pTarget);
1093 Bind(EVT_PLUGMGR_ROUTEMAN_MSG, [&](
ObservedEvt& ev) {
1094 auto msg = UnpackEvtPointer<wxJSONValue>(ev);
1095 SendJSONMessageToAllPlugins(ev.GetString(), *msg);
1106 void PlugInManager::HandlePluginHandlerEvents() {
1107 auto loader = PluginLoader::getInstance();
1109 evt_download_failed_listener.
Listen(loader->evt_update_chart_types,
this,
1110 EVT_DOWNLOAD_FAILED);
1111 Bind(EVT_DOWNLOAD_FAILED, [&](wxCommandEvent& ev) {
1112 wxString message = _(
"Please check system log for more info.");
1113 OCPNMessageBox(gFrame, message, _(
"Installation error"),
1114 wxICON_ERROR | wxOK | wxCENTRE);
1117 evt_download_ok_listener.
Listen(loader->evt_update_chart_types,
this,
1119 Bind(EVT_DOWNLOAD_OK, [&](wxCommandEvent& ev) {
1120 wxString message(ev.GetString());
1121 message += _(
" successfully installed from cache");
1122 OCPNMessageBox(gFrame, message, _(
"Installation complete"),
1123 wxICON_INFORMATION | wxOK | wxCENTRE);
1127 bool PlugInManager::CallLateInit(
void) {
1130 auto plugin_array = PluginLoader::getInstance()->GetPlugInArray();
1131 for (
unsigned int i = 0; i < plugin_array->GetCount(); i++) {
1134 switch (pic->m_api_version) {
1144 ProcessLateInit(pic);
1154 wxString msg(
"PlugInManager: Calling LateInit PlugIn: ");
1159 if (ppi) ppi->LateInit();
1165 if ((pic->
m_cap_flag & INSTALLS_PLUGIN_CHART) ||
1166 (pic->
m_cap_flag & INSTALLS_PLUGIN_CHART_GL)) {
1167 ChartData->PurgeCachePlugins();
1168 gFrame->InvalidateAllQuilts();
1171 for (
unsigned int i = 0; i < m_PlugInToolbarTools.GetCount(); i++) {
1174 if (pttc->m_pplugin == pic->m_pplugin) {
1175 m_PlugInToolbarTools.Remove(pttc);
1181 for (
unsigned int i = 0; i < m_PlugInMenuItems.GetCount(); i++) {
1183 if (pimis->m_pplugin == pic->m_pplugin) {
1184 m_PlugInMenuItems.Remove(pimis);
1190 void PlugInManager::SendVectorChartObjectInfo(
const wxString& chart,
1191 const wxString& feature,
1192 const wxString& objname,
1193 double& lat,
double& lon,
1194 double&
scale,
int& nativescale) {
1195 wxString decouple_chart(chart);
1196 wxString decouple_feature(feature);
1197 wxString decouple_objname(objname);
1198 auto plugin_array = PluginLoader::getInstance()->GetPlugInArray();
1199 for (
unsigned int i = 0; i < plugin_array->GetCount(); i++) {
1201 if (pic->m_enabled && pic->m_init_state) {
1202 if (pic->
m_cap_flag & WANTS_VECTOR_CHART_OBJECT_INFO) {
1203 switch (pic->m_api_version) {
1214 ppi->SendVectorChartObjectInfo(decouple_chart, decouple_feature,
1215 decouple_objname, lat, lon,
scale,
1227 bool PlugInManager::IsAnyPlugInChartEnabled() {
1230 auto plugin_array = PluginLoader::getInstance()->GetPlugInArray();
1231 for (
unsigned int i = 0; i < plugin_array->GetCount(); i++) {
1233 if (pic->m_enabled && pic->m_init_state) {
1234 if ((pic->
m_cap_flag & INSTALLS_PLUGIN_CHART) ||
1235 (pic->
m_cap_flag & INSTALLS_PLUGIN_CHART_GL))
1242 void PlugInManager::UpdateManagedPlugins() {
1243 PluginLoader::getInstance()->UpdateManagedPlugins(
false);
1244 PluginLoader::getInstance()->
SortPlugins(ComparePlugins);
1247 g_options->itemBoxSizerPanelPlugins->Layout();
1250 bool PlugInManager::UpDateChartDataTypes() {
1252 if (NULL == ChartData)
return bret;
1254 auto plugin_array = PluginLoader::getInstance()->GetPlugInArray();
1255 for (
unsigned int i = 0; i < plugin_array->GetCount(); i++) {
1258 if (pic->m_init_state) {
1259 if ((pic->
m_cap_flag & INSTALLS_PLUGIN_CHART) ||
1260 (pic->
m_cap_flag & INSTALLS_PLUGIN_CHART_GL))
1265 if (bret) ChartData->UpdateChartClassDescriptorArray();
1270 void PlugInManager::FinalizePluginLoadall() {
1274 SetColorSchemeForAllPlugIns(global_color_scheme);
1277 SendBaseConfigToAllPlugIns();
1278 SendS52ConfigToAllPlugIns(
true);
1279 SendSKConfigToAllPlugIns();
1284 if (gFrame->GetPrimaryCanvas()->GetglCanvas())
1285 gFrame->GetPrimaryCanvas()->GetglCanvas()->SendJSONConfigMessage();
1293 void PlugInManager::SetPluginOrder(wxString serialized_names) {
1294 m_plugin_order.Empty();
1295 wxStringTokenizer tokenizer(serialized_names,
";");
1296 while (tokenizer.HasMoreTokens()) {
1297 m_plugin_order.Add(tokenizer.GetNextToken());
1301 wxString PlugInManager::GetPluginOrder() {
1302 wxString plugins = wxEmptyString;
1303 auto plugin_array = PluginLoader::getInstance()->GetPlugInArray();
1304 for (
unsigned int i = 0; i < plugin_array->GetCount(); i++) {
1305 plugins.Append(plugin_array->Item(i)->m_common_name);
1306 if (i < plugin_array->GetCount() - 1) plugins.Append(
';');
1311 bool PlugInManager::UpdateConfig() {
1315 auto plugin_array = PluginLoader::getInstance()->GetPlugInArray();
1316 for (
unsigned int i = 0; i < plugin_array->GetCount(); i++) {
1320 wxString config_section = (_T (
"/PlugIns/" ));
1322 pConfig->SetPath(config_section);
1323 pConfig->Write(_T (
"bEnabled" ), pic->m_enabled);
1330 void PlugInManager::ShowDeferredBlacklistMessages() {
1331 m_blacklist_ui->show_deferred_messages();
1334 bool PlugInManager::CheckBlacklistedPlugin(
const PluginMetadata plugin) {
1336 return CheckBlacklistedPlugin(wxString(plugin.name), v.major, v.minor);
1339 bool PlugInManager::CheckBlacklistedPlugin(
opencpn_plugin* plugin) {
1340 int major = plugin->GetPlugInVersionMajor();
1341 int minor = plugin->GetPlugInVersionMinor();
1344 wxString name = wxString::FromAscii(
typeid(*plugin).name());
1345 name.Replace(
"class ", wxEmptyString);
1347 const std::type_info& ti =
typeid(*plugin);
1349 char* realname = abi::__cxa_demangle(ti.name(), 0, 0, &status);
1350 wxString name = wxString::FromAscii(realname);
1353 return CheckBlacklistedPlugin(name, major, minor);
1356 bool PlugInManager::CheckBlacklistedPlugin(wxString name,
int major,
1358 auto block_status = m_blacklist->get_status(name.ToStdString(), major, minor);
1359 if (block_status == plug_status::unblocked)
return true;
1360 plug_data data(name.ToStdString(), major, minor);
1361 auto msg = m_blacklist->get_message(block_status, data);
1362 m_blacklist_ui->message(msg);
1366 bool PlugInManager::RenderAllCanvasOverlayPlugIns(
ocpnDC& dc,
1370 auto plugin_array = PluginLoader::getInstance()->GetPlugInArray();
1371 for (
unsigned int i = 0; i < plugin_array->GetCount(); i++) {
1373 if (pic->m_enabled && pic->m_init_state) {
1374 if (pic->
m_cap_flag & WANTS_OVERLAY_CALLBACK) {
1377 wxDC* pdc = dc.GetDC();
1380 switch (pic->m_api_version) {
1382 if (priority > 0)
break;
1385 if (ppi) ppi->RenderOverlay(*pdc, &pivp);
1389 if (priority > 0)
break;
1392 if (ppi) ppi->RenderOverlay(*pdc, &pivp);
1403 if (priority > 0)
break;
1406 if (ppi) ppi->RenderOverlay(*pdc, &pivp);
1411 if (priority > 0)
break;
1415 ppi->RenderOverlay(*pdc, &pivp);
1420 ppi116->RenderOverlayMultiCanvas(*pdc, &pivp, canvasIndex);
1424 if (priority <= 0) {
1428 ppi->RenderOverlay(*pdc, &pivp);
1444 if (pic->
m_cap_flag & WANTS_OPENGL_OVERLAY_CALLBACK)
continue;
1446 if ((m_cached_overlay_bm.GetWidth() != vp.pix_width) ||
1447 (m_cached_overlay_bm.GetHeight() != vp.pix_height))
1448 m_cached_overlay_bm.Create(vp.pix_width, vp.pix_height, -1);
1451 mdc.SelectObject(m_cached_overlay_bm);
1452 mdc.SetBackground(*wxBLACK_BRUSH);
1455 bool b_rendered =
false;
1457 switch (pic->m_api_version) {
1459 if (priority > 0)
break;
1462 if (ppi) b_rendered = ppi->RenderOverlay(mdc, &pivp);
1466 if (priority > 0)
break;
1469 if (ppi) b_rendered = ppi->RenderOverlay(mdc, &pivp);
1480 if (priority > 0)
break;
1483 if (ppi) b_rendered = ppi->RenderOverlay(mdc, &pivp);
1488 if (priority > 0)
break;
1492 b_rendered = ppi->RenderOverlay(mdc, &pivp);
1497 b_rendered = ppi116->RenderOverlayMultiCanvas(mdc, &pivp,
1502 if (priority <= 0) {
1506 b_rendered = ppi->RenderOverlay(mdc, &pivp);
1513 mdc, &pivp, g_canvasConfig, priority);
1517 b_rendered = pic->m_pplugin->RenderOverlay(&mdc, &pivp);
1522 mdc.SelectObject(wxNullBitmap);
1525 wxMask* p_msk =
new wxMask(m_cached_overlay_bm, wxColour(0, 0, 0));
1526 m_cached_overlay_bm.SetMask(p_msk);
1528 dc.DrawBitmap(m_cached_overlay_bm, 0, 0,
true);
1531 }
else if (pic->
m_cap_flag & WANTS_OPENGL_OVERLAY_CALLBACK) {
1539 bool PlugInManager::RenderAllGLCanvasOverlayPlugIns(wxGLContext* pcontext,
1543 auto plugin_array = PluginLoader::getInstance()->GetPlugInArray();
1544 for (
unsigned int i = 0; i < plugin_array->GetCount(); i++) {
1546 if (pic->m_enabled && pic->m_init_state) {
1547 if (pic->
m_cap_flag & WANTS_OPENGL_OVERLAY_CALLBACK) {
1550 switch (pic->m_api_version) {
1552 if (priority > 0)
break;
1555 if (ppi) ppi->RenderGLOverlay(pcontext, &pivp);
1567 if (priority > 0)
break;
1570 if (ppi) ppi->RenderGLOverlay(pcontext, &pivp);
1575 if (priority > 0)
break;
1579 ppi->RenderGLOverlay(pcontext, &pivp);
1584 ppi116->RenderGLOverlayMultiCanvas(pcontext, &pivp, canvasIndex);
1589 if (priority <= 0) {
1593 ppi->RenderGLOverlay(pcontext, &pivp);
1614 bool PlugInManager::SendMouseEventToPlugins(wxMouseEvent& event) {
1616 auto plugin_array = PluginLoader::getInstance()->GetPlugInArray();
1617 for (
unsigned int i = 0; i < plugin_array->GetCount(); i++) {
1619 if (pic->m_enabled && pic->m_init_state) {
1621 switch (pic->m_api_version) {
1632 if (ppi->MouseEventHook(event)) bret =
true;
1645 bool PlugInManager::SendKeyEventToPlugins(wxKeyEvent& event) {
1647 auto plugin_array = PluginLoader::getInstance()->GetPlugInArray();
1648 for (
unsigned int i = 0; i < plugin_array->GetCount(); i++) {
1650 if (pic->m_enabled && pic->m_init_state) {
1651 if (pic->
m_cap_flag & WANTS_KEYBOARD_EVENTS) {
1653 switch (pic->m_api_version) {
1662 if (ppi && ppi->KeyboardEventHook(event)) bret =
true;
1676 void PlugInManager::SendViewPortToRequestingPlugIns(
ViewPort& vp) {
1677 auto plugin_array = PluginLoader::getInstance()->GetPlugInArray();
1678 for (
unsigned int i = 0; i < plugin_array->GetCount(); i++) {
1680 if (pic->m_enabled && pic->m_init_state) {
1681 if (pic->
m_cap_flag & WANTS_ONPAINT_VIEWPORT) {
1683 if (pic->m_pplugin) pic->m_pplugin->SetCurrentViewPort(pivp);
1689 void PlugInManager::SendCursorLatLonToAllPlugIns(
double lat,
double lon) {
1690 auto plugin_array = PluginLoader::getInstance()->GetPlugInArray();
1691 for (
unsigned int i = 0; i < plugin_array->GetCount(); i++) {
1693 if (pic->m_enabled && pic->m_init_state) {
1695 if (pic->m_pplugin) pic->m_pplugin->SetCursorLatLon(lat, lon);
1700 void NotifySetupOptionsPlugin(
const PlugInData* pd) {
1701 PluginLoader::getInstance()->NotifySetupOptionsPlugin(pd);
1704 void PlugInManager::NotifySetupOptions() {
1705 auto plugin_array = PluginLoader::getInstance()->GetPlugInArray();
1706 for (
unsigned int i = 0; i < plugin_array->GetCount(); i++) {
1708 NotifySetupOptionsPlugin(pic);
1713 int ok_apply_cancel) {
1714 if (pic->m_enabled && pic->m_init_state) {
1715 if ((pic->
m_cap_flag & INSTALLS_TOOLBOX_PAGE) && pic->m_toolbox_panel) {
1716 pic->m_pplugin->OnCloseToolboxPanel(0, ok_apply_cancel);
1717 auto loader = PluginLoader::getInstance();
1723 void PlugInManager::CloseAllPlugInPanels(
int ok_apply_cancel) {
1724 auto plugin_array = PluginLoader::getInstance()->GetPlugInArray();
1725 for (
unsigned int i = 0; i < plugin_array->GetCount(); i++) {
1728 ClosePlugInPanel(pic, ok_apply_cancel);
1733 int PlugInManager::AddCanvasContextMenuItem(wxMenuItem* pitem,
1737 pmic->pmenu_item = pitem;
1738 pmic->m_pplugin = pplugin;
1739 pmic->id = pitem->GetId() == wxID_SEPARATOR ? wxID_SEPARATOR
1740 : m_plugin_menu_item_id_next;
1742 pmic->b_grey =
false;
1743 pmic->m_in_menu = name;
1745 m_PlugInMenuItems.Add(pmic);
1747 m_plugin_menu_item_id_next++;
1752 void PlugInManager::RemoveCanvasContextMenuItem(
int item,
const char* name) {
1753 for (
unsigned int i = 0; i < m_PlugInMenuItems.GetCount(); i++) {
1756 if (pimis->id == item && !strcmp(name, pimis->m_in_menu)) {
1757 m_PlugInMenuItems.Remove(pimis);
1765 void PlugInManager::SetCanvasContextMenuItemViz(
int item,
bool viz,
1767 for (
unsigned int i = 0; i < m_PlugInMenuItems.GetCount(); i++) {
1770 if (pimis->id == item && !strcmp(name, pimis->m_in_menu)) {
1778 void PlugInManager::SetCanvasContextMenuItemGrey(
int item,
bool grey,
1780 for (
unsigned int i = 0; i < m_PlugInMenuItems.GetCount(); i++) {
1783 if (pimis->id == item && !strcmp(name, pimis->m_in_menu)) {
1784 pimis->b_grey = grey;
1791 void PlugInManager::SendNMEASentenceToAllPlugIns(
const wxString& sentence) {
1792 wxString decouple_sentence(
1797 sigaction(SIGSEGV, NULL, &sa_all_PIM_previous);
1799 struct sigaction temp;
1800 sigaction(SIGSEGV, NULL, &temp);
1802 temp.sa_handler = catch_signals_PIM;
1803 sigemptyset(&temp.sa_mask);
1808 sigaction(SIGSEGV, &temp, NULL);
1810 auto plugin_array = PluginLoader::getInstance()->GetPlugInArray();
1811 for (
unsigned int i = 0; i < plugin_array->GetCount(); i++) {
1813 if (pic->m_enabled && pic->m_init_state) {
1814 if (pic->
m_cap_flag & WANTS_NMEA_SENTENCES) {
1816 if (sigsetjmp(env_PIM, 1)) {
1820 sigaction(SIGSEGV, &sa_all_PIM_previous, NULL);
1829 pic->m_pplugin->SetNMEASentence(decouple_sentence);
1836 sigaction(SIGSEGV, &sa_all_PIM_previous, NULL);
1840 int PlugInManager::GetJSONMessageTargetCount() {
1842 auto plugin_array = PluginLoader::getInstance()->GetPlugInArray();
1843 for (
unsigned int i = 0; i < plugin_array->GetCount(); i++) {
1845 if (pic->m_enabled && pic->m_init_state &&
1852 void PlugInManager::SendJSONMessageToAllPlugins(
const wxString& message_id,
1857 SendMessageToAllPlugins(message_id, out);
1858 wxLogDebug(message_id);
1862 void PlugInManager::SendMessageToAllPlugins(
const wxString& message_id,
1863 const wxString& message_body) {
1864 g_lastPluginMessage = message_body;
1866 wxString decouple_message_id(
1869 wxString decouple_message_body(
1872 auto plugin_array = PluginLoader::getInstance()->GetPlugInArray();
1873 for (
unsigned int i = 0; i < plugin_array->GetCount(); i++) {
1875 if (pic->m_enabled && pic->m_init_state) {
1876 if (pic->
m_cap_flag & WANTS_PLUGIN_MESSAGING) {
1877 switch (pic->m_api_version) {
1882 ppi->SetPluginMessage(decouple_message_id, decouple_message_body);
1889 ppi->SetPluginMessage(decouple_message_id, decouple_message_body);
1906 ppi->SetPluginMessage(decouple_message_id, decouple_message_body);
1917 void PlugInManager::SendAISSentenceToAllPlugIns(
const wxString& sentence) {
1918 wxString decouple_sentence(
1921 auto plugin_array = PluginLoader::getInstance()->GetPlugInArray();
1922 for (
unsigned int i = 0; i < plugin_array->GetCount(); i++) {
1924 if (pic->m_enabled && pic->m_init_state) {
1926 pic->m_pplugin->SetAISSentence(decouple_sentence);
1931 void PlugInManager::SendPositionFixToAllPlugIns(
GenericPosDatEx* ppos) {
1934 pfix.Lat = ppos->kLat;
1935 pfix.Lon = ppos->kLon;
1936 pfix.Cog = ppos->kCog;
1937 pfix.Sog = ppos->kSog;
1938 pfix.Var = ppos->kVar;
1939 pfix.FixTime = ppos->FixTime;
1940 pfix.nSats = ppos->nSats;
1942 auto plugin_array = PluginLoader::getInstance()->GetPlugInArray();
1943 for (
unsigned int i = 0; i < plugin_array->GetCount(); i++) {
1945 if (pic->m_enabled && pic->m_init_state) {
1947 if (pic->m_pplugin) pic->m_pplugin->SetPositionFix(pfix);
1953 pfix_ex.Lat = ppos->kLat;
1954 pfix_ex.Lon = ppos->kLon;
1955 pfix_ex.Cog = ppos->kCog;
1956 pfix_ex.Sog = ppos->kSog;
1957 pfix_ex.Var = ppos->kVar;
1958 pfix_ex.FixTime = ppos->FixTime;
1959 pfix_ex.nSats = ppos->nSats;
1960 pfix_ex.Hdt = ppos->kHdt;
1961 pfix_ex.Hdm = ppos->kHdm;
1963 for (
unsigned int i = 0; i < plugin_array->GetCount(); i++) {
1965 if (pic->m_enabled && pic->m_init_state) {
1967 switch (pic->m_api_version) {
1981 if (ppi) ppi->SetPositionFixEx(pfix_ex);
1992 void PlugInManager::SendActiveLegInfoToAllPlugIns(
1995 leg.Btw = leg_info->Btw;
1996 leg.Dtw = leg_info->Dtw;
1997 leg.wp_name = leg_info->wp_name;
1998 leg.Xte = leg_info->Xte;
1999 leg.arrival = leg_info->arrival;
2000 auto plugin_array = PluginLoader::getInstance()->GetPlugInArray();
2001 for (
unsigned int i = 0; i < plugin_array->GetCount(); i++) {
2003 if (pic->m_enabled && pic->m_init_state) {
2005 switch (pic->m_api_version) {
2020 if (ppi) ppi->SetActiveLegInfo(leg);
2031 void PlugInManager::SendResizeEventToAllPlugIns(
int x,
int y) {
2032 auto plugin_array = PluginLoader::getInstance()->GetPlugInArray();
2033 for (
unsigned int i = 0; i < plugin_array->GetCount(); i++) {
2035 if (pic->m_enabled && pic->m_init_state)
2036 pic->m_pplugin->ProcessParentResize(x, y);
2040 void PlugInManager::SetColorSchemeForAllPlugIns(ColorScheme cs) {
2041 auto plugin_array = PluginLoader::getInstance()->GetPlugInArray();
2042 for (
unsigned int i = 0; i < plugin_array->GetCount(); i++) {
2044 if (pic->m_enabled && pic->m_init_state)
2045 pic->m_pplugin->SetColorScheme((PI_ColorScheme)cs);
2049 void PlugInManager::PrepareAllPluginContextMenus() {
2050 int canvasIndex = gFrame->GetCanvasIndexUnderMouse();
2051 if (canvasIndex < 0)
return;
2053 auto plugin_array = PluginLoader::getInstance()->GetPlugInArray();
2054 for (
unsigned int i = 0; i < plugin_array->GetCount(); i++) {
2056 if (pic->m_enabled && pic->m_init_state) {
2057 if (pic->
m_cap_flag & INSTALLS_CONTEXTMENU_ITEMS) {
2058 switch (pic->m_api_version) {
2064 if (ppi) ppi->PrepareContextMenu(canvasIndex);
2075 void PlugInManager::SendSKConfigToAllPlugIns() {
2078 v[_T(
"self")] = g_ownshipMMSI_SK;
2082 SendMessageToAllPlugins(wxString(_T(
"OCPN_CORE_SIGNALK")), out);
2085 void PlugInManager::SendBaseConfigToAllPlugIns() {
2088 v[_T(
"OpenCPN Version Major")] = VERSION_MAJOR;
2089 v[_T(
"OpenCPN Version Minor")] = VERSION_MINOR;
2090 v[_T(
"OpenCPN Version Patch")] = VERSION_PATCH;
2091 v[_T(
"OpenCPN Version Date")] = VERSION_DATE;
2092 v[_T(
"OpenCPN Version Full")] = VERSION_FULL;
2095 if (g_MainToolbar) {
2096 v[_T(
"OpenCPN Toolbar Width")] = g_MainToolbar->GetToolbarRect().width;
2097 v[_T(
"OpenCPN Toolbar Height")] = g_MainToolbar->GetToolbarRect().height;
2098 v[_T(
"OpenCPN Toolbar PosnX")] = g_MainToolbar->GetToolbarRect().x;
2099 v[_T(
"OpenCPN Toolbar PosnY")] = g_MainToolbar->GetToolbarRect().y;
2103 v[_T(
"OpenCPN Zoom Mod Vector")] = g_chart_zoom_modifier_vector;
2104 v[_T(
"OpenCPN Zoom Mod Other")] = g_chart_zoom_modifier_raster;
2105 v[_T(
"OpenCPN Scale Factor Exp")] =
2106 g_Platform->GetChartScaleFactorExp(g_ChartScaleFactor);
2107 v[_T(
"OpenCPN Display Width")] = (int)g_display_size_mm;
2108 v[_T(
"OpenCPN Content Scale Factor")] = OCPN_GetDisplayContentScaleFactor();
2109 v[_T(
"OpenCPN Display DIP Scale Factor")] = OCPN_GetWinDIPScaleFactor();
2114 SendMessageToAllPlugins(wxString(_T(
"OpenCPN Config")), out);
2117 void PlugInManager::SendS52ConfigToAllPlugIns(
bool bReconfig) {
2120 v[_T(
"OpenCPN Version Major")] = VERSION_MAJOR;
2121 v[_T(
"OpenCPN Version Minor")] = VERSION_MINOR;
2122 v[_T(
"OpenCPN Version Patch")] = VERSION_PATCH;
2123 v[_T(
"OpenCPN Version Date")] = VERSION_DATE;
2124 v[_T(
"OpenCPN Version Full")] = VERSION_FULL;
2132 v[_T(
"OpenCPN S52PLIB ShowAnchorConditions")] = ps52plib->GetAnchorOn();
2133 v[_T(
"OpenCPN S52PLIB ShowQualityOfData")] = ps52plib->GetQualityOfData();
2138 v[_T(
"OpenCPN S52PLIB MetaDisplay")] = ps52plib->m_bShowMeta;
2139 v[_T(
"OpenCPN S52PLIB DeclutterText")] = ps52plib->m_bDeClutterText;
2140 v[_T(
"OpenCPN S52PLIB ShowNationalText")] = ps52plib->m_bShowNationalTexts;
2141 v[_T(
"OpenCPN S52PLIB ShowImportantTextOnly")] =
2142 ps52plib->m_bShowS57ImportantTextOnly;
2143 v[_T(
"OpenCPN S52PLIB UseSCAMIN")] = ps52plib->m_bUseSCAMIN;
2144 v[_T(
"OpenCPN S52PLIB UseSUPER_SCAMIN")] = ps52plib->m_bUseSUPER_SCAMIN;
2145 v[_T(
"OpenCPN S52PLIB SymbolStyle")] = ps52plib->m_nSymbolStyle;
2146 v[_T(
"OpenCPN S52PLIB BoundaryStyle")] = ps52plib->m_nBoundaryStyle;
2147 v[_T(
"OpenCPN S52PLIB ColorShades")] =
2148 S52_getMarinerParam(S52_MAR_TWO_SHADES);
2149 v[_T(
"OpenCPN S52PLIB Safety Depth")] =
2150 (double)S52_getMarinerParam(S52_MAR_SAFETY_DEPTH);
2151 v[_T(
"OpenCPN S52PLIB Shallow Contour")] =
2152 (double)S52_getMarinerParam(S52_MAR_SHALLOW_CONTOUR);
2153 v[_T(
"OpenCPN S52PLIB Deep Contour")] =
2154 (double)S52_getMarinerParam(S52_MAR_DEEP_CONTOUR);
2158 v[_T(
"OpenCPN S52PLIB GlobalReconfig")] = bReconfig;
2163 SendMessageToAllPlugins(wxString(_T(
"OpenCPN Config")), out);
2166 void PlugInManager::NotifyAuiPlugIns(
void) {
2167 auto plugin_array = PluginLoader::getInstance()->GetPlugInArray();
2168 for (
unsigned int i = 0; i < plugin_array->GetCount(); i++) {
2170 if (pic->m_enabled && pic->m_init_state &&
2172 pic->m_pplugin->UpdateAuiStatus();
2176 int PlugInManager::AddToolbarTool(wxString label, wxBitmap* bitmap,
2177 wxBitmap* bmpRollover, wxItemKind kind,
2178 wxString shortHelp, wxString longHelp,
2179 wxObject* clientData,
int position,
2182 pttc->label = label;
2184 if (!bitmap->IsOk()) {
2186 pttc->bitmap_day =
new wxBitmap(style->GetIcon(_T(
"default_pi")));
2189 pttc->bitmap_day =
new wxBitmap(*bitmap);
2190 pttc->bitmap_day->UnShare();
2193 if (!bmpRollover->IsOk()) {
2195 pttc->bitmap_Rollover_day =
new wxBitmap(style->GetIcon(_T(
"default_pi")));
2198 pttc->bitmap_Rollover_day =
new wxBitmap(*bmpRollover);
2199 pttc->bitmap_Rollover_day->UnShare();
2202 pttc->bitmap_dusk = BuildDimmedToolBitmap(pttc->bitmap_day, 128);
2203 pttc->bitmap_night = BuildDimmedToolBitmap(pttc->bitmap_day, 32);
2204 pttc->bitmap_Rollover_dusk =
2205 BuildDimmedToolBitmap(pttc->bitmap_Rollover_day, 128);
2206 pttc->bitmap_Rollover_night =
2207 BuildDimmedToolBitmap(pttc->bitmap_Rollover_day, 32);
2210 pttc->shortHelp = shortHelp;
2211 pttc->longHelp = longHelp;
2212 pttc->clientData = clientData;
2213 pttc->position = position;
2214 pttc->m_pplugin = pplugin;
2215 pttc->tool_sel = tool_sel;
2217 pttc->b_toggle =
false;
2218 pttc->id = m_plugin_tool_id_next;
2220 m_PlugInToolbarTools.Add(pttc);
2222 m_plugin_tool_id_next++;
2227 int PlugInManager::AddToolbarTool(wxString label, wxString SVGfile,
2228 wxString SVGRolloverfile,
2229 wxString SVGToggledfile, wxItemKind kind,
2230 wxString shortHelp, wxString longHelp,
2231 wxObject* clientData,
int position,
2234 pttc->label = label;
2236 pttc->pluginNormalIconSVG = SVGfile;
2237 pttc->pluginRolloverIconSVG = SVGRolloverfile;
2238 pttc->pluginToggledIconSVG = SVGToggledfile;
2243 pttc->bitmap_day =
new wxBitmap(style->GetIcon(_T(
"default_pi")));
2244 pttc->bitmap_dusk = BuildDimmedToolBitmap(pttc->bitmap_day, 128);
2245 pttc->bitmap_night = BuildDimmedToolBitmap(pttc->bitmap_day, 32);
2246 pttc->bitmap_Rollover_day =
new wxBitmap(*pttc->bitmap_day);
2247 pttc->bitmap_Rollover_dusk =
2248 BuildDimmedToolBitmap(pttc->bitmap_Rollover_day, 128);
2249 pttc->bitmap_Rollover_night =
2250 BuildDimmedToolBitmap(pttc->bitmap_Rollover_day, 32);
2253 pttc->shortHelp = shortHelp;
2254 pttc->longHelp = longHelp;
2255 pttc->clientData = clientData;
2256 pttc->position = position;
2257 pttc->m_pplugin = pplugin;
2258 pttc->tool_sel = tool_sel;
2260 pttc->b_toggle =
false;
2261 pttc->id = m_plugin_tool_id_next;
2263 m_PlugInToolbarTools.Add(pttc);
2265 m_plugin_tool_id_next++;
2270 void PlugInManager::RemoveToolbarTool(
int tool_id) {
2271 for (
unsigned int i = 0; i < m_PlugInToolbarTools.GetCount(); i++) {
2274 if (pttc->id == tool_id) {
2275 m_PlugInToolbarTools.Remove(pttc);
2281 pParent->RequestNewToolbars();
2284 void PlugInManager::SetToolbarToolViz(
int item,
bool viz) {
2285 for (
unsigned int i = 0; i < m_PlugInToolbarTools.GetCount(); i++) {
2288 if (pttc->id == item) {
2290 pParent->RequestNewToolbars();
2297 void PlugInManager::SetToolbarItemState(
int item,
bool toggle) {
2298 for (
unsigned int i = 0; i < m_PlugInToolbarTools.GetCount(); i++) {
2301 if (pttc->id == item) {
2302 pttc->b_toggle = toggle;
2303 pParent->SetMasterToolbarItemState(item, toggle);
2310 void PlugInManager::SetToolbarItemBitmaps(
int item, wxBitmap* bitmap,
2311 wxBitmap* bmpRollover) {
2312 for (
unsigned int i = 0; i < m_PlugInToolbarTools.GetCount(); i++) {
2315 if (pttc->id == item) {
2316 delete pttc->bitmap_day;
2317 delete pttc->bitmap_dusk;
2318 delete pttc->bitmap_night;
2319 delete pttc->bitmap_Rollover_day;
2321 if (!bitmap->IsOk()) {
2323 pttc->bitmap_day =
new wxBitmap(style->GetIcon(_T(
"default_pi")));
2326 pttc->bitmap_day =
new wxBitmap(*bitmap);
2327 pttc->bitmap_day->UnShare();
2330 if (!bmpRollover->IsOk()) {
2332 pttc->bitmap_Rollover_day =
2333 new wxBitmap(style->GetIcon(_T(
"default_pi")));
2336 pttc->bitmap_Rollover_day =
new wxBitmap(*bmpRollover);
2337 pttc->bitmap_Rollover_day->UnShare();
2340 pttc->bitmap_dusk = BuildDimmedToolBitmap(pttc->bitmap_day, 128);
2341 pttc->bitmap_night = BuildDimmedToolBitmap(pttc->bitmap_day, 32);
2343 pParent->SetToolbarItemBitmaps(item, pttc->bitmap_day,
2344 pttc->bitmap_Rollover_day);
2351 void PlugInManager::SetToolbarItemBitmaps(
int item, wxString SVGfile,
2352 wxString SVGfileRollover,
2353 wxString SVGfileToggled) {
2354 for (
unsigned int i = 0; i < m_PlugInToolbarTools.GetCount(); i++) {
2357 if (pttc->id == item) {
2358 pttc->pluginNormalIconSVG = SVGfile;
2359 pttc->pluginRolloverIconSVG = SVGfileRollover;
2360 pttc->pluginToggledIconSVG = SVGfileToggled;
2361 pParent->SetToolbarItemSVG(item, pttc->pluginNormalIconSVG,
2362 pttc->pluginRolloverIconSVG,
2363 pttc->pluginToggledIconSVG);
2371 for (
unsigned int i = 0; i < m_PlugInToolbarTools.GetCount(); i++) {
2373 if (
id == pc->id)
return pc->m_pplugin;
2379 wxString PlugInManager::GetToolOwnerCommonName(
const int id) {
2382 auto plugin_array = PluginLoader::getInstance()->GetPlugInArray();
2383 for (
unsigned int i = 0; i < plugin_array->GetCount(); i++) {
2385 if (pic && (pic->m_pplugin == ppi))
return pic->
m_common_name;
2389 return wxEmptyString;
2392 wxString PlugInManager::GetLastError() {
return m_last_error_string; }
2394 wxBitmap* PlugInManager::BuildDimmedToolBitmap(wxBitmap* pbmp_normal,
2395 unsigned char dim_ratio) {
2396 wxImage img_dup = pbmp_normal->ConvertToImage();
2398 if (!img_dup.IsOk())
return NULL;
2400 if (dim_ratio < 200) {
2402 int gimg_width = img_dup.GetWidth();
2403 int gimg_height = img_dup.GetHeight();
2405 double factor = (double)(dim_ratio) / 256.0;
2407 for (
int iy = 0; iy < gimg_height; iy++) {
2408 for (
int ix = 0; ix < gimg_width; ix++) {
2409 if (!img_dup.IsTransparent(ix, iy)) {
2410 wxImage::RGBValue rgb(img_dup.GetRed(ix, iy),
2411 img_dup.GetGreen(ix, iy),
2412 img_dup.GetBlue(ix, iy));
2413 wxImage::HSVValue hsv = wxImage::RGBtoHSV(rgb);
2414 hsv.value = hsv.value * factor;
2415 wxImage::RGBValue nrgb = wxImage::HSVtoRGB(hsv);
2416 img_dup.SetRGB(ix, iy, nrgb.red, nrgb.green, nrgb.blue);
2422 wxBitmap* ptoolBarBitmap;
2425 wxBitmap tbmp(img_dup.GetWidth(), img_dup.GetHeight(), -1);
2427 dwxdc.SelectObject(tbmp);
2429 ptoolBarBitmap =
new wxBitmap(img_dup, (wxDC&)dwxdc);
2431 ptoolBarBitmap =
new wxBitmap(img_dup);
2435 return ptoolBarBitmap;
2438 wxArrayString PlugInManager::GetPlugInChartClassNameArray(
void) {
2439 wxArrayString array;
2440 auto plugin_array = PluginLoader::getInstance()->GetPlugInArray();
2441 for (
unsigned int i = 0; i < plugin_array->GetCount(); i++) {
2443 if (pic && pic->m_enabled && pic->m_init_state &&
2444 ((pic->
m_cap_flag & INSTALLS_PLUGIN_CHART) ||
2445 (pic->
m_cap_flag & INSTALLS_PLUGIN_CHART_GL))) {
2446 wxArrayString carray = pic->m_pplugin->GetDynamicChartClassNameArray();
2448 for (
unsigned int j = 0; j < carray.GetCount(); j++) {
2449 array.Add(carray[j]);
2457 while (j < array.GetCount()) {
2458 wxString test = array[j];
2459 unsigned int k = j + 1;
2460 while (k < array.GetCount()) {
2461 if (test == array[k]) {
2480 int InsertPlugInTool(wxString label, wxBitmap* bitmap, wxBitmap* bmpRollover,
2481 wxItemKind kind, wxString shortHelp, wxString longHelp,
2482 wxObject* clientData,
int position,
int tool_sel,
2485 return s_ppim->AddToolbarTool(label, bitmap, bmpRollover, kind, shortHelp,
2486 longHelp, clientData, position, tool_sel,
2492 void RemovePlugInTool(
int tool_id) {
2493 if (s_ppim) s_ppim->RemoveToolbarTool(tool_id);
2496 void SetToolbarToolViz(
int item,
bool viz) {
2497 if (s_ppim) s_ppim->SetToolbarToolViz(item, viz);
2500 void SetToolbarItemState(
int item,
bool toggle) {
2501 if (s_ppim) s_ppim->SetToolbarItemState(item, toggle);
2504 void SetToolbarToolBitmaps(
int item, wxBitmap* bitmap, wxBitmap* bmpRollover) {
2505 if (s_ppim) s_ppim->SetToolbarItemBitmaps(item, bitmap, bmpRollover);
2508 int InsertPlugInToolSVG(wxString label, wxString SVGfile,
2509 wxString SVGfileRollover, wxString SVGfileToggled,
2510 wxItemKind kind, wxString shortHelp, wxString longHelp,
2511 wxObject* clientData,
int position,
int tool_sel,
2514 return s_ppim->AddToolbarTool(label, SVGfile, SVGfileRollover,
2515 SVGfileToggled, kind, shortHelp, longHelp,
2516 clientData, position, tool_sel, pplugin);
2521 void SetToolbarToolBitmapsSVG(
int item, wxString SVGfile,
2522 wxString SVGfileRollover,
2523 wxString SVGfileToggled) {
2525 s_ppim->SetToolbarItemBitmaps(item, SVGfile, SVGfileRollover,
2529 int AddCanvasMenuItem(wxMenuItem* pitem,
opencpn_plugin* pplugin,
2532 return s_ppim->AddCanvasContextMenuItem(pitem, pplugin, name);
2537 void SetCanvasMenuItemViz(
int item,
bool viz,
const char* name) {
2538 if (s_ppim) s_ppim->SetCanvasContextMenuItemViz(item, viz, name);
2541 void SetCanvasMenuItemGrey(
int item,
bool grey,
const char* name) {
2542 if (s_ppim) s_ppim->SetCanvasContextMenuItemGrey(item, grey, name);
2545 void RemoveCanvasMenuItem(
int item,
const char* name) {
2546 if (s_ppim) s_ppim->RemoveCanvasContextMenuItem(item, name);
2549 int AddCanvasContextMenuItem(wxMenuItem* pitem,
opencpn_plugin* pplugin) {
2551 return AddCanvasMenuItem(pitem, pplugin,
"");
2554 void SetCanvasContextMenuItemViz(
int item,
bool viz) {
2555 SetCanvasMenuItemViz(item, viz);
2558 void SetCanvasContextMenuItemGrey(
int item,
bool grey) {
2559 SetCanvasMenuItemGrey(item, grey);
2562 void RemoveCanvasContextMenuItem(
int item) { RemoveCanvasMenuItem(item); }
2564 wxFileConfig* GetOCPNConfigObject(
void) {
2571 wxWindow* GetOCPNCanvasWindow() {
2572 wxWindow* pret = NULL;
2574 MyFrame* pFrame = s_ppim->GetParentFrame();
2575 pret = (wxWindow*)pFrame->GetPrimaryCanvas();
2580 void RequestRefresh(wxWindow* win) {
2581 if (win) win->Refresh();
2584 void GetCanvasPixLL(
PlugIn_ViewPort* vp, wxPoint* pp,
double lat,
double lon) {
2587 ocpn_vp.clat = vp->clat;
2588 ocpn_vp.clon = vp->clon;
2589 ocpn_vp.m_projection_type = vp->m_projection_type;
2590 ocpn_vp.view_scale_ppm = vp->view_scale_ppm;
2591 ocpn_vp.skew = vp->skew;
2592 ocpn_vp.rotation = vp->rotation;
2593 ocpn_vp.pix_width = vp->pix_width;
2594 ocpn_vp.pix_height = vp->pix_height;
2596 wxPoint ret = ocpn_vp.GetPixFromLL(lat, lon);
2601 void GetDoubleCanvasPixLL(
PlugIn_ViewPort* vp, wxPoint2DDouble* pp,
double lat,
2605 ocpn_vp.clat = vp->clat;
2606 ocpn_vp.clon = vp->clon;
2607 ocpn_vp.m_projection_type = vp->m_projection_type;
2608 ocpn_vp.view_scale_ppm = vp->view_scale_ppm;
2609 ocpn_vp.skew = vp->skew;
2610 ocpn_vp.rotation = vp->rotation;
2611 ocpn_vp.pix_width = vp->pix_width;
2612 ocpn_vp.pix_height = vp->pix_height;
2614 *pp = ocpn_vp.GetDoublePixFromLL(lat, lon);
2621 ocpn_vp.clat = vp->clat;
2622 ocpn_vp.clon = vp->clon;
2623 ocpn_vp.m_projection_type = vp->m_projection_type;
2624 ocpn_vp.view_scale_ppm = vp->view_scale_ppm;
2625 ocpn_vp.skew = vp->skew;
2626 ocpn_vp.rotation = vp->rotation;
2627 ocpn_vp.pix_width = vp->pix_width;
2628 ocpn_vp.pix_height = vp->pix_height;
2630 return ocpn_vp.GetLLFromPix(p, plat, plon);
2633 bool GetGlobalColor(wxString colorName, wxColour* pcolour) {
2634 wxColour c = GetGlobalColor(colorName);
2640 wxFont* OCPNGetFont(wxString TextElement,
int default_size) {
2641 return FontMgr::Get().GetFont(TextElement, default_size);
2644 wxFont* GetOCPNScaledFont_PlugIn(wxString TextElement,
int default_size) {
2645 return GetOCPNScaledFont(TextElement, default_size);
2648 double GetOCPNGUIToolScaleFactor_PlugIn(
int GUIScaleFactor) {
2649 return g_Platform->GetToolbarScaleFactor(GUIScaleFactor);
2652 double GetOCPNGUIToolScaleFactor_PlugIn() {
2653 return g_Platform->GetToolbarScaleFactor(g_GUIScaleFactor);
2656 float GetOCPNChartScaleFactor_Plugin() {
2657 return g_Platform->GetChartScaleFactorExp(g_ChartScaleFactor);
2660 wxFont GetOCPNGUIScaledFont_PlugIn(wxString item) {
2661 return GetOCPNGUIScaledFont(item);
2664 bool AddPersistentFontKey(wxString TextElement) {
2665 return FontMgr::Get().AddAuxKey(TextElement);
2668 wxString GetActiveStyleName() {
2670 return g_StyleManager->GetCurrentStyle()->name;
2675 wxBitmap GetBitmapFromSVGFile(wxString filename,
unsigned int width,
2676 unsigned int height) {
2677 wxBitmap bmp = LoadSVG(filename, width, height);
2685 SVGDocumentPixelSize(filename, w, h);
2686 if (w == 0 || h == 0) {
2693 return LoadSVG(filename, w, h);
2697 bool IsTouchInterface_PlugIn(
void) {
return g_btouch; }
2699 wxColour GetFontColour_PlugIn(wxString TextElement) {
2700 return FontMgr::Get().GetFontColor(TextElement);
2703 wxString* GetpSharedDataLocation(
void) {
2704 return g_Platform->GetSharedDataDirPtr();
2707 ArrayOfPlugIn_AIS_Targets* GetAISTargetArray(
void) {
2708 if (!g_pAIS)
return NULL;
2710 ArrayOfPlugIn_AIS_Targets* pret =
new ArrayOfPlugIn_AIS_Targets;
2713 for (
const auto& it : g_pAIS->GetTargetList()) {
2714 auto td = it.second;
2722 td.n_alarm_state = AIS_ALARM_SET;
2729 wxAuiManager* GetFrameAuiManager(
void) {
return g_pauimgr; }
2731 bool AddLocaleCatalog(wxString catalog) {
2732 #if wxUSE_XLOCALE || !wxCHECK_VERSION(3, 0, 0)
2734 if (plocale_def_lang) {
2736 g_locale_catalog_array.Add(catalog);
2738 return plocale_def_lang->AddCatalog(catalog);
2744 void PushNMEABuffer(wxString buf) {
2745 std::string full_sentence = buf.ToStdString();
2747 if ((full_sentence[0] ==
'$') || (full_sentence[0] ==
'!')) {
2748 std::string identifier;
2750 identifier = full_sentence.substr(1, 5);
2754 auto address = std::make_shared<NavAddr0183>(
"virtual");
2756 std::make_shared<const Nmea0183Msg>(identifier, full_sentence, address);
2757 auto msg_all = std::make_shared<const Nmea0183Msg>(*msg,
"ALL");
2759 auto& msgbus = NavMsgBus::GetInstance();
2761 msgbus.Notify(std::move(msg));
2762 msgbus.Notify(std::move(msg_all));
2766 wxXmlDocument GetChartDatabaseEntryXML(
int dbIndex,
bool b_getGeom) {
2767 wxXmlDocument doc = ChartData->GetXMLDescription(dbIndex, b_getGeom);
2772 bool UpdateChartDBInplace(wxArrayString dir_array,
bool b_force_update,
2773 bool b_ProgressDialog) {
2775 ArrayOfCDI ChartDirArray;
2776 for (
unsigned int i = 0; i < dir_array.GetCount(); i++) {
2777 wxString dirname = dir_array[i];
2779 cdi.fullpath = dirname;
2780 cdi.magic_number = _T(
"");
2781 ChartDirArray.Add(cdi);
2783 bool b_ret = gFrame->UpdateChartDatabaseInplace(ChartDirArray, b_force_update,
2785 ChartData->GetDBFileName());
2786 gFrame->ChartsRefresh();
2790 wxArrayString GetChartDBDirArrayString() {
2791 return ChartData->GetChartDirArrayString();
2794 int AddChartToDBInPlace(wxString& full_path,
bool b_RefreshCanvas) {
2796 wxFileName fn(full_path);
2797 wxString fdir = fn.GetPath();
2801 bret = ChartData->AddSingleChart(full_path);
2805 pConfig->UpdateChartDirs(ChartData->GetChartDirArray());
2806 ChartData->SaveBinary(ChartListFileName);
2809 ArrayOfCDI XnewChartDirArray;
2810 pConfig->LoadChartDirArray(XnewChartDirArray);
2813 ChartData->LoadBinary(ChartListFileName, XnewChartDirArray);
2816 if (g_pGroupArray) ChartData->ApplyGroupArray(g_pGroupArray);
2818 if (g_boptionsactive) {
2819 g_options->UpdateDisplayedChartDirList(ChartData->GetChartDirArray());
2822 if (b_RefreshCanvas || !gFrame->GetPrimaryCanvas()->GetQuiltMode()) {
2823 gFrame->ChartsRefresh();
2830 int RemoveChartFromDBInPlace(wxString& full_path) {
2833 bret = ChartData->RemoveSingleChart(full_path);
2836 pConfig->UpdateChartDirs(ChartData->GetChartDirArray());
2837 ChartData->SaveBinary(ChartListFileName);
2840 ArrayOfCDI XnewChartDirArray;
2841 pConfig->LoadChartDirArray(XnewChartDirArray);
2844 ChartData->LoadBinary(ChartListFileName, XnewChartDirArray);
2847 if (g_pGroupArray) ChartData->ApplyGroupArray(g_pGroupArray);
2849 if (g_boptionsactive) {
2850 g_options->UpdateDisplayedChartDirList(ChartData->GetChartDirArray());
2853 gFrame->ChartsRefresh();
2859 wxString GetLocaleCanonicalName() {
return g_locale; }
2861 void SendPluginMessage(wxString message_id, wxString message_body) {
2862 s_ppim->SendMessageToAllPlugins(message_id, message_body);
2870 Nevent.SetID(message_id);
2871 Nevent.SetJSONText(message_body);
2872 gFrame->GetEventHandler()->AddPendingEvent(Nevent);
2875 void DimeWindow(wxWindow* win) { DimeControl(win); }
2877 void JumpToPosition(
double lat,
double lon,
double scale) {
2878 gFrame->JumpToPosition(gFrame->GetFocusCanvas(), lat, lon,
scale);
2882 wxScrolledWindow* AddOptionsPage(OptionsParentPI parent, wxString title) {
2883 if (!g_pOptions)
return NULL;
2887 case PI_OPTIONS_PARENT_DISPLAY:
2888 parentid = g_pOptions->m_pageDisplay;
2890 case PI_OPTIONS_PARENT_CONNECTIONS:
2891 parentid = g_pOptions->m_pageConnections;
2893 case PI_OPTIONS_PARENT_CHARTS:
2894 parentid = g_pOptions->m_pageCharts;
2896 case PI_OPTIONS_PARENT_SHIPS:
2897 parentid = g_pOptions->m_pageShips;
2899 case PI_OPTIONS_PARENT_UI:
2900 parentid = g_pOptions->m_pageUI;
2902 case PI_OPTIONS_PARENT_PLUGINS:
2903 parentid = g_pOptions->m_pagePlugins;
2907 _T(
"Error in PluginManager::AddOptionsPage: Unknown parent"));
2912 return g_pOptions->AddPage(parentid, title);
2915 bool DeleteOptionsPage(wxScrolledWindow* page) {
2916 if (!g_pOptions)
return false;
2917 return g_pOptions->DeletePluginPage(page);
2921 wxString* accumulator) {
2922 if (!pos)
return false;
2925 AisError nerr = AIS_GENERIC_ERROR;
2926 if (g_pAIS) nerr = g_pAIS->DecodeSingleVDO(str, &gpd, accumulator);
2927 if (nerr == AIS_NoError) {
2928 pos->Lat = gpd.kLat;
2929 pos->Lon = gpd.kLon;
2930 pos->Cog = gpd.kCog;
2931 pos->Sog = gpd.kSog;
2932 pos->Hdt = gpd.kHdt;
2946 int GetChartbarHeight(
void) {
2948 if (g_bShowChartBar) {
2950 if (cc && cc->GetPiano()) {
2951 val = cc->GetPiano()->GetHeight();
2957 bool GetRoutepointGPX(
RoutePoint* pRoutePoint,
char* buffer,
2958 unsigned int buffer_length) {
2962 pgpx->AddGPXWaypoint(pRoutePoint);
2963 wxString gpxfilename = wxFileName::CreateTempFileName(wxT(
"gpx"));
2964 pgpx->SaveFile(gpxfilename);
2967 wxFFile gpxfile(gpxfilename);
2969 if (gpxfile.ReadAll(&s)) {
2970 if (s.Length() < buffer_length) {
2971 strncpy(buffer, (
const char*)s.mb_str(wxConvUTF8), buffer_length - 1);
2977 ::wxRemoveFile(gpxfilename);
2982 bool GetActiveRoutepointGPX(
char* buffer,
unsigned int buffer_length) {
2983 if (g_pRouteMan->IsAnyRouteActive())
2984 return GetRoutepointGPX(g_pRouteMan->GetpActivePoint(), buffer,
2990 void PositionBearingDistanceMercator_Plugin(
double lat,
double lon,
double brg,
2991 double dist,
double* dlat,
2993 PositionBearingDistanceMercator(lat, lon, brg, dist, dlat, dlon);
2996 void DistanceBearingMercator_Plugin(
double lat0,
double lon0,
double lat1,
2997 double lon1,
double* brg,
double* dist) {
2998 DistanceBearingMercator(lat0, lon0, lat1, lon1, brg, dist);
3001 double DistGreatCircle_Plugin(
double slat,
double slon,
double dlat,
3003 return DistGreatCircle(slat, slon, dlat, dlon);
3006 void toTM_Plugin(
float lat,
float lon,
float lat0,
float lon0,
double* x,
3008 toTM(lat, lon, lat0, lon0, x, y);
3011 void fromTM_Plugin(
double x,
double y,
double lat0,
double lon0,
double* lat,
3013 fromTM(x, y, lat0, lon0, lat, lon);
3016 void toSM_Plugin(
double lat,
double lon,
double lat0,
double lon0,
double* x,
3018 toSM(lat, lon, lat0, lon0, x, y);
3021 void fromSM_Plugin(
double x,
double y,
double lat0,
double lon0,
double* lat,
3023 fromSM(x, y, lat0, lon0, lat, lon);
3026 void toSM_ECC_Plugin(
double lat,
double lon,
double lat0,
double lon0,
3027 double* x,
double* y) {
3028 toSM_ECC(lat, lon, lat0, lon0, x, y);
3031 void fromSM_ECC_Plugin(
double x,
double y,
double lat0,
double lon0,
3032 double* lat,
double* lon) {
3033 fromSM_ECC(x, y, lat0, lon0, lat, lon);
3036 double toUsrDistance_Plugin(
double nm_distance,
int unit) {
3037 return toUsrDistance(nm_distance,
unit);
3040 double fromUsrDistance_Plugin(
double usr_distance,
int unit) {
3041 return fromUsrDistance(usr_distance,
unit);
3044 double toUsrSpeed_Plugin(
double kts_speed,
int unit) {
3045 return toUsrSpeed(kts_speed,
unit);
3048 double toUsrWindSpeed_Plugin(
double kts_speed,
int unit) {
3049 return toUsrWindSpeed(kts_speed,
unit);
3052 double fromUsrSpeed_Plugin(
double usr_speed,
int unit) {
3053 return fromUsrSpeed(usr_speed,
unit);
3056 double fromUsrWindSpeed_Plugin(
double usr_wspeed,
int unit) {
3057 return fromUsrWindSpeed(usr_wspeed,
unit);
3060 double toUsrTemp_Plugin(
double cel_temp,
int unit) {
3061 return toUsrTemp(cel_temp,
unit);
3064 double fromUsrTemp_Plugin(
double usr_temp,
int unit) {
3065 return fromUsrTemp(usr_temp,
unit);
3068 wxString getUsrDistanceUnit_Plugin(
int unit) {
3069 return getUsrDistanceUnit(
unit);
3072 wxString getUsrSpeedUnit_Plugin(
int unit) {
return getUsrSpeedUnit(
unit); }
3074 wxString getUsrWindSpeedUnit_Plugin(
int unit) {
return getUsrWindSpeedUnit(
unit); }
3076 wxString getUsrTempUnit_Plugin(
int unit) {
return getUsrTempUnit(
unit); }
3078 bool PlugIn_GSHHS_CrossesLand(
double lat1,
double lon1,
double lat2,
3080 static bool loaded =
false;
3082 gshhsCrossesLandInit();
3086 return gshhsCrossesLand(lat1, lon1, lat2, lon2);
3097 PlugIn_Waypoint::PlugIn_Waypoint() { m_HyperlinkList = NULL; }
3099 PlugIn_Waypoint::PlugIn_Waypoint(
double lat,
double lon,
3100 const wxString& icon_ident,
3101 const wxString& wp_name,
3102 const wxString& GUID) {
3103 wxDateTime now = wxDateTime::Now();
3104 m_CreateTime = now.ToUTC();
3105 m_HyperlinkList = NULL;
3109 m_IconName = icon_ident;
3110 m_MarkName = wp_name;
3114 PlugIn_Waypoint::~PlugIn_Waypoint() {}
3117 PlugIn_Route::PlugIn_Route(
void) { pWaypointList =
new Plugin_WaypointList; }
3119 PlugIn_Route::~PlugIn_Route(
void) {
3120 pWaypointList->DeleteContents(
false);
3121 pWaypointList->Clear();
3123 delete pWaypointList;
3127 PlugIn_Track::PlugIn_Track(
void) { pWaypointList =
new Plugin_WaypointList; }
3129 PlugIn_Track::~PlugIn_Track(
void) {
3130 pWaypointList->DeleteContents(
false);
3131 pWaypointList->Clear();
3133 delete pWaypointList;
3136 wxString GetNewGUID(
void) {
return GpxDocument::GetUUID(); }
3138 bool AddCustomWaypointIcon(wxBitmap* pimage, wxString key,
3139 wxString description) {
3140 wxImage image = pimage->ConvertToImage();
3141 WayPointmanGui(*pWayPointMan).ProcessIcon(image, key, description);
3147 if (src->m_HyperlinkList ==
nullptr)
return;
3149 if (src->m_HyperlinkList->GetCount() > 0) {
3150 wxPlugin_HyperlinkListNode* linknode = src->m_HyperlinkList->GetFirst();
3155 h->DescrText = link->DescrText;
3156 h->Link = link->Link;
3157 h->LType = link->Type;
3159 dst->m_HyperlinkList->Append(h);
3161 linknode = linknode->GetNext();
3166 bool AddSingleWaypoint(
PlugIn_Waypoint* pwaypoint,
bool b_permanent) {
3171 bool b_unique =
true;
3172 wxRoutePointListNode* prpnode = pWayPointMan->GetWaypointList()->GetFirst();
3176 if (prp->m_GUID == pwaypoint->m_GUID) {
3180 prpnode = prpnode->GetNext();
3183 if (!b_unique)
return false;
3186 new RoutePoint(pwaypoint->m_lat, pwaypoint->m_lon, pwaypoint->m_IconName,
3187 pwaypoint->m_MarkName, pwaypoint->m_GUID);
3189 pWP->m_bIsolatedMark =
true;
3191 cloneHyperlinkList(pWP, pwaypoint);
3193 pWP->m_MarkDescription = pwaypoint->m_MarkDescription;
3195 if (pwaypoint->m_CreateTime.IsValid())
3196 pWP->SetCreateTime(pwaypoint->m_CreateTime);
3198 wxDateTime dtnow(wxDateTime::Now());
3199 pWP->SetCreateTime(dtnow);
3202 pWP->m_btemp = (b_permanent ==
false);
3204 pSelect->AddSelectableRoutePoint(pwaypoint->m_lat, pwaypoint->m_lon, pWP);
3205 if (b_permanent) pConfig->AddNewWayPoint(pWP, -1);
3207 if (pRouteManagerDialog && pRouteManagerDialog->IsShown())
3208 pRouteManagerDialog->UpdateWptListCtrl();
3213 bool DeleteSingleWaypoint(wxString& GUID) {
3215 bool b_found =
false;
3216 RoutePoint* prp = pWayPointMan->FindRoutePointByGUID(GUID);
3218 if (prp) b_found =
true;
3221 pWayPointMan->DestroyWaypoint(prp);
3222 if (pRouteManagerDialog && pRouteManagerDialog->IsShown())
3223 pRouteManagerDialog->UpdateWptListCtrl();
3231 bool b_found =
false;
3232 RoutePoint* prp = pWayPointMan->FindRoutePointByGUID(pwaypoint->m_GUID);
3234 if (prp) b_found =
true;
3237 double lat_save = prp->m_lat;
3238 double lon_save = prp->m_lon;
3240 prp->m_lat = pwaypoint->m_lat;
3241 prp->m_lon = pwaypoint->m_lon;
3242 prp->SetIconName(pwaypoint->m_IconName);
3243 prp->SetName(pwaypoint->m_MarkName);
3244 prp->m_MarkDescription = pwaypoint->m_MarkDescription;
3245 prp->SetVisible(pwaypoint->m_IsVisible);
3246 if (pwaypoint->m_CreateTime.IsValid())
3247 prp->SetCreateTime(pwaypoint->m_CreateTime);
3251 if (pwaypoint->m_HyperlinkList) {
3252 prp->m_HyperlinkList->Clear();
3253 if (pwaypoint->m_HyperlinkList->GetCount() > 0) {
3254 wxPlugin_HyperlinkListNode* linknode =
3255 pwaypoint->m_HyperlinkList->GetFirst();
3260 h->DescrText = link->DescrText;
3261 h->Link = link->Link;
3262 h->LType = link->Type;
3264 prp->m_HyperlinkList->Append(h);
3266 linknode = linknode->GetNext();
3271 if (prp) prp->ReLoadIcon();
3273 auto canvas = gFrame->GetPrimaryCanvas();
3274 SelectCtx ctx(canvas->m_bShowNavobjects, canvas->GetCanvasTrueScale(), canvas->GetScaleValue());
3276 pSelect->FindSelection(ctx, lat_save, lon_save, SELTYPE_ROUTEPOINT);
3278 pFind->m_slat = pwaypoint->m_lat;
3279 pFind->m_slon = pwaypoint->m_lon;
3282 if (!prp->m_btemp) pConfig->UpdateWayPoint(prp);
3284 if (pRouteManagerDialog && pRouteManagerDialog->IsShown())
3285 pRouteManagerDialog->UpdateWptListCtrl();
3294 dst->m_lat = src->m_lat;
3295 dst->m_lon = src->m_lon;
3296 dst->m_IconName = src->GetIconName();
3297 dst->m_MarkName = src->GetName();
3298 dst->m_MarkDescription = src->m_MarkDescription;
3299 dst->m_IsVisible = src->IsVisible();
3300 dst->m_CreateTime = src->GetCreateTime();
3301 dst->m_GUID = src->m_GUID;
3304 if (src->m_HyperlinkList ==
nullptr)
return;
3306 delete dst->m_HyperlinkList;
3307 dst->m_HyperlinkList =
nullptr;
3309 if (src->m_HyperlinkList->GetCount() > 0) {
3310 dst->m_HyperlinkList =
new Plugin_HyperlinkList;
3312 wxHyperlinkListNode* linknode = src->m_HyperlinkList->GetFirst();
3317 h->DescrText = link->DescrText;
3318 h->Link = link->Link;
3319 h->Type = link->LType;
3321 dst->m_HyperlinkList->Append(h);
3323 linknode = linknode->GetNext();
3330 RoutePoint* prp = pWayPointMan->FindRoutePointByGUID(GUID);
3332 if (!prp)
return false;
3334 PlugInFromRoutePoint(pwaypoint, prp);
3339 wxArrayString GetWaypointGUIDArray(
void) {
3340 wxArrayString result;
3341 RoutePointList* list = pWayPointMan->GetWaypointList();
3343 wxRoutePointListNode* prpnode = list->GetFirst();
3346 result.Add(prp->m_GUID);
3348 prpnode = prpnode->GetNext();
3354 wxArrayString GetRouteGUIDArray(
void) {
3355 wxArrayString result;
3356 RouteList* list = pRouteList;
3358 wxRouteListNode* prpnode = list->GetFirst();
3360 Route* proute = prpnode->GetData();
3361 result.Add(proute->m_GUID);
3363 prpnode = prpnode->GetNext();
3369 wxArrayString GetTrackGUIDArray(
void) {
3370 wxArrayString result;
3371 for (
Track* ptrack : g_TrackList) {
3372 result.Add(ptrack->m_GUID);
3378 wxArrayString GetWaypointGUIDArray(OBJECT_LAYER_REQ req) {
3379 wxArrayString result;
3380 RoutePointList* list = pWayPointMan->GetWaypointList();
3382 wxRoutePointListNode* prpnode = list->GetFirst();
3387 result.Add(prp->m_GUID);
3389 case OBJECTS_NO_LAYERS:
3390 if (!prp->m_bIsInLayer) result.Add(prp->m_GUID);
3392 case OBJECTS_ONLY_LAYERS:
3393 if (prp->m_bIsInLayer) result.Add(prp->m_GUID);
3397 prpnode = prpnode->GetNext();
3403 wxArrayString GetRouteGUIDArray(OBJECT_LAYER_REQ req) {
3404 wxArrayString result;
3405 RouteList* list = pRouteList;
3407 wxRouteListNode* prpnode = list->GetFirst();
3409 Route* proute = prpnode->GetData();
3412 result.Add(proute->m_GUID);
3414 case OBJECTS_NO_LAYERS:
3415 if (!proute->m_bIsInLayer) result.Add(proute->m_GUID);
3417 case OBJECTS_ONLY_LAYERS:
3418 if (proute->m_bIsInLayer) result.Add(proute->m_GUID);
3422 prpnode = prpnode->GetNext();
3428 wxArrayString GetTrackGUIDArray(OBJECT_LAYER_REQ req) {
3429 wxArrayString result;
3430 for (
Track* ptrack : g_TrackList) {
3433 result.Add(ptrack->m_GUID);
3435 case OBJECTS_NO_LAYERS:
3436 if (!ptrack->m_bIsInLayer) result.Add(ptrack->m_GUID);
3438 case OBJECTS_ONLY_LAYERS:
3439 if (ptrack->m_bIsInLayer) result.Add(ptrack->m_GUID);
3447 wxArrayString GetIconNameArray(
void) {
3448 wxArrayString result;
3450 for (
int i = 0; i < pWayPointMan->GetNumIcons(); i++) {
3451 wxString* ps = pWayPointMan->GetIconKey(i);
3457 bool AddPlugInRoute(
PlugIn_Route* proute,
bool b_permanent) {
3463 wxDateTime plannedDeparture;
3465 wxPlugin_WaypointListNode* pwpnode = proute->pWaypointList->GetFirst();
3467 pwp = pwpnode->GetData();
3470 pwp->m_MarkName, pwp->m_GUID);
3473 cloneHyperlinkList(pWP, pwp);
3474 pWP->m_MarkDescription = pwp->m_MarkDescription;
3475 pWP->m_bShowName =
false;
3476 pWP->SetCreateTime(pwp->m_CreateTime);
3478 route->AddPoint(pWP);
3480 pSelect->AddSelectableRoutePoint(pWP->m_lat, pWP->m_lon, pWP);
3483 pSelect->AddSelectableRouteSegment(pWP_src->m_lat, pWP_src->m_lon,
3484 pWP->m_lat, pWP->m_lon, pWP_src, pWP,
3487 plannedDeparture = pwp->m_CreateTime;
3491 pwpnode = pwpnode->GetNext();
3494 route->m_PlannedDeparture = plannedDeparture;
3496 route->m_RouteNameString = proute->m_NameString;
3497 route->m_RouteStartString = proute->m_StartString;
3498 route->m_RouteEndString = proute->m_EndString;
3499 if (!proute->m_GUID.IsEmpty()) {
3500 route->m_GUID = proute->m_GUID;
3502 route->m_btemp = (b_permanent ==
false);
3504 pRouteList->Append(route);
3506 if (b_permanent) pConfig->AddNewRoute(route);
3508 if (pRouteManagerDialog && pRouteManagerDialog->IsShown())
3509 pRouteManagerDialog->UpdateRouteListCtrl();
3514 bool DeletePlugInRoute(wxString& GUID) {
3515 bool b_found =
false;
3518 Route* pRoute = g_pRouteMan->FindRouteByGUID(GUID);
3520 g_pRouteMan->
DeleteRoute(pRoute, NavObjectChanges::getInstance());
3527 bool b_found =
false;
3530 Route* pRoute = g_pRouteMan->FindRouteByGUID(proute->m_GUID);
3531 if (pRoute) b_found =
true;
3534 bool b_permanent = (pRoute->m_btemp ==
false);
3535 g_pRouteMan->
DeleteRoute(pRoute, NavObjectChanges::getInstance());
3537 b_found = AddPlugInRoute(proute, b_permanent);
3543 bool AddPlugInTrack(
PlugIn_Track* ptrack,
bool b_permanent) {
3550 wxPlugin_WaypointListNode* pwpnode = ptrack->pWaypointList->GetFirst();
3552 pwp = pwpnode->GetData();
3555 pWP->SetCreateTime(pwp->m_CreateTime);
3557 track->AddPoint(pWP);
3560 pSelect->AddSelectableTrackSegment(pWP_src->m_lat, pWP_src->m_lon,
3561 pWP->m_lat, pWP->m_lon, pWP_src, pWP,
3566 pwpnode = pwpnode->GetNext();
3569 track->SetName(ptrack->m_NameString);
3570 track->m_TrackStartString = ptrack->m_StartString;
3571 track->m_TrackEndString = ptrack->m_EndString;
3572 track->m_GUID = ptrack->m_GUID;
3573 track->m_btemp = (b_permanent ==
false);
3575 g_TrackList.push_back(track);
3577 if (b_permanent) pConfig->AddNewTrack(track);
3579 if (pRouteManagerDialog && pRouteManagerDialog->IsShown())
3580 pRouteManagerDialog->UpdateTrkListCtrl();
3585 bool DeletePlugInTrack(wxString& GUID) {
3586 bool b_found =
false;
3589 Track* pTrack = g_pRouteMan->FindTrackByGUID(GUID);
3595 if (pRouteManagerDialog && pRouteManagerDialog->IsShown())
3596 pRouteManagerDialog->UpdateTrkListCtrl();
3602 bool b_found =
false;
3605 Track* pTrack = g_pRouteMan->FindTrackByGUID(ptrack->m_GUID);
3606 if (pTrack) b_found =
true;
3609 bool b_permanent = (pTrack->m_btemp ==
false);
3612 b_found = AddPlugInTrack(ptrack, b_permanent);
3621 ocpn_vp.m_projection_type = vp->m_projection_type;
3623 return glChartCanvas::HasNormalizedViewPort(ocpn_vp);
3629 void PlugInMultMatrixViewport(
PlugIn_ViewPort* vp,
float lat,
float lon) {
3632 ocpn_vp.clat = vp->clat;
3633 ocpn_vp.clon = vp->clon;
3634 ocpn_vp.m_projection_type = vp->m_projection_type;
3635 ocpn_vp.view_scale_ppm = vp->view_scale_ppm;
3636 ocpn_vp.skew = vp->skew;
3637 ocpn_vp.rotation = vp->rotation;
3638 ocpn_vp.pix_width = vp->pix_width;
3639 ocpn_vp.pix_height = vp->pix_height;
3646 void PlugInNormalizeViewport(
PlugIn_ViewPort* vp,
float lat,
float lon) {
3649 glChartCanvas::NormalizedViewPort(ocpn_vp, lat, lon);
3651 vp->clat = ocpn_vp.clat;
3652 vp->clon = ocpn_vp.clon;
3653 vp->view_scale_ppm = ocpn_vp.view_scale_ppm;
3654 vp->rotation = ocpn_vp.rotation;
3655 vp->skew = ocpn_vp.skew;
3668 pret->MMSI = ptarget->MMSI;
3669 pret->Class = ptarget->Class;
3670 pret->NavStatus = ptarget->NavStatus;
3671 pret->SOG = ptarget->SOG;
3672 pret->COG = ptarget->COG;
3673 pret->HDG = ptarget->HDG;
3674 pret->Lon = ptarget->Lon;
3675 pret->Lat = ptarget->Lat;
3676 pret->ROTAIS = ptarget->ROTAIS;
3677 pret->ShipType = ptarget->ShipType;
3678 pret->IMO = ptarget->IMO;
3680 pret->Range_NM = ptarget->Range_NM;
3681 pret->Brg = ptarget->Brg;
3684 pret->bCPA_Valid = ptarget->bCPA_Valid;
3685 pret->TCPA = ptarget->TCPA;
3686 pret->CPA = ptarget->CPA;
3688 pret->alarm_state = (plugin_ais_alarm_type)ptarget->n_alert_state;
3690 memcpy(pret->CallSign, ptarget->CallSign,
sizeof(ptarget->CallSign) - 1);
3691 memcpy(pret->ShipName, ptarget->ShipName,
sizeof(ptarget->ShipName) - 1);
3700 #define DISABLED_SETTINGS_MSG \
3701 _("These settings might destabilize OpenCPN and are by default disabled." \
3702 " To despite the dangers enable them manually add a CatalogExpert=1" \
3703 " line in the [PlugIns] section in the configuration file.")
3708 CatalogMgrPanel::CatalogMgrPanel(wxWindow* parent)
3709 : wxPanel(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize),
3711 wxBoxSizer* topSizer =
new wxBoxSizer(wxVERTICAL);
3714 topSizer->Add(
new wxStaticLine(
this), 0, wxGROW | wxLEFT | wxRIGHT, 4);
3716 wxStaticBox* itemStaticBoxSizer4Static =
3717 new wxStaticBox(
this, wxID_ANY, _(
"Plugin Catalog"));
3718 wxStaticBoxSizer* itemStaticBoxSizer4 =
3719 new wxStaticBoxSizer(itemStaticBoxSizer4Static, wxVERTICAL);
3720 topSizer->Add(itemStaticBoxSizer4, 1, wxEXPAND | wxALL, 2);
3724 m_catalogText =
new wxStaticText(
this, wxID_STATIC, _T(
""));
3725 itemStaticBoxSizer4->Add(m_catalogText,
3726 wxSizerFlags().Border().Proportion(1));
3727 m_catalogText->SetLabel(GetCatalogText(
false));
3730 wxBoxSizer* rowSizer2 =
new wxBoxSizer(wxHORIZONTAL);
3731 itemStaticBoxSizer4->Add(rowSizer2,
3732 wxSizerFlags().Expand().Border().Proportion(1));
3734 m_updateButton =
new wxButton(
this, wxID_ANY, _(
"Update Plugin Catalog"),
3735 wxDefaultPosition, wxDefaultSize, 0);
3736 rowSizer2->Add(m_updateButton, 0, wxALIGN_LEFT);
3737 m_updateButton->Bind(wxEVT_COMMAND_BUTTON_CLICKED,
3738 &CatalogMgrPanel::OnUpdateButton,
this);
3739 rowSizer2->AddSpacer(4 * GetCharWidth());
3740 m_tarballButton =
new wxButton(
this, wxID_ANY, _(
"Import plugin..."),
3741 wxDefaultPosition, wxDefaultSize, 0);
3742 rowSizer2->Add(m_tarballButton, 0, wxALIGN_LEFT | wxLEFT, 2 * GetCharWidth());
3743 m_tarballButton->Bind(wxEVT_COMMAND_BUTTON_CLICKED,
3744 &CatalogMgrPanel::OnTarballButton,
this);
3746 rowSizer2->AddSpacer(4 * GetCharWidth());
3747 m_adv_button =
new wxButton(
this, wxID_ANY, _(
"Settings..."),
3748 wxDefaultPosition, wxDefaultSize, 0);
3750 if (expert.Get(
false)) {
3751 m_adv_button->Bind(wxEVT_COMMAND_BUTTON_CLICKED,
3752 &CatalogMgrPanel::OnPluginSettingsButton,
this);
3754 m_adv_button->Bind(wxEVT_COMMAND_BUTTON_CLICKED, [&](wxCommandEvent&) {
3755 wxMessageBox(DISABLED_SETTINGS_MSG, _(
"Disabled"));
3758 rowSizer2->AddSpacer(4 * GetCharWidth());
3759 rowSizer2->Add(m_adv_button, 0, wxALIGN_LEFT);
3761 SetUpdateButtonLabel();
3764 wxBoxSizer* rowSizer3 =
new wxBoxSizer(wxHORIZONTAL);
3765 itemStaticBoxSizer4->Add(rowSizer3, 0, wxEXPAND | wxALL, 4);
3767 SetMinSize(wxSize(m_parent->GetClientSize().x - (4 * GetCharWidth()), -1));
3772 catalog_listener.Listen(catalog,
this, EVT_CATALOG_CHANGE);
3773 Bind(EVT_CATALOG_CHANGE, [&](wxCommandEvent&) { SetUpdateButtonLabel(); });
3776 SetBackgroundColour(wxColour(0x7c, 0xb0, 0xe9));
3778 if (!expert.Get(
false)) {
3780 new wxButton(
this, wxID_ANY, _(
"Update Plugin Catalog: master"),
3781 wxDefaultPosition, wxDefaultSize, 0);
3782 itemStaticBoxSizer4->Add(m_updateButton, 0, wxALIGN_LEFT);
3783 m_updateButton->Bind(wxEVT_COMMAND_BUTTON_CLICKED,
3784 &CatalogMgrPanel::OnUpdateButton,
this);
3785 SetUpdateButtonLabel();
3786 m_tarballButton = NULL;
3787 m_adv_button = NULL;
3790 m_catalogText =
new wxStaticText(
this, wxID_STATIC, GetCatalogText(
false));
3791 itemStaticBoxSizer4->Add(m_catalogText,
3792 wxSizerFlags().Border(wxALL, 5).Proportion(1));
3795 m_updateButton =
new wxButton(
3796 this, wxID_ANY,
"Update Plugin Catalog:master ",
3797 wxDefaultPosition, wxDefaultSize, 0);
3798 itemStaticBoxSizer4->Add(m_updateButton, 0, wxALIGN_LEFT | wxTOP, 5);
3799 m_updateButton->Bind(wxEVT_COMMAND_BUTTON_CLICKED,
3800 &CatalogMgrPanel::OnUpdateButton,
this);
3801 SetUpdateButtonLabel();
3804 m_adv_button =
new wxButton(
this, wxID_ANY, _(
"Settings..."),
3805 wxDefaultPosition, wxDefaultSize, 0);
3806 itemStaticBoxSizer4->Add(m_adv_button, 0, wxALIGN_LEFT | wxTOP,
3808 m_adv_button->Bind(wxEVT_COMMAND_BUTTON_CLICKED,
3809 &CatalogMgrPanel::OnPluginSettingsButton,
this);
3812 m_tarballButton =
new wxButton(
this, wxID_ANY, _(
"Import plugin..."),
3813 wxDefaultPosition, wxDefaultSize, 0);
3814 itemStaticBoxSizer4->Add(m_tarballButton, 0, wxALIGN_LEFT | wxALL,
3815 2 * GetCharWidth());
3816 m_tarballButton->Bind(wxEVT_COMMAND_BUTTON_CLICKED,
3817 &CatalogMgrPanel::OnTarballButton,
this);
3823 CatalogMgrPanel::~CatalogMgrPanel() {
3824 m_updateButton->Unbind(wxEVT_COMMAND_BUTTON_CLICKED,
3825 &CatalogMgrPanel::OnUpdateButton,
this);
3826 if (m_tarballButton)
3827 m_tarballButton->Unbind(wxEVT_COMMAND_BUTTON_CLICKED,
3828 &CatalogMgrPanel::OnTarballButton,
this);
3831 static const char*
const DOWNLOAD_REPO_PROTO =
3832 "https://raw.githubusercontent.com/OpenCPN/plugins/@branch@/"
3835 void CatalogMgrPanel::OnUpdateButton(wxCommandEvent& event) {
3837 std::string catalog(g_catalog_channel ==
"" ?
"master" : g_catalog_channel);
3838 std::string url(g_catalog_custom_url);
3839 if (catalog !=
"custom") {
3840 url = std::string(DOWNLOAD_REPO_PROTO);
3841 ocpn::replace(url,
"@branch@", catalog);
3844 std::string filePath =
3845 wxFileName::CreateTempFileName(
"ocpn_dl").ToStdString();
3847 auto catalogHdlr = CatalogHandler::getInstance();
3849 g_Platform->ShowBusySpinner();
3850 auto status = catalogHdlr->DownloadCatalog(filePath, url);
3851 g_Platform->HideBusySpinner();
3853 std::string message;
3854 if (status != CatalogHandler::ServerStatus::OK) {
3855 message = _(
"Cannot download data from url");
3856 OCPNMessageBox(
this, message, _(
"OpenCPN Catalog update"),
3857 wxICON_ERROR | wxOK);
3863 if (!AndroidSecureCopyFile(wxString(filePath.c_str()),
3865 wxFileName::GetPathSeparator() +
3866 _T(
"ocpn-plugins.xml"))) {
3867 OCPNMessageBox(
this, _(
"Unable to copy catalog file"),
3868 _(
"OpenCPN Catalog update"), wxICON_ERROR | wxOK);
3873 if (!wxCopyFile(wxString(filePath.c_str()),
3875 wxFileName::GetPathSeparator() +
3876 _T(
"ocpn-plugins.xml"))) {
3877 OCPNMessageBox(
this, _(
"Unable to copy catalog file"),
3878 _(
"OpenCPN Catalog update"), wxICON_ERROR | wxOK);
3884 if (catalog ==
"master") {
3886 OCPNMessageBox(
this, _(
"Unable to copy catalog file to cache"),
3887 _(
"OpenCPN Catalog update"), wxICON_ERROR | wxOK);
3893 pConfig->SetPath(_T(
"/PlugIns/"));
3894 pConfig->Write(
"LatestCatalogDownloaded", catalog.c_str());
3900 auto pluginHandler = PluginHandler::getInstance();
3901 pluginHandler->setMetadata(
"");
3905 auto cataloghdlr = CatalogHandler::getInstance();
3906 cataloghdlr->ClearCatalogData();
3910 LoadAllPlugIns(
false);
3914 m_catalogText->SetLabel(GetCatalogText(
true));
3917 OCPNMessageBox(
this, _(
"Catalog update successful"),
3918 _(
"OpenCPN Catalog update"), wxICON_INFORMATION | wxOK);
3921 void CatalogMgrPanel::OnPluginSettingsButton(wxCommandEvent& event) {
3925 androidDisableRotation();
3928 dialog->ShowModal();
3931 androidEnableRotation();
3935 void CatalogMgrPanel::OnTarballButton(wxCommandEvent& event) {
3938 int response = g_Platform->DoFileSelectorDialog(
3939 this, &path, _(
"Select tarball file"), GetImportInitDir(),
"",
3940 "tar files (*.tar.gz)|*.tar.gz|All Files (*.*)|*.*");
3942 if (response != wxID_OK) {
3945 auto handler = PluginHandler::getInstance();
3947 bool ok = handler->ExtractMetadata(path.ToStdString(), metadata);
3949 OCPNMessageBox(
this, _(
"Error extracting metadata from tarball."),
3950 _(
"OpenCPN Plugin Import Error"));
3954 OCPNMessageBox(
this, _(
"Incompatible import plugin detected."),
3955 _(
"OpenCPN Plugin Import Error"));
3956 handler->uninstall(metadata.name);
3959 UninstallPlugin(metadata.name);
3960 ok = handler->installPlugin(metadata, path.ToStdString());
3962 OCPNMessageBox(
this, _(
"Error extracting import plugin tarball."),
3963 _(
"OpenCPN Plugin Import Error"));
3966 metadata.is_imported =
true;
3968 std::ofstream file(metadata_path);
3971 WARNING_LOG <<
"Error saving metadata file: " << metadata_path
3972 <<
" for imported plugin: " << metadata.name;
3974 LoadAllPlugIns(
false,
true);
3977 wxString ws(_(
"Plugin"));
3978 ws += metadata.name + _(
" successfully imported");
3979 OCPNMessageBox(gFrame, ws, _(
"Installation complete"),
3980 wxICON_INFORMATION | wxOK | wxCENTRE);
3983 wxString CatalogMgrPanel::GetCatalogText(
bool updated) {
3985 catalog = updated ? _(
"Active Catalog") : _(
"Last Catalog");
3986 catalog += _T(
": ");
3989 pConfig->SetPath(_T(
"/PlugIns/"));
3990 wxString latestCatalog =
3991 pConfig->Read(_T(
"LatestCatalogDownloaded"), _T(
"default"));
3992 catalog += latestCatalog;
3997 auto pluginHandler = PluginHandler::getInstance();
3998 std::string date = pluginHandler->GetCatalogData()->date;
4000 catalog += wxString(
" ") + _(
"Last change: ") +
" " + date;
4001 if (!updated) catalog += _T(
" : ") + _(
"Please Update Plugin Catalog.");
4007 void CatalogMgrPanel::SetUpdateButtonLabel() {
4008 wxString label = _(
"Update Plugin Catalog");
4010 label += g_catalog_channel ==
"" ?
"master" : g_catalog_channel;
4011 m_updateButton->SetLabel(label);
4015 wxString CatalogMgrPanel::GetImportInitDir() {
4017 pConfig->SetPath(_T(
"/PlugIns/"));
4018 wxString lastImportDir;
4019 lastImportDir = pConfig->Read(_T(
"LatestImportDir"),
4020 g_Platform->GetWritableDocumentsDir());
4021 if (wxDirExists(lastImportDir)) {
4022 return lastImportDir;
4024 return (g_Platform->GetWritableDocumentsDir());
4033 const wxPoint& pos, const wxSize& size)
4034 : wxScrolledWindow(parent,
id, pos, size, wxTAB_TRAVERSAL | wxVSCROLL),
4035 m_PluginSelected(0) {
4036 m_is_loading.clear();
4037 SetSizer(
new wxBoxSizer(wxVERTICAL));
4038 ReloadPluginPanels();
4041 void PluginListPanel::SelectByName(wxString& name) {
4042 for (
auto it = GetChildren().GetFirst(); it; it = it->GetNext()) {
4043 auto pluginPanel =
dynamic_cast<PluginPanel*
>(it->GetData());
4045 if (pluginPanel->GetPluginPtr()->m_common_name.IsSameAs(name)) {
4046 pluginPanel->SetSelected(
true);
4047 pluginPanel->Layout();
4048 SelectPlugin(pluginPanel);
4056 std::vector<const PlugInData*> GetInstalled() {
4057 std::vector<const PlugInData*> result;
4058 auto loader = PluginLoader::getInstance();
4059 for (
size_t i = 0; i < loader->GetPlugInArray()->GetCount(); i++) {
4060 auto const item = loader->GetPlugInArray()->Item(i);
4061 if (item->m_managed_metadata.name.empty()) {
4062 const auto name = item->m_common_name.ToStdString();
4066 result.push_back(item);
4069 std::string slhs, srhs;
4070 for (
auto &cl : lhs->
Key()) slhs += toupper(cl);
4071 for (
auto &cr : rhs->Key()) srhs += toupper(cr);
4072 return slhs.compare(srhs) < 0;
4074 std::sort(result.begin(), result.end(), compare);
4079 static bool IsPluginLoaded(
const std::string& name) {
4080 if (safe_mode::get_mode()) {
4083 std::find(installed.begin(), installed.end(), ocpn::tolower(name));
4084 return found != installed.end();
4086 auto loaded = PluginLoader::getInstance()->GetPlugInArray();
4087 for (
size_t i = 0; i < loaded->GetCount(); i++) {
4088 if (loaded->Item(i)->m_common_name.ToStdString() == name)
return true;
4095 if (m_is_loading.test_and_set()) {
4097 DEBUG_LOG <<
"LoadAllPlugins: recursive invocation";
4101 auto plugins = PluginLoader::getInstance()->GetPlugInArray();
4102 m_PluginItems.Clear();
4104 wxWindowList kids = GetChildren();
4105 for (
unsigned int i = 0; i < kids.GetCount(); i++) {
4106 wxWindowListNode* node = kids.Item(i);
4107 wxWindow* win = node->GetData();
4109 if (pp) win->Destroy();
4111 GetSizer()->Clear();
4114 m_PluginSelected = 0;
4116 if (safe_mode::get_mode()) {
4119 for (
const auto& name : installed) AddPlugin(name) ;
4122 auto available = getCompatiblePlugins();
4126 return IsPluginLoaded(md.name);
4128 auto end = std::remove_if(available.begin(), available.end(), predicate);
4129 available.erase(end, available.end());
4134 std::string slhs, srhs;
4135 for (
auto &cl : lhs.name) slhs += toupper(cl);
4136 for (
auto &cr : rhs.name) srhs += toupper(cr);
4137 return slhs.compare(srhs) < 0;
4141 std::set<PluginMetadata, CompSort> unique_sorted_entries(comp_sort);
4142 for (
const auto& p : available) unique_sorted_entries.insert(p);
4147 for (
const auto& p : GetInstalled())
4148 if (p->m_enabled) AddPlugin(*p);
4151 for (
const auto& p : GetInstalled())
4152 if (!p->m_enabled) AddPlugin(*p);
4155 for (
const auto& p : unique_sorted_entries) AddPlugin(
PlugInData(p));
4163 m_is_loading.clear();
4166 void PluginListPanel::AddPlugin(
const std::string& name) {
4169 panel->SetSelected(
false);
4170 GetSizer()->Add(panel, 0, wxEXPAND);
4171 m_PluginItems.Add(panel);
4172 m_pluginSpacer = g_Platform->GetDisplayDPmm() * 1.0;
4173 GetSizer()->AddSpacer(m_pluginSpacer);
4176 void PluginListPanel::AddPlugin(
const PlugInData& pic) {
4178 new PluginPanel(
this, wxID_ANY, wxDefaultPosition, wxDefaultSize, pic);
4179 pPluginPanel->SetSelected(
false);
4180 GetSizer()->Add(pPluginPanel, 0, wxEXPAND);
4181 m_PluginItems.Add(pPluginPanel);
4183 m_pluginSpacer = g_Platform->GetDisplayDPmm() * 1.0;
4184 GetSizer()->AddSpacer(m_pluginSpacer);
4197 int PluginListPanel::ComputePluginSpace(ArrayOfPluginPanel plugins,
4198 wxBoxSizer* sizer) {
4200 for (
size_t i = 0; i < plugins.GetCount(); i++) {
4201 auto panel = plugins.Item(i);
4202 bool was_selected = panel->GetSelected();
4203 panel->SetSelected(
false);
4205 wxSize unselected = panel->GetSize();
4207 panel->SetSelected(
true);
4209 wxSize selected = panel->GetSize();
4211 int dy = selected.GetHeight() - unselected.GetHeight();
4212 max_dy = wxMax(max_dy, dy);
4213 panel->SetSelected(was_selected);
4218 PluginListPanel::~PluginListPanel() {}
4220 void PluginListPanel::UpdateSelections() {
4221 for (
unsigned int i = 0; i < m_PluginItems.GetCount(); i++) {
4224 pPluginPanel->SetSelected(pPluginPanel->GetSelected());
4229 void PluginListPanel::SelectPlugin(
PluginPanel* pi) {
4231 GetViewStart(&xs, &ys);
4234 if (m_PluginSelected) {
4235 m_PluginSelected->SetSelected(
false);
4236 m_PluginSelected->Layout();
4239 if (pi == NULL) m_PluginSelected->SetSelected(
false);
4241 m_PluginSelected = pi;
4243 GetSizer()->Layout();
4245 wxSize size = GetBestVirtualSize();
4246 SetVirtualSize(size);
4251 for (
unsigned int i = 0; i < m_PluginItems.GetCount(); i++) {
4253 int yd = pPluginPanel->GetSize().y;
4255 htop += m_pluginSpacer;
4256 if (pPluginPanel == pi) {
4257 int piBottom = htop - (ys * g_options->GetScrollRate());
4258 if (piBottom > GetClientSize().y) {
4259 ys += (piBottom - GetClientSize().y) / g_options->GetScrollRate();
4269 int pos = m_PluginItems.Index(pi);
4272 m_PluginItems.RemoveAt(pos);
4275 m_PluginItems.Insert(pi, pos - 1);
4276 wxStaticLine* itemStaticLine =
new wxStaticLine(
4277 this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL);
4282 m_PluginSelected = pi;
4284 GetSizer()->Layout();
4290 int pos = m_PluginItems.Index(pi);
4291 if (pos == (
int)m_PluginItems.Count() -
4294 m_PluginItems.RemoveAt(pos);
4297 m_PluginItems.Insert(pi, pos + 1);
4298 wxStaticLine* itemStaticLine =
new wxStaticLine(
4299 this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL);
4304 m_PluginSelected = pi;
4306 GetSizer()->Layout();
4311 static bool canUninstall(std::string name) {
4312 PluginHandler* pluginHandler = PluginHandler::getInstance();
4316 if (plugin.name == name) {
4317 if (safe_mode::get_mode())
4320 return !plugin.readonly;
4327 : wxPanel(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize,
4329 m_is_safe_panel(true) {
4332 wxASSERT(m_PluginListPanel != 0);
4333 wxBoxSizer* top_sizer =
new wxBoxSizer(wxVERTICAL);
4334 SetSizer(top_sizer);
4335 wxBoxSizer* top_horizontal =
new wxBoxSizer(wxHORIZONTAL);
4336 top_sizer->Add(top_horizontal, 0, wxEXPAND);
4338 double iconSize = GetCharWidth() * 4;
4339 double dpi_mult = g_Platform->GetDisplayDIPMult(
this);
4340 int icon_scale = iconSize * dpi_mult;
4342 wxBitmap bitmap(style->GetIcon(
"default_pi", icon_scale, icon_scale));
4343 m_itemStaticBitmap =
new wxStaticBitmap(
this, wxID_ANY, bitmap);
4344 top_horizontal->Add(m_itemStaticBitmap, 0, wxEXPAND | wxALL, 10);
4346 m_pName =
new wxStaticText(
this, wxID_ANY, name);
4347 top_horizontal->Add(m_pName, wxID_ANY, wxALIGN_CENTER_VERTICAL);
4348 m_pVersion =
new wxStaticText(
this, wxID_ANY,
"");
4349 top_horizontal->Add(m_pVersion);
4352 m_pButtons =
new wxBoxSizer(wxHORIZONTAL);
4353 top_horizontal->Add(m_pButtons);
4354 m_info_btn =
new WebsiteButton(
this,
"https:\\opencpn.org");
4355 top_horizontal->Add(m_info_btn);
4356 m_pButtonUninstall =
new wxButton(
this, wxID_ANY, _(
"Uninstall"),
4357 wxDefaultPosition, wxDefaultSize, 0);
4358 top_horizontal->Add(m_pButtonUninstall, 0,
4359 wxALIGN_CENTER_VERTICAL | wxALL, 2);
4360 auto uninstall = [&](wxCommandEvent ev) {
4361 auto n = m_pName->GetLabel().ToStdString();
4362 int result = OCPNMessageBox(gFrame,
4363 std::string(_(
"Uninstall plugin ")) + n +
"?",
4364 _(
"Un-Installation"),
4365 wxICON_QUESTION | wxOK | wxCANCEL);
4366 if (result != wxID_OK)
return;
4370 m_pButtonUninstall->Bind(wxEVT_COMMAND_BUTTON_CLICKED, uninstall);
4374 EVT_PAINT(PluginPanel::OnPaint)
4379 : wxPanel(parent,
id, pos, size, wxBORDER_NONE),
4381 m_is_safe_panel(false) {
4384 wxASSERT(m_PluginListPanel != 0);
4386 m_bSelected =
false;
4387 m_penWidthUnselected = g_Platform->GetDisplayDPmm() * .25;
4388 m_penWidthSelected = g_Platform->GetDisplayDPmm() * .5;
4390 wxBoxSizer* topSizer =
new wxBoxSizer(wxVERTICAL);
4393 wxBoxSizer* itemBoxSizer01 =
new wxBoxSizer(wxHORIZONTAL);
4394 topSizer->Add(itemBoxSizer01, 0, wxEXPAND);
4395 Bind(wxEVT_LEFT_DOWN, &PluginPanel::OnPluginSelected,
this);
4396 Bind(wxEVT_LEFT_UP, &PluginPanel::OnPluginSelectedUp,
this);
4398 double iconSize = GetCharWidth() * 4;
4399 double dpi_mult = g_Platform->GetDisplayDIPMult(
this);
4400 int icon_scale = iconSize * dpi_mult;
4402 wxImage plugin_icon;
4404 if (m_plugin.m_bitmap.IsOk()) {
4405 plugin_icon = m_plugin.m_bitmap.ConvertToImage();
4408 if (m_plugin.m_status == PluginStatus::ManagedInstallAvailable) {
4409 wxFileName path(g_Platform->GetSharedDataDir(),
"packageBox.svg");
4410 path.AppendDir(
"uidata");
4411 path.AppendDir(
"traditional");
4412 bitmap = LoadSVG(path.GetFullPath(), icon_scale, icon_scale);
4413 }
else if (plugin_icon.IsOk()) {
4414 int nowSize = plugin_icon.GetWidth();
4415 plugin_icon.Rescale(icon_scale, icon_scale, wxIMAGE_QUALITY_HIGH);
4416 bitmap = wxBitmap(plugin_icon);
4418 bitmap = wxBitmap(style->GetIcon(
"default_pi", icon_scale, icon_scale));
4420 m_itemStaticBitmap =
new wxStaticBitmap(
this, wxID_ANY, bitmap);
4422 itemBoxSizer01->Add(m_itemStaticBitmap, 0, wxEXPAND | wxALL, 10);
4423 m_itemStaticBitmap->Bind(wxEVT_LEFT_DOWN, &PluginPanel::OnPluginSelected,
4425 m_itemStaticBitmap->Bind(wxEVT_LEFT_UP, &PluginPanel::OnPluginSelectedUp,
4428 wxBoxSizer* itemBoxSizer02 =
new wxBoxSizer(wxVERTICAL);
4429 itemBoxSizer01->Add(itemBoxSizer02, 1, wxEXPAND | wxALL, 0);
4432 int nChars = g_options->GetSize().x / GetCharWidth();
4433 bool bCompact =
false;
4439 wxString nameString = m_plugin.m_common_name;
4440 int maxWidth = g_Platform->getDisplaySize().x * 3 / 10;
4443 dc.GetTextExtent(m_plugin.m_common_name, &nameWidth, NULL);
4444 if (nameWidth > maxWidth) {
4445 nameString = wxControl::Ellipsize(m_plugin.m_common_name, dc,
4446 wxELLIPSIZE_END, maxWidth);
4448 m_pName =
new wxStaticText(
this, wxID_ANY, nameString);
4449 m_pName->Bind(wxEVT_LEFT_DOWN, &PluginPanel::OnPluginSelected,
this);
4450 m_pName->Bind(wxEVT_LEFT_UP, &PluginPanel::OnPluginSelectedUp,
this);
4451 itemBoxSizer02->Add(m_pName, 0, wxALL, 5);
4453 wxFlexGridSizer* sl1 =
new wxFlexGridSizer(2, 0, 0);
4454 sl1->AddGrowableCol(1);
4455 itemBoxSizer02->Add(sl1, 0, wxEXPAND);
4457 m_pVersion =
new wxStaticText(
this, wxID_ANY, _T(
"X.YY.ZZ.AA"));
4458 sl1->Add(m_pVersion, 0, wxALL, 5);
4459 if (m_plugin.m_status == PluginStatus::ManagedInstallAvailable) {
4462 m_pVersion->Bind(wxEVT_LEFT_DOWN, &PluginPanel::OnPluginSelected,
this);
4463 m_pVersion->Bind(wxEVT_LEFT_UP, &PluginPanel::OnPluginSelectedUp,
this);
4465 m_cbEnable =
new wxCheckBox(
this, wxID_ANY, _(
"Enabled"));
4466 sl1->Add(m_cbEnable, 1, wxALIGN_RIGHT | wxTOP, 5);
4467 m_cbEnable->Bind(wxEVT_CHECKBOX, &PluginPanel::OnPluginEnableToggle,
this);
4470 wxString descriptionString = m_plugin.m_short_description;
4471 int maxDescriptionWidth = g_Platform->getDisplaySize().x - (iconSize * 4);
4472 int descriptionWidth;
4473 dc.GetTextExtent(m_plugin.m_short_description, &descriptionWidth, NULL);
4474 if (descriptionWidth > maxDescriptionWidth)
4476 wxControl::Ellipsize(m_plugin.m_short_description, dc,
4477 wxELLIPSIZE_END, maxDescriptionWidth);
4482 new wxStaticText(
this, wxID_ANY, descriptionString, wxDefaultPosition,
4483 wxSize(maxDescriptionWidth, -1), wxST_NO_AUTORESIZE);
4484 itemBoxSizer02->Add(m_pDescription, 0, wxEXPAND | wxALL, 5);
4485 m_pDescription->Bind(wxEVT_LEFT_DOWN, &PluginPanel::OnPluginSelected,
this);
4486 m_pDescription->Bind(wxEVT_LEFT_UP, &PluginPanel::OnPluginSelectedUp,
this);
4489 wxFlexGridSizer* itemBoxSizer03 =
new wxFlexGridSizer(4, 0, 0);
4490 itemBoxSizer03->AddGrowableCol(2);
4491 itemBoxSizer02->Add(itemBoxSizer03, 0, wxEXPAND);
4493 wxString nameString = m_plugin.m_common_name;
4494 m_pName =
new wxStaticText(
this, wxID_ANY, nameString);
4495 m_pName->Bind(wxEVT_LEFT_DOWN, &PluginPanel::OnPluginSelected,
this);
4496 m_pName->Bind(wxEVT_LEFT_UP, &PluginPanel::OnPluginSelectedUp,
this);
4500 wxFont font = GetFont();
4501 font.SetWeight(wxFONTWEIGHT_BOLD);
4502 m_pName->SetFont(font);
4505 itemBoxSizer03->Add(m_pName, 0, wxALL, 10);
4507 m_pVersion =
new wxStaticText(
this, wxID_ANY, _T(
"X.YY.ZZ.AA"));
4508 itemBoxSizer03->Add(m_pVersion, 0, wxALL, 10);
4509 if (m_plugin.m_status == PluginStatus::ManagedInstallAvailable ||
4510 m_plugin.m_status == PluginStatus::System ||
4511 (m_plugin.m_status == PluginStatus::Unmanaged &&
4512 !m_plugin.m_managed_metadata.is_orphan) ) {
4515 m_pVersion->Bind(wxEVT_LEFT_DOWN, &PluginPanel::OnPluginSelected,
this);
4516 m_pVersion->Bind(wxEVT_LEFT_UP, &PluginPanel::OnPluginSelectedUp,
this);
4518 m_cbEnable =
new wxCheckBox(
this, wxID_ANY, _(
"Enabled"));
4519 itemBoxSizer03->Add(m_cbEnable, 1, wxALIGN_RIGHT | wxTOP, 10);
4520 m_cbEnable->Bind(wxEVT_CHECKBOX, &PluginPanel::OnPluginEnableToggle,
this);
4522 itemBoxSizer03->Add(5 * GetCharWidth(), 1, 0, wxALIGN_RIGHT | wxTOP, 10);
4524 m_pDescription =
new wxStaticText(
4525 this, wxID_ANY, m_plugin.m_short_description, wxDefaultPosition,
4527 itemBoxSizer02->Add(m_pDescription, 1, wxEXPAND | wxALL, 5);
4528 m_pDescription->Bind(wxEVT_LEFT_DOWN, &PluginPanel::OnPluginSelected,
this);
4529 m_pDescription->Bind(wxEVT_LEFT_UP, &PluginPanel::OnPluginSelectedUp,
this);
4533 m_info_btn =
new WebsiteButton(
this,
"https:\\opencpn.org");
4535 itemBoxSizer02->Add(m_info_btn, 0);
4537 m_pButtons =
new wxBoxSizer(wxHORIZONTAL);
4538 itemBoxSizer02->Add(m_pButtons, 0, wxALL, 0);
4539 m_pButtonPreferences =
new wxButton(
this, wxID_ANY, _(
"Preferences"),
4540 wxDefaultPosition, wxDefaultSize, 0);
4541 m_pButtons->Add(m_pButtonPreferences, 0, wxALIGN_LEFT | wxALL, 2);
4543 m_pButtons->AddSpacer(3 * GetCharWidth());
4546 new wxButton(
this, wxID_ANY,
"Upgrade to Version XX.XX.XX",
4547 wxDefaultPosition, wxDefaultSize, 0);
4548 m_pButtons->Add(m_pButtonAction, 0, wxALIGN_LEFT | wxALL, 2);
4550 m_pButtonUninstall =
new wxButton(
this, wxID_ANY, _(
"Uninstall"),
4551 wxDefaultPosition, wxDefaultSize, 0);
4552 m_pButtons->Add(m_pButtonUninstall, 0, wxALIGN_LEFT | wxALL, 2);
4554 m_pButtons =
new wxBoxSizer(wxVERTICAL);
4555 itemBoxSizer02->Add(m_pButtons, 0, wxALL, 0);
4557 wxBoxSizer* tline =
new wxBoxSizer(wxHORIZONTAL);
4558 m_pButtons->Add(tline, 0, wxALL, 2);
4560 m_pButtonPreferences =
new wxButton(
this, wxID_ANY, _(
"Preferences"),
4561 wxDefaultPosition, wxDefaultSize, 0);
4562 tline->Add(m_pButtonPreferences, 0, wxALIGN_LEFT | wxALL, 0);
4564 tline->AddSpacer(3 * GetCharWidth());
4566 m_info_btn =
new WebsiteButton(
this,
"https:\\opencpn.org");
4568 tline->Add(m_info_btn, 0);
4571 new wxButton(
this, wxID_ANY,
"Upgrade to Version XX.XX.XX",
4572 wxDefaultPosition, wxDefaultSize);
4573 m_pButtons->Add(m_pButtonAction, 0, wxALIGN_LEFT | wxALL, 2);
4575 m_pButtonUninstall =
new wxButton(
this, wxID_ANY, _(
"Uninstall"),
4576 wxDefaultPosition, wxDefaultSize, 0);
4577 m_pButtons->Add(m_pButtonUninstall, 0, wxALIGN_LEFT | wxALL, 2);
4580 wxBitmap statusBitmap;
4581 const auto stat = m_plugin.m_status;
4582 auto icon_name = icon_by_status.at(stat);
4584 wxFileName path(g_Platform->GetSharedDataDir(), icon_name);
4585 path.AppendDir(
"uidata");
4586 path.AppendDir(
"traditional");
4588 int bmsize = GetCharWidth() * 3 * dpi_mult;
4589 if (path.IsFileReadable()) {
4590 statusBitmap = LoadSVG(path.GetFullPath(), bmsize, bmsize);
4591 ok = statusBitmap.IsOk();
4594 auto style = g_StyleManager->GetCurrentStyle();
4595 statusBitmap = wxBitmap(style->GetIcon(_T(
"default_pi"), bmsize, bmsize));
4596 wxLogMessage(
"Icon: %s not found.", path.GetFullPath());
4599 m_itemStatusIconBitmap =
new wxStaticBitmap(
this, wxID_ANY, statusBitmap);
4600 m_itemStatusIconBitmap->SetToolTip(message_by_status(stat));
4601 m_itemStatusIconBitmap->Bind(wxEVT_LEFT_DOWN, &PluginPanel::OnPluginSelected,
this);
4602 m_itemStatusIconBitmap->Bind(wxEVT_LEFT_UP, &PluginPanel::OnPluginSelectedUp,
this);
4604 itemBoxSizer01->Add(m_itemStatusIconBitmap, 0, wxEXPAND | wxALL, 20);
4606 itemBoxSizer02->AddSpacer(GetCharWidth());
4608 m_pButtonPreferences->Bind(wxEVT_COMMAND_BUTTON_CLICKED,
4609 &PluginPanel::OnPluginPreferences,
this);
4610 m_pButtonUninstall->Bind(wxEVT_COMMAND_BUTTON_CLICKED,
4611 &PluginPanel::OnPluginUninstall,
this);
4612 m_pButtonAction->Bind(wxEVT_COMMAND_BUTTON_CLICKED,
4613 &PluginPanel::OnPluginAction,
this);
4615 SetSelected(m_bSelected);
4616 SetAutoLayout(
true);
4624 PluginPanel::~PluginPanel() {
4625 Unbind(wxEVT_LEFT_DOWN, &PluginPanel::OnPluginSelected,
this);
4626 if (m_is_safe_panel)
return;
4627 m_itemStaticBitmap->Unbind(wxEVT_LEFT_DOWN, &PluginPanel::OnPluginSelected,
4629 m_pName->Unbind(wxEVT_LEFT_DOWN, &PluginPanel::OnPluginSelected,
this);
4630 m_pVersion->Unbind(wxEVT_LEFT_DOWN, &PluginPanel::OnPluginSelected,
this);
4631 m_pDescription->Unbind(wxEVT_LEFT_DOWN, &PluginPanel::OnPluginSelected,
this);
4632 if (m_pButtonAction) {
4633 m_pButtonAction->Unbind(wxEVT_COMMAND_BUTTON_CLICKED,
4634 &PluginPanel::OnPluginAction,
this);
4636 m_pButtonPreferences->Unbind(wxEVT_COMMAND_BUTTON_CLICKED,
4637 &PluginPanel::OnPluginPreferences,
this);
4638 m_cbEnable->Unbind(wxEVT_COMMAND_BUTTON_CLICKED,
4639 &PluginPanel::OnPluginEnableToggle,
this);
4642 void PluginPanel::SetActionLabel(wxString& label) {
4643 m_pButtonAction->SetLabel(label);
4647 static wxStopWatch swclick;
4648 static int downx, downy;
4650 void PluginPanel::OnPluginSelected(wxMouseEvent& event) {
4653 event.GetPosition(&downx, &downy);
4659 void PluginPanel::OnPluginSelectedUp(wxMouseEvent& event) {
4661 qDebug() << swclick.Time();
4662 if (swclick.Time() < 200) {
4664 event.GetPosition(&upx, &upy);
4665 if ((fabs(upx - downx) < GetCharWidth()) &&
4666 (fabs(upy - downy) < GetCharWidth())) {
4674 void PluginPanel::DoPluginSelect() {
4675 if (m_plugin.m_status == PluginStatus::ManagedInstallAvailable) {
4681 run_update_dialog(m_PluginListPanel, &m_plugin,
false, 0,
true);
4682 }
else if (m_bSelected) {
4684 m_PluginListPanel->SelectPlugin(NULL);
4687 m_PluginListPanel->SelectPlugin(
this);
4695 static PluginMetadata GetMetadataByName(
const std::string& name) {
4696 auto plugins = PluginHandler::getInstance()->
getInstalled();
4697 auto predicate = [name](
const PluginMetadata& pm) {
return pm.name == name; };
4698 auto found = std::find_if(plugins.begin(), plugins.end(), predicate);
4699 if (found == plugins.end()) {
4700 wxLogDebug(
"Cannot find metadata for %s", name.c_str());
4705 void PluginPanel::SetSelected(
bool selected) {
4706 m_bSelected = selected;
4708 m_pVersion->SetLabel(
4711 SetBackgroundColour(GetDialogColor(DLG_SELECTED_BACKGROUND));
4712 m_pButtons->Show(
true);
4713 bool unInstallPossible = canUninstall(m_plugin.
m_common_name.ToStdString());
4716 if (m_plugin.m_status == PluginStatus::LegacyUpdateAvailable ||
4717 m_plugin.m_status == PluginStatus::Unmanaged ||
4718 m_plugin.m_status == PluginStatus::System)
4719 unInstallPossible =
false;
4722 if (m_plugin.m_managed_metadata.is_orphan)
4723 unInstallPossible =
true;
4725 m_pButtonUninstall->Show(unInstallPossible);
4727 if (m_plugin.m_managed_metadata.info_url.size()) {
4728 m_info_btn->SetURL(m_plugin.m_managed_metadata.info_url.c_str());
4732 m_cbEnable->Show(
true);
4737 switch (m_plugin.m_status) {
4738 case PluginStatus::LegacyUpdateAvailable:
4739 label = _(
"Upgrade to Version ");
4740 label += wxString(m_plugin.m_managed_metadata.version.c_str());
4741 m_action = ActionVerb::UPGRADE_TO_MANAGED_VERSION;
4742 m_pButtonAction->Enable();
4745 case PluginStatus::ManagedInstallAvailable:
4746 label = _(
"Install...");
4747 m_action = ActionVerb::INSTALL_MANAGED_VERSION;
4748 m_pButtonAction->Enable();
4751 case PluginStatus::ManagedInstalledUpdateAvailable:
4752 label = _(
"Update to ");
4753 label += wxString(m_plugin.m_managed_metadata.version.c_str());
4754 m_action = ActionVerb::UPGRADE_INSTALLED_MANAGED_VERSION;
4755 m_pButtonAction->Enable();
4758 case PluginStatus::ManagedInstalledCurrentVersion:
4759 label = _(
"Reinstall");
4760 m_action = ActionVerb::REINSTALL_MANAGED_VERSION;
4761 m_pButtonAction->Enable();
4764 case PluginStatus::ManagedInstalledDowngradeAvailable:
4765 label = _(
"Downgrade");
4766 m_action = ActionVerb::DOWNGRADE_INSTALLED_MANAGED_VERSION;
4767 m_pButtonAction->Enable();
4770 case PluginStatus::Unmanaged:
4771 m_action = ActionVerb::NOP;
4772 m_pButtonAction->Hide();
4775 case PluginStatus::System:
4776 m_action = ActionVerb::NOP;
4777 m_pButtonAction->Hide();
4782 m_action = ActionVerb::NOP;
4785 SetActionLabel(label);
4786 const auto plugin_name = m_plugin.
m_common_name.ToStdString();
4788 m_pButtonAction->Hide();
4793 SetBackgroundColour(GetDialogColor(DLG_UNSELECTED_BACKGROUND));
4802 m_pButtons->Show(
false);
4805 if (m_plugin.m_status == PluginStatus::ManagedInstallAvailable)
4806 m_cbEnable->Show(
false);
4822 SetBackgroundColour(GetDialogColor(DLG_SELECTED_BACKGROUND));
4824 SetBackgroundColour(GetDialogColor(DLG_UNSELECTED_BACKGROUND));
4827 SetEnabled(m_plugin.m_enabled);
4842 void PluginPanel::OnPaint(wxPaintEvent& event) {
4845 int penWidth = m_penWidthUnselected;
4846 wxColour color = GetDialogColor(DLG_UNSELECTED_BACKGROUND);
4847 wxColour border = GetDialogColor(DLG_UNSELECTED_ACCENT);
4850 penWidth = m_penWidthSelected;
4851 color = GetDialogColor(DLG_SELECTED_BACKGROUND);
4852 border = GetDialogColor(DLG_SELECTED_ACCENT);
4855 wxBrush b(color, wxBRUSHSTYLE_SOLID);
4857 dc.SetPen(wxPen(border, penWidth));
4859 dc.DrawRoundedRectangle(5, 5, GetSize().x - 10, GetSize().y - 10, 5);
4862 void PluginPanel::OnPluginPreferences(wxCommandEvent& event) {
4863 if (m_plugin.m_enabled && m_plugin.m_init_state &&
4866 androidDisableRotation();
4877 void PluginPanel::OnPluginEnableToggle(wxCommandEvent& event) {
4878 SetEnabled(event.IsChecked());
4879 m_pVersion->SetLabel(
4881 if (m_plugin.m_status == PluginStatus::System) {
4884 PluginLoader::getInstance()->evt_pluglist_change.
Notify();
4888 void PluginPanel::OnPluginUninstall(wxCommandEvent& event) {
4889 m_action = ActionVerb::UNINSTALL_MANAGED_VERSION;
4892 wxCommandEvent actionEvent(wxEVT_COMMAND_BUTTON_CLICKED);
4893 actionEvent.SetId(ID_CMD_BUTTON_PERFORM_ACTION);
4894 actionEvent.SetClientData(
this);
4895 g_pi_manager->GetUtilHandler()->AddPendingEvent(actionEvent);
4898 void PluginPanel::OnPluginAction(wxCommandEvent& event) {
4900 wxCommandEvent actionEvent(wxEVT_COMMAND_BUTTON_CLICKED);
4901 actionEvent.SetId(ID_CMD_BUTTON_PERFORM_ACTION);
4902 actionEvent.SetClientData(
this);
4903 g_pi_manager->GetUtilHandler()->AddPendingEvent(actionEvent);
4908 static void SetWindowFontStyle(wxWindow* window, wxFontStyle style) {
4909 auto font = window->GetFont();
4910 font.SetStyle(style);
4911 window->SetFont(font);
4915 void PluginPanel::SetEnabled(
bool enabled) {
4916 if (m_is_safe_panel)
return;
4918 PluginLoader::getInstance()->UpdatePlugIns();
4919 NotifySetupOptionsPlugin(&m_plugin);
4920 if (!enabled && !m_bSelected) {
4921 SetWindowFontStyle(m_pName, wxFONTSTYLE_ITALIC);
4922 SetWindowFontStyle(m_pVersion, wxFONTSTYLE_ITALIC);
4923 SetWindowFontStyle(m_pDescription, wxFONTSTYLE_ITALIC);
4926 m_pVersion->Disable();
4927 m_pDescription->Disable();
4930 SetWindowFontStyle(m_pName, wxFONTSTYLE_NORMAL);
4931 SetWindowFontStyle(m_pVersion, wxFONTSTYLE_NORMAL);
4932 SetWindowFontStyle(m_pDescription, wxFONTSTYLE_NORMAL);
4935 m_pVersion->Enable();
4936 m_pDescription->Enable();
4941 m_pName->Enable(enabled || m_bSelected);
4942 m_pVersion->Enable(enabled || m_bSelected);
4943 m_pDescription->Enable(enabled || m_bSelected);
4947 wxString description = m_plugin.m_long_description;
4948 if (description.IsEmpty())
4949 description = wxString(m_plugin.m_managed_metadata.description.c_str());
4952 g_options->GetSize().x * 7 / 10);
4953 m_pDescription->SetLabel(wrapper.GetWrapped());
4954 if (m_plugin.m_managed_metadata.info_url.size()) {
4955 m_info_btn->SetURL(m_plugin.m_managed_metadata.info_url.c_str());
4959 wxString description = m_plugin.m_short_description;
4960 if (description.IsEmpty())
4961 description = wxString(m_plugin.m_managed_metadata.summary.c_str());
4963 g_options->GetSize().x * 7 / 10);
4964 m_pDescription->SetLabel(wrapper.GetWrapped());
4967 m_pButtonPreferences->Enable(enabled &&
4969 m_cbEnable->SetValue(enabled);
4972 void PluginPanel::OnPluginUp(wxCommandEvent& event) {
4973 m_PluginListPanel->MoveUp(
this);
4976 void PluginPanel::OnPluginDown(wxCommandEvent& event) {
4977 m_PluginListPanel->MoveDown(
this);
4982 : wxPanel(parent), m_url(url) {
4983 auto vbox =
new wxBoxSizer(wxVERTICAL);
4984 auto button =
new wxButton(
this, wxID_ANY, _(
"Website"));
4985 button->Enable(strlen(url) > 0);
4988 Bind(wxEVT_COMMAND_BUTTON_CLICKED,
4989 [=](wxCommandEvent&) { wxLaunchDefaultBrowser(m_url); });
4997 PlugInChartBase::PlugInChartBase() { m_Chart_Error_Factor = 0.; }
4999 PlugInChartBase::~PlugInChartBase() {}
5001 wxString PlugInChartBase::GetFileSearchMask(
void) {
return _T(
""); }
5003 int PlugInChartBase::Init(
const wxString& name,
int init_flags) {
return 0; }
5007 double PlugInChartBase::GetNormalScaleMin(
double canvas_scale_factor,
5008 bool b_allow_overzoom) {
5012 double PlugInChartBase::GetNormalScaleMax(
double canvas_scale_factor,
5017 bool PlugInChartBase::GetChartExtent(
ExtentPI* pext) {
return false; }
5019 wxBitmap& PlugInChartBase::RenderRegionView(
const PlugIn_ViewPort& VPoint,
5020 const wxRegion& Region) {
5021 return wxNullBitmap;
5029 void PlugInChartBase::GetValidCanvasRegion(
const PlugIn_ViewPort& VPoint,
5030 wxRegion* pValidRegion) {}
5032 void PlugInChartBase::SetColorScheme(
int cs,
bool bApplyImmediate) {}
5034 double PlugInChartBase::GetNearestPreferredScalePPM(
double target_scale_ppm) {
5038 wxBitmap* PlugInChartBase::GetThumbnail(
int tnx,
int tny,
int cs) {
5042 void PlugInChartBase::ComputeSourceRectangle(
const PlugIn_ViewPort& vp,
5043 wxRect* pSourceRect) {}
5045 double PlugInChartBase::GetRasterScaleFactor() {
return 1.0; }
5047 bool PlugInChartBase::GetChartBits(wxRect& source,
unsigned char* pPix,
5052 int PlugInChartBase::GetSize_X() {
return 1; }
5054 int PlugInChartBase::GetSize_Y() {
return 1; }
5056 void PlugInChartBase::latlong_to_chartpix(
double lat,
double lon,
double& pixx,
5059 void PlugInChartBase::chartpix_to_latlong(
double pixx,
double pixy,
5060 double* plat,
double* plon) {}
5067 PlugInChartBaseGL::PlugInChartBaseGL() {}
5069 PlugInChartBaseGL::~PlugInChartBaseGL() {}
5071 int PlugInChartBaseGL::RenderRegionViewOnGL(
const wxGLContext& glc,
5073 const wxRegion& Region,
5074 bool b_use_stencil) {
5078 ListOfPI_S57Obj* PlugInChartBaseGL::GetObjRuleListAtLatLon(
5083 wxString PlugInChartBaseGL::CreateObjDescriptions(ListOfPI_S57Obj* obj_list) {
5087 int PlugInChartBaseGL::GetNoCOVREntries() {
return 0; }
5089 int PlugInChartBaseGL::GetNoCOVRTablePoints(
int iTable) {
return 0; }
5091 int PlugInChartBaseGL::GetNoCOVRTablenPoints(
int iTable) {
return 0; }
5093 float* PlugInChartBaseGL::GetNoCOVRTableHead(
int iTable) {
return 0; }
5100 PlugInChartBaseExtended::PlugInChartBaseExtended() {}
5102 PlugInChartBaseExtended::~PlugInChartBaseExtended() {}
5104 int PlugInChartBaseExtended::RenderRegionViewOnGL(
const wxGLContext& glc,
5106 const wxRegion& Region,
5107 bool b_use_stencil) {
5111 int PlugInChartBaseExtended::RenderRegionViewOnGLNoText(
5113 const wxRegion& Region,
bool b_use_stencil) {
5117 int PlugInChartBaseExtended::RenderRegionViewOnGLTextOnly(
5119 const wxRegion& Region,
bool b_use_stencil) {
5123 wxBitmap& PlugInChartBaseExtended::RenderRegionViewOnDCNoText(
5125 return wxNullBitmap;
5128 bool PlugInChartBaseExtended::RenderRegionViewOnDCTextOnly(
5129 wxMemoryDC& dc,
const PlugIn_ViewPort& VPoint,
const wxRegion& Region) {
5133 ListOfPI_S57Obj* PlugInChartBaseExtended::GetObjRuleListAtLatLon(
5138 wxString PlugInChartBaseExtended::CreateObjDescriptions(
5139 ListOfPI_S57Obj* obj_list) {
5143 int PlugInChartBaseExtended::GetNoCOVREntries() {
return 0; }
5145 int PlugInChartBaseExtended::GetNoCOVRTablePoints(
int iTable) {
return 0; }
5147 int PlugInChartBaseExtended::GetNoCOVRTablenPoints(
int iTable) {
return 0; }
5149 float* PlugInChartBaseExtended::GetNoCOVRTableHead(
int iTable) {
return 0; }
5151 void PlugInChartBaseExtended::ClearPLIBTextList() {}
5158 PlugInChartBaseExtendedPlus2::PlugInChartBaseExtendedPlus2() {}
5160 PlugInChartBaseExtendedPlus2::~PlugInChartBaseExtendedPlus2() {}
5163 PlugInChartBaseExtendedPlus2::GetLightsObjRuleListVisibleAtLatLon(
5173 PlugInChartBaseGLPlus2::PlugInChartBaseGLPlus2() {}
5175 PlugInChartBaseGLPlus2::~PlugInChartBaseGLPlus2() {}
5177 ListOfPI_S57Obj* PlugInChartBaseGLPlus2::GetLightsObjRuleListVisibleAtLatLon(
5187 ChartPlugInWrapper::ChartPlugInWrapper() {}
5189 ChartPlugInWrapper::ChartPlugInWrapper(
const wxString& chart_class) {
5190 m_ppo = ::wxCreateDynamicObject(chart_class);
5194 ChartPlugInWrapper::~ChartPlugInWrapper() {
5195 if (m_ppicb)
delete m_ppicb;
5198 wxString ChartPlugInWrapper::GetFileSearchMask(
void) {
5200 return m_ppicb->GetFileSearchMask();
5205 InitReturn ChartPlugInWrapper::Init(
const wxString& name,
5206 ChartInitFlag init_flags) {
5208 wxWindow* pa = wxWindow::FindFocus();
5210 InitReturn ret_val = (InitReturn)m_ppicb->Init(name, (
int)init_flags);
5214 if (ret_val == INIT_OK) {
5215 m_FullPath = m_ppicb->GetFullPath();
5216 m_ChartType = (ChartTypeEnum)m_ppicb->GetChartType();
5217 m_ChartFamily = (ChartFamilyEnum)m_ppicb->GetChartFamily();
5218 m_projection = (OcpnProjType)m_ppicb->GetChartProjection();
5219 m_EdDate = m_ppicb->GetEditionDate();
5220 m_Name = m_ppicb->GetName();
5221 m_ID = m_ppicb->GetID();
5222 m_DepthUnits = m_ppicb->GetDepthUnits();
5223 m_SoundingsDatum = m_ppicb->GetSoundingsDatum();
5224 m_datum_str = m_ppicb->GetDatumString();
5225 m_SE = m_ppicb->GetSE();
5226 m_EdDate = m_ppicb->GetEditionDate();
5227 m_ExtraInfo = m_ppicb->GetExtraInfo();
5228 Chart_Error_Factor = m_ppicb->GetChartErrorFactor();
5229 m_depth_unit_id = (ChartDepthUnitType)m_ppicb->GetDepthUnitId();
5230 m_Chart_Skew = m_ppicb->GetChartSkew();
5231 m_Chart_Scale = m_ppicb->GetNativeScale();
5236 m_ppm_avg = 10000. / m_ppicb->GetNativeScale();
5239 if ((fabs(m_Chart_Skew) < .01) &&
5240 (CHART_FAMILY_RASTER == m_ChartFamily)) {
5242 if (GetChartExtent(&extent)) {
5243 double lon_range = extent.ELON - extent.WLON;
5244 if ((lon_range > 0) &&
5246 m_ppm_avg = GetSize_X() / (lon_range * 1852 * 60);
5250 m_overlayENC =
false;
5251 if (m_ChartFamily == (ChartFamilyEnum)PI_CHART_FAMILY_VECTOR) {
5252 wxCharBuffer buf = m_FullPath.ToUTF8();
5253 m_overlayENC = s57chart::IsCellOverlayType(buf.data());
5256 bReadyToRender = m_ppicb->IsReadyToRender();
5259 m_ChartType = CHART_TYPE_UNKNOWN;
5260 m_ChartFamily = CHART_FAMILY_UNKNOWN;
5266 if (pc) pc->SetFocus();
5270 return INIT_FAIL_REMOVE;
5274 int ChartPlugInWrapper::GetCOVREntries() {
5276 return m_ppicb->GetCOVREntries();
5281 int ChartPlugInWrapper::GetCOVRTablePoints(
int iTable) {
5283 return m_ppicb->GetCOVRTablePoints(iTable);
5288 int ChartPlugInWrapper::GetCOVRTablenPoints(
int iTable) {
5290 return m_ppicb->GetCOVRTablenPoints(iTable);
5295 float* ChartPlugInWrapper::GetCOVRTableHead(
int iTable) {
5297 return m_ppicb->GetCOVRTableHead(iTable);
5307 int ChartPlugInWrapper::GetNoCOVREntries() {
5311 return ppicbgl->GetNoCOVREntries();
5317 int ChartPlugInWrapper::GetNoCOVRTablePoints(
int iTable) {
5321 return ppicbgl->GetNoCOVRTablePoints(iTable);
5327 int ChartPlugInWrapper::GetNoCOVRTablenPoints(
int iTable) {
5331 return ppicbgl->GetNoCOVRTablenPoints(iTable);
5337 float* ChartPlugInWrapper::GetNoCOVRTableHead(
int iTable) {
5341 return ppicbgl->GetNoCOVRTableHead(iTable);
5347 bool ChartPlugInWrapper::GetChartExtent(
Extent* pext) {
5350 if (m_ppicb->GetChartExtent(&xpi)) {
5351 pext->NLAT = xpi.NLAT;
5352 pext->SLAT = xpi.SLAT;
5353 pext->ELON = xpi.ELON;
5354 pext->WLON = xpi.WLON;
5363 ThumbData* ChartPlugInWrapper::GetThumbData(
int tnx,
int tny,
float lat,
5368 if (!pThumbData->pDIBThumb) {
5369 wxBitmap* pBMPOwnedByChart =
5370 m_ppicb->GetThumbnail(tnx, tny, m_global_color_scheme);
5371 if (pBMPOwnedByChart) {
5372 wxImage img = pBMPOwnedByChart->ConvertToImage();
5373 pThumbData->pDIBThumb =
new wxBitmap(img);
5375 pThumbData->pDIBThumb = NULL;
5378 pThumbData->Thumb_Size_X = tnx;
5379 pThumbData->Thumb_Size_Y = tny;
5406 pThumbData->ShipX = 0;
5407 pThumbData->ShipY = 0;
5414 ThumbData* ChartPlugInWrapper::GetThumbData() {
return pThumbData; }
5416 bool ChartPlugInWrapper::UpdateThumbData(
double lat,
double lon) {
5420 double ChartPlugInWrapper::GetNormalScaleMin(
double canvas_scale_factor,
5421 bool b_allow_overzoom) {
5423 return m_ppicb->GetNormalScaleMin(canvas_scale_factor, b_allow_overzoom);
5428 double ChartPlugInWrapper::GetNormalScaleMax(
double canvas_scale_factor,
5431 return m_ppicb->GetNormalScaleMax(canvas_scale_factor, canvas_width);
5450 void RenderRotateToViewPort(
const ViewPort& VPoint) {
5451 #ifndef USE_ANDROID_GLES2
5452 float xt = VPoint.pix_width / 2.0, yt = VPoint.pix_height / 2.0;
5453 glTranslatef(xt, yt, 0);
5454 glRotatef(VPoint.rotation * 180. / PI, 0, 0, 1);
5455 glTranslatef(-xt, -yt, 0);
5459 void UndoRenderRotateToViewPort(
const ViewPort& VPoint) {
5460 #ifndef USE_ANDROID_GLES2
5461 float xt = VPoint.pix_width / 2.0, yt = VPoint.pix_height / 2.0;
5462 glTranslatef(xt, yt, 0);
5463 glRotatef(-VPoint.rotation * 180. / PI, 0, 0, 1);
5464 glTranslatef(-xt, -yt, 0);
5468 bool ChartPlugInWrapper::RenderRegionViewOnGL(
const wxGLContext& glc,
5471 const LLRegion& Region) {
5480 if (!Region.Empty() && (ppicb_gl || ppicb_x)) {
5481 wxRegion* r = RectRegion.GetNew_wxRegion();
5484 LLRegion chart_region = vp.GetLLRegion(upd.GetRect());
5485 chart_region.Intersect(Region);
5487 if (!chart_region.Empty()) {
5488 ViewPort cvp = glChartCanvas::ClippedViewport(VPoint, chart_region);
5490 glChartCanvas::SetClipRect(cvp, upd.GetRect(),
false);
5494 #ifndef USE_ANDROID_GLES2
5497 RenderRotateToViewPort(VPoint);
5501 ppicb_x->RenderRegionViewOnGL(glc, pivp, *r,
5502 glChartCanvas::s_b_useStencil);
5504 ppicb_gl->RenderRegionViewOnGL(glc, pivp, *r,
5505 glChartCanvas::s_b_useStencil);
5506 UndoRenderRotateToViewPort(VPoint);
5508 #ifndef USE_ANDROID_GLES2
5511 glChartCanvas::DisableClipRegion();
5525 bool ChartPlugInWrapper::RenderRegionViewOnGLNoText(
5526 const wxGLContext& glc,
const ViewPort& VPoint,
5527 const OCPNRegion& RectRegion,
const LLRegion& Region) {
5536 if (!Region.Empty() && ppicb_x) {
5538 glChartCanvas::SetClipRect(VPoint, VPoint.rv_rect,
false);
5539 glChartCanvas::DisableClipRegion();
5542 RenderRotateToViewPort(VPoint);
5545 wxRegion* r = RectRegion.GetNew_wxRegion();
5547 ppicb_x->RenderRegionViewOnGLNoText(glc, pivp, *r,
5548 glChartCanvas::s_b_useStencil);
5551 UndoRenderRotateToViewPort(VPoint);
5556 else if (!Region.Empty() &&
5560 wxRegion* r = RectRegion.GetNew_wxRegion();
5563 LLRegion chart_region = vp.GetLLRegion(upd.GetRect());
5564 chart_region.Intersect(Region);
5566 if (!chart_region.Empty()) {
5567 ViewPort cvp = glChartCanvas::ClippedViewport(VPoint, chart_region);
5569 glChartCanvas::SetClipRect(cvp, upd.GetRect(),
false);
5571 RenderRotateToViewPort(VPoint);
5574 ppicb->RenderRegionViewOnGL(glc, pivp, *r,
5575 glChartCanvas::s_b_useStencil);
5578 UndoRenderRotateToViewPort(VPoint);
5580 glChartCanvas::DisableClipRegion();
5593 bool ChartPlugInWrapper::RenderRegionViewOnGLTextOnly(
5600 if (!Region.Empty() && ppicb_x) {
5601 wxRegion* r = Region.GetNew_wxRegion();
5603 #ifndef USE_ANDROID_GLES2
5606 RenderRotateToViewPort(VPoint);
5609 ppicb_x->RenderRegionViewOnGLTextOnly(glc, pivp, *r,
5610 glChartCanvas::s_b_useStencil);
5611 UndoRenderRotateToViewPort(VPoint);
5613 #ifndef USE_ANDROID_GLES2
5626 bool ChartPlugInWrapper::RenderRegionViewOnDC(wxMemoryDC& dc,
5632 if (Region.IsOk()) {
5633 wxRegion* r = Region.GetNew_wxRegion();
5635 dc.SelectObject(m_ppicb->RenderRegionView(pivp, *r));
5637 wxBitmap& obmp = m_ppicb->RenderRegionView(pivp, *r);
5640 wxColour nodat = GetGlobalColor(_T (
"NODTA" ));
5641 wxColour nodat_sub = nodat;
5643 #ifdef ocpnUSE_ocpnBitmap
5644 nodat_sub = wxColour(nodat.Blue(), nodat.Green(), nodat.Red());
5646 m_pMask =
new wxMask(obmp, nodat_sub);
5647 obmp.SetMask(m_pMask);
5649 dc.SelectObject(obmp);
5660 bool ChartPlugInWrapper::RenderRegionViewOnDCNoText(wxMemoryDC& dc,
5671 if (Region.IsOk() && (pCBx || ppicb)) {
5672 wxRegion* r = Region.GetNew_wxRegion();
5675 dc.SelectObject(pCBx->RenderRegionViewOnDCNoText(pivp, *r));
5677 dc.SelectObject(ppicb->RenderRegionView(pivp, *r));
5687 bool ChartPlugInWrapper::RenderRegionViewOnDCTextOnly(
5690 bool ret_val =
false;
5693 if (Region.IsOk()) {
5694 wxRegion* r = Region.GetNew_wxRegion();
5698 if (pCBx) ret_val = pCBx->RenderRegionViewOnDCTextOnly(dc, pivp, *r);
5708 void ChartPlugInWrapper::ClearPLIBTextList() {
5712 if (pCBx) pCBx->ClearPLIBTextList();
5716 bool ChartPlugInWrapper::AdjustVP(
ViewPort& vp_last,
ViewPort& vp_proposed) {
5720 return m_ppicb->AdjustVP(pivp_last, pivp_proposed);
5725 void ChartPlugInWrapper::GetValidCanvasRegion(
const ViewPort& VPoint,
5733 m_ppicb->GetValidCanvasRegion(pivp, ®ion);
5740 void ChartPlugInWrapper::SetColorScheme(ColorScheme cs,
bool bApplyImmediate) {
5742 m_ppicb->SetColorScheme(cs, bApplyImmediate);
5744 m_global_color_scheme = cs;
5746 if (pThumbData) pThumbData->pDIBThumb = NULL;
5749 double ChartPlugInWrapper::GetNearestPreferredScalePPM(
5750 double target_scale_ppm) {
5752 return m_ppicb->GetNearestPreferredScalePPM(target_scale_ppm);
5757 void ChartPlugInWrapper::ComputeSourceRectangle(
const ViewPort& VPoint,
5758 wxRect* pSourceRect) {
5761 m_ppicb->ComputeSourceRectangle(pivp, pSourceRect);
5765 double ChartPlugInWrapper::GetRasterScaleFactor(
const ViewPort& vp) {
5767 return (wxRound(100000 * GetPPM() / vp.view_scale_ppm)) / 100000.;
5772 bool ChartPlugInWrapper::GetChartBits(wxRect& source,
unsigned char* pPix,
5774 wxCriticalSectionLocker locker(m_critSect);
5778 return m_ppicb->GetChartBits(source, pPix, sub_samp);
5783 int ChartPlugInWrapper::GetSize_X() {
5785 return m_ppicb->GetSize_X();
5790 int ChartPlugInWrapper::GetSize_Y() {
5792 return m_ppicb->GetSize_Y();
5797 void ChartPlugInWrapper::latlong_to_chartpix(
double lat,
double lon,
5798 double& pixx,
double& pixy) {
5799 if (m_ppicb) m_ppicb->latlong_to_chartpix(lat, lon, pixx, pixy);
5802 void ChartPlugInWrapper::chartpix_to_latlong(
double pixx,
double pixy,
5803 double* plat,
double* plon) {
5804 if (m_ppicb) m_ppicb->chartpix_to_latlong(pixx, pixy, plat, plon);
5812 wxString toSDMM_PlugIn(
int NEflag,
double a,
bool hi_precision) {
5813 return toSDMM(NEflag, a, hi_precision);
5816 wxColour GetBaseGlobalColor(wxString colorName) {
5817 return GetGlobalColor(colorName);
5820 int OCPNMessageBox_PlugIn(wxWindow* parent,
const wxString& message,
5821 const wxString& caption,
int style,
int x,
int y) {
5822 return OCPNMessageBox(parent, message, caption, style, 100, x, y);
5825 wxString GetOCPN_ExePath(
void) {
return g_Platform->GetExePath(); }
5827 wxString* GetpPlugInLocation() {
return g_Platform->GetPluginDirPtr(); }
5829 wxString GetWritableDocumentsDir(
void) {
5830 return g_Platform->GetWritableDocumentsDir();
5835 auto loader = PluginLoader::getInstance();
5836 for (
unsigned int i = 0; i < loader->GetPlugInArray()->GetCount(); i++) {
5838 if (pic->m_pplugin == pplugin) {
5848 ListOfPI_S57Obj* PlugInManager::GetPlugInObjRuleListAtLatLon(
5851 ListOfPI_S57Obj* list = NULL;
5857 list = picbgl->GetObjRuleListAtLatLon(zlat, zlon, SelectRadius, &pi_vp);
5865 list = picbx->GetObjRuleListAtLatLon(zlat, zlon, SelectRadius, &pi_vp);
5875 ListOfPI_S57Obj* rule_list) {
5881 ret_str = picbgl->CreateObjDescriptions(rule_list);
5886 ret_str = picbx->CreateObjDescriptions(rule_list);
5894 wxString PI_GetPLIBColorScheme() {
5898 int PI_GetPLIBDepthUnitInt() {
5900 return ps52plib->m_nDepthUnitDisplay;
5905 int PI_GetPLIBSymbolStyle() {
5907 return ps52plib->m_nSymbolStyle;
5912 int PI_GetPLIBBoundaryStyle() {
5914 return ps52plib->m_nBoundaryStyle;
5924 CreateCompatibleS57Object(pObj, &cobj, &ctx);
5926 ViewPort cvp = CreateCompatibleViewport(*vp);
5931 ObjRazRules rzRules;
5932 rzRules.obj = &cobj;
5933 rzRules.LUP = pContext->LUP;
5934 rzRules.sm_transform_parms = 0;
5935 rzRules.child = NULL;
5936 rzRules.next = NULL;
5938 if (pContext->LUP) {
5939 ps52plib->SetVPointCompat(
5940 cvp.pix_width, cvp.pix_height, cvp.view_scale_ppm, cvp.rotation,
5941 cvp.clat, cvp.clon, cvp.chart_scale, cvp.rv_rect, cvp.GetBBox(),
5942 cvp.ref_scale, GetOCPNCanvasWindow()->GetContentScaleFactor());
5943 ps52plib->PrepareForRender();
5945 return ps52plib->ObjectRenderCheck(&rzRules);
5952 int PI_GetPLIBStateHash() {
5954 return ps52plib->GetStateHash();
5959 void CreateCompatibleS57Object(
PI_S57Obj* pObj, S57Obj* cobj,
5960 chart_context* pctx) {
5961 strncpy(cobj->FeatureName, pObj->FeatureName, 8);
5962 cobj->Primitive_type = (GeoPrim_t)pObj->Primitive_type;
5963 cobj->att_array = pObj->att_array;
5964 cobj->attVal = pObj->attVal;
5965 cobj->n_attr = pObj->n_attr;
5970 cobj->npt = pObj->npt;
5972 cobj->iOBJL = pObj->iOBJL;
5973 cobj->Index = pObj->Index;
5975 cobj->geoPt = (pt*)pObj->geoPt;
5976 cobj->geoPtz = pObj->geoPtz;
5977 cobj->geoPtMulti = pObj->geoPtMulti;
5979 cobj->m_lat = pObj->m_lat;
5980 cobj->m_lon = pObj->m_lon;
5982 cobj->m_DisplayCat = (DisCat)pObj->m_DisplayCat;
5983 cobj->x_rate = pObj->x_rate;
5984 cobj->y_rate = pObj->y_rate;
5985 cobj->x_origin = pObj->x_origin;
5986 cobj->y_origin = pObj->y_origin;
5988 cobj->Scamin = pObj->Scamin;
5989 cobj->nRef = pObj->nRef;
5990 cobj->bIsAton = pObj->bIsAton;
5991 cobj->bIsAssociable = pObj->bIsAssociable;
5993 cobj->m_n_lsindex = pObj->m_n_lsindex;
5994 cobj->m_lsindex_array = pObj->m_lsindex_array;
5995 cobj->m_n_edge_max_points = pObj->m_n_edge_max_points;
5997 if (gs_plib_flags & PLIB_CAPS_OBJSEGLIST) {
5998 cobj->m_ls_list_legacy =
6002 cobj->m_ls_list_legacy = 0;
6003 cobj->m_ls_list = 0;
6005 if (gs_plib_flags & PLIB_CAPS_OBJCATMUTATE)
6006 cobj->m_bcategory_mutable = pObj->m_bcategory_mutable;
6008 cobj->m_bcategory_mutable =
true;
6011 if (gs_plib_flags & PLIB_CAPS_OBJCATMUTATE) {
6012 if (pObj->m_DPRI == -1) {
6014 if (pCtx->LUP) cobj->m_DPRI = pCtx->LUP->DPRI -
'0';
6016 cobj->m_DPRI = pObj->m_DPRI;
6019 cobj->pPolyTessGeo = (PolyTessGeo*)pObj->pPolyTessGeo;
6020 cobj->m_chart_context = (chart_context*)pObj->m_chart_context;
6022 if (pObj->auxParm3 != 1234) {
6023 pObj->auxParm3 = 1234;
6024 pObj->auxParm0 = -99;
6027 cobj->auxParm0 = pObj->auxParm0;
6034 if (pContext->bBBObj_valid)
6036 cobj->BBObj.Set(pContext->BBObj.GetMinY(), pContext->BBObj.GetMinX(),
6037 pContext->BBObj.GetMaxY(), pContext->BBObj.GetMaxX());
6039 cobj->CSrules = pContext->CSrules;
6040 cobj->bCS_Added = pContext->bCS_Added;
6042 cobj->FText = pContext->FText;
6043 cobj->bFText_Added = pContext->bFText_Added;
6044 cobj->rText = pContext->rText;
6046 cobj->bIsClone =
true;
6049 cobj->m_chart_context = pctx;
6050 chart_context* ppctx = (chart_context*)pObj->m_chart_context;
6053 cobj->m_chart_context->m_pvc_hash = ppctx->m_pvc_hash;
6054 cobj->m_chart_context->m_pve_hash = ppctx->m_pve_hash;
6055 cobj->m_chart_context->ref_lat = ppctx->ref_lat;
6056 cobj->m_chart_context->ref_lon = ppctx->ref_lon;
6057 cobj->m_chart_context->pFloatingATONArray = ppctx->pFloatingATONArray;
6058 cobj->m_chart_context->pRigidATONArray = ppctx->pRigidATONArray;
6059 cobj->m_chart_context->safety_contour = ppctx->safety_contour;
6060 cobj->m_chart_context->vertex_buffer = ppctx->vertex_buffer;
6062 cobj->m_chart_context->chart =
6064 cobj->m_chart_context->chart_type = S52_CHART_TYPE_PLUGIN;
6068 bool PI_PLIBSetContext(
PI_S57Obj* pObj) {
6070 if (!pObj->S52_Context) {
6072 pObj->S52_Context = ctx;
6078 CreateCompatibleS57Object(pObj, &cobj, NULL);
6080 LUPname LUP_Name = PAPER_CHART;
6083 ctx->CSrules = NULL;
6084 ctx->bCS_Added =
false;
6087 if (ctx->bFText_Added) {
6088 ctx->bFText_Added =
false;
6094 ctx->bBBObj_valid =
true;
6095 ctx->BBObj.SetMin(pObj->lon_min, pObj->lat_min);
6096 ctx->BBObj.SetMax(pObj->lon_max, pObj->lat_max);
6099 switch (cobj.Primitive_type) {
6104 if (PAPER_CHART == ps52plib->m_nSymbolStyle)
6105 LUP_Name = PAPER_CHART;
6107 LUP_Name = SIMPLIFIED;
6116 if (PLAIN_BOUNDARIES == ps52plib->m_nBoundaryStyle)
6117 LUP_Name = PLAIN_BOUNDARIES;
6119 LUP_Name = SYMBOLIZED_BOUNDARIES;
6124 LUPrec* lup = ps52plib->S52_LUPLookup(LUP_Name, cobj.FeatureName, &cobj);
6128 ps52plib->_LUP2rules(lup, &cobj);
6130 ctx->MPSRulesList = NULL;
6135 void PI_UpdateContext(
PI_S57Obj* pObj) {
6138 pContext->bBBObj_valid =
true;
6139 pContext->BBObj.SetMin(pObj->lon_min, pObj->lat_min);
6140 pContext->BBObj.SetMax(pObj->lon_max, pObj->lat_max);
6144 void UpdatePIObjectPlibContext(
PI_S57Obj* pObj, S57Obj* cobj,
6145 ObjRazRules* rzRules) {
6149 pContext->CSrules = cobj->CSrules;
6150 pContext->bCS_Added = cobj->bCS_Added;
6152 pContext->FText = cobj->FText;
6153 pContext->bFText_Added = cobj->bFText_Added;
6154 pContext->rText = cobj->rText;
6156 if (cobj->BBObj.GetValid()) {
6159 BoundingBox(cobj->BBObj.GetMinLon(), cobj->BBObj.GetMinLat(),
6160 cobj->BBObj.GetMaxLon(), cobj->BBObj.GetMaxLat());
6161 pContext->bBBObj_valid =
true;
6166 pObj->m_DisplayCat = (PI_DisCat)cobj->m_DisplayCat;
6168 if (gs_plib_flags & PLIB_CAPS_OBJCATMUTATE) pObj->m_DPRI = cobj->m_DPRI;
6170 pContext->ChildRazRules = rzRules->child;
6171 pContext->MPSRulesList = rzRules->mps;
6173 pObj->auxParm0 = cobj->auxParm0;
6176 bool PI_GetObjectRenderBox(
PI_S57Obj* pObj,
double* lat_min,
double* lat_max,
6177 double* lon_min,
double* lon_max) {
6180 if (lat_min) *lat_min = pContext->BBObj.GetMinY();
6181 if (lat_max) *lat_max = pContext->BBObj.GetMaxY();
6182 if (lon_min) *lon_min = pContext->BBObj.GetMinX();
6183 if (lon_max) *lon_max = pContext->BBObj.GetMaxX();
6184 return pContext->bBBObj_valid;
6189 PI_LUPname PI_GetObjectLUPName(
PI_S57Obj* pObj) {
6192 LUPrec* lup = pContext->LUP;
6193 if (lup)
return (PI_LUPname)(lup->TNAM);
6195 return (PI_LUPname)(-1);
6198 PI_DisPrio PI_GetObjectDisplayPriority(
PI_S57Obj* pObj) {
6201 LUPrec* lup = pContext->LUP;
6202 if (lup)
return (PI_DisPrio)(lup->DPRI);
6205 return (PI_DisPrio)(-1);
6208 PI_DisCat PI_GetObjectDisplayCategory(
PI_S57Obj* pObj) {
6211 LUPrec* lup = pContext->LUP;
6212 if (lup)
return (PI_DisCat)(lup->DISC);
6214 return (PI_DisCat)(-1);
6216 double PI_GetPLIBMarinerSafetyContour() {
6217 return S52_getMarinerParam(S52_MAR_SAFETY_CONTOUR);
6220 void PI_PLIBSetLineFeaturePriority(
PI_S57Obj* pObj,
int prio) {
6224 CreateCompatibleS57Object(pObj, &cobj, &ctx);
6229 ObjRazRules rzRules;
6230 rzRules.obj = &cobj;
6231 rzRules.LUP = pContext->LUP;
6232 rzRules.sm_transform_parms = 0;
6233 rzRules.child = NULL;
6234 rzRules.next = NULL;
6235 rzRules.mps = pContext->MPSRulesList;
6237 if (pContext->LUP) {
6238 ps52plib->SetLineFeaturePriority(&rzRules, prio);
6241 UpdatePIObjectPlibContext(pObj, &cobj, &rzRules);
6245 void PI_PLIBPrepareForNewRender(
void) {
6247 ps52plib->PrepareForRender();
6248 ps52plib->ClearTextList();
6250 if (gs_plib_flags & PLIB_CAPS_LINE_BUFFER)
6251 ps52plib->EnableGLLS(
true);
6253 ps52plib->EnableGLLS(
false);
6257 void PI_PLIBSetRenderCaps(
unsigned int flags) { gs_plib_flags = flags; }
6259 void PI_PLIBFreeContext(
void* pContext) {
6262 if (pctx->ChildRazRules) {
6263 ObjRazRules* ctop = pctx->ChildRazRules;
6267 if (ps52plib) ps52plib->DestroyLUP(ctop->LUP);
6269 ObjRazRules* cnxx = ctop->next;
6275 if (pctx->MPSRulesList) {
6276 if (ps52plib && pctx->MPSRulesList->cs_rules) {
6277 for (
unsigned int i = 0; i < pctx->MPSRulesList->cs_rules->GetCount();
6279 Rules* top = pctx->MPSRulesList->cs_rules->Item(i);
6280 ps52plib->DestroyRulesChain(top);
6282 delete pctx->MPSRulesList->cs_rules;
6284 free(pctx->MPSRulesList);
6296 CreateCompatibleS57Object(pObj, &cobj, &ctx);
6302 toSM(vp->clat, vp->clon, pObj->chart_ref_lat, pObj->chart_ref_lon,
6303 &transform.easting_vp_center, &transform.northing_vp_center);
6306 ObjRazRules rzRules;
6307 rzRules.obj = &cobj;
6308 rzRules.LUP = pContext->LUP;
6309 rzRules.sm_transform_parms = &transform;
6310 rzRules.child = pContext->ChildRazRules;
6311 rzRules.next = NULL;
6312 rzRules.mps = pContext->MPSRulesList;
6314 if (pContext->LUP) {
6315 ViewPort cvp = CreateCompatibleViewport(*vp);
6319 ps52plib->SetVPointCompat(cvp.pix_width, cvp.pix_height, cvp.view_scale_ppm,
6320 cvp.rotation, cvp.clat, cvp.clon, cvp.chart_scale,
6321 cvp.rv_rect, cvp.GetBBox(), cvp.ref_scale,
6322 GetOCPNCanvasWindow()->GetContentScaleFactor());
6323 ps52plib->PrepareForRender();
6325 ps52plib->RenderObjectToDC(pdc, &rzRules);
6328 UpdatePIObjectPlibContext(pObj, &cobj, &rzRules);
6335 wxRect rect,
unsigned char* pixbuf) {
6337 render_canvas_parms pb_spec;
6339 pb_spec.depth = BPP;
6340 pb_spec.pb_pitch = ((rect.width * pb_spec.depth / 8));
6341 pb_spec.lclip = rect.x;
6342 pb_spec.rclip = rect.x + rect.width - 1;
6343 pb_spec.pix_buff = pixbuf;
6344 pb_spec.width = rect.width;
6345 pb_spec.height = rect.height;
6348 #ifdef ocpnUSE_ocpnBitmap
6349 pb_spec.b_revrgb =
true;
6351 pb_spec.b_revrgb =
false;
6354 pb_spec.b_revrgb =
false;
6359 CreateCompatibleS57Object(pObj, &cobj, &ctx);
6365 toSM(vp->clat, vp->clon, pObj->chart_ref_lat, pObj->chart_ref_lon,
6366 &transform.easting_vp_center, &transform.northing_vp_center);
6369 ObjRazRules rzRules;
6370 rzRules.obj = &cobj;
6371 rzRules.LUP = pContext->LUP;
6372 rzRules.sm_transform_parms = &transform;
6373 rzRules.child = pContext->ChildRazRules;
6374 rzRules.next = NULL;
6375 rzRules.mps = pContext->MPSRulesList;
6377 ViewPort cvp = CreateCompatibleViewport(*vp);
6381 if (!(gs_plib_flags & PLIB_CAPS_SINGLEGEO_BUFFER)) {
6382 if (!pObj->geoPtMulti) {
6383 PolyTessGeo* tess = (PolyTessGeo*)pObj->pPolyTessGeo;
6385 if (!tess)
return 1;
6387 PolyTriGroup* ptg =
new PolyTriGroup;
6388 ptg->tri_prim_head =
6389 tess->Get_PolyTriGroup_head()->tri_prim_head;
6390 ptg->bsingle_alloc =
false;
6391 ptg->data_type = DATA_TYPE_DOUBLE;
6392 tess->Set_PolyTriGroup_head(ptg);
6394 double* pd = (
double*)malloc(
sizeof(
double));
6395 pObj->geoPtMulti = pd;
6399 if (pContext->LUP) {
6402 ps52plib->SetVPointCompat(cvp.pix_width, cvp.pix_height, cvp.view_scale_ppm,
6403 cvp.rotation, cvp.clat, cvp.clon, cvp.chart_scale,
6404 cvp.rv_rect, cvp.GetBBox(), cvp.ref_scale,
6405 GetOCPNCanvasWindow()->GetContentScaleFactor());
6406 ps52plib->PrepareForRender();
6408 ps52plib->RenderAreaToDC(pdc, &rzRules, &pb_spec);
6411 UpdatePIObjectPlibContext(pObj, &cobj, &rzRules);
6417 int PI_PLIBRenderAreaToGL(
const wxGLContext& glcc,
PI_S57Obj* pObj,
6423 CreateCompatibleS57Object(pObj, &cobj, &ctx);
6430 if (!(gs_plib_flags & PLIB_CAPS_SINGLEGEO_BUFFER)) {
6431 if (!pObj->geoPtMulti) {
6432 PolyTessGeo* tess = (PolyTessGeo*)pObj->pPolyTessGeo;
6434 if (!tess)
return 1;
6438 ptg->tri_prim_head = tess->Get_PolyTriGroup_head()->tri_prim_head;
6439 ptg->bsingle_alloc =
false;
6440 ptg->data_type = DATA_TYPE_DOUBLE;
6441 tess->Set_PolyTriGroup_head(ptg);
6445 double* pd = (
double*)malloc(
sizeof(
double));
6446 pObj->geoPtMulti = pd;
6452 if (pObj->auxParm0 < 1)
6461 toSM(vp->clat, vp->clon, pObj->chart_ref_lat, pObj->chart_ref_lon,
6462 &transform.easting_vp_center, &transform.northing_vp_center);
6465 ObjRazRules rzRules;
6466 rzRules.obj = &cobj;
6467 rzRules.LUP = pContext->LUP;
6468 rzRules.sm_transform_parms = &transform;
6469 rzRules.child = pContext->ChildRazRules;
6470 rzRules.next = NULL;
6471 rzRules.mps = pContext->MPSRulesList;
6473 if (pContext->LUP) {
6474 ViewPort cvp = CreateCompatibleViewport(*vp);
6478 ps52plib->SetVPointCompat(cvp.pix_width, cvp.pix_height, cvp.view_scale_ppm,
6479 cvp.rotation, cvp.clat, cvp.clon, cvp.chart_scale,
6480 cvp.rv_rect, cvp.GetBBox(), cvp.ref_scale,
6481 GetOCPNCanvasWindow()->GetContentScaleFactor());
6482 ps52plib->PrepareForRender();
6484 ps52plib->RenderAreaToGL(glcc, &rzRules);
6487 UpdatePIObjectPlibContext(pObj, &cobj, &rzRules);
6494 int PI_PLIBRenderObjectToGL(
const wxGLContext& glcc,
PI_S57Obj* pObj,
6499 CreateCompatibleS57Object(pObj, &cobj, &ctx);
6505 toSM(vp->clat, vp->clon, pObj->chart_ref_lat, pObj->chart_ref_lon,
6506 &transform.easting_vp_center, &transform.northing_vp_center);
6509 ObjRazRules rzRules;
6510 rzRules.obj = &cobj;
6511 rzRules.LUP = pContext->LUP;
6512 rzRules.sm_transform_parms = &transform;
6513 rzRules.child = pContext->ChildRazRules;
6514 rzRules.next = NULL;
6515 rzRules.mps = pContext->MPSRulesList;
6517 if (pContext->LUP) {
6518 ViewPort cvp = CreateCompatibleViewport(*vp);
6522 ps52plib->SetVPointCompat(cvp.pix_width, cvp.pix_height, cvp.view_scale_ppm,
6523 cvp.rotation, cvp.clat, cvp.clon, cvp.chart_scale,
6524 cvp.rv_rect, cvp.GetBBox(), cvp.ref_scale,
6525 GetOCPNCanvasWindow()->GetContentScaleFactor());
6526 ps52plib->PrepareForRender();
6528 ps52plib->RenderObjectToGL(glcc, &rzRules);
6531 UpdatePIObjectPlibContext(pObj, &cobj, &rzRules);
6542 double fromDMM_Plugin(wxString sdms) {
return fromDMM(sdms); }
6544 void SetCanvasRotation(
double rotation) {
6545 gFrame->GetPrimaryCanvas()->DoRotateCanvas(rotation);
6548 double GetCanvasTilt() {
return gFrame->GetPrimaryCanvas()->GetVPTilt(); }
6550 void SetCanvasTilt(
double tilt) {
6551 gFrame->GetPrimaryCanvas()->DoTiltCanvas(tilt);
6554 void SetCanvasProjection(
int projection) {
6555 gFrame->GetPrimaryCanvas()->SetVPProjection(projection);
6558 OcpnSound* g_PluginSound = SoundFactory();
6559 static void onPlugInPlaySoundExFinished(
void* ptr) {}
6563 bool ok = g_PluginSound->Load(sound_file, deviceIndex);
6565 wxLogWarning(
"Cannot load sound file: %s", sound_file);
6568 auto cmd_sound =
dynamic_cast<SystemCmdSound*
>(g_PluginSound);
6569 if (cmd_sound) cmd_sound->SetCmd(g_CmdSoundString.mb_str(wxConvUTF8));
6571 g_PluginSound->SetFinishedCallback(onPlugInPlaySoundExFinished, NULL);
6572 ok = g_PluginSound->Play();
6574 wxLogWarning(
"Cannot play sound file: %s", sound_file);
6579 bool CheckEdgePan_PlugIn(
int x,
int y,
bool dragging,
int margin,
int delta) {
6580 return gFrame->GetPrimaryCanvas()->CheckEdgePan(x, y, dragging, margin,
6584 wxBitmap GetIcon_PlugIn(
const wxString& name) {
6586 return style->GetIcon(name);
6589 void SetCursor_PlugIn(wxCursor* pCursor) {
6590 gFrame->GetPrimaryCanvas()->pPlugIn_Cursor = pCursor;
6593 void AddChartDirectory(wxString& path) {
6595 g_options->AddChartDir(path);
6599 void ForceChartDBUpdate() {
6601 g_options->pScanCheckBox->SetValue(
true);
6602 g_options->pUpdateCheckBox->SetValue(
true);
6606 void ForceChartDBRebuild() {
6608 g_options->pUpdateCheckBox->SetValue(
true);
6612 wxDialog* GetActiveOptionsDialog() {
return g_options; }
6614 int PlatformDirSelectorDialog(wxWindow* parent, wxString* file_spec,
6615 wxString Title, wxString initDir) {
6616 return g_Platform->DoDirSelectorDialog(parent, file_spec, Title, initDir);
6619 int PlatformFileSelectorDialog(wxWindow* parent, wxString* file_spec,
6620 wxString Title, wxString initDir,
6621 wxString suggestedName, wxString wildcard) {
6622 return g_Platform->DoFileSelectorDialog(parent, file_spec, Title, initDir,
6623 suggestedName, wildcard);
6630 OCPN_downloadEvent::OCPN_downloadEvent(wxEventType commandType,
int id)
6631 : wxEvent(id, commandType) {
6632 m_stat = OCPN_DL_UNKNOWN;
6633 m_condition = OCPN_DL_EVENT_TYPE_UNKNOWN;
6634 m_b_complete =
false;
6638 OCPN_downloadEvent::~OCPN_downloadEvent() {}
6640 wxEvent* OCPN_downloadEvent::Clone()
const {
6642 newevent->m_stat = this->m_stat;
6643 newevent->m_condition = this->m_condition;
6645 newevent->m_totalBytes = this->m_totalBytes;
6646 newevent->m_sofarBytes = this->m_sofarBytes;
6647 newevent->m_b_complete = this->m_b_complete;
6653 DECL_EXP wxEventType wxEVT_DOWNLOAD_EVENT = wxNewEventType();
6655 _OCPN_DLStatus g_download_status;
6656 _OCPN_DLCondition g_download_condition;
6658 #define DL_EVENT_TIMER 4388
6666 void setBackgroundMode(
long ID, wxEvtHandler* handler);
6667 void clearBackgroundMode();
6668 void onTimerEvent(wxTimerEvent& event);
6671 wxTimer m_eventTimer;
6672 wxEvtHandler* m_download_evHandler;
6678 PI_DLEvtHandler::PI_DLEvtHandler() {
6679 g_download_status = OCPN_DL_UNKNOWN;
6680 g_download_condition = OCPN_DL_EVENT_TYPE_UNKNOWN;
6682 m_download_evHandler = NULL;
6688 PI_DLEvtHandler::~PI_DLEvtHandler() {
6689 m_eventTimer.Stop();
6692 (wxObjectEventFunction)(wxEventFunction)&PI_DLEvtHandler::onTimerEvent);
6699 g_download_status =
event.getDLEventStatus();
6700 g_download_condition =
event.getDLEventCondition();
6703 if (m_download_evHandler &&
6704 (OCPN_DL_EVENT_TYPE_END == event.getDLEventCondition())) {
6706 ev.setComplete(
true);
6707 ev.setTransferred(m_sofarBytes);
6708 ev.setTotal(m_totalBytes);
6710 ev.setDLEventStatus(event.getDLEventStatus());
6711 ev.setDLEventCondition(OCPN_DL_EVENT_TYPE_END);
6713 m_download_evHandler->AddPendingEvent(ev);
6714 m_eventTimer.Stop();
6716 finishAndroidFileDownload();
6723 void PI_DLEvtHandler::setBackgroundMode(
long ID, wxEvtHandler* handler) {
6725 m_download_evHandler = handler;
6727 m_eventTimer.SetOwner(
this, DL_EVENT_TIMER);
6731 (wxObjectEventFunction)(wxEventFunction)&PI_DLEvtHandler::onTimerEvent);
6732 m_eventTimer.Start(1000, wxTIMER_CONTINUOUS);
6735 void PI_DLEvtHandler::clearBackgroundMode() {
6736 m_download_evHandler = NULL;
6737 m_eventTimer.Stop();
6740 void PI_DLEvtHandler::onTimerEvent(wxTimerEvent& event) {
6746 int stat = queryAndroidFileDownload(m_id, &sstat);
6749 long sofarBytes = 0;
6750 long totalBytes = -1;
6754 qDebug() <<
"Error on queryAndroidFileDownload, ending download";
6755 ev.setComplete(
true);
6756 ev.setTransferred(sofarBytes);
6757 ev.setTotal(totalBytes);
6759 ev.setDLEventStatus(OCPN_DL_FAILED);
6760 ev.setDLEventCondition(OCPN_DL_EVENT_TYPE_END);
6762 wxStringTokenizer tk(sstat, _T(
";"));
6763 if (tk.HasMoreTokens()) {
6764 wxString token = tk.GetNextToken();
6765 token.ToLong(&state);
6766 token = tk.GetNextToken();
6767 token.ToLong(&sofarBytes);
6768 token = tk.GetNextToken();
6769 token.ToLong(&totalBytes);
6772 qDebug() << state << sofarBytes << totalBytes;
6774 m_sofarBytes = sofarBytes;
6775 m_totalBytes = totalBytes;
6777 ev.setTransferred(sofarBytes);
6778 ev.setTotal(totalBytes);
6781 qDebug() <<
"Event OCPN_DL_FAILED/OCPN_DL_EVENT_TYPE_END";
6782 ev.setComplete(
true);
6783 ev.setDLEventStatus(OCPN_DL_FAILED);
6784 ev.setDLEventCondition(OCPN_DL_EVENT_TYPE_END);
6785 }
else if (state == 8) {
6786 qDebug() <<
"Event OCPN_DL_NO_ERROR/OCPN_DL_EVENT_TYPE_END";
6787 ev.setComplete(
true);
6788 ev.setDLEventStatus(OCPN_DL_NO_ERROR);
6789 ev.setDLEventCondition(OCPN_DL_EVENT_TYPE_END);
6791 ev.setComplete(
false);
6792 ev.setDLEventStatus(OCPN_DL_UNKNOWN);
6793 ev.setDLEventCondition(OCPN_DL_EVENT_TYPE_PROGRESS);
6799 if (m_download_evHandler) {
6801 m_download_evHandler->AddPendingEvent(ev);
6805 if (OCPN_DL_EVENT_TYPE_END == ev.getDLEventCondition()) {
6806 m_eventTimer.Stop();
6807 finishAndroidFileDownload();
6816 _OCPN_DLStatus OCPN_downloadFile(
const wxString& url,
6817 const wxString& outputFile,
6818 const wxString& title,
const wxString& message,
6819 const wxBitmap& bitmap, wxWindow* parent,
6820 long style,
int timeout_secs) {
6823 wxString msg = _T(
"Downloading file synchronously: ");
6830 int vres = validateAndroidWriteLocation(outputFile);
6832 return OCPN_DL_ABORTED;
6838 g_download_status = OCPN_DL_UNKNOWN;
6839 g_download_condition = OCPN_DL_EVENT_TYPE_UNKNOWN;
6842 g_piEventHandler->Connect(
6843 wxEVT_DOWNLOAD_EVENT,
6844 (wxObjectEventFunction)(wxEventFunction)&PI_DLEvtHandler::onDLEvent);
6849 wxString fURI = outputFile;
6850 if (!fURI.StartsWith(_T(
"file://"))) {
6851 fURI.Prepend(_T(
"file://"));
6854 int res = startAndroidFileDownload(url, fURI, g_piEventHandler, &dl_ID);
6857 finishAndroidFileDownload();
6858 g_piEventHandler->Disconnect(
6859 wxEVT_DOWNLOAD_EVENT,
6860 (wxObjectEventFunction)(wxEventFunction)&PI_DLEvtHandler::onDLEvent);
6862 return OCPN_DL_FAILED;
6865 wxDateTime dl_start_time = wxDateTime::Now();
6869 wxTimeSpan dt = wxDateTime::Now() - dl_start_time;
6870 qDebug() <<
"Spin.." << dt.GetSeconds().GetLo();
6872 if (dt.GetSeconds() > timeout_secs) {
6873 qDebug() <<
"USER_TIMOUT";
6874 finishAndroidFileDownload();
6875 g_piEventHandler->Disconnect(
6876 wxEVT_DOWNLOAD_EVENT,
6877 (wxObjectEventFunction)(wxEventFunction)&PI_DLEvtHandler::onDLEvent);
6879 return (OCPN_DL_USER_TIMEOUT);
6882 if (g_download_condition != OCPN_DL_EVENT_TYPE_UNKNOWN) {
6883 if (OCPN_DL_EVENT_TYPE_END == g_download_condition) {
6884 _OCPN_DLStatus ss = g_download_status;
6885 finishAndroidFileDownload();
6886 g_piEventHandler->Disconnect(
6887 wxEVT_DOWNLOAD_EVENT,
6891 qDebug() <<
"RETURN DL_END" << (int)ss;
6897 int stat = queryAndroidFileDownload(dl_ID, &sstat);
6899 qDebug() <<
"Error on queryAndroidFileDownload";
6900 finishAndroidFileDownload();
6901 g_piEventHandler->Disconnect(
6902 wxEVT_DOWNLOAD_EVENT,
6903 (wxObjectEventFunction)(wxEventFunction)&PI_DLEvtHandler::onDLEvent);
6906 return OCPN_DL_FAILED;
6913 #elif defined(OCPN_USE_CURL)
6914 wxFileName tfn = wxFileName::CreateTempFileName(outputFile);
6915 wxFileOutputStream output(tfn.GetFullPath());
6917 wxCurlDownloadDialog ddlg(url, &output, title, message + url, bitmap, parent,
6919 wxCurlDialogReturnFlag ret = ddlg.RunModal();
6922 _OCPN_DLStatus result = OCPN_DL_UNKNOWN;
6925 case wxCDRF_SUCCESS: {
6926 if (wxCopyFile(tfn.GetFullPath(), outputFile))
6927 result = OCPN_DL_NO_ERROR;
6929 result = OCPN_DL_FAILED;
6932 case wxCDRF_FAILED: {
6933 result = OCPN_DL_FAILED;
6936 case wxCDRF_USER_ABORTED: {
6937 result = OCPN_DL_ABORTED;
6944 if (wxFileExists(tfn.GetFullPath())) wxRemoveFile(tfn.GetFullPath());
6948 return OCPN_DL_FAILED;
6953 _OCPN_DLStatus OCPN_downloadFileBackground(
const wxString& url,
6954 const wxString& outputFile,
6955 wxEvtHandler* handler,
6958 wxString msg = _T(
"Downloading file asynchronously: ");
6970 int res = startAndroidFileDownload(url, outputFile, NULL ,
6974 finishAndroidFileDownload();
6975 return OCPN_DL_FAILED;
6979 g_piEventHandler->setBackgroundMode(dl_ID, handler);
6981 if (handle) *handle = dl_ID;
6983 return OCPN_DL_STARTED;
6985 #elif defined(OCPN_USE_CURL)
6986 if (g_pi_manager->m_pCurlThread)
6989 return OCPN_DL_FAILED;
6990 g_pi_manager->m_pCurlThread =
6991 new wxCurlDownloadThread(g_pi_manager, CurlThreadId);
6992 bool http = (url.StartsWith(wxS(
"http:")) || url.StartsWith(wxS(
"https:")));
6994 if (http && g_pi_manager->m_pCurl &&
6995 dynamic_cast<wxCurlHTTP*
>(g_pi_manager->m_pCurl.get())) {
6999 g_pi_manager->m_pCurl = 0;
7002 bool failed =
false;
7003 if (!g_pi_manager->HandleCurlThreadError(
7004 g_pi_manager->m_pCurlThread->SetURL(url, g_pi_manager->m_pCurl),
7005 g_pi_manager->m_pCurlThread, url))
7008 g_pi_manager->m_pCurl = g_pi_manager->m_pCurlThread->GetCurlSharedPtr();
7009 if (!g_pi_manager->HandleCurlThreadError(
7010 g_pi_manager->m_pCurlThread->SetOutputStream(
7011 new wxFileOutputStream(outputFile)),
7012 g_pi_manager->m_pCurlThread))
7016 g_pi_manager->m_download_evHandler = handler;
7017 g_pi_manager->m_downloadHandle = handle;
7019 wxCurlThreadError err = g_pi_manager->m_pCurlThread->Download();
7020 if (err != wxCTE_NO_ERROR) {
7021 g_pi_manager->HandleCurlThreadError(
7022 err, g_pi_manager->m_pCurlThread);
7023 g_pi_manager->m_pCurlThread->Abort();
7028 if (!failed)
return OCPN_DL_STARTED;
7030 if (g_pi_manager->m_pCurlThread) {
7031 if (g_pi_manager->m_pCurlThread->IsAlive())
7032 g_pi_manager->m_pCurlThread->Abort();
7033 if (g_pi_manager->m_pCurlThread->GetOutputStream())
7034 delete (g_pi_manager->m_pCurlThread->GetOutputStream());
7035 wxDELETE(g_pi_manager->m_pCurlThread);
7036 g_pi_manager->m_download_evHandler = NULL;
7037 g_pi_manager->m_downloadHandle = NULL;
7038 return OCPN_DL_STARTED;
7040 g_pi_manager->m_pCurl = 0;
7041 return OCPN_DL_FAILED;
7044 return OCPN_DL_FAILED;
7048 void OCPN_cancelDownloadFileBackground(
long handle) {
7049 #ifdef OCPN_USE_CURL
7052 cancelAndroidFileDownload(handle);
7053 finishAndroidFileDownload();
7054 if (g_piEventHandler) g_piEventHandler->clearBackgroundMode();
7056 if (g_pi_manager->m_pCurlThread) {
7057 g_pi_manager->m_pCurlThread->Abort();
7058 delete (g_pi_manager->m_pCurlThread->GetOutputStream());
7059 wxDELETE(g_pi_manager->m_pCurlThread);
7060 g_pi_manager->m_download_evHandler = NULL;
7061 g_pi_manager->m_downloadHandle = NULL;
7063 g_pi_manager->m_pCurl = 0;
7068 _OCPN_DLStatus OCPN_postDataHttp(
const wxString& url,
7069 const wxString& parameters, wxString& result,
7072 wxString lparms = parameters;
7073 wxString postResult = doAndroidPOST(url, lparms, timeout_secs * 1000);
7074 if (postResult.IsSameAs(_T(
"NOK")))
return OCPN_DL_FAILED;
7076 result = postResult;
7077 return OCPN_DL_NO_ERROR;
7079 #elif defined(OCPN_USE_CURL)
7081 post.SetOpt(CURLOPT_TIMEOUT, timeout_secs);
7082 size_t res = post.Post(parameters.ToAscii(), parameters.Len(), url);
7085 result = wxString(post.GetResponseBody().c_str(), wxConvUTF8);
7086 return OCPN_DL_NO_ERROR;
7088 result = wxEmptyString;
7090 return OCPN_DL_FAILED;
7093 return OCPN_DL_FAILED;
7097 bool OCPN_isOnline() {
7099 return androidCheckOnline();
7102 #if !defined(__ANDROID__) && defined(OCPN_USE_CURL)
7103 if (wxDateTime::GetTimeNow() >
7104 g_pi_manager->m_last_online_chk + ONLINE_CHECK_RETRY) {
7106 get.Head(_T(
"http://yahoo.com/"));
7107 g_pi_manager->m_last_online = get.GetResponseCode() > 0;
7109 g_pi_manager->m_last_online_chk = wxDateTime::GetTimeNow();
7111 return g_pi_manager->m_last_online;
7117 #if !defined(__ANDROID__) && defined(OCPN_USE_CURL)
7118 void PlugInManager::OnEndPerformCurlDownload(wxCurlEndPerformEvent& ev) {
7120 if (ev.IsSuccessful()) {
7121 event.setDLEventStatus(OCPN_DL_NO_ERROR);
7123 g_pi_manager->m_pCurl = 0;
7124 event.setDLEventStatus(OCPN_DL_FAILED);
7126 event.setDLEventCondition(OCPN_DL_EVENT_TYPE_END);
7127 event.setComplete(
true);
7129 if (m_download_evHandler) {
7130 m_download_evHandler->AddPendingEvent(event);
7131 m_download_evHandler = NULL;
7132 m_downloadHandle = NULL;
7135 if (m_pCurlThread) {
7136 m_pCurlThread->Wait();
7137 if (!m_pCurlThread->IsAborting()) {
7138 delete (m_pCurlThread->GetOutputStream());
7139 wxDELETE(m_pCurlThread);
7144 void PlugInManager::OnCurlDownload(wxCurlDownloadEvent& ev) {
7146 event.setDLEventStatus(OCPN_DL_UNKNOWN);
7147 event.setDLEventCondition(OCPN_DL_EVENT_TYPE_PROGRESS);
7148 event.setTotal(ev.GetTotalBytes());
7149 event.setTransferred(ev.GetDownloadedBytes());
7150 event.setComplete(
false);
7152 if (m_download_evHandler) {
7153 m_download_evHandler->AddPendingEvent(event);
7157 bool PlugInManager::HandleCurlThreadError(wxCurlThreadError err,
7158 wxCurlBaseThread* p,
7159 const wxString& url) {
7161 case wxCTE_NO_ERROR:
7164 case wxCTE_NO_RESOURCE:
7166 wxS(
"Insufficient resources for correct execution of the program."));
7169 case wxCTE_ALREADY_RUNNING:
7173 case wxCTE_INVALID_PROTOCOL:
7174 wxLogError(wxS(
"The URL '%s' uses an unsupported protocol."),
7178 case wxCTE_NO_VALID_STREAM:
7185 case wxCTE_CURL_ERROR: {
7186 wxString ws = wxS(
"unknown");
7187 if (p->GetCurlSession())
7189 wxString(p->GetCurlSession()->GetErrorString().c_str(), wxConvUTF8);
7190 wxLogError(wxS(
"Network error: %s"), ws.c_str());
7195 if (p->IsAlive()) p->Abort();
7202 bool LaunchDefaultBrowser_Plugin(wxString url) {
7203 if (g_Platform) g_Platform->platformLaunchDefaultBrowser(url);
7210 void PlugInAISDrawGL(wxGLCanvas* glcanvas,
const PlugIn_ViewPort& vp) {
7211 ViewPort ocpn_vp = CreateCompatibleViewport(vp);
7216 AISDraw(dc, ocpn_vp, NULL);
7219 bool PlugInSetFontColor(
const wxString TextElement,
const wxColour color) {
7220 return FontMgr::Get().SetFontColor(TextElement, color);
7225 double PlugInGetDisplaySizeMM() {
return g_Platform->GetDisplaySizeMM(); }
7227 wxFont* FindOrCreateFont_PlugIn(
int point_size, wxFontFamily family,
7228 wxFontStyle style, wxFontWeight weight,
7229 bool underline,
const wxString& facename,
7230 wxFontEncoding encoding) {
7231 return FontMgr::Get().FindOrCreateFont(point_size, family, style, weight,
7232 underline, facename, encoding);
7235 int PluginGetMinAvailableGshhgQuality() {
7236 return gFrame->GetPrimaryCanvas()->GetMinAvailableGshhgQuality();
7238 int PluginGetMaxAvailableGshhgQuality() {
7239 return gFrame->GetPrimaryCanvas()->GetMaxAvailableGshhgQuality();
7243 void PlugInHandleAutopilotRoute(
bool enable) {
7244 g_bPluginHandleAutopilotRoute = enable;
7248 wxString GetSelectedWaypointGUID_Plugin() {
7250 if (cc && cc->GetSelectedRoutePoint()) {
7251 return cc->GetSelectedRoutePoint()->m_GUID;
7253 return wxEmptyString;
7256 wxString GetSelectedRouteGUID_Plugin() {
7258 if (cc && cc->GetSelectedRoute()) {
7259 return cc->GetSelectedRoute()->m_GUID;
7261 return wxEmptyString;
7264 wxString GetSelectedTrackGUID_Plugin() {
7266 if (cc && cc->GetSelectedTrack()) {
7267 return cc->GetSelectedTrack()->m_GUID;
7269 return wxEmptyString;
7272 std::unique_ptr<PlugIn_Waypoint> GetWaypoint_Plugin(
const wxString& GUID) {
7274 GetSingleWaypoint(GUID, w.get());
7278 std::unique_ptr<PlugIn_Route> GetRoute_Plugin(
const wxString& GUID) {
7279 std::unique_ptr<PlugIn_Route> r;
7280 Route* route = g_pRouteMan->FindRouteByGUID(GUID);
7281 if (route ==
nullptr)
return r;
7288 wxRoutePointListNode* node = route->pRoutePointList->GetFirst();
7291 src_wp = node->GetData();
7294 PlugInFromRoutePoint(dst_wp, src_wp);
7296 dst_route->pWaypointList->Append(dst_wp);
7298 node = node->GetNext();
7300 dst_route->m_NameString = route->m_RouteNameString;
7301 dst_route->m_StartString = route->m_RouteStartString;
7302 dst_route->m_EndString = route->m_RouteEndString;
7303 dst_route->m_GUID = route->m_GUID;
7308 std::unique_ptr<PlugIn_Track> GetTrack_Plugin(
const wxString& GUID) {
7309 std::unique_ptr<PlugIn_Track> t;
7311 Track* pTrack = g_pRouteMan->FindTrackByGUID(GUID);
7312 if (!pTrack)
return t;
7314 std::unique_ptr<PlugIn_Track> tk =
7317 dst_track->m_NameString = pTrack->GetName();
7318 dst_track->m_StartString = pTrack->m_TrackStartString;
7319 dst_track->m_EndString = pTrack->m_TrackEndString;
7320 dst_track->m_GUID = pTrack->m_GUID;
7322 for (
int i = 0; i < pTrack->GetnPoints(); i++) {
7327 dst_wp->m_lat = ptp->m_lat;
7328 dst_wp->m_lon = ptp->m_lon;
7329 dst_wp->m_CreateTime = ptp->GetCreateTime();
7331 dst_track->pWaypointList->Append(dst_wp);
7337 wxWindow* PluginGetFocusCanvas() {
return g_focusCanvas; }
7339 wxWindow* PluginGetOverlayRenderCanvas() {
7341 return g_overlayCanvas;
7345 void CanvasJumpToPosition(wxWindow* canvas,
double lat,
double lon,
7348 if (oCanvas) gFrame->JumpToPosition(oCanvas, lat, lon,
scale);
7351 bool ShuttingDown(
void) {
return g_bquiting; }
7353 wxWindow* GetCanvasUnderMouse(
void) {
return gFrame->GetCanvasUnderMouse(); }
7355 int GetCanvasIndexUnderMouse(
void) {
7356 ChartCanvas* l_canvas = gFrame->GetCanvasUnderMouse();
7358 for (
unsigned int i = 0; i < g_canvasArray.GetCount(); ++i) {
7359 if (l_canvas == g_canvasArray[i])
return i;
7376 wxWindow* GetCanvasByIndex(
int canvasIndex) {
7377 if (g_canvasConfig == 0)
7378 return gFrame->GetPrimaryCanvas();
7380 if ((canvasIndex >= 0) && g_canvasArray[canvasIndex]) {
7381 return g_canvasArray[canvasIndex];
7387 bool CheckMUIEdgePan_PlugIn(
int x,
int y,
bool dragging,
int margin,
int delta,
7389 if (g_canvasConfig == 0)
7390 return gFrame->GetPrimaryCanvas()->CheckEdgePan(x, y, dragging, margin,
7393 if ((canvasIndex >= 0) && g_canvasArray[canvasIndex]) {
7394 return g_canvasArray[canvasIndex]->CheckEdgePan(x, y, dragging, margin,
7402 void SetMUICursor_PlugIn(wxCursor* pCursor,
int canvasIndex) {
7403 if (g_canvasConfig == 0)
7404 gFrame->GetPrimaryCanvas()->pPlugIn_Cursor = pCursor;
7406 if ((canvasIndex >= 0) && g_canvasArray[canvasIndex]) {
7407 g_canvasArray[canvasIndex]->pPlugIn_Cursor = pCursor;
7412 int GetCanvasCount() {
7413 if (g_canvasConfig == 1)
return 2;
7418 int GetLatLonFormat() {
return g_iSDMMFormat; }
7420 wxRect GetMasterToolbarRect() {
7422 return g_MainToolbar->GetToolbarRect();
7424 return wxRect(0, 0, 1, 1);
7431 g_pRouteMan->ZeroCurrentXTEToActivePoint();
7435 ListOfPI_S57Obj* PlugInManager::GetLightsObjRuleListVisibleAtLatLon(
7437 ListOfPI_S57Obj* list = NULL;
7443 list = picbgl->GetLightsObjRuleListVisibleAtLatLon(zlat, zlon, &pi_vp);
7451 list = picbx->GetLightsObjRuleListVisibleAtLatLon(zlat, zlon, &pi_vp);
7461 WX_DEFINE_LIST(Plugin_WaypointExList)
7464 PlugIn_Waypoint_Ex::PlugIn_Waypoint_Ex() { InitDefaults(); }
7466 PlugIn_Waypoint_Ex::PlugIn_Waypoint_Ex(
7467 double lat,
double lon,
const wxString& icon_ident,
const wxString& wp_name,
7468 const wxString& GUID,
const double ScaMin,
const bool bNameVisible,
7469 const int nRangeRings,
const double RangeDistance,
7470 const wxColor RangeColor) {
7473 wxDateTime now = wxDateTime::Now();
7474 m_CreateTime = now.ToUTC();
7475 m_HyperlinkList = NULL;
7479 IconName = icon_ident;
7480 m_MarkName = wp_name;
7483 IsNameVisible = bNameVisible;
7484 nrange_rings = nRangeRings;
7485 RangeRingSpace = RangeDistance;
7486 RangeRingColor = RangeColor;
7489 void PlugIn_Waypoint_Ex::InitDefaults() {
7490 m_HyperlinkList = NULL;
7492 b_useScamin =
false;
7495 IsNameVisible =
false;
7497 RangeRingColor = *wxBLACK;
7498 m_CreateTime = wxDateTime::Now();
7504 bool PlugIn_Waypoint_Ex::GetFSStatus() {
7505 RoutePoint* prp = pWayPointMan->FindRoutePointByGUID(m_GUID);
7506 if (!prp)
return false;
7508 if (prp->m_bIsInRoute && !prp->IsShared())
return false;
7513 int PlugIn_Waypoint_Ex::GetRouteMembershipCount() {
7515 RoutePoint* pWP = pWayPointMan->FindRoutePointByGUID(m_GUID);
7519 wxRouteListNode* node = pRouteList->GetFirst();
7521 Route* proute = node->GetData();
7522 wxRoutePointListNode* pnode = (proute->pRoutePointList)->GetFirst();
7525 if (prp == pWP) nCount++;
7526 pnode = pnode->GetNext();
7529 node = node->GetNext();
7535 PlugIn_Waypoint_Ex::~PlugIn_Waypoint_Ex() {}
7538 PlugIn_Route_Ex::PlugIn_Route_Ex(
void) {
7539 pWaypointList =
new Plugin_WaypointExList;
7542 PlugIn_Route_Ex::~PlugIn_Route_Ex(
void) {
7543 pWaypointList->DeleteContents(
false);
7544 pWaypointList->Clear();
7546 delete pWaypointList;
7554 dst->m_lat = src->m_lat;
7555 dst->m_lon = src->m_lon;
7556 dst->IconName = src->GetIconName();
7557 dst->m_MarkName = src->GetName();
7558 dst->m_MarkDescription = src->GetDescription();
7559 dst->IconDescription = pWayPointMan->GetIconDescription(src->GetIconName());
7560 dst->IsVisible = src->IsVisible();
7561 dst->m_CreateTime = src->GetCreateTime();
7562 dst->m_GUID = src->m_GUID;
7565 if (src->m_HyperlinkList ==
nullptr)
return;
7567 delete dst->m_HyperlinkList;
7568 dst->m_HyperlinkList =
nullptr;
7570 if (src->m_HyperlinkList->GetCount() > 0) {
7571 dst->m_HyperlinkList =
new Plugin_HyperlinkList;
7573 wxHyperlinkListNode* linknode = src->m_HyperlinkList->GetFirst();
7578 h->DescrText = link->DescrText;
7579 h->Link = link->Link;
7580 h->Type = link->LType;
7582 dst->m_HyperlinkList->Append(h);
7584 linknode = linknode->GetNext();
7589 dst->nrange_rings = src->m_iWaypointRangeRingsNumber;
7590 dst->RangeRingSpace = src->m_fWaypointRangeRingsStep;
7591 dst->RangeRingColor = src->m_wxcWaypointRangeRingsColour;
7594 dst->IsNameVisible = src->m_bShowName;
7595 dst->scamin = src->GetScaMin();
7596 dst->b_useScamin = src->GetUseSca();
7597 dst->IsActive = src->m_bIsActive;
7600 static void cloneHyperlinkListEx(
RoutePoint* dst,
7603 if (src->m_HyperlinkList ==
nullptr)
return;
7605 if (src->m_HyperlinkList->GetCount() > 0) {
7606 wxPlugin_HyperlinkListNode* linknode = src->m_HyperlinkList->GetFirst();
7611 h->DescrText = link->DescrText;
7612 h->Link = link->Link;
7613 h->LType = link->Type;
7615 dst->m_HyperlinkList->Append(h);
7617 linknode = linknode->GetNext();
7624 src->m_MarkName, src->m_GUID);
7626 pWP->m_bIsolatedMark =
true;
7628 cloneHyperlinkListEx(pWP, src);
7630 pWP->m_MarkDescription = src->m_MarkDescription;
7632 if (src->m_CreateTime.IsValid())
7633 pWP->SetCreateTime(src->m_CreateTime);
7635 wxDateTime dtnow(wxDateTime::Now());
7636 pWP->SetCreateTime(dtnow);
7639 pWP->m_btemp = (b_permanent ==
false);
7642 pWP->SetIconName(src->IconName);
7643 pWP->SetWaypointRangeRingsNumber(src->nrange_rings);
7644 pWP->SetWaypointRangeRingsStep(src->RangeRingSpace);
7645 pWP->SetWaypointRangeRingsColour(src->RangeRingColor);
7646 pWP->SetScaMin(src->scamin);
7647 pWP->SetUseSca(src->b_useScamin);
7648 pWP->SetNameShown(src->IsNameVisible);
7649 pWP->SetVisible(src->IsVisible);
7655 RoutePoint* prp = pWayPointMan->FindRoutePointByGUID(GUID);
7657 if (!prp)
return false;
7659 PlugInExFromRoutePoint(pwaypoint, prp);
7669 bool b_unique =
true;
7670 wxRoutePointListNode* prpnode = pWayPointMan->GetWaypointList()->GetFirst();
7674 if (prp->m_GUID == pwaypointex->m_GUID) {
7678 prpnode = prpnode->GetNext();
7681 if (!b_unique)
return false;
7683 RoutePoint* pWP = CreateNewPoint(pwaypointex, b_permanent);
7685 pWP->SetShowWaypointRangeRings(pwaypointex->nrange_rings > 0);
7687 pSelect->AddSelectableRoutePoint(pWP->m_lat, pWP->m_lon, pWP);
7688 if (b_permanent) pConfig->AddNewWayPoint(pWP, -1);
7690 if (pRouteManagerDialog && pRouteManagerDialog->IsShown())
7691 pRouteManagerDialog->UpdateWptListCtrl();
7698 bool b_found =
false;
7699 RoutePoint* prp = pWayPointMan->FindRoutePointByGUID(pwaypoint->m_GUID);
7701 if (prp) b_found =
true;
7704 double lat_save = prp->m_lat;
7705 double lon_save = prp->m_lon;
7707 prp->m_lat = pwaypoint->m_lat;
7708 prp->m_lon = pwaypoint->m_lon;
7709 prp->SetIconName(pwaypoint->IconName);
7710 prp->SetName(pwaypoint->m_MarkName);
7711 prp->m_MarkDescription = pwaypoint->m_MarkDescription;
7712 prp->SetVisible(pwaypoint->IsVisible);
7713 if (pwaypoint->m_CreateTime.IsValid())
7714 prp->SetCreateTime(pwaypoint->m_CreateTime);
7718 if (pwaypoint->m_HyperlinkList) {
7719 prp->m_HyperlinkList->Clear();
7720 if (pwaypoint->m_HyperlinkList->GetCount() > 0) {
7721 wxPlugin_HyperlinkListNode* linknode =
7722 pwaypoint->m_HyperlinkList->GetFirst();
7727 h->DescrText = link->DescrText;
7728 h->Link = link->Link;
7729 h->LType = link->Type;
7731 prp->m_HyperlinkList->Append(h);
7733 linknode = linknode->GetNext();
7739 prp->SetWaypointRangeRingsNumber(pwaypoint->nrange_rings);
7740 prp->SetWaypointRangeRingsStep(pwaypoint->RangeRingSpace);
7741 prp->SetWaypointRangeRingsColour(pwaypoint->RangeRingColor);
7742 prp->SetScaMin(pwaypoint->scamin);
7743 prp->SetUseSca(pwaypoint->b_useScamin);
7744 prp->SetNameShown(pwaypoint->IsNameVisible);
7746 prp->SetShowWaypointRangeRings(pwaypoint->nrange_rings > 0);
7748 if (prp) prp->ReLoadIcon();
7750 auto canvas = gFrame->GetPrimaryCanvas();
7751 SelectCtx ctx(canvas->m_bShowNavobjects, canvas->GetCanvasTrueScale(), canvas->GetScaleValue());
7753 pSelect->FindSelection(ctx, lat_save, lon_save, SELTYPE_ROUTEPOINT);
7755 pFind->m_slat = pwaypoint->m_lat;
7756 pFind->m_slon = pwaypoint->m_lon;
7759 if (!prp->m_btemp) pConfig->UpdateWayPoint(prp);
7761 if (pRouteManagerDialog && pRouteManagerDialog->IsShown())
7762 pRouteManagerDialog->UpdateWptListCtrl();
7774 wxDateTime plannedDeparture;
7776 wxPlugin_WaypointExListNode* pwpnode = proute->pWaypointList->GetFirst();
7778 pwaypointex = pwpnode->GetData();
7780 pWP = pWayPointMan->FindRoutePointByGUID(pwaypointex->m_GUID);
7782 pWP = CreateNewPoint(pwaypointex, b_permanent);
7783 pWP->m_bIsolatedMark =
false;
7786 route->AddPoint(pWP);
7788 pSelect->AddSelectableRoutePoint(pWP->m_lat, pWP->m_lon, pWP);
7791 pSelect->AddSelectableRouteSegment(pWP_src->m_lat, pWP_src->m_lon,
7792 pWP->m_lat, pWP->m_lon, pWP_src, pWP,
7795 plannedDeparture = pwaypointex->m_CreateTime;
7799 pwpnode = pwpnode->GetNext();
7802 route->m_PlannedDeparture = plannedDeparture;
7804 route->m_RouteNameString = proute->m_NameString;
7805 route->m_RouteStartString = proute->m_StartString;
7806 route->m_RouteEndString = proute->m_EndString;
7807 if (!proute->m_GUID.IsEmpty()) {
7808 route->m_GUID = proute->m_GUID;
7810 route->m_btemp = (b_permanent ==
false);
7811 route->SetVisible(proute->m_isVisible);
7812 route->m_RouteDescription = proute->m_Description;
7814 pRouteList->Append(route);
7816 if (b_permanent) pConfig->AddNewRoute(route);
7818 if (pRouteManagerDialog && pRouteManagerDialog->IsShown())
7819 pRouteManagerDialog->UpdateRouteListCtrl();
7825 bool b_found =
false;
7828 Route* pRoute = g_pRouteMan->FindRouteByGUID(proute->m_GUID);
7829 if (pRoute) b_found =
true;
7832 bool b_permanent = !pRoute->m_btemp;
7833 g_pRouteMan->
DeleteRoute(pRoute, NavObjectChanges::getInstance());
7835 b_found = AddPlugInRouteEx(proute, b_permanent);
7849 std::unique_ptr<PlugIn_Waypoint_Ex> GetWaypointEx_Plugin(
const wxString& GUID) {
7851 GetSingleWaypointEx(GUID, w.get());
7855 std::unique_ptr<PlugIn_Route_Ex> GetRouteEx_Plugin(
const wxString& GUID) {
7856 std::unique_ptr<PlugIn_Route_Ex> r;
7857 Route* route = g_pRouteMan->FindRouteByGUID(GUID);
7858 if (route ==
nullptr)
return r;
7865 wxRoutePointListNode* node = route->pRoutePointList->GetFirst();
7868 src_wp = node->GetData();
7871 PlugInExFromRoutePoint(dst_wp, src_wp);
7873 dst_route->pWaypointList->Append(dst_wp);
7875 node = node->GetNext();
7877 dst_route->m_NameString = route->m_RouteNameString;
7878 dst_route->m_StartString = route->m_RouteStartString;
7879 dst_route->m_EndString = route->m_RouteEndString;
7880 dst_route->m_GUID = route->m_GUID;
7881 dst_route->m_isActive = g_pRouteMan->GetpActiveRoute() == route;
7882 dst_route->m_isVisible = route->IsVisible();
7883 dst_route->m_Description = route->m_RouteDescription;
7888 wxString GetActiveWaypointGUID(
7890 RoutePoint* rp = g_pRouteMan->GetpActivePoint();
7892 return wxEmptyString;
7897 wxString GetActiveRouteGUID(
7899 Route* rt = g_pRouteMan->GetpActiveRoute();
7901 return wxEmptyString;
7911 MyApp& app = wxGetApp();
7912 return (app.m_comm_bridge.GetPriorityMaps());
7915 std::vector<std::string> GetActivePriorityIdentifiers() {
7916 std::vector<std::string> result;
7918 MyApp& app = wxGetApp();
7921 app.m_comm_bridge.GetPriorityContainer(
"position").active_source;
7922 result.push_back(
id);
7923 id = app.m_comm_bridge.GetPriorityContainer(
"velocity").active_source;
7924 result.push_back(
id);
7925 id = app.m_comm_bridge.GetPriorityContainer(
"heading").active_source;
7926 result.push_back(
id);
7927 id = app.m_comm_bridge.GetPriorityContainer(
"variation").active_source;
7928 result.push_back(
id);
7929 id = app.m_comm_bridge.GetPriorityContainer(
"satellites").active_source;
7930 result.push_back(
id);
7935 double OCPN_GetDisplayContentScaleFactor() {
7937 #if defined(__WXOSX__) || defined(__WXGTK3__)
7939 if (gFrame) rv = gFrame->GetContentScaleFactor();
7943 double OCPN_GetWinDIPScaleFactor() {
7944 double scaler = 1.0;
7946 if (gFrame) scaler = (double)(gFrame->ToDIP(100)) / 100.;
EventVar plugin_msg
A JSON message should be sent.
Handle messages for blacklisted plugins.
Modal dialog, displays settings for plugin catalog.
const std::vector< DriverPtr > & GetDrivers()
Wrapper for configuration variables which lives in a wxBaseConfig object.
const void Notify()
Notify all listeners, no data supplied.
Wrapper for global variable, supports notification events when value changes.
Add progress and final message dialogs to the basic Downloader.
static std::string MessageKey(const char *type="ALL")
Return key which should be used to listen to given message type.
void Init(const KeyProvider &kp, 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.
Adds a std::shared<void> element to wxCommandEvent.
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.
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.
std::vector< std::string > GetInstalldataPlugins()
Return list of installed plugins lower case names, not necessarily loaded.
static std::string fileListPath(std::string name)
Return path to installation manifest for given plugin.
static std::string versionPath(std::string name)
Return path to file containing version for given plugin.
bool uninstall(const std::string plugin)
Uninstall an installed and loaded plugin.
bool ClearInstallData(const std::string plugin_name)
Remove installation data for not loaded plugin.
void SetInstalledMetadata(const PluginMetadata &pm)
Set metadata for an installed 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.
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.
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.
void ShowPreferencesDialog(const PlugInData &pd, wxWindow *parent)
Display the preferences dialog for a plugin.
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.
bool DeleteRoute(Route *pRoute, NavObjectChanges *nav_obj_changes)
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...
virtual bool RenderGLOverlayMultiCanvas(wxGLContext *pcontext, PlugIn_ViewPort *vp, int canvasIndex, int priority)
Render plugin overlay over chart canvas in OpenGL mode.
virtual bool RenderOverlayMultiCanvas(wxDC &dc, PlugIn_ViewPort *vp, int canvas_ix, int priority)
Render plugin overlay over chart canvas in non-OpenGL mode.
std::string lookup_tarball(const char *uri)
Get path to tarball in cache for given filename.
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.
DECL_EXP std::vector< std::string > GetPriorityMaps()
Comm Priority query support methods
DECL_EXP int GetGlobalWatchdogTimoutSeconds()
Comm Global Watchdog Query
DECL_EXP bool PlugInPlaySoundEx(wxString &sound_file, int deviceIndex=-1)
Start playing a sound file asynchronously.
DECL_EXP void PlugInPlaySound(wxString &sound_file)
Start playing a sound file asynchronously.
wxDEFINE_EVENT(REST_IO_EVT, ObservedEvt)
Event from IO thread to main.
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.