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) {
716 name = m_pSelectedRoute->m_RouteNameString;
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(
731 m_pSelectedRoute->m_pRouteActivePoint);
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(
749 m_pSelectedRoute->m_pRouteActivePoint);
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()) {
855 if (m_pSelectedRoute->m_pRouteActivePoint != m_pFoundRoutePoint)
856 MenuAppend1(menuWaypoint, ID_RT_MENU_ACTPOINT, _(
"Activate"));
859 if (m_pSelectedRoute && m_pSelectedRoute->IsActive()) {
860 if (m_pSelectedRoute->m_pRouteActivePoint == m_pFoundRoutePoint) {
861 int indexActive = m_pSelectedRoute->GetIndexOf(
862 m_pSelectedRoute->m_pRouteActivePoint);
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);
1204 temp_route->m_RouteNameString = _(
"Temporary GOTO Route");
1205 temp_route->m_RouteStartString = _(
"Here");
1207 temp_route->m_RouteEndString = _(
"There");
1209 temp_route->m_bDeleteOnArrival =
true;
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);
1275 temp_route->m_RouteNameString = rteName;
1276 temp_route->m_RouteStartString = _(
"Here");
1278 temp_route->m_RouteEndString = name;
1279 temp_route->m_bDeleteOnArrival =
true;
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:
1507 case ID_RT_MENU_REVERSE: {
1508 if (m_pSelectedRoute->m_bIsInLayer)
break;
1511 OCPNMessageBox(parent, g_pRouteMan->GetRouteReverseMessage(),
1512 _(
"Rename Waypoints?"), wxYES_NO | wxCANCEL);
1514 if (ask_return != wxID_CANCEL) {
1515 pSelect->DeleteAllSelectableRouteSegments(m_pSelectedRoute);
1516 m_pSelectedRoute->Reverse(ask_return == wxID_YES);
1517 pSelect->AddAllSelectableRouteSegments(m_pSelectedRoute);
1519 pConfig->UpdateRoute(m_pSelectedRoute);
1521 if (pRoutePropDialog && (pRoutePropDialog->IsShown())) {
1522 pRoutePropDialog->SetRouteAndUpdate(m_pSelectedRoute);
1525 gFrame->InvalidateAllGL();
1526 gFrame->RefreshAllCanvas();
1531 case ID_RT_MENU_SHOWNAMES: {
1532 if (m_pSelectedRoute) {
1533 m_pSelectedRoute->ShowWaypointNames(
1534 !m_pSelectedRoute->AreWaypointNamesVisible());
1540 case ID_RT_MENU_RESEQUENCE: {
1541 if (m_pSelectedRoute) {
1542 if (m_pSelectedRoute->m_bIsInLayer)
break;
1545 OCPNMessageBox(parent, g_pRouteMan->GetRouteResequenceMessage(),
1546 _(
"Rename Waypoints?"), wxYES_NO | wxCANCEL);
1548 if (ask_return != wxID_CANCEL) {
1549 m_pSelectedRoute->RenameRoutePoints();
1552 gFrame->InvalidateAllGL();
1553 gFrame->RefreshAllCanvas();
1559 case ID_RT_MENU_DELETE: {
1560 bool confirmed = RouteGui::OnDelete(parent);
1563 if (g_pRouteMan->GetpActiveRoute() == m_pSelectedRoute)
1564 g_pRouteMan->DeactivateRoute();
1566 if (m_pSelectedRoute->m_bIsInLayer)
break;
1569 NavObjectChanges::getInstance()))
1572 if (RouteManagerDialog::getInstanceFlag()) {
1573 if (pRouteManagerDialog && pRouteManagerDialog->IsShown())
1574 pRouteManagerDialog->UpdateRouteListCtrl();
1577 if (g_pMarkInfoDialog && g_pMarkInfoDialog->IsShown()) {
1578 g_pMarkInfoDialog->ValidateMark();
1579 g_pMarkInfoDialog->UpdateProperties();
1582 parent->undo->InvalidateUndo();
1584 gFrame->InvalidateAllGL();
1585 gFrame->RefreshAllCanvas();
1590 case ID_RT_MENU_ACTIVATE: {
1591 if (g_pRouteMan->GetpActiveRoute()) g_pRouteMan->DeactivateRoute();
1597 if (m_pSelectedRoute) {
1599 m_pSelectedRoute->m_RouteNameString.Find(_T(
"MOB"))) {
1600 best_point = g_pRouteMan->FindBestActivatePoint(
1601 m_pSelectedRoute, gLat, gLon, gCog, gSog);
1603 best_point = m_pSelectedRoute->GetPoint(2);
1606 m_pSelectedRoute->m_bRtIsSelected =
false;
1612 case ID_RT_MENU_DEACTIVATE:
1613 g_pRouteMan->DeactivateRoute();
1614 m_pSelectedRoute->m_bRtIsSelected =
false;
1618 case ID_RT_MENU_INSERT: {
1619 if (m_pSelectedRoute->m_bIsInLayer)
break;
1620 bool rename =
false;
1621 m_pSelectedRoute->InsertPointAfter(m_pFoundRoutePoint, zlat, zlon,
1624 pSelect->DeleteAllSelectableRoutePoints(m_pSelectedRoute);
1625 pSelect->DeleteAllSelectableRouteSegments(m_pSelectedRoute);
1627 pSelect->AddAllSelectableRouteSegments(m_pSelectedRoute);
1628 pSelect->AddAllSelectableRoutePoints(m_pSelectedRoute);
1641 pConfig->UpdateRoute(m_pSelectedRoute);
1643 if (pRoutePropDialog && (pRoutePropDialog->IsShown())) {
1644 pRoutePropDialog->SetRouteAndUpdate(m_pSelectedRoute,
true);
1650 case ID_RT_MENU_APPEND:
1652 if (m_pSelectedRoute->m_bIsInLayer)
break;
1654 parent->m_pMouseRoute = m_pSelectedRoute;
1655 parent->m_routeState = m_pSelectedRoute->GetnPoints() + 1;
1656 parent->m_pMouseRoute->m_lastMousePointIndex =
1657 m_pSelectedRoute->GetnPoints();
1658 parent->m_pMouseRoute->SetHiLite(50);
1660 pLast = m_pSelectedRoute->GetLastPoint();
1662 parent->m_prev_rlat = pLast->m_lat;
1663 parent->m_prev_rlon = pLast->m_lon;
1664 parent->m_prev_pMousePoint = pLast;
1666 parent->m_bAppendingRoute =
true;
1668 parent->SetCursor(*parent->pCursorPencil);
1670 androidSetRouteAnnunciator(
true);
1673 parent->HideGlobalToolbar();
1677 case ID_RT_MENU_SPLIT_LEG:
1679 dupFirstWpt =
false;
1680 case ID_RT_MENU_SPLIT_WPT:
1682 showRPD = (pRoutePropDialog && pRoutePropDialog->IsShown());
1684 if (g_pRouteMan->GetpActiveRoute() == m_pSelectedRoute)
1685 g_pRouteMan->DeactivateRoute();
1687 m_pHead =
new Route();
1688 m_pTail =
new Route();
1689 m_pHead->CloneRoute(m_pSelectedRoute, 1, m_SelectedIdx, _(
"_A"));
1690 m_pTail->CloneRoute(m_pSelectedRoute, m_SelectedIdx + splitMode,
1691 m_pSelectedRoute->GetnPoints(), _(
"_B"), dupFirstWpt);
1692 pRouteList->Append(m_pHead);
1693 pConfig->AddNewRoute(m_pHead);
1695 pRouteList->Append(m_pTail);
1696 pConfig->AddNewRoute(m_pTail);
1698 pConfig->DeleteConfigRoute(m_pSelectedRoute);
1700 pSelect->DeleteAllSelectableRoutePoints(m_pSelectedRoute);
1701 pSelect->DeleteAllSelectableRouteSegments(m_pSelectedRoute);
1703 NavObjectChanges::getInstance());
1704 pSelect->AddAllSelectableRouteSegments(m_pTail);
1705 pSelect->AddAllSelectableRoutePoints(m_pTail);
1706 pSelect->AddAllSelectableRouteSegments(m_pHead);
1707 pSelect->AddAllSelectableRoutePoints(m_pHead);
1710 pRoutePropDialog->SetRouteAndUpdate(m_pHead);
1711 pRoutePropDialog->Show();
1713 if (RouteManagerDialog::getInstanceFlag() && pRouteManagerDialog &&
1714 (pRouteManagerDialog->IsShown()))
1715 pRouteManagerDialog->UpdateRouteListCtrl();
1718 case ID_RT_MENU_COPY:
1719 if (m_pSelectedRoute) Kml::CopyRouteToClipboard(m_pSelectedRoute);
1722 case ID_TK_MENU_COPY:
1723 if (m_pSelectedTrack) Kml::CopyTrackToClipboard(m_pSelectedTrack);
1726 case ID_WPT_MENU_COPY:
1727 if (m_pFoundRoutePoint) Kml::CopyWaypointToClipboard(m_pFoundRoutePoint);
1730 case ID_WPT_MENU_SENDTOGPS:
1731 if (m_pFoundRoutePoint) {
1732 if (parent->m_active_upload_port.Length())
1734 .SendToGPS(parent->m_active_upload_port.BeforeFirst(
' '), NULL);
1737 dlg.SetWaypoint(m_pFoundRoutePoint);
1741 dlg.Create(NULL, -1, _(
"Send to GPS") + _T(
"..." ), _T(
""));
1747 case ID_WPT_MENU_SENDTONEWGPS:
1748 if (m_pFoundRoutePoint) {
1750 dlg.SetWaypoint(m_pFoundRoutePoint);
1752 dlg.Create(NULL, -1, _(
"Send to GPS") + _T(
"..." ), _T(
""));
1757 case ID_WPT_MENU_SENDTOPEER:
1758 if (m_pFoundRoutePoint) {
1760 dlg.SetWaypoint(m_pFoundRoutePoint);
1765 MdnsCache::GetInstance().
Validate();
1766 if (MdnsCache::GetInstance().GetCache().empty())
1767 dlg.SetScanOnCreate(
true);
1770 dlg.Create(NULL, -1, _(
"Send Waypoint to OpenCPN Peer") + _T(
"..." ),
1776 case ID_RT_MENU_SENDTOGPS:
1777 if (m_pSelectedRoute) {
1778 if (parent->m_active_upload_port.Length())
1780 .SendToGPS(parent->m_active_upload_port.BeforeFirst(
' '),
true,
1784 dlg.SetRoute(m_pSelectedRoute);
1786 dlg.Create(NULL, -1, _(
"Send to GPS") + _T(
"..." ), _T(
""));
1792 case ID_RT_MENU_SENDTONEWGPS:
1793 if (m_pSelectedRoute) {
1795 dlg.SetRoute(m_pSelectedRoute);
1797 dlg.Create(NULL, -1, _(
"Send to GPS") + _T(
"..." ), _T(
""));
1802 case ID_RT_MENU_SENDTOPEER:
1803 if (m_pSelectedRoute) {
1805 dlg.SetRoute(m_pSelectedRoute);
1810 MdnsCache::GetInstance().
Validate();
1811 if (MdnsCache::GetInstance().GetCache().empty())
1812 dlg.SetScanOnCreate(
true);
1815 dlg.Create(NULL, -1, _(
"Send Route to OpenCPN Peer") + _T(
"..." ),
1821 case ID_PASTE_WAYPOINT:
1822 pupHandler_PasteWaypoint();
1825 case ID_PASTE_ROUTE:
1826 pupHandler_PasteRoute();
1829 case ID_PASTE_TRACK:
1830 pupHandler_PasteTrack();
1833 case ID_RT_MENU_DELPOINT:
1834 if (m_pSelectedRoute) {
1835 if (m_pSelectedRoute->m_bIsInLayer)
break;
1837 pWayPointMan->DestroyWaypoint(m_pFoundRoutePoint);
1839 if (pRoutePropDialog && (pRoutePropDialog->IsShown())) {
1842 if (g_pRouteMan->IsRouteValid(m_pSelectedRoute)) {
1843 pRoutePropDialog->SetRouteAndUpdate(m_pSelectedRoute,
true);
1845 pRoutePropDialog->Hide();
1848 if (RouteManagerDialog::getInstanceFlag()) {
1849 if (pRouteManagerDialog && pRouteManagerDialog->IsShown()) {
1850 pRouteManagerDialog->UpdateWptListCtrl();
1851 pRouteManagerDialog->UpdateRouteListCtrl();
1855 gFrame->InvalidateAllGL();
1856 gFrame->RefreshAllCanvas(
true);
1861 case ID_RT_MENU_REMPOINT:
1862 if (m_pSelectedRoute) {
1863 if (m_pSelectedRoute->m_bIsInLayer)
break;
1864 g_pRouteMan->RemovePointFromRoute(m_pFoundRoutePoint, m_pSelectedRoute,
1865 parent->m_routeState);
1866 gFrame->InvalidateAllGL();
1867 gFrame->RefreshAllCanvas();
1871 case ID_RT_MENU_ACTPOINT:
1872 if (g_pRouteMan->GetpActiveRoute() == m_pSelectedRoute) {
1874 m_pSelectedRoute->m_bRtIsSelected =
false;
1879 case ID_RT_MENU_DEACTPOINT:
1882 case ID_RT_MENU_ACTNXTPOINT:
1883 if (g_pRouteMan->GetpActiveRoute() == m_pSelectedRoute) {
1885 m_pSelectedRoute->m_bRtIsSelected =
false;
1890 case ID_RT_MENU_PROPERTIES: {
1891 parent->ShowRoutePropertiesDialog(_(
"Route Properties"),
1896 case ID_TK_MENU_PROPERTIES: {
1897 parent->ShowTrackPropertiesDialog(m_pSelectedTrack);
1901 case ID_TK_MENU_DELETE: {
1902 int dlg_return = wxID_YES;
1903 if (g_bConfirmObjectDelete) {
1904 dlg_return = OCPNMessageBox(
1905 parent, _(
"Are you sure you want to delete this track?"),
1906 _(
"OpenCPN Track Delete"),
1907 (
long)wxYES_NO | wxCANCEL | wxYES_DEFAULT);
1910 if (dlg_return == wxID_YES) {
1911 if (m_pSelectedTrack == g_pActiveTrack)
1912 m_pSelectedTrack = parent->parent_frame->TrackOff();
1913 g_pAIS->DeletePersistentTrack(m_pSelectedTrack);
1914 pConfig->DeleteConfigTrack(m_pSelectedTrack);
1916 RoutemanGui(*g_pRouteMan).DeleteTrack(m_pSelectedTrack);
1918 if (TrackPropDlg::getInstanceFlag() && pTrackPropDialog &&
1919 (pTrackPropDialog->IsShown()) &&
1920 (m_pSelectedTrack == pTrackPropDialog->GetTrack())) {
1921 pTrackPropDialog->Hide();
1924 if (RoutePropDlgImpl::getInstanceFlag() && pRouteManagerDialog &&
1925 pRouteManagerDialog->IsShown()) {
1926 pRouteManagerDialog->UpdateTrkListCtrl();
1927 pRouteManagerDialog->UpdateRouteListCtrl();
1929 gFrame->InvalidateAllGL();
1930 gFrame->RefreshAllCanvas();
1935 case ID_TK_MENU_SENDTOPEER:
1936 if (m_pSelectedTrack) {
1938 dlg.SetTrack(m_pSelectedTrack);
1943 MdnsCache::GetInstance().
Validate();
1944 if (MdnsCache::GetInstance().GetCache().empty())
1945 dlg.SetScanOnCreate(
true);
1948 dlg.Create(NULL, -1, _(
"Send Track to OpenCPN Peer") + _T(
"..." ),
1954 case ID_RC_MENU_SCALE_IN:
1955 parent->parent_frame->DoStackDown(parent);
1957 parent->WarpPointer(r.x, r.y);
1960 case ID_RC_MENU_SCALE_OUT:
1961 parent->parent_frame->DoStackUp(parent);
1963 parent->WarpPointer(r.x, r.y);
1966 case ID_RC_MENU_ZOOM_IN:
1969 parent->WarpPointer(r.x, r.y);
1972 case ID_RC_MENU_ZOOM_OUT:
1975 parent->WarpPointer(r.x, r.y);
1978 case ID_RC_MENU_FINISH:
1979 parent->FinishRoute();
1981 parent->Refresh(
false);
1982 g_FlushNavobjChanges =
true;
1985 case ID_DEF_ZERO_XTE:
1986 g_pRouteMan->ZeroCurrentXTEToActivePoint();
1992 ArrayOfPlugInMenuItems item_array =
1993 g_pi_manager->GetPluginContextMenuItemArray();
1995 for (
unsigned int i = 0; i < item_array.GetCount(); i++) {
1998 if (pimis->id == event.GetId()) {
1999 if (pimis->m_pplugin)
2010 if ((event.GetId() >= ID_DEF_MENU_GROUPBASE) &&
2012 ID_DEF_MENU_GROUPBASE + (
int)g_pGroupArray->GetCount())) {
2013 parent->SetGroupIndex(event.GetId() - ID_DEF_MENU_GROUPBASE);
2016 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 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.