27#include <wx/aui/aui.h>
28#include <wx/clipbrd.h>
29#include <wx/dynarray.h>
33#include <wx/graphics.h>
35#include <wx/listbook.h>
83#include "androidUTIL.h"
88 ID_DEF_MENU_MAX_DETAIL = 1,
90 ID_DEF_MENU_SCALE_OUT,
94 ID_DEF_MENU_MOVE_BOAT_HERE,
95 ID_DEF_MENU_GOTO_HERE,
96 ID_DEF_MENU_GOTOPOSITION,
99 ID_WP_MENU_PROPERTIES,
101 ID_RT_MENU_DEACTIVATE,
105 ID_RT_MENU_SPLIT_LEG,
106 ID_RT_MENU_SPLIT_WPT,
109 ID_WPT_MENU_SENDTOGPS,
110 ID_WPT_MENU_SENDTONEWGPS,
111 ID_WPT_MENU_SENDTOPEER,
119 ID_RT_MENU_DEACTPOINT,
120 ID_RT_MENU_ACTNXTPOINT,
122 ID_RT_MENU_PROPERTIES,
123 ID_RT_MENU_SENDTOGPS,
124 ID_RT_MENU_SENDTONEWGPS,
125 ID_RT_MENU_SHOWNAMES,
126 ID_RT_MENU_RESEQUENCE,
127 ID_RT_MENU_SENDTOPEER,
128 ID_WP_MENU_SET_ANCHORWATCH,
129 ID_WP_MENU_CLEAR_ANCHORWATCH,
130 ID_DEF_MENU_AISTARGETLIST,
131 ID_DEF_MENU_AIS_CPAWARNING,
134 ID_RC_MENU_SCALE_OUT,
138 ID_DEF_MENU_AIS_QUERY,
140 ID_DEF_MENU_AISSHOWTRACK,
141 ID_DEF_MENU_ACTIVATE_MEASURE,
142 ID_DEF_MENU_DEACTIVATE_MEASURE,
143 ID_DEF_MENU_COPY_MMSI,
148 ID_DEF_MENU_CM93OFFSET_DIALOG,
150 ID_TK_MENU_PROPERTIES,
152 ID_TK_MENU_SENDTOPEER,
153 ID_WP_MENU_ADDITIONAL_INFO,
155 ID_DEF_MENU_QUILTREMOVE,
159 ID_DEF_MENU_TOGGLE_FULL,
160 ID_DEF_MENU_TIDEINFO,
161 ID_DEF_MENU_CURRENTINFO,
165 ID_DGB_MENU_NMEA_WINDOW,
167 ID_DEF_MENU_GROUPBASE,
176int CanvasMenuHandler::GetNextContextMenuId() {
177 return ID_DEF_MENU_LAST +
181wxFont CanvasMenuHandler::m_scaledFont;
184CanvasMenuHandler::CanvasMenuHandler(
ChartCanvas *parentCanvas,
187 int selectedAIS_MMSI,
188 void *selectedTCIndex, wxWindow *nmea_log)
189 : m_nmea_log(nmea_log) {
190 parent = parentCanvas;
191 m_pSelectedRoute = selectedRoute;
192 m_pSelectedTrack = selectedTrack;
193 m_pFoundRoutePoint = selectedPoint;
194 m_FoundAIS_MMSI = selectedAIS_MMSI;
195 m_pIDXCandidate = selectedTCIndex;
196 if (!m_scaledFont.IsOk()) {
198 m_scaledFont = *qFont;
204CanvasMenuHandler::~CanvasMenuHandler() {}
210void CanvasMenuHandler::PrepareMenuItem(wxMenuItem *item) {
211#if defined(__WXMSW__)
212 wxColour ctrl_back_color = GetGlobalColor(
"DILG1");
213 item->SetBackgroundColour(ctrl_back_color);
214 wxColour menu_text_color = GetGlobalColor(
"UITX1");
215 item->SetTextColour(menu_text_color);
219void CanvasMenuHandler::MenuPrepend1(wxMenu *menu,
int id, wxString label) {
220 wxMenuItem *item =
new wxMenuItem(menu,
id, label);
221#if defined(__WXMSW__)
222 item->SetFont(m_scaledFont);
227 item->SetFont(sFont);
230 PrepareMenuItem(item);
232 if (g_btouch) menu->InsertSeparator(0);
236void CanvasMenuHandler::MenuAppend1(wxMenu *menu,
int id, wxString label) {
237 wxMenuItem *item =
new wxMenuItem(menu,
id, label);
238#if defined(__WXMSW__)
239 item->SetFont(m_scaledFont);
244 item->SetFont(sFont);
247 PrepareMenuItem(item);
250 if (g_btouch) menu->AppendSeparator();
253void CanvasMenuHandler::SetMenuItemFont1(wxMenuItem *item) {
254#if defined(__WXMSW__)
255 item->SetFont(m_scaledFont);
258#if defined(__ANDROID__)
260 item->SetFont(*qFont);
263 PrepareMenuItem(item);
266void CanvasMenuHandler::CanvasPopupMenu(
int x,
int y,
int seltype) {
267 wxMenu *contextMenu =
new wxMenu;
268 wxMenu *menuWaypoint = NULL;
269 wxMenu *menuRoute = NULL;
270 wxMenu *menuTrack = NULL;
271 wxMenu *menuAIS = NULL;
273 wxMenu *subMenuChart =
new wxMenu;
274 wxMenu *subMenuUndo =
new wxMenu(
"Undo...Ctrl-Z");
277 wxMenu *subMenuRedo =
new wxMenu(
"Redo...Shift-Ctrl-Z");
279 wxMenu *subMenuRedo =
new wxMenu(
"Redo...Ctrl-Y");
281 wxMenu *subMenuDebug =
new wxMenu(
"");
282 MenuAppend1(subMenuDebug, ID_DGB_MENU_NMEA_WINDOW, _(
"Show Data Monitor"));
284 wxMenu *menuFocus = contextMenu;
289 if (!g_bBasicMenus || (seltype != SELTYPE_ROUTECREATE)) {
290 bool bsubMenus =
false;
293 if (parent->undo->AnythingToUndo()) {
295 wxMenuItem *subMenuItemundo =
296 contextMenu->AppendSubMenu(subMenuUndo, _(
"Undo"));
299 undoItem << _(
"Undo") <<
" "
300 << parent->undo->GetNextUndoableAction()->Description();
301 MenuAppend1(subMenuUndo, ID_UNDO, undoItem);
303 if (parent->undo->AnythingToRedo()) {
305 wxMenuItem *subMenuItemRedo =
306 contextMenu->AppendSubMenu(subMenuRedo, _(
"Redo"));
309 redoItem << _(
"Redo") <<
" "
310 << parent->undo->GetNextRedoableAction()->Description();
311 MenuAppend1(subMenuRedo, ID_REDO, redoItem);
314 if (parent->undo->AnythingToUndo()) {
316 undoItem << _(
"Undo") <<
" "
317 << parent->undo->GetNextUndoableAction()->Description();
318 MenuAppend1(contextMenu, ID_UNDO, _menuText(undoItem,
"Ctrl-Z"));
321 if (parent->undo->AnythingToRedo()) {
323 redoItem << _(
"Redo") <<
" "
324 << parent->undo->GetNextRedoableAction()->Description();
326 MenuAppend1(contextMenu, ID_REDO, _menuText(redoItem,
"Shift-Ctrl-Z"));
328 MenuAppend1(contextMenu, ID_REDO, _menuText(redoItem,
"Ctrl-Y"));
334 if (seltype == SELTYPE_ROUTECREATE) {
335 MenuAppend1(contextMenu, ID_RC_MENU_FINISH,
336 _menuText(_(
"End Route"),
"Esc"));
339 if (!parent->m_pMouseRoute) {
340 if (parent->m_bMeasure_Active)
341 MenuAppend1(contextMenu, ID_DEF_MENU_DEACTIVATE_MEASURE,
342 _menuText(_(
"Measure Off"),
"Esc"));
344 MenuAppend1(contextMenu, ID_DEF_MENU_ACTIVATE_MEASURE,
345 _menuText(_(
"Measure"),
"M"));
348 bool ais_areanotice =
false;
349 if (
g_pAIS && parent->GetShowAIS() && g_bShowAreaNotices) {
352 for (
const auto &target :
g_pAIS->GetAreaNoticeSourcesList()) {
353 auto target_data = target.second;
354 if (!target_data->area_notices.empty()) {
355 for (
auto &ani : target_data->area_notices) {
359 for (Ais8_001_22_SubAreaList::iterator sa =
360 area_notice.sub_areas.begin();
361 sa != area_notice.sub_areas.end(); ++sa) {
363 case AIS8_001_22_SHAPE_CIRCLE: {
364 wxPoint target_point;
367 bbox.Expand(target_point);
368 if (sa->radius_m > 0.0) bbox.EnLarge(sa->radius_m * vp_scale);
371 case AIS8_001_22_SHAPE_RECT:
372 case AIS8_001_22_SHAPE_POLYGON:
373 case AIS8_001_22_SHAPE_POLYLINE: {
374 double lat = sa->latitude;
375 double lon = sa->longitude;
376 for (
int i = 0; i < 4; ++i) {
377 ll_gc_ll(lat, lon, sa->angles[i], sa->dists_m[i] / 1852.0,
379 wxPoint target_point;
381 bbox.Expand(target_point);
385 case AIS8_001_22_SHAPE_SECTOR: {
386 double lat1 = sa->latitude;
387 double lon1 = sa->longitude;
389 wxPoint target_point;
391 bbox.Expand(target_point);
392 for (
int i = 0; i < 18; ++i) {
396 i * (sa->right_bound_deg - sa->left_bound_deg) / 18,
397 sa->radius_m / 1852.0, &lat, &lon);
399 bbox.Expand(target_point);
401 ll_gc_ll(lat1, lon1, sa->right_bound_deg, sa->radius_m / 1852.0,
404 bbox.Expand(target_point);
410 if (bbox.GetValid() && bbox.PointInBox(x, y)) {
411 ais_areanotice =
true;
420 if (parent->GetpCurrentStack())
421 nChartStack = parent->GetpCurrentStack()->nEntry;
423 if (!parent->GetVP().b_quilt) {
424 if (nChartStack > 1) {
425 MenuAppend1(contextMenu, ID_DEF_MENU_MAX_DETAIL, _(
"Max Detail Here"));
426 MenuAppend1(contextMenu, ID_DEF_MENU_SCALE_IN,
427 _menuText(_(
"Scale In"),
"Ctrl-Left"));
428 MenuAppend1(contextMenu, ID_DEF_MENU_SCALE_OUT,
429 _menuText(_(
"Scale Out"),
"Ctrl-Right"));
432 if ((parent->m_singleChart &&
433 (parent->m_singleChart->GetChartFamily() == CHART_FAMILY_VECTOR)) ||
435 MenuAppend1(contextMenu, ID_DEF_MENU_QUERY, _(
"Object Query") +
"...");
440 parent->m_pQuilt->GetChartAtPix(parent->GetVP(), wxPoint(x, y));
441 if ((pChartTest && (pChartTest->GetChartFamily() == CHART_FAMILY_VECTOR)) ||
443 MenuAppend1(contextMenu, ID_DEF_MENU_QUERY, _(
"Object Query") +
"...");
446 if (!g_bBasicMenus && (nChartStack > 1)) {
447 MenuAppend1(contextMenu, ID_DEF_MENU_SCALE_IN,
448 _menuText(_(
"Scale In"),
"Ctrl-Left"));
449 MenuAppend1(contextMenu, ID_DEF_MENU_SCALE_OUT,
450 _menuText(_(
"Scale Out"),
"Ctrl-Right"));
456 if (!g_bBasicMenus || (seltype != SELTYPE_ROUTECREATE)) {
457 bool b_dm_add =
true;
458 if (g_btouch && parent->IsMeasureActive()) b_dm_add =
false;
461 MenuAppend1(contextMenu, ID_DEF_MENU_DROP_WP,
462 _menuText(_(
"Drop Mark"),
"Ctrl-M"));
463 MenuAppend1(contextMenu, ID_DEF_MENU_NEW_RT,
464 _menuText(_(
"New Route..."),
"Ctrl-R"));
468 MenuAppend1(contextMenu, ID_DEF_MENU_MOVE_BOAT_HERE, _(
"Move Boat Here"));
471 if (!g_bBasicMenus && !
g_pRouteMan->GetpActiveRoute() &&
472 (!(seltype & SELTYPE_MARKPOINT) ||
473 (m_pFoundRoutePoint && m_pFoundRoutePoint->
m_bIsInLayer)))
474 MenuAppend1(contextMenu, ID_DEF_MENU_GOTO_HERE, _(
"Navigate To Here"));
477 MenuAppend1(contextMenu, ID_DEF_MENU_GOTOPOSITION,
478 _(
"Center view") +
"...");
480 if (!g_bBasicMenus) {
481 if (parent->GetVP().b_quilt) {
482 if (parent->GetUpMode() == NORTH_UP_MODE) {
483 MenuAppend1(contextMenu, ID_DEF_MENU_COGUP, _(
"Course Up Mode"));
484 if (!std::isnan(
gHdt))
485 MenuAppend1(contextMenu, ID_DEF_MENU_HEADUP, _(
"Heading Up Mode"));
487 MenuAppend1(contextMenu, ID_DEF_MENU_NORTHUP, _(
"North Up Mode"));
490 if (parent->m_singleChart &&
491 (fabs(parent->m_singleChart->GetChartSkew()) > .01) && !g_bskew_comp)
492 MenuAppend1(contextMenu, ID_DEF_MENU_NORTHUP, _(
"Chart Up Mode"));
494 MenuAppend1(contextMenu, ID_DEF_MENU_NORTHUP, _(
"North Up Mode"));
498 if (!g_bBasicMenus) {
499 bool full_toggle_added =
false;
502 MenuAppend1(contextMenu, ID_DEF_MENU_TOGGLE_FULL,
503 _(
"Toggle Full Screen"));
504 full_toggle_added =
true;
507 if (!full_toggle_added) {
509 MenuAppend1(contextMenu, ID_DEF_MENU_TOGGLE_FULL,
510 _(
"Toggle Full Screen"));
516 MenuAppend1(contextMenu, ID_DEF_ZERO_XTE, _(
"Zero XTE"));
519 int pasteBuffer = kml->ParsePasteBuffer();
520 if (pasteBuffer != KML_PASTE_INVALID) {
521 switch (pasteBuffer) {
522 case KML_PASTE_WAYPOINT: {
523 MenuAppend1(contextMenu, ID_PASTE_WAYPOINT, _(
"Paste Waypoint"));
526 case KML_PASTE_ROUTE: {
527 MenuAppend1(contextMenu, ID_PASTE_ROUTE, _(
"Paste Route"));
530 case KML_PASTE_TRACK: {
531 MenuAppend1(contextMenu, ID_PASTE_TRACK, _(
"Paste Track"));
534 case KML_PASTE_ROUTE_TRACK: {
535 MenuAppend1(contextMenu, ID_PASTE_ROUTE, _(
"Paste Route"));
536 MenuAppend1(contextMenu, ID_PASTE_TRACK, _(
"Paste Track"));
543 if (!parent->GetVP().b_quilt && parent->m_singleChart &&
544 (parent->m_singleChart->GetChartType() == CHART_TYPE_CM93COMP)) {
545 MenuAppend1(contextMenu, ID_DEF_MENU_CM93OFFSET_DIALOG,
546 _(
"CM93 Offset Dialog..."));
570 wxMenuItem *subItemChart =
571 contextMenu->AppendSubMenu(subMenuChart, _(
"Chart Groups"));
572 if (g_btouch) contextMenu->AppendSeparator();
574 SetMenuItemFont1(subItemChart);
578 MenuAppend1(subMenuChart, wxID_CANCEL, _(
"temporary"));
580 wxMenuItem *subItem0 = subMenuChart->AppendRadioItem(
581 ID_DEF_MENU_GROUPBASE, _(
"All Active Charts"));
583 SetMenuItemFont1(subItem0);
585 for (
unsigned int i = 0; i <
g_pGroupArray->GetCount(); i++) {
586 subItem0 = subMenuChart->AppendRadioItem(
587 ID_DEF_MENU_GROUPBASE + i + 1,
g_pGroupArray->Item(i)->m_group_name);
588 SetMenuItemFont1(subItem0);
592 subMenuChart->Remove(wxID_CANCEL);
594 subMenuChart->Check(ID_DEF_MENU_GROUPBASE + parent->m_groupIndex,
true);
598 menuFocus = contextMenu;
601 if (!g_bBasicMenus || (seltype != SELTYPE_ROUTECREATE)) {
603 if (parent->GetShowAIS() &&
604 (seltype & SELTYPE_AISTARGET &&
605 !(GetContextMenuMask() & CONTEXT_MENU_DISABLE_AISTARGET))) {
606 auto myptarget =
g_pAIS->Get_Target_Data_From_MMSI(m_FoundAIS_MMSI);
607 if (!g_bBasicMenus && myptarget) {
608 name = myptarget->GetFullName();
609 if (name.IsEmpty()) name.Printf(
"%d", m_FoundAIS_MMSI);
610 name.Prepend(
" ( ").Append(
" )");
612 name = wxEmptyString;
613 menuAIS =
new wxMenu(_(
"AIS") + name);
614 MenuAppend1(menuAIS, ID_DEF_MENU_AIS_QUERY, _(
"Target Query..."));
615 if (myptarget && myptarget->bCPA_Valid &&
616 (myptarget->n_alert_state != AIS_ALERT_SET)) {
617 if (myptarget->b_show_AIS_CPA)
618 MenuAppend1(menuAIS, ID_DEF_MENU_AIS_CPA, _(
"Hide Target CPA"));
620 MenuAppend1(menuAIS, ID_DEF_MENU_AIS_CPA, _(
"Show Target CPA"));
622 MenuAppend1(menuAIS, ID_DEF_MENU_AISTARGETLIST, _(
"Target List..."));
623 if (myptarget->Class != AIS_METEO ) {
624 if (myptarget && !myptarget->b_PersistTrack) {
625 if (myptarget->b_show_track)
626 MenuAppend1(menuAIS, ID_DEF_MENU_AISSHOWTRACK,
627 _(
"Hide Target Track"));
629 MenuAppend1(menuAIS, ID_DEF_MENU_AISSHOWTRACK,
630 _(
"Show Target Track"));
634 MenuAppend1(menuAIS, ID_DEF_MENU_COPY_MMSI, _(
"Copy Target MMSI"));
635 menuAIS->AppendSeparator();
637 if (!parent->GetVP().b_quilt) {
638 if ((parent->m_singleChart &&
639 (parent->m_singleChart->GetChartFamily() ==
640 CHART_FAMILY_VECTOR))) {
641 MenuAppend1(menuAIS, ID_DEF_MENU_QUERY, _(
"Object Query..."));
646 parent->m_pQuilt->GetChartAtPix(parent->GetVP(), wxPoint(x, y));
648 (pChartTest->GetChartFamily() == CHART_FAMILY_VECTOR))) {
649 MenuAppend1(menuAIS, ID_DEF_MENU_QUERY, _(
"Object Query..."));
655 bool enable_list =
true;
657 double char_x = gFrame->GetSize().x / gFrame->GetCharWidth();
658 double char_y = gFrame->GetSize().y / gFrame->GetCharWidth();
659 double char_min = wxMin(char_x, char_y);
660 if (char_min < 100) enable_list =
false;
664 if (wxMin(size_x, size_y) < 100)
668 MenuAppend1(contextMenu, ID_DEF_MENU_AISTARGETLIST,
669 _(
"AIS target list") +
"...");
671 wxString nextCPAstatus = g_bCPAWarn ? _(
"Hide") : _(
"Show");
672 MenuAppend1(contextMenu, ID_DEF_MENU_AIS_CPAWARNING,
673 _menuText(nextCPAstatus +
" " + _(
"CPA alarm "),
"W"));
677 if (g_enable_root_menu_debug) {
678 wxMenuItem *subItemDebug =
679 contextMenu->AppendSubMenu(subMenuDebug, _(
"Debug"));
680 if (g_btouch) contextMenu->AppendSeparator();
681 SetMenuItemFont1(subItemDebug);
684 if (seltype & SELTYPE_ROUTESEGMENT &&
685 !(GetContextMenuMask() & CONTEXT_MENU_DISABLE_ROUTE)) {
686 if (!g_bBasicMenus && m_pSelectedRoute) {
688 if (name.IsEmpty()) name = _(
"Unnamed Route");
689 name.Prepend(
" ( ").Append(
" )");
691 name = wxEmptyString;
693 if (m_pSelectedRoute && m_pSelectedRoute->
m_bIsInLayer) blay =
true;
696 menuRoute =
new wxMenu(_(
"Layer Route") + name);
697 MenuAppend1(menuRoute, ID_RT_MENU_PROPERTIES, _(
"Properties") +
"...");
698 if (m_pSelectedRoute) {
699 if (m_pSelectedRoute->IsActive()) {
700 int indexActive = m_pSelectedRoute->GetIndexOf(
702 if ((indexActive + 1) <= m_pSelectedRoute->GetnPoints()) {
703 MenuAppend1(menuRoute, ID_RT_MENU_ACTNXTPOINT,
704 _(
"Activate Next Waypoint"));
706 MenuAppend1(menuRoute, ID_RT_MENU_DEACTIVATE, _(
"Deactivate"));
707 MenuAppend1(menuRoute, ID_DEF_ZERO_XTE, _(
"Zero XTE"));
709 MenuAppend1(menuRoute, ID_RT_MENU_ACTIVATE, _(
"Activate"));
713 menuRoute =
new wxMenu(_(
"Route") + name);
714 MenuAppend1(menuRoute, ID_RT_MENU_PROPERTIES, _(
"Properties") +
"...");
715 if (m_pSelectedRoute) {
716 if (m_pSelectedRoute->IsActive()) {
717 int indexActive = m_pSelectedRoute->GetIndexOf(
719 if ((indexActive + 1) <= m_pSelectedRoute->GetnPoints()) {
720 MenuAppend1(menuRoute, ID_RT_MENU_ACTNXTPOINT,
721 _(
"Activate Next Waypoint"));
723 MenuAppend1(menuRoute, ID_RT_MENU_DEACTIVATE, _(
"Deactivate"));
724 MenuAppend1(menuRoute, ID_DEF_ZERO_XTE, _(
"Zero XTE"));
726 MenuAppend1(menuRoute, ID_RT_MENU_ACTIVATE, _(
"Activate"));
729 MenuAppend1(menuRoute, ID_RT_MENU_INSERT, _(
"Insert Waypoint"));
730 MenuAppend1(menuRoute, ID_RT_MENU_APPEND, _(
"Append Waypoint"));
731 if (!(seltype & SELTYPE_ROUTEPOINT) && m_pSelectedRoute) {
732 m_SelectedIdx = m_pSelectedRoute->GetIndexOf(m_pFoundRoutePoint);
733 if (m_SelectedIdx > 1 &&
734 m_SelectedIdx < m_pSelectedRoute->GetnPoints() - 1)
735 MenuAppend1(menuRoute, ID_RT_MENU_SPLIT_LEG, _(
"Split around Leg"));
737 MenuAppend1(menuRoute, ID_RT_MENU_COPY, _(
"Copy as KML") +
"...");
738 MenuAppend1(menuRoute, ID_RT_MENU_DELETE, _(
"Delete") +
"...");
739 MenuAppend1(menuRoute, ID_RT_MENU_REVERSE, _(
"Reverse..."));
740 if (m_pSelectedRoute) {
741 if (m_pSelectedRoute->AreWaypointNamesVisible())
742 MenuAppend1(menuRoute, ID_RT_MENU_SHOWNAMES,
743 _(
"Hide Waypoint Names"));
745 MenuAppend1(menuRoute, ID_RT_MENU_SHOWNAMES,
746 _(
"Show Waypoint Names"));
748 MenuAppend1(menuRoute, ID_RT_MENU_RESEQUENCE,
749 _(
"Resequence Waypoints..."));
752 wxString port = parent->FindValidUploadPort();
753 parent->m_active_upload_port = port;
754 wxString item = _(
"Send to GPS");
755 if (!port.IsEmpty()) {
760 MenuAppend1(menuRoute, ID_RT_MENU_SENDTOGPS, item);
762 if (!port.IsEmpty()) {
763 wxString item = _(
"Send to new GPS");
764 MenuAppend1(menuRoute, ID_RT_MENU_SENDTONEWGPS, item);
767 wxString itemstp = SYMBOL_STP_TITLE;
768 MenuAppend1(menuRoute, ID_RT_MENU_SENDTOPEER, itemstp);
771 if (menuFocus != menuAIS) menuFocus = menuRoute;
774 if (seltype & SELTYPE_TRACKSEGMENT &&
775 !(GetContextMenuMask() & CONTEXT_MENU_DISABLE_TRACK)) {
776 name = wxEmptyString;
777 if (!g_bBasicMenus && m_pSelectedTrack)
778 name =
" ( " + m_pSelectedTrack->GetName(
true) +
" )";
780 name = wxEmptyString;
782 if (m_pSelectedTrack && m_pSelectedTrack->m_bIsInLayer) blay =
true;
785 menuTrack =
new wxMenu(_(
"Layer Track") + name);
786 MenuAppend1(menuTrack, ID_TK_MENU_PROPERTIES, _(
"Properties") +
"...");
788 menuTrack =
new wxMenu(_(
"Track") + name);
789 MenuAppend1(menuTrack, ID_TK_MENU_PROPERTIES, _(
"Properties") +
"...");
790 MenuAppend1(menuTrack, ID_TK_MENU_COPY, _(
"Copy as KML"));
791 MenuAppend1(menuTrack, ID_TK_MENU_DELETE, _(
"Delete") +
"...");
794 wxString itemstp = SYMBOL_STP_TITLE;
795 MenuAppend1(menuTrack, ID_TK_MENU_SENDTOPEER, itemstp);
798 if (menuFocus != menuAIS) menuFocus = menuTrack;
801 if (seltype & SELTYPE_ROUTEPOINT &&
802 !(GetContextMenuMask() & CONTEXT_MENU_DISABLE_WAYPOINT)) {
803 if (!g_bBasicMenus && m_pFoundRoutePoint) {
804 name = m_pFoundRoutePoint->GetName();
805 if (name.IsEmpty()) name = _(
"Unnamed Waypoint");
806 name.Prepend(
" ( ").Append(
" )");
808 name = wxEmptyString;
810 if (m_pFoundRoutePoint && m_pFoundRoutePoint->
m_bIsInLayer) blay =
true;
813 menuWaypoint =
new wxMenu(_(
"Layer Waypoint") + name);
814 MenuAppend1(menuWaypoint, ID_WP_MENU_PROPERTIES, _(
"Properties") +
"...");
816 if (m_pSelectedRoute && m_pSelectedRoute->IsActive())
817 MenuAppend1(menuWaypoint, ID_RT_MENU_ACTPOINT, _(
"Activate"));
819 menuWaypoint =
new wxMenu(_(
"Waypoint") + name);
820 MenuAppend1(menuWaypoint, ID_WP_MENU_PROPERTIES, _(
"Properties") +
"...");
821 if (m_pSelectedRoute && m_pSelectedRoute->IsActive()) {
823 MenuAppend1(menuWaypoint, ID_RT_MENU_ACTPOINT, _(
"Activate"));
826 if (m_pSelectedRoute && m_pSelectedRoute->IsActive()) {
828 int indexActive = m_pSelectedRoute->GetIndexOf(
830 if ((indexActive + 1) <= m_pSelectedRoute->GetnPoints())
831 MenuAppend1(menuWaypoint, ID_RT_MENU_ACTNXTPOINT,
832 _(
"Activate Next Waypoint"));
835 if (m_pSelectedRoute && m_pSelectedRoute->GetnPoints() > 2) {
836 MenuAppend1(menuWaypoint, ID_RT_MENU_REMPOINT, _(
"Remove from Route"));
838 m_SelectedIdx = m_pSelectedRoute->GetIndexOf(m_pFoundRoutePoint);
839 if (m_SelectedIdx > 1 && m_SelectedIdx < m_pSelectedRoute->GetnPoints())
840 MenuAppend1(menuWaypoint, ID_RT_MENU_SPLIT_WPT,
841 _(
"Split Route at Waypoint"));
844 MenuAppend1(menuWaypoint, ID_WPT_MENU_COPY, _(
"Copy as KML"));
846 if (m_pFoundRoutePoint && m_pFoundRoutePoint->GetIconName() !=
"mob")
847 MenuAppend1(menuWaypoint, ID_RT_MENU_DELPOINT, _(
"Delete"));
850 wxString port = parent->FindValidUploadPort();
851 parent->m_active_upload_port = port;
852 wxString item = _(
"Send to GPS");
853 if (!port.IsEmpty()) {
858 MenuAppend1(menuWaypoint, ID_WPT_MENU_SENDTOGPS, item);
860 if (!port.IsEmpty()) {
861 wxString item = _(
"Send to new GPS");
862 MenuAppend1(menuWaypoint, ID_WPT_MENU_SENDTONEWGPS, item);
865 MenuAppend1(menuWaypoint, ID_WPT_MENU_SENDTOPEER,
870 if (menuFocus != menuAIS) menuFocus = menuWaypoint;
873 if (seltype & SELTYPE_MARKPOINT &&
874 !(GetContextMenuMask() & CONTEXT_MENU_DISABLE_WAYPOINT)) {
875 if (!g_bBasicMenus && m_pFoundRoutePoint) {
876 name = m_pFoundRoutePoint->GetName();
877 if (name.IsEmpty()) name = _(
"Unnamed Mark");
878 name.Prepend(
" ( ").Append(
" )");
880 name = wxEmptyString;
882 if (m_pFoundRoutePoint && m_pFoundRoutePoint->
m_bIsInLayer) blay =
true;
885 menuWaypoint =
new wxMenu(_(
"Layer Waypoint") + name);
886 MenuAppend1(menuWaypoint, ID_WP_MENU_PROPERTIES, _(
"Properties") +
"...");
888 menuWaypoint =
new wxMenu(_(
"Mark") + name);
889 MenuAppend1(menuWaypoint, ID_WP_MENU_PROPERTIES, _(
"Properties") +
"...");
892 MenuAppend1(menuWaypoint, ID_WP_MENU_GOTO, _(
"Navigate To This"));
894 MenuAppend1(menuWaypoint, ID_WPT_MENU_COPY, _(
"Copy as KML"));
896 if (m_pFoundRoutePoint && m_pFoundRoutePoint->GetIconName() !=
"mob")
897 MenuAppend1(menuWaypoint, ID_WP_MENU_DELPOINT, _(
"Delete"));
900 wxString port = parent->FindValidUploadPort();
901 parent->m_active_upload_port = port;
902 wxString item = _(
"Send to GPS");
903 if (!port.IsEmpty()) {
908 MenuAppend1(menuWaypoint, ID_WPT_MENU_SENDTOGPS, item);
910 MenuAppend1(menuWaypoint, ID_WPT_MENU_SENDTOPEER,
916 MenuAppend1(menuWaypoint, ID_WP_MENU_CLEAR_ANCHORWATCH,
917 _(
"Clear Anchor Watch"));
919 if (m_pFoundRoutePoint && !(m_pFoundRoutePoint->
m_bIsInLayer) &&
923 DistanceBearingMercator(m_pFoundRoutePoint->m_lat,
924 m_pFoundRoutePoint->m_lon,
gLat,
gLon, &brg,
926 if (dist * 1852. <= g_nAWMax)
927 MenuAppend1(menuWaypoint, ID_WP_MENU_SET_ANCHORWATCH,
928 _(
"Set Anchor Watch"));
933 if (menuFocus != menuAIS) menuFocus = menuWaypoint;
937 AddPluginContextMenuItems(contextMenu, menuRoute, menuTrack, menuWaypoint,
941 enum { WPMENU = 1, TKMENU = 2, RTMENU = 4, MMMENU = 8 };
943 if (!g_bBasicMenus && menuFocus != contextMenu) {
944 if (global_color_scheme != GLOBAL_COLOR_SCHEME_DUSK &&
945 global_color_scheme != GLOBAL_COLOR_SCHEME_NIGHT) {
946 menuFocus->AppendSeparator();
949 wxMenuItem *subMenu1;
950 if (menuWaypoint && menuFocus != menuWaypoint) {
952 menuFocus->AppendSubMenu(menuWaypoint, menuWaypoint->GetTitle());
953 SetMenuItemFont1(subMenu1);
956 menuWaypoint->SetTitle(wxEmptyString);
959 if (menuTrack && menuFocus != menuTrack) {
960 subMenu1 = menuFocus->AppendSubMenu(menuTrack, menuTrack->GetTitle());
961 SetMenuItemFont1(subMenu1);
964 menuTrack->SetTitle(wxEmptyString);
967 if (menuRoute && menuFocus != menuRoute) {
968 subMenu1 = menuFocus->AppendSubMenu(menuRoute, menuRoute->GetTitle());
969 SetMenuItemFont1(subMenu1);
972 menuRoute->SetTitle(wxEmptyString);
975 subMenu1 = menuFocus->AppendSubMenu(contextMenu, _(
"Main Menu"));
976 SetMenuItemFont1(subMenu1);
980 if (!subMenuChart->GetMenuItemCount()) contextMenu->Destroy(subItemChart);
985 if (seltype & SELTYPE_TIDEPOINT) {
986 menuFocus->AppendSeparator();
988 MenuAppend1(menuFocus, ID_DEF_MENU_TIDEINFO, _(
"Show Tide Information"));
991 if (seltype & SELTYPE_CURRENTPOINT) {
992 if (!bsep) menuFocus->AppendSeparator();
993 MenuAppend1(menuFocus, ID_DEF_MENU_CURRENTINFO,
994 _(
"Show Current Information"));
1000 androidEnableBackButton(
false);
1001 androidEnableOptionsMenu(
false);
1009 parent->PopupMenu(menuFocus, x, y);
1012 androidEnableBackButton(
true);
1013 androidEnableOptionsMenu(
true);
1020 if (!(sub_menu & MMMENU))
delete contextMenu;
1021 if (!(sub_menu & RTMENU))
delete menuRoute;
1022 if (!(sub_menu & TKMENU))
delete menuTrack;
1023 if (!(sub_menu & WPMENU))
delete menuWaypoint;
1026void CanvasMenuHandler::AddPluginContextMenuItems(wxMenu *contextMenu,
1029 wxMenu *menuWaypoint,
1035 ArrayOfPlugInMenuItems item_array =
1038 for (
unsigned int i = 0; i < item_array.GetCount(); i++) {
1040 if (!pimis->b_viz)
continue;
1042 wxMenu *submenu = NULL;
1043 if (pimis->pmenu_item->GetSubMenu()) {
1045 auto submenu_proto = pimis->pmenu_item->GetSubMenu();
1046 submenu =
new wxMenu();
1047 const wxMenuItemList &items =
1048 pimis->pmenu_item->GetSubMenu()->GetMenuItems();
1049 for (wxMenuItemList::const_iterator it = items.begin(); it != items.end();
1051 int id = (*it)->GetId();
1053 new wxMenuItem(submenu,
id, (*it)->GetItemLabelText(),
1054 (*it)->GetHelp(), (*it)->GetKind());
1057 psmi->SetFont(m_scaledFont);
1062 psmi->SetFont(sFont);
1065 PrepareMenuItem(psmi);
1066 submenu->Append(psmi);
1067 psmi->Check((*it)->IsChecked());
1071 wxMenuItem *pmi =
new wxMenuItem(
1072 contextMenu, pimis->id, pimis->pmenu_item->GetItemLabelText(),
1073 pimis->pmenu_item->GetHelp(), pimis->pmenu_item->GetKind(), submenu);
1075 pmi->SetFont(m_scaledFont);
1080 pmi->SetFont(sFont);
1083 PrepareMenuItem(pmi);
1085 wxMenu *dst = contextMenu;
1086 if (pimis->m_in_menu ==
"Waypoint")
1088 else if (pimis->m_in_menu ==
"Route")
1090 else if (pimis->m_in_menu ==
"Track")
1092 else if (pimis->m_in_menu ==
"AIS")
1097 dst->Enable(pimis->id, !pimis->b_grey);
1102void CanvasMenuHandler::PopupMenuHandler(wxCommandEvent &event) {
1109 bool dupFirstWpt =
true, showRPD;
1114 switch (event.GetId()) {
1115 case ID_DEF_MENU_MAX_DETAIL:
1118 parent->ClearbFollow();
1120 parent->parent_frame->DoChartUpdate();
1122 parent->SelectChartFromStack(0,
false, CHART_TYPE_DONTCARE,
1123 CHART_FAMILY_RASTER);
1126 case ID_DEF_MENU_SCALE_IN:
1127 parent->DoCanvasStackDelta(-1);
1130 case ID_DEF_MENU_SCALE_OUT:
1131 parent->DoCanvasStackDelta(1);
1135 parent->undo->UndoLastAction();
1136 parent->InvalidateGL();
1137 parent->Refresh(
false);
1141 parent->undo->RedoNextAction();
1142 parent->InvalidateGL();
1143 parent->Refresh(
false);
1146 case ID_DEF_MENU_MOVE_BOAT_HERE:
1149 gFrame->UpdateStatusBar();
1152 case ID_DEF_MENU_GOTO_HERE: {
1154 wxEmptyString, wxEmptyString);
1155 pSelect->AddSelectableRoutePoint(zlat, zlon, pWP_dest);
1158 wxEmptyString, wxEmptyString);
1164 temp_route->AddPoint(pWP_src);
1165 temp_route->AddPoint(pWP_dest);
1168 pWP_dest, temp_route);
1184 case ID_DEF_MENU_DROP_WP: {
1186 wxEmptyString, wxEmptyString);
1188 pSelect->AddSelectableRoutePoint(zlat, zlon, pWP);
1189 NavObj_dB::GetInstance().InsertRoutePoint(pWP);
1194 if (RouteManagerDialog::getInstanceFlag()) {
1195 if (pRouteManagerDialog && pRouteManagerDialog->IsShown()) {
1196 pRouteManagerDialog->UpdateWptListCtrl();
1200 parent->undo->BeforeUndoableAction(Undo_CreateWaypoint, pWP,
1201 Undo_HasParent, NULL);
1202 parent->undo->AfterUndoableAction(NULL);
1203 gFrame->RefreshAllCanvas(
false);
1204 gFrame->InvalidateAllGL();
1205 g_FlushNavobjChanges =
true;
1209 case ID_DEF_MENU_NEW_RT: {
1210 parent->StartRoute();
1214 case ID_DEF_MENU_AISTARGETLIST:
1215 parent->ShowAISTargetList();
1218 case ID_DEF_MENU_AIS_CPAWARNING:
1219 parent->ToggleCPAWarn();
1222 case ID_WP_MENU_GOTO: {
1224 wxEmptyString, wxEmptyString);
1230 temp_route->AddPoint(pWP_src);
1231 temp_route->AddPoint(m_pFoundRoutePoint);
1232 m_pFoundRoutePoint->SetShared(
true);
1234 pSelect->AddSelectableRouteSegment(
gLat,
gLon, m_pFoundRoutePoint->m_lat,
1235 m_pFoundRoutePoint->m_lon, pWP_src,
1236 m_pFoundRoutePoint, temp_route);
1238 wxString name = m_pFoundRoutePoint->GetName();
1239 if (name.IsEmpty()) name = _(
"(Unnamed Waypoint)");
1240 wxString rteName = _(
"Go to ");
1241 rteName.Append(name);
1255 case ID_DEF_MENU_COGUP:
1256 parent->SetUpMode(COURSE_UP_MODE);
1259 case ID_DEF_MENU_HEADUP:
1260 parent->SetUpMode(HEAD_UP_MODE);
1263 case ID_DEF_MENU_NORTHUP:
1264 parent->SetUpMode(NORTH_UP_MODE);
1267 case ID_DEF_MENU_TOGGLE_FULL:
1268 gFrame->ToggleFullScreen();
1271 case ID_DEF_MENU_GOTOPOSITION:
1280 case ID_WP_MENU_DELPOINT: {
1289 if (m_pFoundRoutePoint && !(m_pFoundRoutePoint->
m_bIsInLayer) &&
1290 (m_pFoundRoutePoint->GetIconName() !=
"mob")) {
1294 wxArrayPtrVoid *proute_array =
1297 pWayPointMan->DestroyWaypoint(m_pFoundRoutePoint);
1298 delete proute_array;
1300 parent->undo->BeforeUndoableAction(
1301 Undo_DeleteWaypoint, m_pFoundRoutePoint, Undo_IsOrphanded,
1303 NavObj_dB::GetInstance().DeleteRoutePoint(m_pFoundRoutePoint);
1304 pSelect->DeleteSelectablePoint(m_pFoundRoutePoint,
1305 SELTYPE_ROUTEPOINT);
1306 if (NULL != pWayPointMan)
1308 parent->undo->AfterUndoableAction(NULL);
1315 if (RouteManagerDialog::getInstanceFlag()) {
1316 if (pRouteManagerDialog) {
1317 if (pRouteManagerDialog->IsShown())
1318 pRouteManagerDialog->UpdateWptListCtrl();
1322 gFrame->RefreshAllCanvas(
false);
1323 gFrame->InvalidateAllGL();
1327 case ID_WP_MENU_PROPERTIES:
1328 parent->ShowMarkPropertiesDialog(m_pFoundRoutePoint);
1331 case ID_WP_MENU_CLEAR_ANCHORWATCH: {
1332 wxString guid = wxEmptyString;
1342 if (!guid.IsEmpty()) {
1345 wxString msg_id(
"OCPN_ANCHOR_WATCH_CLEARED");
1346 SendJSONMessageToAllPlugins(msg_id, v);
1351 case ID_WP_MENU_SET_ANCHORWATCH: {
1352 wxString guid = wxEmptyString;
1358 nn = m_pFoundRoutePoint->GetName();
1360 nn.Printf(
"%d m", g_nAWDefault);
1361 m_pFoundRoutePoint->SetName(nn);
1368 nn = m_pFoundRoutePoint->GetName();
1370 nn.Printf(
"%d m", g_nAWDefault);
1371 m_pFoundRoutePoint->SetName(nn);
1374 if (!guid.IsEmpty()) {
1377 wxString msg_id(
"OCPN_ANCHOR_WATCH_SET");
1378 SendJSONMessageToAllPlugins(msg_id, v);
1383 case ID_DEF_MENU_ACTIVATE_MEASURE:
1384 parent->StartMeasureRoute();
1387 case ID_DEF_MENU_DEACTIVATE_MEASURE:
1388 parent->CancelMeasureRoute();
1390 parent->InvalidateGL();
1391 parent->Refresh(
false);
1394 case ID_DEF_MENU_CM93OFFSET_DIALOG: {
1400 if (!parent->GetVP().b_quilt && parent->m_singleChart &&
1401 (parent->m_singleChart->GetChartType() == CHART_TYPE_CM93COMP)) {
1413 case ID_DEF_MENU_QUERY: {
1414 parent->ShowObjectQueryWindow(popx, popy, zlat, zlon);
1417 case ID_DEF_MENU_AIS_QUERY: {
1418 ShowAISTargetQueryDialog(parent, m_FoundAIS_MMSI);
1422 case ID_DEF_MENU_AIS_CPA: {
1423 auto myptarget =
g_pAIS->Get_Target_Data_From_MMSI(m_FoundAIS_MMSI);
1424 if (myptarget) myptarget->Toggle_AIS_CPA();
1428 case ID_DEF_MENU_AISSHOWTRACK: {
1429 auto myptarget =
g_pAIS->Get_Target_Data_From_MMSI(m_FoundAIS_MMSI);
1430 if (myptarget) myptarget->ToggleShowTrack();
1434 case ID_DEF_MENU_COPY_MMSI: {
1436 if (wxTheClipboard->Open()) {
1437 wxTheClipboard->SetData(
1438 new wxTextDataObject(wxString::Format(
"%09d", m_FoundAIS_MMSI)));
1439 wxTheClipboard->Close();
1444 case ID_DEF_MENU_QUILTREMOVE: {
1445 if (parent->GetVP().b_quilt) {
1446 int dbIndex = parent->m_pQuilt->GetChartdbIndexAtPix(
1447 parent->GetVP(), wxPoint(popx, popy));
1448 parent->RemoveChartFromQuilt(dbIndex);
1456 case ID_DEF_MENU_CURRENTINFO: {
1457 parent->
DrawTCWindow(popx, popy, (
void *)m_pIDXCandidate);
1458 parent->Refresh(
false);
1463 case ID_DEF_MENU_TIDEINFO: {
1464 parent->
DrawTCWindow(popx, popy, (
void *)m_pIDXCandidate);
1465 parent->Refresh(
false);
1470 case ID_DGB_MENU_NMEA_WINDOW:
1472 m_nmea_log->Raise();
1475 case ID_RT_MENU_REVERSE: {
1479 OCPNMessageBox(parent,
g_pRouteMan->GetRouteReverseMessage(),
1480 _(
"Rename Waypoints?"), wxYES_NO | wxCANCEL);
1482 if (ask_return != wxID_CANCEL) {
1483 pSelect->DeleteAllSelectableRouteSegments(m_pSelectedRoute);
1484 m_pSelectedRoute->Reverse(ask_return == wxID_YES);
1485 pSelect->AddAllSelectableRouteSegments(m_pSelectedRoute);
1487 NavObj_dB::GetInstance().UpdateRoute(m_pSelectedRoute);
1493 gFrame->InvalidateAllGL();
1494 gFrame->RefreshAllCanvas();
1499 case ID_RT_MENU_SHOWNAMES: {
1500 if (m_pSelectedRoute) {
1501 m_pSelectedRoute->ShowWaypointNames(
1502 !m_pSelectedRoute->AreWaypointNamesVisible());
1508 case ID_RT_MENU_RESEQUENCE: {
1509 if (m_pSelectedRoute) {
1513 OCPNMessageBox(parent,
g_pRouteMan->GetRouteResequenceMessage(),
1514 _(
"Rename Waypoints?"), wxYES_NO | wxCANCEL);
1516 if (ask_return != wxID_CANCEL) {
1517 m_pSelectedRoute->RenameRoutePoints();
1520 gFrame->InvalidateAllGL();
1521 gFrame->RefreshAllCanvas();
1527 case ID_RT_MENU_DELETE: {
1528 bool confirmed = RouteGui::OnDelete(parent);
1531 if (
g_pRouteMan->GetpActiveRoute() == m_pSelectedRoute)
1536 NavObj_dB::GetInstance().DeleteRoute(m_pSelectedRoute);
1539 if (RouteManagerDialog::getInstanceFlag()) {
1540 if (pRouteManagerDialog && pRouteManagerDialog->IsShown())
1541 pRouteManagerDialog->UpdateRouteListCtrl();
1549 parent->undo->InvalidateUndo();
1551 gFrame->InvalidateAllGL();
1552 gFrame->RefreshAllCanvas();
1557 case ID_RT_MENU_ACTIVATE: {
1564 if (m_pSelectedRoute) {
1569 best_point = m_pSelectedRoute->GetPoint(2);
1578 case ID_RT_MENU_DEACTIVATE:
1584 case ID_RT_MENU_INSERT: {
1586 bool rename =
false;
1587 m_pSelectedRoute->InsertPointAfter(m_pFoundRoutePoint, zlat, zlon,
1590 pSelect->DeleteAllSelectableRoutePoints(m_pSelectedRoute);
1591 pSelect->DeleteAllSelectableRouteSegments(m_pSelectedRoute);
1593 pSelect->AddAllSelectableRouteSegments(m_pSelectedRoute);
1594 pSelect->AddAllSelectableRoutePoints(m_pSelectedRoute);
1607 NavObj_dB::GetInstance().UpdateRoute(m_pSelectedRoute);
1616 case ID_RT_MENU_APPEND:
1620 parent->m_pMouseRoute = m_pSelectedRoute;
1621 parent->m_routeState = m_pSelectedRoute->GetnPoints() + 1;
1623 m_pSelectedRoute->GetnPoints();
1624 parent->m_pMouseRoute->SetHiLite(50);
1626 pLast = m_pSelectedRoute->GetLastPoint();
1628 parent->m_prev_rlat = pLast->m_lat;
1629 parent->m_prev_rlon = pLast->m_lon;
1630 parent->m_prev_pMousePoint = pLast;
1632 parent->m_bAppendingRoute =
true;
1634 parent->SetCursor(*parent->pCursorPencil);
1636 androidSetRouteAnnunciator(
true);
1639 parent->HideGlobalToolbar();
1643 case ID_RT_MENU_SPLIT_LEG:
1645 dupFirstWpt =
false;
1646 case ID_RT_MENU_SPLIT_WPT:
1650 if (
g_pRouteMan->GetpActiveRoute() == m_pSelectedRoute)
1653 m_pHead =
new Route();
1654 m_pTail =
new Route();
1655 m_pHead->CloneRoute(m_pSelectedRoute, 1, m_SelectedIdx, _(
"_A"));
1656 m_pTail->CloneRoute(m_pSelectedRoute, m_SelectedIdx + splitMode,
1657 m_pSelectedRoute->GetnPoints(), _(
"_B"), dupFirstWpt);
1659 NavObj_dB::GetInstance().InsertRoute(m_pHead);
1662 NavObj_dB::GetInstance().InsertRoute(m_pTail);
1664 NavObj_dB::GetInstance().DeleteRoute(m_pSelectedRoute);
1666 pSelect->DeleteAllSelectableRoutePoints(m_pSelectedRoute);
1667 pSelect->DeleteAllSelectableRouteSegments(m_pSelectedRoute);
1669 pSelect->AddAllSelectableRouteSegments(m_pTail);
1670 pSelect->AddAllSelectableRoutePoints(m_pTail);
1671 pSelect->AddAllSelectableRouteSegments(m_pHead);
1672 pSelect->AddAllSelectableRoutePoints(m_pHead);
1678 if (RouteManagerDialog::getInstanceFlag() && pRouteManagerDialog &&
1679 (pRouteManagerDialog->IsShown()))
1680 pRouteManagerDialog->UpdateRouteListCtrl();
1683 case ID_RT_MENU_COPY:
1684 if (m_pSelectedRoute) Kml::CopyRouteToClipboard(m_pSelectedRoute);
1687 case ID_TK_MENU_COPY:
1688 if (m_pSelectedTrack) Kml::CopyTrackToClipboard(m_pSelectedTrack);
1691 case ID_WPT_MENU_COPY:
1692 if (m_pFoundRoutePoint) Kml::CopyWaypointToClipboard(m_pFoundRoutePoint);
1695 case ID_WPT_MENU_SENDTOGPS:
1696 if (m_pFoundRoutePoint) {
1697 if (parent->m_active_upload_port.Length())
1699 .SendToGPS(parent->m_active_upload_port.BeforeFirst(
' '), NULL);
1702 dlg.SetWaypoint(m_pFoundRoutePoint);
1706 dlg.Create(NULL, -1, _(
"Send to GPS") +
"...",
"");
1712 case ID_WPT_MENU_SENDTONEWGPS:
1713 if (m_pFoundRoutePoint) {
1715 dlg.SetWaypoint(m_pFoundRoutePoint);
1717 dlg.Create(NULL, -1, _(
"Send to GPS") +
"...",
"");
1722 case ID_WPT_MENU_SENDTOPEER:
1723 if (m_pFoundRoutePoint) {
1725 dlg.SetWaypoint(m_pFoundRoutePoint);
1730 MdnsCache::GetInstance().
Validate();
1731 if (MdnsCache::GetInstance().GetCache().empty())
1732 dlg.SetScanOnCreate(
true);
1735 dlg.Create(NULL, -1, _(
"Send Waypoint to OpenCPN Peer") +
"...",
"");
1740 case ID_RT_MENU_SENDTOGPS:
1741 if (m_pSelectedRoute) {
1742 if (parent->m_active_upload_port.Length())
1744 .SendToGPS(parent->m_active_upload_port.BeforeFirst(
' '),
true,
1748 dlg.SetRoute(m_pSelectedRoute);
1750 dlg.Create(NULL, -1, _(
"Send to GPS") +
"...",
"");
1756 case ID_RT_MENU_SENDTONEWGPS:
1757 if (m_pSelectedRoute) {
1759 dlg.SetRoute(m_pSelectedRoute);
1761 dlg.Create(NULL, -1, _(
"Send to GPS") +
"...",
"");
1766 case ID_RT_MENU_SENDTOPEER:
1767 if (m_pSelectedRoute) {
1769 dlg.SetRoute(m_pSelectedRoute);
1774 MdnsCache::GetInstance().
Validate();
1775 if (MdnsCache::GetInstance().GetCache().empty())
1776 dlg.SetScanOnCreate(
true);
1779 dlg.Create(NULL, -1, _(
"Send Route to OpenCPN Peer") +
"...",
"");
1784 case ID_PASTE_WAYPOINT:
1785 pupHandler_PasteWaypoint();
1788 case ID_PASTE_ROUTE:
1789 pupHandler_PasteRoute();
1792 case ID_PASTE_TRACK:
1793 pupHandler_PasteTrack();
1796 case ID_RT_MENU_DELPOINT:
1797 if (m_pSelectedRoute) {
1800 pWayPointMan->DestroyWaypoint(m_pFoundRoutePoint);
1805 if (
g_pRouteMan->IsRouteValid(m_pSelectedRoute)) {
1811 if (RouteManagerDialog::getInstanceFlag()) {
1812 if (pRouteManagerDialog && pRouteManagerDialog->IsShown()) {
1813 pRouteManagerDialog->UpdateWptListCtrl();
1814 pRouteManagerDialog->UpdateRouteListCtrl();
1818 gFrame->InvalidateAllGL();
1819 gFrame->RefreshAllCanvas(
true);
1824 case ID_RT_MENU_REMPOINT:
1825 if (m_pSelectedRoute) {
1827 g_pRouteMan->RemovePointFromRoute(m_pFoundRoutePoint, m_pSelectedRoute,
1828 parent->m_routeState);
1829 gFrame->InvalidateAllGL();
1830 gFrame->RefreshAllCanvas();
1834 case ID_RT_MENU_ACTPOINT:
1835 if (
g_pRouteMan->GetpActiveRoute() == m_pSelectedRoute) {
1842 case ID_RT_MENU_DEACTPOINT:
1845 case ID_RT_MENU_ACTNXTPOINT:
1846 if (
g_pRouteMan->GetpActiveRoute() == m_pSelectedRoute) {
1853 case ID_RT_MENU_PROPERTIES: {
1854 parent->ShowRoutePropertiesDialog(_(
"Route Properties"),
1859 case ID_TK_MENU_PROPERTIES: {
1860 parent->ShowTrackPropertiesDialog(m_pSelectedTrack);
1864 case ID_TK_MENU_DELETE: {
1865 int dlg_return = wxID_YES;
1866 if (g_bConfirmObjectDelete) {
1867 dlg_return = OCPNMessageBox(
1868 parent, _(
"Are you sure you want to delete this track?"),
1869 _(
"OpenCPN Track Delete"),
1870 (
long)wxYES_NO | wxCANCEL | wxYES_DEFAULT);
1873 if (dlg_return == wxID_YES) {
1875 m_pSelectedTrack = parent->parent_frame->TrackOff();
1876 g_pAIS->DeletePersistentTrack(m_pSelectedTrack);
1878 NavObj_dB::GetInstance().DeleteTrack(m_pSelectedTrack);
1879 RoutemanGui(*g_pRouteMan).DeleteTrack(m_pSelectedTrack);
1887 if (RoutePropDlgImpl::getInstanceFlag() && pRouteManagerDialog &&
1888 pRouteManagerDialog->IsShown()) {
1889 pRouteManagerDialog->UpdateTrkListCtrl();
1890 pRouteManagerDialog->UpdateRouteListCtrl();
1892 gFrame->InvalidateAllGL();
1893 gFrame->RefreshAllCanvas();
1898 case ID_TK_MENU_SENDTOPEER:
1899 if (m_pSelectedTrack) {
1901 dlg.SetTrack(m_pSelectedTrack);
1906 MdnsCache::GetInstance().
Validate();
1907 if (MdnsCache::GetInstance().GetCache().empty())
1908 dlg.SetScanOnCreate(
true);
1911 dlg.Create(NULL, -1, _(
"Send Track to OpenCPN Peer") +
"...",
"");
1916 case ID_RC_MENU_SCALE_IN:
1917 parent->parent_frame->DoStackDown(parent);
1919 parent->WarpPointer(r.x, r.y);
1922 case ID_RC_MENU_SCALE_OUT:
1923 parent->parent_frame->DoStackUp(parent);
1925 parent->WarpPointer(r.x, r.y);
1928 case ID_RC_MENU_ZOOM_IN:
1931 parent->WarpPointer(r.x, r.y);
1934 case ID_RC_MENU_ZOOM_OUT:
1937 parent->WarpPointer(r.x, r.y);
1940 case ID_RC_MENU_FINISH:
1941 parent->FinishRoute();
1943 parent->Refresh(
false);
1944 g_FlushNavobjChanges =
true;
1947 case ID_DEF_ZERO_XTE:
1954 ArrayOfPlugInMenuItems item_array =
1957 for (
unsigned int i = 0; i < item_array.GetCount(); i++) {
1959 int target_id = pimis->id;
1962 if (pimis->pmenu_item->GetSubMenu()) {
1963 const wxMenuItemList &items =
1964 pimis->pmenu_item->GetSubMenu()->GetMenuItems();
1965 for (wxMenuItemList::const_iterator it = items.begin();
1966 it != items.end(); ++it) {
1967 if ((*it)->GetId() ==
event.GetId()) {
1968 target_id = (*it)->GetId();
1974 if (pimis->m_pplugin && (target_id == event.GetId())) {
1975 if (pimis->extended) {
1976 std::string object_type;
1977 std::string object_ident;
1979 if ((pimis->m_in_menu.IsSameAs(
"Waypoint")) && m_pFoundRoutePoint) {
1980 object_type =
"Waypoint";
1981 object_ident = m_pFoundRoutePoint->
m_GUID.ToStdString();
1982 }
else if ((pimis->m_in_menu.IsSameAs(
"Route")) &&
1984 object_type =
"Route";
1985 object_ident = m_pSelectedRoute->
m_GUID.ToStdString();
1986 }
else if ((pimis->m_in_menu.IsSameAs(
"Track")) &&
1988 object_type =
"Track";
1989 object_ident = m_pSelectedTrack->m_GUID.ToStdString();
1990 }
else if ((pimis->m_in_menu.IsSameAs(
"AIS")) && m_FoundAIS_MMSI) {
1991 object_type =
"AIS";
1992 wxString sAIS = wxString::Format(
"%d", m_FoundAIS_MMSI);
1993 object_ident = sAIS.ToStdString();
1999 ppi->OnContextMenuItemCallbackExt(target_id, object_ident,
2000 object_type, zlat, zlon);
2011 if ((event.GetId() >= ID_DEF_MENU_GROUPBASE) &&
2014 parent->SetGroupIndex(event.GetId() - ID_DEF_MENU_GROUPBASE);
2017 parent->InvalidateGL();
AisDecoder * g_pAIS
Global instance.
Class AisDecoder and helpers.
Global state for AIS decoder.
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.
float GetVPScale()
Return the ViewPort scale factor, in physical pixels per meter.
bool SetVPScale(double sc, bool b_refresh=true)
Sets the viewport scale while maintaining the center point.
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.
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.
The JSON value class implementation.
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.
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.
ActiveTrack * g_pActiveTrack
global instance
Recorded track abstraction.
Track and Trackpoint drawing stuff.
TrackPropDlg * pTrackPropDialog
Global instance.
Framework for Undo features.