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 "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 menuFocus->AppendSeparator();
978 wxMenuItem *subMenu1;
979 if (menuWaypoint && menuFocus != menuWaypoint) {
981 menuFocus->AppendSubMenu(menuWaypoint, menuWaypoint->GetTitle());
982 SetMenuItemFont1(subMenu1);
985 menuWaypoint->SetTitle(wxEmptyString);
988 if (menuTrack && menuFocus != menuTrack) {
989 subMenu1 = menuFocus->AppendSubMenu(menuTrack, menuTrack->GetTitle());
990 SetMenuItemFont1(subMenu1);
993 menuTrack->SetTitle(wxEmptyString);
996 if (menuRoute && menuFocus != menuRoute) {
997 subMenu1 = menuFocus->AppendSubMenu(menuRoute, menuRoute->GetTitle());
998 SetMenuItemFont1(subMenu1);
1001 menuRoute->SetTitle(wxEmptyString);
1004 subMenu1 = menuFocus->AppendSubMenu(contextMenu, _(
"Main Menu"));
1005 SetMenuItemFont1(subMenu1);
1009 if (!subMenuChart->GetMenuItemCount()) contextMenu->Destroy(subItemChart);
1014 if (seltype & SELTYPE_TIDEPOINT) {
1015 menuFocus->AppendSeparator();
1017 MenuAppend1(menuFocus, ID_DEF_MENU_TIDEINFO, _(
"Show Tide Information"));
1020 if (seltype & SELTYPE_CURRENTPOINT) {
1021 if (!bsep) menuFocus->AppendSeparator();
1022 MenuAppend1(menuFocus, ID_DEF_MENU_CURRENTINFO,
1023 _(
"Show Current Information"));
1029 androidEnableBackButton(
false);
1030 androidEnableOptionsMenu(
false);
1038 parent->PopupMenu(menuFocus, x, y);
1041 androidEnableBackButton(
true);
1042 androidEnableOptionsMenu(
true);
1049 if (!(sub_menu & MMMENU))
delete contextMenu;
1050 if (!(sub_menu & RTMENU))
delete menuRoute;
1051 if (!(sub_menu & TKMENU))
delete menuTrack;
1052 if (!(sub_menu & WPMENU))
delete menuWaypoint;
1056void CanvasMenuHandler::AddPluginContextMenuItems(wxMenu *contextMenu,
1059 wxMenu *menuWaypoint,
1065 ArrayOfPlugInMenuItems item_array =
1068 for (
unsigned int i = 0; i < item_array.GetCount(); i++) {
1070 if (!pimis->b_viz)
continue;
1072 wxMenu *submenu = NULL;
1073 if (pimis->pmenu_item->GetSubMenu()) {
1075 auto submenu_proto = pimis->pmenu_item->GetSubMenu();
1076 submenu =
new wxMenu();
1077 const wxMenuItemList &items =
1078 pimis->pmenu_item->GetSubMenu()->GetMenuItems();
1079 for (wxMenuItemList::const_iterator it = items.begin(); it != items.end();
1081 int id = (*it)->GetId();
1083 new wxMenuItem(submenu,
id, (*it)->GetItemLabelText(),
1084 (*it)->GetHelp(), (*it)->GetKind());
1087 psmi->SetFont(m_scaledFont);
1092 psmi->SetFont(sFont);
1095 PrepareMenuItem(psmi);
1096 submenu->Append(psmi);
1097 psmi->Check((*it)->IsChecked());
1101 wxMenuItem *pmi =
new wxMenuItem(
1102 contextMenu, pimis->id, pimis->pmenu_item->GetItemLabelText(),
1103 pimis->pmenu_item->GetHelp(), pimis->pmenu_item->GetKind(), submenu);
1105 pmi->SetFont(m_scaledFont);
1110 pmi->SetFont(sFont);
1113 PrepareMenuItem(pmi);
1115 wxMenu *dst = contextMenu;
1116 if (pimis->m_in_menu ==
"Waypoint")
1118 else if (pimis->m_in_menu ==
"Route")
1120 else if (pimis->m_in_menu ==
"Track")
1122 else if (pimis->m_in_menu ==
"AIS")
1127 dst->Enable(pimis->id, !pimis->b_grey);
1132void CanvasMenuHandler::PopupMenuHandler(wxCommandEvent &event) {
1139 bool dupFirstWpt =
true, showRPD;
1144 switch (event.GetId()) {
1145 case ID_DEF_MENU_MAX_DETAIL:
1148 parent->ClearbFollow();
1150 top_frame::Get()->DoChartUpdate();
1152 parent->SelectChartFromStack(0,
false, CHART_TYPE_DONTCARE,
1153 CHART_FAMILY_RASTER);
1156 case ID_DEF_MENU_SCALE_IN:
1157 parent->DoCanvasStackDelta(-1);
1160 case ID_DEF_MENU_SCALE_OUT:
1161 parent->DoCanvasStackDelta(1);
1165 parent->undo->UndoLastAction();
1166 parent->InvalidateGL();
1167 parent->Refresh(
false);
1171 parent->undo->RedoNextAction();
1172 parent->InvalidateGL();
1173 parent->Refresh(
false);
1176 case ID_DEF_MENU_MOVE_BOAT_HERE:
1179 top_frame::Get()->UpdateStatusBar();
1182 case ID_DEF_MENU_GOTO_HERE: {
1184 wxEmptyString, wxEmptyString);
1185 pSelect->AddSelectableRoutePoint(zlat, zlon, pWP_dest);
1188 wxEmptyString, wxEmptyString);
1194 temp_route->AddPoint(pWP_src);
1195 temp_route->AddPoint(pWP_dest);
1198 pWP_dest, temp_route);
1214 case ID_DEF_MENU_DROP_WP: {
1216 wxEmptyString, wxEmptyString);
1218 pSelect->AddSelectableRoutePoint(zlat, zlon, pWP);
1219 NavObj_dB::GetInstance().InsertRoutePoint(pWP);
1224 if (RouteManagerDialog::getInstanceFlag()) {
1230 parent->undo->BeforeUndoableAction(Undo_CreateWaypoint, pWP,
1231 Undo_HasParent, NULL);
1232 parent->undo->AfterUndoableAction(NULL);
1233 top_frame::Get()->RefreshAllCanvas(
false);
1234 top_frame::Get()->InvalidateAllGL();
1235 g_FlushNavobjChanges =
true;
1239 case ID_DEF_MENU_NEW_RT: {
1240 parent->StartRoute();
1244 case ID_DEF_MENU_AISTARGETLIST:
1245 parent->ShowAISTargetList();
1248 case ID_DEF_MENU_AIS_CPAWARNING:
1249 parent->ToggleCPAWarn();
1252 case ID_WP_MENU_GOTO: {
1254 wxEmptyString, wxEmptyString);
1260 temp_route->AddPoint(pWP_src);
1261 temp_route->AddPoint(m_pFoundRoutePoint);
1262 m_pFoundRoutePoint->SetShared(
true);
1264 pSelect->AddSelectableRouteSegment(
gLat,
gLon, m_pFoundRoutePoint->m_lat,
1265 m_pFoundRoutePoint->m_lon, pWP_src,
1266 m_pFoundRoutePoint, temp_route);
1268 wxString name = m_pFoundRoutePoint->GetName();
1269 if (name.IsEmpty()) name = _(
"(Unnamed Waypoint)");
1270 wxString rteName = _(
"Go to ");
1271 rteName.Append(name);
1285 case ID_DEF_MENU_COGUP:
1286 parent->SetUpMode(COURSE_UP_MODE);
1289 case ID_DEF_MENU_HEADUP:
1290 parent->SetUpMode(HEAD_UP_MODE);
1293 case ID_DEF_MENU_NORTHUP:
1294 parent->SetUpMode(NORTH_UP_MODE);
1297 case ID_DEF_MENU_TOGGLE_FULL:
1298 top_frame::Get()->ToggleFullScreen();
1301 case ID_DEF_MENU_GOTOPOSITION:
1310 case ID_WP_MENU_DELPOINT: {
1319 if (m_pFoundRoutePoint && !(m_pFoundRoutePoint->
m_bIsInLayer) &&
1320 (m_pFoundRoutePoint->GetIconName() !=
"mob")) {
1324 wxArrayPtrVoid *proute_array =
1327 pWayPointMan->DestroyWaypoint(m_pFoundRoutePoint);
1328 delete proute_array;
1330 parent->undo->BeforeUndoableAction(
1331 Undo_DeleteWaypoint, m_pFoundRoutePoint, Undo_IsOrphanded,
1333 NavObj_dB::GetInstance().DeleteRoutePoint(m_pFoundRoutePoint);
1334 pSelect->DeleteSelectablePoint(m_pFoundRoutePoint,
1335 SELTYPE_ROUTEPOINT);
1336 if (NULL != pWayPointMan)
1338 parent->undo->AfterUndoableAction(NULL);
1345 if (RouteManagerDialog::getInstanceFlag()) {
1351 top_frame::Get()->RefreshAllCanvas(
false);
1352 top_frame::Get()->InvalidateAllGL();
1356 case ID_WP_MENU_PROPERTIES:
1357 parent->ShowMarkPropertiesDialog(m_pFoundRoutePoint);
1360 case ID_WP_MENU_CLEAR_ANCHORWATCH: {
1361 wxString guid = wxEmptyString;
1371 if (!guid.IsEmpty()) {
1374 SendJsonMessageToAllPlugins(
"OCPN_ANCHOR_WATCH_CLEARED", v);
1379 case ID_WP_MENU_SET_ANCHORWATCH: {
1380 wxString guid = wxEmptyString;
1386 nn = m_pFoundRoutePoint->GetName();
1388 nn.Printf(
"%d m", g_nAWDefault);
1389 m_pFoundRoutePoint->SetName(nn);
1396 nn = m_pFoundRoutePoint->GetName();
1398 nn.Printf(
"%d m", g_nAWDefault);
1399 m_pFoundRoutePoint->SetName(nn);
1402 if (!guid.IsEmpty()) {
1405 SendJsonMessageToAllPlugins(
"OCPN_ANCHOR_WATCH_SET", v);
1410 case ID_DEF_MENU_ACTIVATE_MEASURE:
1411 parent->StartMeasureRoute();
1414 case ID_DEF_MENU_DEACTIVATE_MEASURE:
1415 parent->CancelMeasureRoute();
1417 parent->InvalidateGL();
1418 parent->Refresh(
false);
1421 case ID_DEF_MENU_CM93OFFSET_DIALOG: {
1427 if (!parent->GetVP().b_quilt && parent->m_singleChart &&
1428 (parent->m_singleChart->GetChartType() == CHART_TYPE_CM93COMP)) {
1440 case ID_DEF_MENU_QUERY: {
1441 parent->ShowObjectQueryWindow(popx, popy, zlat, zlon);
1444 case ID_DEF_MENU_AIS_QUERY: {
1445 ShowAISTargetQueryDialog(parent, m_FoundAIS_MMSI);
1449 case ID_DEF_MENU_AIS_CPA: {
1450 auto myptarget =
g_pAIS->Get_Target_Data_From_MMSI(m_FoundAIS_MMSI);
1451 if (myptarget) myptarget->Toggle_AIS_CPA();
1455 case ID_DEF_MENU_AISSHOWTRACK: {
1456 auto myptarget =
g_pAIS->Get_Target_Data_From_MMSI(m_FoundAIS_MMSI);
1457 if (myptarget) myptarget->ToggleShowTrack();
1461 case ID_DEF_MENU_COPY_MMSI: {
1463 if (wxTheClipboard->Open()) {
1464 wxTheClipboard->SetData(
1465 new wxTextDataObject(wxString::Format(
"%09d", m_FoundAIS_MMSI)));
1466 wxTheClipboard->Close();
1471 case ID_DEF_MENU_QUILTREMOVE: {
1472 if (parent->GetVP().b_quilt) {
1473 int dbIndex = parent->m_pQuilt->GetChartdbIndexAtPix(
1474 parent->GetVP(), wxPoint(popx, popy));
1475 parent->RemoveChartFromQuilt(dbIndex);
1483 case ID_DEF_MENU_CURRENTINFO: {
1484 parent->
DrawTCWindow(popx, popy, (
void *)m_pIDXCandidate);
1485 parent->Refresh(
false);
1490 case ID_DEF_MENU_TIDEINFO: {
1491 parent->
DrawTCWindow(popx, popy, (
void *)m_pIDXCandidate);
1492 parent->Refresh(
false);
1497 case ID_DGB_MENU_NMEA_WINDOW:
1499 m_nmea_log->Raise();
1502 case ID_RT_MENU_REVERSE: {
1506 OCPNMessageBox(parent,
g_pRouteMan->GetRouteReverseMessage(),
1507 _(
"Rename Waypoints?"), wxYES_NO | wxCANCEL);
1509 if (ask_return != wxID_CANCEL) {
1510 pSelect->DeleteAllSelectableRouteSegments(m_pSelectedRoute);
1511 m_pSelectedRoute->Reverse(ask_return == wxID_YES);
1512 pSelect->AddAllSelectableRouteSegments(m_pSelectedRoute);
1514 NavObj_dB::GetInstance().UpdateRoute(m_pSelectedRoute);
1520 top_frame::Get()->InvalidateAllGL();
1521 top_frame::Get()->RefreshAllCanvas();
1526 case ID_RT_MENU_SHOWNAMES: {
1527 if (m_pSelectedRoute) {
1528 m_pSelectedRoute->ShowWaypointNames(
1529 !m_pSelectedRoute->AreWaypointNamesVisible());
1535 case ID_RT_MENU_RESEQUENCE: {
1536 if (m_pSelectedRoute) {
1540 OCPNMessageBox(parent,
g_pRouteMan->GetRouteResequenceMessage(),
1541 _(
"Rename Waypoints?"), wxYES_NO | wxCANCEL);
1543 if (ask_return != wxID_CANCEL) {
1544 m_pSelectedRoute->RenameRoutePoints();
1547 top_frame::Get()->InvalidateAllGL();
1548 top_frame::Get()->RefreshAllCanvas();
1554 case ID_RT_MENU_DELETE: {
1555 bool confirmed = RouteGui::OnDelete(parent);
1558 if (
g_pRouteMan->GetpActiveRoute() == m_pSelectedRoute)
1563 NavObj_dB::GetInstance().DeleteRoute(m_pSelectedRoute);
1566 if (RouteManagerDialog::getInstanceFlag()) {
1576 parent->undo->InvalidateUndo();
1578 top_frame::Get()->InvalidateAllGL();
1579 top_frame::Get()->RefreshAllCanvas();
1584 case ID_RT_MENU_ACTIVATE: {
1591 if (m_pSelectedRoute) {
1596 best_point = m_pSelectedRoute->GetPoint(2);
1605 case ID_RT_MENU_DEACTIVATE:
1611 case ID_RT_MENU_INSERT: {
1613 bool rename =
false;
1614 m_pSelectedRoute->InsertPointAfter(m_pFoundRoutePoint, zlat, zlon,
1617 pSelect->DeleteAllSelectableRoutePoints(m_pSelectedRoute);
1618 pSelect->DeleteAllSelectableRouteSegments(m_pSelectedRoute);
1620 pSelect->AddAllSelectableRouteSegments(m_pSelectedRoute);
1621 pSelect->AddAllSelectableRoutePoints(m_pSelectedRoute);
1634 NavObj_dB::GetInstance().UpdateRoute(m_pSelectedRoute);
1643 case ID_RT_MENU_APPEND:
1647 parent->m_pMouseRoute = m_pSelectedRoute;
1648 parent->m_routeState = m_pSelectedRoute->GetnPoints() + 1;
1650 m_pSelectedRoute->GetnPoints();
1651 parent->m_pMouseRoute->SetHiLite(50);
1653 pLast = m_pSelectedRoute->GetLastPoint();
1655 parent->m_prev_rlat = pLast->m_lat;
1656 parent->m_prev_rlon = pLast->m_lon;
1657 parent->m_prev_pMousePoint = pLast;
1659 parent->m_bAppendingRoute =
true;
1661 parent->SetCursor(*parent->pCursorPencil);
1663 androidSetRouteAnnunciator(
true);
1666 parent->HideGlobalToolbar();
1670 case ID_RT_MENU_SPLIT_LEG:
1672 dupFirstWpt =
false;
1673 case ID_RT_MENU_SPLIT_WPT:
1677 if (
g_pRouteMan->GetpActiveRoute() == m_pSelectedRoute)
1680 m_pHead =
new Route();
1681 m_pTail =
new Route();
1682 m_pHead->CloneRoute(m_pSelectedRoute, 1, m_SelectedIdx + 1, _(
"_A"));
1683 m_pTail->CloneRoute(m_pSelectedRoute, m_SelectedIdx + 1 + splitMode,
1684 m_pSelectedRoute->GetnPoints(), _(
"_B"), dupFirstWpt);
1686 NavObj_dB::GetInstance().InsertRoute(m_pHead);
1689 NavObj_dB::GetInstance().InsertRoute(m_pTail);
1691 NavObj_dB::GetInstance().DeleteRoute(m_pSelectedRoute);
1693 pSelect->DeleteAllSelectableRoutePoints(m_pSelectedRoute);
1694 pSelect->DeleteAllSelectableRouteSegments(m_pSelectedRoute);
1696 pSelect->AddAllSelectableRouteSegments(m_pTail);
1697 pSelect->AddAllSelectableRoutePoints(m_pTail);
1698 pSelect->AddAllSelectableRouteSegments(m_pHead);
1699 pSelect->AddAllSelectableRoutePoints(m_pHead);
1710 case ID_RT_MENU_COPY:
1711 if (m_pSelectedRoute) Kml::CopyRouteToClipboard(m_pSelectedRoute);
1714 case ID_TK_MENU_COPY:
1715 if (m_pSelectedTrack) Kml::CopyTrackToClipboard(m_pSelectedTrack);
1718 case ID_WPT_MENU_COPY:
1719 if (m_pFoundRoutePoint) Kml::CopyWaypointToClipboard(m_pFoundRoutePoint);
1722 case ID_WPT_MENU_SENDTOGPS:
1723 if (m_pFoundRoutePoint) {
1724 if (parent->m_active_upload_port.Length())
1726 .SendToGPS(parent->m_active_upload_port.BeforeFirst(
' '), NULL);
1729 dlg.SetWaypoint(m_pFoundRoutePoint);
1733 dlg.Create(NULL, -1, _(
"Send to GPS") +
"...",
"");
1739 case ID_WPT_MENU_SENDTONEWGPS:
1740 if (m_pFoundRoutePoint) {
1742 dlg.SetWaypoint(m_pFoundRoutePoint);
1744 dlg.Create(NULL, -1, _(
"Send to GPS") +
"...",
"");
1749 case ID_WPT_MENU_SENDTOPEER:
1750 if (m_pFoundRoutePoint) {
1752 dlg.SetWaypoint(m_pFoundRoutePoint);
1757 MdnsCache::GetInstance().
Validate();
1758 if (MdnsCache::GetInstance().GetCache().empty())
1759 dlg.SetScanOnCreate(
true);
1762 dlg.Create(NULL, -1, _(
"Send Waypoint to OpenCPN Peer") +
"...",
"");
1767 case ID_RT_MENU_SENDTOGPS:
1768 if (m_pSelectedRoute) {
1769 if (parent->m_active_upload_port.Length())
1771 .SendToGPS(parent->m_active_upload_port.BeforeFirst(
' '),
true,
1775 dlg.SetRoute(m_pSelectedRoute);
1777 dlg.Create(NULL, -1, _(
"Send to GPS") +
"...",
"");
1783 case ID_RT_MENU_SENDTONEWGPS:
1784 if (m_pSelectedRoute) {
1786 dlg.SetRoute(m_pSelectedRoute);
1788 dlg.Create(NULL, -1, _(
"Send to GPS") +
"...",
"");
1793 case ID_RT_MENU_SENDTOPEER:
1794 if (m_pSelectedRoute) {
1796 dlg.SetRoute(m_pSelectedRoute);
1801 MdnsCache::GetInstance().
Validate();
1802 if (MdnsCache::GetInstance().GetCache().empty())
1803 dlg.SetScanOnCreate(
true);
1806 dlg.Create(NULL, -1, _(
"Send Route to OpenCPN Peer") +
"...",
"");
1811 case ID_PASTE_WAYPOINT:
1812 pupHandler_PasteWaypoint();
1815 case ID_PASTE_ROUTE:
1816 pupHandler_PasteRoute();
1819 case ID_PASTE_TRACK:
1820 pupHandler_PasteTrack();
1823 case ID_RT_MENU_DELPOINT:
1824 if (m_pSelectedRoute) {
1827 pWayPointMan->DestroyWaypoint(m_pFoundRoutePoint);
1832 if (
g_pRouteMan->IsRouteValid(m_pSelectedRoute)) {
1838 if (RouteManagerDialog::getInstanceFlag()) {
1845 top_frame::Get()->InvalidateAllGL();
1846 top_frame::Get()->RefreshAllCanvas(
true);
1851 case ID_RT_MENU_REMPOINT:
1852 if (m_pSelectedRoute) {
1854 g_pRouteMan->RemovePointFromRoute(m_pFoundRoutePoint, m_pSelectedRoute,
1855 parent->m_routeState);
1856 top_frame::Get()->InvalidateAllGL();
1857 top_frame::Get()->RefreshAllCanvas();
1861 case ID_RT_MENU_ACTPOINT:
1862 if (
g_pRouteMan->GetpActiveRoute() == m_pSelectedRoute) {
1869 case ID_RT_MENU_DEACTPOINT:
1872 case ID_RT_MENU_ACTNXTPOINT:
1873 if (
g_pRouteMan->GetpActiveRoute() == m_pSelectedRoute) {
1880 case ID_RT_MENU_PROPERTIES: {
1881 parent->ShowRoutePropertiesDialog(_(
"Route Properties"),
1886 case ID_TK_MENU_PROPERTIES: {
1887 parent->ShowTrackPropertiesDialog(m_pSelectedTrack);
1891 case ID_TK_MENU_DELETE: {
1892 int dlg_return = wxID_YES;
1893 if (g_bConfirmObjectDelete) {
1894 dlg_return = OCPNMessageBox(
1895 parent, _(
"Are you sure you want to delete this track?"),
1896 _(
"OpenCPN Track Delete"),
1897 (
long)wxYES_NO | wxCANCEL | wxYES_DEFAULT);
1900 if (dlg_return == wxID_YES) {
1902 m_pSelectedTrack = top_frame::Get()->TrackOff();
1903 g_pAIS->DeletePersistentTrack(m_pSelectedTrack);
1905 NavObj_dB::GetInstance().DeleteTrack(m_pSelectedTrack);
1906 RoutemanGui(*g_pRouteMan).DeleteTrack(m_pSelectedTrack);
1919 top_frame::Get()->InvalidateAllGL();
1920 top_frame::Get()->RefreshAllCanvas();
1925 case ID_TK_MENU_SENDTOPEER:
1926 if (m_pSelectedTrack) {
1928 dlg.SetTrack(m_pSelectedTrack);
1933 MdnsCache::GetInstance().
Validate();
1934 if (MdnsCache::GetInstance().GetCache().empty())
1935 dlg.SetScanOnCreate(
true);
1938 dlg.Create(NULL, -1, _(
"Send Track to OpenCPN Peer") +
"...",
"");
1943 case ID_RC_MENU_SCALE_IN:
1944 top_frame::Get()->DoStackDown(parent);
1946 parent->WarpPointer(r.x, r.y);
1949 case ID_RC_MENU_SCALE_OUT:
1950 top_frame::Get()->DoStackUp(parent);
1952 parent->WarpPointer(r.x, r.y);
1955 case ID_RC_MENU_ZOOM_IN:
1958 parent->WarpPointer(r.x, r.y);
1961 case ID_RC_MENU_ZOOM_OUT:
1964 parent->WarpPointer(r.x, r.y);
1967 case ID_RC_MENU_FINISH:
1968 parent->FinishRoute();
1970 parent->Refresh(
false);
1971 g_FlushNavobjChanges =
true;
1974 case ID_DEF_ZERO_XTE:
1981 ArrayOfPlugInMenuItems item_array =
1984 for (
unsigned int i = 0; i < item_array.GetCount(); i++) {
1986 int target_id = pimis->id;
1989 if (pimis->pmenu_item->GetSubMenu()) {
1990 const wxMenuItemList &items =
1991 pimis->pmenu_item->GetSubMenu()->GetMenuItems();
1992 for (wxMenuItemList::const_iterator it = items.begin();
1993 it != items.end(); ++it) {
1994 if ((*it)->GetId() ==
event.GetId()) {
1995 target_id = (*it)->GetId();
2001 if (pimis->m_pplugin && (target_id == event.GetId())) {
2002 if (pimis->extended) {
2003 std::string object_type;
2004 std::string object_ident;
2006 if ((pimis->m_in_menu.IsSameAs(
"Waypoint")) && m_pFoundRoutePoint) {
2007 object_type =
"Waypoint";
2008 object_ident = m_pFoundRoutePoint->
m_GUID.ToStdString();
2009 }
else if ((pimis->m_in_menu.IsSameAs(
"Route")) &&
2011 object_type =
"Route";
2012 object_ident = m_pSelectedRoute->
m_GUID.ToStdString();
2013 }
else if ((pimis->m_in_menu.IsSameAs(
"Track")) &&
2015 object_type =
"Track";
2016 object_ident = m_pSelectedTrack->m_GUID.ToStdString();
2017 }
else if ((pimis->m_in_menu.IsSameAs(
"AIS")) && m_FoundAIS_MMSI) {
2018 object_type =
"AIS";
2019 wxString sAIS = wxString::Format(
"%d", m_FoundAIS_MMSI);
2020 object_ident = sAIS.ToStdString();
2026 ppi->OnContextMenuItemCallbackExt(target_id, object_ident,
2027 object_type, zlat, zlon);
2038 if ((event.GetId() >= ID_DEF_MENU_GROUPBASE) &&
2041 parent->SetGroupIndex(event.GetId() - ID_DEF_MENU_GROUPBASE);
2044 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.1.
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.