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"
94#include "androidUTIL.h"
100extern void pupHandler_PasteRoute();
101extern void pupHandler_PasteTrack();
102extern void pupHandler_PasteWaypoint();
105extern bool g_bskew_comp;
106extern double vLat, vLon;
108extern ChartGroupArray *g_pGroupArray;
111extern int g_nAWDefault;
112extern wxString g_AW1GUID;
113extern wxString g_AW2GUID;
114extern int g_click_stop;
119extern bool g_bConfirmObjectDelete;
126extern RouteList *pRouteList;
127extern wxString g_default_wp_icon;
128extern bool g_bBasicMenus;
130extern bool g_FlushNavobjChanges;
131extern ColorScheme global_color_scheme;
135 ID_DEF_MENU_MAX_DETAIL = 1,
136 ID_DEF_MENU_SCALE_IN,
137 ID_DEF_MENU_SCALE_OUT,
141 ID_DEF_MENU_MOVE_BOAT_HERE,
142 ID_DEF_MENU_GOTO_HERE,
143 ID_DEF_MENU_GOTOPOSITION,
147 ID_WP_MENU_PROPERTIES,
149 ID_RT_MENU_DEACTIVATE,
153 ID_RT_MENU_SPLIT_LEG,
154 ID_RT_MENU_SPLIT_WPT,
157 ID_WPT_MENU_SENDTOGPS,
158 ID_WPT_MENU_SENDTONEWGPS,
159 ID_WPT_MENU_SENDTOPEER,
167 ID_RT_MENU_DEACTPOINT,
168 ID_RT_MENU_ACTNXTPOINT,
170 ID_RT_MENU_PROPERTIES,
171 ID_RT_MENU_SENDTOGPS,
172 ID_RT_MENU_SENDTONEWGPS,
173 ID_RT_MENU_SHOWNAMES,
174 ID_RT_MENU_RESEQUENCE,
175 ID_RT_MENU_SENDTOPEER,
176 ID_WP_MENU_SET_ANCHORWATCH,
177 ID_WP_MENU_CLEAR_ANCHORWATCH,
178 ID_DEF_MENU_AISTARGETLIST,
179 ID_DEF_MENU_AIS_CPAWARNING,
182 ID_RC_MENU_SCALE_OUT,
186 ID_DEF_MENU_AIS_QUERY,
188 ID_DEF_MENU_AISSHOWTRACK,
189 ID_DEF_MENU_ACTIVATE_MEASURE,
190 ID_DEF_MENU_DEACTIVATE_MEASURE,
191 ID_DEF_MENU_COPY_MMSI,
196 ID_DEF_MENU_CM93OFFSET_DIALOG,
198 ID_TK_MENU_PROPERTIES,
200 ID_TK_MENU_SENDTOPEER,
201 ID_WP_MENU_ADDITIONAL_INFO,
203 ID_DEF_MENU_QUILTREMOVE,
207 ID_DEF_MENU_TOGGLE_FULL,
208 ID_DEF_MENU_TIDEINFO,
209 ID_DEF_MENU_CURRENTINFO,
213 ID_DGB_MENU_NMEA_WINDOW,
215 ID_DEF_MENU_GROUPBASE,
224int CanvasMenuHandler::GetNextContextMenuId() {
225 return ID_DEF_MENU_LAST +
229wxFont CanvasMenuHandler::m_scaledFont;
232CanvasMenuHandler::CanvasMenuHandler(
ChartCanvas *parentCanvas,
235 int selectedAIS_MMSI,
236 void *selectedTCIndex, wxWindow *nmea_log)
237 : m_nmea_log(nmea_log) {
238 parent = parentCanvas;
239 m_pSelectedRoute = selectedRoute;
240 m_pSelectedTrack = selectedTrack;
241 m_pFoundRoutePoint = selectedPoint;
242 m_FoundAIS_MMSI = selectedAIS_MMSI;
243 m_pIDXCandidate = selectedTCIndex;
244 if (!m_scaledFont.IsOk()) {
246 m_scaledFont = *qFont;
252CanvasMenuHandler::~CanvasMenuHandler() {}
258void CanvasMenuHandler::PrepareMenuItem(wxMenuItem *item) {
259#if defined(__WXMSW__)
260 wxColour ctrl_back_color = GetGlobalColor(_T(
"DILG1"));
261 item->SetBackgroundColour(ctrl_back_color);
262 wxColour menu_text_color = GetGlobalColor(_T (
"UITX1" ));
263 item->SetTextColour(menu_text_color);
267void CanvasMenuHandler::MenuPrepend1(wxMenu *menu,
int id, wxString label) {
268 wxMenuItem *item =
new wxMenuItem(menu,
id, label);
269#if defined(__WXMSW__)
270 item->SetFont(m_scaledFont);
275 item->SetFont(sFont);
278 PrepareMenuItem(item);
280 if (g_btouch) menu->InsertSeparator(0);
284void CanvasMenuHandler::MenuAppend1(wxMenu *menu,
int id, wxString label) {
285 wxMenuItem *item =
new wxMenuItem(menu,
id, label);
286#if defined(__WXMSW__)
287 item->SetFont(m_scaledFont);
292 item->SetFont(sFont);
295 PrepareMenuItem(item);
298 if (g_btouch) menu->AppendSeparator();
301void CanvasMenuHandler::SetMenuItemFont1(wxMenuItem *item) {
302#if defined(__WXMSW__)
303 item->SetFont(m_scaledFont);
306#if defined(__ANDROID__)
308 item->SetFont(*qFont);
311 PrepareMenuItem(item);
314void CanvasMenuHandler::CanvasPopupMenu(
int x,
int y,
int seltype) {
315 wxMenu *contextMenu =
new wxMenu;
316 wxMenu *menuWaypoint = NULL;
317 wxMenu *menuRoute = NULL;
318 wxMenu *menuTrack = NULL;
319 wxMenu *menuAIS = NULL;
321 wxMenu *subMenuChart =
new wxMenu;
322 wxMenu *subMenuUndo =
new wxMenu(
"Undo...Ctrl-Z");
325 wxMenu *subMenuRedo =
new wxMenu(
"Redo...Shift-Ctrl-Z");
327 wxMenu *subMenuRedo =
new wxMenu(
"Redo...Ctrl-Y");
329 wxMenu *subMenuDebug =
new wxMenu(
"");
330 MenuAppend1(subMenuDebug, ID_DGB_MENU_NMEA_WINDOW, _(
"Show Data Monitor"));
332 wxMenu *menuFocus = contextMenu;
337 if (!g_bBasicMenus || (seltype != SELTYPE_ROUTECREATE)) {
338 bool bsubMenus =
false;
341 if (parent->undo->AnythingToUndo()) {
343 wxMenuItem *subMenuItemundo =
344 contextMenu->AppendSubMenu(subMenuUndo, _(
"Undo"));
347 undoItem << _(
"Undo") << _T(
" ")
348 << parent->undo->GetNextUndoableAction()->Description();
349 MenuAppend1(subMenuUndo, ID_UNDO, undoItem);
351 if (parent->undo->AnythingToRedo()) {
353 wxMenuItem *subMenuItemRedo =
354 contextMenu->AppendSubMenu(subMenuRedo, _(
"Redo"));
357 redoItem << _(
"Redo") << _T(
" ")
358 << parent->undo->GetNextRedoableAction()->Description();
359 MenuAppend1(subMenuRedo, ID_REDO, redoItem);
362 if (parent->undo->AnythingToUndo()) {
364 undoItem << _(
"Undo") << _T(
" ")
365 << parent->undo->GetNextUndoableAction()->Description();
366 MenuAppend1(contextMenu, ID_UNDO, _menuText(undoItem, _T(
"Ctrl-Z")));
369 if (parent->undo->AnythingToRedo()) {
371 redoItem << _(
"Redo") << _T(
" ")
372 << parent->undo->GetNextRedoableAction()->Description();
374 MenuAppend1(contextMenu, ID_REDO,
375 _menuText(redoItem, _T(
"Shift-Ctrl-Z")));
377 MenuAppend1(contextMenu, ID_REDO, _menuText(redoItem, _T(
"Ctrl-Y")));
383 if (seltype == SELTYPE_ROUTECREATE) {
384 MenuAppend1(contextMenu, ID_RC_MENU_FINISH,
385 _menuText(_(
"End Route"), _T(
"Esc")));
388 if (!parent->m_pMouseRoute) {
389 if (parent->m_bMeasure_Active)
390 MenuAppend1(contextMenu, ID_DEF_MENU_DEACTIVATE_MEASURE,
391 _menuText(_(
"Measure Off"), _T(
"Esc")));
393 MenuAppend1(contextMenu, ID_DEF_MENU_ACTIVATE_MEASURE,
394 _menuText(_(
"Measure"), _T(
"M")));
397 bool ais_areanotice =
false;
398 if (g_pAIS && parent->GetShowAIS() && g_bShowAreaNotices) {
401 for (
const auto &target : g_pAIS->GetAreaNoticeSourcesList()) {
402 auto target_data = target.second;
403 if (!target_data->area_notices.empty()) {
404 for (
auto &ani : target_data->area_notices) {
408 for (Ais8_001_22_SubAreaList::iterator sa =
409 area_notice.sub_areas.begin();
410 sa != area_notice.sub_areas.end(); ++sa) {
412 case AIS8_001_22_SHAPE_CIRCLE: {
413 wxPoint target_point;
416 bbox.Expand(target_point);
417 if (sa->radius_m > 0.0) bbox.EnLarge(sa->radius_m * vp_scale);
420 case AIS8_001_22_SHAPE_RECT:
421 case AIS8_001_22_SHAPE_POLYGON:
422 case AIS8_001_22_SHAPE_POLYLINE: {
423 double lat = sa->latitude;
424 double lon = sa->longitude;
425 for (
int i = 0; i < 4; ++i) {
426 ll_gc_ll(lat, lon, sa->angles[i], sa->dists_m[i] / 1852.0,
428 wxPoint target_point;
430 bbox.Expand(target_point);
434 case AIS8_001_22_SHAPE_SECTOR: {
435 double lat1 = sa->latitude;
436 double lon1 = sa->longitude;
438 wxPoint target_point;
440 bbox.Expand(target_point);
441 for (
int i = 0; i < 18; ++i) {
445 i * (sa->right_bound_deg - sa->left_bound_deg) / 18,
446 sa->radius_m / 1852.0, &lat, &lon);
448 bbox.Expand(target_point);
450 ll_gc_ll(lat1, lon1, sa->right_bound_deg, sa->radius_m / 1852.0,
453 bbox.Expand(target_point);
459 if (bbox.GetValid() && bbox.PointInBox(x, y)) {
460 ais_areanotice =
true;
469 if (parent->GetpCurrentStack())
470 nChartStack = parent->GetpCurrentStack()->nEntry;
472 if (!parent->GetVP().b_quilt) {
473 if (nChartStack > 1) {
474 MenuAppend1(contextMenu, ID_DEF_MENU_MAX_DETAIL, _(
"Max Detail Here"));
475 MenuAppend1(contextMenu, ID_DEF_MENU_SCALE_IN,
476 _menuText(_(
"Scale In"), _T(
"Ctrl-Left")));
477 MenuAppend1(contextMenu, ID_DEF_MENU_SCALE_OUT,
478 _menuText(_(
"Scale Out"), _T(
"Ctrl-Right")));
481 if ((parent->m_singleChart &&
482 (parent->m_singleChart->GetChartFamily() == CHART_FAMILY_VECTOR)) ||
484 MenuAppend1(contextMenu, ID_DEF_MENU_QUERY,
485 _(
"Object Query") + _T(
"..." ));
490 parent->m_pQuilt->GetChartAtPix(parent->GetVP(), wxPoint(x, y));
491 if ((pChartTest && (pChartTest->GetChartFamily() == CHART_FAMILY_VECTOR)) ||
493 MenuAppend1(contextMenu, ID_DEF_MENU_QUERY,
494 _(
"Object Query") + _T(
"..." ));
497 if (!g_bBasicMenus && (nChartStack > 1)) {
498 MenuAppend1(contextMenu, ID_DEF_MENU_SCALE_IN,
499 _menuText(_(
"Scale In"), _T(
"Ctrl-Left")));
500 MenuAppend1(contextMenu, ID_DEF_MENU_SCALE_OUT,
501 _menuText(_(
"Scale Out"), _T(
"Ctrl-Right")));
507 if (!g_bBasicMenus || (seltype != SELTYPE_ROUTECREATE)) {
508 bool b_dm_add =
true;
509 if (g_btouch && parent->IsMeasureActive()) b_dm_add =
false;
512 MenuAppend1(contextMenu, ID_DEF_MENU_DROP_WP,
513 _menuText(_(
"Drop Mark"), _T(
"Ctrl-M")));
514 MenuAppend1(contextMenu, ID_DEF_MENU_NEW_RT,
515 _menuText(_(
"New Route..."), _T(
"Ctrl-R")));
519 MenuAppend1(contextMenu, ID_DEF_MENU_MOVE_BOAT_HERE, _(
"Move Boat Here"));
522 if (!g_bBasicMenus && !g_pRouteMan->GetpActiveRoute() &&
523 (!(seltype & SELTYPE_MARKPOINT) ||
524 (m_pFoundRoutePoint && m_pFoundRoutePoint->
m_bIsInLayer)))
525 MenuAppend1(contextMenu, ID_DEF_MENU_GOTO_HERE, _(
"Navigate To Here"));
528 MenuAppend1(contextMenu, ID_DEF_MENU_GOTOPOSITION,
529 _(
"Center view") + _T(
"..."));
531 if (!g_bBasicMenus) {
532 if (parent->GetVP().b_quilt) {
533 if (parent->GetUpMode() == NORTH_UP_MODE) {
534 MenuAppend1(contextMenu, ID_DEF_MENU_COGUP, _(
"Course Up Mode"));
535 if (!std::isnan(gHdt))
536 MenuAppend1(contextMenu, ID_DEF_MENU_HEADUP, _(
"Heading Up Mode"));
538 MenuAppend1(contextMenu, ID_DEF_MENU_NORTHUP, _(
"North Up Mode"));
541 if (parent->m_singleChart &&
542 (fabs(parent->m_singleChart->GetChartSkew()) > .01) && !g_bskew_comp)
543 MenuAppend1(contextMenu, ID_DEF_MENU_NORTHUP, _(
"Chart Up Mode"));
545 MenuAppend1(contextMenu, ID_DEF_MENU_NORTHUP, _(
"North Up Mode"));
549 if (!g_bBasicMenus) {
550 bool full_toggle_added =
false;
553 MenuAppend1(contextMenu, ID_DEF_MENU_TOGGLE_FULL,
554 _(
"Toggle Full Screen"));
555 full_toggle_added =
true;
558 if (!full_toggle_added) {
560 MenuAppend1(contextMenu, ID_DEF_MENU_TOGGLE_FULL,
561 _(
"Toggle Full Screen"));
565 if (g_pRouteMan->IsAnyRouteActive() &&
566 g_pRouteMan->GetCurrentXTEToActivePoint() > 0.)
567 MenuAppend1(contextMenu, ID_DEF_ZERO_XTE, _(
"Zero XTE"));
570 int pasteBuffer = kml->ParsePasteBuffer();
571 if (pasteBuffer != KML_PASTE_INVALID) {
572 switch (pasteBuffer) {
573 case KML_PASTE_WAYPOINT: {
574 MenuAppend1(contextMenu, ID_PASTE_WAYPOINT, _(
"Paste Waypoint"));
577 case KML_PASTE_ROUTE: {
578 MenuAppend1(contextMenu, ID_PASTE_ROUTE, _(
"Paste Route"));
581 case KML_PASTE_TRACK: {
582 MenuAppend1(contextMenu, ID_PASTE_TRACK, _(
"Paste Track"));
585 case KML_PASTE_ROUTE_TRACK: {
586 MenuAppend1(contextMenu, ID_PASTE_ROUTE, _(
"Paste Route"));
587 MenuAppend1(contextMenu, ID_PASTE_TRACK, _(
"Paste Track"));
594 if (!parent->GetVP().b_quilt && parent->m_singleChart &&
595 (parent->m_singleChart->GetChartType() == CHART_TYPE_CM93COMP)) {
596 MenuAppend1(contextMenu, ID_DEF_MENU_CM93OFFSET_DIALOG,
597 _(
"CM93 Offset Dialog..."));
621 wxMenuItem *subItemChart =
622 contextMenu->AppendSubMenu(subMenuChart, _(
"Chart Groups"));
623 if (g_btouch) contextMenu->AppendSeparator();
625 SetMenuItemFont1(subItemChart);
627 if (g_pGroupArray->GetCount()) {
629 MenuAppend1(subMenuChart, wxID_CANCEL, _(
"temporary"));
631 wxMenuItem *subItem0 = subMenuChart->AppendRadioItem(
632 ID_DEF_MENU_GROUPBASE, _(
"All Active Charts"));
634 SetMenuItemFont1(subItem0);
636 for (
unsigned int i = 0; i < g_pGroupArray->GetCount(); i++) {
637 subItem0 = subMenuChart->AppendRadioItem(
638 ID_DEF_MENU_GROUPBASE + i + 1, g_pGroupArray->Item(i)->m_group_name);
639 SetMenuItemFont1(subItem0);
643 subMenuChart->Remove(wxID_CANCEL);
645 subMenuChart->Check(ID_DEF_MENU_GROUPBASE + parent->m_groupIndex,
true);
649 menuFocus = contextMenu;
652 if (!g_bBasicMenus || (seltype != SELTYPE_ROUTECREATE)) {
654 if (parent->GetShowAIS() && (seltype & SELTYPE_AISTARGET)) {
655 auto myptarget = g_pAIS->Get_Target_Data_From_MMSI(m_FoundAIS_MMSI);
656 if (!g_bBasicMenus && myptarget) {
657 name = myptarget->GetFullName();
658 if (name.IsEmpty()) name.Printf(_T(
"%d"), m_FoundAIS_MMSI);
659 name.Prepend(_T(
" ( ")).Append(_T(
" )"));
661 name = wxEmptyString;
662 menuAIS =
new wxMenu(_(
"AIS") + name);
663 MenuAppend1(menuAIS, ID_DEF_MENU_AIS_QUERY, _(
"Target Query..."));
664 if (myptarget && myptarget->bCPA_Valid &&
665 (myptarget->n_alert_state != AIS_ALERT_SET)) {
666 if (myptarget->b_show_AIS_CPA)
667 MenuAppend1(menuAIS, ID_DEF_MENU_AIS_CPA, _(
"Hide Target CPA"));
669 MenuAppend1(menuAIS, ID_DEF_MENU_AIS_CPA, _(
"Show Target CPA"));
671 MenuAppend1(menuAIS, ID_DEF_MENU_AISTARGETLIST, _(
"Target List..."));
672 if (myptarget->Class != AIS_METEO ) {
673 if (myptarget && !myptarget->b_PersistTrack) {
674 if (myptarget->b_show_track)
675 MenuAppend1(menuAIS, ID_DEF_MENU_AISSHOWTRACK,
676 _(
"Hide Target Track"));
678 MenuAppend1(menuAIS, ID_DEF_MENU_AISSHOWTRACK,
679 _(
"Show Target Track"));
683 MenuAppend1(menuAIS, ID_DEF_MENU_COPY_MMSI, _(
"Copy Target MMSI"));
684 menuAIS->AppendSeparator();
686 if (!parent->GetVP().b_quilt) {
687 if ((parent->m_singleChart &&
688 (parent->m_singleChart->GetChartFamily() ==
689 CHART_FAMILY_VECTOR))) {
690 MenuAppend1(menuAIS, ID_DEF_MENU_QUERY, _(
"Object Query..."));
695 parent->m_pQuilt->GetChartAtPix(parent->GetVP(), wxPoint(x, y));
697 (pChartTest->GetChartFamily() == CHART_FAMILY_VECTOR))) {
698 MenuAppend1(menuAIS, ID_DEF_MENU_QUERY, _(
"Object Query..."));
704 MenuAppend1(contextMenu, ID_DEF_MENU_AISTARGETLIST,
705 _(
"AIS target list") + _T(
"..."));
707 wxString nextCPAstatus = g_bCPAWarn ? _(
"Hide") : _(
"Show");
708 MenuAppend1(contextMenu, ID_DEF_MENU_AIS_CPAWARNING,
709 _menuText(nextCPAstatus +
" " + _(
"CPA alarm "),
"W"));
713 if (g_enable_root_menu_debug) {
714 wxMenuItem *subItemDebug =
715 contextMenu->AppendSubMenu(subMenuDebug, _(
"Debug"));
716 if (g_btouch) contextMenu->AppendSeparator();
717 SetMenuItemFont1(subItemDebug);
720 if (seltype & SELTYPE_ROUTESEGMENT) {
721 if (!g_bBasicMenus && m_pSelectedRoute) {
723 if (name.IsEmpty()) name = _(
"Unnamed Route");
724 name.Prepend(_T(
" ( ")).Append(_T(
" )"));
726 name = wxEmptyString;
728 if (m_pSelectedRoute && m_pSelectedRoute->
m_bIsInLayer) blay =
true;
731 menuRoute =
new wxMenu(_(
"Layer Route") + name);
732 MenuAppend1(menuRoute, ID_RT_MENU_PROPERTIES,
733 _(
"Properties") + _T(
"..." ));
734 if (m_pSelectedRoute) {
735 if (m_pSelectedRoute->IsActive()) {
736 int indexActive = m_pSelectedRoute->GetIndexOf(
738 if ((indexActive + 1) <= m_pSelectedRoute->GetnPoints()) {
739 MenuAppend1(menuRoute, ID_RT_MENU_ACTNXTPOINT,
740 _(
"Activate Next Waypoint"));
742 MenuAppend1(menuRoute, ID_RT_MENU_DEACTIVATE, _(
"Deactivate"));
743 MenuAppend1(menuRoute, ID_DEF_ZERO_XTE, _(
"Zero XTE"));
745 MenuAppend1(menuRoute, ID_RT_MENU_ACTIVATE, _(
"Activate"));
749 menuRoute =
new wxMenu(_(
"Route") + name);
750 MenuAppend1(menuRoute, ID_RT_MENU_PROPERTIES,
751 _(
"Properties") + _T(
"..." ));
752 if (m_pSelectedRoute) {
753 if (m_pSelectedRoute->IsActive()) {
754 int indexActive = m_pSelectedRoute->GetIndexOf(
756 if ((indexActive + 1) <= m_pSelectedRoute->GetnPoints()) {
757 MenuAppend1(menuRoute, ID_RT_MENU_ACTNXTPOINT,
758 _(
"Activate Next Waypoint"));
760 MenuAppend1(menuRoute, ID_RT_MENU_DEACTIVATE, _(
"Deactivate"));
761 MenuAppend1(menuRoute, ID_DEF_ZERO_XTE, _(
"Zero XTE"));
763 MenuAppend1(menuRoute, ID_RT_MENU_ACTIVATE, _(
"Activate"));
766 MenuAppend1(menuRoute, ID_RT_MENU_INSERT, _(
"Insert Waypoint"));
767 MenuAppend1(menuRoute, ID_RT_MENU_APPEND, _(
"Append Waypoint"));
768 if (!(seltype & SELTYPE_ROUTEPOINT) && m_pSelectedRoute) {
769 m_SelectedIdx = m_pSelectedRoute->GetIndexOf(m_pFoundRoutePoint);
770 if (m_SelectedIdx > 1 &&
771 m_SelectedIdx < m_pSelectedRoute->GetnPoints() - 1)
772 MenuAppend1(menuRoute, ID_RT_MENU_SPLIT_LEG, _(
"Split around Leg"));
774 MenuAppend1(menuRoute, ID_RT_MENU_COPY, _(
"Copy as KML") + _T(
"..." ));
775 MenuAppend1(menuRoute, ID_RT_MENU_DELETE, _(
"Delete") + _T(
"..." ));
776 MenuAppend1(menuRoute, ID_RT_MENU_REVERSE, _(
"Reverse..."));
777 if (m_pSelectedRoute) {
778 if (m_pSelectedRoute->AreWaypointNamesVisible())
779 MenuAppend1(menuRoute, ID_RT_MENU_SHOWNAMES,
780 _(
"Hide Waypoint Names"));
782 MenuAppend1(menuRoute, ID_RT_MENU_SHOWNAMES,
783 _(
"Show Waypoint Names"));
785 MenuAppend1(menuRoute, ID_RT_MENU_RESEQUENCE,
786 _(
"Resequence Waypoints..."));
789 wxString port = parent->FindValidUploadPort();
790 parent->m_active_upload_port = port;
791 wxString item = _(
"Send to GPS");
792 if (!port.IsEmpty()) {
793 item.Append(_T(
" ( "));
795 item.Append(_T(
" )"));
797 MenuAppend1(menuRoute, ID_RT_MENU_SENDTOGPS, item);
799 if (!port.IsEmpty()) {
800 wxString item = _(
"Send to new GPS");
801 MenuAppend1(menuRoute, ID_RT_MENU_SENDTONEWGPS, item);
804 wxString itemstp = SYMBOL_STP_TITLE;
805 MenuAppend1(menuRoute, ID_RT_MENU_SENDTOPEER, itemstp);
808 if (menuFocus != menuAIS) menuFocus = menuRoute;
811 if (seltype & SELTYPE_TRACKSEGMENT) {
812 name = wxEmptyString;
813 if (!g_bBasicMenus && m_pSelectedTrack)
814 name = _T(
" ( ") + m_pSelectedTrack->GetName(
true) + _T(
" )");
816 name = wxEmptyString;
818 if (m_pSelectedTrack && m_pSelectedTrack->m_bIsInLayer) blay =
true;
821 menuTrack =
new wxMenu(_(
"Layer Track") + name);
822 MenuAppend1(menuTrack, ID_TK_MENU_PROPERTIES,
823 _(
"Properties") + _T(
"..." ));
825 menuTrack =
new wxMenu(_(
"Track") + name);
826 MenuAppend1(menuTrack, ID_TK_MENU_PROPERTIES,
827 _(
"Properties") + _T(
"..." ));
828 MenuAppend1(menuTrack, ID_TK_MENU_COPY, _(
"Copy as KML"));
829 MenuAppend1(menuTrack, ID_TK_MENU_DELETE, _(
"Delete") + _T(
"..." ));
832 wxString itemstp = SYMBOL_STP_TITLE;
833 MenuAppend1(menuTrack, ID_TK_MENU_SENDTOPEER, itemstp);
836 if (menuFocus != menuAIS) menuFocus = menuTrack;
839 if (seltype & SELTYPE_ROUTEPOINT) {
840 if (!g_bBasicMenus && m_pFoundRoutePoint) {
841 name = m_pFoundRoutePoint->GetName();
842 if (name.IsEmpty()) name = _(
"Unnamed Waypoint");
843 name.Prepend(_T(
" ( ")).Append(_T(
" )"));
845 name = wxEmptyString;
847 if (m_pFoundRoutePoint && m_pFoundRoutePoint->
m_bIsInLayer) blay =
true;
850 menuWaypoint =
new wxMenu(_(
"Layer Waypoint") + name);
851 MenuAppend1(menuWaypoint, ID_WP_MENU_PROPERTIES,
852 _(
"Properties") + _T(
"..." ));
854 if (m_pSelectedRoute && m_pSelectedRoute->IsActive())
855 MenuAppend1(menuWaypoint, ID_RT_MENU_ACTPOINT, _(
"Activate"));
857 menuWaypoint =
new wxMenu(_(
"Waypoint") + name);
858 MenuAppend1(menuWaypoint, ID_WP_MENU_PROPERTIES,
859 _(
"Properties") + _T(
"..." ));
860 if (m_pSelectedRoute && m_pSelectedRoute->IsActive()) {
862 MenuAppend1(menuWaypoint, ID_RT_MENU_ACTPOINT, _(
"Activate"));
865 if (m_pSelectedRoute && m_pSelectedRoute->IsActive()) {
867 int indexActive = m_pSelectedRoute->GetIndexOf(
869 if ((indexActive + 1) <= m_pSelectedRoute->GetnPoints())
870 MenuAppend1(menuWaypoint, ID_RT_MENU_ACTNXTPOINT,
871 _(
"Activate Next Waypoint"));
874 if (m_pSelectedRoute && m_pSelectedRoute->GetnPoints() > 2) {
875 MenuAppend1(menuWaypoint, ID_RT_MENU_REMPOINT, _(
"Remove from Route"));
877 m_SelectedIdx = m_pSelectedRoute->GetIndexOf(m_pFoundRoutePoint);
878 if (m_SelectedIdx > 1 && m_SelectedIdx < m_pSelectedRoute->GetnPoints())
879 MenuAppend1(menuWaypoint, ID_RT_MENU_SPLIT_WPT,
880 _(
"Split Route at Waypoint"));
883 MenuAppend1(menuWaypoint, ID_WPT_MENU_COPY, _(
"Copy as KML"));
885 if (m_pFoundRoutePoint && m_pFoundRoutePoint->GetIconName() != _T(
"mob"))
886 MenuAppend1(menuWaypoint, ID_RT_MENU_DELPOINT, _(
"Delete"));
889 wxString port = parent->FindValidUploadPort();
890 parent->m_active_upload_port = port;
891 wxString item = _(
"Send to GPS");
892 if (!port.IsEmpty()) {
893 item.Append(_T(
" ( "));
895 item.Append(_T(
" )"));
897 MenuAppend1(menuWaypoint, ID_WPT_MENU_SENDTOGPS, item);
899 if (!port.IsEmpty()) {
900 wxString item = _(
"Send to new GPS");
901 MenuAppend1(menuWaypoint, ID_WPT_MENU_SENDTONEWGPS, item);
904 MenuAppend1(menuWaypoint, ID_WPT_MENU_SENDTOPEER,
909 if (menuFocus != menuAIS) menuFocus = menuWaypoint;
912 if (seltype & SELTYPE_MARKPOINT) {
913 if (!g_bBasicMenus && m_pFoundRoutePoint) {
914 name = m_pFoundRoutePoint->GetName();
915 if (name.IsEmpty()) name = _(
"Unnamed Mark");
916 name.Prepend(_T(
" ( ")).Append(_T(
" )"));
918 name = wxEmptyString;
920 if (m_pFoundRoutePoint && m_pFoundRoutePoint->
m_bIsInLayer) blay =
true;
923 menuWaypoint =
new wxMenu(_(
"Layer Waypoint") + name);
924 MenuAppend1(menuWaypoint, ID_WP_MENU_PROPERTIES,
925 _(
"Properties") + _T(
"..." ));
927 menuWaypoint =
new wxMenu(_(
"Mark") + name);
928 MenuAppend1(menuWaypoint, ID_WP_MENU_PROPERTIES,
929 _(
"Properties") + _T(
"..." ));
931 if (!g_pRouteMan->GetpActiveRoute())
932 MenuAppend1(menuWaypoint, ID_WP_MENU_GOTO, _(
"Navigate To This"));
934 MenuAppend1(menuWaypoint, ID_WPT_MENU_COPY, _(
"Copy as KML"));
936 if (m_pFoundRoutePoint && m_pFoundRoutePoint->GetIconName() != _T(
"mob"))
937 MenuAppend1(menuWaypoint, ID_WP_MENU_DELPOINT, _(
"Delete"));
940 wxString port = parent->FindValidUploadPort();
941 parent->m_active_upload_port = port;
942 wxString item = _(
"Send to GPS");
943 if (!port.IsEmpty()) {
944 item.Append(_T(
" ( "));
946 item.Append(_T(
" )"));
948 MenuAppend1(menuWaypoint, ID_WPT_MENU_SENDTOGPS, item);
950 MenuAppend1(menuWaypoint, ID_WPT_MENU_SENDTOPEER,
954 if ((m_pFoundRoutePoint == pAnchorWatchPoint1) ||
955 (m_pFoundRoutePoint == pAnchorWatchPoint2))
956 MenuAppend1(menuWaypoint, ID_WP_MENU_CLEAR_ANCHORWATCH,
957 _(
"Clear Anchor Watch"));
959 if (m_pFoundRoutePoint && !(m_pFoundRoutePoint->
m_bIsInLayer) &&
960 ((NULL == pAnchorWatchPoint1) || (NULL == pAnchorWatchPoint2))) {
963 DistanceBearingMercator(m_pFoundRoutePoint->m_lat,
964 m_pFoundRoutePoint->m_lon, gLat, gLon, &brg,
966 if (dist * 1852. <= g_nAWMax)
967 MenuAppend1(menuWaypoint, ID_WP_MENU_SET_ANCHORWATCH,
968 _(
"Set Anchor Watch"));
973 if (menuFocus != menuAIS) menuFocus = menuWaypoint;
977 AddPluginContextMenuItems(contextMenu, menuRoute, menuTrack, menuWaypoint,
981 enum { WPMENU = 1, TKMENU = 2, RTMENU = 4, MMMENU = 8 };
983 if (!g_bBasicMenus && menuFocus != contextMenu) {
984 if (global_color_scheme != GLOBAL_COLOR_SCHEME_DUSK &&
985 global_color_scheme != GLOBAL_COLOR_SCHEME_NIGHT) {
986 menuFocus->AppendSeparator();
989 wxMenuItem *subMenu1;
990 if (menuWaypoint && menuFocus != menuWaypoint) {
992 menuFocus->AppendSubMenu(menuWaypoint, menuWaypoint->GetTitle());
993 SetMenuItemFont1(subMenu1);
996 menuWaypoint->SetTitle(wxEmptyString);
999 if (menuTrack && menuFocus != menuTrack) {
1000 subMenu1 = menuFocus->AppendSubMenu(menuTrack, menuTrack->GetTitle());
1001 SetMenuItemFont1(subMenu1);
1004 menuTrack->SetTitle(wxEmptyString);
1007 if (menuRoute && menuFocus != menuRoute) {
1008 subMenu1 = menuFocus->AppendSubMenu(menuRoute, menuRoute->GetTitle());
1009 SetMenuItemFont1(subMenu1);
1012 menuRoute->SetTitle(wxEmptyString);
1015 subMenu1 = menuFocus->AppendSubMenu(contextMenu, _(
"Main Menu"));
1016 SetMenuItemFont1(subMenu1);
1020 if (!subMenuChart->GetMenuItemCount()) contextMenu->Destroy(subItemChart);
1025 if (seltype & SELTYPE_TIDEPOINT) {
1026 menuFocus->AppendSeparator();
1028 MenuAppend1(menuFocus, ID_DEF_MENU_TIDEINFO, _(
"Show Tide Information"));
1031 if (seltype & SELTYPE_CURRENTPOINT) {
1032 if (!bsep) menuFocus->AppendSeparator();
1033 MenuAppend1(menuFocus, ID_DEF_MENU_CURRENTINFO,
1034 _(
"Show Current Information"));
1040 androidEnableBackButton(
false);
1041 androidEnableOptionsMenu(
false);
1049 parent->PopupMenu(menuFocus, x, y);
1052 androidEnableBackButton(
true);
1053 androidEnableOptionsMenu(
true);
1060 if (!(sub_menu & MMMENU))
delete contextMenu;
1061 if (!(sub_menu & RTMENU))
delete menuRoute;
1062 if (!(sub_menu & TKMENU))
delete menuTrack;
1063 if (!(sub_menu & WPMENU))
delete menuWaypoint;
1066void CanvasMenuHandler::AddPluginContextMenuItems(wxMenu *contextMenu,
1069 wxMenu *menuWaypoint,
1072 g_pi_manager->PrepareAllPluginContextMenus();
1075 ArrayOfPlugInMenuItems item_array =
1076 g_pi_manager->GetPluginContextMenuItemArray();
1078 for (
unsigned int i = 0; i < item_array.GetCount(); i++) {
1080 if (!pimis->b_viz)
continue;
1082 wxMenu *submenu = NULL;
1083 if (pimis->pmenu_item->GetSubMenu()) {
1085 auto submenu_proto = pimis->pmenu_item->GetSubMenu();
1086 submenu =
new wxMenu();
1087 const wxMenuItemList &items =
1088 pimis->pmenu_item->GetSubMenu()->GetMenuItems();
1089 for (wxMenuItemList::const_iterator it = items.begin(); it != items.end();
1091 int id = (*it)->GetId();
1093 new wxMenuItem(submenu,
id, (*it)->GetItemLabelText(),
1094 (*it)->GetHelp(), (*it)->GetKind());
1097 psmi->SetFont(m_scaledFont);
1102 psmi->SetFont(sFont);
1105 PrepareMenuItem(psmi);
1106 submenu->Append(psmi);
1107 psmi->Check((*it)->IsChecked());
1111 wxMenuItem *pmi =
new wxMenuItem(
1112 contextMenu, pimis->id, pimis->pmenu_item->GetItemLabelText(),
1113 pimis->pmenu_item->GetHelp(), pimis->pmenu_item->GetKind(), submenu);
1115 pmi->SetFont(m_scaledFont);
1120 pmi->SetFont(sFont);
1123 PrepareMenuItem(pmi);
1125 wxMenu *dst = contextMenu;
1126 if (pimis->m_in_menu ==
"Waypoint")
1128 else if (pimis->m_in_menu ==
"Route")
1130 else if (pimis->m_in_menu ==
"Track")
1132 else if (pimis->m_in_menu ==
"AIS")
1137 dst->Enable(pimis->id, !pimis->b_grey);
1142void CanvasMenuHandler::PopupMenuHandler(wxCommandEvent &event) {
1149 bool dupFirstWpt =
true, showRPD;
1154 switch (event.GetId()) {
1155 case ID_DEF_MENU_MAX_DETAIL:
1158 parent->ClearbFollow();
1160 parent->parent_frame->DoChartUpdate();
1162 parent->SelectChartFromStack(0,
false, CHART_TYPE_DONTCARE,
1163 CHART_FAMILY_RASTER);
1166 case ID_DEF_MENU_SCALE_IN:
1167 parent->DoCanvasStackDelta(-1);
1170 case ID_DEF_MENU_SCALE_OUT:
1171 parent->DoCanvasStackDelta(1);
1175 parent->undo->UndoLastAction();
1176 parent->InvalidateGL();
1177 parent->Refresh(
false);
1181 parent->undo->RedoNextAction();
1182 parent->InvalidateGL();
1183 parent->Refresh(
false);
1186 case ID_DEF_MENU_MOVE_BOAT_HERE:
1189 gFrame->UpdateStatusBar();
1192 case ID_DEF_MENU_GOTO_HERE: {
1194 wxEmptyString, wxEmptyString);
1195 pSelect->AddSelectableRoutePoint(zlat, zlon, pWP_dest);
1198 wxEmptyString, wxEmptyString);
1199 pSelect->AddSelectableRoutePoint(gLat, gLon, pWP_src);
1202 pRouteList->Append(temp_route);
1204 temp_route->AddPoint(pWP_src);
1205 temp_route->AddPoint(pWP_dest);
1207 pSelect->AddSelectableRouteSegment(gLat, gLon, zlat, zlon, pWP_src,
1208 pWP_dest, temp_route);
1217 if (g_pRouteMan->GetpActiveRoute()) g_pRouteMan->DeactivateRoute();
1224 case ID_DEF_MENU_DROP_WP: {
1226 wxEmptyString, wxEmptyString);
1228 pSelect->AddSelectableRoutePoint(zlat, zlon, pWP);
1229 NavObj_dB::GetInstance().InsertRoutePoint(pWP);
1234 if (RouteManagerDialog::getInstanceFlag()) {
1235 if (pRouteManagerDialog && pRouteManagerDialog->IsShown()) {
1236 pRouteManagerDialog->UpdateWptListCtrl();
1240 parent->undo->BeforeUndoableAction(Undo_CreateWaypoint, pWP,
1241 Undo_HasParent, NULL);
1242 parent->undo->AfterUndoableAction(NULL);
1243 gFrame->RefreshAllCanvas(
false);
1244 gFrame->InvalidateAllGL();
1245 g_FlushNavobjChanges =
true;
1249 case ID_DEF_MENU_NEW_RT: {
1250 parent->StartRoute();
1254 case ID_DEF_MENU_AISTARGETLIST:
1255 parent->ShowAISTargetList();
1258 case ID_DEF_MENU_AIS_CPAWARNING:
1259 parent->ToggleCPAWarn();
1262 case ID_WP_MENU_GOTO: {
1264 wxEmptyString, wxEmptyString);
1265 pSelect->AddSelectableRoutePoint(gLat, gLon, pWP_src);
1268 pRouteList->Append(temp_route);
1270 temp_route->AddPoint(pWP_src);
1271 temp_route->AddPoint(m_pFoundRoutePoint);
1272 m_pFoundRoutePoint->SetShared(
true);
1274 pSelect->AddSelectableRouteSegment(gLat, gLon, m_pFoundRoutePoint->m_lat,
1275 m_pFoundRoutePoint->m_lon, pWP_src,
1276 m_pFoundRoutePoint, temp_route);
1278 wxString name = m_pFoundRoutePoint->GetName();
1279 if (name.IsEmpty()) name = _(
"(Unnamed Waypoint)");
1280 wxString rteName = _(
"Go to ");
1281 rteName.Append(name);
1288 if (g_pRouteMan->GetpActiveRoute()) g_pRouteMan->DeactivateRoute();
1295 case ID_DEF_MENU_COGUP:
1296 parent->SetUpMode(COURSE_UP_MODE);
1299 case ID_DEF_MENU_HEADUP:
1300 parent->SetUpMode(HEAD_UP_MODE);
1303 case ID_DEF_MENU_NORTHUP:
1304 parent->SetUpMode(NORTH_UP_MODE);
1307 case ID_DEF_MENU_TOGGLE_FULL:
1308 gFrame->ToggleFullScreen();
1311 case ID_DEF_MENU_GOTOPOSITION:
1312 if (NULL == pGoToPositionDialog)
1315 pGoToPositionDialog->SetCanvas(parent);
1316 pGoToPositionDialog->CheckPasteBufferForPosition();
1317 pGoToPositionDialog->Show();
1320 case ID_WP_MENU_DELPOINT: {
1321 if (m_pFoundRoutePoint == pAnchorWatchPoint1) {
1322 pAnchorWatchPoint1 = NULL;
1324 }
else if (m_pFoundRoutePoint == pAnchorWatchPoint2) {
1325 pAnchorWatchPoint2 = NULL;
1329 if (m_pFoundRoutePoint && !(m_pFoundRoutePoint->
m_bIsInLayer) &&
1330 (m_pFoundRoutePoint->GetIconName() != _T(
"mob"))) {
1334 wxArrayPtrVoid *proute_array =
1337 pWayPointMan->DestroyWaypoint(m_pFoundRoutePoint);
1338 delete proute_array;
1340 parent->undo->BeforeUndoableAction(
1341 Undo_DeleteWaypoint, m_pFoundRoutePoint, Undo_IsOrphanded,
1343 NavObj_dB::GetInstance().DeleteRoutePoint(m_pFoundRoutePoint);
1344 pSelect->DeleteSelectablePoint(m_pFoundRoutePoint,
1345 SELTYPE_ROUTEPOINT);
1346 if (NULL != pWayPointMan)
1348 parent->undo->AfterUndoableAction(NULL);
1351 if (g_pMarkInfoDialog) {
1352 g_pMarkInfoDialog->ClearData();
1355 if (RouteManagerDialog::getInstanceFlag()) {
1356 if (pRouteManagerDialog) {
1357 if (pRouteManagerDialog->IsShown())
1358 pRouteManagerDialog->UpdateWptListCtrl();
1362 gFrame->RefreshAllCanvas(
false);
1363 gFrame->InvalidateAllGL();
1367 case ID_WP_MENU_PROPERTIES:
1368 parent->ShowMarkPropertiesDialog(m_pFoundRoutePoint);
1371 case ID_WP_MENU_CLEAR_ANCHORWATCH: {
1372 wxString guid = wxEmptyString;
1373 if (pAnchorWatchPoint1 == m_pFoundRoutePoint) {
1374 pAnchorWatchPoint1 = NULL;
1377 }
else if (pAnchorWatchPoint2 == m_pFoundRoutePoint) {
1378 pAnchorWatchPoint2 = NULL;
1382 if (!guid.IsEmpty()) {
1384 v[_T(
"GUID")] = guid;
1385 wxString msg_id(_T(
"OCPN_ANCHOR_WATCH_CLEARED"));
1386 SendJSONMessageToAllPlugins(msg_id, v);
1391 case ID_WP_MENU_SET_ANCHORWATCH: {
1392 wxString guid = wxEmptyString;
1393 if (pAnchorWatchPoint1 == NULL) {
1394 pAnchorWatchPoint1 = m_pFoundRoutePoint;
1395 g_AW1GUID = pAnchorWatchPoint1->
m_GUID;
1398 nn = m_pFoundRoutePoint->GetName();
1400 nn.Printf(_T(
"%d m"), g_nAWDefault);
1401 m_pFoundRoutePoint->SetName(nn);
1403 }
else if (pAnchorWatchPoint2 == NULL) {
1404 pAnchorWatchPoint2 = m_pFoundRoutePoint;
1405 g_AW2GUID = pAnchorWatchPoint2->
m_GUID;
1408 nn = m_pFoundRoutePoint->GetName();
1410 nn.Printf(_T(
"%d m"), g_nAWDefault);
1411 m_pFoundRoutePoint->SetName(nn);
1414 if (!guid.IsEmpty()) {
1416 v[_T(
"GUID")] = guid;
1417 wxString msg_id(_T(
"OCPN_ANCHOR_WATCH_SET"));
1418 SendJSONMessageToAllPlugins(msg_id, v);
1423 case ID_DEF_MENU_ACTIVATE_MEASURE:
1424 parent->StartMeasureRoute();
1427 case ID_DEF_MENU_DEACTIVATE_MEASURE:
1428 parent->CancelMeasureRoute();
1430 parent->InvalidateGL();
1431 parent->Refresh(
false);
1434 case ID_DEF_MENU_CM93OFFSET_DIALOG: {
1435 if (NULL == g_pCM93OffsetDialog) {
1440 if (!parent->GetVP().b_quilt && parent->m_singleChart &&
1441 (parent->m_singleChart->GetChartType() == CHART_TYPE_CM93COMP)) {
1445 if (g_pCM93OffsetDialog) {
1446 g_pCM93OffsetDialog->SetCM93Chart(pch);
1447 g_pCM93OffsetDialog->Show();
1448 g_pCM93OffsetDialog->UpdateMCOVRList(parent->GetVP());
1453 case ID_DEF_MENU_QUERY: {
1454 parent->ShowObjectQueryWindow(popx, popy, zlat, zlon);
1457 case ID_DEF_MENU_AIS_QUERY: {
1458 ShowAISTargetQueryDialog(parent, m_FoundAIS_MMSI);
1462 case ID_DEF_MENU_AIS_CPA: {
1463 auto myptarget = g_pAIS->Get_Target_Data_From_MMSI(m_FoundAIS_MMSI);
1464 if (myptarget) myptarget->Toggle_AIS_CPA();
1468 case ID_DEF_MENU_AISSHOWTRACK: {
1469 auto myptarget = g_pAIS->Get_Target_Data_From_MMSI(m_FoundAIS_MMSI);
1470 if (myptarget) myptarget->ToggleShowTrack();
1474 case ID_DEF_MENU_COPY_MMSI: {
1476 if (wxTheClipboard->Open()) {
1477 wxTheClipboard->SetData(
new wxTextDataObject(
1478 wxString::Format(wxT(
"%09d"), m_FoundAIS_MMSI)));
1479 wxTheClipboard->Close();
1484 case ID_DEF_MENU_QUILTREMOVE: {
1485 if (parent->GetVP().b_quilt) {
1486 int dbIndex = parent->m_pQuilt->GetChartdbIndexAtPix(
1487 parent->GetVP(), wxPoint(popx, popy));
1488 parent->RemoveChartFromQuilt(dbIndex);
1496 case ID_DEF_MENU_CURRENTINFO: {
1497 parent->DrawTCWindow(popx, popy, (
void *)m_pIDXCandidate);
1498 parent->Refresh(
false);
1503 case ID_DEF_MENU_TIDEINFO: {
1504 parent->DrawTCWindow(popx, popy, (
void *)m_pIDXCandidate);
1505 parent->Refresh(
false);
1510 case ID_DGB_MENU_NMEA_WINDOW:
1512 m_nmea_log->Raise();
1515 case ID_RT_MENU_REVERSE: {
1519 OCPNMessageBox(parent, g_pRouteMan->GetRouteReverseMessage(),
1520 _(
"Rename Waypoints?"), wxYES_NO | wxCANCEL);
1522 if (ask_return != wxID_CANCEL) {
1523 pSelect->DeleteAllSelectableRouteSegments(m_pSelectedRoute);
1524 m_pSelectedRoute->Reverse(ask_return == wxID_YES);
1525 pSelect->AddAllSelectableRouteSegments(m_pSelectedRoute);
1527 NavObj_dB::GetInstance().UpdateRoute(m_pSelectedRoute);
1529 if (pRoutePropDialog && (pRoutePropDialog->IsShown())) {
1530 pRoutePropDialog->SetRouteAndUpdate(m_pSelectedRoute);
1533 gFrame->InvalidateAllGL();
1534 gFrame->RefreshAllCanvas();
1539 case ID_RT_MENU_SHOWNAMES: {
1540 if (m_pSelectedRoute) {
1541 m_pSelectedRoute->ShowWaypointNames(
1542 !m_pSelectedRoute->AreWaypointNamesVisible());
1548 case ID_RT_MENU_RESEQUENCE: {
1549 if (m_pSelectedRoute) {
1553 OCPNMessageBox(parent, g_pRouteMan->GetRouteResequenceMessage(),
1554 _(
"Rename Waypoints?"), wxYES_NO | wxCANCEL);
1556 if (ask_return != wxID_CANCEL) {
1557 m_pSelectedRoute->RenameRoutePoints();
1560 gFrame->InvalidateAllGL();
1561 gFrame->RefreshAllCanvas();
1567 case ID_RT_MENU_DELETE: {
1568 bool confirmed = RouteGui::OnDelete(parent);
1571 if (g_pRouteMan->GetpActiveRoute() == m_pSelectedRoute)
1572 g_pRouteMan->DeactivateRoute();
1576 NavObj_dB::GetInstance().DeleteRoute(m_pSelectedRoute);
1577 if (!g_pRouteMan->
DeleteRoute(m_pSelectedRoute))
break;
1579 if (RouteManagerDialog::getInstanceFlag()) {
1580 if (pRouteManagerDialog && pRouteManagerDialog->IsShown())
1581 pRouteManagerDialog->UpdateRouteListCtrl();
1584 if (g_pMarkInfoDialog && g_pMarkInfoDialog->IsShown()) {
1585 g_pMarkInfoDialog->ValidateMark();
1586 g_pMarkInfoDialog->UpdateProperties();
1589 parent->undo->InvalidateUndo();
1591 gFrame->InvalidateAllGL();
1592 gFrame->RefreshAllCanvas();
1597 case ID_RT_MENU_ACTIVATE: {
1598 if (g_pRouteMan->GetpActiveRoute()) g_pRouteMan->DeactivateRoute();
1604 if (m_pSelectedRoute) {
1607 best_point = g_pRouteMan->FindBestActivatePoint(
1608 m_pSelectedRoute, gLat, gLon, gCog, gSog);
1610 best_point = m_pSelectedRoute->GetPoint(2);
1619 case ID_RT_MENU_DEACTIVATE:
1620 g_pRouteMan->DeactivateRoute();
1625 case ID_RT_MENU_INSERT: {
1627 bool rename =
false;
1628 m_pSelectedRoute->InsertPointAfter(m_pFoundRoutePoint, zlat, zlon,
1631 pSelect->DeleteAllSelectableRoutePoints(m_pSelectedRoute);
1632 pSelect->DeleteAllSelectableRouteSegments(m_pSelectedRoute);
1634 pSelect->AddAllSelectableRouteSegments(m_pSelectedRoute);
1635 pSelect->AddAllSelectableRoutePoints(m_pSelectedRoute);
1648 NavObj_dB::GetInstance().UpdateRoute(m_pSelectedRoute);
1650 if (pRoutePropDialog && (pRoutePropDialog->IsShown())) {
1651 pRoutePropDialog->SetRouteAndUpdate(m_pSelectedRoute,
true);
1657 case ID_RT_MENU_APPEND:
1661 parent->m_pMouseRoute = m_pSelectedRoute;
1662 parent->m_routeState = m_pSelectedRoute->GetnPoints() + 1;
1664 m_pSelectedRoute->GetnPoints();
1665 parent->m_pMouseRoute->SetHiLite(50);
1667 pLast = m_pSelectedRoute->GetLastPoint();
1669 parent->m_prev_rlat = pLast->m_lat;
1670 parent->m_prev_rlon = pLast->m_lon;
1671 parent->m_prev_pMousePoint = pLast;
1673 parent->m_bAppendingRoute =
true;
1675 parent->SetCursor(*parent->pCursorPencil);
1677 androidSetRouteAnnunciator(
true);
1680 parent->HideGlobalToolbar();
1684 case ID_RT_MENU_SPLIT_LEG:
1686 dupFirstWpt =
false;
1687 case ID_RT_MENU_SPLIT_WPT:
1689 showRPD = (pRoutePropDialog && pRoutePropDialog->IsShown());
1691 if (g_pRouteMan->GetpActiveRoute() == m_pSelectedRoute)
1692 g_pRouteMan->DeactivateRoute();
1694 m_pHead =
new Route();
1695 m_pTail =
new Route();
1696 m_pHead->CloneRoute(m_pSelectedRoute, 1, m_SelectedIdx, _(
"_A"));
1697 m_pTail->CloneRoute(m_pSelectedRoute, m_SelectedIdx + splitMode,
1698 m_pSelectedRoute->GetnPoints(), _(
"_B"), dupFirstWpt);
1699 pRouteList->Append(m_pHead);
1700 NavObj_dB::GetInstance().InsertRoute(m_pHead);
1702 pRouteList->Append(m_pTail);
1703 NavObj_dB::GetInstance().InsertRoute(m_pTail);
1705 NavObj_dB::GetInstance().DeleteRoute(m_pSelectedRoute);
1707 pSelect->DeleteAllSelectableRoutePoints(m_pSelectedRoute);
1708 pSelect->DeleteAllSelectableRouteSegments(m_pSelectedRoute);
1710 pSelect->AddAllSelectableRouteSegments(m_pTail);
1711 pSelect->AddAllSelectableRoutePoints(m_pTail);
1712 pSelect->AddAllSelectableRouteSegments(m_pHead);
1713 pSelect->AddAllSelectableRoutePoints(m_pHead);
1716 pRoutePropDialog->SetRouteAndUpdate(m_pHead);
1717 pRoutePropDialog->Show();
1719 if (RouteManagerDialog::getInstanceFlag() && pRouteManagerDialog &&
1720 (pRouteManagerDialog->IsShown()))
1721 pRouteManagerDialog->UpdateRouteListCtrl();
1724 case ID_RT_MENU_COPY:
1725 if (m_pSelectedRoute) Kml::CopyRouteToClipboard(m_pSelectedRoute);
1728 case ID_TK_MENU_COPY:
1729 if (m_pSelectedTrack) Kml::CopyTrackToClipboard(m_pSelectedTrack);
1732 case ID_WPT_MENU_COPY:
1733 if (m_pFoundRoutePoint) Kml::CopyWaypointToClipboard(m_pFoundRoutePoint);
1736 case ID_WPT_MENU_SENDTOGPS:
1737 if (m_pFoundRoutePoint) {
1738 if (parent->m_active_upload_port.Length())
1740 .SendToGPS(parent->m_active_upload_port.BeforeFirst(
' '), NULL);
1743 dlg.SetWaypoint(m_pFoundRoutePoint);
1747 dlg.Create(NULL, -1, _(
"Send to GPS") + _T(
"..." ), _T(
""));
1753 case ID_WPT_MENU_SENDTONEWGPS:
1754 if (m_pFoundRoutePoint) {
1756 dlg.SetWaypoint(m_pFoundRoutePoint);
1758 dlg.Create(NULL, -1, _(
"Send to GPS") + _T(
"..." ), _T(
""));
1763 case ID_WPT_MENU_SENDTOPEER:
1764 if (m_pFoundRoutePoint) {
1766 dlg.SetWaypoint(m_pFoundRoutePoint);
1771 MdnsCache::GetInstance().
Validate();
1772 if (MdnsCache::GetInstance().GetCache().empty())
1773 dlg.SetScanOnCreate(
true);
1776 dlg.Create(NULL, -1, _(
"Send Waypoint to OpenCPN Peer") + _T(
"..." ),
1782 case ID_RT_MENU_SENDTOGPS:
1783 if (m_pSelectedRoute) {
1784 if (parent->m_active_upload_port.Length())
1786 .SendToGPS(parent->m_active_upload_port.BeforeFirst(
' '),
true,
1790 dlg.SetRoute(m_pSelectedRoute);
1792 dlg.Create(NULL, -1, _(
"Send to GPS") + _T(
"..." ), _T(
""));
1798 case ID_RT_MENU_SENDTONEWGPS:
1799 if (m_pSelectedRoute) {
1801 dlg.SetRoute(m_pSelectedRoute);
1803 dlg.Create(NULL, -1, _(
"Send to GPS") + _T(
"..." ), _T(
""));
1808 case ID_RT_MENU_SENDTOPEER:
1809 if (m_pSelectedRoute) {
1811 dlg.SetRoute(m_pSelectedRoute);
1816 MdnsCache::GetInstance().
Validate();
1817 if (MdnsCache::GetInstance().GetCache().empty())
1818 dlg.SetScanOnCreate(
true);
1821 dlg.Create(NULL, -1, _(
"Send Route to OpenCPN Peer") + _T(
"..." ),
1827 case ID_PASTE_WAYPOINT:
1828 pupHandler_PasteWaypoint();
1831 case ID_PASTE_ROUTE:
1832 pupHandler_PasteRoute();
1835 case ID_PASTE_TRACK:
1836 pupHandler_PasteTrack();
1839 case ID_RT_MENU_DELPOINT:
1840 if (m_pSelectedRoute) {
1843 pWayPointMan->DestroyWaypoint(m_pFoundRoutePoint);
1845 if (pRoutePropDialog && (pRoutePropDialog->IsShown())) {
1848 if (g_pRouteMan->IsRouteValid(m_pSelectedRoute)) {
1849 pRoutePropDialog->SetRouteAndUpdate(m_pSelectedRoute,
true);
1851 pRoutePropDialog->Hide();
1854 if (RouteManagerDialog::getInstanceFlag()) {
1855 if (pRouteManagerDialog && pRouteManagerDialog->IsShown()) {
1856 pRouteManagerDialog->UpdateWptListCtrl();
1857 pRouteManagerDialog->UpdateRouteListCtrl();
1861 gFrame->InvalidateAllGL();
1862 gFrame->RefreshAllCanvas(
true);
1867 case ID_RT_MENU_REMPOINT:
1868 if (m_pSelectedRoute) {
1870 g_pRouteMan->RemovePointFromRoute(m_pFoundRoutePoint, m_pSelectedRoute,
1871 parent->m_routeState);
1872 gFrame->InvalidateAllGL();
1873 gFrame->RefreshAllCanvas();
1877 case ID_RT_MENU_ACTPOINT:
1878 if (g_pRouteMan->GetpActiveRoute() == m_pSelectedRoute) {
1885 case ID_RT_MENU_DEACTPOINT:
1888 case ID_RT_MENU_ACTNXTPOINT:
1889 if (g_pRouteMan->GetpActiveRoute() == m_pSelectedRoute) {
1896 case ID_RT_MENU_PROPERTIES: {
1897 parent->ShowRoutePropertiesDialog(_(
"Route Properties"),
1902 case ID_TK_MENU_PROPERTIES: {
1903 parent->ShowTrackPropertiesDialog(m_pSelectedTrack);
1907 case ID_TK_MENU_DELETE: {
1908 int dlg_return = wxID_YES;
1909 if (g_bConfirmObjectDelete) {
1910 dlg_return = OCPNMessageBox(
1911 parent, _(
"Are you sure you want to delete this track?"),
1912 _(
"OpenCPN Track Delete"),
1913 (
long)wxYES_NO | wxCANCEL | wxYES_DEFAULT);
1916 if (dlg_return == wxID_YES) {
1917 if (m_pSelectedTrack == g_pActiveTrack)
1918 m_pSelectedTrack = parent->parent_frame->TrackOff();
1919 g_pAIS->DeletePersistentTrack(m_pSelectedTrack);
1921 NavObj_dB::GetInstance().DeleteTrack(m_pSelectedTrack);
1922 RoutemanGui(*g_pRouteMan).DeleteTrack(m_pSelectedTrack);
1924 if (TrackPropDlg::getInstanceFlag() && pTrackPropDialog &&
1925 (pTrackPropDialog->IsShown()) &&
1926 (m_pSelectedTrack == pTrackPropDialog->GetTrack())) {
1927 pTrackPropDialog->Hide();
1930 if (RoutePropDlgImpl::getInstanceFlag() && pRouteManagerDialog &&
1931 pRouteManagerDialog->IsShown()) {
1932 pRouteManagerDialog->UpdateTrkListCtrl();
1933 pRouteManagerDialog->UpdateRouteListCtrl();
1935 gFrame->InvalidateAllGL();
1936 gFrame->RefreshAllCanvas();
1941 case ID_TK_MENU_SENDTOPEER:
1942 if (m_pSelectedTrack) {
1944 dlg.SetTrack(m_pSelectedTrack);
1949 MdnsCache::GetInstance().
Validate();
1950 if (MdnsCache::GetInstance().GetCache().empty())
1951 dlg.SetScanOnCreate(
true);
1954 dlg.Create(NULL, -1, _(
"Send Track to OpenCPN Peer") + _T(
"..." ),
1960 case ID_RC_MENU_SCALE_IN:
1961 parent->parent_frame->DoStackDown(parent);
1963 parent->WarpPointer(r.x, r.y);
1966 case ID_RC_MENU_SCALE_OUT:
1967 parent->parent_frame->DoStackUp(parent);
1969 parent->WarpPointer(r.x, r.y);
1972 case ID_RC_MENU_ZOOM_IN:
1975 parent->WarpPointer(r.x, r.y);
1978 case ID_RC_MENU_ZOOM_OUT:
1981 parent->WarpPointer(r.x, r.y);
1984 case ID_RC_MENU_FINISH:
1985 parent->FinishRoute();
1987 parent->Refresh(
false);
1988 g_FlushNavobjChanges =
true;
1991 case ID_DEF_ZERO_XTE:
1992 g_pRouteMan->ZeroCurrentXTEToActivePoint();
1998 ArrayOfPlugInMenuItems item_array =
1999 g_pi_manager->GetPluginContextMenuItemArray();
2001 for (
unsigned int i = 0; i < item_array.GetCount(); i++) {
2003 int target_id = pimis->id;
2006 if (pimis->pmenu_item->GetSubMenu()) {
2007 const wxMenuItemList &items =
2008 pimis->pmenu_item->GetSubMenu()->GetMenuItems();
2009 for (wxMenuItemList::const_iterator it = items.begin();
2010 it != items.end(); ++it) {
2011 if ((*it)->GetId() ==
event.GetId()) {
2012 target_id = (*it)->GetId();
2018 if (pimis->m_pplugin && (target_id == event.GetId())) {
2019 if (pimis->extended) {
2020 std::string object_type;
2021 std::string object_ident;
2023 if ((pimis->m_in_menu.IsSameAs(
"Waypoint")) && m_pFoundRoutePoint) {
2024 object_type =
"Waypoint";
2025 object_ident = m_pFoundRoutePoint->
m_GUID.ToStdString();
2026 }
else if ((pimis->m_in_menu.IsSameAs(
"Route")) &&
2028 object_type =
"Route";
2029 object_ident = m_pSelectedRoute->
m_GUID.ToStdString();
2030 }
else if ((pimis->m_in_menu.IsSameAs(
"Track")) &&
2032 object_type =
"Track";
2033 object_ident = m_pSelectedTrack->m_GUID.ToStdString();
2034 }
else if ((pimis->m_in_menu.IsSameAs(
"AIS")) && m_FoundAIS_MMSI) {
2035 object_type =
"AIS";
2036 wxString sAIS = wxString::Format(
"%d", m_FoundAIS_MMSI);
2037 object_ident = sAIS.ToStdString();
2043 ppi->OnContextMenuItemCallbackExt(target_id, object_ident,
2044 object_type, zlat, zlon);
2055 if ((event.GetId() >= ID_DEF_MENU_GROUPBASE) &&
2057 ID_DEF_MENU_GROUPBASE + (int)g_pGroupArray->GetCount())) {
2058 parent->SetGroupIndex(event.GetId() - ID_DEF_MENU_GROUPBASE);
2061 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.
wxString m_GUID
Globally Unique Identifier for the waypoint.
bool m_bIsolatedMark
Flag indicating if the waypoint is a standalone mark.
bool m_bIsInLayer
Flag indicating if the waypoint belongs to a layer.
Represents a navigational route in the navigation system.
bool m_bRtIsSelected
Flag indicating whether this route is currently selected in the UI.
wxString m_RouteStartString
Name or description of the route's starting point.
bool m_bDeleteOnArrival
Flag indicating whether the route should be deleted once navigation reaches the end.
wxString m_RouteEndString
Name or description of the route's ending point.
RoutePoint * m_pRouteActivePoint
Pointer to the currently active waypoint within this route.
wxString m_RouteNameString
User-assigned name for the route.
wxString m_GUID
Globally unique identifier for this route.
bool m_bIsInLayer
Flag indicating whether this route belongs to a layer.
int m_lastMousePointIndex
Index of the most recently interacted with route point.
bool ActivateRoutePoint(Route *pA, RoutePoint *pRP)
Activates a specific waypoint within a route for navigation.
wxArrayPtrVoid * GetRouteArrayContaining(RoutePoint *pWP)
Find all routes that contain the given waypoint.
bool ActivateNextPoint(Route *pr, bool skipped)
Activates the next waypoint in a route when the current waypoint is reached.
bool DeleteRoute(Route *pRoute)
bool ActivateRoute(Route *pRouteToActivate, RoutePoint *pStartPoint=NULL)
Activates a route for navigation.
Dialog for sending routes/waypoints to a GPS device.
Dialog for sending navigation objects to peer devices.
Represents a track, which is a series of connected track points.
bool RemoveRoutePoint(RoutePoint *prp)
Remove a routepoint from list if present, deallocate it all cases.
Represents a composite CM93 chart covering multiple scales.
virtual void OnContextMenuItemCallback(int id)
Handles context menu item selection.
The JSON value class implementation.
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.