35#include <unordered_map>
56#if defined(__linux__) && !defined(__ANDROID__)
61#include <archive_entry.h>
67#include <wx/aui/aui.h>
70#include <wx/filename.h>
71#include <wx/hashmap.h>
72#include <wx/hashset.h>
73#include <wx/jsonreader.h>
74#include <wx/jsonval.h>
75#include <wx/listimpl.cpp>
76#include <wx/platinfo.h>
77#include <wx/popupwin.h>
78#include <wx/progdlg.h>
79#include <wx/statline.h>
80#include <wx/tarstrm.h>
81#include <wx/textwrapper.h>
82#include <wx/tokenzr.h>
83#include <wx/tooltip.h>
86#include <wx/zipstrm.h>
87#include <wx/zstream.h>
108#include "model/nav_object_database.h"
153#include "SoundFactory.h"
156#include "SystemCmdSound.h"
163#include "androidUTIL.h"
170typedef __LA_INT64_T la_int64_t;
171enum { CurlThreadId = wxID_HIGHEST + 1 };
173#if wxUSE_XLOCALE || !wxCHECK_VERSION(3, 0, 0)
174extern wxLocale* plocale_def_lang;
179void NotifySetupOptionsPlugin(
const PlugInData* pic);
181WX_DEFINE_LIST(Plugin_WaypointList);
182WX_DEFINE_LIST(Plugin_HyperlinkList);
189 explicit RawKey(
const std::string& key) : m_key(key) {}
190 [[nodiscard]] std::string
GetKey()
const override {
return m_key; }
196static void SendAisJsonMessage(std::shared_ptr<const AisTargetData> pTarget) {
198 if (!GetJSONMessageTargetCount())
return;
203 wxLongLong t = ::wxGetLocalTimeMillis();
205 jMsg[wxS(
"Source")] = wxS(
"AisDecoder");
206 jMsg[
"Type"] =
"Information";
207 jMsg[
"Msg"] = wxS(
"AIS Target");
208 jMsg[
"MsgId"] = t.GetValue();
209 jMsg[wxS(
"lat")] = pTarget->Lat;
210 jMsg[wxS(
"lon")] = pTarget->Lon;
211 jMsg[wxS(
"sog")] = pTarget->SOG;
212 jMsg[wxS(
"cog")] = pTarget->COG;
213 jMsg[wxS(
"hdg")] = pTarget->HDG;
214 jMsg[wxS(
"mmsi")] = pTarget->MMSI;
215 jMsg[wxS(
"class")] = pTarget->Class;
216 jMsg[wxS(
"ownship")] = pTarget->b_OwnShip;
217 jMsg[wxS(
"active")] = pTarget->b_active;
218 jMsg[wxS(
"lost")] = pTarget->b_lost;
219 wxString l_ShipName = wxString::FromUTF8(pTarget->ShipName);
220 for (
size_t i = 0; i < l_ShipName.Len(); i++) {
221 if (l_ShipName.GetChar(i) ==
'@') l_ShipName.SetChar(i,
'\n');
223 jMsg[wxS(
"shipname")] = l_ShipName;
224 wxString l_CallSign = wxString::FromUTF8(pTarget->CallSign);
225 for (
size_t i = 0; i < l_CallSign.Len(); i++) {
226 if (l_CallSign.GetChar(i) ==
'@') l_CallSign.SetChar(i,
'\n');
228 jMsg[wxS(
"callsign")] = l_CallSign;
229 jMsg[wxS(
"removed")] = pTarget->b_removed;
230 SendJSONMessageToAllPlugins(
"AIS", jMsg);
234 return (*p1)->Key().compare((*p2)->Key());
238 auto version = metadata.version;
240 if (version[0] ==
'v') version = version.substr(1);
245 auto imported_version = ParseVersion(metadata);
246 for (
auto& md :
PluginHandler::GetInstance()->GetAvailable()) {
247 if (md.name != metadata.name)
continue;
248 if (md.is_imported)
continue;
250 if (ParseVersion(md) >= imported_version)
return true;
261 void message(
const std::string& message) {
263 m_deferred_messages.push_back(message);
268 void show_deferred_messages() {
269 for (
auto m : m_deferred_messages) show_msg(m);
276 void show_msg(wxString msg) {
277 OCPNMessageBox(NULL, msg, wxString(_(
"OpenCPN Info")),
278 wxICON_INFORMATION | wxOK, 10);
282 std::vector<wxString> m_deferred_messages;
289 Wrap(win, text, widthMax);
291 wxString
const& GetWrapped()
const {
return m_wrapped; }
292 int const GetLineCount()
const {
return m_lineCount; }
293 wxArrayString GetLineArray() {
return m_array; }
296 virtual void OnOutputLine(
const wxString& line) {
300 virtual void OnNewLine() {
308 wxArrayString m_array;
312 template <
typename T>
313 std::size_t operator()(T t)
const {
314 return static_cast<std::size_t
>(t);
321 return _(
"Plugin is a standard system plugin");
323 return _(
"Plugin is managed by OpenCPN");
325 return _(
"Plugin is not managed by OpenCPN");
328 case PluginStatus::Unknown:
329 return _(
"Plugin status unknown");
330 case PluginStatus::LegacyUpdateAvailable:
331 return _(
"Update to managed Plugin is available");
332 case PluginStatus::ManagedInstallAvailable:
333 return _(
"New managed Plugin installation available");
334 case PluginStatus::ManagedInstalledUpdateAvailable:
335 return _(
"Update to installed Plugin is available");
336 case PluginStatus::ManagedInstalledCurrentVersion:
337 return _(
"Plugin is latest available");
338 case PluginStatus::Imported:
339 return _(
"Plugin is imported");
340 case PluginStatus::ManagedInstalledDowngradeAvailable:
342 case PluginStatus::PendingListRemoval:
349static const std::unordered_map<PluginStatus, const char*, EnumClassHash>
355 {PluginStatus::Unknown,
"emblem-unmanaged.svg"},
356 {PluginStatus::LegacyUpdateAvailable,
"emblem-legacy-update.svg"},
357 {PluginStatus::ManagedInstallAvailable,
"emblem-download.svg"},
358 {PluginStatus::ManagedInstalledUpdateAvailable,
359 "emblem-legacy-update.svg"},
360 {PluginStatus::ManagedInstalledCurrentVersion,
"emblem-default.svg"},
361 {PluginStatus::ManagedInstalledDowngradeAvailable,
362 "emblem-default.svg"},
363 {PluginStatus::PendingListRemoval,
"emblem-default.svg"},
364 {PluginStatus::Imported,
"emblem-default.svg"}});
366static const std::unordered_map<PluginStatus, const char*, EnumClassHash>
367 literalstatus_by_status(
372 {PluginStatus::Unknown,
"Unknown"},
373 {PluginStatus::LegacyUpdateAvailable,
"LegacyUpdateAvailable"},
374 {PluginStatus::ManagedInstallAvailable,
"ManagedInstallAvailable"},
375 {PluginStatus::ManagedInstalledUpdateAvailable,
376 "ManagedInstalledUpdateAvailable"},
377 {PluginStatus::ManagedInstalledCurrentVersion,
378 "ManagedInstalledCurrentVersion"},
379 {PluginStatus::ManagedInstalledDowngradeAvailable,
380 "ManagedInstalledDowngradeAvailable"},
381 {PluginStatus::PendingListRemoval,
"PendingListRemoval"},
382 {PluginStatus::Imported,
"Imported"}
390static std::vector<PluginMetadata> getCompatiblePlugins() {
392 struct metadata_compare {
395 return lhs.key() < rhs.key();
399 std::vector<PluginMetadata> returnArray;
401 std::set<PluginMetadata, metadata_compare> unique_plugins;
402 for (
auto plugin :
PluginHandler::GetInstance()->GetAvailable()) {
403 unique_plugins.insert(plugin);
405 for (
auto plugin : unique_plugins) {
407 returnArray.push_back(plugin);
424 std::string installed;
426 if (path ==
"" || !wxFileName::IsFileReadable(path)) {
429 std::ifstream stream;
430 stream.open(path, std::ifstream::in);
439static std::vector<PluginMetadata> getUpdates(
const char* name) {
440 auto updates = getCompatiblePlugins();
442 std::remove_if(updates.begin(), updates.end(),
446 auto inst_vers = getInstalledVersion(name);
447 if (inst_vers.major == -1) {
452 updates.erase(std::remove_if(updates.begin(), updates.end(),
454 return metadata_version(m) == inst_vers;
461static void gui_uninstall(
const PlugInData* pic,
const char* plugin) {
462 g_Platform->ShowBusySpinner();
467 wxLogMessage(
"Uninstalling %s", plugin);
470 g_Platform->HideBusySpinner();
473static bool LoadAllPlugIns(
bool load_enabled,
bool keep_orphans =
false) {
474 g_Platform->ShowBusySpinner();
476 PluginLoader::GetInstance()->
LoadAllPlugIns(load_enabled, keep_orphans);
477 g_Platform->HideBusySpinner();
482static void UninstallPlugin(
const std::string& name) {
484 auto loader = PluginLoader::GetInstance();
485 auto finder = [name](
const PluginMetadata pm) {
return pm.name == name; };
486 const auto& installed = handler->GetInstalled();
487 auto found = std::find_if(installed.begin(), installed.end(), finder);
488 if (found != installed.end()) {
489 for (
size_t i = 0; i < loader->GetPlugInArray()->GetCount(); i++) {
490 auto const& item = loader->GetPlugInArray()->Item(i);
491 if (item->m_common_name.ToStdString() == name) {
492 DEBUG_LOG <<
"Unloading plugin: " << name;
493 loader->UnLoadPlugIn(i);
497 handler->Uninstall(found->name);
498 DEBUG_LOG <<
"Uninstalling: " << found->name;
503 bool uninstall,
const char* name = 0,
504 bool b_forceEnable =
false) {
506 const char* plugin = name == 0 ? pic->
m_common_name.mb_str().data() : name;
507 auto updates = getUpdates(plugin);
508 auto parent_dlg =
dynamic_cast<wxScrolledWindow*
>(parent);
509 wxASSERT(parent_dlg != 0);
511 auto status = dialog.ShowModal();
512 status = dialog.GetReturnCode();
513 if (status != wxID_OK) {
517 auto update = dialog.GetUpdate();
522 wxLogMessage(
"Installing %s", update.name.c_str());
524 g_Platform->ShowBusySpinner();
528 if (uninstall && path !=
"") {
529 gui_uninstall(pic, update.name.c_str());
531 bool cacheResult = pluginHandler->InstallPluginFromCache(update);
534 g_Platform->ShowBusySpinner();
538 std::string tempTarballPath = downloader->run(parent_dlg, uninstall);
540 if (!tempTarballPath.size())
546 if (!isRegularFile(manifestPath.c_str())) {
547 wxLogMessage(
"Installation of %s failed", update.name.c_str());
548 PluginHandler::CleanupFiles(manifestPath, update.name);
554 wxLogMessage(
"Installation of %s successful", update.name.c_str());
555 wxURI uri(wxString(update.tarball_url.c_str()));
556 wxFileName fn(uri.GetPath());
557 std::string basename = fn.GetFullName().ToStdString();
560 wxLogDebug(
"Copied %s to local cache at %s", tempTarballPath.c_str(),
562 remove(tempTarballPath.c_str());
570 wxString pispec =
"_pi.dll";
571#elif defined(__WXOSX__)
572 wxString pispec =
"_pi.dylib";
574 wxString pispec =
"_pi.so";
578 wxTextFile manifest_file(manifestPath);
580 if (manifest_file.Open()) {
582 for (wxString str = manifest_file.GetFirstLine(); !manifest_file.Eof();
583 str = manifest_file.GetNextLine()) {
584 if (str.Contains(pispec)) {
585 if (getenv(
"OCPN_KEEP_PLUGINS")) {
589 auto loader = PluginLoader::GetInstance();
590 if (!loader->CheckPluginCompatibility(str)) {
592 _(
"The plugin is not compatible with this version of OpenCPN, "
593 "and will be uninstalled.");
594 OCPNMessageBox(NULL, msg, wxString(_(
"OpenCPN Info")),
595 wxICON_INFORMATION | wxOK, 10);
597 PluginHandler::CleanupFiles(manifestPath, update.name);
606 if (b_forceEnable && pluginFile.Length()) {
607 wxString config_section = (_T (
"/PlugIns/" ));
608 wxFileName fn(pluginFile);
609 config_section += fn.GetFullName();
610 pConfig->SetPath(config_section);
611 pConfig->Write(_T (
"bEnabled" ),
true);
617 std::remove(handler->ImportedMetadataPath(update.name).c_str());
620 LoadAllPlugIns(
false);
623 g_Platform->HideBusySpinner();
643 pivp.
lat_min = tvp.GetBBox().GetMinLat();
644 pivp.
lat_max = tvp.GetBBox().GetMaxLat();
645 pivp.
lon_min = tvp.GetBBox().GetMinLon();
646 pivp.
lon_max = tvp.GetBBox().GetMaxLon();
648 pivp.
bValid = tvp.IsValid();
669 if (gFrame->GetPrimaryCanvas())
685 void OnPluginUtilAction(wxCommandEvent& event);
687 DECLARE_EVENT_TABLE()
691EVT_BUTTON(ID_CMD_BUTTON_PERFORM_ACTION, pluginUtilHandler::OnPluginUtilAction)
696void pluginUtilHandler::OnPluginUtilAction(wxCommandEvent& event) {
697 auto panel =
static_cast<PluginPanel*
>(
event.GetClientData());
700 wxASSERT(plugin_list_panel != 0);
702 auto actionPIC = panel->GetPlugin();
703 wxString name = actionPIC->m_common_name;
706 switch (panel->GetAction()) {
707 case ActionVerb::UPGRADE_TO_MANAGED_VERSION: {
708 auto loader = PluginLoader::GetInstance();
711 std::string pluginName = actionPIC->m_managed_metadata.name;
713 wxLogMessage(
"Installing managed plugin: %s", pluginName.c_str());
715 new GuiDownloader(plugin_list_panel, actionPIC->m_managed_metadata);
716 downloader->run(plugin_list_panel,
false);
720 if (isRegularFile(manifestPath.c_str())) {
722 for (
unsigned i = 0; i < loader->GetPlugInArray()->GetCount(); i += 1) {
723 if (actionPIC->m_managed_metadata.name ==
724 loader->GetPlugInArray()->Item(i)->m_common_name.ToStdString()) {
725 loader->UnLoadPlugIn(i);
731 LoadAllPlugIns(
false);
733 PluginHandler::CleanupFiles(manifestPath,
734 actionPIC->m_managed_metadata.name);
737 plugin_list_panel->SelectByName(name);
742 case ActionVerb::UPDATE_IMPORTED_VERSION:
743 case ActionVerb::UPGRADE_INSTALLED_MANAGED_VERSION:
744 case ActionVerb::REINSTALL_MANAGED_VERSION:
745 case ActionVerb::DOWNGRADE_INSTALLED_MANAGED_VERSION: {
747 auto metaSave = actionPIC->m_managed_metadata;
748 run_update_dialog(plugin_list_panel, actionPIC,
true,
749 metaSave.name.c_str());
753 case ActionVerb::INSTALL_MANAGED_VERSION: {
754 wxLogMessage(
"Installing new managed plugin.");
755 run_update_dialog(plugin_list_panel, actionPIC,
false);
759 case ActionVerb::UNINSTALL_MANAGED_VERSION: {
762 message.Printf(
"%s %s\n", actionPIC->m_managed_metadata.name.c_str(),
763 actionPIC->m_managed_metadata.version.c_str());
764 message += _(
"successfully un-installed");
766 wxLogMessage(
"Uninstalling %s",
767 actionPIC->m_managed_metadata.name.c_str());
770 actionPIC->m_managed_metadata.name);
773 LoadAllPlugIns(
false);
775 OCPNMessageBox(gFrame, message, _(
"Un-Installation complete"),
776 wxICON_INFORMATION | wxOK);
780 case ActionVerb::NOP:
791const wxEventType wxEVT_OCPN_MSG = wxNewEventType();
793OCPN_MsgEvent::OCPN_MsgEvent(wxEventType commandType,
int id)
794 : wxEvent(id, commandType) {}
796OCPN_MsgEvent::~OCPN_MsgEvent() {}
798wxEvent* OCPN_MsgEvent::Clone()
const {
800 newevent->m_MessageID =
803 newevent->m_MessageText = this->m_MessageText.c_str();
812PlugInToolbarToolContainer::PlugInToolbarToolContainer() {
816 bitmap_Rollover_day = NULL;
817 bitmap_Rollover_dusk = NULL;
818 bitmap_Rollover_night = NULL;
821PlugInToolbarToolContainer::~PlugInToolbarToolContainer() {
825 delete bitmap_Rollover_day;
826 delete bitmap_Rollover_dusk;
827 delete bitmap_Rollover_night;
838#if !defined(__ANDROID__) && defined(OCPN_USE_CURL)
839EVT_CURL_END_PERFORM(CurlThreadId, PlugInManager::OnEndPerformCurlDownload)
840EVT_CURL_DOWNLOAD(CurlThreadId, PlugInManager::OnCurlDownload)
844static
void event_message_box(const wxString& msg) {
845 OCPNMessageBox(NULL, msg, wxString(_(
"OpenCPN Info")),
846 wxICON_INFORMATION | wxOK, 0);
852 if (!pic->m_toolbox_panel) NotifySetupOptionsPlugin(pic);
857PlugInManager::PlugInManager(
MyFrame* parent) {
858#if !defined(__ANDROID__) && defined(OCPN_USE_CURL)
859 m_pCurlThread = NULL;
865 MyFrame* pFrame = GetParentFrame();
867 m_plugin_menu_item_id_next = CanvasMenuHandler::GetNextContextMenuId();
868 m_plugin_tool_id_next = pFrame->GetNextToolbarToolId();
881 new wxRadioBox(pFrame, -1,
"", wxPoint(0, 0), wxSize(-1, -1), as);
887#if !defined(__ANDROID__) && defined(OCPN_USE_CURL)
889 m_last_online =
false;
890 m_last_online_chk = -1;
895 m_blacklist = blacklist_factory();
896 m_blacklist_ui = std::unique_ptr<BlacklistUI>(
new BlacklistUI());
898 wxDEFINE_EVENT(EVT_JSON_TO_ALL_PLUGINS,
ObservedEvt);
900 EVT_JSON_TO_ALL_PLUGINS);
901 Bind(EVT_JSON_TO_ALL_PLUGINS, [&](
ObservedEvt& ev) {
902 auto json = std::static_pointer_cast<const wxJSONValue>(ev.
GetSharedPtr());
903 SendJSONMessageToAllPlugins(ev.GetString(), *json);
906 wxDEFINE_EVENT(EVT_LEGINFO_TO_ALL_PLUGINS,
ObservedEvt);
908 EVT_LEGINFO_TO_ALL_PLUGINS);
909 Bind(EVT_LEGINFO_TO_ALL_PLUGINS, [&](
ObservedEvt& ev) {
910 auto ptr = UnpackEvtPointer<ActiveLegDat>(ev);
911 SendActiveLegInfoToAllPlugIns(ptr.get());
914 HandlePluginLoaderEvents();
920 m_new_msgtype_lstnr.
Init(NavMsgBus::GetInstance().new_msg_event,
923PlugInManager::~PlugInManager() {
924#if !defined(__ANDROID__) && defined(OCPN_USE_CURL)
925 wxCurlBase::Shutdown();
927 delete m_utilHandler;
930void PlugInManager::InitCommListeners() {
934 auto& msgbus = NavMsgBus::GetInstance();
937 m_listener_SignalK.
Listen(sk_msg,
this, EVT_SIGNALK);
944void PlugInManager::OnNewMessageType() {
945 for (
auto msg_key :
NavMsgBus::GetInstance().GetActiveMessages()) {
946 if (m_0183_listeners.find(msg_key) != m_0183_listeners.end())
continue;
947 if (msg_key.find(
"::") == std::string::npos)
continue;
949 if (key_parts.size() < 2)
continue;
954 m_0183_listeners[msg_key] = std::move(ol);
959 assert(n0183_msg->bus == NavAddr::Bus::N0183);
960 const std::string& payload = n0183_msg->payload;
962 if (payload[0] ==
'$') {
963 const auto& drivers = CommDriverRegistry::GetInstance().
GetDrivers();
964 auto& target_driver =
FindDriver(drivers, n0183_msg->source->iface);
968 bool passes_input_filter =
true;
972 passes_input_filter =
973 params.SentencePassesFilter(payload.c_str(), FILTER_INPUT);
976 }
else if (payload[0] ==
'!') {
977 SendAISSentenceToAllPlugIns(payload.c_str());
982 g_ownshipMMSI_SK = sK_msg->context_self;
987 std::string msgTerminated = sK_msg->raw_message;
990 int errors = jsonReader.
Parse(msgTerminated, &root);
991 if (errors == 0) SendJSONMessageToAllPlugins(
"OCPN_CORE_SIGNALK", root);
1000wxDEFINE_EVENT(EVT_PLUGMGR_ROUTEMAN_MSG,
ObservedEvt);
1001wxDEFINE_EVENT(EVT_BLACKLISTED_PLUGIN, wxCommandEvent);
1002wxDEFINE_EVENT(EVT_LOAD_DIRECTORY, wxCommandEvent);
1003wxDEFINE_EVENT(EVT_LOAD_PLUGIN, wxCommandEvent);
1004wxDEFINE_EVENT(EVT_PLUGIN_UNLOAD, wxCommandEvent);
1005wxDEFINE_EVENT(EVT_PLUGLIST_CHANGE, wxCommandEvent);
1006wxDEFINE_EVENT(EVT_UPDATE_CHART_TYPES, wxCommandEvent);
1007wxDEFINE_EVENT(EVT_PLUGIN_LOADALL_FINALIZE, wxCommandEvent);
1009void PlugInManager::HandlePluginLoaderEvents() {
1010 auto loader = PluginLoader::GetInstance();
1012 loader->SetOnActivateCb(
1014 loader->SetOnDeactivateCb(
1017 evt_pluglist_change_listener.
Listen(loader->evt_pluglist_change,
this,
1018 EVT_PLUGLIST_CHANGE);
1019 Bind(EVT_PLUGLIST_CHANGE, [&](wxCommandEvent&) {
1024 evt_load_directory_listener.
Listen(loader->evt_load_directory,
this,
1025 EVT_LOAD_DIRECTORY);
1026 Bind(EVT_LOAD_DIRECTORY, [&](wxCommandEvent&) {
1027 pConfig->SetPath(
"/PlugIns/");
1028 SetPluginOrder(pConfig->Read(
"PluginOrder", wxEmptyString));
1031 evt_load_plugin_listener.
Listen(loader->evt_load_plugin,
this,
1033 Bind(EVT_LOAD_PLUGIN, [&](wxCommandEvent& ev) {
1038 evt_update_chart_types_listener.
Listen(loader->evt_update_chart_types,
this,
1039 EVT_UPDATE_CHART_TYPES);
1040 Bind(EVT_UPDATE_CHART_TYPES,
1041 [&](wxCommandEvent& ev) { UpDateChartDataTypes(); });
1043 evt_plugin_loadall_finalize_listener.
Listen(
1044 loader->evt_plugin_loadall_finalize,
this, EVT_PLUGIN_LOADALL_FINALIZE);
1045 Bind(EVT_PLUGIN_LOADALL_FINALIZE,
1046 [&](wxCommandEvent& ev) { FinalizePluginLoadall(); });
1050 EVT_PLUGMGR_ROUTEMAN_MSG);
1052 auto pTarget = UnpackEvtPointer<AisTargetData>(ev);
1053 SendAisJsonMessage(pTarget);
1055 Bind(EVT_PLUGMGR_ROUTEMAN_MSG, [&](
ObservedEvt& ev) {
1056 auto msg = UnpackEvtPointer<wxJSONValue>(ev);
1057 SendJSONMessageToAllPlugins(ev.GetString(), *msg);
1065wxDEFINE_EVENT(EVT_DOWNLOAD_FAILED, wxCommandEvent);
1066wxDEFINE_EVENT(EVT_DOWNLOAD_OK, wxCommandEvent);
1068void PlugInManager::HandlePluginHandlerEvents() {
1069 auto loader = PluginLoader::GetInstance();
1071 evt_download_failed_listener.
Listen(loader->evt_update_chart_types,
this,
1072 EVT_DOWNLOAD_FAILED);
1073 Bind(EVT_DOWNLOAD_FAILED, [&](wxCommandEvent& ev) {
1074 wxString message = _(
"Please check system log for more info.");
1075 OCPNMessageBox(gFrame, message, _(
"Installation error"),
1076 wxICON_ERROR | wxOK | wxCENTRE);
1079 evt_download_ok_listener.
Listen(loader->evt_update_chart_types,
this,
1081 Bind(EVT_DOWNLOAD_OK, [&](wxCommandEvent& ev) {
1082 wxString message(ev.GetString());
1083 message += _(
" successfully installed from cache");
1084 OCPNMessageBox(gFrame, message, _(
"Installation complete"),
1085 wxICON_INFORMATION | wxOK | wxCENTRE);
1089bool PlugInManager::CallLateInit() {
1092 auto plugin_array = PluginLoader::GetInstance()->
GetPlugInArray();
1093 for (
unsigned int i = 0; i < plugin_array->GetCount(); i++) {
1096 switch (pic->m_api_version) {
1109 ProcessLateInit(pic);
1119 wxString msg(
"PlugInManager: Calling LateInit PlugIn: ");
1124 if (ppi) ppi->LateInit();
1133 if (gFrame->GetPrimaryCanvas()->GetglCanvas()) {
1134 gFrame->GetPrimaryCanvas()->GetglCanvas()->SendJSONConfigMessage();
1135 SendS52ConfigToAllPlugIns(
true);
1150 for (
unsigned int i = 0; i < m_PlugInToolbarTools.GetCount(); i++) {
1153 if (pttc->m_pplugin == pic->m_pplugin) {
1154 m_PlugInToolbarTools.Remove(pttc);
1160 for (
unsigned int i = 0; i < m_PlugInMenuItems.GetCount(); i++) {
1162 if (pimis->m_pplugin == pic->m_pplugin) {
1163 m_PlugInMenuItems.Remove(pimis);
1169bool PlugInManager::IsAnyPlugInChartEnabled() {
1172 auto plugin_array = PluginLoader::GetInstance()->
GetPlugInArray();
1173 for (
unsigned int i = 0; i < plugin_array->GetCount(); i++) {
1175 if (pic->m_enabled && pic->m_init_state) {
1184void PlugInManager::UpdateManagedPlugins() {
1186 PluginLoader::GetInstance()->
SortPlugins(ComparePlugins);
1189 g_options->itemBoxSizerPanelPlugins->Layout();
1192bool PlugInManager::UpDateChartDataTypes() {
1196 auto plugin_array = PluginLoader::GetInstance()->
GetPlugInArray();
1197 for (
unsigned int i = 0; i < plugin_array->GetCount(); i++) {
1200 if (pic->m_init_state) {
1208 if (bret)
ChartData->UpdateChartClassDescriptorArray();
1213void PlugInManager::FinalizePluginLoadall() {
1217 SetColorSchemeForAllPlugIns(global_color_scheme);
1220 SendBaseConfigToAllPlugIns();
1221 SendS52ConfigToAllPlugIns(
true);
1222 SendSKConfigToAllPlugIns();
1227 if (gFrame->GetPrimaryCanvas()->GetglCanvas())
1228 gFrame->GetPrimaryCanvas()->GetglCanvas()->SendJSONConfigMessage();
1236void PlugInManager::SetPluginOrder(wxString serialized_names) {
1237 m_plugin_order.Empty();
1238 wxStringTokenizer tokenizer(serialized_names,
";");
1239 while (tokenizer.HasMoreTokens()) {
1240 m_plugin_order.Add(tokenizer.GetNextToken());
1244wxString PlugInManager::GetPluginOrder() {
1245 wxString plugins = wxEmptyString;
1246 auto plugin_array = PluginLoader::GetInstance()->
GetPlugInArray();
1247 for (
unsigned int i = 0; i < plugin_array->GetCount(); i++) {
1248 plugins.Append(plugin_array->Item(i)->m_common_name);
1249 if (i < plugin_array->GetCount() - 1) plugins.Append(
';');
1254bool PlugInManager::UpdateConfig() {
1258 auto plugin_array = PluginLoader::GetInstance()->
GetPlugInArray();
1259 for (
unsigned int i = 0; i < plugin_array->GetCount(); i++) {
1263 wxString config_section = (_T (
"/PlugIns/" ));
1265 pConfig->SetPath(config_section);
1266 pConfig->Write(_T (
"bEnabled" ), pic->m_enabled);
1273void PlugInManager::ShowDeferredBlacklistMessages() {
1274 m_blacklist_ui->show_deferred_messages();
1277bool PlugInManager::CheckBlacklistedPlugin(
const PluginMetadata plugin) {
1279 return CheckBlacklistedPlugin(wxString(plugin.name), v.major, v.minor);
1282bool PlugInManager::CheckBlacklistedPlugin(
opencpn_plugin* plugin) {
1287 wxString name = wxString::FromAscii(
typeid(*plugin).name());
1288 name.Replace(
"class ", wxEmptyString);
1290 const std::type_info& ti =
typeid(*plugin);
1292 char* realname = abi::__cxa_demangle(ti.name(), 0, 0, &status);
1293 wxString name = wxString::FromAscii(realname);
1296 return CheckBlacklistedPlugin(name, major, minor);
1299bool PlugInManager::CheckBlacklistedPlugin(wxString name,
int major,
1301 auto block_status = m_blacklist->get_status(name.ToStdString(), major, minor);
1302 if (block_status == plug_status::unblocked)
return true;
1303 plug_data data(name.ToStdString(), major, minor);
1304 auto msg = m_blacklist->get_message(block_status, data);
1305 m_blacklist_ui->message(msg);
1309bool PlugInManager::RenderAllCanvasOverlayPlugIns(
ocpnDC& dc,
1313 auto plugin_array = PluginLoader::GetInstance()->
GetPlugInArray();
1314 for (
unsigned int i = 0; i < plugin_array->GetCount(); i++) {
1316 if (pic->m_enabled && pic->m_init_state) {
1320 wxDC* pdc = dc.GetDC();
1323 switch (pic->m_api_version) {
1325 if (priority > 0)
break;
1332 if (priority > 0)
break;
1335 if (ppi) ppi->RenderOverlay(*pdc, &pivp);
1346 if (priority > 0)
break;
1349 if (ppi) ppi->RenderOverlay(*pdc, &pivp);
1354 if (priority > 0)
break;
1358 ppi->RenderOverlay(*pdc, &pivp);
1370 if (priority <= 0) {
1374 ppi->RenderOverlay(*pdc, &pivp);
1390 if (pic->
m_cap_flag & WANTS_OPENGL_OVERLAY_CALLBACK)
continue;
1392 if ((m_cached_overlay_bm.GetWidth() != vp.
pix_width) ||
1393 (m_cached_overlay_bm.GetHeight() != vp.
pix_height))
1397 mdc.SelectObject(m_cached_overlay_bm);
1398 mdc.SetBackground(*wxBLACK_BRUSH);
1401 bool b_rendered =
false;
1403 switch (pic->m_api_version) {
1405 if (priority > 0)
break;
1412 if (priority > 0)
break;
1415 if (ppi) b_rendered = ppi->RenderOverlay(mdc, &pivp);
1426 if (priority > 0)
break;
1429 if (ppi) b_rendered = ppi->RenderOverlay(mdc, &pivp);
1434 if (priority > 0)
break;
1438 b_rendered = ppi->RenderOverlay(mdc, &pivp);
1451 if (priority <= 0) {
1455 b_rendered = ppi->RenderOverlay(mdc, &pivp);
1462 mdc, &pivp, g_canvasConfig, priority);
1471 mdc.SelectObject(wxNullBitmap);
1474 wxMask* p_msk =
new wxMask(m_cached_overlay_bm, wxColour(0, 0, 0));
1475 m_cached_overlay_bm.SetMask(p_msk);
1477 dc.DrawBitmap(m_cached_overlay_bm, 0, 0,
true);
1480 }
else if (pic->
m_cap_flag & WANTS_OPENGL_OVERLAY_CALLBACK) {
1488bool PlugInManager::RenderAllGLCanvasOverlayPlugIns(wxGLContext* pcontext,
1492 auto plugin_array = PluginLoader::GetInstance()->
GetPlugInArray();
1493 for (
unsigned int i = 0; i < plugin_array->GetCount(); i++) {
1495 if (pic->m_enabled && pic->m_init_state) {
1496 if (pic->
m_cap_flag & WANTS_OPENGL_OVERLAY_CALLBACK) {
1499 switch (pic->m_api_version) {
1501 if (priority > 0)
break;
1504 if (ppi) ppi->RenderGLOverlay(pcontext, &pivp);
1516 if (priority > 0)
break;
1524 if (priority > 0)
break;
1541 if (priority <= 0) {
1566void PlugInManager::SendViewPortToRequestingPlugIns(
ViewPort& vp) {
1567 auto plugin_array = PluginLoader::GetInstance()->
GetPlugInArray();
1568 for (
unsigned int i = 0; i < plugin_array->GetCount(); i++) {
1570 if (pic->m_enabled && pic->m_init_state) {
1579void NotifySetupOptionsPlugin(
const PlugInData* pd) {
1580 PluginLoader::GetInstance()->NotifySetupOptionsPlugin(pd);
1583void PlugInManager::NotifySetupOptions() {
1584 auto plugin_array = PluginLoader::GetInstance()->
GetPlugInArray();
1585 for (
unsigned int i = 0; i < plugin_array->GetCount(); i++) {
1587 NotifySetupOptionsPlugin(pic);
1592 int ok_apply_cancel) {
1593 if (pic->m_enabled && pic->m_init_state) {
1596 auto loader = PluginLoader::GetInstance();
1603void PlugInManager::CloseAllPlugInPanels(
int ok_apply_cancel) {
1604 auto plugin_array = PluginLoader::GetInstance()->
GetPlugInArray();
1605 for (
unsigned int i = 0; i < plugin_array->GetCount(); i++) {
1608 ClosePlugInPanel(pic, ok_apply_cancel);
1613int PlugInManager::AddCanvasContextMenuItemPIM(wxMenuItem* pitem,
1618 pmic->pmenu_item = pitem;
1619 pmic->m_pplugin = pplugin;
1620 pmic->id = pitem->GetId() == wxID_SEPARATOR ? wxID_SEPARATOR
1621 : m_plugin_menu_item_id_next;
1623 pmic->b_grey =
false;
1624 pmic->m_in_menu = name;
1625 pmic->extended = is_extended;
1627 m_PlugInMenuItems.Add(pmic);
1629 m_plugin_menu_item_id_next++;
1634void PlugInManager::RemoveCanvasContextMenuItem(
int item,
const char* name) {
1635 for (
unsigned int i = 0; i < m_PlugInMenuItems.GetCount(); i++) {
1638 if (pimis->id == item) {
1639 m_PlugInMenuItems.Remove(pimis);
1647void PlugInManager::SetCanvasContextMenuItemViz(
int item,
bool viz,
1649 for (
unsigned int i = 0; i < m_PlugInMenuItems.GetCount(); i++) {
1652 if (pimis->id == item && !strcmp(name, pimis->m_in_menu)) {
1660void PlugInManager::SetCanvasContextMenuItemGrey(
int item,
bool grey,
1662 for (
unsigned int i = 0; i < m_PlugInMenuItems.GetCount(); i++) {
1665 if (pimis->id == item && !strcmp(name, pimis->m_in_menu)) {
1666 pimis->b_grey = grey;
1673void PlugInManager::SendResizeEventToAllPlugIns(
int x,
int y) {
1674 auto plugin_array = PluginLoader::GetInstance()->
GetPlugInArray();
1675 for (
unsigned int i = 0; i < plugin_array->GetCount(); i++) {
1677 if (pic->m_enabled && pic->m_init_state)
1682void PlugInManager::SetColorSchemeForAllPlugIns(ColorScheme cs) {
1683 auto plugin_array = PluginLoader::GetInstance()->
GetPlugInArray();
1684 for (
unsigned int i = 0; i < plugin_array->GetCount(); i++) {
1686 if (pic->m_enabled && pic->m_init_state)
1691void PlugInManager::PrepareAllPluginContextMenus() {
1692 int canvasIndex = gFrame->GetCanvasIndexUnderMouse();
1693 if (canvasIndex < 0)
return;
1695 auto plugin_array = PluginLoader::GetInstance()->
GetPlugInArray();
1696 for (
unsigned int i = 0; i < plugin_array->GetCount(); i++) {
1698 if (pic->m_enabled && pic->m_init_state) {
1700 switch (pic->m_api_version) {
1720void PlugInManager::SendSKConfigToAllPlugIns() {
1723 v[
"self"] = g_ownshipMMSI_SK;
1727 SendMessageToAllPlugins(wxString(
"OCPN_CORE_SIGNALK"), out);
1730void PlugInManager::SendBaseConfigToAllPlugIns() {
1733 v[
"OpenCPN Version Major"] = VERSION_MAJOR;
1734 v[
"OpenCPN Version Minor"] = VERSION_MINOR;
1735 v[
"OpenCPN Version Patch"] = VERSION_PATCH;
1736 v[
"OpenCPN Version Date"] = VERSION_DATE;
1737 v[
"OpenCPN Version Full"] = VERSION_FULL;
1741 v[
"OpenCPN Toolbar Width"] =
g_MainToolbar->GetToolbarRect().width;
1742 v[
"OpenCPN Toolbar Height"] =
g_MainToolbar->GetToolbarRect().height;
1743 v[
"OpenCPN Toolbar PosnX"] =
g_MainToolbar->GetToolbarRect().x;
1744 v[
"OpenCPN Toolbar PosnY"] =
g_MainToolbar->GetToolbarRect().y;
1748 v[
"OpenCPN Zoom Mod Vector"] = g_chart_zoom_modifier_vector;
1749 v[
"OpenCPN Zoom Mod Other"] = g_chart_zoom_modifier_raster;
1750 v[
"OpenCPN Scale Factor Exp"] =
1751 g_Platform->GetChartScaleFactorExp(g_ChartScaleFactor);
1759 SendMessageToAllPlugins(wxString(
"OpenCPN Config"), out);
1762void PlugInManager::SendS52ConfigToAllPlugIns(
bool bReconfig) {
1765 v[
"OpenCPN Version Major"] = VERSION_MAJOR;
1766 v[
"OpenCPN Version Minor"] = VERSION_MINOR;
1767 v[
"OpenCPN Version Patch"] = VERSION_PATCH;
1768 v[
"OpenCPN Version Date"] = VERSION_DATE;
1769 v[
"OpenCPN Version Full"] = VERSION_FULL;
1777 v[
"OpenCPN S52PLIB ShowAnchorConditions"] = ps52plib->GetAnchorOn();
1778 v[
"OpenCPN S52PLIB ShowQualityOfData"] = ps52plib->GetQualityOfData();
1783 v[
"OpenCPN S52PLIB MetaDisplay"] = ps52plib->m_bShowMeta;
1784 v[
"OpenCPN S52PLIB DeclutterText"] = ps52plib->m_bDeClutterText;
1785 v[
"OpenCPN S52PLIB ShowNationalText"] = ps52plib->m_bShowNationalTexts;
1786 v[
"OpenCPN S52PLIB ShowImportantTextOnly"] =
1787 ps52plib->m_bShowS57ImportantTextOnly;
1788 v[
"OpenCPN S52PLIB UseSCAMIN"] = ps52plib->m_bUseSCAMIN;
1789 v[
"OpenCPN S52PLIB UseSUPER_SCAMIN"] = ps52plib->m_bUseSUPER_SCAMIN;
1790 v[
"OpenCPN S52PLIB SymbolStyle"] = ps52plib->m_nSymbolStyle;
1791 v[
"OpenCPN S52PLIB BoundaryStyle"] = ps52plib->m_nBoundaryStyle;
1792 v[
"OpenCPN S52PLIB ColorShades"] = S52_getMarinerParam(S52_MAR_TWO_SHADES);
1793 v[
"OpenCPN S52PLIB Safety Depth"] =
1794 (double)S52_getMarinerParam(S52_MAR_SAFETY_DEPTH);
1795 v[
"OpenCPN S52PLIB Shallow Contour"] =
1796 (double)S52_getMarinerParam(S52_MAR_SHALLOW_CONTOUR);
1797 v[
"OpenCPN S52PLIB Deep Contour"] =
1798 (double)S52_getMarinerParam(S52_MAR_DEEP_CONTOUR);
1802 v[
"OpenCPN S52PLIB GlobalReconfig"] = bReconfig;
1807 SendMessageToAllPlugins(wxString(
"OpenCPN Config"), out);
1810void PlugInManager::NotifyAuiPlugIns() {
1811 auto plugin_array = PluginLoader::GetInstance()->
GetPlugInArray();
1812 for (
unsigned int i = 0; i < plugin_array->GetCount(); i++) {
1814 if (pic->m_enabled && pic->m_init_state &&
1820int PlugInManager::AddToolbarTool(wxString label, wxBitmap* bitmap,
1821 wxBitmap* bmpRollover, wxItemKind kind,
1822 wxString shortHelp, wxString longHelp,
1823 wxObject* clientData,
int position,
1826 pttc->label = label;
1828 if (!bitmap->IsOk()) {
1830 pttc->bitmap_day =
new wxBitmap(style->GetIcon(
"default_pi"));
1833 pttc->bitmap_day =
new wxBitmap(*bitmap);
1834 pttc->bitmap_day->UnShare();
1837 if (!bmpRollover->IsOk()) {
1839 pttc->bitmap_Rollover_day =
new wxBitmap(style->GetIcon(
"default_pi"));
1842 pttc->bitmap_Rollover_day =
new wxBitmap(*bmpRollover);
1843 pttc->bitmap_Rollover_day->UnShare();
1846 pttc->bitmap_dusk = BuildDimmedToolBitmap(pttc->bitmap_day, 128);
1847 pttc->bitmap_night = BuildDimmedToolBitmap(pttc->bitmap_day, 32);
1848 pttc->bitmap_Rollover_dusk =
1849 BuildDimmedToolBitmap(pttc->bitmap_Rollover_day, 128);
1850 pttc->bitmap_Rollover_night =
1851 BuildDimmedToolBitmap(pttc->bitmap_Rollover_day, 32);
1854 pttc->shortHelp = shortHelp;
1855 pttc->longHelp = longHelp;
1856 pttc->clientData = clientData;
1857 pttc->position = position;
1858 pttc->m_pplugin = pplugin;
1859 pttc->tool_sel = tool_sel;
1861 pttc->b_toggle =
false;
1862 pttc->id = m_plugin_tool_id_next;
1864 m_PlugInToolbarTools.Add(pttc);
1866 m_plugin_tool_id_next++;
1871int PlugInManager::AddToolbarTool(wxString label, wxString SVGfile,
1872 wxString SVGRolloverfile,
1873 wxString SVGToggledfile, wxItemKind kind,
1874 wxString shortHelp, wxString longHelp,
1875 wxObject* clientData,
int position,
1878 pttc->label = label;
1880 pttc->pluginNormalIconSVG = SVGfile;
1881 pttc->pluginRolloverIconSVG = SVGRolloverfile;
1882 pttc->pluginToggledIconSVG = SVGToggledfile;
1887 pttc->bitmap_day =
new wxBitmap(style->GetIcon(
"default_pi"));
1888 pttc->bitmap_dusk = BuildDimmedToolBitmap(pttc->bitmap_day, 128);
1889 pttc->bitmap_night = BuildDimmedToolBitmap(pttc->bitmap_day, 32);
1890 pttc->bitmap_Rollover_day =
new wxBitmap(*pttc->bitmap_day);
1891 pttc->bitmap_Rollover_dusk =
1892 BuildDimmedToolBitmap(pttc->bitmap_Rollover_day, 128);
1893 pttc->bitmap_Rollover_night =
1894 BuildDimmedToolBitmap(pttc->bitmap_Rollover_day, 32);
1897 pttc->shortHelp = shortHelp;
1898 pttc->longHelp = longHelp;
1899 pttc->clientData = clientData;
1900 pttc->position = position;
1901 pttc->m_pplugin = pplugin;
1902 pttc->tool_sel = tool_sel;
1904 pttc->b_toggle =
false;
1905 pttc->id = m_plugin_tool_id_next;
1907 m_PlugInToolbarTools.Add(pttc);
1909 m_plugin_tool_id_next++;
1914void PlugInManager::RemoveToolbarTool(
int tool_id) {
1915 for (
unsigned int i = 0; i < m_PlugInToolbarTools.GetCount(); i++) {
1918 if (pttc->id == tool_id) {
1919 m_PlugInToolbarTools.Remove(pttc);
1925 pParent->RequestNewToolbars();
1928void PlugInManager::SetToolbarToolViz(
int item,
bool viz) {
1929 for (
unsigned int i = 0; i < m_PlugInToolbarTools.GetCount(); i++) {
1932 if (pttc->id == item) {
1934 pParent->RequestNewToolbars();
1941void PlugInManager::SetToolbarItemState(
int item,
bool toggle) {
1942 for (
unsigned int i = 0; i < m_PlugInToolbarTools.GetCount(); i++) {
1945 if (pttc->id == item) {
1946 pttc->b_toggle = toggle;
1947 pParent->SetMasterToolbarItemState(item, toggle);
1954void PlugInManager::SetToolbarItemBitmaps(
int item, wxBitmap* bitmap,
1955 wxBitmap* bmpRollover) {
1956 for (
unsigned int i = 0; i < m_PlugInToolbarTools.GetCount(); i++) {
1959 if (pttc->id == item) {
1960 delete pttc->bitmap_day;
1961 delete pttc->bitmap_dusk;
1962 delete pttc->bitmap_night;
1963 delete pttc->bitmap_Rollover_day;
1965 if (!bitmap->IsOk()) {
1967 pttc->bitmap_day =
new wxBitmap(style->GetIcon(
"default_pi"));
1970 pttc->bitmap_day =
new wxBitmap(*bitmap);
1971 pttc->bitmap_day->UnShare();
1974 if (!bmpRollover->IsOk()) {
1976 pttc->bitmap_Rollover_day =
1977 new wxBitmap(style->GetIcon(
"default_pi"));
1980 pttc->bitmap_Rollover_day =
new wxBitmap(*bmpRollover);
1981 pttc->bitmap_Rollover_day->UnShare();
1984 pttc->bitmap_dusk = BuildDimmedToolBitmap(pttc->bitmap_day, 128);
1985 pttc->bitmap_night = BuildDimmedToolBitmap(pttc->bitmap_day, 32);
1987 pParent->SetToolbarItemBitmaps(item, pttc->bitmap_day,
1988 pttc->bitmap_Rollover_day);
1995void PlugInManager::SetToolbarItemBitmaps(
int item, wxString SVGfile,
1996 wxString SVGfileRollover,
1997 wxString SVGfileToggled) {
1998 for (
unsigned int i = 0; i < m_PlugInToolbarTools.GetCount(); i++) {
2001 if (pttc->id == item) {
2002 pttc->pluginNormalIconSVG = SVGfile;
2003 pttc->pluginRolloverIconSVG = SVGfileRollover;
2004 pttc->pluginToggledIconSVG = SVGfileToggled;
2005 pParent->SetToolbarItemSVG(item, pttc->pluginNormalIconSVG,
2006 pttc->pluginRolloverIconSVG,
2007 pttc->pluginToggledIconSVG);
2015 for (
unsigned int i = 0; i < m_PlugInToolbarTools.GetCount(); i++) {
2017 if (
id == pc->id)
return pc->m_pplugin;
2023wxString PlugInManager::GetToolOwnerCommonName(
const int id) {
2026 auto plugin_array = PluginLoader::GetInstance()->
GetPlugInArray();
2027 for (
unsigned int i = 0; i < plugin_array->GetCount(); i++) {
2029 if (pic && (pic->m_pplugin == ppi))
return pic->
m_common_name;
2033 return wxEmptyString;
2036wxString PlugInManager::GetLastError() {
return m_last_error_string; }
2038wxBitmap* PlugInManager::BuildDimmedToolBitmap(wxBitmap* pbmp_normal,
2039 unsigned char dim_ratio) {
2040 wxImage img_dup = pbmp_normal->ConvertToImage();
2042 if (!img_dup.IsOk())
return NULL;
2044 if (dim_ratio < 200) {
2046 int gimg_width = img_dup.GetWidth();
2047 int gimg_height = img_dup.GetHeight();
2049 double factor = (double)(dim_ratio) / 256.0;
2051 for (
int iy = 0; iy < gimg_height; iy++) {
2052 for (
int ix = 0; ix < gimg_width; ix++) {
2053 if (!img_dup.IsTransparent(ix, iy)) {
2054 wxImage::RGBValue rgb(img_dup.GetRed(ix, iy),
2055 img_dup.GetGreen(ix, iy),
2056 img_dup.GetBlue(ix, iy));
2057 wxImage::HSVValue hsv = wxImage::RGBtoHSV(rgb);
2058 hsv.value = hsv.value * factor;
2059 wxImage::RGBValue nrgb = wxImage::HSVtoRGB(hsv);
2060 img_dup.SetRGB(ix, iy, nrgb.red, nrgb.green, nrgb.blue);
2066 wxBitmap* ptoolBarBitmap;
2069 wxBitmap tbmp(img_dup.GetWidth(), img_dup.GetHeight(), -1);
2071 dwxdc.SelectObject(tbmp);
2073 ptoolBarBitmap =
new wxBitmap(img_dup, (wxDC&)dwxdc);
2075 ptoolBarBitmap =
new wxBitmap(img_dup);
2079 return ptoolBarBitmap;
2082wxArrayString PlugInManager::GetPlugInChartClassNameArray() {
2083 wxArrayString array;
2084 auto plugin_array = PluginLoader::GetInstance()->
GetPlugInArray();
2085 for (
unsigned int i = 0; i < plugin_array->GetCount(); i++) {
2087 if (pic && pic->m_enabled && pic->m_init_state &&
2092 for (
unsigned int j = 0; j < carray.GetCount(); j++) {
2093 array.Add(carray[j]);
2101 while (j < array.GetCount()) {
2102 wxString test = array[j];
2103 unsigned int k = j + 1;
2104 while (k < array.GetCount()) {
2105 if (test == array[k]) {
2123#define DISABLED_SETTINGS_MSG \
2124 _("These settings might destabilize OpenCPN and are by default disabled." \
2125 " To despite the dangers enable them manually add a CatalogExpert=1" \
2126 " line in the [PlugIns] section in the configuration file.")
2131CatalogMgrPanel::CatalogMgrPanel(wxWindow* parent)
2132 : wxPanel(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize),
2134 wxBoxSizer* topSizer =
new wxBoxSizer(wxVERTICAL);
2137 topSizer->Add(
new wxStaticLine(
this), 0, wxGROW | wxLEFT | wxRIGHT, 4);
2139 wxStaticBox* itemStaticBoxSizer4Static =
2140 new wxStaticBox(
this, wxID_ANY, _(
"Plugin Catalog"));
2141 wxStaticBoxSizer* itemStaticBoxSizer4 =
2142 new wxStaticBoxSizer(itemStaticBoxSizer4Static, wxVERTICAL);
2143 topSizer->Add(itemStaticBoxSizer4, 1, wxEXPAND | wxALL, 2);
2147 m_catalogText =
new wxStaticText(
this, wxID_STATIC,
"");
2148 itemStaticBoxSizer4->Add(m_catalogText,
2149 wxSizerFlags().Border().Proportion(1));
2150 m_catalogText->SetLabel(GetCatalogText(
false));
2153 wxBoxSizer* rowSizer2 =
new wxBoxSizer(wxHORIZONTAL);
2154 itemStaticBoxSizer4->Add(rowSizer2,
2155 wxSizerFlags().Expand().Border().Proportion(1));
2157 m_updateButton =
new wxButton(
this, wxID_ANY, _(
"Update Plugin Catalog"),
2158 wxDefaultPosition, wxDefaultSize, 0);
2159 rowSizer2->Add(m_updateButton, 0, wxALIGN_LEFT);
2160 m_updateButton->Bind(wxEVT_COMMAND_BUTTON_CLICKED,
2161 &CatalogMgrPanel::OnUpdateButton,
this);
2162 rowSizer2->AddSpacer(4 * GetCharWidth());
2163 m_tarballButton =
new wxButton(
this, wxID_ANY, _(
"Import plugin..."),
2164 wxDefaultPosition, wxDefaultSize, 0);
2165 rowSizer2->Add(m_tarballButton, 0, wxALIGN_LEFT | wxLEFT, 2 * GetCharWidth());
2166 m_tarballButton->Bind(wxEVT_COMMAND_BUTTON_CLICKED,
2167 &CatalogMgrPanel::OnTarballButton,
this);
2169 rowSizer2->AddSpacer(4 * GetCharWidth());
2170 m_adv_button =
new wxButton(
this, wxID_ANY, _(
"Settings..."),
2171 wxDefaultPosition, wxDefaultSize, 0);
2173 if (expert.Get(
false)) {
2174 m_adv_button->Bind(wxEVT_COMMAND_BUTTON_CLICKED,
2175 &CatalogMgrPanel::OnPluginSettingsButton,
this);
2177 m_adv_button->Bind(wxEVT_COMMAND_BUTTON_CLICKED, [&](wxCommandEvent&) {
2178 wxMessageBox(DISABLED_SETTINGS_MSG, _(
"Disabled"));
2181 rowSizer2->AddSpacer(4 * GetCharWidth());
2182 rowSizer2->Add(m_adv_button, 0, wxALIGN_LEFT);
2184 SetUpdateButtonLabel();
2187 wxBoxSizer* rowSizer3 =
new wxBoxSizer(wxHORIZONTAL);
2188 itemStaticBoxSizer4->Add(rowSizer3, 0, wxEXPAND | wxALL, 4);
2190 SetMinSize(wxSize(m_parent->GetClientSize().x - (4 * GetCharWidth()), -1));
2194 wxDEFINE_EVENT(EVT_CATALOG_CHANGE, wxCommandEvent);
2195 catalog_listener.Listen(catalog,
this, EVT_CATALOG_CHANGE);
2196 Bind(EVT_CATALOG_CHANGE, [&](wxCommandEvent&) { SetUpdateButtonLabel(); });
2199 SetBackgroundColour(wxColour(0x7c, 0xb0, 0xe9));
2201 if (!expert.Get(
false)) {
2203 new wxButton(
this, wxID_ANY, _(
"Update Plugin Catalog: master"),
2204 wxDefaultPosition, wxDefaultSize, 0);
2205 itemStaticBoxSizer4->Add(m_updateButton, 0, wxALIGN_LEFT);
2206 m_updateButton->Bind(wxEVT_COMMAND_BUTTON_CLICKED,
2207 &CatalogMgrPanel::OnUpdateButton,
this);
2208 SetUpdateButtonLabel();
2209 m_tarballButton = NULL;
2210 m_adv_button = NULL;
2213 m_catalogText =
new wxStaticText(
this, wxID_STATIC, GetCatalogText(
false));
2214 itemStaticBoxSizer4->Add(m_catalogText,
2215 wxSizerFlags().Border(wxALL, 5).Proportion(1));
2218 m_updateButton =
new wxButton(
2219 this, wxID_ANY,
"Update Plugin Catalog:master ",
2220 wxDefaultPosition, wxDefaultSize, 0);
2221 itemStaticBoxSizer4->Add(m_updateButton, 0, wxALIGN_LEFT | wxTOP, 5);
2222 m_updateButton->Bind(wxEVT_COMMAND_BUTTON_CLICKED,
2223 &CatalogMgrPanel::OnUpdateButton,
this);
2224 SetUpdateButtonLabel();
2227 m_adv_button =
new wxButton(
this, wxID_ANY, _(
"Settings..."),
2228 wxDefaultPosition, wxDefaultSize, 0);
2229 itemStaticBoxSizer4->Add(m_adv_button, 0, wxALIGN_LEFT | wxTOP,
2231 m_adv_button->Bind(wxEVT_COMMAND_BUTTON_CLICKED,
2232 &CatalogMgrPanel::OnPluginSettingsButton,
this);
2235 m_tarballButton =
new wxButton(
this, wxID_ANY, _(
"Import plugin..."),
2236 wxDefaultPosition, wxDefaultSize, 0);
2237 itemStaticBoxSizer4->Add(m_tarballButton, 0, wxALIGN_LEFT | wxALL,
2238 2 * GetCharWidth());
2239 m_tarballButton->Bind(wxEVT_COMMAND_BUTTON_CLICKED,
2240 &CatalogMgrPanel::OnTarballButton,
this);
2246CatalogMgrPanel::~CatalogMgrPanel() {
2247 m_updateButton->Unbind(wxEVT_COMMAND_BUTTON_CLICKED,
2248 &CatalogMgrPanel::OnUpdateButton,
this);
2249 if (m_tarballButton)
2250 m_tarballButton->Unbind(wxEVT_COMMAND_BUTTON_CLICKED,
2251 &CatalogMgrPanel::OnTarballButton,
this);
2254static const char*
const DOWNLOAD_REPO_PROTO =
2255 "https://raw.githubusercontent.com/OpenCPN/plugins/@branch@/"
2258void CatalogMgrPanel::OnUpdateButton(wxCommandEvent& event) {
2260 std::string catalog(g_catalog_channel ==
"" ?
"master" : g_catalog_channel);
2261 std::string url(g_catalog_custom_url);
2262 if (catalog !=
"custom") {
2263 url = std::string(DOWNLOAD_REPO_PROTO);
2267 std::string filePath =
2268 wxFileName::CreateTempFileName(
"ocpn_dl").ToStdString();
2270 auto catalogHdlr = CatalogHandler::GetInstance();
2272 g_Platform->ShowBusySpinner();
2273 auto status = catalogHdlr->DownloadCatalog(filePath, url);
2274 g_Platform->HideBusySpinner();
2276 std::string message;
2277 if (status != CatalogHandler::ServerStatus::OK) {
2278 message = _(
"Cannot download data from url");
2279 OCPNMessageBox(
this, message, _(
"OpenCPN Catalog update"),
2280 wxICON_ERROR | wxOK);
2286 if (!AndroidSecureCopyFile(wxString(filePath.c_str()),
2288 wxFileName::GetPathSeparator() +
2289 "ocpn-plugins.xml")) {
2290 OCPNMessageBox(
this, _(
"Unable to copy catalog file"),
2291 _(
"OpenCPN Catalog update"), wxICON_ERROR | wxOK);
2296 if (!wxCopyFile(wxString(filePath.c_str()),
2298 wxFileName::GetPathSeparator() +
"ocpn-plugins.xml")) {
2299 OCPNMessageBox(
this, _(
"Unable to copy catalog file"),
2300 _(
"OpenCPN Catalog update"), wxICON_ERROR | wxOK);
2306 if (catalog ==
"master") {
2308 OCPNMessageBox(
this, _(
"Unable to copy catalog file to cache"),
2309 _(
"OpenCPN Catalog update"), wxICON_ERROR | wxOK);
2315 pConfig->SetPath(
"/PlugIns/");
2316 pConfig->Write(
"LatestCatalogDownloaded", catalog.c_str());
2323 pluginHandler->setMetadata(
"");
2327 auto cataloghdlr = CatalogHandler::GetInstance();
2328 cataloghdlr->ClearCatalogData();
2331 LoadAllPlugIns(
false);
2335 m_catalogText->SetLabel(GetCatalogText(
true));
2338 OCPNMessageBox(
this, _(
"Catalog update successful"),
2339 _(
"OpenCPN Catalog update"), wxICON_INFORMATION | wxOK);
2342void CatalogMgrPanel::OnPluginSettingsButton(wxCommandEvent& event) {
2346 androidDisableRotation();
2349 dialog->ShowModal();
2352 androidEnableRotation();
2356void CatalogMgrPanel::OnTarballButton(wxCommandEvent& event) {
2359 int response = g_Platform->DoFileSelectorDialog(
2360 this, &path, _(
"Select tarball file"), GetImportInitDir(),
"",
2361 "tar files (*.tar.gz)|*.tar.gz|All Files (*.*)|*.*");
2363 if (response != wxID_OK) {
2368 bool ok = handler->ExtractMetadata(path.ToStdString(), metadata);
2372 _(
"Error extracting metadata from tarball (missing metadata.xml?)"),
2373 _(
"OpenCPN Plugin Import Error"));
2377 OCPNMessageBox(
this, _(
"Incompatible import plugin detected."),
2378 _(
"OpenCPN Plugin Import Error"));
2379 handler->Uninstall(metadata.name);
2382 UninstallPlugin(metadata.name);
2383 ok = handler->InstallPlugin(metadata, path.ToStdString());
2385 OCPNMessageBox(
this, _(
"Error extracting import plugin tarball."),
2386 _(
"OpenCPN Plugin Import Error"));
2389 metadata.is_imported =
true;
2391 std::ofstream file(metadata_path);
2394 WARNING_LOG <<
"Error saving metadata file: " << metadata_path
2395 <<
" for imported plugin: " << metadata.name;
2397 LoadAllPlugIns(
false,
true);
2400 wxString ws(_(
"Plugin"));
2401 ws += metadata.name + _(
" successfully imported");
2402 OCPNMessageBox(gFrame, ws, _(
"Installation complete"),
2403 wxICON_INFORMATION | wxOK | wxCENTRE);
2406wxString CatalogMgrPanel::GetCatalogText(
bool updated) {
2408 catalog = updated ? _(
"Active Catalog") : _(
"Last Catalog");
2412 pConfig->SetPath(
"/PlugIns/");
2413 wxString latestCatalog = pConfig->Read(
"LatestCatalogDownloaded",
"default");
2414 catalog += latestCatalog;
2420 std::string date = pluginHandler->GetCatalogData()->date;
2422 catalog += wxString(
" ") + _(
"Last change: ") +
" " + date;
2423 if (!updated) catalog +=
" : " + _(
"Please Update Plugin Catalog.");
2429void CatalogMgrPanel::SetUpdateButtonLabel() {
2430 wxString label = _(
"Update Plugin Catalog");
2432 label += g_catalog_channel ==
"" ?
"master" : g_catalog_channel;
2433 m_updateButton->SetLabel(label);
2437wxString CatalogMgrPanel::GetImportInitDir() {
2439 pConfig->SetPath(
"/PlugIns/");
2440 wxString lastImportDir;
2442 pConfig->Read(
"LatestImportDir", g_Platform->GetWritableDocumentsDir());
2443 if (wxDirExists(lastImportDir)) {
2444 return lastImportDir;
2446 return (g_Platform->GetWritableDocumentsDir());
2455 const wxPoint& pos, const wxSize& size)
2456 : wxScrolledWindow(parent,
id, pos, size, wxTAB_TRAVERSAL | wxVSCROLL),
2457 m_PluginSelected(0) {
2458 m_is_loading.clear();
2459 SetSizer(
new wxBoxSizer(wxVERTICAL));
2460 ReloadPluginPanels();
2463void PluginListPanel::SelectByName(wxString& name) {
2464 for (
auto it = GetChildren().GetFirst(); it; it = it->GetNext()) {
2465 auto pluginPanel =
dynamic_cast<PluginPanel*
>(it->GetData());
2467 if (pluginPanel->GetPluginPtr()->m_common_name.IsSameAs(name)) {
2468 pluginPanel->SetSelected(
true);
2469 pluginPanel->Layout();
2470 SelectPlugin(pluginPanel);
2479 std::vector<const PlugInData*> result;
2480 auto loader = PluginLoader::GetInstance();
2481 for (
size_t i = 0; i < loader->GetPlugInArray()->GetCount(); i++) {
2482 auto const item = loader->GetPlugInArray()->Item(i);
2483 if (item->m_managed_metadata.name.empty()) {
2484 const auto name = item->m_common_name.ToStdString();
2488 result.push_back(item);
2491 std::string slhs, srhs;
2492 for (
auto& cl : lhs->
Key()) slhs += toupper(cl);
2493 for (
auto& cr : rhs->Key()) srhs += toupper(cr);
2494 return slhs.compare(srhs) < 0;
2496 std::sort(result.begin(), result.end(), compare);
2501static bool IsPluginLoaded(
const std::string& name) {
2502 if (safe_mode::get_mode()) {
2505 std::find(installed.begin(), installed.end(),
ocpn::tolower(name));
2506 return found != installed.end();
2509 for (
size_t i = 0; i < loaded->GetCount(); i++) {
2510 if (loaded->Item(i)->m_common_name.ToStdString() == name)
return true;
2517 if (m_is_loading.test_and_set()) {
2519 DEBUG_LOG <<
"LoadAllPlugins: recursive invocation";
2524 m_PluginItems.Clear();
2526 wxWindowList kids = GetChildren();
2527 for (
unsigned int i = 0; i < kids.GetCount(); i++) {
2528 wxWindowListNode* node = kids.Item(i);
2529 wxWindow* win = node->GetData();
2531 if (pp) win->Destroy();
2533 GetSizer()->Clear();
2536 m_PluginSelected = 0;
2538 if (safe_mode::get_mode()) {
2541 for (
const auto& name : installed) AddPlugin(name);
2544 auto available = getCompatiblePlugins();
2548 return IsPluginLoaded(md.name);
2550 auto end = std::remove_if(available.begin(), available.end(), predicate);
2551 available.erase(end, available.end());
2557 std::string slhs, srhs;
2558 for (
auto& cl : lhs.name) slhs += toupper(cl);
2559 for (
auto& cr : rhs.name) srhs += toupper(cr);
2560 return slhs.compare(srhs) < 0;
2564 std::set<PluginMetadata, CompSort> unique_sorted_entries(comp_sort);
2565 for (
const auto& p : available) unique_sorted_entries.insert(p);
2571 if (p->m_enabled) AddPlugin(*p);
2575 if (!p->m_enabled) AddPlugin(*p);
2578 for (
const auto& p : unique_sorted_entries) AddPlugin(
PlugInData(p));
2586 m_is_loading.clear();
2589void PluginListPanel::AddPlugin(
const std::string& name) {
2592 panel->SetSelected(
false);
2593 GetSizer()->Add(panel, 0, wxEXPAND);
2594 m_PluginItems.Add(panel);
2595 m_pluginSpacer = g_Platform->GetDisplayDPmm() * 1.0;
2596 GetSizer()->AddSpacer(m_pluginSpacer);
2599void PluginListPanel::AddPlugin(
const PlugInData& pic) {
2601 new PluginPanel(
this, wxID_ANY, wxDefaultPosition, wxDefaultSize, pic);
2602 pPluginPanel->SetSelected(
false);
2603 GetSizer()->Add(pPluginPanel, 0, wxEXPAND);
2604 m_PluginItems.Add(pPluginPanel);
2606 m_pluginSpacer = g_Platform->GetDisplayDPmm() * 1.0;
2607 GetSizer()->AddSpacer(m_pluginSpacer);
2620int PluginListPanel::ComputePluginSpace(ArrayOfPluginPanel plugins,
2621 wxBoxSizer* sizer) {
2623 for (
size_t i = 0; i < plugins.GetCount(); i++) {
2624 auto panel = plugins.Item(i);
2625 bool was_selected = panel->GetSelected();
2626 panel->SetSelected(
false);
2628 wxSize unselected = panel->GetSize();
2630 panel->SetSelected(
true);
2632 wxSize selected = panel->GetSize();
2634 int dy = selected.GetHeight() - unselected.GetHeight();
2635 max_dy = wxMax(max_dy, dy);
2636 panel->SetSelected(was_selected);
2641PluginListPanel::~PluginListPanel() {}
2643void PluginListPanel::UpdateSelections() {
2644 for (
unsigned int i = 0; i < m_PluginItems.GetCount(); i++) {
2647 pPluginPanel->SetSelected(pPluginPanel->GetSelected());
2652void PluginListPanel::SelectPlugin(
PluginPanel* pi) {
2654 GetViewStart(&xs, &ys);
2657 if (m_PluginSelected) {
2658 m_PluginSelected->SetSelected(
false);
2659 m_PluginSelected->Layout();
2662 if (pi == NULL) m_PluginSelected->SetSelected(
false);
2664 m_PluginSelected = pi;
2666 GetSizer()->Layout();
2668 wxSize size = GetBestVirtualSize();
2669 SetVirtualSize(size);
2674 for (
unsigned int i = 0; i < m_PluginItems.GetCount(); i++) {
2676 int yd = pPluginPanel->GetSize().y;
2678 htop += m_pluginSpacer;
2679 if (pPluginPanel == pi) {
2680 int piBottom = htop - (ys *
g_options->GetScrollRate());
2681 if (piBottom > GetClientSize().y) {
2682 ys += (piBottom - GetClientSize().y) /
g_options->GetScrollRate();
2692 int pos = m_PluginItems.Index(pi);
2695 m_PluginItems.RemoveAt(pos);
2698 m_PluginItems.Insert(pi, pos - 1);
2699 wxStaticLine* itemStaticLine =
new wxStaticLine(
2700 this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL);
2705 m_PluginSelected = pi;
2707 GetSizer()->Layout();
2713 int pos = m_PluginItems.Index(pi);
2714 if (pos == (
int)m_PluginItems.Count() -
2717 m_PluginItems.RemoveAt(pos);
2720 m_PluginItems.Insert(pi, pos + 1);
2721 wxStaticLine* itemStaticLine =
new wxStaticLine(
2722 this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL);
2727 m_PluginSelected = pi;
2729 GetSizer()->Layout();
2734static bool canUninstall(std::string name) {
2739 if (plugin.name == name) {
2740 if (safe_mode::get_mode())
2743 return !plugin.readonly;
2750 : wxPanel(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize,
2752 m_is_safe_panel(true) {
2754 wxASSERT(m_PluginListPanel != 0);
2755 wxBoxSizer* top_sizer =
new wxBoxSizer(wxVERTICAL);
2756 SetSizer(top_sizer);
2757 wxBoxSizer* top_horizontal =
new wxBoxSizer(wxHORIZONTAL);
2758 top_sizer->Add(top_horizontal, 0, wxEXPAND);
2760 double iconSize = GetCharWidth() * 4;
2762 int icon_scale = iconSize * dpi_mult;
2764 wxBitmap bitmap(style->GetIcon(
"default_pi", icon_scale, icon_scale));
2765 m_itemStaticBitmap =
new wxStaticBitmap(
this, wxID_ANY, bitmap);
2766 top_horizontal->Add(m_itemStaticBitmap, 0, wxEXPAND | wxALL, 10);
2768 m_pName =
new wxStaticText(
this, wxID_ANY, name);
2769 top_horizontal->Add(m_pName, wxID_ANY, wxALIGN_CENTER_VERTICAL);
2770 m_pVersion =
new wxStaticText(
this, wxID_ANY,
"");
2771 top_horizontal->Add(m_pVersion);
2774 m_pButtons =
new wxBoxSizer(wxHORIZONTAL);
2775 top_horizontal->Add(m_pButtons);
2776 m_info_btn =
new WebsiteButton(
this,
"https:\\opencpn.org");
2777 top_horizontal->Add(m_info_btn);
2778 m_pButtonUninstall =
new wxButton(
this, wxID_ANY, _(
"Uninstall"),
2779 wxDefaultPosition, wxDefaultSize, 0);
2780 top_horizontal->Add(m_pButtonUninstall, 0, wxALIGN_CENTER_VERTICAL | wxALL,
2782 auto uninstall = [&](wxCommandEvent ev) {
2783 auto n = m_pName->GetLabel().ToStdString();
2785 OCPNMessageBox(gFrame, std::string(_(
"Uninstall plugin ")) + n +
"?",
2786 _(
"Un-Installation"), wxICON_QUESTION | wxOK | wxCANCEL);
2787 if (result != wxID_OK)
return;
2791 m_pButtonUninstall->Bind(wxEVT_COMMAND_BUTTON_CLICKED, uninstall);
2795EVT_PAINT(PluginPanel::OnPaint)
2800 : wxPanel(parent,
id, pos, size, wxBORDER_NONE),
2802 m_is_safe_panel(false) {
2805 wxASSERT(m_PluginListPanel != 0);
2807 m_bSelected =
false;
2808 m_penWidthUnselected = g_Platform->GetDisplayDPmm() * .25;
2809 m_penWidthSelected = g_Platform->GetDisplayDPmm() * .5;
2811 wxBoxSizer* topSizer =
new wxBoxSizer(wxVERTICAL);
2814 wxBoxSizer* itemBoxSizer01 =
new wxBoxSizer(wxHORIZONTAL);
2815 topSizer->Add(itemBoxSizer01, 0, wxEXPAND);
2816 Bind(wxEVT_LEFT_DOWN, &PluginPanel::OnPluginSelected,
this);
2817 Bind(wxEVT_LEFT_UP, &PluginPanel::OnPluginSelectedUp,
this);
2819 double iconSize = GetCharWidth() * 4;
2821 int icon_scale = iconSize * dpi_mult;
2823 wxImage plugin_icon;
2825 if (m_plugin.m_bitmap.IsOk()) {
2826 plugin_icon = m_plugin.m_bitmap.ConvertToImage();
2829 if (m_plugin.m_status == PluginStatus::ManagedInstallAvailable) {
2830 wxFileName path(g_Platform->GetSharedDataDir(),
"packageBox.svg");
2831 path.AppendDir(
"uidata");
2832 path.AppendDir(
"traditional");
2833 bitmap =
LoadSVG(path.GetFullPath(), icon_scale, icon_scale);
2834 }
else if (plugin_icon.IsOk()) {
2835 int nowSize = plugin_icon.GetWidth();
2836 plugin_icon.Rescale(icon_scale, icon_scale, wxIMAGE_QUALITY_HIGH);
2837 bitmap = wxBitmap(plugin_icon);
2839 bitmap = wxBitmap(style->GetIcon(
"default_pi", icon_scale, icon_scale));
2841 m_itemStaticBitmap =
new wxStaticBitmap(
this, wxID_ANY, bitmap);
2843 itemBoxSizer01->Add(m_itemStaticBitmap, 0, wxEXPAND | wxALL, 10);
2844 m_itemStaticBitmap->Bind(wxEVT_LEFT_DOWN, &PluginPanel::OnPluginSelected,
2846 m_itemStaticBitmap->Bind(wxEVT_LEFT_UP, &PluginPanel::OnPluginSelectedUp,
2849 wxBoxSizer* itemBoxSizer02 =
new wxBoxSizer(wxVERTICAL);
2850 itemBoxSizer01->Add(itemBoxSizer02, 1, wxEXPAND | wxALL, 0);
2853 int nChars =
g_options->GetSize().x / GetCharWidth();
2854 bool bCompact =
false;
2860 wxString nameString = m_plugin.m_common_name;
2864 dc.GetTextExtent(m_plugin.m_common_name, &nameWidth, NULL);
2865 if (nameWidth > maxWidth) {
2866 nameString = wxControl::Ellipsize(m_plugin.m_common_name, dc,
2867 wxELLIPSIZE_END, maxWidth);
2869 m_pName =
new wxStaticText(
this, wxID_ANY, nameString);
2870 m_pName->Bind(wxEVT_LEFT_DOWN, &PluginPanel::OnPluginSelected,
this);
2871 m_pName->Bind(wxEVT_LEFT_UP, &PluginPanel::OnPluginSelectedUp,
this);
2872 itemBoxSizer02->Add(m_pName, 0, wxALL, 5);
2874 wxFlexGridSizer* sl1 =
new wxFlexGridSizer(2, 0, 0);
2875 sl1->AddGrowableCol(1);
2876 itemBoxSizer02->Add(sl1, 0, wxEXPAND);
2878 m_pVersion =
new wxStaticText(
this, wxID_ANY,
"X.YY.ZZ.AA");
2879 sl1->Add(m_pVersion, 0, wxALL, 5);
2880 if (m_plugin.m_status == PluginStatus::ManagedInstallAvailable) {
2883 m_pVersion->Bind(wxEVT_LEFT_DOWN, &PluginPanel::OnPluginSelected,
this);
2884 m_pVersion->Bind(wxEVT_LEFT_UP, &PluginPanel::OnPluginSelectedUp,
this);
2886 m_cbEnable =
new wxCheckBox(
this, wxID_ANY, _(
"Enabled"));
2887 sl1->Add(m_cbEnable, 1, wxALIGN_RIGHT | wxTOP, 5);
2888 m_cbEnable->Bind(wxEVT_CHECKBOX, &PluginPanel::OnPluginEnableToggle,
this);
2891 wxString descriptionString = m_plugin.m_short_description;
2892 int maxDescriptionWidth = g_Platform->
getDisplaySize().x - (iconSize * 4);
2893 int descriptionWidth;
2894 dc.GetTextExtent(m_plugin.m_short_description, &descriptionWidth, NULL);
2895 if (descriptionWidth > maxDescriptionWidth)
2897 wxControl::Ellipsize(m_plugin.m_short_description, dc,
2898 wxELLIPSIZE_END, maxDescriptionWidth);
2903 new wxStaticText(
this, wxID_ANY, descriptionString, wxDefaultPosition,
2904 wxSize(maxDescriptionWidth, -1), wxST_NO_AUTORESIZE);
2905 itemBoxSizer02->Add(m_pDescription, 0, wxEXPAND | wxALL, 5);
2906 m_pDescription->Bind(wxEVT_LEFT_DOWN, &PluginPanel::OnPluginSelected,
this);
2907 m_pDescription->Bind(wxEVT_LEFT_UP, &PluginPanel::OnPluginSelectedUp,
this);
2910 wxFlexGridSizer* itemBoxSizer03 =
new wxFlexGridSizer(4, 0, 0);
2911 itemBoxSizer03->AddGrowableCol(2);
2912 itemBoxSizer02->Add(itemBoxSizer03, 0, wxEXPAND);
2914 wxString nameString = m_plugin.m_common_name;
2915 m_pName =
new wxStaticText(
this, wxID_ANY, nameString);
2916 m_pName->Bind(wxEVT_LEFT_DOWN, &PluginPanel::OnPluginSelected,
this);
2917 m_pName->Bind(wxEVT_LEFT_UP, &PluginPanel::OnPluginSelectedUp,
this);
2921 wxFont font = GetFont();
2922 font.SetWeight(wxFONTWEIGHT_BOLD);
2923 m_pName->SetFont(font);
2926 itemBoxSizer03->Add(m_pName, 0, wxALL, 10);
2928 m_pVersion =
new wxStaticText(
this, wxID_ANY,
"X.YY.ZZ.AA");
2929 itemBoxSizer03->Add(m_pVersion, 0, wxALL, 10);
2930 if (m_plugin.m_status == PluginStatus::ManagedInstallAvailable ||
2933 !m_plugin.m_managed_metadata.is_orphan)) {
2936 m_pVersion->Bind(wxEVT_LEFT_DOWN, &PluginPanel::OnPluginSelected,
this);
2937 m_pVersion->Bind(wxEVT_LEFT_UP, &PluginPanel::OnPluginSelectedUp,
this);
2939 m_cbEnable =
new wxCheckBox(
this, wxID_ANY, _(
"Enabled"));
2940 itemBoxSizer03->Add(m_cbEnable, 1, wxALIGN_RIGHT | wxTOP, 10);
2941 m_cbEnable->Bind(wxEVT_CHECKBOX, &PluginPanel::OnPluginEnableToggle,
this);
2943 itemBoxSizer03->Add(5 * GetCharWidth(), 1, 0, wxALIGN_RIGHT | wxTOP, 10);
2945 m_pDescription =
new wxStaticText(
2946 this, wxID_ANY, m_plugin.m_short_description, wxDefaultPosition,
2948 itemBoxSizer02->Add(m_pDescription, 1, wxEXPAND | wxALL, 5);
2949 m_pDescription->Bind(wxEVT_LEFT_DOWN, &PluginPanel::OnPluginSelected,
this);
2950 m_pDescription->Bind(wxEVT_LEFT_UP, &PluginPanel::OnPluginSelectedUp,
this);
2954 m_info_btn =
new WebsiteButton(
this,
"https:\\opencpn.org");
2956 itemBoxSizer02->Add(m_info_btn, 0);
2958 m_pButtons =
new wxBoxSizer(wxHORIZONTAL);
2959 itemBoxSizer02->Add(m_pButtons, 0, wxALL, 0);
2960 m_pButtonPreferences =
new wxButton(
this, wxID_ANY, _(
"Preferences"),
2961 wxDefaultPosition, wxDefaultSize, 0);
2962 m_pButtons->Add(m_pButtonPreferences, 0, wxALIGN_LEFT | wxALL, 2);
2964 m_pButtons->AddSpacer(3 * GetCharWidth());
2967 new wxButton(
this, wxID_ANY,
"Upgrade to Version XX.XX.XX",
2968 wxDefaultPosition, wxDefaultSize, 0);
2969 m_pButtons->Add(m_pButtonAction, 0, wxALIGN_LEFT | wxALL, 2);
2971 m_pButtonUninstall =
new wxButton(
this, wxID_ANY, _(
"Uninstall"),
2972 wxDefaultPosition, wxDefaultSize, 0);
2973 m_pButtons->Add(m_pButtonUninstall, 0, wxALIGN_LEFT | wxALL, 2);
2975 m_pButtons =
new wxBoxSizer(wxVERTICAL);
2976 itemBoxSizer02->Add(m_pButtons, 0, wxALL, 0);
2978 wxBoxSizer* tline =
new wxBoxSizer(wxHORIZONTAL);
2979 m_pButtons->Add(tline, 0, wxALL, 2);
2981 m_pButtonPreferences =
new wxButton(
this, wxID_ANY, _(
"Preferences"),
2982 wxDefaultPosition, wxDefaultSize, 0);
2983 tline->Add(m_pButtonPreferences, 0, wxALIGN_LEFT | wxALL, 0);
2985 tline->AddSpacer(3 * GetCharWidth());
2987 m_info_btn =
new WebsiteButton(
this,
"https:\\opencpn.org");
2989 tline->Add(m_info_btn, 0);
2992 new wxButton(
this, wxID_ANY,
"Upgrade to Version XX.XX.XX",
2993 wxDefaultPosition, wxDefaultSize);
2994 m_pButtons->Add(m_pButtonAction, 0, wxALIGN_LEFT | wxALL, 2);
2996 m_pButtonUninstall =
new wxButton(
this, wxID_ANY, _(
"Uninstall"),
2997 wxDefaultPosition, wxDefaultSize, 0);
2998 m_pButtons->Add(m_pButtonUninstall, 0, wxALIGN_LEFT | wxALL, 2);
3001 wxBitmap statusBitmap;
3002 const auto stat = m_plugin.m_status;
3003 auto icon_name = icon_by_status.at(stat);
3004 if (stat == PluginStatus::Imported &&
3005 IsUpdateAvailable(m_plugin.m_managed_metadata)) {
3007 icon_by_status.at(PluginStatus::ManagedInstalledUpdateAvailable);
3010 wxFileName path(g_Platform->GetSharedDataDir(), icon_name);
3011 path.AppendDir(
"uidata");
3012 path.AppendDir(
"traditional");
3014 int bmsize = GetCharWidth() * 3 * dpi_mult;
3015 if (path.IsFileReadable()) {
3016 statusBitmap =
LoadSVG(path.GetFullPath(), bmsize, bmsize);
3017 ok = statusBitmap.IsOk();
3020 auto style = g_StyleManager->GetCurrentStyle();
3021 statusBitmap = wxBitmap(style->GetIcon(
"default_pi", bmsize, bmsize));
3022 wxLogMessage(
"Icon: %s not found.", path.GetFullPath());
3025 m_itemStatusIconBitmap =
new wxStaticBitmap(
this, wxID_ANY, statusBitmap);
3026 m_itemStatusIconBitmap->SetToolTip(message_by_status(stat));
3027 m_itemStatusIconBitmap->Bind(wxEVT_LEFT_DOWN, &PluginPanel::OnPluginSelected,
3029 m_itemStatusIconBitmap->Bind(wxEVT_LEFT_UP, &PluginPanel::OnPluginSelectedUp,
3032 itemBoxSizer01->Add(m_itemStatusIconBitmap, 0, wxEXPAND | wxALL, 20);
3034 itemBoxSizer02->AddSpacer(GetCharWidth());
3036 m_pButtonPreferences->Bind(wxEVT_COMMAND_BUTTON_CLICKED,
3037 &PluginPanel::OnPluginPreferences,
this);
3038 m_pButtonUninstall->Bind(wxEVT_COMMAND_BUTTON_CLICKED,
3039 &PluginPanel::OnPluginUninstall,
this);
3040 m_pButtonAction->Bind(wxEVT_COMMAND_BUTTON_CLICKED,
3041 &PluginPanel::OnPluginAction,
this);
3043 SetSelected(m_bSelected);
3044 SetAutoLayout(
true);
3052PluginPanel::~PluginPanel() {
3053 Unbind(wxEVT_LEFT_DOWN, &PluginPanel::OnPluginSelected,
this);
3054 if (m_is_safe_panel)
return;
3055 m_itemStaticBitmap->Unbind(wxEVT_LEFT_DOWN, &PluginPanel::OnPluginSelected,
3057 m_pName->Unbind(wxEVT_LEFT_DOWN, &PluginPanel::OnPluginSelected,
this);
3058 m_pVersion->Unbind(wxEVT_LEFT_DOWN, &PluginPanel::OnPluginSelected,
this);
3059 m_pDescription->Unbind(wxEVT_LEFT_DOWN, &PluginPanel::OnPluginSelected,
this);
3060 if (m_pButtonAction) {
3061 m_pButtonAction->Unbind(wxEVT_COMMAND_BUTTON_CLICKED,
3062 &PluginPanel::OnPluginAction,
this);
3064 m_pButtonPreferences->Unbind(wxEVT_COMMAND_BUTTON_CLICKED,
3065 &PluginPanel::OnPluginPreferences,
this);
3066 m_cbEnable->Unbind(wxEVT_COMMAND_BUTTON_CLICKED,
3067 &PluginPanel::OnPluginEnableToggle,
this);
3070void PluginPanel::SetActionLabel(wxString& label) {
3071 m_pButtonAction->SetLabel(label);
3075static wxStopWatch swclick;
3076static int downx, downy;
3078void PluginPanel::OnPluginSelected(wxMouseEvent& event) {
3081 event.GetPosition(&downx, &downy);
3087void PluginPanel::OnPluginSelectedUp(wxMouseEvent& event) {
3089 qDebug() << swclick.Time();
3090 if (swclick.Time() < 200) {
3092 event.GetPosition(&upx, &upy);
3093 if ((fabs(upx - downx) < GetCharWidth()) &&
3094 (fabs(upy - downy) < GetCharWidth())) {
3102void PluginPanel::DoPluginSelect() {
3103 if (m_plugin.m_status == PluginStatus::ManagedInstallAvailable) {
3109 run_update_dialog(m_PluginListPanel, &m_plugin,
false, 0,
true);
3110 }
else if (m_bSelected) {
3112 m_PluginListPanel->SelectPlugin(NULL);
3115 m_PluginListPanel->SelectPlugin(
this);
3123static PluginMetadata GetMetadataByName(
const std::string& name) {
3125 auto predicate = [name](
const PluginMetadata& pm) {
return pm.name == name; };
3126 auto found = std::find_if(plugins.begin(), plugins.end(), predicate);
3127 if (found == plugins.end()) {
3128 wxLogDebug(
"Cannot find metadata for %s", name.c_str());
3133void PluginPanel::SetSelected(
bool selected) {
3134 m_bSelected = selected;
3136 m_pVersion->SetLabel(
3140 m_pButtons->Show(
true);
3141 bool unInstallPossible = canUninstall(m_plugin.
m_common_name.ToStdString());
3144 if (m_plugin.m_status == PluginStatus::LegacyUpdateAvailable ||
3147 unInstallPossible =
false;
3150 if (m_plugin.m_managed_metadata.is_orphan) unInstallPossible =
true;
3152 m_pButtonUninstall->Show(unInstallPossible);
3154 if (m_plugin.m_managed_metadata.info_url.size()) {
3155 m_info_btn->SetURL(m_plugin.m_managed_metadata.info_url.c_str());
3159 m_cbEnable->Show(
true);
3164 switch (m_plugin.m_status) {
3165 case PluginStatus::LegacyUpdateAvailable:
3166 label = _(
"Upgrade to Version ");
3167 label += wxString(m_plugin.m_managed_metadata.version.c_str());
3168 m_action = ActionVerb::UPGRADE_TO_MANAGED_VERSION;
3169 m_pButtonAction->Enable();
3172 case PluginStatus::ManagedInstallAvailable:
3173 label = _(
"Install...");
3174 m_action = ActionVerb::INSTALL_MANAGED_VERSION;
3175 m_pButtonAction->Enable();
3178 case PluginStatus::ManagedInstalledUpdateAvailable:
3179 label = _(
"Update to ");
3180 label += wxString(m_plugin.m_managed_metadata.version.c_str());
3181 m_action = ActionVerb::UPGRADE_INSTALLED_MANAGED_VERSION;
3182 m_pButtonAction->Enable();
3185 case PluginStatus::ManagedInstalledCurrentVersion:
3186 label = _(
"Reinstall");
3187 m_action = ActionVerb::REINSTALL_MANAGED_VERSION;
3188 m_pButtonAction->Enable();
3191 case PluginStatus::ManagedInstalledDowngradeAvailable:
3192 label = _(
"Downgrade");
3193 m_action = ActionVerb::DOWNGRADE_INSTALLED_MANAGED_VERSION;
3194 m_pButtonAction->Enable();
3197 case PluginStatus::Imported:
3198 if (IsUpdateAvailable(m_plugin.m_managed_metadata)) {
3199 label = _(
"Update");
3200 m_action = ActionVerb::UPDATE_IMPORTED_VERSION;
3202 m_pButtonAction->Hide();
3203 m_action = ActionVerb::NOP;
3208 m_action = ActionVerb::NOP;
3209 m_pButtonAction->Hide();
3213 m_action = ActionVerb::NOP;
3214 m_pButtonAction->Hide();
3219 m_action = ActionVerb::NOP;
3222 SetActionLabel(label);
3234 m_pButtons->Show(
false);
3237 if (m_plugin.m_status == PluginStatus::ManagedInstallAvailable)
3238 m_cbEnable->Show(
false);
3259 SetEnabled(m_plugin.m_enabled);
3274void PluginPanel::OnPaint(wxPaintEvent& event) {
3277 int penWidth = m_penWidthUnselected;
3282 penWidth = m_penWidthSelected;
3287 wxBrush b(color, wxBRUSHSTYLE_SOLID);
3289 dc.SetPen(wxPen(border, penWidth));
3291 dc.DrawRoundedRectangle(5, 5, GetSize().x - 10, GetSize().y - 10, 5);
3294void PluginPanel::OnPluginPreferences(wxCommandEvent& event) {
3295 if (m_plugin.m_enabled && m_plugin.m_init_state &&
3298 androidDisableRotation();
3309void PluginPanel::OnPluginEnableToggle(wxCommandEvent& event) {
3310 g_Platform->ShowBusySpinner();
3311 SetEnabled(event.IsChecked());
3312 m_pVersion->SetLabel(
3319 g_Platform->HideBusySpinner();
3322void PluginPanel::OnPluginUninstall(wxCommandEvent& event) {
3323 m_action = ActionVerb::UNINSTALL_MANAGED_VERSION;
3326 wxCommandEvent actionEvent(wxEVT_COMMAND_BUTTON_CLICKED);
3327 actionEvent.SetId(ID_CMD_BUTTON_PERFORM_ACTION);
3328 actionEvent.SetClientData(
this);
3329 g_pi_manager->GetUtilHandler()->AddPendingEvent(actionEvent);
3332void PluginPanel::OnPluginAction(wxCommandEvent& event) {
3334 wxCommandEvent actionEvent(wxEVT_COMMAND_BUTTON_CLICKED);
3335 actionEvent.SetId(ID_CMD_BUTTON_PERFORM_ACTION);
3336 actionEvent.SetClientData(
this);
3337 g_pi_manager->GetUtilHandler()->AddPendingEvent(actionEvent);
3342static void SetWindowFontStyle(wxWindow* window, wxFontStyle style) {
3343 auto font = window->GetFont();
3344 font.SetStyle(style);
3345 window->SetFont(font);
3348void PluginPanel::SetEnabled(
bool enabled) {
3349 if (m_is_safe_panel)
return;
3352 if (enabled) NotifySetupOptionsPlugin(&m_plugin);
3353 if (!enabled && !m_bSelected) {
3354 SetWindowFontStyle(m_pName, wxFONTSTYLE_ITALIC);
3355 SetWindowFontStyle(m_pVersion, wxFONTSTYLE_ITALIC);
3356 SetWindowFontStyle(m_pDescription, wxFONTSTYLE_ITALIC);
3359 m_pVersion->Disable();
3360 m_pDescription->Disable();
3363 SetWindowFontStyle(m_pName, wxFONTSTYLE_NORMAL);
3364 SetWindowFontStyle(m_pVersion, wxFONTSTYLE_NORMAL);
3365 SetWindowFontStyle(m_pDescription, wxFONTSTYLE_NORMAL);
3368 m_pVersion->Enable();
3369 m_pDescription->Enable();
3374 m_pName->Enable(enabled || m_bSelected);
3375 m_pVersion->Enable(enabled || m_bSelected);
3376 m_pDescription->Enable(enabled || m_bSelected);
3380 wxString description = m_plugin.m_long_description;
3381 if (description.IsEmpty())
3382 description = wxString(m_plugin.m_managed_metadata.description.c_str());
3386 m_pDescription->SetLabel(wrapper.GetWrapped());
3387 if (m_plugin.m_managed_metadata.info_url.size()) {
3388 m_info_btn->SetURL(m_plugin.m_managed_metadata.info_url.c_str());
3392 wxString description = m_plugin.m_short_description;
3393 if (description.IsEmpty())
3394 description = wxString(m_plugin.m_managed_metadata.summary.c_str());
3397 m_pDescription->SetLabel(wrapper.GetWrapped());
3400 m_pButtonPreferences->Enable(enabled &&
3402 m_cbEnable->SetValue(enabled);
3405void PluginPanel::OnPluginUp(wxCommandEvent& event) {
3406 m_PluginListPanel->MoveUp(
this);
3409void PluginPanel::OnPluginDown(wxCommandEvent& event) {
3410 m_PluginListPanel->MoveDown(
this);
3415 : wxPanel(parent), m_url(url) {
3416 auto vbox =
new wxBoxSizer(wxVERTICAL);
3417 auto button =
new wxButton(
this, wxID_ANY, _(
"Website"));
3418 button->Enable(strlen(url) > 0);
3421 Bind(wxEVT_COMMAND_BUTTON_CLICKED,
3422 [=](wxCommandEvent&) { wxLaunchDefaultBrowser(m_url); });
3430PlugInChartBase::PlugInChartBase() { m_Chart_Error_Factor = 0.; }
3432PlugInChartBase::~PlugInChartBase() {}
3441 bool b_allow_overzoom) {
3453 const wxRegion& Region) {
3454 return wxNullBitmap;
3463 wxRegion* pValidRegion) {}
3476 wxRect* pSourceRect) {}
3493 double* plat,
double* plon) {}
3500PlugInChartBaseGL::PlugInChartBaseGL() {}
3502PlugInChartBaseGL::~PlugInChartBaseGL() {}
3506 const wxRegion& Region,
3507 bool b_use_stencil) {
3533PlugInChartBaseExtended::PlugInChartBaseExtended() {}
3535PlugInChartBaseExtended::~PlugInChartBaseExtended() {}
3539 const wxRegion& Region,
3540 bool b_use_stencil) {
3546 const wxRegion& Region,
bool b_use_stencil) {
3552 const wxRegion& Region,
bool b_use_stencil) {
3558 return wxNullBitmap;
3562 wxMemoryDC& dc,
const PlugIn_ViewPort& VPoint,
const wxRegion& Region) {
3566ListOfPI_S57Obj* PlugInChartBaseExtended::GetObjRuleListAtLatLon(
3571wxString PlugInChartBaseExtended::CreateObjDescriptions(
3572 ListOfPI_S57Obj* obj_list) {
3576int PlugInChartBaseExtended::GetNoCOVREntries() {
return 0; }
3578int PlugInChartBaseExtended::GetNoCOVRTablePoints(
int iTable) {
return 0; }
3580int PlugInChartBaseExtended::GetNoCOVRTablenPoints(
int iTable) {
return 0; }
3582float* PlugInChartBaseExtended::GetNoCOVRTableHead(
int iTable) {
return 0; }
3591PlugInChartBaseExtendedPlus2::PlugInChartBaseExtendedPlus2() {}
3593PlugInChartBaseExtendedPlus2::~PlugInChartBaseExtendedPlus2() {}
3596PlugInChartBaseExtendedPlus2::GetLightsObjRuleListVisibleAtLatLon(
3606PlugInChartBaseGLPlus2::PlugInChartBaseGLPlus2() {}
3608PlugInChartBaseGLPlus2::~PlugInChartBaseGLPlus2() {}
3620ChartPlugInWrapper::ChartPlugInWrapper() {}
3622ChartPlugInWrapper::ChartPlugInWrapper(
const wxString& chart_class) {
3623 m_ppo = ::wxCreateDynamicObject(chart_class);
3627ChartPlugInWrapper::~ChartPlugInWrapper() {
3628 if (m_ppicb)
delete m_ppicb;
3631wxString ChartPlugInWrapper::GetFileSearchMask() {
3638InitReturn ChartPlugInWrapper::Init(
const wxString& name,
3639 ChartInitFlag init_flags) {
3641 wxWindow* pa = wxWindow::FindFocus();
3643 InitReturn ret_val = (InitReturn)m_ppicb->
Init(name, (
int)init_flags);
3647 if (ret_val == INIT_OK) {
3654 m_ID = m_ppicb->
GetID();
3658 m_SE = m_ppicb->
GetSE();
3672 if ((fabs(m_Chart_Skew) < .01) &&
3673 (CHART_FAMILY_RASTER == m_ChartFamily)) {
3675 if (GetChartExtent(&extent)) {
3676 double lon_range = extent.ELON - extent.WLON;
3677 if ((lon_range > 0) &&
3679 m_ppm_avg = GetSize_X() / (lon_range * 1852 * 60);
3683 m_overlayENC =
false;
3685 wxCharBuffer buf = m_FullPath.ToUTF8();
3686 m_overlayENC = s57chart::IsCellOverlayType(buf.data());
3692 m_ChartType = CHART_TYPE_UNKNOWN;
3693 m_ChartFamily = CHART_FAMILY_UNKNOWN;
3699 if (pc) pc->SetFocus();
3703 return INIT_FAIL_REMOVE;
3707int ChartPlugInWrapper::GetCOVREntries() {
3714int ChartPlugInWrapper::GetCOVRTablePoints(
int iTable) {
3721int ChartPlugInWrapper::GetCOVRTablenPoints(
int iTable) {
3728float* ChartPlugInWrapper::GetCOVRTableHead(
int iTable) {
3740int ChartPlugInWrapper::GetNoCOVREntries() {
3750int ChartPlugInWrapper::GetNoCOVRTablePoints(
int iTable) {
3760int ChartPlugInWrapper::GetNoCOVRTablenPoints(
int iTable) {
3770float* ChartPlugInWrapper::GetNoCOVRTableHead(
int iTable) {
3780bool ChartPlugInWrapper::GetChartExtent(
Extent* pext) {
3784 pext->NLAT = xpi.
NLAT;
3785 pext->SLAT = xpi.
SLAT;
3786 pext->ELON = xpi.
ELON;
3787 pext->WLON = xpi.
WLON;
3796ThumbData* ChartPlugInWrapper::GetThumbData(
int tnx,
int tny,
float lat,
3801 if (!pThumbData->pDIBThumb) {
3802 wxBitmap* pBMPOwnedByChart =
3803 m_ppicb->
GetThumbnail(tnx, tny, m_global_color_scheme);
3804 if (pBMPOwnedByChart) {
3805 wxImage img = pBMPOwnedByChart->ConvertToImage();
3806 pThumbData->pDIBThumb =
new wxBitmap(img);
3808 pThumbData->pDIBThumb = NULL;
3811 pThumbData->Thumb_Size_X = tnx;
3812 pThumbData->Thumb_Size_Y = tny;
3839 pThumbData->ShipX = 0;
3840 pThumbData->ShipY = 0;
3847ThumbData* ChartPlugInWrapper::GetThumbData() {
return pThumbData; }
3849bool ChartPlugInWrapper::UpdateThumbData(
double lat,
double lon) {
3853double ChartPlugInWrapper::GetNormalScaleMin(
double canvas_scale_factor,
3854 bool b_allow_overzoom) {
3861double ChartPlugInWrapper::GetNormalScaleMax(
double canvas_scale_factor,
3883void RenderRotateToViewPort(
const ViewPort& VPoint) {
3884#ifndef USE_ANDROID_GLES2
3886 glTranslatef(xt, yt, 0);
3887 glRotatef(VPoint.
rotation * 180. / PI, 0, 0, 1);
3888 glTranslatef(-xt, -yt, 0);
3892void UndoRenderRotateToViewPort(
const ViewPort& VPoint) {
3893#ifndef USE_ANDROID_GLES2
3895 glTranslatef(xt, yt, 0);
3896 glRotatef(-VPoint.
rotation * 180. / PI, 0, 0, 1);
3897 glTranslatef(-xt, -yt, 0);
3901bool ChartPlugInWrapper::RenderRegionViewOnGL(
const wxGLContext& glc,
3904 const LLRegion& Region) {
3913 if (!Region.Empty() && (ppicb_gl || ppicb_x)) {
3914 wxRegion* r = RectRegion.GetNew_wxRegion();
3917 LLRegion chart_region = vp.GetLLRegion(upd.GetRect());
3918 chart_region.Intersect(Region);
3920 if (!chart_region.Empty()) {
3921 ViewPort cvp = glChartCanvas::ClippedViewport(VPoint, chart_region);
3923 glChartCanvas::SetClipRect(cvp, upd.GetRect(),
false);
3927#ifndef USE_ANDROID_GLES2
3930 RenderRotateToViewPort(VPoint);
3935 glChartCanvas::s_b_useStencil);
3938 glChartCanvas::s_b_useStencil);
3939 UndoRenderRotateToViewPort(VPoint);
3941#ifndef USE_ANDROID_GLES2
3944 glChartCanvas::DisableClipRegion();
3958bool ChartPlugInWrapper::RenderRegionViewOnGLNoText(
3959 const wxGLContext& glc,
const ViewPort& VPoint,
3960 const OCPNRegion& RectRegion,
const LLRegion& Region) {
3969 if (!Region.Empty() && ppicb_x) {
3971 glChartCanvas::SetClipRect(VPoint, VPoint.rv_rect,
false);
3972 glChartCanvas::DisableClipRegion();
3975 RenderRotateToViewPort(VPoint);
3978 wxRegion* r = RectRegion.GetNew_wxRegion();
3981 glChartCanvas::s_b_useStencil);
3984 UndoRenderRotateToViewPort(VPoint);
3989 else if (!Region.Empty() &&
3993 wxRegion* r = RectRegion.GetNew_wxRegion();
3996 LLRegion chart_region = vp.GetLLRegion(upd.GetRect());
3997 chart_region.Intersect(Region);
3999 if (!chart_region.Empty()) {
4000 ViewPort cvp = glChartCanvas::ClippedViewport(VPoint, chart_region);
4002 glChartCanvas::SetClipRect(cvp, upd.GetRect(),
false);
4004 RenderRotateToViewPort(VPoint);
4008 glChartCanvas::s_b_useStencil);
4011 UndoRenderRotateToViewPort(VPoint);
4013 glChartCanvas::DisableClipRegion();
4026bool ChartPlugInWrapper::RenderRegionViewOnGLTextOnly(
4033 if (!Region.Empty() && ppicb_x) {
4034 wxRegion* r = Region.GetNew_wxRegion();
4036#ifndef USE_ANDROID_GLES2
4039 RenderRotateToViewPort(VPoint);
4043 glChartCanvas::s_b_useStencil);
4044 UndoRenderRotateToViewPort(VPoint);
4046#ifndef USE_ANDROID_GLES2
4059bool ChartPlugInWrapper::RenderRegionViewOnDC(wxMemoryDC& dc,
4065 if (Region.IsOk()) {
4066 wxRegion* r = Region.GetNew_wxRegion();
4073 wxColour nodat = GetGlobalColor(_T (
"NODTA" ));
4074 wxColour nodat_sub = nodat;
4076#ifdef ocpnUSE_ocpnBitmap
4077 nodat_sub = wxColour(nodat.Blue(), nodat.Green(), nodat.Red());
4079 m_pMask =
new wxMask(obmp, nodat_sub);
4080 obmp.SetMask(m_pMask);
4082 dc.SelectObject(obmp);
4093bool ChartPlugInWrapper::RenderRegionViewOnDCNoText(wxMemoryDC& dc,
4104 if (Region.IsOk() && (pCBx || ppicb)) {
4105 wxRegion* r = Region.GetNew_wxRegion();
4120bool ChartPlugInWrapper::RenderRegionViewOnDCTextOnly(
4123 bool ret_val =
false;
4126 if (Region.IsOk()) {
4127 wxRegion* r = Region.GetNew_wxRegion();
4141void ChartPlugInWrapper::ClearPLIBTextList() {
4149bool ChartPlugInWrapper::AdjustVP(
ViewPort& vp_last,
ViewPort& vp_proposed) {
4153 return m_ppicb->
AdjustVP(pivp_last, pivp_proposed);
4158void ChartPlugInWrapper::GetValidCanvasRegion(
const ViewPort& VPoint,
4173void ChartPlugInWrapper::SetColorScheme(ColorScheme cs,
bool bApplyImmediate) {
4177 m_global_color_scheme = cs;
4179 if (pThumbData) pThumbData->pDIBThumb = NULL;
4183 double target_scale_ppm) {
4190void ChartPlugInWrapper::ComputeSourceRectangle(
const ViewPort& VPoint,
4191 wxRect* pSourceRect) {
4198double ChartPlugInWrapper::GetRasterScaleFactor(
const ViewPort& vp) {
4200 return (wxRound(100000 * GetPPM() / vp.
view_scale_ppm)) / 100000.;
4205bool ChartPlugInWrapper::GetChartBits(wxRect& source,
unsigned char* pPix,
4207 wxCriticalSectionLocker locker(m_critSect);
4216int ChartPlugInWrapper::GetSize_X() {
4223int ChartPlugInWrapper::GetSize_Y() {
4230void ChartPlugInWrapper::latlong_to_chartpix(
double lat,
double lon,
4231 double& pixx,
double& pixy) {
4235void ChartPlugInWrapper::chartpix_to_latlong(
double pixx,
double pixy,
4236 double* plat,
double* plon) {
4251 return toSDMM(NEflag, a, hi_precision);
4255 return GetGlobalColor(colorName);
4259 const wxString& caption,
int style,
int x,
int y) {
4260 return OCPNMessageBox(parent, message, caption, style, 100, x, y);
4268 return g_Platform->GetWritableDocumentsDir();
4273 auto loader = PluginLoader::GetInstance();
4274 for (
unsigned int i = 0; i < loader->GetPlugInArray()->GetCount(); i++) {
4276 if (pic->m_pplugin == pplugin) {
4286ListOfPI_S57Obj* PlugInManager::GetPlugInObjRuleListAtLatLon(
4289 ListOfPI_S57Obj* list = NULL;
4303 list = picbx->GetObjRuleListAtLatLon(zlat, zlon, SelectRadius, &pi_vp);
4313 ListOfPI_S57Obj* rule_list) {
4324 ret_str = picbx->CreateObjDescriptions(rule_list);
4338 return ps52plib->m_nDepthUnitDisplay;
4345 return ps52plib->m_nSymbolStyle;
4352 return ps52plib->m_nBoundaryStyle;
4362 CreateCompatibleS57Object(pObj, &cobj, &ctx);
4364 ViewPort cvp = CreateCompatibleViewport(*vp);
4369 ObjRazRules rzRules;
4370 rzRules.obj = &cobj;
4371 rzRules.LUP = pContext->LUP;
4372 rzRules.sm_transform_parms = 0;
4373 rzRules.child = NULL;
4374 rzRules.next = NULL;
4376 if (pContext->LUP) {
4377 ps52plib->SetVPointCompat(
4381 ps52plib->PrepareForRender();
4383 return ps52plib->ObjectRenderCheck(&rzRules);
4392 return ps52plib->GetStateHash();
4397void CreateCompatibleS57Object(
PI_S57Obj* pObj, S57Obj* cobj,
4398 chart_context* pctx) {
4401 cobj->att_array = pObj->att_array;
4402 cobj->attVal = pObj->attVal;
4403 cobj->n_attr = pObj->n_attr;
4408 cobj->npt = pObj->npt;
4410 cobj->iOBJL = pObj->iOBJL;
4411 cobj->Index = pObj->Index;
4413 cobj->geoPt = (pt*)pObj->geoPt;
4414 cobj->geoPtz = pObj->geoPtz;
4415 cobj->geoPtMulti = pObj->geoPtMulti;
4417 cobj->m_lat = pObj->m_lat;
4418 cobj->m_lon = pObj->m_lon;
4420 cobj->m_DisplayCat = (DisCat)pObj->m_DisplayCat;
4421 cobj->x_rate = pObj->x_rate;
4422 cobj->y_rate = pObj->y_rate;
4423 cobj->x_origin = pObj->x_origin;
4424 cobj->y_origin = pObj->y_origin;
4426 cobj->Scamin = pObj->Scamin;
4427 cobj->nRef = pObj->nRef;
4428 cobj->bIsAton = pObj->bIsAton;
4429 cobj->bIsAssociable = pObj->bIsAssociable;
4431 cobj->m_n_lsindex = pObj->m_n_lsindex;
4432 cobj->m_lsindex_array = pObj->m_lsindex_array;
4433 cobj->m_n_edge_max_points = pObj->m_n_edge_max_points;
4436 cobj->m_ls_list_legacy =
4440 cobj->m_ls_list_legacy = 0;
4441 cobj->m_ls_list = 0;
4444 cobj->m_bcategory_mutable = pObj->m_bcategory_mutable;
4446 cobj->m_bcategory_mutable =
true;
4450 if (pObj->m_DPRI == -1) {
4452 if (pCtx->LUP) cobj->m_DPRI = pCtx->LUP->DPRI -
'0';
4454 cobj->m_DPRI = pObj->m_DPRI;
4457 cobj->pPolyTessGeo = (PolyTessGeo*)pObj->pPolyTessGeo;
4458 cobj->m_chart_context = (chart_context*)pObj->m_chart_context;
4460 if (pObj->auxParm3 != 1234) {
4461 pObj->auxParm3 = 1234;
4462 pObj->auxParm0 = -99;
4465 cobj->auxParm0 = pObj->auxParm0;
4472 if (pContext->bBBObj_valid)
4474 cobj->BBObj.Set(pContext->BBObj.GetMinY(), pContext->BBObj.GetMinX(),
4475 pContext->BBObj.GetMaxY(), pContext->BBObj.GetMaxX());
4477 cobj->CSrules = pContext->CSrules;
4478 cobj->bCS_Added = pContext->bCS_Added;
4480 cobj->FText = pContext->FText;
4481 cobj->bFText_Added = pContext->bFText_Added;
4482 cobj->rText = pContext->rText;
4484 cobj->bIsClone =
true;
4487 cobj->m_chart_context = pctx;
4488 chart_context* ppctx = (chart_context*)pObj->m_chart_context;
4491 cobj->m_chart_context->m_pvc_hash = ppctx->m_pvc_hash;
4492 cobj->m_chart_context->m_pve_hash = ppctx->m_pve_hash;
4493 cobj->m_chart_context->ref_lat = ppctx->ref_lat;
4494 cobj->m_chart_context->ref_lon = ppctx->ref_lon;
4495 cobj->m_chart_context->pFloatingATONArray = ppctx->pFloatingATONArray;
4496 cobj->m_chart_context->pRigidATONArray = ppctx->pRigidATONArray;
4497 cobj->m_chart_context->safety_contour = ppctx->safety_contour;
4498 cobj->m_chart_context->vertex_buffer = ppctx->vertex_buffer;
4500 cobj->m_chart_context->chart =
4502 cobj->m_chart_context->chart_type = S52_CHART_TYPE_PLUGIN;
4516 CreateCompatibleS57Object(pObj, &cobj, NULL);
4518 LUPname LUP_Name = PAPER_CHART;
4521 ctx->CSrules = NULL;
4522 ctx->bCS_Added =
false;
4525 if (ctx->bFText_Added) {
4526 ctx->bFText_Added =
false;
4532 ctx->bBBObj_valid =
true;
4537 switch (cobj.Primitive_type) {
4542 if (PAPER_CHART == ps52plib->m_nSymbolStyle)
4543 LUP_Name = PAPER_CHART;
4545 LUP_Name = SIMPLIFIED;
4554 if (PLAIN_BOUNDARIES == ps52plib->m_nBoundaryStyle)
4555 LUP_Name = PLAIN_BOUNDARIES;
4557 LUP_Name = SYMBOLIZED_BOUNDARIES;
4562 LUPrec* lup = ps52plib->S52_LUPLookup(LUP_Name, cobj.FeatureName, &cobj);
4566 ps52plib->_LUP2rules(lup, &cobj);
4568 ctx->MPSRulesList = NULL;
4576 pContext->bBBObj_valid =
true;
4582void UpdatePIObjectPlibContext(
PI_S57Obj* pObj, S57Obj* cobj,
4583 ObjRazRules* rzRules) {
4587 pContext->CSrules = cobj->CSrules;
4588 pContext->bCS_Added = cobj->bCS_Added;
4590 pContext->FText = cobj->FText;
4591 pContext->bFText_Added = cobj->bFText_Added;
4592 pContext->rText = cobj->rText;
4594 if (cobj->BBObj.GetValid()) {
4597 BoundingBox(cobj->BBObj.GetMinLon(), cobj->BBObj.GetMinLat(),
4598 cobj->BBObj.GetMaxLon(), cobj->BBObj.GetMaxLat());
4599 pContext->bBBObj_valid =
true;
4604 pObj->m_DisplayCat = (
PI_DisCat)cobj->m_DisplayCat;
4608 pContext->ChildRazRules = rzRules->child;
4609 pContext->MPSRulesList = rzRules->mps;
4611 pObj->auxParm0 = cobj->auxParm0;
4615 double* lon_min,
double* lon_max) {
4618 if (lat_min) *lat_min = pContext->BBObj.GetMinY();
4619 if (lat_max) *lat_max = pContext->BBObj.GetMaxY();
4620 if (lon_min) *lon_min = pContext->BBObj.GetMinX();
4621 if (lon_max) *lon_max = pContext->BBObj.GetMaxX();
4622 return pContext->bBBObj_valid;
4630 LUPrec* lup = pContext->LUP;
4639 LUPrec* lup = pContext->LUP;
4649 LUPrec* lup = pContext->LUP;
4655 return S52_getMarinerParam(S52_MAR_SAFETY_CONTOUR);
4662 CreateCompatibleS57Object(pObj, &cobj, &ctx);
4667 ObjRazRules rzRules;
4668 rzRules.obj = &cobj;
4669 rzRules.LUP = pContext->LUP;
4670 rzRules.sm_transform_parms = 0;
4671 rzRules.child = NULL;
4672 rzRules.next = NULL;
4673 rzRules.mps = pContext->MPSRulesList;
4675 if (pContext->LUP) {
4676 ps52plib->SetLineFeaturePriority(&rzRules, prio);
4679 UpdatePIObjectPlibContext(pObj, &cobj, &rzRules);
4685 ps52plib->PrepareForRender();
4686 ps52plib->ClearTextList();
4689 ps52plib->EnableGLLS(
true);
4691 ps52plib->EnableGLLS(
false);
4700 if (pctx->ChildRazRules) {
4701 ObjRazRules* ctop = pctx->ChildRazRules;
4705 if (ps52plib) ps52plib->DestroyLUP(ctop->LUP);
4707 ObjRazRules* cnxx = ctop->next;
4713 if (pctx->MPSRulesList) {
4714 if (ps52plib && pctx->MPSRulesList->cs_rules) {
4715 for (
unsigned int i = 0; i < pctx->MPSRulesList->cs_rules->GetCount();
4717 Rules* top = pctx->MPSRulesList->cs_rules->Item(i);
4718 ps52plib->DestroyRulesChain(top);
4720 delete pctx->MPSRulesList->cs_rules;
4722 free(pctx->MPSRulesList);
4734 CreateCompatibleS57Object(pObj, &cobj, &ctx);
4741 &transform.easting_vp_center, &transform.northing_vp_center);
4744 ObjRazRules rzRules;
4745 rzRules.obj = &cobj;
4746 rzRules.LUP = pContext->LUP;
4747 rzRules.sm_transform_parms = &transform;
4748 rzRules.child = pContext->ChildRazRules;
4749 rzRules.next = NULL;
4750 rzRules.mps = pContext->MPSRulesList;
4752 if (pContext->LUP) {
4753 ViewPort cvp = CreateCompatibleViewport(*vp);
4759 cvp.rv_rect, cvp.GetBBox(), cvp.
ref_scale,
4761 ps52plib->PrepareForRender();
4763 ps52plib->RenderObjectToDC(pdc, &rzRules);
4766 UpdatePIObjectPlibContext(pObj, &cobj, &rzRules);
4773 wxRect rect,
unsigned char* pixbuf) {
4775 render_canvas_parms pb_spec;
4777 pb_spec.depth = BPP;
4778 pb_spec.pb_pitch = ((rect.width * pb_spec.depth / 8));
4779 pb_spec.lclip = rect.x;
4780 pb_spec.rclip = rect.x + rect.width - 1;
4781 pb_spec.pix_buff = pixbuf;
4782 pb_spec.width = rect.width;
4783 pb_spec.height = rect.height;
4786#ifdef ocpnUSE_ocpnBitmap
4787 pb_spec.b_revrgb =
true;
4789 pb_spec.b_revrgb =
false;
4792 pb_spec.b_revrgb =
false;
4797 CreateCompatibleS57Object(pObj, &cobj, &ctx);
4804 &transform.easting_vp_center, &transform.northing_vp_center);
4807 ObjRazRules rzRules;
4808 rzRules.obj = &cobj;
4809 rzRules.LUP = pContext->LUP;
4810 rzRules.sm_transform_parms = &transform;
4811 rzRules.child = pContext->ChildRazRules;
4812 rzRules.next = NULL;
4813 rzRules.mps = pContext->MPSRulesList;
4815 ViewPort cvp = CreateCompatibleViewport(*vp);
4823 if (!tess)
return 1;
4825 PolyTriGroup* ptg =
new PolyTriGroup;
4826 ptg->tri_prim_head =
4827 tess->Get_PolyTriGroup_head()->tri_prim_head;
4828 ptg->bsingle_alloc =
false;
4829 ptg->data_type = DATA_TYPE_DOUBLE;
4830 tess->Set_PolyTriGroup_head(ptg);
4832 double* pd = (
double*)malloc(
sizeof(
double));
4837 if (pContext->LUP) {
4842 cvp.rv_rect, cvp.GetBBox(), cvp.
ref_scale,
4844 ps52plib->PrepareForRender();
4846 ps52plib->RenderAreaToDC(pdc, &rzRules, &pb_spec);
4849 UpdatePIObjectPlibContext(pObj, &cobj, &rzRules);
4861 CreateCompatibleS57Object(pObj, &cobj, &ctx);
4872 if (!tess)
return 1;
4876 ptg->tri_prim_head = tess->Get_PolyTriGroup_head()->tri_prim_head;
4877 ptg->bsingle_alloc =
false;
4878 ptg->data_type = DATA_TYPE_DOUBLE;
4879 tess->Set_PolyTriGroup_head(ptg);
4883 double* pd = (
double*)malloc(
sizeof(
double));
4900 &transform.easting_vp_center, &transform.northing_vp_center);
4903 ObjRazRules rzRules;
4904 rzRules.obj = &cobj;
4905 rzRules.LUP = pContext->LUP;
4906 rzRules.sm_transform_parms = &transform;
4907 rzRules.child = pContext->ChildRazRules;
4908 rzRules.next = NULL;
4909 rzRules.mps = pContext->MPSRulesList;
4911 if (pContext->LUP) {
4912 ViewPort cvp = CreateCompatibleViewport(*vp);
4918 cvp.rv_rect, cvp.GetBBox(), cvp.
ref_scale,
4920 ps52plib->PrepareForRender();
4922 ps52plib->RenderAreaToGL(glcc, &rzRules);
4925 UpdatePIObjectPlibContext(pObj, &cobj, &rzRules);
4937 CreateCompatibleS57Object(pObj, &cobj, &ctx);
4944 &transform.easting_vp_center, &transform.northing_vp_center);
4947 ObjRazRules rzRules;
4948 rzRules.obj = &cobj;
4949 rzRules.LUP = pContext->LUP;
4950 rzRules.sm_transform_parms = &transform;
4951 rzRules.child = pContext->ChildRazRules;
4952 rzRules.next = NULL;
4953 rzRules.mps = pContext->MPSRulesList;
4955 if (pContext->LUP) {
4956 ViewPort cvp = CreateCompatibleViewport(*vp);
4962 cvp.rv_rect, cvp.GetBBox(), cvp.
ref_scale,
4964 ps52plib->PrepareForRender();
4966 ps52plib->RenderObjectToGL(glcc, &rzRules);
4969 UpdatePIObjectPlibContext(pObj, &cobj, &rzRules);
4979OCPN_downloadEvent::OCPN_downloadEvent(wxEventType commandType,
int id)
4980 : wxEvent(id, commandType) {
4983 m_b_complete =
false;
4987OCPN_downloadEvent::~OCPN_downloadEvent() {}
4989wxEvent* OCPN_downloadEvent::Clone()
const {
4991 newevent->m_stat = this->m_stat;
4992 newevent->m_condition = this->m_condition;
4994 newevent->m_totalBytes = this->m_totalBytes;
4995 newevent->m_sofarBytes = this->m_sofarBytes;
4996 newevent->m_b_complete = this->m_b_complete;
5002DECL_EXP wxEventType wxEVT_DOWNLOAD_EVENT = wxNewEventType();
5007#define DL_EVENT_TIMER 4388
5015 void setBackgroundMode(
long ID, wxEvtHandler* handler);
5016 void clearBackgroundMode();
5017 void onTimerEvent(wxTimerEvent& event);
5020 wxTimer m_eventTimer;
5021 wxEvtHandler* m_download_evHandler;
5027PI_DLEvtHandler::PI_DLEvtHandler() {
5031 m_download_evHandler = NULL;
5037PI_DLEvtHandler::~PI_DLEvtHandler() {
5038 m_eventTimer.Stop();
5041 (wxObjectEventFunction)(wxEventFunction)&PI_DLEvtHandler::onTimerEvent);
5048 g_download_status =
event.getDLEventStatus();
5049 g_download_condition =
event.getDLEventCondition();
5052 if (m_download_evHandler &&
5055 ev.setComplete(
true);
5056 ev.setTransferred(m_sofarBytes);
5057 ev.setTotal(m_totalBytes);
5059 ev.setDLEventStatus(event.getDLEventStatus());
5062 m_download_evHandler->AddPendingEvent(ev);
5063 m_eventTimer.Stop();
5065 finishAndroidFileDownload();
5072void PI_DLEvtHandler::setBackgroundMode(
long ID, wxEvtHandler* handler) {
5074 m_download_evHandler = handler;
5076 m_eventTimer.SetOwner(
this, DL_EVENT_TIMER);
5080 (wxObjectEventFunction)(wxEventFunction)&PI_DLEvtHandler::onTimerEvent);
5081 m_eventTimer.Start(1000, wxTIMER_CONTINUOUS);
5084void PI_DLEvtHandler::clearBackgroundMode() {
5085 m_download_evHandler = NULL;
5086 m_eventTimer.Stop();
5089void PI_DLEvtHandler::onTimerEvent(wxTimerEvent& event) {
5095 int stat = queryAndroidFileDownload(m_id, &sstat);
5098 long sofarBytes = 0;
5099 long totalBytes = -1;
5103 qDebug() <<
"Error on queryAndroidFileDownload, ending download";
5104 ev.setComplete(
true);
5105 ev.setTransferred(sofarBytes);
5106 ev.setTotal(totalBytes);
5111 wxStringTokenizer tk(sstat,
";");
5112 if (tk.HasMoreTokens()) {
5113 wxString token = tk.GetNextToken();
5114 token.ToLong(&state);
5115 token = tk.GetNextToken();
5116 token.ToLong(&sofarBytes);
5117 token = tk.GetNextToken();
5118 token.ToLong(&totalBytes);
5121 qDebug() << state << sofarBytes << totalBytes;
5123 m_sofarBytes = sofarBytes;
5124 m_totalBytes = totalBytes;
5126 ev.setTransferred(sofarBytes);
5127 ev.setTotal(totalBytes);
5130 qDebug() <<
"Event OCPN_DL_FAILED/OCPN_DL_EVENT_TYPE_END";
5131 ev.setComplete(
true);
5134 }
else if (state == 8) {
5135 qDebug() <<
"Event OCPN_DL_NO_ERROR/OCPN_DL_EVENT_TYPE_END";
5136 ev.setComplete(
true);
5140 ev.setComplete(
false);
5148 if (m_download_evHandler) {
5150 m_download_evHandler->AddPendingEvent(ev);
5155 m_eventTimer.Stop();
5156 finishAndroidFileDownload();
5166 const wxString& outputFile,
5167 const wxString& title,
const wxString& message,
5168 const wxBitmap& bitmap, wxWindow* parent,
5169 long style,
int timeout_secs) {
5172 wxString msg =
"Downloading file synchronously: ";
5179 int vres = validateAndroidWriteLocation(outputFile);
5191 g_piEventHandler->Connect(
5192 wxEVT_DOWNLOAD_EVENT,
5193 (wxObjectEventFunction)(wxEventFunction)&PI_DLEvtHandler::onDLEvent);
5198 wxString fURI = outputFile;
5199 if (!fURI.StartsWith(
"file://")) {
5200 fURI.Prepend(
"file://");
5203 int res = startAndroidFileDownload(url, fURI, g_piEventHandler, &dl_ID);
5206 finishAndroidFileDownload();
5207 g_piEventHandler->Disconnect(
5208 wxEVT_DOWNLOAD_EVENT,
5209 (wxObjectEventFunction)(wxEventFunction)&PI_DLEvtHandler::onDLEvent);
5214 wxDateTime dl_start_time = wxDateTime::Now();
5218 wxTimeSpan dt = wxDateTime::Now() - dl_start_time;
5219 qDebug() <<
"Spin.." << dt.GetSeconds().GetLo();
5221 if (dt.GetSeconds() > timeout_secs) {
5222 qDebug() <<
"USER_TIMOUT";
5223 finishAndroidFileDownload();
5224 g_piEventHandler->Disconnect(
5225 wxEVT_DOWNLOAD_EVENT,
5226 (wxObjectEventFunction)(wxEventFunction)&PI_DLEvtHandler::onDLEvent);
5234 finishAndroidFileDownload();
5235 g_piEventHandler->Disconnect(
5236 wxEVT_DOWNLOAD_EVENT,
5240 qDebug() <<
"RETURN DL_END" << (int)ss;
5246 int stat = queryAndroidFileDownload(dl_ID, &sstat);
5248 qDebug() <<
"Error on queryAndroidFileDownload";
5249 finishAndroidFileDownload();
5250 g_piEventHandler->Disconnect(
5251 wxEVT_DOWNLOAD_EVENT,
5252 (wxObjectEventFunction)(wxEventFunction)&PI_DLEvtHandler::onDLEvent);
5262#elif defined(OCPN_USE_CURL)
5263 wxFileName tfn = wxFileName::CreateTempFileName(outputFile);
5264 wxFileOutputStream output(tfn.GetFullPath());
5266 wxCurlDownloadDialog ddlg(url, &output, title, message + url, bitmap, parent,
5268 wxCurlDialogReturnFlag ret = ddlg.RunModal();
5274 case wxCDRF_SUCCESS: {
5275 if (wxCopyFile(tfn.GetFullPath(), outputFile))
5281 case wxCDRF_FAILED: {
5285 case wxCDRF_USER_ABORTED: {
5293 if (wxFileExists(tfn.GetFullPath())) wxRemoveFile(tfn.GetFullPath());
5303 return ocpn::toUsrDateTimeFormat(date_time,
options);
5308 const wxString& outputFile,
5309 wxEvtHandler* handler,
5312 wxString msg =
"Downloading file asynchronously: ";
5324 int res = startAndroidFileDownload(url, outputFile, NULL ,
5328 finishAndroidFileDownload();
5333 g_piEventHandler->setBackgroundMode(dl_ID, handler);
5335 if (handle) *handle = dl_ID;
5339#elif defined(OCPN_USE_CURL)
5346 bool http = (url.StartsWith(wxS(
"http:")) || url.StartsWith(wxS(
"https:")));
5349 dynamic_cast<wxCurlHTTP*
>(
g_pi_manager->m_pCurl.get())) {
5356 bool failed =
false;
5365 new wxFileOutputStream(outputFile)),
5373 wxCurlThreadError err =
g_pi_manager->m_pCurlThread->Download();
5374 if (err != wxCTE_NO_ERROR) {
5388 delete (
g_pi_manager->m_pCurlThread->GetOutputStream());
5406 cancelAndroidFileDownload(handle);
5407 finishAndroidFileDownload();
5408 if (g_piEventHandler) g_piEventHandler->clearBackgroundMode();
5412 delete (
g_pi_manager->m_pCurlThread->GetOutputStream());
5423 const wxString& parameters, wxString& result,
5426 wxString lparms = parameters;
5427 wxString postResult = doAndroidPOST(url, lparms, timeout_secs * 1000);
5430 result = postResult;
5433#elif defined(OCPN_USE_CURL)
5435 post.SetOpt(CURLOPT_TIMEOUT, timeout_secs);
5436 size_t res = post.Post(parameters.ToAscii(), parameters.Len(), url);
5439 result = wxString(post.GetResponseBody().c_str(), wxConvUTF8);
5442 result = wxEmptyString;
5453 return androidCheckOnline();
5456#if !defined(__ANDROID__) && defined(OCPN_USE_CURL)
5457 if (wxDateTime::GetTimeNow() >
5458 g_pi_manager->m_last_online_chk + ONLINE_CHECK_RETRY) {
5460 get.Head(
"http://yahoo.com/");
5461 g_pi_manager->m_last_online = get.GetResponseCode() > 0;
5463 g_pi_manager->m_last_online_chk = wxDateTime::GetTimeNow();
5471#if !defined(__ANDROID__) && defined(OCPN_USE_CURL)
5472void PlugInManager::OnEndPerformCurlDownload(wxCurlEndPerformEvent& ev) {
5474 if (ev.IsSuccessful()) {
5481 event.setComplete(
true);
5483 if (m_download_evHandler) {
5484 m_download_evHandler->AddPendingEvent(event);
5485 m_download_evHandler = NULL;
5486 m_downloadHandle = NULL;
5489 if (m_pCurlThread) {
5490 m_pCurlThread->Wait();
5491 if (!m_pCurlThread->IsAborting()) {
5492 delete (m_pCurlThread->GetOutputStream());
5493 wxDELETE(m_pCurlThread);
5498void PlugInManager::OnCurlDownload(wxCurlDownloadEvent& ev) {
5502 event.setTotal(ev.GetTotalBytes());
5503 event.setTransferred(ev.GetDownloadedBytes());
5504 event.setComplete(
false);
5506 if (m_download_evHandler) {
5507 m_download_evHandler->AddPendingEvent(event);
5511bool PlugInManager::HandleCurlThreadError(wxCurlThreadError err,
5512 wxCurlBaseThread* p,
5513 const wxString& url) {
5515 case wxCTE_NO_ERROR:
5518 case wxCTE_NO_RESOURCE:
5520 wxS(
"Insufficient resources for correct execution of the program."));
5523 case wxCTE_ALREADY_RUNNING:
5527 case wxCTE_INVALID_PROTOCOL:
5528 wxLogError(wxS(
"The URL '%s' uses an unsupported protocol."),
5532 case wxCTE_NO_VALID_STREAM:
5539 case wxCTE_CURL_ERROR: {
5540 wxString ws = wxS(
"unknown");
5541 if (p->GetCurlSession())
5543 wxString(p->GetCurlSession()->GetErrorString().c_str(), wxConvUTF8);
5544 wxLogError(wxS(
"Network error: %s"), ws.c_str());
5549 if (p->IsAlive()) p->Abort();
AisDecoder * g_pAIS
Global instance.
Class AisDecoder and helpers.
Plugin catalog settings dialog.
Plugin catalog management: Build the runtime catalog, handling downloads as required.
General chart base definitions.
ChartDB * ChartData
Global instance.
Charts database management
Basic chart info storage.
Generic Chart canvas base.
EventVar plugin_msg
A JSON message should be sent.
Handle messages for blacklisted plugins.
Modal dialog for plugin catalog settings.
ChartCanvas - Main chart display and interaction component.
Wrapper class for plugin-based charts.
virtual double GetNearestPreferredScalePPM(double target_scale_ppm)
Find the nearest preferred viewport scale (in pixels/meter) for this chart.
NMEA0183 basic parsing common parts:
const std::vector< DriverPtr > & GetDrivers() const
Wrapper for configuration variables which lives in a wxBaseConfig object.
void Notify() override
Notify all listeners, no data supplied.
Wrapper for global variable, supports notification events when value changes.
Downloader with progress and final message dialogs.
Interface implemented by classes which listens.
The raw message layer, a singleton.
static NavAddr::Bus GetBusByKey(const std::string &key)
Return bus corresponding to given key.
An iterator class for OCPNRegion.
A wrapper class for wxRegion with additional functionality.
Define an action to be performed when a KeyProvider is notified.
void Init(const KeyProvider &kp, const std::function< void(ObservedEvt &ev)> &action)
Initiate an object yet not listening.
void Listen(const std::string &key, wxEvtHandler *listener, wxEventType evt)
Set object to send wxEventType ev to listener on changes in key.
Custom event class for OpenCPN's notification system.
std::shared_ptr< const void > GetSharedPtr() const
Gets the event's payload data.
Class representing an S-57 chart object.
double lon_max
Bounding box maximum longitude.
double lon_min
Bounding box minimum longitude.
double lat_max
Bounding box maximum latitude.
int auxParm0
Auxiliary parameter 0.
void * pPolyTessGeo
Tesselated polygon geometry.
double chart_ref_lon
Chart reference longitude.
double * geoPtMulti
Lat/lon pairs for decomposed points.
void * S52_Context
S52 presentation data.
double chart_ref_lat
Chart reference latitude.
char FeatureName[8]
S-57 feature type code (e.g., "DEPARE")
double lat_min
Bounding box minimum latitude.
int Primitive_type
Geometry type (point, line, area)
Represents a line segment element for efficient vector chart rendering.
Extended chart base class with separated text rendering.
virtual wxBitmap & RenderRegionViewOnDCNoText(const PlugIn_ViewPort &VPoint, const wxRegion &Region)
Standard DC rendering without text.
virtual bool RenderRegionViewOnDCTextOnly(wxMemoryDC &dc, const PlugIn_ViewPort &VPoint, const wxRegion &Region)
Standard DC text-only rendering.
virtual void ClearPLIBTextList()
Clears any cached text elements.
virtual int RenderRegionViewOnGLNoText(const wxGLContext &glc, const PlugIn_ViewPort &VPoint, const wxRegion &Region, bool b_use_stencil)
OpenGL rendering without text.
virtual int RenderRegionViewOnGLTextOnly(const wxGLContext &glc, const PlugIn_ViewPort &VPoint, const wxRegion &Region, bool b_use_stencil)
OpenGL text-only rendering.
virtual int RenderRegionViewOnGL(const wxGLContext &glc, const PlugIn_ViewPort &VPoint, const wxRegion &Region, bool b_use_stencil)
OpenGL rendering with combined text and graphics.
virtual ListOfPI_S57Obj * GetLightsObjRuleListVisibleAtLatLon(float lat, float lon, PlugIn_ViewPort *VPoint)
Gets list of visible light objects at specified position.
OpenGL-optimized chart base class for plugin chart types.
virtual int GetNoCOVRTablenPoints(int iTable)
Alternative to GetNoCOVRTablePoints().
virtual int GetNoCOVREntries()
Gets number of no-coverage areas in chart.
virtual int GetNoCOVRTablePoints(int iTable)
Gets number of points in no-coverage area boundary.
virtual wxString CreateObjDescriptions(ListOfPI_S57Obj *obj_list)
Creates description text for chart objects.
virtual float * GetNoCOVRTableHead(int iTable)
Gets coordinate data for no-coverage area boundary.
virtual int RenderRegionViewOnGL(const wxGLContext &glc, const PlugIn_ViewPort &VPoint, const wxRegion &Region, bool b_use_stencil)
Renders chart content using OpenGL.
virtual ListOfPI_S57Obj * GetObjRuleListAtLatLon(float lat, float lon, float select_radius, PlugIn_ViewPort *VPoint)
Gets chart objects near specified position.
Base class for implementing custom chart types in OpenCPN plugins.
virtual void SetColorScheme(int cs, bool bApplyImmediate)
Sets the color scheme for chart display.
virtual bool GetChartExtent(ExtentPI *pext)
Gets the geographic boundaries of the chart.
virtual void chartpix_to_latlong(double pixx, double pixy, double *plat, double *plon)
Converts chart pixel coordinates to geographic coordinates.
virtual double GetNearestPreferredScalePPM(double target_scale_ppm)
Returns the nearest preferred scale value for this chart.
virtual double GetNormalScaleMin(double canvas_scale_factor, bool b_allow_overzoom)
Returns the minimum recommended scale for this chart.
virtual wxBitmap & RenderRegionView(const PlugIn_ViewPort &VPoint, const wxRegion &Region)
Renders a region of the chart for display.
virtual ChartFamilyEnumPI GetChartFamily()
Returns the chart family classification.
virtual wxString GetID()
Returns a unique identifier for the chart.
virtual wxString GetDatumString()
Returns the horizontal geodetic datum of the chart.
virtual wxString GetName()
Returns the chart's name or title.
virtual double GetRasterScaleFactor()
Returns the scale factor for raster chart rendering.
virtual wxDateTime GetEditionDate(void)
Returns the edition date of the chart.
virtual int GetCOVRTablenPoints(int iTable)
Alternative method to get the number of points in a coverage table entry.
virtual bool GetChartBits(wxRect &source, unsigned char *pPix, int sub_samp)
Gets pixel data for a portion of a raster chart.
virtual int GetCOVREntries()
Returns the number of coverage table entries for this chart.
virtual double GetNormalScaleMax(double canvas_scale_factor, int canvas_width)
Returns the maximum recommended scale for this chart.
virtual wxString GetSoundingsDatum()
Returns the vertical datum used for soundings in the chart.
virtual wxString GetExtraInfo()
Returns additional information about the chart.
virtual int GetSize_X()
Gets the width of the chart in pixels.
virtual wxString GetFullPath() const
Returns the full file path of the chart.
virtual wxString GetSE()
Returns the chart's source edition identifier.
virtual bool IsReadyToRender()
Indicates whether the chart is ready for rendering.
virtual int GetNativeScale()
Returns the native scale of the chart.
virtual double GetChartSkew()
Returns the skew/rotation angle of the chart.
virtual wxString GetDepthUnits()
Returns the depth units used in the chart.
virtual int Init(const wxString &full_path, int init_flags)
Initializes a chart instance from a file.
virtual wxString GetFileSearchMask(void)
Returns file pattern(s) for chart files this plugin can handle.
virtual int GetSize_Y()
Gets the height of the chart in pixels.
virtual void latlong_to_chartpix(double lat, double lon, double &pixx, double &pixy)
Converts geographic coordinates to chart pixel coordinates.
virtual void ComputeSourceRectangle(const PlugIn_ViewPort &vp, wxRect *pSourceRect)
Computes the source rectangle for the chart based on a given viewport.
virtual float * GetCOVRTableHead(int iTable)
Returns a pointer to the coverage table data for a specific entry.
virtual double GetChartErrorFactor()
Returns the error factor for the chart.
virtual OcpnProjTypePI GetChartProjection()
Returns the projection type used by the chart.
virtual wxBitmap * GetThumbnail(int tnx, int tny, int cs)
Generates a thumbnail image of the chart.
virtual ChartTypeEnumPI GetChartType()
Returns the chart type identifier.
virtual void GetValidCanvasRegion(const PlugIn_ViewPort &VPoint, wxRegion *pValidRegion)
Determines the valid display area for this chart.
virtual bool AdjustVP(PlugIn_ViewPort &vp_last, PlugIn_ViewPort &vp_proposed)
Adjusts viewport parameters for chart-specific requirements.
virtual int GetCOVRTablePoints(int iTable)
Returns the number of points in a specific coverage table entry.
virtual ChartDepthUnitTypePI GetDepthUnitId()
Returns the depth unit type identifier.
Data for a loaded plugin, including dl-loaded library.
Basic data for a loaded plugin, trivially copyable.
wxString m_plugin_filename
The short file path.
wxString m_plugin_file
The full file path.
int m_cap_flag
PlugIn Capabilities descriptor.
wxString m_common_name
A common name string for the plugin.
std::string Key() const
sort key.
void HandleN0183(std::shared_ptr< const Nmea0183Msg > n0183_msg)
Process incoming NMEA 0183 messages from the message bus.
void HandleSignalK(std::shared_ptr< const SignalkMsg > sK_msg)
Process incoming SignalK messages from the message bus.
Contains view parameters and status information for a chart display viewport.
double view_scale_ppm
Display scale in pixels per meter.
wxRect rv_rect
Rectangle defining the rendered view area.
int pix_width
Viewport width in pixels.
double lon_max
Maximum longitude of the viewport.
double clon
Center longitude of the viewport in decimal degrees.
double lat_max
Maximum latitude of the viewport.
int pix_height
Viewport height in pixels.
double clat
Center latitude of the viewport in decimal degrees.
double skew
Display skew angle in radians.
double rotation
Display rotation angle in radians.
bool bValid
True if this viewport is valid and can be used for rendering.
double lon_min
Minimum longitude of the viewport.
double lat_min
Minimum latitude of the viewport.
int m_projection_type
Chart projection type (PROJECTION_MERCATOR, etc.)
bool b_quilt
True if the viewport is in quilt mode (showing multiple charts)
float chart_scale
Conventional chart displayed scale (e.g., 1:50000)
Handle plugin install from remote repositories and local operations to Uninstall and list plugins.
bool Uninstall(const std::string plugin)
Uninstall an installed and loaded plugin.
const std::vector< PluginMetadata > GetInstalled()
Return list of all installed and loaded plugins.
static std::string ImportedMetadataPath(std::string name)
Return path to imported metadata for given plugin.
static std::string VersionPath(std::string name)
Return path to file containing version for given plugin.
std::vector< std::string > GetInstalldataPlugins()
Return list of installed plugins lower case names, not necessarily loaded.
bool ClearInstallData(const std::string plugin_name)
Remove installation data for not loaded plugin.
static bool IsCompatible(const PluginMetadata &metadata, const char *os=PKG_TARGET, const char *os_version=PKG_TARGET_VERSION)
Return true if given plugin is loadable on given os/version.
static std::string FileListPath(std::string name)
Return path to installation manifest for given plugin.
void SetInstalledMetadata(const PluginMetadata &pm)
Set metadata for an installed plugin.
static PluginHandler * GetInstance()
Singleton factory.
void ReloadPluginPanels()
Complete reload from plugins array.
bool LoadAllPlugIns(bool enabled_plugins, bool keep_orphans=false)
Update catalog with imported metadata and load all plugin library files.
void UpdateManagedPlugins(bool keep_orphans)
Update all managed plugins i.
EventVar evt_pluglist_change
Notified without data when the GetPlugInArray() list is changed.
static std::string GetPluginVersion(const PlugInData pd, std::function< const PluginMetadata(const std::string &)> get_metadata)
Return version string for a plugin, possibly with an "Imported" suffix.
void SortPlugins(int(*cmp_func)(PlugInContainer **, PlugInContainer **))
Sort GetPluginArray().
static void UpdatePlugin(PlugInContainer *plugin, const PluginMetadata &md)
Update PlugInContainer status using data from PluginMetadata and manifest.
void SetEnabled(const wxString &common_name, bool enabled)
Update enabled/disabled state for plugin with given name.
static PluginMetadata MetadataByName(const std::string &name)
Find metadata for given plugin.
bool DeactivatePlugIn(PlugInContainer *pic)
Deactivate given plugin.
bool UpdatePlugIns()
Update the GetPlugInArray() list by reloading all plugins from disk.
void ShowPreferencesDialog(const PlugInData &pd, wxWindow *parent)
Display the preferences dialog for a plugin.
const ArrayOfPlugIns * GetPlugInArray()
Return list of currently loaded plugins.
PluginPanel(wxPanel *parent, wxWindowID id, const wxPoint &pos, const wxSize &size, const PlugInData plugin)
An entry in the list of plugins presented by Options | Plugins.
KeyProvider wrapper for a plain key string.
std::string GetKey() const override
Get the Key object from the Key Provider.
EventVar json_msg
Notified with message targeting all plugins.
EventVar json_leg_info
Notified with a shared_ptr<ActiveLegDat>, leg info to all plugins.
EventVar on_message_sent
Notified when a message available as GetString() is sent to garmin.
A parsed SignalK message over ipv4.
Modal dialog, displays available updates (possibly just one) and lets user select and eventually conf...
ViewPort - Core geographic projection and coordinate transformation engine.
void SetBoxes()
Computes the bounding box coordinates for the current viewport.
double view_scale_ppm
Requested view scale in physical pixels per meter (ppm), before applying projections.
double ref_scale
The nominal scale of the "reference chart" for this view.
int pix_height
Height of the viewport in physical pixels.
double rotation
Rotation angle of the viewport in radians.
int pix_width
Width of the viewport in physical pixels.
double skew
Angular distortion (shear transform) applied to the viewport in radians.
double clon
Center longitude of the viewport in degrees.
double clat
Center latitude of the viewport in degrees.
double chart_scale
Chart scale denominator (e.g., 50000 for a 1:50000 scale).
Device context class that can use either wxDC or OpenGL for drawing.
virtual void PrepareContextMenu(int canvasIndex)
Prepares plugin context menu items.
virtual bool RenderOverlayMultiCanvas(wxDC &dc, PlugIn_ViewPort *vp, int canvasIndex)
Renders plugin overlay graphics in standard DC mode for multi-canvas support.
virtual bool RenderGLOverlayMultiCanvas(wxGLContext *pcontext, PlugIn_ViewPort *vp, int canvasIndex)
Renders plugin overlay graphics in OpenGL mode for multi-canvas support.
virtual bool RenderGLOverlayMultiCanvas(wxGLContext *pcontext, PlugIn_ViewPort *vp, int canvasIndex, int priority)
Renders plugin overlay graphics in OpenGL mode with priority control.
virtual bool RenderOverlayMultiCanvas(wxDC &dc, PlugIn_ViewPort *vp, int canvas_ix, int priority)
Renders plugin overlay graphics in standard DC mode with priority control.
virtual bool RenderOverlay(wxDC &dc, PlugIn_ViewPort *vp)
Renders plugin overlay graphics in standard DC mode for single canvas.
virtual bool RenderGLOverlay(wxGLContext *pcontext, PlugIn_ViewPort *vp)
Renders plugin overlay graphics in OpenGL mode for single canvas.
Base class for OpenCPN plugins.
virtual void OnCloseToolboxPanel(int page_sel, int ok_apply_cancel)
Handles preference page closure.
virtual void SetCurrentViewPort(PlugIn_ViewPort &vp)
Notifies plugin of viewport changes.
virtual void UpdateAuiStatus(void)
Updates AUI manager status.
virtual void SetColorScheme(PI_ColorScheme cs)
Updates plugin color scheme.
virtual wxArrayString GetDynamicChartClassNameArray(void)
Returns array of dynamically loaded chart class names.
virtual int GetPlugInVersionMajor()
Returns the major version number of the plugin itself.
virtual bool RenderOverlay(wxMemoryDC *pmdc, PlugIn_ViewPort *vp)
Render plugin overlay graphics using standard device context.
virtual void ProcessParentResize(int x, int y)
Handles parent window resize events.
virtual int GetPlugInVersionMinor()
Returns the minor version number of the plugin itself.
int Parse(const wxString &doc, wxJSONValue *val)
Parse the JSON document.
The JSON value class implementation.
The JSON document writer.
void Write(const wxJSONValue &value, wxString &str)
Write the JSONvalue object to a JSON text.
wxColour GetDialogColor(DialogColor color)
Retrieves a dialog color based on its role in the application's dialogs.
@ DLG_SELECTED_ACCENT
Accent color for selected items.
@ DLG_SELECTED_BACKGROUND
Background color for selected items.
@ DLG_UNSELECTED_ACCENT
Accent color for unselected items.
@ DLG_UNSELECTED_BACKGROUND
Background color for unselected items.
DriverPtr & FindDriver(const std::vector< DriverPtr > &drivers, const std::string &iface, const NavAddr::Bus _bus)
Search list of drivers for a driver with given interface string.
Driver registration container, a singleton.
Raw messages layer, supports sending and recieving navmsg messages.
Variables maintained by comm stack, read-only access for others.
double g_display_size_mm
Physical display width (mm)
Global variables stored in configuration file.
Generic GUI downloads tool.
Handle downloading of files from remote urls.
OpenGL chart rendering canvas.
GSHHS Chart Object (Global Self-consistent, Hierarchical, High-resolution Shoreline) Derived from htt...
Miscellaneous globals primarely used by gui layer, not persisted in configuration file.
JSON event definition used in internal communications to/from plugins.
Enhanced logging interface on top of wx/log.h.
Multiplexer class and helpers.
bool replace(std::string &str, const std::string &from, const std::string &to)
Perform in place substitution in str, replacing "from" with "to".
std::string lookup_tarball(const char *uri)
Get path to tarball in cache for given filename.
std::string tolower(const std::string &input)
Return copy of s with all characters converted to lower case.
std::vector< std::string > split(const char *token_string, const std::string &delimiter)
Return vector of items in s separated by delimiter.
bool store_metadata(const char *path)
Store metadata in metadata cache, return success/fail.
bool store_tarball(const char *path, const char *basename)
Store a tarball in tarball cache, return success/fail.
Navigation Utility Functions without GUI dependencies.
Notify()/Listen() configuration variable wrapper.
Global variables Listen()/Notify() wrapper.
Optimized wxBitmap Object.
enum _PI_DisCat PI_DisCat
Display categories for S52 chart features.
#define INSTALLS_PLUGIN_CHART
Plugin provides new chart type for standard (non-GL) view.
enum _PI_DisPrio PI_DisPrio
Display priority levels for S52 chart objects.
#define PLIB_CAPS_OBJCATMUTATE
Support for object category mutation Allows dynamic changes to object display categories.
#define INSTALLS_CONTEXTMENU_ITEMS
Plugin will add items to chart context menu.
#define WANTS_LATE_INIT
Delay full plugin initialization until system is ready.
_OCPN_DLCondition
Event types for HTTP file download operations.
@ OCPN_DL_EVENT_TYPE_UNKNOWN
Unknown event type.
@ OCPN_DL_EVENT_TYPE_PROGRESS
Download progress update.
@ OCPN_DL_EVENT_TYPE_END
Download has completed.
PI_ColorScheme
Color schemes for different lighting conditions.
#define PLIB_CAPS_SINGLEGEO_BUFFER
Support for single geometry buffers Allows combining multiple geometries into a single buffer.
#define PLIB_CAPS_LINE_BUFFER
Support for line vertex buffers Enables batched line rendering using vertex buffers.
_OCPN_DLStatus
Status codes for HTTP file download operations.
@ OCPN_DL_NO_ERROR
Download completed successfully.
@ OCPN_DL_USER_TIMEOUT
Download timed out waiting for user action.
@ OCPN_DL_STARTED
Download has begun but not yet complete.
@ OCPN_DL_FAILED
Download failed (general error)
@ OCPN_DL_UNKNOWN
Unknown or uninitialized status.
@ OCPN_DL_ABORTED
Download was cancelled by user.
@ PI_CHART_FAMILY_VECTOR
Vector chart formats (S-57, CM93, etc.)
#define INSTALLS_TOOLBOX_PAGE
Plugin will add pages to the toolbox/settings dialog.
enum _PI_LUPname PI_LUPname
Name identifiers for S57 lookup table sets.
#define USES_AUI_MANAGER
Plugin uses wxAuiManager for window management.
#define PLIB_CAPS_OBJSEGLIST
Support for object segment lists Enables breaking complex geometries into optimized segments.
#define INSTALLS_PLUGIN_CHART_GL
Plugin provides new chart type for OpenGL view.
#define WANTS_ONPAINT_VIEWPORT
Receive callbacks during chart viewport painting.
#define WANTS_PREFERENCES
Plugin will add page(s) to global preferences dialog.
#define WANTS_OVERLAY_CALLBACK
Receive callbacks to render custom overlay graphics on the chart.
wxWindow * GetOCPNCanvasWindow()
Gets OpenCPN's main canvas window.
double OCPN_GetDisplayContentScaleFactor()
Gets content scaling factor for current display.
double OCPN_GetWinDIPScaleFactor()
Gets Windows-specific DPI scaling factor.
Miscellaneous utilities, many of which string related.
Layer to use wxDC or opengl.
options * g_options
Global instance.
Downloaded plugins cache.
void SendNMEASentenceToAllPlugIns(const wxString &sentence)
Distribute a NMEA 0183 sentence to all plugins that have registered interest by setting the WANTS_NME...
Tools to send data to plugins.
Plugin remote repositories installation and Uninstall/list operations.
Low level code to load plugins from disk, notably the PluginLoader class.
@ Ghost
Managed, shadowing another (packaged?) plugin.
@ Unmanaged
Unmanaged, probably a package.
@ Managed
Managed by installer.
@ System
One of the four system plugins, unmanaged.
Plugin installation and data paths support.
wxString toSDMM_PlugIn(int NEflag, double a, bool hi_precision)
Convert decimal degrees to a formatted string.
bool PI_GetObjectRenderBox(PI_S57Obj *pObj, double *lat_min, double *lat_max, double *lon_min, double *lon_max)
Gets geographic bounding box of S57 object.
void PI_PLIBFreeContext(void *pContext)
Frees S52 PLIB context.
_OCPN_DLStatus OCPN_postDataHttp(const wxString &url, const wxString ¶meters, wxString &result, int timeout_secs)
Performs HTTP POST request.
int PI_GetPLIBSymbolStyle()
Gets configured S52 symbol style.
void OCPN_cancelDownloadFileBackground(long handle)
Cancels a background download.
wxString GetPlugInPath(opencpn_plugin *pplugin)
Gets the installation path for a specific plugin.
int PI_GetPLIBStateHash()
Gets hash value representing current PLIB state.
int PI_PLIBRenderAreaToDC(wxDC *pdc, PI_S57Obj *pObj, PlugIn_ViewPort *vp, wxRect rect, unsigned char *pixbuf)
Renders an S57 area object using standard device context.
wxColour GetBaseGlobalColor(wxString colorName)
Gets a global system color.
wxString PI_GetPLIBColorScheme()
Gets current color scheme used by S52 PLIB.
double PI_GetPLIBMarinerSafetyContour()
Gets configured safety contour depth.
bool PI_PLIBObjectRenderCheck(PI_S57Obj *pObj, PlugIn_ViewPort *vp)
Checks if object should be rendered.
PlugInManager * g_pi_manager
Global instance.
std::vector< const PlugInData * > GetInstalled()
Return sorted list of all installed plugins.
int PI_GetPLIBDepthUnitInt()
Gets configured depth unit for S52 display.
bool PI_PLIBSetContext(PI_S57Obj *pObj)
Sets S52 PLIB rendering context for an object.
void PI_PLIBSetLineFeaturePriority(PI_S57Obj *pObj, int prio)
Sets rendering priority for line feature.
void PI_PLIBPrepareForNewRender()
Prepares PLIB for new rendering pass.
PI_DisCat PI_GetObjectDisplayCategory(PI_S57Obj *pObj)
Gets display category for object.
PI_LUPname PI_GetObjectLUPName(PI_S57Obj *pObj)
Gets Look-Up Table (LUP) name for object.
int OCPNMessageBox_PlugIn(wxWindow *parent, const wxString &message, const wxString &caption, int style, int x, int y)
Shows a message box dialog.
int PI_PLIBRenderObjectToGL(const wxGLContext &glcc, PI_S57Obj *pObj, PlugIn_ViewPort *vp, wxRect &render_rect)
Renders any S57 object using OpenGL.
int PI_PLIBRenderAreaToGL(const wxGLContext &glcc, PI_S57Obj *pObj, PlugIn_ViewPort *vp, wxRect &render_rect)
Renders an S57 area object using OpenGL.
_OCPN_DLStatus OCPN_downloadFileBackground(const wxString &url, const wxString &outputFile, wxEvtHandler *handler, long *handle)
Asynchronously downloads a file in the background.
wxString toUsrDateTimeFormat_Plugin(const wxDateTime date_time, const DateTimeFormatOptions &options)
Format a date/time to a localized string representation, conforming to the global date/time format an...
int PI_PLIBRenderObjectToDC(wxDC *pdc, PI_S57Obj *pObj, PlugIn_ViewPort *vp)
Renders an S57 object using standard device context.
void PI_UpdateContext(PI_S57Obj *pObj)
Updates rendering context for S57 object.
wxString GetOCPN_ExePath()
Gets OpenCPN executable path.
_OCPN_DLStatus OCPN_downloadFile(const wxString &url, const wxString &outputFile, const wxString &title, const wxString &message, const wxBitmap &bitmap, wxWindow *parent, long style, int timeout_secs)
Synchronously download a file with progress dialog.
wxString * GetpPlugInLocation()
Gets plugins directory location.
int PI_GetPLIBBoundaryStyle()
Gets configured S52 boundary style.
bool OCPN_isOnline()
Checks internet connectivity.
void PI_PLIBSetRenderCaps(unsigned int flags)
Sets rendering capability flags.
PI_DisPrio PI_GetObjectDisplayPriority(PI_S57Obj *pObj)
Gets display priority for object.
wxString GetWritableDocumentsDir()
Returns the platform-specific default documents directory.
PlugInManager and helper classes – Mostly gui parts (dialogs) and plugin API stuff.
PlugInManager * g_pi_manager
Global instance.
Routeman * g_pRouteMan
Global instance.
Safe mode non-gui handling.
Selected route, segment, waypoint, etc.
Semantic version encode/decode object.
Versions uses a modified semantic versioning scheme: major.minor.revision.post-tag+build.
static SemanticVersion parse(std::string s)
Parse a version string, sets major == -1 on errors.
Geographic extent structure defining a bounding box.
double NLAT
Northern latitude boundary in decimal degrees.
double WLON
Western longitude boundary in decimal degrees.
double SLAT
Southern latitude boundary in decimal degrees.
double ELON
Eastern longitude boundary in decimal degrees.
wxBitmap LoadSVG(const wxString filename, const unsigned int width, const unsigned int height, wxBitmap *default_bitmap, bool use_cache)
Load SVG file and return it's bitmap representation of requested size In case file can't be loaded an...
Recorded track abstraction.
WaypointMan drawing stuff.