29#include <wx/aui/aui.h>
30#include <wx/clipbrd.h>
31#include <wx/dynarray.h>
35#include <wx/graphics.h>
37#include <wx/listbook.h>
40#include "ocpn-nlohmann/json.hpp"
85#include "user_colors.h"
88#include "androidUTIL.h"
93 ID_DEF_MENU_MAX_DETAIL = 1,
95 ID_DEF_MENU_SCALE_OUT,
99 ID_DEF_MENU_MOVE_BOAT_HERE,
100 ID_DEF_MENU_GOTO_HERE,
101 ID_DEF_MENU_GOTOPOSITION,
104 ID_WP_MENU_PROPERTIES,
106 ID_RT_MENU_DEACTIVATE,
110 ID_RT_MENU_SPLIT_LEG,
111 ID_RT_MENU_SPLIT_WPT,
114 ID_WPT_MENU_SENDTOGPS,
115 ID_WPT_MENU_SENDTONEWGPS,
116 ID_WPT_MENU_SENDTOPEER,
124 ID_RT_MENU_DEACTPOINT,
125 ID_RT_MENU_ACTNXTPOINT,
127 ID_RT_MENU_PROPERTIES,
128 ID_RT_MENU_SENDTOGPS,
129 ID_RT_MENU_SENDTONEWGPS,
130 ID_RT_MENU_SHOWNAMES,
131 ID_RT_MENU_RESEQUENCE,
132 ID_RT_MENU_SENDTOPEER,
133 ID_WP_MENU_SET_ANCHORWATCH,
134 ID_WP_MENU_CLEAR_ANCHORWATCH,
135 ID_DEF_MENU_AISTARGETLIST,
136 ID_DEF_MENU_AIS_CPAWARNING,
139 ID_RC_MENU_SCALE_OUT,
143 ID_DEF_MENU_AIS_QUERY,
145 ID_DEF_MENU_AISSHOWTRACK,
146 ID_DEF_MENU_ACTIVATE_MEASURE,
147 ID_DEF_MENU_DEACTIVATE_MEASURE,
148 ID_DEF_MENU_COPY_MMSI,
153 ID_DEF_MENU_CM93OFFSET_DIALOG,
155 ID_TK_MENU_PROPERTIES,
157 ID_TK_MENU_SENDTOPEER,
158 ID_WP_MENU_ADDITIONAL_INFO,
160 ID_DEF_MENU_QUILTREMOVE,
164 ID_DEF_MENU_TOGGLE_FULL,
165 ID_DEF_MENU_TIDEINFO,
166 ID_DEF_MENU_CURRENTINFO,
170 ID_DGB_MENU_NMEA_WINDOW,
172 ID_DEF_MENU_GROUPBASE,
179static wxString _menuText(wxString name, wxString shortcut) {
183 menutext <<
"\t" << shortcut;
191int CanvasMenuHandler::GetNextContextMenuId() {
192 return ID_DEF_MENU_LAST +
196wxFont CanvasMenuHandler::m_scaledFont;
199CanvasMenuHandler::CanvasMenuHandler(
ChartCanvas *parentCanvas,
202 int selectedAIS_MMSI,
203 void *selectedTCIndex, wxWindow *nmea_log)
204 : m_nmea_log(nmea_log) {
205 parent = parentCanvas;
206 m_pSelectedRoute = selectedRoute;
207 m_pSelectedTrack = selectedTrack;
208 m_pFoundRoutePoint = selectedPoint;
209 m_FoundAIS_MMSI = selectedAIS_MMSI;
210 m_pIDXCandidate = selectedTCIndex;
211 if (!m_scaledFont.IsOk()) {
213 m_scaledFont = *qFont;
219CanvasMenuHandler::~CanvasMenuHandler() {}
225void CanvasMenuHandler::PrepareMenuItem(wxMenuItem *item) {
226#if defined(__WXMSW__)
227 wxColour ctrl_back_color = GetGlobalColor(
"DILG1");
228 item->SetBackgroundColour(ctrl_back_color);
229 wxColour menu_text_color = GetGlobalColor(
"UITX1");
230 item->SetTextColour(menu_text_color);
234void CanvasMenuHandler::MenuPrepend1(wxMenu *menu,
int id, wxString label) {
235 wxMenuItem *item =
new wxMenuItem(menu,
id, label);
236#if defined(__WXMSW__)
237 item->SetFont(m_scaledFont);
242 item->SetFont(sFont);
245 PrepareMenuItem(item);
247 if (g_btouch) menu->InsertSeparator(0);
251void CanvasMenuHandler::MenuAppend1(wxMenu *menu,
int id, wxString label) {
252 wxMenuItem *item =
new wxMenuItem(menu,
id, label);
253#if defined(__WXMSW__)
254 item->SetFont(m_scaledFont);
259 item->SetFont(sFont);
262 PrepareMenuItem(item);
265 if (g_btouch) menu->AppendSeparator();
268void CanvasMenuHandler::SetMenuItemFont1(wxMenuItem *item) {
269#if defined(__WXMSW__)
270 item->SetFont(m_scaledFont);
273#if defined(__ANDROID__)
275 item->SetFont(*qFont);
278 PrepareMenuItem(item);
281void CanvasMenuHandler::CanvasPopupMenu(
int x,
int y,
int seltype) {
282 wxMenu *contextMenu =
new wxMenu;
283 wxMenu *menuWaypoint = NULL;
284 wxMenu *menuRoute = NULL;
285 wxMenu *menuTrack = NULL;
286 wxMenu *menuAIS = NULL;
288 wxMenu *subMenuChart =
new wxMenu;
289 wxMenu *subMenuUndo =
new wxMenu(
"Undo...Ctrl-Z");
292 wxMenu *subMenuRedo =
new wxMenu(
"Redo...Shift-Ctrl-Z");
294 wxMenu *subMenuRedo =
new wxMenu(
"Redo...Ctrl-Y");
296 wxMenu *subMenuDebug =
new wxMenu(
"");
297 MenuAppend1(subMenuDebug, ID_DGB_MENU_NMEA_WINDOW, _(
"Show Data Monitor"));
299 wxMenu *menuFocus = contextMenu;
304 if (!g_bBasicMenus || (seltype != SELTYPE_ROUTECREATE)) {
305 bool bsubMenus =
false;
308 if (parent->undo->AnythingToUndo()) {
310 wxMenuItem *subMenuItemundo =
311 contextMenu->AppendSubMenu(subMenuUndo, _(
"Undo"));
314 undoItem << _(
"Undo") <<
" "
315 << parent->undo->GetNextUndoableAction()->Description();
316 MenuAppend1(subMenuUndo, ID_UNDO, undoItem);
318 if (parent->undo->AnythingToRedo()) {
320 wxMenuItem *subMenuItemRedo =
321 contextMenu->AppendSubMenu(subMenuRedo, _(
"Redo"));
324 redoItem << _(
"Redo") <<
" "
325 << parent->undo->GetNextRedoableAction()->Description();
326 MenuAppend1(subMenuRedo, ID_REDO, redoItem);
329 if (parent->undo->AnythingToUndo()) {
331 undoItem << _(
"Undo") <<
" "
332 << parent->undo->GetNextUndoableAction()->Description();
333 MenuAppend1(contextMenu, ID_UNDO, _menuText(undoItem,
"Ctrl-Z"));
336 if (parent->undo->AnythingToRedo()) {
338 redoItem << _(
"Redo") <<
" "
339 << parent->undo->GetNextRedoableAction()->Description();
341 MenuAppend1(contextMenu, ID_REDO, _menuText(redoItem,
"Shift-Ctrl-Z"));
343 MenuAppend1(contextMenu, ID_REDO, _menuText(redoItem,
"Ctrl-Y"));
349 if (seltype == SELTYPE_ROUTECREATE) {
350 MenuAppend1(contextMenu, ID_RC_MENU_FINISH,
351 _menuText(_(
"End Route"),
"Esc"));
354 if (!parent->m_pMouseRoute) {
355 if (parent->m_bMeasure_Active)
356 MenuAppend1(contextMenu, ID_DEF_MENU_DEACTIVATE_MEASURE,
357 _menuText(_(
"Measure Off"),
"Esc"));
359 MenuAppend1(contextMenu, ID_DEF_MENU_ACTIVATE_MEASURE,
360 _menuText(_(
"Measure"),
"M"));
363 bool ais_areanotice =
false;
364 if (
g_pAIS && parent->GetShowAIS() && g_bShowAreaNotices) {
367 for (
const auto &target :
g_pAIS->GetAreaNoticeSourcesList()) {
368 auto target_data = target.second;
369 if (!target_data->area_notices.empty()) {
370 for (
auto &ani : target_data->area_notices) {
374 for (Ais8_001_22_SubAreaList::iterator sa =
375 area_notice.sub_areas.begin();
376 sa != area_notice.sub_areas.end(); ++sa) {
378 case AIS8_001_22_SHAPE_CIRCLE: {
379 wxPoint target_point;
382 bbox.Expand(target_point);
383 if (sa->radius_m > 0.0) bbox.EnLarge(sa->radius_m * vp_scale);
386 case AIS8_001_22_SHAPE_RECT:
387 case AIS8_001_22_SHAPE_POLYGON:
388 case AIS8_001_22_SHAPE_POLYLINE: {
389 double lat = sa->latitude;
390 double lon = sa->longitude;
391 for (
int i = 0; i < 4; ++i) {
392 ll_gc_ll(lat, lon, sa->angles[i], sa->dists_m[i] / 1852.0,
394 wxPoint target_point;
396 bbox.Expand(target_point);
400 case AIS8_001_22_SHAPE_SECTOR: {
401 double lat1 = sa->latitude;
402 double lon1 = sa->longitude;
404 wxPoint target_point;
406 bbox.Expand(target_point);
407 for (
int i = 0; i < 18; ++i) {
411 i * (sa->right_bound_deg - sa->left_bound_deg) / 18,
412 sa->radius_m / 1852.0, &lat, &lon);
414 bbox.Expand(target_point);
416 ll_gc_ll(lat1, lon1, sa->right_bound_deg, sa->radius_m / 1852.0,
419 bbox.Expand(target_point);
425 if (bbox.GetValid() && bbox.PointInBox(x, y)) {
426 ais_areanotice =
true;
435 if (parent->GetpCurrentStack())
436 nChartStack = parent->GetpCurrentStack()->nEntry;
438 if (!parent->GetVP().b_quilt) {
439 if (nChartStack > 1) {
440 MenuAppend1(contextMenu, ID_DEF_MENU_MAX_DETAIL, _(
"Max Detail Here"));
441 MenuAppend1(contextMenu, ID_DEF_MENU_SCALE_IN,
442 _menuText(_(
"Scale In"),
"Ctrl-Left"));
443 MenuAppend1(contextMenu, ID_DEF_MENU_SCALE_OUT,
444 _menuText(_(
"Scale Out"),
"Ctrl-Right"));
447 if ((parent->m_singleChart &&
448 (parent->m_singleChart->GetChartFamily() == CHART_FAMILY_VECTOR)) ||
450 MenuAppend1(contextMenu, ID_DEF_MENU_QUERY, _(
"Object Query") +
"...");
455 parent->m_pQuilt->GetChartAtPix(parent->GetVP(), wxPoint(x, y));
456 if ((pChartTest && (pChartTest->GetChartFamily() == CHART_FAMILY_VECTOR)) ||
458 MenuAppend1(contextMenu, ID_DEF_MENU_QUERY, _(
"Object Query") +
"...");
461 if (!g_bBasicMenus && (nChartStack > 1)) {
462 MenuAppend1(contextMenu, ID_DEF_MENU_SCALE_IN,
463 _menuText(_(
"Scale In"),
"Ctrl-Left"));
464 MenuAppend1(contextMenu, ID_DEF_MENU_SCALE_OUT,
465 _menuText(_(
"Scale Out"),
"Ctrl-Right"));
471 if (!g_bBasicMenus || (seltype != SELTYPE_ROUTECREATE)) {
472 bool b_dm_add =
true;
473 if (g_btouch && parent->IsMeasureActive()) b_dm_add =
false;
476 MenuAppend1(contextMenu, ID_DEF_MENU_DROP_WP,
477 _menuText(_(
"Drop Mark"),
"Ctrl-M"));
478 MenuAppend1(contextMenu, ID_DEF_MENU_NEW_RT,
479 _menuText(_(
"New Route..."),
"Ctrl-R"));
483 MenuAppend1(contextMenu, ID_DEF_MENU_MOVE_BOAT_HERE, _(
"Move Boat Here"));
486 if (!g_bBasicMenus && !
g_pRouteMan->GetpActiveRoute() &&
487 (!(seltype & SELTYPE_MARKPOINT) ||
488 (m_pFoundRoutePoint && m_pFoundRoutePoint->
m_bIsInLayer)))
489 MenuAppend1(contextMenu, ID_DEF_MENU_GOTO_HERE, _(
"Navigate To Here"));
492 MenuAppend1(contextMenu, ID_DEF_MENU_GOTOPOSITION,
493 _(
"Center view") +
"...");
495 if (!g_bBasicMenus) {
496 if (parent->GetVP().b_quilt) {
497 if (parent->GetUpMode() == NORTH_UP_MODE) {
498 MenuAppend1(contextMenu, ID_DEF_MENU_COGUP, _(
"Course Up Mode"));
499 if (!std::isnan(
gHdt))
500 MenuAppend1(contextMenu, ID_DEF_MENU_HEADUP, _(
"Heading Up Mode"));
502 MenuAppend1(contextMenu, ID_DEF_MENU_NORTHUP, _(
"North Up Mode"));
505 if (parent->m_singleChart &&
506 (fabs(parent->m_singleChart->GetChartSkew()) > .01) && !g_bskew_comp)
507 MenuAppend1(contextMenu, ID_DEF_MENU_NORTHUP, _(
"Chart Up Mode"));
509 MenuAppend1(contextMenu, ID_DEF_MENU_NORTHUP, _(
"North Up Mode"));
513 if (!g_bBasicMenus) {
514 bool full_toggle_added =
false;
517 MenuAppend1(contextMenu, ID_DEF_MENU_TOGGLE_FULL,
518 _(
"Toggle Full Screen"));
519 full_toggle_added =
true;
522 if (!full_toggle_added) {
524 MenuAppend1(contextMenu, ID_DEF_MENU_TOGGLE_FULL,
525 _(
"Toggle Full Screen"));
531 MenuAppend1(contextMenu, ID_DEF_ZERO_XTE, _(
"Zero XTE"));
534 int pasteBuffer = kml->ParsePasteBuffer();
535 if (pasteBuffer != KML_PASTE_INVALID) {
536 switch (pasteBuffer) {
537 case KML_PASTE_WAYPOINT: {
538 MenuAppend1(contextMenu, ID_PASTE_WAYPOINT, _(
"Paste Waypoint"));
541 case KML_PASTE_ROUTE: {
542 MenuAppend1(contextMenu, ID_PASTE_ROUTE, _(
"Paste Route"));
545 case KML_PASTE_TRACK: {
546 MenuAppend1(contextMenu, ID_PASTE_TRACK, _(
"Paste Track"));
549 case KML_PASTE_ROUTE_TRACK: {
550 MenuAppend1(contextMenu, ID_PASTE_ROUTE, _(
"Paste Route"));
551 MenuAppend1(contextMenu, ID_PASTE_TRACK, _(
"Paste Track"));
558 if (!parent->GetVP().b_quilt && parent->m_singleChart &&
559 (parent->m_singleChart->GetChartType() == CHART_TYPE_CM93COMP)) {
560 MenuAppend1(contextMenu, ID_DEF_MENU_CM93OFFSET_DIALOG,
561 _(
"CM93 Offset Dialog..."));
585 wxMenuItem *subItemChart =
586 contextMenu->AppendSubMenu(subMenuChart, _(
"Chart Groups"));
587 if (g_btouch) contextMenu->AppendSeparator();
589 SetMenuItemFont1(subItemChart);
593 MenuAppend1(subMenuChart, wxID_CANCEL, _(
"temporary"));
595 wxMenuItem *subItem0 = subMenuChart->AppendRadioItem(
596 ID_DEF_MENU_GROUPBASE, _(
"All Active Charts"));
598 SetMenuItemFont1(subItem0);
600 for (
unsigned int i = 0; i <
g_pGroupArray->GetCount(); i++) {
601 subItem0 = subMenuChart->AppendRadioItem(
602 ID_DEF_MENU_GROUPBASE + i + 1,
g_pGroupArray->Item(i)->m_group_name);
603 SetMenuItemFont1(subItem0);
607 subMenuChart->Remove(wxID_CANCEL);
609 subMenuChart->Check(ID_DEF_MENU_GROUPBASE + parent->m_groupIndex,
true);
613 menuFocus = contextMenu;
616 std::unique_ptr<HostApi> host_api =
GetHostApi();
617 auto *api_121 =
dynamic_cast<HostApi121 *
>(host_api.get());
619 if (!g_bBasicMenus || (seltype != SELTYPE_ROUTECREATE)) {
621 if (api_121 && parent->GetShowAIS() &&
622 (seltype & SELTYPE_AISTARGET &&
623 !(api_121->GetContextMenuMask() &
624 api_121->kContextMenuDisableAistarget))) {
625 auto myptarget =
g_pAIS->Get_Target_Data_From_MMSI(m_FoundAIS_MMSI);
626 if (!g_bBasicMenus && myptarget) {
627 name = myptarget->GetFullName();
628 if (name.IsEmpty()) name.Printf(
"%d", m_FoundAIS_MMSI);
629 name.Prepend(
" ( ").Append(
" )");
631 name = wxEmptyString;
632 menuAIS =
new wxMenu(_(
"AIS") + name);
633 MenuAppend1(menuAIS, ID_DEF_MENU_AIS_QUERY, _(
"Target Query..."));
634 if (myptarget && myptarget->bCPA_Valid &&
635 (myptarget->n_alert_state != AIS_ALERT_SET)) {
636 if (myptarget->b_show_AIS_CPA)
637 MenuAppend1(menuAIS, ID_DEF_MENU_AIS_CPA, _(
"Hide Target CPA"));
639 MenuAppend1(menuAIS, ID_DEF_MENU_AIS_CPA, _(
"Show Target CPA"));
641 MenuAppend1(menuAIS, ID_DEF_MENU_AISTARGETLIST, _(
"Target List..."));
642 if (myptarget->Class != AIS_METEO ) {
643 if (myptarget && !myptarget->b_PersistTrack) {
644 if (myptarget->b_show_track)
645 MenuAppend1(menuAIS, ID_DEF_MENU_AISSHOWTRACK,
646 _(
"Hide Target Track"));
648 MenuAppend1(menuAIS, ID_DEF_MENU_AISSHOWTRACK,
649 _(
"Show Target Track"));
653 MenuAppend1(menuAIS, ID_DEF_MENU_COPY_MMSI, _(
"Copy Target MMSI"));
654 menuAIS->AppendSeparator();
656 if (!parent->GetVP().b_quilt) {
657 if ((parent->m_singleChart &&
658 (parent->m_singleChart->GetChartFamily() ==
659 CHART_FAMILY_VECTOR))) {
660 MenuAppend1(menuAIS, ID_DEF_MENU_QUERY, _(
"Object Query..."));
665 parent->m_pQuilt->GetChartAtPix(parent->GetVP(), wxPoint(x, y));
667 (pChartTest->GetChartFamily() == CHART_FAMILY_VECTOR))) {
668 MenuAppend1(menuAIS, ID_DEF_MENU_QUERY, _(
"Object Query..."));
674 bool enable_list =
true;
676 double char_x = wxTheApp->GetTopWindow()->GetSize().x /
677 wxTheApp->GetTopWindow()->GetCharWidth();
678 double char_y = wxTheApp->GetTopWindow()->GetSize().y /
679 wxTheApp->GetTopWindow()->GetCharWidth();
680 double char_min = wxMin(char_x, char_y);
681 if (char_min < 100) enable_list =
false;
683 double size_x = wxTheApp->GetTopWindow()->GetSize().x /
g_androidDPmm;
684 double size_y = wxTheApp->GetTopWindow()->GetSize().y /
g_androidDPmm;
685 if (wxMin(size_x, size_y) < 100)
689 MenuAppend1(contextMenu, ID_DEF_MENU_AISTARGETLIST,
690 _(
"AIS target list") +
"...");
692 wxString nextCPAstatus = g_bCPAWarn ? _(
"Hide") : _(
"Show");
693 MenuAppend1(contextMenu, ID_DEF_MENU_AIS_CPAWARNING,
694 _menuText(nextCPAstatus +
" " + _(
"CPA alarm "),
"W"));
698 if (g_enable_root_menu_debug) {
699 wxMenuItem *subItemDebug =
700 contextMenu->AppendSubMenu(subMenuDebug, _(
"Debug"));
701 if (g_btouch) contextMenu->AppendSeparator();
702 SetMenuItemFont1(subItemDebug);
705 if (seltype & SELTYPE_ROUTESEGMENT &&
706 !(api_121->GetContextMenuMask() & api_121->kContextMenuDisableRoute)) {
707 if (!g_bBasicMenus && m_pSelectedRoute) {
709 if (name.IsEmpty()) name = _(
"Unnamed Route");
710 name.Prepend(
" ( ").Append(
" )");
712 name = wxEmptyString;
714 if (m_pSelectedRoute && m_pSelectedRoute->
m_bIsInLayer) blay =
true;
717 menuRoute =
new wxMenu(_(
"Layer Route") + name);
718 MenuAppend1(menuRoute, ID_RT_MENU_PROPERTIES, _(
"Properties") +
"...");
719 if (m_pSelectedRoute) {
720 if (m_pSelectedRoute->IsActive()) {
721 int indexActive = m_pSelectedRoute->GetIndexOf(
723 if (indexActive + 1 < m_pSelectedRoute->GetnPoints() - 1) {
724 MenuAppend1(menuRoute, ID_RT_MENU_ACTNXTPOINT,
725 _(
"Activate Next Waypoint"));
727 MenuAppend1(menuRoute, ID_RT_MENU_DEACTIVATE, _(
"Deactivate"));
728 MenuAppend1(menuRoute, ID_DEF_ZERO_XTE, _(
"Zero XTE"));
730 MenuAppend1(menuRoute, ID_RT_MENU_ACTIVATE, _(
"Activate"));
734 menuRoute =
new wxMenu(_(
"Route") + name);
735 MenuAppend1(menuRoute, ID_RT_MENU_PROPERTIES, _(
"Properties") +
"...");
736 if (m_pSelectedRoute) {
737 if (m_pSelectedRoute->IsActive()) {
738 int indexActive = m_pSelectedRoute->GetIndexOf(
740 if (indexActive + 1 < m_pSelectedRoute->GetnPoints() - 1) {
741 MenuAppend1(menuRoute, ID_RT_MENU_ACTNXTPOINT,
742 _(
"Activate Next Waypoint"));
744 MenuAppend1(menuRoute, ID_RT_MENU_DEACTIVATE, _(
"Deactivate"));
745 MenuAppend1(menuRoute, ID_DEF_ZERO_XTE, _(
"Zero XTE"));
747 MenuAppend1(menuRoute, ID_RT_MENU_ACTIVATE, _(
"Activate"));
750 MenuAppend1(menuRoute, ID_RT_MENU_INSERT, _(
"Insert Waypoint"));
751 MenuAppend1(menuRoute, ID_RT_MENU_APPEND, _(
"Append Waypoint"));
752 if (!(seltype & SELTYPE_ROUTEPOINT) && m_pSelectedRoute) {
753 m_SelectedIdx = m_pSelectedRoute->GetIndexOf(m_pFoundRoutePoint);
754 if (m_SelectedIdx >= 1 &&
755 m_SelectedIdx < m_pSelectedRoute->GetnPoints() - 2)
756 MenuAppend1(menuRoute, ID_RT_MENU_SPLIT_LEG, _(
"Split around Leg"));
758 MenuAppend1(menuRoute, ID_RT_MENU_COPY, _(
"Copy as KML") +
"...");
759 MenuAppend1(menuRoute, ID_RT_MENU_DELETE, _(
"Delete") +
"...");
760 MenuAppend1(menuRoute, ID_RT_MENU_REVERSE, _(
"Reverse..."));
761 if (m_pSelectedRoute) {
762 if (m_pSelectedRoute->AreWaypointNamesVisible())
763 MenuAppend1(menuRoute, ID_RT_MENU_SHOWNAMES,
764 _(
"Hide Waypoint Names"));
766 MenuAppend1(menuRoute, ID_RT_MENU_SHOWNAMES,
767 _(
"Show Waypoint Names"));
769 MenuAppend1(menuRoute, ID_RT_MENU_RESEQUENCE,
770 _(
"Resequence Waypoints..."));
773 wxString port = parent->FindValidUploadPort();
774 parent->m_active_upload_port = port;
775 wxString item = _(
"Send to GPS");
776 if (!port.IsEmpty()) {
781 MenuAppend1(menuRoute, ID_RT_MENU_SENDTOGPS, item);
783 if (!port.IsEmpty()) {
784 wxString item = _(
"Send to new GPS");
785 MenuAppend1(menuRoute, ID_RT_MENU_SENDTONEWGPS, item);
788 wxString itemstp = SYMBOL_STP_TITLE;
789 MenuAppend1(menuRoute, ID_RT_MENU_SENDTOPEER, itemstp);
792 if (menuFocus != menuAIS) menuFocus = menuRoute;
795 if (seltype & SELTYPE_TRACKSEGMENT &&
796 !(api_121->GetContextMenuMask() & api_121->kContextMenuDisableTrack)) {
797 name = wxEmptyString;
798 if (!g_bBasicMenus && m_pSelectedTrack)
799 name =
" ( " + m_pSelectedTrack->GetName(
true) +
" )";
801 name = wxEmptyString;
803 if (m_pSelectedTrack && m_pSelectedTrack->m_bIsInLayer) blay =
true;
806 menuTrack =
new wxMenu(_(
"Layer Track") + name);
807 MenuAppend1(menuTrack, ID_TK_MENU_PROPERTIES, _(
"Properties") +
"...");
809 menuTrack =
new wxMenu(_(
"Track") + name);
810 MenuAppend1(menuTrack, ID_TK_MENU_PROPERTIES, _(
"Properties") +
"...");
811 MenuAppend1(menuTrack, ID_TK_MENU_COPY, _(
"Copy as KML"));
812 MenuAppend1(menuTrack, ID_TK_MENU_DELETE, _(
"Delete") +
"...");
815 wxString itemstp = SYMBOL_STP_TITLE;
816 MenuAppend1(menuTrack, ID_TK_MENU_SENDTOPEER, itemstp);
819 if (menuFocus != menuAIS) menuFocus = menuTrack;
822 if (seltype & SELTYPE_ROUTEPOINT &&
823 !(api_121->GetContextMenuMask() &
824 api_121->kContextMenuDisableWaypoint)) {
825 if (!g_bBasicMenus && m_pFoundRoutePoint) {
826 name = m_pFoundRoutePoint->GetName();
827 if (name.IsEmpty()) name = _(
"Unnamed Waypoint");
828 name.Prepend(
" ( ").Append(
" )");
830 name = wxEmptyString;
832 if (m_pFoundRoutePoint && m_pFoundRoutePoint->
m_bIsInLayer) blay =
true;
835 menuWaypoint =
new wxMenu(_(
"Layer Waypoint") + name);
836 MenuAppend1(menuWaypoint, ID_WP_MENU_PROPERTIES,
837 _(
"Properties") +
"...");
839 if (m_pSelectedRoute && m_pSelectedRoute->IsActive())
840 MenuAppend1(menuWaypoint, ID_RT_MENU_ACTPOINT, _(
"Activate"));
842 menuWaypoint =
new wxMenu(_(
"Waypoint") + name);
843 MenuAppend1(menuWaypoint, ID_WP_MENU_PROPERTIES,
844 _(
"Properties") +
"...");
845 if (m_pSelectedRoute && m_pSelectedRoute->IsActive()) {
847 MenuAppend1(menuWaypoint, ID_RT_MENU_ACTPOINT, _(
"Activate"));
850 if (m_pSelectedRoute && m_pSelectedRoute->IsActive()) {
852 int indexActive = m_pSelectedRoute->GetIndexOf(
854 if (indexActive < m_pSelectedRoute->GetnPoints() - 1)
855 MenuAppend1(menuWaypoint, ID_RT_MENU_ACTNXTPOINT,
856 _(
"Activate Next Waypoint"));
859 if (m_pSelectedRoute && m_pSelectedRoute->GetnPoints() > 2) {
860 MenuAppend1(menuWaypoint, ID_RT_MENU_REMPOINT,
861 _(
"Remove from Route"));
863 m_SelectedIdx = m_pSelectedRoute->GetIndexOf(m_pFoundRoutePoint);
864 if (m_SelectedIdx >= 1 &&
865 m_SelectedIdx < m_pSelectedRoute->GetnPoints() - 1)
866 MenuAppend1(menuWaypoint, ID_RT_MENU_SPLIT_WPT,
867 _(
"Split Route at Waypoint"));
870 MenuAppend1(menuWaypoint, ID_WPT_MENU_COPY, _(
"Copy as KML"));
872 if (m_pFoundRoutePoint && m_pFoundRoutePoint->GetIconName() !=
"mob")
873 MenuAppend1(menuWaypoint, ID_RT_MENU_DELPOINT, _(
"Delete"));
876 wxString port = parent->FindValidUploadPort();
877 parent->m_active_upload_port = port;
878 wxString item = _(
"Send to GPS");
879 if (!port.IsEmpty()) {
884 MenuAppend1(menuWaypoint, ID_WPT_MENU_SENDTOGPS, item);
886 if (!port.IsEmpty()) {
887 wxString item = _(
"Send to new GPS");
888 MenuAppend1(menuWaypoint, ID_WPT_MENU_SENDTONEWGPS, item);
891 MenuAppend1(menuWaypoint, ID_WPT_MENU_SENDTOPEER,
896 if (menuFocus != menuAIS) menuFocus = menuWaypoint;
899 if (seltype & SELTYPE_MARKPOINT &&
900 !(api_121->GetContextMenuMask() &
901 api_121->kContextMenuDisableWaypoint)) {
902 if (!g_bBasicMenus && m_pFoundRoutePoint) {
903 name = m_pFoundRoutePoint->GetName();
904 if (name.IsEmpty()) name = _(
"Unnamed Mark");
905 name.Prepend(
" ( ").Append(
" )");
907 name = wxEmptyString;
909 if (m_pFoundRoutePoint && m_pFoundRoutePoint->
m_bIsInLayer) blay =
true;
912 menuWaypoint =
new wxMenu(_(
"Layer Waypoint") + name);
913 MenuAppend1(menuWaypoint, ID_WP_MENU_PROPERTIES,
914 _(
"Properties") +
"...");
916 menuWaypoint =
new wxMenu(_(
"Mark") + name);
917 MenuAppend1(menuWaypoint, ID_WP_MENU_PROPERTIES,
918 _(
"Properties") +
"...");
921 MenuAppend1(menuWaypoint, ID_WP_MENU_GOTO, _(
"Navigate To This"));
923 MenuAppend1(menuWaypoint, ID_WPT_MENU_COPY, _(
"Copy as KML"));
925 if (m_pFoundRoutePoint && m_pFoundRoutePoint->GetIconName() !=
"mob")
926 MenuAppend1(menuWaypoint, ID_WP_MENU_DELPOINT, _(
"Delete"));
929 wxString port = parent->FindValidUploadPort();
930 parent->m_active_upload_port = port;
931 wxString item = _(
"Send to GPS");
932 if (!port.IsEmpty()) {
937 MenuAppend1(menuWaypoint, ID_WPT_MENU_SENDTOGPS, item);
939 MenuAppend1(menuWaypoint, ID_WPT_MENU_SENDTOPEER,
945 MenuAppend1(menuWaypoint, ID_WP_MENU_CLEAR_ANCHORWATCH,
946 _(
"Clear Anchor Watch"));
948 if (m_pFoundRoutePoint && !(m_pFoundRoutePoint->
m_bIsInLayer) &&
952 DistanceBearingMercator(m_pFoundRoutePoint->m_lat,
953 m_pFoundRoutePoint->m_lon,
gLat,
gLon, &brg,
955 if (dist * 1852. <= g_nAWMax)
956 MenuAppend1(menuWaypoint, ID_WP_MENU_SET_ANCHORWATCH,
957 _(
"Set Anchor Watch"));
962 if (menuFocus != menuAIS) menuFocus = menuWaypoint;
966 AddPluginContextMenuItems(contextMenu, menuRoute, menuTrack, menuWaypoint,
970 enum { WPMENU = 1, TKMENU = 2, RTMENU = 4, MMMENU = 8 };
972 if (!g_bBasicMenus && menuFocus != contextMenu) {
973 if (global_color_scheme != GLOBAL_COLOR_SCHEME_DUSK &&
974 global_color_scheme != GLOBAL_COLOR_SCHEME_NIGHT &&
975 global_color_scheme != GLOBAL_COLOR_SCHEME_NIGHT_HICON) {
976 menuFocus->AppendSeparator();
979 wxMenuItem *subMenu1;
980 if (menuWaypoint && menuFocus != menuWaypoint) {
982 menuFocus->AppendSubMenu(menuWaypoint, menuWaypoint->GetTitle());
983 SetMenuItemFont1(subMenu1);
986 menuWaypoint->SetTitle(wxEmptyString);
989 if (menuTrack && menuFocus != menuTrack) {
990 subMenu1 = menuFocus->AppendSubMenu(menuTrack, menuTrack->GetTitle());
991 SetMenuItemFont1(subMenu1);
994 menuTrack->SetTitle(wxEmptyString);
997 if (menuRoute && menuFocus != menuRoute) {
998 subMenu1 = menuFocus->AppendSubMenu(menuRoute, menuRoute->GetTitle());
999 SetMenuItemFont1(subMenu1);
1002 menuRoute->SetTitle(wxEmptyString);
1005 subMenu1 = menuFocus->AppendSubMenu(contextMenu, _(
"Main Menu"));
1006 SetMenuItemFont1(subMenu1);
1010 if (!subMenuChart->GetMenuItemCount()) contextMenu->Destroy(subItemChart);
1015 if (seltype & SELTYPE_TIDEPOINT) {
1016 menuFocus->AppendSeparator();
1018 MenuAppend1(menuFocus, ID_DEF_MENU_TIDEINFO, _(
"Show Tide Information"));
1021 if (seltype & SELTYPE_CURRENTPOINT) {
1022 if (!bsep) menuFocus->AppendSeparator();
1023 MenuAppend1(menuFocus, ID_DEF_MENU_CURRENTINFO,
1024 _(
"Show Current Information"));
1030 androidEnableBackButton(
false);
1031 androidEnableOptionsMenu(
false);
1039 parent->PopupMenu(menuFocus, x, y);
1042 androidEnableBackButton(
true);
1043 androidEnableOptionsMenu(
true);
1050 if (!(sub_menu & MMMENU))
delete contextMenu;
1051 if (!(sub_menu & RTMENU))
delete menuRoute;
1052 if (!(sub_menu & TKMENU))
delete menuTrack;
1053 if (!(sub_menu & WPMENU))
delete menuWaypoint;
1057void CanvasMenuHandler::AddPluginContextMenuItems(wxMenu *contextMenu,
1060 wxMenu *menuWaypoint,
1066 ArrayOfPlugInMenuItems item_array =
1069 for (
unsigned int i = 0; i < item_array.GetCount(); i++) {
1071 if (!pimis->b_viz)
continue;
1073 wxMenu *submenu = NULL;
1074 if (pimis->pmenu_item->GetSubMenu()) {
1076 auto submenu_proto = pimis->pmenu_item->GetSubMenu();
1077 submenu =
new wxMenu();
1078 const wxMenuItemList &items =
1079 pimis->pmenu_item->GetSubMenu()->GetMenuItems();
1080 for (wxMenuItemList::const_iterator it = items.begin(); it != items.end();
1082 int id = (*it)->GetId();
1084 new wxMenuItem(submenu,
id, (*it)->GetItemLabelText(),
1085 (*it)->GetHelp(), (*it)->GetKind());
1088 psmi->SetFont(m_scaledFont);
1093 psmi->SetFont(sFont);
1096 PrepareMenuItem(psmi);
1097 submenu->Append(psmi);
1098 psmi->Check((*it)->IsChecked());
1102 wxMenuItem *pmi =
new wxMenuItem(
1103 contextMenu, pimis->id, pimis->pmenu_item->GetItemLabelText(),
1104 pimis->pmenu_item->GetHelp(), pimis->pmenu_item->GetKind(), submenu);
1106 pmi->SetFont(m_scaledFont);
1111 pmi->SetFont(sFont);
1114 PrepareMenuItem(pmi);
1116 wxMenu *dst = contextMenu;
1117 if (pimis->m_in_menu ==
"Waypoint")
1119 else if (pimis->m_in_menu ==
"Route")
1121 else if (pimis->m_in_menu ==
"Track")
1123 else if (pimis->m_in_menu ==
"AIS")
1128 dst->Enable(pimis->id, !pimis->b_grey);
1133void CanvasMenuHandler::PopupMenuHandler(wxCommandEvent &event) {
1140 bool dupFirstWpt =
true, showRPD;
1145 switch (event.GetId()) {
1146 case ID_DEF_MENU_MAX_DETAIL:
1149 parent->ClearbFollow();
1151 top_frame::Get()->DoChartUpdate();
1153 parent->SelectChartFromStack(0,
false, CHART_TYPE_DONTCARE,
1154 CHART_FAMILY_RASTER);
1157 case ID_DEF_MENU_SCALE_IN:
1158 parent->DoCanvasStackDelta(-1);
1161 case ID_DEF_MENU_SCALE_OUT:
1162 parent->DoCanvasStackDelta(1);
1166 parent->undo->UndoLastAction();
1167 parent->InvalidateGL();
1168 parent->Refresh(
false);
1172 parent->undo->RedoNextAction();
1173 parent->InvalidateGL();
1174 parent->Refresh(
false);
1177 case ID_DEF_MENU_MOVE_BOAT_HERE:
1180 top_frame::Get()->UpdateStatusBar();
1183 case ID_DEF_MENU_GOTO_HERE: {
1185 wxEmptyString, wxEmptyString);
1186 pSelect->AddSelectableRoutePoint(zlat, zlon, pWP_dest);
1189 wxEmptyString, wxEmptyString);
1195 temp_route->AddPoint(pWP_src);
1196 temp_route->AddPoint(pWP_dest);
1199 pWP_dest, temp_route);
1215 case ID_DEF_MENU_DROP_WP: {
1217 wxEmptyString, wxEmptyString);
1219 pSelect->AddSelectableRoutePoint(zlat, zlon, pWP);
1220 NavObj_dB::GetInstance().InsertRoutePoint(pWP);
1225 if (RouteManagerDialog::getInstanceFlag()) {
1231 parent->undo->BeforeUndoableAction(Undo_CreateWaypoint, pWP,
1232 Undo_HasParent, NULL);
1233 parent->undo->AfterUndoableAction(NULL);
1234 top_frame::Get()->RefreshAllCanvas(
false);
1235 top_frame::Get()->InvalidateAllGL();
1236 g_FlushNavobjChanges =
true;
1240 case ID_DEF_MENU_NEW_RT: {
1241 parent->StartRoute();
1245 case ID_DEF_MENU_AISTARGETLIST:
1246 parent->ShowAISTargetList();
1249 case ID_DEF_MENU_AIS_CPAWARNING:
1250 parent->ToggleCPAWarn();
1253 case ID_WP_MENU_GOTO: {
1255 wxEmptyString, wxEmptyString);
1261 temp_route->AddPoint(pWP_src);
1262 temp_route->AddPoint(m_pFoundRoutePoint);
1263 m_pFoundRoutePoint->SetShared(
true);
1265 pSelect->AddSelectableRouteSegment(
gLat,
gLon, m_pFoundRoutePoint->m_lat,
1266 m_pFoundRoutePoint->m_lon, pWP_src,
1267 m_pFoundRoutePoint, temp_route);
1269 wxString name = m_pFoundRoutePoint->GetName();
1270 if (name.IsEmpty()) name = _(
"(Unnamed Waypoint)");
1271 wxString rteName = _(
"Go to ");
1272 rteName.Append(name);
1286 case ID_DEF_MENU_COGUP:
1287 parent->SetUpMode(COURSE_UP_MODE);
1290 case ID_DEF_MENU_HEADUP:
1291 parent->SetUpMode(HEAD_UP_MODE);
1294 case ID_DEF_MENU_NORTHUP:
1295 parent->SetUpMode(NORTH_UP_MODE);
1298 case ID_DEF_MENU_TOGGLE_FULL:
1299 top_frame::Get()->ToggleFullScreen();
1302 case ID_DEF_MENU_GOTOPOSITION:
1311 case ID_WP_MENU_DELPOINT: {
1320 if (m_pFoundRoutePoint && !(m_pFoundRoutePoint->
m_bIsInLayer) &&
1321 (m_pFoundRoutePoint->GetIconName() !=
"mob")) {
1325 wxArrayPtrVoid *proute_array =
1328 pWayPointMan->DestroyWaypoint(m_pFoundRoutePoint);
1329 delete proute_array;
1331 parent->undo->BeforeUndoableAction(
1332 Undo_DeleteWaypoint, m_pFoundRoutePoint, Undo_IsOrphanded,
1334 NavObj_dB::GetInstance().DeleteRoutePoint(m_pFoundRoutePoint);
1335 pSelect->DeleteSelectablePoint(m_pFoundRoutePoint,
1336 SELTYPE_ROUTEPOINT);
1337 if (NULL != pWayPointMan)
1339 parent->undo->AfterUndoableAction(NULL);
1346 if (RouteManagerDialog::getInstanceFlag()) {
1352 top_frame::Get()->RefreshAllCanvas(
false);
1353 top_frame::Get()->InvalidateAllGL();
1357 case ID_WP_MENU_PROPERTIES:
1358 parent->ShowMarkPropertiesDialog(m_pFoundRoutePoint);
1361 case ID_WP_MENU_CLEAR_ANCHORWATCH: {
1362 wxString guid = wxEmptyString;
1372 if (!guid.IsEmpty()) {
1375 SendJsonMessageToAllPlugins(
"OCPN_ANCHOR_WATCH_CLEARED", v);
1380 case ID_WP_MENU_SET_ANCHORWATCH: {
1381 wxString guid = wxEmptyString;
1387 nn = m_pFoundRoutePoint->GetName();
1389 nn.Printf(
"%d m", g_nAWDefault);
1390 m_pFoundRoutePoint->SetName(nn);
1397 nn = m_pFoundRoutePoint->GetName();
1399 nn.Printf(
"%d m", g_nAWDefault);
1400 m_pFoundRoutePoint->SetName(nn);
1403 if (!guid.IsEmpty()) {
1406 SendJsonMessageToAllPlugins(
"OCPN_ANCHOR_WATCH_SET", v);
1411 case ID_DEF_MENU_ACTIVATE_MEASURE:
1412 parent->StartMeasureRoute();
1415 case ID_DEF_MENU_DEACTIVATE_MEASURE:
1416 parent->CancelMeasureRoute();
1418 parent->InvalidateGL();
1419 parent->Refresh(
false);
1422 case ID_DEF_MENU_CM93OFFSET_DIALOG: {
1428 if (!parent->GetVP().b_quilt && parent->m_singleChart &&
1429 (parent->m_singleChart->GetChartType() == CHART_TYPE_CM93COMP)) {
1441 case ID_DEF_MENU_QUERY: {
1442 parent->ShowObjectQueryWindow(popx, popy, zlat, zlon);
1445 case ID_DEF_MENU_AIS_QUERY: {
1446 ShowAISTargetQueryDialog(parent, m_FoundAIS_MMSI);
1450 case ID_DEF_MENU_AIS_CPA: {
1451 auto myptarget =
g_pAIS->Get_Target_Data_From_MMSI(m_FoundAIS_MMSI);
1452 if (myptarget) myptarget->Toggle_AIS_CPA();
1456 case ID_DEF_MENU_AISSHOWTRACK: {
1457 auto myptarget =
g_pAIS->Get_Target_Data_From_MMSI(m_FoundAIS_MMSI);
1458 if (myptarget) myptarget->ToggleShowTrack();
1462 case ID_DEF_MENU_COPY_MMSI: {
1464 if (wxTheClipboard->Open()) {
1465 wxTheClipboard->SetData(
1466 new wxTextDataObject(wxString::Format(
"%09d", m_FoundAIS_MMSI)));
1467 wxTheClipboard->Close();
1472 case ID_DEF_MENU_QUILTREMOVE: {
1473 if (parent->GetVP().b_quilt) {
1474 int dbIndex = parent->m_pQuilt->GetChartdbIndexAtPix(
1475 parent->GetVP(), wxPoint(popx, popy));
1476 parent->RemoveChartFromQuilt(dbIndex);
1484 case ID_DEF_MENU_CURRENTINFO: {
1485 parent->
DrawTCWindow(popx, popy, (
void *)m_pIDXCandidate);
1486 parent->Refresh(
false);
1491 case ID_DEF_MENU_TIDEINFO: {
1492 parent->
DrawTCWindow(popx, popy, (
void *)m_pIDXCandidate);
1493 parent->Refresh(
false);
1498 case ID_DGB_MENU_NMEA_WINDOW:
1500 m_nmea_log->Raise();
1503 case ID_RT_MENU_REVERSE: {
1507 OCPNMessageBox(parent,
g_pRouteMan->GetRouteReverseMessage(),
1508 _(
"Rename Waypoints?"), wxYES_NO | wxCANCEL);
1510 if (ask_return != wxID_CANCEL) {
1511 pSelect->DeleteAllSelectableRouteSegments(m_pSelectedRoute);
1512 m_pSelectedRoute->Reverse(ask_return == wxID_YES);
1513 pSelect->AddAllSelectableRouteSegments(m_pSelectedRoute);
1515 NavObj_dB::GetInstance().UpdateRoute(m_pSelectedRoute);
1521 top_frame::Get()->InvalidateAllGL();
1522 top_frame::Get()->RefreshAllCanvas();
1527 case ID_RT_MENU_SHOWNAMES: {
1528 if (m_pSelectedRoute) {
1529 m_pSelectedRoute->ShowWaypointNames(
1530 !m_pSelectedRoute->AreWaypointNamesVisible());
1536 case ID_RT_MENU_RESEQUENCE: {
1537 if (m_pSelectedRoute) {
1541 OCPNMessageBox(parent,
g_pRouteMan->GetRouteResequenceMessage(),
1542 _(
"Rename Waypoints?"), wxYES_NO | wxCANCEL);
1544 if (ask_return != wxID_CANCEL) {
1545 m_pSelectedRoute->RenameRoutePoints();
1548 top_frame::Get()->InvalidateAllGL();
1549 top_frame::Get()->RefreshAllCanvas();
1555 case ID_RT_MENU_DELETE: {
1556 bool confirmed = RouteGui::OnDelete(parent);
1559 if (
g_pRouteMan->GetpActiveRoute() == m_pSelectedRoute)
1564 NavObj_dB::GetInstance().DeleteRoute(m_pSelectedRoute);
1567 if (RouteManagerDialog::getInstanceFlag()) {
1577 parent->undo->InvalidateUndo();
1579 top_frame::Get()->InvalidateAllGL();
1580 top_frame::Get()->RefreshAllCanvas();
1585 case ID_RT_MENU_ACTIVATE: {
1592 if (m_pSelectedRoute) {
1597 best_point = m_pSelectedRoute->GetPoint(2);
1606 case ID_RT_MENU_DEACTIVATE:
1612 case ID_RT_MENU_INSERT: {
1614 bool rename =
false;
1615 m_pSelectedRoute->InsertPointAfter(m_pFoundRoutePoint, zlat, zlon,
1618 pSelect->DeleteAllSelectableRoutePoints(m_pSelectedRoute);
1619 pSelect->DeleteAllSelectableRouteSegments(m_pSelectedRoute);
1621 pSelect->AddAllSelectableRouteSegments(m_pSelectedRoute);
1622 pSelect->AddAllSelectableRoutePoints(m_pSelectedRoute);
1635 NavObj_dB::GetInstance().UpdateRoute(m_pSelectedRoute);
1644 case ID_RT_MENU_APPEND:
1648 parent->m_pMouseRoute = m_pSelectedRoute;
1649 parent->m_routeState = m_pSelectedRoute->GetnPoints() + 1;
1651 m_pSelectedRoute->GetnPoints();
1652 parent->m_pMouseRoute->SetHiLite(50);
1654 pLast = m_pSelectedRoute->GetLastPoint();
1656 parent->m_prev_rlat = pLast->m_lat;
1657 parent->m_prev_rlon = pLast->m_lon;
1658 parent->m_prev_pMousePoint = pLast;
1660 parent->m_bAppendingRoute =
true;
1662 parent->SetCursor(*parent->pCursorPencil);
1664 androidSetRouteAnnunciator(
true);
1667 parent->HideGlobalToolbar();
1671 case ID_RT_MENU_SPLIT_LEG:
1673 dupFirstWpt =
false;
1674 case ID_RT_MENU_SPLIT_WPT:
1678 if (
g_pRouteMan->GetpActiveRoute() == m_pSelectedRoute)
1681 m_pHead =
new Route();
1682 m_pTail =
new Route();
1683 m_pHead->CloneRoute(m_pSelectedRoute, 1, m_SelectedIdx + 1, _(
"_A"));
1684 m_pTail->CloneRoute(m_pSelectedRoute, m_SelectedIdx + 1 + splitMode,
1685 m_pSelectedRoute->GetnPoints(), _(
"_B"), dupFirstWpt);
1687 NavObj_dB::GetInstance().InsertRoute(m_pHead);
1690 NavObj_dB::GetInstance().InsertRoute(m_pTail);
1692 NavObj_dB::GetInstance().DeleteRoute(m_pSelectedRoute);
1694 pSelect->DeleteAllSelectableRoutePoints(m_pSelectedRoute);
1695 pSelect->DeleteAllSelectableRouteSegments(m_pSelectedRoute);
1697 pSelect->AddAllSelectableRouteSegments(m_pTail);
1698 pSelect->AddAllSelectableRoutePoints(m_pTail);
1699 pSelect->AddAllSelectableRouteSegments(m_pHead);
1700 pSelect->AddAllSelectableRoutePoints(m_pHead);
1711 case ID_RT_MENU_COPY:
1712 if (m_pSelectedRoute) Kml::CopyRouteToClipboard(m_pSelectedRoute);
1715 case ID_TK_MENU_COPY:
1716 if (m_pSelectedTrack) Kml::CopyTrackToClipboard(m_pSelectedTrack);
1719 case ID_WPT_MENU_COPY:
1720 if (m_pFoundRoutePoint) Kml::CopyWaypointToClipboard(m_pFoundRoutePoint);
1723 case ID_WPT_MENU_SENDTOGPS:
1724 if (m_pFoundRoutePoint) {
1725 if (parent->m_active_upload_port.Length())
1727 .SendToGPS(parent->m_active_upload_port.BeforeFirst(
' '), NULL);
1730 dlg.SetWaypoint(m_pFoundRoutePoint);
1734 dlg.Create(NULL, -1, _(
"Send to GPS") +
"...",
"");
1740 case ID_WPT_MENU_SENDTONEWGPS:
1741 if (m_pFoundRoutePoint) {
1743 dlg.SetWaypoint(m_pFoundRoutePoint);
1745 dlg.Create(NULL, -1, _(
"Send to GPS") +
"...",
"");
1750 case ID_WPT_MENU_SENDTOPEER:
1751 if (m_pFoundRoutePoint) {
1753 dlg.SetWaypoint(m_pFoundRoutePoint);
1758 MdnsCache::GetInstance().
Validate();
1759 if (MdnsCache::GetInstance().GetCache().empty())
1760 dlg.SetScanOnCreate(
true);
1763 dlg.Create(NULL, -1, _(
"Send Waypoint to OpenCPN Peer") +
"...",
"");
1768 case ID_RT_MENU_SENDTOGPS:
1769 if (m_pSelectedRoute) {
1770 if (parent->m_active_upload_port.Length())
1772 .SendToGPS(parent->m_active_upload_port.BeforeFirst(
' '),
true,
1776 dlg.SetRoute(m_pSelectedRoute);
1778 dlg.Create(NULL, -1, _(
"Send to GPS") +
"...",
"");
1784 case ID_RT_MENU_SENDTONEWGPS:
1785 if (m_pSelectedRoute) {
1787 dlg.SetRoute(m_pSelectedRoute);
1789 dlg.Create(NULL, -1, _(
"Send to GPS") +
"...",
"");
1794 case ID_RT_MENU_SENDTOPEER:
1795 if (m_pSelectedRoute) {
1797 dlg.SetRoute(m_pSelectedRoute);
1802 MdnsCache::GetInstance().
Validate();
1803 if (MdnsCache::GetInstance().GetCache().empty())
1804 dlg.SetScanOnCreate(
true);
1807 dlg.Create(NULL, -1, _(
"Send Route to OpenCPN Peer") +
"...",
"");
1812 case ID_PASTE_WAYPOINT:
1813 pupHandler_PasteWaypoint();
1816 case ID_PASTE_ROUTE:
1817 pupHandler_PasteRoute();
1820 case ID_PASTE_TRACK:
1821 pupHandler_PasteTrack();
1824 case ID_RT_MENU_DELPOINT:
1825 if (m_pSelectedRoute) {
1828 pWayPointMan->DestroyWaypoint(m_pFoundRoutePoint);
1833 if (
g_pRouteMan->IsRouteValid(m_pSelectedRoute)) {
1839 if (RouteManagerDialog::getInstanceFlag()) {
1846 top_frame::Get()->InvalidateAllGL();
1847 top_frame::Get()->RefreshAllCanvas(
true);
1852 case ID_RT_MENU_REMPOINT:
1853 if (m_pSelectedRoute) {
1855 g_pRouteMan->RemovePointFromRoute(m_pFoundRoutePoint, m_pSelectedRoute,
1856 parent->m_routeState);
1857 top_frame::Get()->InvalidateAllGL();
1858 top_frame::Get()->RefreshAllCanvas();
1862 case ID_RT_MENU_ACTPOINT:
1863 if (
g_pRouteMan->GetpActiveRoute() == m_pSelectedRoute) {
1870 case ID_RT_MENU_DEACTPOINT:
1873 case ID_RT_MENU_ACTNXTPOINT:
1874 if (
g_pRouteMan->GetpActiveRoute() == m_pSelectedRoute) {
1881 case ID_RT_MENU_PROPERTIES: {
1882 parent->ShowRoutePropertiesDialog(_(
"Route Properties"),
1887 case ID_TK_MENU_PROPERTIES: {
1888 parent->ShowTrackPropertiesDialog(m_pSelectedTrack);
1892 case ID_TK_MENU_DELETE: {
1893 int dlg_return = wxID_YES;
1894 if (g_bConfirmObjectDelete) {
1895 dlg_return = OCPNMessageBox(
1896 parent, _(
"Are you sure you want to delete this track?"),
1897 _(
"OpenCPN Track Delete"),
1898 (
long)wxYES_NO | wxCANCEL | wxYES_DEFAULT);
1901 if (dlg_return == wxID_YES) {
1903 m_pSelectedTrack = top_frame::Get()->TrackOff();
1904 g_pAIS->DeletePersistentTrack(m_pSelectedTrack);
1906 NavObj_dB::GetInstance().DeleteTrack(m_pSelectedTrack);
1907 RoutemanGui(*g_pRouteMan).DeleteTrack(m_pSelectedTrack);
1920 top_frame::Get()->InvalidateAllGL();
1921 top_frame::Get()->RefreshAllCanvas();
1926 case ID_TK_MENU_SENDTOPEER:
1927 if (m_pSelectedTrack) {
1929 dlg.SetTrack(m_pSelectedTrack);
1934 MdnsCache::GetInstance().
Validate();
1935 if (MdnsCache::GetInstance().GetCache().empty())
1936 dlg.SetScanOnCreate(
true);
1939 dlg.Create(NULL, -1, _(
"Send Track to OpenCPN Peer") +
"...",
"");
1944 case ID_RC_MENU_SCALE_IN:
1945 top_frame::Get()->DoStackDown(parent);
1947 parent->WarpPointer(r.x, r.y);
1950 case ID_RC_MENU_SCALE_OUT:
1951 top_frame::Get()->DoStackUp(parent);
1953 parent->WarpPointer(r.x, r.y);
1956 case ID_RC_MENU_ZOOM_IN:
1959 parent->WarpPointer(r.x, r.y);
1962 case ID_RC_MENU_ZOOM_OUT:
1965 parent->WarpPointer(r.x, r.y);
1968 case ID_RC_MENU_FINISH:
1969 parent->FinishRoute();
1971 parent->Refresh(
false);
1972 g_FlushNavobjChanges =
true;
1975 case ID_DEF_ZERO_XTE:
1982 ArrayOfPlugInMenuItems item_array =
1985 for (
unsigned int i = 0; i < item_array.GetCount(); i++) {
1987 int target_id = pimis->id;
1990 if (pimis->pmenu_item->GetSubMenu()) {
1991 const wxMenuItemList &items =
1992 pimis->pmenu_item->GetSubMenu()->GetMenuItems();
1993 for (wxMenuItemList::const_iterator it = items.begin();
1994 it != items.end(); ++it) {
1995 if ((*it)->GetId() ==
event.GetId()) {
1996 target_id = (*it)->GetId();
2002 if (pimis->m_pplugin && (target_id == event.GetId())) {
2003 if (pimis->extended) {
2004 std::string object_type;
2005 std::string object_ident;
2007 if ((pimis->m_in_menu.IsSameAs(
"Waypoint")) && m_pFoundRoutePoint) {
2008 object_type =
"Waypoint";
2009 object_ident = m_pFoundRoutePoint->
m_GUID.ToStdString();
2010 }
else if ((pimis->m_in_menu.IsSameAs(
"Route")) &&
2012 object_type =
"Route";
2013 object_ident = m_pSelectedRoute->
m_GUID.ToStdString();
2014 }
else if ((pimis->m_in_menu.IsSameAs(
"Track")) &&
2016 object_type =
"Track";
2017 object_ident = m_pSelectedTrack->m_GUID.ToStdString();
2018 }
else if ((pimis->m_in_menu.IsSameAs(
"AIS")) && m_FoundAIS_MMSI) {
2019 object_type =
"AIS";
2020 wxString sAIS = wxString::Format(
"%d", m_FoundAIS_MMSI);
2021 object_ident = sAIS.ToStdString();
2027 ppi->OnContextMenuItemCallbackExt(target_id, object_ident,
2028 object_type, zlat, zlon);
2039 if ((event.GetId() >= ID_DEF_MENU_GROUPBASE) &&
2042 parent->SetGroupIndex(event.GetId() - ID_DEF_MENU_GROUPBASE);
2045 parent->InvalidateGL();
AisDecoder * g_pAIS
Global instance.
Class AisDecoder and helpers.
Global state for AIS decoder.
std::unique_ptr< HostApi > GetHostApi()
HostApi factory,.
Charts database management
ChartGroupArray * g_pGroupArray
Global instance.
Basic chart info storage.
Generic Chart canvas base.
Dialog for managing CM93 chart offsets.
Base class for all chart types.
ChartCanvas - Main chart display and interaction component.
bool GetCanvasPointPix(double rlat, double rlon, wxPoint *r)
Convert latitude/longitude to canvas pixel coordinates (physical pixels) rounded to nearest integer.
double GetDisplayScale()
Get the ratio of physical to logical pixel for the display.
bool SetVPScale(double sc, bool b_refresh=true)
Sets the viewport scale while maintaining the center point.
float GetVPScale() override
Return ViewPort scale factor, in physical pixels per meter.
void GetCanvasPixPoint(double x, double y, double &lat, double &lon)
Convert canvas pixel coordinates (physical pixels) to latitude/longitude.
void DrawTCWindow(int x, int y, void *pIDX)
Legacy tide dialog creation method.
Locked down interface published in 5.14.0.
void Validate()
Check that all entries are accessible, remove stale ones.
Represents a waypoint or mark within the navigation system.
wxString m_GUID
Globally Unique Identifier for the waypoint.
bool m_bIsolatedMark
Flag indicating if the waypoint is a standalone mark.
bool m_bIsInLayer
Flag indicating if the waypoint belongs to a layer.
Represents a navigational route in the navigation system.
bool m_bRtIsSelected
Flag indicating whether this route is currently selected in the UI.
wxString m_RouteStartString
Name or description of the route's starting point.
bool m_bDeleteOnArrival
Flag indicating whether the route should be deleted once navigation reaches the end.
wxString m_RouteEndString
Name or description of the route's ending point.
RoutePoint * m_pRouteActivePoint
Pointer to the currently active waypoint within this route.
wxString m_RouteNameString
User-assigned name for the route.
wxString m_GUID
Globally unique identifier for this route.
bool m_bIsInLayer
Flag indicating whether this route belongs to a layer.
int m_lastMousePointIndex
Index of the most recently interacted with route point.
bool ActivateRoutePoint(Route *pA, RoutePoint *pRP)
Activates a specific waypoint within a route for navigation.
wxArrayPtrVoid * GetRouteArrayContaining(RoutePoint *pWP)
Find all routes that contain the given waypoint.
bool ActivateNextPoint(Route *pr, bool skipped)
Activates the next waypoint in a route when the current waypoint is reached.
bool DeleteRoute(Route *pRoute)
bool ActivateRoute(Route *pRouteToActivate, RoutePoint *pStartPoint=NULL)
Activates a route for navigation.
Dialog for sending routes/waypoints to a GPS device.
Dialog for sending navigation objects to peer devices.
Represents a track, which is a series of connected track points.
bool RemoveRoutePoint(RoutePoint *prp)
Remove a routepoint from list if present, deallocate it all cases.
Represents a composite CM93 chart covering multiple scales.
virtual void OnContextMenuItemCallback(int id)
Handles context menu item selection.
CM93OffsetDialog * g_pCM93OffsetDialog
Global instance.
Class cm93chart and helpers – CM93 chart state.
Global variables stored in configuration file.
GoToPositionDialog * pGoToPositionDialog
Global instance.
wxFont * GetOCPNScaledFont(wxString item, int default_size)
Retrieves a font from FontMgr, optionally scaled for physical readability.
wxFont GetOCPNGUIScaledFont(wxString item)
Retrieves a font optimized for touch and high-resolution interfaces.
double vLat
Virtual lat from chcanv popup.
double vLon
Virtual lon from chcanv popup.
double g_androidDPmm
Only used used by ANDROID
Miscellaneous globals primarely used by gui layer, not persisted in configuration file.
Read and write KML Format.
MarkInfoDlg * g_pMarkInfoDialog
global instance
Waypoint properties maintenance dialog.
MySQL based storage for routes, tracks, etc.
bool bGPSValid
Indicate whether the Global Navigation Satellite System (GNSS) has a valid position.
double gHdt
True heading in degrees (0-359.99).
double gLat
Vessel's current latitude in decimal degrees.
double gCog
Course over ground in degrees (0-359.99).
double gSog
Speed over ground in knots.
double gLon
Vessel's current longitude in decimal degrees.
Position, course, speed, etc.
Confirm peer transfer PIN code dialog.
Tools to send data to plugins.
PlugInManager * g_pi_manager
Global instance.
PlugInManager and helper classes – Mostly gui parts (dialogs) and plugin API stuff.
Purpose: Track and Trackpoint drawing stuff.
RoutePropDlgImpl * pRoutePropDialog
Global instance.
RoutePoint * pAnchorWatchPoint2
Global instance.
Routeman * g_pRouteMan
Global instance.
RouteList * pRouteList
Global instance.
RoutePoint * pAnchorWatchPoint1
Global instance.
RouteManagerDialog * pRouteManagerDialog
Global instance.
Select * pSelect
Global instance.
Selected route, segment, waypoint, etc.
Send route/waypoint to GPS dialog.
Send Route/Waypoint/Track to peer dialog.
Tide and Current Manager @TODO Add original author copyright.
Abstract gFrame/MyFrame interface.
ActiveTrack * g_pActiveTrack
global instance
Recorded track abstraction.
Track and Trackpoint drawing stuff.
TrackPropDlg * pTrackPropDialog
Global instance.
Framework for Undo features.