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>
38#include <wx/listimpl.cpp>
41#include "model/ais_decoder.h"
43#include "model/ais_target_data.h"
44#include "model/config_vars.h"
45#include "model/cutil.h"
46#include "model/georef.h"
50#include "model/nav_object_database.h"
51#include "model/own_ship.h"
52#include "model/own_ship.h"
54#include "model/route.h"
55#include "model/routeman.h"
56#include "model/select.h"
57#include "model/track.h"
60#include "canvasMenu.h"
69#include "ocpn_frame.h"
70#include "OCPNPlatform.h"
71#include "peer_client_dlg.h"
72#include "pluginmanager.h"
75#include "routemanagerdialog.h"
76#include "routeman_gui.h"
77#include "route_point_gui.h"
78#include "RoutePropDlgImpl.h"
82#include "SendToGpsDlg.h"
83#include "SendToPeerDlg.h"
89#include "TrackPropDlg.h"
93#include "androidUTIL.h"
99extern void pupHandler_PasteRoute();
100extern void pupHandler_PasteTrack();
101extern void pupHandler_PasteWaypoint();
104extern bool g_bskew_comp;
105extern double vLat, vLon;
107extern ChartGroupArray *g_pGroupArray;
110extern int g_nAWDefault;
111extern wxString g_AW1GUID;
112extern wxString g_AW2GUID;
113extern int g_click_stop;
118extern bool g_bConfirmObjectDelete;
125extern RouteList *pRouteList;
126extern wxString g_default_wp_icon;
127extern bool g_bBasicMenus;
129extern bool g_FlushNavobjChanges;
130extern ColorScheme global_color_scheme;
134 ID_DEF_MENU_MAX_DETAIL = 1,
135 ID_DEF_MENU_SCALE_IN,
136 ID_DEF_MENU_SCALE_OUT,
140 ID_DEF_MENU_MOVE_BOAT_HERE,
141 ID_DEF_MENU_GOTO_HERE,
142 ID_DEF_MENU_GOTOPOSITION,
146 ID_WP_MENU_PROPERTIES,
148 ID_RT_MENU_DEACTIVATE,
152 ID_RT_MENU_SPLIT_LEG,
153 ID_RT_MENU_SPLIT_WPT,
156 ID_WPT_MENU_SENDTOGPS,
157 ID_WPT_MENU_SENDTONEWGPS,
158 ID_WPT_MENU_SENDTOPEER,
166 ID_RT_MENU_DEACTPOINT,
167 ID_RT_MENU_ACTNXTPOINT,
169 ID_RT_MENU_PROPERTIES,
170 ID_RT_MENU_SENDTOGPS,
171 ID_RT_MENU_SENDTONEWGPS,
172 ID_RT_MENU_SHOWNAMES,
173 ID_RT_MENU_RESEQUENCE,
174 ID_RT_MENU_SENDTOPEER,
175 ID_WP_MENU_SET_ANCHORWATCH,
176 ID_WP_MENU_CLEAR_ANCHORWATCH,
177 ID_DEF_MENU_AISTARGETLIST,
178 ID_DEF_MENU_AIS_CPAWARNING,
181 ID_RC_MENU_SCALE_OUT,
185 ID_DEF_MENU_AIS_QUERY,
187 ID_DEF_MENU_AISSHOWTRACK,
188 ID_DEF_MENU_ACTIVATE_MEASURE,
189 ID_DEF_MENU_DEACTIVATE_MEASURE,
190 ID_DEF_MENU_COPY_MMSI,
195 ID_DEF_MENU_CM93OFFSET_DIALOG,
197 ID_TK_MENU_PROPERTIES,
199 ID_TK_MENU_SENDTOPEER,
200 ID_WP_MENU_ADDITIONAL_INFO,
202 ID_DEF_MENU_QUILTREMOVE,
206 ID_DEF_MENU_TOGGLE_FULL,
207 ID_DEF_MENU_TIDEINFO,
208 ID_DEF_MENU_CURRENTINFO,
212 ID_DGB_MENU_NMEA_WINDOW,
214 ID_DEF_MENU_GROUPBASE,
223int CanvasMenuHandler::GetNextContextMenuId() {
224 return ID_DEF_MENU_LAST +
228wxFont CanvasMenuHandler::m_scaledFont;
231CanvasMenuHandler::CanvasMenuHandler(
ChartCanvas *parentCanvas,
234 int selectedAIS_MMSI,
235 void *selectedTCIndex, wxWindow *nmea_log)
236 : m_nmea_log(nmea_log) {
237 parent = parentCanvas;
238 m_pSelectedRoute = selectedRoute;
239 m_pSelectedTrack = selectedTrack;
240 m_pFoundRoutePoint = selectedPoint;
241 m_FoundAIS_MMSI = selectedAIS_MMSI;
242 m_pIDXCandidate = selectedTCIndex;
243 if (!m_scaledFont.IsOk()) {
245 m_scaledFont = *qFont;
251CanvasMenuHandler::~CanvasMenuHandler() {}
257void CanvasMenuHandler::PrepareMenuItem(wxMenuItem *item) {
258#if defined(__WXMSW__)
259 wxColour ctrl_back_color = GetGlobalColor(_T(
"DILG1"));
260 item->SetBackgroundColour(ctrl_back_color);
261 wxColour menu_text_color = GetGlobalColor(_T (
"UITX1" ));
262 item->SetTextColour(menu_text_color);
266void CanvasMenuHandler::MenuPrepend1(wxMenu *menu,
int id, wxString label) {
267 wxMenuItem *item =
new wxMenuItem(menu,
id, label);
268#if defined(__WXMSW__)
269 item->SetFont(m_scaledFont);
274 item->SetFont(sFont);
277 PrepareMenuItem(item);
279 if (g_btouch) menu->InsertSeparator(0);
283void CanvasMenuHandler::MenuAppend1(wxMenu *menu,
int id, wxString label) {
284 wxMenuItem *item =
new wxMenuItem(menu,
id, label);
285#if defined(__WXMSW__)
286 item->SetFont(m_scaledFont);
291 item->SetFont(sFont);
294 PrepareMenuItem(item);
297 if (g_btouch) menu->AppendSeparator();
300void CanvasMenuHandler::SetMenuItemFont1(wxMenuItem *item) {
301#if defined(__WXMSW__)
302 item->SetFont(m_scaledFont);
305#if defined(__ANDROID__)
307 item->SetFont(*qFont);
310 PrepareMenuItem(item);
313void CanvasMenuHandler::CanvasPopupMenu(
int x,
int y,
int seltype) {
314 wxMenu *contextMenu =
new wxMenu;
315 wxMenu *menuWaypoint = NULL;
316 wxMenu *menuRoute = NULL;
317 wxMenu *menuTrack = NULL;
318 wxMenu *menuAIS = NULL;
320 wxMenu *subMenuChart =
new wxMenu;
321 wxMenu *subMenuUndo =
new wxMenu(
"Undo...Ctrl-Z");
324 wxMenu *subMenuRedo =
new wxMenu(
"Redo...Shift-Ctrl-Z");
326 wxMenu *subMenuRedo =
new wxMenu(
"Redo...Ctrl-Y");
328 wxMenu *subMenuDebug =
new wxMenu(
"");
329 MenuAppend1(subMenuDebug, ID_DGB_MENU_NMEA_WINDOW, _(
"Show Data Monitor"));
331 wxMenu *menuFocus = contextMenu;
336 if (!g_bBasicMenus || (seltype != SELTYPE_ROUTECREATE)) {
337 bool bsubMenus =
false;
340 if (parent->undo->AnythingToUndo()) {
342 wxMenuItem *subMenuItemundo =
343 contextMenu->AppendSubMenu(subMenuUndo, _(
"Undo"));
346 undoItem << _(
"Undo") << _T(
" ")
347 << parent->undo->GetNextUndoableAction()->Description();
348 MenuAppend1(subMenuUndo, ID_UNDO, undoItem);
350 if (parent->undo->AnythingToRedo()) {
352 wxMenuItem *subMenuItemRedo =
353 contextMenu->AppendSubMenu(subMenuRedo, _(
"Redo"));
356 redoItem << _(
"Redo") << _T(
" ")
357 << parent->undo->GetNextRedoableAction()->Description();
358 MenuAppend1(subMenuRedo, ID_REDO, redoItem);
361 if (parent->undo->AnythingToUndo()) {
363 undoItem << _(
"Undo") << _T(
" ")
364 << parent->undo->GetNextUndoableAction()->Description();
365 MenuAppend1(contextMenu, ID_UNDO, _menuText(undoItem, _T(
"Ctrl-Z")));
368 if (parent->undo->AnythingToRedo()) {
370 redoItem << _(
"Redo") << _T(
" ")
371 << parent->undo->GetNextRedoableAction()->Description();
373 MenuAppend1(contextMenu, ID_REDO,
374 _menuText(redoItem, _T(
"Shift-Ctrl-Z")));
376 MenuAppend1(contextMenu, ID_REDO, _menuText(redoItem, _T(
"Ctrl-Y")));
382 if (seltype == SELTYPE_ROUTECREATE) {
383 MenuAppend1(contextMenu, ID_RC_MENU_FINISH,
384 _menuText(_(
"End Route"), _T(
"Esc")));
387 if (!parent->m_pMouseRoute) {
388 if (parent->m_bMeasure_Active)
389 MenuAppend1(contextMenu, ID_DEF_MENU_DEACTIVATE_MEASURE,
390 _menuText(_(
"Measure Off"), _T(
"Esc")));
392 MenuAppend1(contextMenu, ID_DEF_MENU_ACTIVATE_MEASURE,
393 _menuText(_(
"Measure"), _T(
"M")));
396 bool ais_areanotice =
false;
397 if (g_pAIS && parent->GetShowAIS() && g_bShowAreaNotices) {
400 for (
const auto &target : g_pAIS->GetAreaNoticeSourcesList()) {
401 auto target_data = target.second;
402 if (!target_data->area_notices.empty()) {
403 for (
auto &ani : target_data->area_notices) {
407 for (Ais8_001_22_SubAreaList::iterator sa =
408 area_notice.sub_areas.begin();
409 sa != area_notice.sub_areas.end(); ++sa) {
411 case AIS8_001_22_SHAPE_CIRCLE: {
412 wxPoint target_point;
415 bbox.Expand(target_point);
416 if (sa->radius_m > 0.0) bbox.EnLarge(sa->radius_m * vp_scale);
419 case AIS8_001_22_SHAPE_RECT:
420 case AIS8_001_22_SHAPE_POLYGON:
421 case AIS8_001_22_SHAPE_POLYLINE: {
422 double lat = sa->latitude;
423 double lon = sa->longitude;
424 for (
int i = 0; i < 4; ++i) {
425 ll_gc_ll(lat, lon, sa->angles[i], sa->dists_m[i] / 1852.0,
427 wxPoint target_point;
429 bbox.Expand(target_point);
433 case AIS8_001_22_SHAPE_SECTOR: {
434 double lat1 = sa->latitude;
435 double lon1 = sa->longitude;
437 wxPoint target_point;
439 bbox.Expand(target_point);
440 for (
int i = 0; i < 18; ++i) {
444 i * (sa->right_bound_deg - sa->left_bound_deg) / 18,
445 sa->radius_m / 1852.0, &lat, &lon);
447 bbox.Expand(target_point);
449 ll_gc_ll(lat1, lon1, sa->right_bound_deg, sa->radius_m / 1852.0,
452 bbox.Expand(target_point);
458 if (bbox.GetValid() && bbox.PointInBox(x, y)) {
459 ais_areanotice =
true;
468 if (parent->GetpCurrentStack())
469 nChartStack = parent->GetpCurrentStack()->nEntry;
471 if (!parent->GetVP().b_quilt) {
472 if (nChartStack > 1) {
473 MenuAppend1(contextMenu, ID_DEF_MENU_MAX_DETAIL, _(
"Max Detail Here"));
474 MenuAppend1(contextMenu, ID_DEF_MENU_SCALE_IN,
475 _menuText(_(
"Scale In"), _T(
"Ctrl-Left")));
476 MenuAppend1(contextMenu, ID_DEF_MENU_SCALE_OUT,
477 _menuText(_(
"Scale Out"), _T(
"Ctrl-Right")));
480 if ((parent->m_singleChart &&
481 (parent->m_singleChart->GetChartFamily() == CHART_FAMILY_VECTOR)) ||
483 MenuAppend1(contextMenu, ID_DEF_MENU_QUERY,
484 _(
"Object Query") + _T(
"..." ));
489 parent->m_pQuilt->GetChartAtPix(parent->GetVP(), wxPoint(x, y));
490 if ((pChartTest && (pChartTest->GetChartFamily() == CHART_FAMILY_VECTOR)) ||
492 MenuAppend1(contextMenu, ID_DEF_MENU_QUERY,
493 _(
"Object Query") + _T(
"..." ));
496 if (!g_bBasicMenus && (nChartStack > 1)) {
497 MenuAppend1(contextMenu, ID_DEF_MENU_SCALE_IN,
498 _menuText(_(
"Scale In"), _T(
"Ctrl-Left")));
499 MenuAppend1(contextMenu, ID_DEF_MENU_SCALE_OUT,
500 _menuText(_(
"Scale Out"), _T(
"Ctrl-Right")));
506 if (!g_bBasicMenus || (seltype != SELTYPE_ROUTECREATE)) {
507 bool b_dm_add =
true;
508 if (g_btouch && parent->IsMeasureActive()) b_dm_add =
false;
511 MenuAppend1(contextMenu, ID_DEF_MENU_DROP_WP,
512 _menuText(_(
"Drop Mark"), _T(
"Ctrl-M")));
513 MenuAppend1(contextMenu, ID_DEF_MENU_NEW_RT,
514 _menuText(_(
"New Route..."), _T(
"Ctrl-R")));
518 MenuAppend1(contextMenu, ID_DEF_MENU_MOVE_BOAT_HERE, _(
"Move Boat Here"));
521 if (!g_bBasicMenus &&
522 (!(g_pRouteMan->GetpActiveRoute() || (seltype & SELTYPE_MARKPOINT))))
523 MenuAppend1(contextMenu, ID_DEF_MENU_GOTO_HERE, _(
"Navigate To Here"));
526 MenuAppend1(contextMenu, ID_DEF_MENU_GOTOPOSITION,
527 _(
"Center view") + _T(
"..."));
529 if (!g_bBasicMenus) {
530 if (parent->GetVP().b_quilt) {
531 if (parent->GetUpMode() == NORTH_UP_MODE) {
532 MenuAppend1(contextMenu, ID_DEF_MENU_COGUP, _(
"Course Up Mode"));
533 if (!std::isnan(gHdt))
534 MenuAppend1(contextMenu, ID_DEF_MENU_HEADUP, _(
"Heading Up Mode"));
536 MenuAppend1(contextMenu, ID_DEF_MENU_NORTHUP, _(
"North Up Mode"));
539 if (parent->m_singleChart &&
540 (fabs(parent->m_singleChart->GetChartSkew()) > .01) && !g_bskew_comp)
541 MenuAppend1(contextMenu, ID_DEF_MENU_NORTHUP, _(
"Chart Up Mode"));
543 MenuAppend1(contextMenu, ID_DEF_MENU_NORTHUP, _(
"North Up Mode"));
547 if (!g_bBasicMenus) {
548 bool full_toggle_added =
false;
551 MenuAppend1(contextMenu, ID_DEF_MENU_TOGGLE_FULL,
552 _(
"Toggle Full Screen"));
553 full_toggle_added =
true;
556 if (!full_toggle_added) {
558 MenuAppend1(contextMenu, ID_DEF_MENU_TOGGLE_FULL,
559 _(
"Toggle Full Screen"));
563 if (g_pRouteMan->IsAnyRouteActive() &&
564 g_pRouteMan->GetCurrentXTEToActivePoint() > 0.)
565 MenuAppend1(contextMenu, ID_DEF_ZERO_XTE, _(
"Zero XTE"));
568 int pasteBuffer = kml->ParsePasteBuffer();
569 if (pasteBuffer != KML_PASTE_INVALID) {
570 switch (pasteBuffer) {
571 case KML_PASTE_WAYPOINT: {
572 MenuAppend1(contextMenu, ID_PASTE_WAYPOINT, _(
"Paste Waypoint"));
575 case KML_PASTE_ROUTE: {
576 MenuAppend1(contextMenu, ID_PASTE_ROUTE, _(
"Paste Route"));
579 case KML_PASTE_TRACK: {
580 MenuAppend1(contextMenu, ID_PASTE_TRACK, _(
"Paste Track"));
583 case KML_PASTE_ROUTE_TRACK: {
584 MenuAppend1(contextMenu, ID_PASTE_ROUTE, _(
"Paste Route"));
585 MenuAppend1(contextMenu, ID_PASTE_TRACK, _(
"Paste Track"));
592 if (!parent->GetVP().b_quilt && parent->m_singleChart &&
593 (parent->m_singleChart->GetChartType() == CHART_TYPE_CM93COMP)) {
594 MenuAppend1(contextMenu, ID_DEF_MENU_CM93OFFSET_DIALOG,
595 _(
"CM93 Offset Dialog..."));
619 wxMenuItem *subItemChart =
620 contextMenu->AppendSubMenu(subMenuChart, _(
"Chart Groups"));
621 if (g_btouch) contextMenu->AppendSeparator();
623 SetMenuItemFont1(subItemChart);
625 if (g_pGroupArray->GetCount()) {
627 MenuAppend1(subMenuChart, wxID_CANCEL, _(
"temporary"));
629 wxMenuItem *subItem0 = subMenuChart->AppendRadioItem(
630 ID_DEF_MENU_GROUPBASE, _(
"All Active Charts"));
632 SetMenuItemFont1(subItem0);
634 for (
unsigned int i = 0; i < g_pGroupArray->GetCount(); i++) {
635 subItem0 = subMenuChart->AppendRadioItem(
636 ID_DEF_MENU_GROUPBASE + i + 1, g_pGroupArray->Item(i)->m_group_name);
637 SetMenuItemFont1(subItem0);
641 subMenuChart->Remove(wxID_CANCEL);
643 subMenuChart->Check(ID_DEF_MENU_GROUPBASE + parent->m_groupIndex,
true);
647 menuFocus = contextMenu;
650 if (!g_bBasicMenus || (seltype != SELTYPE_ROUTECREATE)) {
652 if (parent->GetShowAIS() && (seltype & SELTYPE_AISTARGET)) {
653 auto myptarget = g_pAIS->Get_Target_Data_From_MMSI(m_FoundAIS_MMSI);
654 if (!g_bBasicMenus && myptarget) {
655 name = myptarget->GetFullName();
656 if (name.IsEmpty()) name.Printf(_T(
"%d"), m_FoundAIS_MMSI);
657 name.Prepend(_T(
" ( ")).Append(_T(
" )"));
659 name = wxEmptyString;
660 menuAIS =
new wxMenu(_(
"AIS") + name);
661 MenuAppend1(menuAIS, ID_DEF_MENU_AIS_QUERY, _(
"Target Query..."));
662 if (myptarget && myptarget->bCPA_Valid &&
663 (myptarget->n_alert_state != AIS_ALERT_SET)) {
664 if (myptarget->b_show_AIS_CPA)
665 MenuAppend1(menuAIS, ID_DEF_MENU_AIS_CPA, _(
"Hide Target CPA"));
667 MenuAppend1(menuAIS, ID_DEF_MENU_AIS_CPA, _(
"Show Target CPA"));
669 MenuAppend1(menuAIS, ID_DEF_MENU_AISTARGETLIST, _(
"Target List..."));
670 if (myptarget->Class != AIS_METEO ) {
671 if (myptarget && !myptarget->b_PersistTrack) {
672 if (myptarget->b_show_track)
673 MenuAppend1(menuAIS, ID_DEF_MENU_AISSHOWTRACK,
674 _(
"Hide Target Track"));
676 MenuAppend1(menuAIS, ID_DEF_MENU_AISSHOWTRACK,
677 _(
"Show Target Track"));
681 MenuAppend1(menuAIS, ID_DEF_MENU_COPY_MMSI, _(
"Copy Target MMSI"));
682 menuAIS->AppendSeparator();
684 if (!parent->GetVP().b_quilt) {
685 if ((parent->m_singleChart &&
686 (parent->m_singleChart->GetChartFamily() ==
687 CHART_FAMILY_VECTOR))) {
688 MenuAppend1(menuAIS, ID_DEF_MENU_QUERY, _(
"Object Query..."));
693 parent->m_pQuilt->GetChartAtPix(parent->GetVP(), wxPoint(x, y));
695 (pChartTest->GetChartFamily() == CHART_FAMILY_VECTOR))) {
696 MenuAppend1(menuAIS, ID_DEF_MENU_QUERY, _(
"Object Query..."));
702 MenuAppend1(contextMenu, ID_DEF_MENU_AISTARGETLIST,
703 _(
"AIS target list") + _T(
"..."));
705 wxString nextCPAstatus = g_bCPAWarn ? _(
"Hide") : _(
"Show");
706 MenuAppend1(contextMenu, ID_DEF_MENU_AIS_CPAWARNING,
707 _menuText(nextCPAstatus +
" " + _(
"CPA alarm "),
"W"));
711 if (g_enable_root_menu_debug)
712 contextMenu->AppendSubMenu(subMenuDebug, _(
"Debug"));
714 if (seltype & SELTYPE_ROUTESEGMENT) {
715 if (!g_bBasicMenus && m_pSelectedRoute) {
717 if (name.IsEmpty()) name = _(
"Unnamed Route");
718 name.Prepend(_T(
" ( ")).Append(_T(
" )"));
720 name = wxEmptyString;
722 if (m_pSelectedRoute && m_pSelectedRoute->
m_bIsInLayer) blay =
true;
725 menuRoute =
new wxMenu(_(
"Layer Route") + name);
726 MenuAppend1(menuRoute, ID_RT_MENU_PROPERTIES,
727 _(
"Properties") + _T(
"..." ));
728 if (m_pSelectedRoute) {
729 if (m_pSelectedRoute->IsActive()) {
730 int indexActive = m_pSelectedRoute->GetIndexOf(
732 if ((indexActive + 1) <= m_pSelectedRoute->GetnPoints()) {
733 MenuAppend1(menuRoute, ID_RT_MENU_ACTNXTPOINT,
734 _(
"Activate Next Waypoint"));
736 MenuAppend1(menuRoute, ID_RT_MENU_DEACTIVATE, _(
"Deactivate"));
737 MenuAppend1(menuRoute, ID_DEF_ZERO_XTE, _(
"Zero XTE"));
739 MenuAppend1(menuRoute, ID_RT_MENU_ACTIVATE, _(
"Activate"));
743 menuRoute =
new wxMenu(_(
"Route") + name);
744 MenuAppend1(menuRoute, ID_RT_MENU_PROPERTIES,
745 _(
"Properties") + _T(
"..." ));
746 if (m_pSelectedRoute) {
747 if (m_pSelectedRoute->IsActive()) {
748 int indexActive = m_pSelectedRoute->GetIndexOf(
750 if ((indexActive + 1) <= m_pSelectedRoute->GetnPoints()) {
751 MenuAppend1(menuRoute, ID_RT_MENU_ACTNXTPOINT,
752 _(
"Activate Next Waypoint"));
754 MenuAppend1(menuRoute, ID_RT_MENU_DEACTIVATE, _(
"Deactivate"));
755 MenuAppend1(menuRoute, ID_DEF_ZERO_XTE, _(
"Zero XTE"));
757 MenuAppend1(menuRoute, ID_RT_MENU_ACTIVATE, _(
"Activate"));
760 MenuAppend1(menuRoute, ID_RT_MENU_INSERT, _(
"Insert Waypoint"));
761 MenuAppend1(menuRoute, ID_RT_MENU_APPEND, _(
"Append Waypoint"));
762 if (!(seltype & SELTYPE_ROUTEPOINT) && m_pSelectedRoute) {
763 m_SelectedIdx = m_pSelectedRoute->GetIndexOf(m_pFoundRoutePoint);
764 if (m_SelectedIdx > 1 &&
765 m_SelectedIdx < m_pSelectedRoute->GetnPoints() - 1)
766 MenuAppend1(menuRoute, ID_RT_MENU_SPLIT_LEG, _(
"Split around Leg"));
768 MenuAppend1(menuRoute, ID_RT_MENU_COPY, _(
"Copy as KML") + _T(
"..." ));
769 MenuAppend1(menuRoute, ID_RT_MENU_DELETE, _(
"Delete") + _T(
"..." ));
770 MenuAppend1(menuRoute, ID_RT_MENU_REVERSE, _(
"Reverse..."));
771 if (m_pSelectedRoute) {
772 if (m_pSelectedRoute->AreWaypointNamesVisible())
773 MenuAppend1(menuRoute, ID_RT_MENU_SHOWNAMES,
774 _(
"Hide Waypoint Names"));
776 MenuAppend1(menuRoute, ID_RT_MENU_SHOWNAMES,
777 _(
"Show Waypoint Names"));
779 MenuAppend1(menuRoute, ID_RT_MENU_RESEQUENCE,
780 _(
"Resequence Waypoints..."));
783 wxString port = parent->FindValidUploadPort();
784 parent->m_active_upload_port = port;
785 wxString item = _(
"Send to GPS");
786 if (!port.IsEmpty()) {
787 item.Append(_T(
" ( "));
789 item.Append(_T(
" )"));
791 MenuAppend1(menuRoute, ID_RT_MENU_SENDTOGPS, item);
793 if (!port.IsEmpty()) {
794 wxString item = _(
"Send to new GPS");
795 MenuAppend1(menuRoute, ID_RT_MENU_SENDTONEWGPS, item);
798 wxString itemstp = SYMBOL_STP_TITLE;
799 MenuAppend1(menuRoute, ID_RT_MENU_SENDTOPEER, itemstp);
802 if (menuFocus != menuAIS) menuFocus = menuRoute;
805 if (seltype & SELTYPE_TRACKSEGMENT) {
806 name = wxEmptyString;
807 if (!g_bBasicMenus && m_pSelectedTrack)
808 name = _T(
" ( ") + m_pSelectedTrack->GetName(
true) + _T(
" )");
810 name = wxEmptyString;
812 if (m_pSelectedTrack && m_pSelectedTrack->m_bIsInLayer) blay =
true;
815 menuTrack =
new wxMenu(_(
"Layer Track") + name);
816 MenuAppend1(menuTrack, ID_TK_MENU_PROPERTIES,
817 _(
"Properties") + _T(
"..." ));
819 menuTrack =
new wxMenu(_(
"Track") + name);
820 MenuAppend1(menuTrack, ID_TK_MENU_PROPERTIES,
821 _(
"Properties") + _T(
"..." ));
822 MenuAppend1(menuTrack, ID_TK_MENU_COPY, _(
"Copy as KML"));
823 MenuAppend1(menuTrack, ID_TK_MENU_DELETE, _(
"Delete") + _T(
"..." ));
826 wxString itemstp = SYMBOL_STP_TITLE;
827 MenuAppend1(menuTrack, ID_TK_MENU_SENDTOPEER, itemstp);
830 if (menuFocus != menuAIS) menuFocus = menuTrack;
833 if (seltype & SELTYPE_ROUTEPOINT) {
834 if (!g_bBasicMenus && m_pFoundRoutePoint) {
835 name = m_pFoundRoutePoint->GetName();
836 if (name.IsEmpty()) name = _(
"Unnamed Waypoint");
837 name.Prepend(_T(
" ( ")).Append(_T(
" )"));
839 name = wxEmptyString;
841 if (m_pFoundRoutePoint && m_pFoundRoutePoint->m_bIsInLayer) blay =
true;
844 menuWaypoint =
new wxMenu(_(
"Layer Waypoint") + name);
845 MenuAppend1(menuWaypoint, ID_WP_MENU_PROPERTIES,
846 _(
"Properties") + _T(
"..." ));
848 if (m_pSelectedRoute && m_pSelectedRoute->IsActive())
849 MenuAppend1(menuWaypoint, ID_RT_MENU_ACTPOINT, _(
"Activate"));
851 menuWaypoint =
new wxMenu(_(
"Waypoint") + name);
852 MenuAppend1(menuWaypoint, ID_WP_MENU_PROPERTIES,
853 _(
"Properties") + _T(
"..." ));
854 if (m_pSelectedRoute && m_pSelectedRoute->IsActive()) {
856 MenuAppend1(menuWaypoint, ID_RT_MENU_ACTPOINT, _(
"Activate"));
859 if (m_pSelectedRoute && m_pSelectedRoute->IsActive()) {
861 int indexActive = m_pSelectedRoute->GetIndexOf(
863 if ((indexActive + 1) <= m_pSelectedRoute->GetnPoints())
864 MenuAppend1(menuWaypoint, ID_RT_MENU_ACTNXTPOINT,
865 _(
"Activate Next Waypoint"));
868 if (m_pSelectedRoute && m_pSelectedRoute->GetnPoints() > 2) {
869 MenuAppend1(menuWaypoint, ID_RT_MENU_REMPOINT, _(
"Remove from Route"));
871 m_SelectedIdx = m_pSelectedRoute->GetIndexOf(m_pFoundRoutePoint);
872 if (m_SelectedIdx > 1 && m_SelectedIdx < m_pSelectedRoute->GetnPoints())
873 MenuAppend1(menuWaypoint, ID_RT_MENU_SPLIT_WPT,
874 _(
"Split Route at Waypoint"));
877 MenuAppend1(menuWaypoint, ID_WPT_MENU_COPY, _(
"Copy as KML"));
879 if (m_pFoundRoutePoint && m_pFoundRoutePoint->GetIconName() != _T(
"mob"))
880 MenuAppend1(menuWaypoint, ID_RT_MENU_DELPOINT, _(
"Delete"));
883 wxString port = parent->FindValidUploadPort();
884 parent->m_active_upload_port = port;
885 wxString item = _(
"Send to GPS");
886 if (!port.IsEmpty()) {
887 item.Append(_T(
" ( "));
889 item.Append(_T(
" )"));
891 MenuAppend1(menuWaypoint, ID_WPT_MENU_SENDTOGPS, item);
893 if (!port.IsEmpty()) {
894 wxString item = _(
"Send to new GPS");
895 MenuAppend1(menuWaypoint, ID_WPT_MENU_SENDTONEWGPS, item);
898 MenuAppend1(menuWaypoint, ID_WPT_MENU_SENDTOPEER,
903 if (menuFocus != menuAIS) menuFocus = menuWaypoint;
906 if (seltype & SELTYPE_MARKPOINT) {
907 if (!g_bBasicMenus && m_pFoundRoutePoint) {
908 name = m_pFoundRoutePoint->GetName();
909 if (name.IsEmpty()) name = _(
"Unnamed Mark");
910 name.Prepend(_T(
" ( ")).Append(_T(
" )"));
912 name = wxEmptyString;
914 if (m_pFoundRoutePoint && m_pFoundRoutePoint->m_bIsInLayer) blay =
true;
917 menuWaypoint =
new wxMenu(_(
"Layer Waypoint") + name);
918 MenuAppend1(menuWaypoint, ID_WP_MENU_PROPERTIES,
919 _(
"Properties") + _T(
"..." ));
921 menuWaypoint =
new wxMenu(_(
"Mark") + name);
922 MenuAppend1(menuWaypoint, ID_WP_MENU_PROPERTIES,
923 _(
"Properties") + _T(
"..." ));
925 if (!g_pRouteMan->GetpActiveRoute())
926 MenuAppend1(menuWaypoint, ID_WP_MENU_GOTO, _(
"Navigate To This"));
928 MenuAppend1(menuWaypoint, ID_WPT_MENU_COPY, _(
"Copy as KML"));
930 if (m_pFoundRoutePoint && m_pFoundRoutePoint->GetIconName() != _T(
"mob"))
931 MenuAppend1(menuWaypoint, ID_WP_MENU_DELPOINT, _(
"Delete"));
934 wxString port = parent->FindValidUploadPort();
935 parent->m_active_upload_port = port;
936 wxString item = _(
"Send to GPS");
937 if (!port.IsEmpty()) {
938 item.Append(_T(
" ( "));
940 item.Append(_T(
" )"));
942 MenuAppend1(menuWaypoint, ID_WPT_MENU_SENDTOGPS, item);
944 MenuAppend1(menuWaypoint, ID_WPT_MENU_SENDTOPEER,
948 if ((m_pFoundRoutePoint == pAnchorWatchPoint1) ||
949 (m_pFoundRoutePoint == pAnchorWatchPoint2))
950 MenuAppend1(menuWaypoint, ID_WP_MENU_CLEAR_ANCHORWATCH,
951 _(
"Clear Anchor Watch"));
953 if (m_pFoundRoutePoint && !(m_pFoundRoutePoint->m_bIsInLayer) &&
954 ((NULL == pAnchorWatchPoint1) || (NULL == pAnchorWatchPoint2))) {
957 DistanceBearingMercator(m_pFoundRoutePoint->m_lat,
958 m_pFoundRoutePoint->m_lon, gLat, gLon, &brg,
960 if (dist * 1852. <= g_nAWMax)
961 MenuAppend1(menuWaypoint, ID_WP_MENU_SET_ANCHORWATCH,
962 _(
"Set Anchor Watch"));
967 if (menuFocus != menuAIS) menuFocus = 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();
977 wxMenuItem *subMenu1;
978 if (menuWaypoint && menuFocus != menuWaypoint) {
980 menuFocus->AppendSubMenu(menuWaypoint, menuWaypoint->GetTitle());
981 SetMenuItemFont1(subMenu1);
984 menuWaypoint->SetTitle(wxEmptyString);
987 if (menuTrack && menuFocus != menuTrack) {
988 subMenu1 = menuFocus->AppendSubMenu(menuTrack, menuTrack->GetTitle());
989 SetMenuItemFont1(subMenu1);
992 menuTrack->SetTitle(wxEmptyString);
995 if (menuRoute && menuFocus != menuRoute) {
996 subMenu1 = menuFocus->AppendSubMenu(menuRoute, menuRoute->GetTitle());
997 SetMenuItemFont1(subMenu1);
1000 menuRoute->SetTitle(wxEmptyString);
1003 subMenu1 = menuFocus->AppendSubMenu(contextMenu, _(
"Main Menu"));
1004 SetMenuItemFont1(subMenu1);
1008 if (!subMenuChart->GetMenuItemCount()) contextMenu->Destroy(subItemChart);
1013 if (seltype & SELTYPE_TIDEPOINT) {
1014 menuFocus->AppendSeparator();
1016 MenuAppend1(menuFocus, ID_DEF_MENU_TIDEINFO, _(
"Show Tide Information"));
1019 if (seltype & SELTYPE_CURRENTPOINT) {
1020 if (!bsep) menuFocus->AppendSeparator();
1021 MenuAppend1(menuFocus, ID_DEF_MENU_CURRENTINFO,
1022 _(
"Show Current Information"));
1026 g_pi_manager->PrepareAllPluginContextMenus();
1029 ArrayOfPlugInMenuItems item_array =
1030 g_pi_manager->GetPluginContextMenuItemArray();
1032 for (
unsigned int i = 0; i < item_array.GetCount(); i++) {
1034 if (!pimis->b_viz)
continue;
1036 wxMenu *submenu = NULL;
1037 if (pimis->pmenu_item->GetSubMenu()) {
1038 submenu =
new wxMenu();
1039 const wxMenuItemList &items =
1040 pimis->pmenu_item->GetSubMenu()->GetMenuItems();
1041 for (wxMenuItemList::const_iterator it = items.begin(); it != items.end();
1044 for (
unsigned int j = 0; j < item_array.GetCount(); j++) {
1046 if (pimis->pmenu_item == *it)
id = pimis->id;
1049 wxMenuItem *pmi =
new wxMenuItem(submenu,
id,
1050#
if wxCHECK_VERSION(3, 0, 0)
1051 (*it)->GetItemLabelText(),
1055 (*it)->GetHelp(), (*it)->GetKind());
1058 pmi->SetFont(m_scaledFont);
1063 pmi->SetFont(sFont);
1066 PrepareMenuItem(pmi);
1067 submenu->Append(pmi);
1068 pmi->Check((*it)->IsChecked());
1072 wxMenuItem *pmi =
new wxMenuItem(contextMenu, pimis->id,
1073#
if wxCHECK_VERSION(3, 0, 0)
1074 pimis->pmenu_item->GetItemLabelText(),
1076 pimis->pmenu_item->GetLabel(),
1078 pimis->pmenu_item->GetHelp(),
1079 pimis->pmenu_item->GetKind(), submenu);
1081 pmi->SetFont(m_scaledFont);
1086 pmi->SetFont(sFont);
1089 PrepareMenuItem(pmi);
1091 wxMenu *dst = contextMenu;
1092 if (pimis->m_in_menu ==
"Waypoint")
1094 else if (pimis->m_in_menu ==
"Route")
1096 else if (pimis->m_in_menu ==
"Track")
1098 else if (pimis->m_in_menu ==
"AIS")
1103 dst->Enable(pimis->id, !pimis->b_grey);
1110 androidEnableBackButton(
false);
1111 androidEnableOptionsMenu(
false);
1119 parent->PopupMenu(menuFocus, x, y);
1122 androidEnableBackButton(
true);
1123 androidEnableOptionsMenu(
true);
1130 if (!(sub_menu & MMMENU))
delete contextMenu;
1131 if (!(sub_menu & RTMENU))
delete menuRoute;
1132 if (!(sub_menu & TKMENU))
delete menuTrack;
1133 if (!(sub_menu & WPMENU))
delete menuWaypoint;
1136void CanvasMenuHandler::PopupMenuHandler(wxCommandEvent &event) {
1143 bool dupFirstWpt =
true, showRPD;
1148 switch (event.GetId()) {
1149 case ID_DEF_MENU_MAX_DETAIL:
1152 parent->ClearbFollow();
1154 parent->parent_frame->DoChartUpdate();
1156 parent->SelectChartFromStack(0,
false, CHART_TYPE_DONTCARE,
1157 CHART_FAMILY_RASTER);
1160 case ID_DEF_MENU_SCALE_IN:
1161 parent->DoCanvasStackDelta(-1);
1164 case ID_DEF_MENU_SCALE_OUT:
1165 parent->DoCanvasStackDelta(1);
1169 parent->undo->UndoLastAction();
1170 parent->InvalidateGL();
1171 parent->Refresh(
false);
1175 parent->undo->RedoNextAction();
1176 parent->InvalidateGL();
1177 parent->Refresh(
false);
1180 case ID_DEF_MENU_MOVE_BOAT_HERE:
1183 gFrame->UpdateStatusBar();
1186 case ID_DEF_MENU_GOTO_HERE: {
1188 wxEmptyString, wxEmptyString);
1189 pSelect->AddSelectableRoutePoint(zlat, zlon, pWP_dest);
1192 wxEmptyString, wxEmptyString);
1193 pSelect->AddSelectableRoutePoint(gLat, gLon, pWP_src);
1196 pRouteList->Append(temp_route);
1198 temp_route->AddPoint(pWP_src);
1199 temp_route->AddPoint(pWP_dest);
1201 pSelect->AddSelectableRouteSegment(gLat, gLon, zlat, zlon, pWP_src,
1202 pWP_dest, temp_route);
1211 if (g_pRouteMan->GetpActiveRoute()) g_pRouteMan->DeactivateRoute();
1218 case ID_DEF_MENU_DROP_WP: {
1220 wxEmptyString, wxEmptyString);
1222 pSelect->AddSelectableRoutePoint(zlat, zlon, pWP);
1223 pConfig->AddNewWayPoint(pWP, -1);
1227 if (RouteManagerDialog::getInstanceFlag()) {
1228 if (pRouteManagerDialog && pRouteManagerDialog->IsShown()) {
1229 pRouteManagerDialog->UpdateWptListCtrl();
1233 parent->undo->BeforeUndoableAction(Undo_CreateWaypoint, pWP,
1234 Undo_HasParent, NULL);
1235 parent->undo->AfterUndoableAction(NULL);
1236 gFrame->RefreshAllCanvas(
false);
1237 gFrame->InvalidateAllGL();
1238 g_FlushNavobjChanges =
true;
1242 case ID_DEF_MENU_NEW_RT: {
1243 parent->StartRoute();
1247 case ID_DEF_MENU_AISTARGETLIST:
1248 parent->ShowAISTargetList();
1251 case ID_DEF_MENU_AIS_CPAWARNING:
1252 parent->ToggleCPAWarn();
1255 case ID_WP_MENU_GOTO: {
1257 wxEmptyString, wxEmptyString);
1258 pSelect->AddSelectableRoutePoint(gLat, gLon, pWP_src);
1261 pRouteList->Append(temp_route);
1263 temp_route->AddPoint(pWP_src);
1264 temp_route->AddPoint(m_pFoundRoutePoint);
1265 m_pFoundRoutePoint->SetShared(
true);
1267 pSelect->AddSelectableRouteSegment(gLat, gLon, m_pFoundRoutePoint->m_lat,
1268 m_pFoundRoutePoint->m_lon, pWP_src,
1269 m_pFoundRoutePoint, temp_route);
1271 wxString name = m_pFoundRoutePoint->GetName();
1272 if (name.IsEmpty()) name = _(
"(Unnamed Waypoint)");
1273 wxString rteName = _(
"Go to ");
1274 rteName.Append(name);
1281 if (g_pRouteMan->GetpActiveRoute()) g_pRouteMan->DeactivateRoute();
1288 case ID_DEF_MENU_COGUP:
1289 parent->SetUpMode(COURSE_UP_MODE);
1292 case ID_DEF_MENU_HEADUP:
1293 parent->SetUpMode(HEAD_UP_MODE);
1296 case ID_DEF_MENU_NORTHUP:
1297 parent->SetUpMode(NORTH_UP_MODE);
1300 case ID_DEF_MENU_TOGGLE_FULL:
1301 gFrame->ToggleFullScreen();
1304 case ID_DEF_MENU_GOTOPOSITION:
1305 if (NULL == pGoToPositionDialog)
1308 pGoToPositionDialog->SetCanvas(parent);
1309 pGoToPositionDialog->CheckPasteBufferForPosition();
1310 pGoToPositionDialog->Show();
1313 case ID_WP_MENU_DELPOINT: {
1314 if (m_pFoundRoutePoint == pAnchorWatchPoint1) {
1315 pAnchorWatchPoint1 = NULL;
1317 }
else if (m_pFoundRoutePoint == pAnchorWatchPoint2) {
1318 pAnchorWatchPoint2 = NULL;
1322 if (m_pFoundRoutePoint && !(m_pFoundRoutePoint->m_bIsInLayer) &&
1323 (m_pFoundRoutePoint->GetIconName() != _T(
"mob"))) {
1327 wxArrayPtrVoid *proute_array =
1330 pWayPointMan->DestroyWaypoint(m_pFoundRoutePoint);
1331 delete proute_array;
1333 parent->undo->BeforeUndoableAction(
1334 Undo_DeleteWaypoint, m_pFoundRoutePoint, Undo_IsOrphanded,
1336 pConfig->DeleteWayPoint(m_pFoundRoutePoint);
1337 pSelect->DeleteSelectablePoint(m_pFoundRoutePoint,
1338 SELTYPE_ROUTEPOINT);
1339 if (NULL != pWayPointMan)
1341 parent->undo->AfterUndoableAction(NULL);
1344 if (g_pMarkInfoDialog) {
1345 g_pMarkInfoDialog->ClearData();
1348 if (RouteManagerDialog::getInstanceFlag()) {
1349 if (pRouteManagerDialog) {
1350 if (pRouteManagerDialog->IsShown())
1351 pRouteManagerDialog->UpdateWptListCtrl();
1355 gFrame->RefreshAllCanvas(
false);
1356 gFrame->InvalidateAllGL();
1360 case ID_WP_MENU_PROPERTIES:
1361 parent->ShowMarkPropertiesDialog(m_pFoundRoutePoint);
1364 case ID_WP_MENU_CLEAR_ANCHORWATCH: {
1365 wxString guid = wxEmptyString;
1366 if (pAnchorWatchPoint1 == m_pFoundRoutePoint) {
1367 pAnchorWatchPoint1 = NULL;
1370 }
else if (pAnchorWatchPoint2 == m_pFoundRoutePoint) {
1371 pAnchorWatchPoint2 = NULL;
1375 if (!guid.IsEmpty()) {
1377 v[_T(
"GUID")] = guid;
1378 wxString msg_id(_T(
"OCPN_ANCHOR_WATCH_CLEARED"));
1379 SendJSONMessageToAllPlugins(msg_id, v);
1384 case ID_WP_MENU_SET_ANCHORWATCH: {
1385 wxString guid = wxEmptyString;
1386 if (pAnchorWatchPoint1 == NULL) {
1387 pAnchorWatchPoint1 = m_pFoundRoutePoint;
1388 g_AW1GUID = pAnchorWatchPoint1->m_GUID;
1391 nn = m_pFoundRoutePoint->GetName();
1393 nn.Printf(_T(
"%d m"), g_nAWDefault);
1394 m_pFoundRoutePoint->SetName(nn);
1396 }
else if (pAnchorWatchPoint2 == NULL) {
1397 pAnchorWatchPoint2 = m_pFoundRoutePoint;
1398 g_AW2GUID = pAnchorWatchPoint2->m_GUID;
1401 nn = m_pFoundRoutePoint->GetName();
1403 nn.Printf(_T(
"%d m"), g_nAWDefault);
1404 m_pFoundRoutePoint->SetName(nn);
1407 if (!guid.IsEmpty()) {
1409 v[_T(
"GUID")] = guid;
1410 wxString msg_id(_T(
"OCPN_ANCHOR_WATCH_SET"));
1411 SendJSONMessageToAllPlugins(msg_id, v);
1416 case ID_DEF_MENU_ACTIVATE_MEASURE:
1417 parent->StartMeasureRoute();
1420 case ID_DEF_MENU_DEACTIVATE_MEASURE:
1421 parent->CancelMeasureRoute();
1423 parent->InvalidateGL();
1424 parent->Refresh(
false);
1427 case ID_DEF_MENU_CM93OFFSET_DIALOG: {
1428 if (NULL == g_pCM93OffsetDialog) {
1433 if (!parent->GetVP().b_quilt && parent->m_singleChart &&
1434 (parent->m_singleChart->GetChartType() == CHART_TYPE_CM93COMP)) {
1438 if (g_pCM93OffsetDialog) {
1439 g_pCM93OffsetDialog->SetCM93Chart(pch);
1440 g_pCM93OffsetDialog->Show();
1441 g_pCM93OffsetDialog->UpdateMCOVRList(parent->GetVP());
1446 case ID_DEF_MENU_QUERY: {
1447 parent->ShowObjectQueryWindow(popx, popy, zlat, zlon);
1450 case ID_DEF_MENU_AIS_QUERY: {
1451 ShowAISTargetQueryDialog(parent, m_FoundAIS_MMSI);
1455 case ID_DEF_MENU_AIS_CPA: {
1456 auto myptarget = g_pAIS->Get_Target_Data_From_MMSI(m_FoundAIS_MMSI);
1457 if (myptarget) myptarget->Toggle_AIS_CPA();
1461 case ID_DEF_MENU_AISSHOWTRACK: {
1462 auto myptarget = g_pAIS->Get_Target_Data_From_MMSI(m_FoundAIS_MMSI);
1463 if (myptarget) myptarget->ToggleShowTrack();
1467 case ID_DEF_MENU_COPY_MMSI: {
1469 if (wxTheClipboard->Open()) {
1470 wxTheClipboard->SetData(
new wxTextDataObject(
1471 wxString::Format(wxT(
"%09d"), m_FoundAIS_MMSI)));
1472 wxTheClipboard->Close();
1477 case ID_DEF_MENU_QUILTREMOVE: {
1478 if (parent->GetVP().b_quilt) {
1479 int dbIndex = parent->m_pQuilt->GetChartdbIndexAtPix(
1480 parent->GetVP(), wxPoint(popx, popy));
1481 parent->RemoveChartFromQuilt(dbIndex);
1489 case ID_DEF_MENU_CURRENTINFO: {
1490 parent->DrawTCWindow(popx, popy, (
void *)m_pIDXCandidate);
1491 parent->Refresh(
false);
1496 case ID_DEF_MENU_TIDEINFO: {
1497 parent->DrawTCWindow(popx, popy, (
void *)m_pIDXCandidate);
1498 parent->Refresh(
false);
1503 case ID_DGB_MENU_NMEA_WINDOW:
1505 m_nmea_log->Raise();
1508 case ID_RT_MENU_REVERSE: {
1512 OCPNMessageBox(parent, g_pRouteMan->GetRouteReverseMessage(),
1513 _(
"Rename Waypoints?"), wxYES_NO | wxCANCEL);
1515 if (ask_return != wxID_CANCEL) {
1516 pSelect->DeleteAllSelectableRouteSegments(m_pSelectedRoute);
1517 m_pSelectedRoute->Reverse(ask_return == wxID_YES);
1518 pSelect->AddAllSelectableRouteSegments(m_pSelectedRoute);
1520 pConfig->UpdateRoute(m_pSelectedRoute);
1522 if (pRoutePropDialog && (pRoutePropDialog->IsShown())) {
1523 pRoutePropDialog->SetRouteAndUpdate(m_pSelectedRoute);
1526 gFrame->InvalidateAllGL();
1527 gFrame->RefreshAllCanvas();
1532 case ID_RT_MENU_SHOWNAMES: {
1533 if (m_pSelectedRoute) {
1534 m_pSelectedRoute->ShowWaypointNames(
1535 !m_pSelectedRoute->AreWaypointNamesVisible());
1541 case ID_RT_MENU_RESEQUENCE: {
1542 if (m_pSelectedRoute) {
1546 OCPNMessageBox(parent, g_pRouteMan->GetRouteResequenceMessage(),
1547 _(
"Rename Waypoints?"), wxYES_NO | wxCANCEL);
1549 if (ask_return != wxID_CANCEL) {
1550 m_pSelectedRoute->RenameRoutePoints();
1553 gFrame->InvalidateAllGL();
1554 gFrame->RefreshAllCanvas();
1560 case ID_RT_MENU_DELETE: {
1561 bool confirmed = RouteGui::OnDelete(parent);
1564 if (g_pRouteMan->GetpActiveRoute() == m_pSelectedRoute)
1565 g_pRouteMan->DeactivateRoute();
1570 NavObjectChanges::getInstance()))
1573 if (RouteManagerDialog::getInstanceFlag()) {
1574 if (pRouteManagerDialog && pRouteManagerDialog->IsShown())
1575 pRouteManagerDialog->UpdateRouteListCtrl();
1578 if (g_pMarkInfoDialog && g_pMarkInfoDialog->IsShown()) {
1579 g_pMarkInfoDialog->ValidateMark();
1580 g_pMarkInfoDialog->UpdateProperties();
1583 parent->undo->InvalidateUndo();
1585 gFrame->InvalidateAllGL();
1586 gFrame->RefreshAllCanvas();
1591 case ID_RT_MENU_ACTIVATE: {
1592 if (g_pRouteMan->GetpActiveRoute()) g_pRouteMan->DeactivateRoute();
1598 if (m_pSelectedRoute) {
1601 best_point = g_pRouteMan->FindBestActivatePoint(
1602 m_pSelectedRoute, gLat, gLon, gCog, gSog);
1604 best_point = m_pSelectedRoute->GetPoint(2);
1613 case ID_RT_MENU_DEACTIVATE:
1614 g_pRouteMan->DeactivateRoute();
1619 case ID_RT_MENU_INSERT: {
1621 bool rename =
false;
1622 m_pSelectedRoute->InsertPointAfter(m_pFoundRoutePoint, zlat, zlon,
1625 pSelect->DeleteAllSelectableRoutePoints(m_pSelectedRoute);
1626 pSelect->DeleteAllSelectableRouteSegments(m_pSelectedRoute);
1628 pSelect->AddAllSelectableRouteSegments(m_pSelectedRoute);
1629 pSelect->AddAllSelectableRoutePoints(m_pSelectedRoute);
1642 pConfig->UpdateRoute(m_pSelectedRoute);
1644 if (pRoutePropDialog && (pRoutePropDialog->IsShown())) {
1645 pRoutePropDialog->SetRouteAndUpdate(m_pSelectedRoute,
true);
1651 case ID_RT_MENU_APPEND:
1655 parent->m_pMouseRoute = m_pSelectedRoute;
1656 parent->m_routeState = m_pSelectedRoute->GetnPoints() + 1;
1658 m_pSelectedRoute->GetnPoints();
1659 parent->m_pMouseRoute->SetHiLite(50);
1661 pLast = m_pSelectedRoute->GetLastPoint();
1663 parent->m_prev_rlat = pLast->m_lat;
1664 parent->m_prev_rlon = pLast->m_lon;
1665 parent->m_prev_pMousePoint = pLast;
1667 parent->m_bAppendingRoute =
true;
1669 parent->SetCursor(*parent->pCursorPencil);
1671 androidSetRouteAnnunciator(
true);
1674 parent->HideGlobalToolbar();
1678 case ID_RT_MENU_SPLIT_LEG:
1680 dupFirstWpt =
false;
1681 case ID_RT_MENU_SPLIT_WPT:
1683 showRPD = (pRoutePropDialog && pRoutePropDialog->IsShown());
1685 if (g_pRouteMan->GetpActiveRoute() == m_pSelectedRoute)
1686 g_pRouteMan->DeactivateRoute();
1688 m_pHead =
new Route();
1689 m_pTail =
new Route();
1690 m_pHead->CloneRoute(m_pSelectedRoute, 1, m_SelectedIdx, _(
"_A"));
1691 m_pTail->CloneRoute(m_pSelectedRoute, m_SelectedIdx + splitMode,
1692 m_pSelectedRoute->GetnPoints(), _(
"_B"), dupFirstWpt);
1693 pRouteList->Append(m_pHead);
1694 pConfig->AddNewRoute(m_pHead);
1696 pRouteList->Append(m_pTail);
1697 pConfig->AddNewRoute(m_pTail);
1699 pConfig->DeleteConfigRoute(m_pSelectedRoute);
1701 pSelect->DeleteAllSelectableRoutePoints(m_pSelectedRoute);
1702 pSelect->DeleteAllSelectableRouteSegments(m_pSelectedRoute);
1704 NavObjectChanges::getInstance());
1705 pSelect->AddAllSelectableRouteSegments(m_pTail);
1706 pSelect->AddAllSelectableRoutePoints(m_pTail);
1707 pSelect->AddAllSelectableRouteSegments(m_pHead);
1708 pSelect->AddAllSelectableRoutePoints(m_pHead);
1711 pRoutePropDialog->SetRouteAndUpdate(m_pHead);
1712 pRoutePropDialog->Show();
1714 if (RouteManagerDialog::getInstanceFlag() && pRouteManagerDialog &&
1715 (pRouteManagerDialog->IsShown()))
1716 pRouteManagerDialog->UpdateRouteListCtrl();
1719 case ID_RT_MENU_COPY:
1720 if (m_pSelectedRoute) Kml::CopyRouteToClipboard(m_pSelectedRoute);
1723 case ID_TK_MENU_COPY:
1724 if (m_pSelectedTrack) Kml::CopyTrackToClipboard(m_pSelectedTrack);
1727 case ID_WPT_MENU_COPY:
1728 if (m_pFoundRoutePoint) Kml::CopyWaypointToClipboard(m_pFoundRoutePoint);
1731 case ID_WPT_MENU_SENDTOGPS:
1732 if (m_pFoundRoutePoint) {
1733 if (parent->m_active_upload_port.Length())
1735 .SendToGPS(parent->m_active_upload_port.BeforeFirst(
' '), NULL);
1738 dlg.SetWaypoint(m_pFoundRoutePoint);
1742 dlg.Create(NULL, -1, _(
"Send to GPS") + _T(
"..." ), _T(
""));
1748 case ID_WPT_MENU_SENDTONEWGPS:
1749 if (m_pFoundRoutePoint) {
1751 dlg.SetWaypoint(m_pFoundRoutePoint);
1753 dlg.Create(NULL, -1, _(
"Send to GPS") + _T(
"..." ), _T(
""));
1758 case ID_WPT_MENU_SENDTOPEER:
1759 if (m_pFoundRoutePoint) {
1761 dlg.SetWaypoint(m_pFoundRoutePoint);
1766 MdnsCache::GetInstance().
Validate();
1767 if (MdnsCache::GetInstance().GetCache().empty())
1768 dlg.SetScanOnCreate(
true);
1771 dlg.Create(NULL, -1, _(
"Send Waypoint to OpenCPN Peer") + _T(
"..." ),
1777 case ID_RT_MENU_SENDTOGPS:
1778 if (m_pSelectedRoute) {
1779 if (parent->m_active_upload_port.Length())
1781 .SendToGPS(parent->m_active_upload_port.BeforeFirst(
' '),
true,
1785 dlg.SetRoute(m_pSelectedRoute);
1787 dlg.Create(NULL, -1, _(
"Send to GPS") + _T(
"..." ), _T(
""));
1793 case ID_RT_MENU_SENDTONEWGPS:
1794 if (m_pSelectedRoute) {
1796 dlg.SetRoute(m_pSelectedRoute);
1798 dlg.Create(NULL, -1, _(
"Send to GPS") + _T(
"..." ), _T(
""));
1803 case ID_RT_MENU_SENDTOPEER:
1804 if (m_pSelectedRoute) {
1806 dlg.SetRoute(m_pSelectedRoute);
1811 MdnsCache::GetInstance().
Validate();
1812 if (MdnsCache::GetInstance().GetCache().empty())
1813 dlg.SetScanOnCreate(
true);
1816 dlg.Create(NULL, -1, _(
"Send Route to OpenCPN Peer") + _T(
"..." ),
1822 case ID_PASTE_WAYPOINT:
1823 pupHandler_PasteWaypoint();
1826 case ID_PASTE_ROUTE:
1827 pupHandler_PasteRoute();
1830 case ID_PASTE_TRACK:
1831 pupHandler_PasteTrack();
1834 case ID_RT_MENU_DELPOINT:
1835 if (m_pSelectedRoute) {
1838 pWayPointMan->DestroyWaypoint(m_pFoundRoutePoint);
1840 if (pRoutePropDialog && (pRoutePropDialog->IsShown())) {
1843 if (g_pRouteMan->IsRouteValid(m_pSelectedRoute)) {
1844 pRoutePropDialog->SetRouteAndUpdate(m_pSelectedRoute,
true);
1846 pRoutePropDialog->Hide();
1849 if (RouteManagerDialog::getInstanceFlag()) {
1850 if (pRouteManagerDialog && pRouteManagerDialog->IsShown()) {
1851 pRouteManagerDialog->UpdateWptListCtrl();
1852 pRouteManagerDialog->UpdateRouteListCtrl();
1856 gFrame->InvalidateAllGL();
1857 gFrame->RefreshAllCanvas(
true);
1862 case ID_RT_MENU_REMPOINT:
1863 if (m_pSelectedRoute) {
1865 g_pRouteMan->RemovePointFromRoute(m_pFoundRoutePoint, m_pSelectedRoute,
1866 parent->m_routeState);
1867 gFrame->InvalidateAllGL();
1868 gFrame->RefreshAllCanvas();
1872 case ID_RT_MENU_ACTPOINT:
1873 if (g_pRouteMan->GetpActiveRoute() == m_pSelectedRoute) {
1880 case ID_RT_MENU_DEACTPOINT:
1883 case ID_RT_MENU_ACTNXTPOINT:
1884 if (g_pRouteMan->GetpActiveRoute() == m_pSelectedRoute) {
1891 case ID_RT_MENU_PROPERTIES: {
1892 parent->ShowRoutePropertiesDialog(_(
"Route Properties"),
1897 case ID_TK_MENU_PROPERTIES: {
1898 parent->ShowTrackPropertiesDialog(m_pSelectedTrack);
1902 case ID_TK_MENU_DELETE: {
1903 int dlg_return = wxID_YES;
1904 if (g_bConfirmObjectDelete) {
1905 dlg_return = OCPNMessageBox(
1906 parent, _(
"Are you sure you want to delete this track?"),
1907 _(
"OpenCPN Track Delete"),
1908 (
long)wxYES_NO | wxCANCEL | wxYES_DEFAULT);
1911 if (dlg_return == wxID_YES) {
1912 if (m_pSelectedTrack == g_pActiveTrack)
1913 m_pSelectedTrack = parent->parent_frame->TrackOff();
1914 g_pAIS->DeletePersistentTrack(m_pSelectedTrack);
1915 pConfig->DeleteConfigTrack(m_pSelectedTrack);
1917 RoutemanGui(*g_pRouteMan).DeleteTrack(m_pSelectedTrack);
1919 if (TrackPropDlg::getInstanceFlag() && pTrackPropDialog &&
1920 (pTrackPropDialog->IsShown()) &&
1921 (m_pSelectedTrack == pTrackPropDialog->GetTrack())) {
1922 pTrackPropDialog->Hide();
1925 if (RoutePropDlgImpl::getInstanceFlag() && pRouteManagerDialog &&
1926 pRouteManagerDialog->IsShown()) {
1927 pRouteManagerDialog->UpdateTrkListCtrl();
1928 pRouteManagerDialog->UpdateRouteListCtrl();
1930 gFrame->InvalidateAllGL();
1931 gFrame->RefreshAllCanvas();
1936 case ID_TK_MENU_SENDTOPEER:
1937 if (m_pSelectedTrack) {
1939 dlg.SetTrack(m_pSelectedTrack);
1944 MdnsCache::GetInstance().
Validate();
1945 if (MdnsCache::GetInstance().GetCache().empty())
1946 dlg.SetScanOnCreate(
true);
1949 dlg.Create(NULL, -1, _(
"Send Track to OpenCPN Peer") + _T(
"..." ),
1955 case ID_RC_MENU_SCALE_IN:
1956 parent->parent_frame->DoStackDown(parent);
1958 parent->WarpPointer(r.x, r.y);
1961 case ID_RC_MENU_SCALE_OUT:
1962 parent->parent_frame->DoStackUp(parent);
1964 parent->WarpPointer(r.x, r.y);
1967 case ID_RC_MENU_ZOOM_IN:
1970 parent->WarpPointer(r.x, r.y);
1973 case ID_RC_MENU_ZOOM_OUT:
1976 parent->WarpPointer(r.x, r.y);
1979 case ID_RC_MENU_FINISH:
1980 parent->FinishRoute();
1982 parent->Refresh(
false);
1983 g_FlushNavobjChanges =
true;
1986 case ID_DEF_ZERO_XTE:
1987 g_pRouteMan->ZeroCurrentXTEToActivePoint();
1993 ArrayOfPlugInMenuItems item_array =
1994 g_pi_manager->GetPluginContextMenuItemArray();
1996 for (
unsigned int i = 0; i < item_array.GetCount(); i++) {
1999 if (pimis->id == event.GetId()) {
2000 if (pimis->m_pplugin)
2011 if ((event.GetId() >= ID_DEF_MENU_GROUPBASE) &&
2013 ID_DEF_MENU_GROUPBASE + (
int)g_pGroupArray->GetCount())) {
2014 parent->SetGroupIndex(event.GetId() - ID_DEF_MENU_GROUPBASE);
2017 parent->InvalidateGL();
Global state for AIS decoder.
Represents an active track that is currently being recorded.
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.
Dialog for displaying and editing waypoint properties.
void Validate()
Check that all entries are accessible, remove stale ones.
Represents a waypoint or mark within the navigation system.
bool m_bIsolatedMark
Flag indicating if the waypoint is a standalone mark.
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.
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, NavObjectChanges *nav_obj_changes)
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.
Hooks into gui available in model.
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.
MdnsCache mDNS host lookups cache.
Tools to send data to plugins.