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 contextMenu->AppendSubMenu(subMenuDebug, _(
"Debug"));
716 if (seltype & SELTYPE_ROUTESEGMENT) {
717 if (!g_bBasicMenus && m_pSelectedRoute) {
719 if (name.IsEmpty()) name = _(
"Unnamed Route");
720 name.Prepend(_T(
" ( ")).Append(_T(
" )"));
722 name = wxEmptyString;
724 if (m_pSelectedRoute && m_pSelectedRoute->
m_bIsInLayer) blay =
true;
727 menuRoute =
new wxMenu(_(
"Layer Route") + name);
728 MenuAppend1(menuRoute, ID_RT_MENU_PROPERTIES,
729 _(
"Properties") + _T(
"..." ));
730 if (m_pSelectedRoute) {
731 if (m_pSelectedRoute->IsActive()) {
732 int indexActive = m_pSelectedRoute->GetIndexOf(
734 if ((indexActive + 1) <= m_pSelectedRoute->GetnPoints()) {
735 MenuAppend1(menuRoute, ID_RT_MENU_ACTNXTPOINT,
736 _(
"Activate Next Waypoint"));
738 MenuAppend1(menuRoute, ID_RT_MENU_DEACTIVATE, _(
"Deactivate"));
739 MenuAppend1(menuRoute, ID_DEF_ZERO_XTE, _(
"Zero XTE"));
741 MenuAppend1(menuRoute, ID_RT_MENU_ACTIVATE, _(
"Activate"));
745 menuRoute =
new wxMenu(_(
"Route") + name);
746 MenuAppend1(menuRoute, ID_RT_MENU_PROPERTIES,
747 _(
"Properties") + _T(
"..." ));
748 if (m_pSelectedRoute) {
749 if (m_pSelectedRoute->IsActive()) {
750 int indexActive = m_pSelectedRoute->GetIndexOf(
752 if ((indexActive + 1) <= m_pSelectedRoute->GetnPoints()) {
753 MenuAppend1(menuRoute, ID_RT_MENU_ACTNXTPOINT,
754 _(
"Activate Next Waypoint"));
756 MenuAppend1(menuRoute, ID_RT_MENU_DEACTIVATE, _(
"Deactivate"));
757 MenuAppend1(menuRoute, ID_DEF_ZERO_XTE, _(
"Zero XTE"));
759 MenuAppend1(menuRoute, ID_RT_MENU_ACTIVATE, _(
"Activate"));
762 MenuAppend1(menuRoute, ID_RT_MENU_INSERT, _(
"Insert Waypoint"));
763 MenuAppend1(menuRoute, ID_RT_MENU_APPEND, _(
"Append Waypoint"));
764 if (!(seltype & SELTYPE_ROUTEPOINT) && m_pSelectedRoute) {
765 m_SelectedIdx = m_pSelectedRoute->GetIndexOf(m_pFoundRoutePoint);
766 if (m_SelectedIdx > 1 &&
767 m_SelectedIdx < m_pSelectedRoute->GetnPoints() - 1)
768 MenuAppend1(menuRoute, ID_RT_MENU_SPLIT_LEG, _(
"Split around Leg"));
770 MenuAppend1(menuRoute, ID_RT_MENU_COPY, _(
"Copy as KML") + _T(
"..." ));
771 MenuAppend1(menuRoute, ID_RT_MENU_DELETE, _(
"Delete") + _T(
"..." ));
772 MenuAppend1(menuRoute, ID_RT_MENU_REVERSE, _(
"Reverse..."));
773 if (m_pSelectedRoute) {
774 if (m_pSelectedRoute->AreWaypointNamesVisible())
775 MenuAppend1(menuRoute, ID_RT_MENU_SHOWNAMES,
776 _(
"Hide Waypoint Names"));
778 MenuAppend1(menuRoute, ID_RT_MENU_SHOWNAMES,
779 _(
"Show Waypoint Names"));
781 MenuAppend1(menuRoute, ID_RT_MENU_RESEQUENCE,
782 _(
"Resequence Waypoints..."));
785 wxString port = parent->FindValidUploadPort();
786 parent->m_active_upload_port = port;
787 wxString item = _(
"Send to GPS");
788 if (!port.IsEmpty()) {
789 item.Append(_T(
" ( "));
791 item.Append(_T(
" )"));
793 MenuAppend1(menuRoute, ID_RT_MENU_SENDTOGPS, item);
795 if (!port.IsEmpty()) {
796 wxString item = _(
"Send to new GPS");
797 MenuAppend1(menuRoute, ID_RT_MENU_SENDTONEWGPS, item);
800 wxString itemstp = SYMBOL_STP_TITLE;
801 MenuAppend1(menuRoute, ID_RT_MENU_SENDTOPEER, itemstp);
804 if (menuFocus != menuAIS) menuFocus = menuRoute;
807 if (seltype & SELTYPE_TRACKSEGMENT) {
808 name = wxEmptyString;
809 if (!g_bBasicMenus && m_pSelectedTrack)
810 name = _T(
" ( ") + m_pSelectedTrack->GetName(
true) + _T(
" )");
812 name = wxEmptyString;
814 if (m_pSelectedTrack && m_pSelectedTrack->m_bIsInLayer) blay =
true;
817 menuTrack =
new wxMenu(_(
"Layer Track") + name);
818 MenuAppend1(menuTrack, ID_TK_MENU_PROPERTIES,
819 _(
"Properties") + _T(
"..." ));
821 menuTrack =
new wxMenu(_(
"Track") + name);
822 MenuAppend1(menuTrack, ID_TK_MENU_PROPERTIES,
823 _(
"Properties") + _T(
"..." ));
824 MenuAppend1(menuTrack, ID_TK_MENU_COPY, _(
"Copy as KML"));
825 MenuAppend1(menuTrack, ID_TK_MENU_DELETE, _(
"Delete") + _T(
"..." ));
828 wxString itemstp = SYMBOL_STP_TITLE;
829 MenuAppend1(menuTrack, ID_TK_MENU_SENDTOPEER, itemstp);
832 if (menuFocus != menuAIS) menuFocus = menuTrack;
835 if (seltype & SELTYPE_ROUTEPOINT) {
836 if (!g_bBasicMenus && m_pFoundRoutePoint) {
837 name = m_pFoundRoutePoint->GetName();
838 if (name.IsEmpty()) name = _(
"Unnamed Waypoint");
839 name.Prepend(_T(
" ( ")).Append(_T(
" )"));
841 name = wxEmptyString;
843 if (m_pFoundRoutePoint && m_pFoundRoutePoint->
m_bIsInLayer) blay =
true;
846 menuWaypoint =
new wxMenu(_(
"Layer Waypoint") + name);
847 MenuAppend1(menuWaypoint, ID_WP_MENU_PROPERTIES,
848 _(
"Properties") + _T(
"..." ));
850 if (m_pSelectedRoute && m_pSelectedRoute->IsActive())
851 MenuAppend1(menuWaypoint, ID_RT_MENU_ACTPOINT, _(
"Activate"));
853 menuWaypoint =
new wxMenu(_(
"Waypoint") + name);
854 MenuAppend1(menuWaypoint, ID_WP_MENU_PROPERTIES,
855 _(
"Properties") + _T(
"..." ));
856 if (m_pSelectedRoute && m_pSelectedRoute->IsActive()) {
858 MenuAppend1(menuWaypoint, ID_RT_MENU_ACTPOINT, _(
"Activate"));
861 if (m_pSelectedRoute && m_pSelectedRoute->IsActive()) {
863 int indexActive = m_pSelectedRoute->GetIndexOf(
865 if ((indexActive + 1) <= m_pSelectedRoute->GetnPoints())
866 MenuAppend1(menuWaypoint, ID_RT_MENU_ACTNXTPOINT,
867 _(
"Activate Next Waypoint"));
870 if (m_pSelectedRoute && m_pSelectedRoute->GetnPoints() > 2) {
871 MenuAppend1(menuWaypoint, ID_RT_MENU_REMPOINT, _(
"Remove from Route"));
873 m_SelectedIdx = m_pSelectedRoute->GetIndexOf(m_pFoundRoutePoint);
874 if (m_SelectedIdx > 1 && m_SelectedIdx < m_pSelectedRoute->GetnPoints())
875 MenuAppend1(menuWaypoint, ID_RT_MENU_SPLIT_WPT,
876 _(
"Split Route at Waypoint"));
879 MenuAppend1(menuWaypoint, ID_WPT_MENU_COPY, _(
"Copy as KML"));
881 if (m_pFoundRoutePoint && m_pFoundRoutePoint->GetIconName() != _T(
"mob"))
882 MenuAppend1(menuWaypoint, ID_RT_MENU_DELPOINT, _(
"Delete"));
885 wxString port = parent->FindValidUploadPort();
886 parent->m_active_upload_port = port;
887 wxString item = _(
"Send to GPS");
888 if (!port.IsEmpty()) {
889 item.Append(_T(
" ( "));
891 item.Append(_T(
" )"));
893 MenuAppend1(menuWaypoint, ID_WPT_MENU_SENDTOGPS, item);
895 if (!port.IsEmpty()) {
896 wxString item = _(
"Send to new GPS");
897 MenuAppend1(menuWaypoint, ID_WPT_MENU_SENDTONEWGPS, item);
900 MenuAppend1(menuWaypoint, ID_WPT_MENU_SENDTOPEER,
905 if (menuFocus != menuAIS) menuFocus = menuWaypoint;
908 if (seltype & SELTYPE_MARKPOINT) {
909 if (!g_bBasicMenus && m_pFoundRoutePoint) {
910 name = m_pFoundRoutePoint->GetName();
911 if (name.IsEmpty()) name = _(
"Unnamed Mark");
912 name.Prepend(_T(
" ( ")).Append(_T(
" )"));
914 name = wxEmptyString;
916 if (m_pFoundRoutePoint && m_pFoundRoutePoint->
m_bIsInLayer) blay =
true;
919 menuWaypoint =
new wxMenu(_(
"Layer Waypoint") + name);
920 MenuAppend1(menuWaypoint, ID_WP_MENU_PROPERTIES,
921 _(
"Properties") + _T(
"..." ));
923 menuWaypoint =
new wxMenu(_(
"Mark") + name);
924 MenuAppend1(menuWaypoint, ID_WP_MENU_PROPERTIES,
925 _(
"Properties") + _T(
"..." ));
927 if (!g_pRouteMan->GetpActiveRoute())
928 MenuAppend1(menuWaypoint, ID_WP_MENU_GOTO, _(
"Navigate To This"));
930 MenuAppend1(menuWaypoint, ID_WPT_MENU_COPY, _(
"Copy as KML"));
932 if (m_pFoundRoutePoint && m_pFoundRoutePoint->GetIconName() != _T(
"mob"))
933 MenuAppend1(menuWaypoint, ID_WP_MENU_DELPOINT, _(
"Delete"));
936 wxString port = parent->FindValidUploadPort();
937 parent->m_active_upload_port = port;
938 wxString item = _(
"Send to GPS");
939 if (!port.IsEmpty()) {
940 item.Append(_T(
" ( "));
942 item.Append(_T(
" )"));
944 MenuAppend1(menuWaypoint, ID_WPT_MENU_SENDTOGPS, item);
946 MenuAppend1(menuWaypoint, ID_WPT_MENU_SENDTOPEER,
950 if ((m_pFoundRoutePoint == pAnchorWatchPoint1) ||
951 (m_pFoundRoutePoint == pAnchorWatchPoint2))
952 MenuAppend1(menuWaypoint, ID_WP_MENU_CLEAR_ANCHORWATCH,
953 _(
"Clear Anchor Watch"));
955 if (m_pFoundRoutePoint && !(m_pFoundRoutePoint->
m_bIsInLayer) &&
956 ((NULL == pAnchorWatchPoint1) || (NULL == pAnchorWatchPoint2))) {
959 DistanceBearingMercator(m_pFoundRoutePoint->m_lat,
960 m_pFoundRoutePoint->m_lon, gLat, gLon, &brg,
962 if (dist * 1852. <= g_nAWMax)
963 MenuAppend1(menuWaypoint, ID_WP_MENU_SET_ANCHORWATCH,
964 _(
"Set Anchor Watch"));
969 if (menuFocus != menuAIS) menuFocus = menuWaypoint;
973 AddPluginContextMenuItems(contextMenu, menuRoute, menuTrack, menuWaypoint,
977 enum { WPMENU = 1, TKMENU = 2, RTMENU = 4, MMMENU = 8 };
979 if (!g_bBasicMenus && menuFocus != contextMenu) {
980 if (global_color_scheme != GLOBAL_COLOR_SCHEME_DUSK &&
981 global_color_scheme != GLOBAL_COLOR_SCHEME_NIGHT) {
982 menuFocus->AppendSeparator();
985 wxMenuItem *subMenu1;
986 if (menuWaypoint && menuFocus != menuWaypoint) {
988 menuFocus->AppendSubMenu(menuWaypoint, menuWaypoint->GetTitle());
989 SetMenuItemFont1(subMenu1);
992 menuWaypoint->SetTitle(wxEmptyString);
995 if (menuTrack && menuFocus != menuTrack) {
996 subMenu1 = menuFocus->AppendSubMenu(menuTrack, menuTrack->GetTitle());
997 SetMenuItemFont1(subMenu1);
1000 menuTrack->SetTitle(wxEmptyString);
1003 if (menuRoute && menuFocus != menuRoute) {
1004 subMenu1 = menuFocus->AppendSubMenu(menuRoute, menuRoute->GetTitle());
1005 SetMenuItemFont1(subMenu1);
1008 menuRoute->SetTitle(wxEmptyString);
1011 subMenu1 = menuFocus->AppendSubMenu(contextMenu, _(
"Main Menu"));
1012 SetMenuItemFont1(subMenu1);
1016 if (!subMenuChart->GetMenuItemCount()) contextMenu->Destroy(subItemChart);
1021 if (seltype & SELTYPE_TIDEPOINT) {
1022 menuFocus->AppendSeparator();
1024 MenuAppend1(menuFocus, ID_DEF_MENU_TIDEINFO, _(
"Show Tide Information"));
1027 if (seltype & SELTYPE_CURRENTPOINT) {
1028 if (!bsep) menuFocus->AppendSeparator();
1029 MenuAppend1(menuFocus, ID_DEF_MENU_CURRENTINFO,
1030 _(
"Show Current Information"));
1036 androidEnableBackButton(
false);
1037 androidEnableOptionsMenu(
false);
1045 parent->PopupMenu(menuFocus, x, y);
1048 androidEnableBackButton(
true);
1049 androidEnableOptionsMenu(
true);
1056 if (!(sub_menu & MMMENU))
delete contextMenu;
1057 if (!(sub_menu & RTMENU))
delete menuRoute;
1058 if (!(sub_menu & TKMENU))
delete menuTrack;
1059 if (!(sub_menu & WPMENU))
delete menuWaypoint;
1062void CanvasMenuHandler::AddPluginContextMenuItems(wxMenu *contextMenu,
1065 wxMenu *menuWaypoint,
1068 g_pi_manager->PrepareAllPluginContextMenus();
1071 ArrayOfPlugInMenuItems item_array =
1072 g_pi_manager->GetPluginContextMenuItemArray();
1074 for (
unsigned int i = 0; i < item_array.GetCount(); i++) {
1076 if (!pimis->b_viz)
continue;
1078 wxMenu *submenu = NULL;
1079 if (pimis->pmenu_item->GetSubMenu()) {
1081 auto submenu_proto = pimis->pmenu_item->GetSubMenu();
1082 submenu =
new wxMenu();
1083 const wxMenuItemList &items =
1084 pimis->pmenu_item->GetSubMenu()->GetMenuItems();
1085 for (wxMenuItemList::const_iterator it = items.begin(); it != items.end();
1087 int id = (*it)->GetId();
1089 new wxMenuItem(submenu,
id, (*it)->GetItemLabelText(),
1090 (*it)->GetHelp(), (*it)->GetKind());
1093 psmi->SetFont(m_scaledFont);
1098 psmi->SetFont(sFont);
1101 PrepareMenuItem(psmi);
1102 submenu->Append(psmi);
1103 psmi->Check((*it)->IsChecked());
1107 wxMenuItem *pmi =
new wxMenuItem(
1108 contextMenu, pimis->id, pimis->pmenu_item->GetItemLabelText(),
1109 pimis->pmenu_item->GetHelp(), pimis->pmenu_item->GetKind(), submenu);
1111 pmi->SetFont(m_scaledFont);
1116 pmi->SetFont(sFont);
1119 PrepareMenuItem(pmi);
1121 wxMenu *dst = contextMenu;
1122 if (pimis->m_in_menu ==
"Waypoint")
1124 else if (pimis->m_in_menu ==
"Route")
1126 else if (pimis->m_in_menu ==
"Track")
1128 else if (pimis->m_in_menu ==
"AIS")
1133 dst->Enable(pimis->id, !pimis->b_grey);
1138void CanvasMenuHandler::PopupMenuHandler(wxCommandEvent &event) {
1145 bool dupFirstWpt =
true, showRPD;
1150 switch (event.GetId()) {
1151 case ID_DEF_MENU_MAX_DETAIL:
1154 parent->ClearbFollow();
1156 parent->parent_frame->DoChartUpdate();
1158 parent->SelectChartFromStack(0,
false, CHART_TYPE_DONTCARE,
1159 CHART_FAMILY_RASTER);
1162 case ID_DEF_MENU_SCALE_IN:
1163 parent->DoCanvasStackDelta(-1);
1166 case ID_DEF_MENU_SCALE_OUT:
1167 parent->DoCanvasStackDelta(1);
1171 parent->undo->UndoLastAction();
1172 parent->InvalidateGL();
1173 parent->Refresh(
false);
1177 parent->undo->RedoNextAction();
1178 parent->InvalidateGL();
1179 parent->Refresh(
false);
1182 case ID_DEF_MENU_MOVE_BOAT_HERE:
1185 gFrame->UpdateStatusBar();
1188 case ID_DEF_MENU_GOTO_HERE: {
1190 wxEmptyString, wxEmptyString);
1191 pSelect->AddSelectableRoutePoint(zlat, zlon, pWP_dest);
1194 wxEmptyString, wxEmptyString);
1195 pSelect->AddSelectableRoutePoint(gLat, gLon, pWP_src);
1198 pRouteList->Append(temp_route);
1200 temp_route->AddPoint(pWP_src);
1201 temp_route->AddPoint(pWP_dest);
1203 pSelect->AddSelectableRouteSegment(gLat, gLon, zlat, zlon, pWP_src,
1204 pWP_dest, temp_route);
1213 if (g_pRouteMan->GetpActiveRoute()) g_pRouteMan->DeactivateRoute();
1220 case ID_DEF_MENU_DROP_WP: {
1222 wxEmptyString, wxEmptyString);
1224 pSelect->AddSelectableRoutePoint(zlat, zlon, pWP);
1225 NavObj_dB::GetInstance().InsertRoutePoint(pWP);
1230 if (RouteManagerDialog::getInstanceFlag()) {
1231 if (pRouteManagerDialog && pRouteManagerDialog->IsShown()) {
1232 pRouteManagerDialog->UpdateWptListCtrl();
1236 parent->undo->BeforeUndoableAction(Undo_CreateWaypoint, pWP,
1237 Undo_HasParent, NULL);
1238 parent->undo->AfterUndoableAction(NULL);
1239 gFrame->RefreshAllCanvas(
false);
1240 gFrame->InvalidateAllGL();
1241 g_FlushNavobjChanges =
true;
1245 case ID_DEF_MENU_NEW_RT: {
1246 parent->StartRoute();
1250 case ID_DEF_MENU_AISTARGETLIST:
1251 parent->ShowAISTargetList();
1254 case ID_DEF_MENU_AIS_CPAWARNING:
1255 parent->ToggleCPAWarn();
1258 case ID_WP_MENU_GOTO: {
1260 wxEmptyString, wxEmptyString);
1261 pSelect->AddSelectableRoutePoint(gLat, gLon, pWP_src);
1264 pRouteList->Append(temp_route);
1266 temp_route->AddPoint(pWP_src);
1267 temp_route->AddPoint(m_pFoundRoutePoint);
1268 m_pFoundRoutePoint->SetShared(
true);
1270 pSelect->AddSelectableRouteSegment(gLat, gLon, m_pFoundRoutePoint->m_lat,
1271 m_pFoundRoutePoint->m_lon, pWP_src,
1272 m_pFoundRoutePoint, temp_route);
1274 wxString name = m_pFoundRoutePoint->GetName();
1275 if (name.IsEmpty()) name = _(
"(Unnamed Waypoint)");
1276 wxString rteName = _(
"Go to ");
1277 rteName.Append(name);
1284 if (g_pRouteMan->GetpActiveRoute()) g_pRouteMan->DeactivateRoute();
1291 case ID_DEF_MENU_COGUP:
1292 parent->SetUpMode(COURSE_UP_MODE);
1295 case ID_DEF_MENU_HEADUP:
1296 parent->SetUpMode(HEAD_UP_MODE);
1299 case ID_DEF_MENU_NORTHUP:
1300 parent->SetUpMode(NORTH_UP_MODE);
1303 case ID_DEF_MENU_TOGGLE_FULL:
1304 gFrame->ToggleFullScreen();
1307 case ID_DEF_MENU_GOTOPOSITION:
1308 if (NULL == pGoToPositionDialog)
1311 pGoToPositionDialog->SetCanvas(parent);
1312 pGoToPositionDialog->CheckPasteBufferForPosition();
1313 pGoToPositionDialog->Show();
1316 case ID_WP_MENU_DELPOINT: {
1317 if (m_pFoundRoutePoint == pAnchorWatchPoint1) {
1318 pAnchorWatchPoint1 = NULL;
1320 }
else if (m_pFoundRoutePoint == pAnchorWatchPoint2) {
1321 pAnchorWatchPoint2 = NULL;
1325 if (m_pFoundRoutePoint && !(m_pFoundRoutePoint->
m_bIsInLayer) &&
1326 (m_pFoundRoutePoint->GetIconName() != _T(
"mob"))) {
1330 wxArrayPtrVoid *proute_array =
1333 pWayPointMan->DestroyWaypoint(m_pFoundRoutePoint);
1334 delete proute_array;
1336 parent->undo->BeforeUndoableAction(
1337 Undo_DeleteWaypoint, m_pFoundRoutePoint, Undo_IsOrphanded,
1339 NavObj_dB::GetInstance().DeleteRoutePoint(m_pFoundRoutePoint);
1340 pSelect->DeleteSelectablePoint(m_pFoundRoutePoint,
1341 SELTYPE_ROUTEPOINT);
1342 if (NULL != pWayPointMan)
1344 parent->undo->AfterUndoableAction(NULL);
1347 if (g_pMarkInfoDialog) {
1348 g_pMarkInfoDialog->ClearData();
1351 if (RouteManagerDialog::getInstanceFlag()) {
1352 if (pRouteManagerDialog) {
1353 if (pRouteManagerDialog->IsShown())
1354 pRouteManagerDialog->UpdateWptListCtrl();
1358 gFrame->RefreshAllCanvas(
false);
1359 gFrame->InvalidateAllGL();
1363 case ID_WP_MENU_PROPERTIES:
1364 parent->ShowMarkPropertiesDialog(m_pFoundRoutePoint);
1367 case ID_WP_MENU_CLEAR_ANCHORWATCH: {
1368 wxString guid = wxEmptyString;
1369 if (pAnchorWatchPoint1 == m_pFoundRoutePoint) {
1370 pAnchorWatchPoint1 = NULL;
1373 }
else if (pAnchorWatchPoint2 == m_pFoundRoutePoint) {
1374 pAnchorWatchPoint2 = NULL;
1378 if (!guid.IsEmpty()) {
1380 v[_T(
"GUID")] = guid;
1381 wxString msg_id(_T(
"OCPN_ANCHOR_WATCH_CLEARED"));
1382 SendJSONMessageToAllPlugins(msg_id, v);
1387 case ID_WP_MENU_SET_ANCHORWATCH: {
1388 wxString guid = wxEmptyString;
1389 if (pAnchorWatchPoint1 == NULL) {
1390 pAnchorWatchPoint1 = m_pFoundRoutePoint;
1391 g_AW1GUID = pAnchorWatchPoint1->
m_GUID;
1394 nn = m_pFoundRoutePoint->GetName();
1396 nn.Printf(_T(
"%d m"), g_nAWDefault);
1397 m_pFoundRoutePoint->SetName(nn);
1399 }
else if (pAnchorWatchPoint2 == NULL) {
1400 pAnchorWatchPoint2 = m_pFoundRoutePoint;
1401 g_AW2GUID = pAnchorWatchPoint2->
m_GUID;
1404 nn = m_pFoundRoutePoint->GetName();
1406 nn.Printf(_T(
"%d m"), g_nAWDefault);
1407 m_pFoundRoutePoint->SetName(nn);
1410 if (!guid.IsEmpty()) {
1412 v[_T(
"GUID")] = guid;
1413 wxString msg_id(_T(
"OCPN_ANCHOR_WATCH_SET"));
1414 SendJSONMessageToAllPlugins(msg_id, v);
1419 case ID_DEF_MENU_ACTIVATE_MEASURE:
1420 parent->StartMeasureRoute();
1423 case ID_DEF_MENU_DEACTIVATE_MEASURE:
1424 parent->CancelMeasureRoute();
1426 parent->InvalidateGL();
1427 parent->Refresh(
false);
1430 case ID_DEF_MENU_CM93OFFSET_DIALOG: {
1431 if (NULL == g_pCM93OffsetDialog) {
1436 if (!parent->GetVP().b_quilt && parent->m_singleChart &&
1437 (parent->m_singleChart->GetChartType() == CHART_TYPE_CM93COMP)) {
1441 if (g_pCM93OffsetDialog) {
1442 g_pCM93OffsetDialog->SetCM93Chart(pch);
1443 g_pCM93OffsetDialog->Show();
1444 g_pCM93OffsetDialog->UpdateMCOVRList(parent->GetVP());
1449 case ID_DEF_MENU_QUERY: {
1450 parent->ShowObjectQueryWindow(popx, popy, zlat, zlon);
1453 case ID_DEF_MENU_AIS_QUERY: {
1454 ShowAISTargetQueryDialog(parent, m_FoundAIS_MMSI);
1458 case ID_DEF_MENU_AIS_CPA: {
1459 auto myptarget = g_pAIS->Get_Target_Data_From_MMSI(m_FoundAIS_MMSI);
1460 if (myptarget) myptarget->Toggle_AIS_CPA();
1464 case ID_DEF_MENU_AISSHOWTRACK: {
1465 auto myptarget = g_pAIS->Get_Target_Data_From_MMSI(m_FoundAIS_MMSI);
1466 if (myptarget) myptarget->ToggleShowTrack();
1470 case ID_DEF_MENU_COPY_MMSI: {
1472 if (wxTheClipboard->Open()) {
1473 wxTheClipboard->SetData(
new wxTextDataObject(
1474 wxString::Format(wxT(
"%09d"), m_FoundAIS_MMSI)));
1475 wxTheClipboard->Close();
1480 case ID_DEF_MENU_QUILTREMOVE: {
1481 if (parent->GetVP().b_quilt) {
1482 int dbIndex = parent->m_pQuilt->GetChartdbIndexAtPix(
1483 parent->GetVP(), wxPoint(popx, popy));
1484 parent->RemoveChartFromQuilt(dbIndex);
1492 case ID_DEF_MENU_CURRENTINFO: {
1493 parent->DrawTCWindow(popx, popy, (
void *)m_pIDXCandidate);
1494 parent->Refresh(
false);
1499 case ID_DEF_MENU_TIDEINFO: {
1500 parent->DrawTCWindow(popx, popy, (
void *)m_pIDXCandidate);
1501 parent->Refresh(
false);
1506 case ID_DGB_MENU_NMEA_WINDOW:
1508 m_nmea_log->Raise();
1511 case ID_RT_MENU_REVERSE: {
1515 OCPNMessageBox(parent, g_pRouteMan->GetRouteReverseMessage(),
1516 _(
"Rename Waypoints?"), wxYES_NO | wxCANCEL);
1518 if (ask_return != wxID_CANCEL) {
1519 pSelect->DeleteAllSelectableRouteSegments(m_pSelectedRoute);
1520 m_pSelectedRoute->Reverse(ask_return == wxID_YES);
1521 pSelect->AddAllSelectableRouteSegments(m_pSelectedRoute);
1523 NavObj_dB::GetInstance().UpdateRoute(m_pSelectedRoute);
1525 if (pRoutePropDialog && (pRoutePropDialog->IsShown())) {
1526 pRoutePropDialog->SetRouteAndUpdate(m_pSelectedRoute);
1529 gFrame->InvalidateAllGL();
1530 gFrame->RefreshAllCanvas();
1535 case ID_RT_MENU_SHOWNAMES: {
1536 if (m_pSelectedRoute) {
1537 m_pSelectedRoute->ShowWaypointNames(
1538 !m_pSelectedRoute->AreWaypointNamesVisible());
1544 case ID_RT_MENU_RESEQUENCE: {
1545 if (m_pSelectedRoute) {
1549 OCPNMessageBox(parent, g_pRouteMan->GetRouteResequenceMessage(),
1550 _(
"Rename Waypoints?"), wxYES_NO | wxCANCEL);
1552 if (ask_return != wxID_CANCEL) {
1553 m_pSelectedRoute->RenameRoutePoints();
1556 gFrame->InvalidateAllGL();
1557 gFrame->RefreshAllCanvas();
1563 case ID_RT_MENU_DELETE: {
1564 bool confirmed = RouteGui::OnDelete(parent);
1567 if (g_pRouteMan->GetpActiveRoute() == m_pSelectedRoute)
1568 g_pRouteMan->DeactivateRoute();
1572 NavObj_dB::GetInstance().DeleteRoute(m_pSelectedRoute);
1573 if (!g_pRouteMan->
DeleteRoute(m_pSelectedRoute))
break;
1575 if (RouteManagerDialog::getInstanceFlag()) {
1576 if (pRouteManagerDialog && pRouteManagerDialog->IsShown())
1577 pRouteManagerDialog->UpdateRouteListCtrl();
1580 if (g_pMarkInfoDialog && g_pMarkInfoDialog->IsShown()) {
1581 g_pMarkInfoDialog->ValidateMark();
1582 g_pMarkInfoDialog->UpdateProperties();
1585 parent->undo->InvalidateUndo();
1587 gFrame->InvalidateAllGL();
1588 gFrame->RefreshAllCanvas();
1593 case ID_RT_MENU_ACTIVATE: {
1594 if (g_pRouteMan->GetpActiveRoute()) g_pRouteMan->DeactivateRoute();
1600 if (m_pSelectedRoute) {
1603 best_point = g_pRouteMan->FindBestActivatePoint(
1604 m_pSelectedRoute, gLat, gLon, gCog, gSog);
1606 best_point = m_pSelectedRoute->GetPoint(2);
1615 case ID_RT_MENU_DEACTIVATE:
1616 g_pRouteMan->DeactivateRoute();
1621 case ID_RT_MENU_INSERT: {
1623 bool rename =
false;
1624 m_pSelectedRoute->InsertPointAfter(m_pFoundRoutePoint, zlat, zlon,
1627 pSelect->DeleteAllSelectableRoutePoints(m_pSelectedRoute);
1628 pSelect->DeleteAllSelectableRouteSegments(m_pSelectedRoute);
1630 pSelect->AddAllSelectableRouteSegments(m_pSelectedRoute);
1631 pSelect->AddAllSelectableRoutePoints(m_pSelectedRoute);
1644 NavObj_dB::GetInstance().UpdateRoute(m_pSelectedRoute);
1646 if (pRoutePropDialog && (pRoutePropDialog->IsShown())) {
1647 pRoutePropDialog->SetRouteAndUpdate(m_pSelectedRoute,
true);
1653 case ID_RT_MENU_APPEND:
1657 parent->m_pMouseRoute = m_pSelectedRoute;
1658 parent->m_routeState = m_pSelectedRoute->GetnPoints() + 1;
1660 m_pSelectedRoute->GetnPoints();
1661 parent->m_pMouseRoute->SetHiLite(50);
1663 pLast = m_pSelectedRoute->GetLastPoint();
1665 parent->m_prev_rlat = pLast->m_lat;
1666 parent->m_prev_rlon = pLast->m_lon;
1667 parent->m_prev_pMousePoint = pLast;
1669 parent->m_bAppendingRoute =
true;
1671 parent->SetCursor(*parent->pCursorPencil);
1673 androidSetRouteAnnunciator(
true);
1676 parent->HideGlobalToolbar();
1680 case ID_RT_MENU_SPLIT_LEG:
1682 dupFirstWpt =
false;
1683 case ID_RT_MENU_SPLIT_WPT:
1685 showRPD = (pRoutePropDialog && pRoutePropDialog->IsShown());
1687 if (g_pRouteMan->GetpActiveRoute() == m_pSelectedRoute)
1688 g_pRouteMan->DeactivateRoute();
1690 m_pHead =
new Route();
1691 m_pTail =
new Route();
1692 m_pHead->CloneRoute(m_pSelectedRoute, 1, m_SelectedIdx, _(
"_A"));
1693 m_pTail->CloneRoute(m_pSelectedRoute, m_SelectedIdx + splitMode,
1694 m_pSelectedRoute->GetnPoints(), _(
"_B"), dupFirstWpt);
1695 pRouteList->Append(m_pHead);
1696 NavObj_dB::GetInstance().InsertRoute(m_pHead);
1698 pRouteList->Append(m_pTail);
1699 NavObj_dB::GetInstance().InsertRoute(m_pTail);
1701 NavObj_dB::GetInstance().DeleteRoute(m_pSelectedRoute);
1703 pSelect->DeleteAllSelectableRoutePoints(m_pSelectedRoute);
1704 pSelect->DeleteAllSelectableRouteSegments(m_pSelectedRoute);
1706 pSelect->AddAllSelectableRouteSegments(m_pTail);
1707 pSelect->AddAllSelectableRoutePoints(m_pTail);
1708 pSelect->AddAllSelectableRouteSegments(m_pHead);
1709 pSelect->AddAllSelectableRoutePoints(m_pHead);
1712 pRoutePropDialog->SetRouteAndUpdate(m_pHead);
1713 pRoutePropDialog->Show();
1715 if (RouteManagerDialog::getInstanceFlag() && pRouteManagerDialog &&
1716 (pRouteManagerDialog->IsShown()))
1717 pRouteManagerDialog->UpdateRouteListCtrl();
1720 case ID_RT_MENU_COPY:
1721 if (m_pSelectedRoute) Kml::CopyRouteToClipboard(m_pSelectedRoute);
1724 case ID_TK_MENU_COPY:
1725 if (m_pSelectedTrack) Kml::CopyTrackToClipboard(m_pSelectedTrack);
1728 case ID_WPT_MENU_COPY:
1729 if (m_pFoundRoutePoint) Kml::CopyWaypointToClipboard(m_pFoundRoutePoint);
1732 case ID_WPT_MENU_SENDTOGPS:
1733 if (m_pFoundRoutePoint) {
1734 if (parent->m_active_upload_port.Length())
1736 .SendToGPS(parent->m_active_upload_port.BeforeFirst(
' '), NULL);
1739 dlg.SetWaypoint(m_pFoundRoutePoint);
1743 dlg.Create(NULL, -1, _(
"Send to GPS") + _T(
"..." ), _T(
""));
1749 case ID_WPT_MENU_SENDTONEWGPS:
1750 if (m_pFoundRoutePoint) {
1752 dlg.SetWaypoint(m_pFoundRoutePoint);
1754 dlg.Create(NULL, -1, _(
"Send to GPS") + _T(
"..." ), _T(
""));
1759 case ID_WPT_MENU_SENDTOPEER:
1760 if (m_pFoundRoutePoint) {
1762 dlg.SetWaypoint(m_pFoundRoutePoint);
1767 MdnsCache::GetInstance().
Validate();
1768 if (MdnsCache::GetInstance().GetCache().empty())
1769 dlg.SetScanOnCreate(
true);
1772 dlg.Create(NULL, -1, _(
"Send Waypoint to OpenCPN Peer") + _T(
"..." ),
1778 case ID_RT_MENU_SENDTOGPS:
1779 if (m_pSelectedRoute) {
1780 if (parent->m_active_upload_port.Length())
1782 .SendToGPS(parent->m_active_upload_port.BeforeFirst(
' '),
true,
1786 dlg.SetRoute(m_pSelectedRoute);
1788 dlg.Create(NULL, -1, _(
"Send to GPS") + _T(
"..." ), _T(
""));
1794 case ID_RT_MENU_SENDTONEWGPS:
1795 if (m_pSelectedRoute) {
1797 dlg.SetRoute(m_pSelectedRoute);
1799 dlg.Create(NULL, -1, _(
"Send to GPS") + _T(
"..." ), _T(
""));
1804 case ID_RT_MENU_SENDTOPEER:
1805 if (m_pSelectedRoute) {
1807 dlg.SetRoute(m_pSelectedRoute);
1812 MdnsCache::GetInstance().
Validate();
1813 if (MdnsCache::GetInstance().GetCache().empty())
1814 dlg.SetScanOnCreate(
true);
1817 dlg.Create(NULL, -1, _(
"Send Route to OpenCPN Peer") + _T(
"..." ),
1823 case ID_PASTE_WAYPOINT:
1824 pupHandler_PasteWaypoint();
1827 case ID_PASTE_ROUTE:
1828 pupHandler_PasteRoute();
1831 case ID_PASTE_TRACK:
1832 pupHandler_PasteTrack();
1835 case ID_RT_MENU_DELPOINT:
1836 if (m_pSelectedRoute) {
1839 pWayPointMan->DestroyWaypoint(m_pFoundRoutePoint);
1841 if (pRoutePropDialog && (pRoutePropDialog->IsShown())) {
1844 if (g_pRouteMan->IsRouteValid(m_pSelectedRoute)) {
1845 pRoutePropDialog->SetRouteAndUpdate(m_pSelectedRoute,
true);
1847 pRoutePropDialog->Hide();
1850 if (RouteManagerDialog::getInstanceFlag()) {
1851 if (pRouteManagerDialog && pRouteManagerDialog->IsShown()) {
1852 pRouteManagerDialog->UpdateWptListCtrl();
1853 pRouteManagerDialog->UpdateRouteListCtrl();
1857 gFrame->InvalidateAllGL();
1858 gFrame->RefreshAllCanvas(
true);
1863 case ID_RT_MENU_REMPOINT:
1864 if (m_pSelectedRoute) {
1866 g_pRouteMan->RemovePointFromRoute(m_pFoundRoutePoint, m_pSelectedRoute,
1867 parent->m_routeState);
1868 gFrame->InvalidateAllGL();
1869 gFrame->RefreshAllCanvas();
1873 case ID_RT_MENU_ACTPOINT:
1874 if (g_pRouteMan->GetpActiveRoute() == m_pSelectedRoute) {
1881 case ID_RT_MENU_DEACTPOINT:
1884 case ID_RT_MENU_ACTNXTPOINT:
1885 if (g_pRouteMan->GetpActiveRoute() == m_pSelectedRoute) {
1892 case ID_RT_MENU_PROPERTIES: {
1893 parent->ShowRoutePropertiesDialog(_(
"Route Properties"),
1898 case ID_TK_MENU_PROPERTIES: {
1899 parent->ShowTrackPropertiesDialog(m_pSelectedTrack);
1903 case ID_TK_MENU_DELETE: {
1904 int dlg_return = wxID_YES;
1905 if (g_bConfirmObjectDelete) {
1906 dlg_return = OCPNMessageBox(
1907 parent, _(
"Are you sure you want to delete this track?"),
1908 _(
"OpenCPN Track Delete"),
1909 (
long)wxYES_NO | wxCANCEL | wxYES_DEFAULT);
1912 if (dlg_return == wxID_YES) {
1913 if (m_pSelectedTrack == g_pActiveTrack)
1914 m_pSelectedTrack = parent->parent_frame->TrackOff();
1915 g_pAIS->DeletePersistentTrack(m_pSelectedTrack);
1917 NavObj_dB::GetInstance().DeleteTrack(m_pSelectedTrack);
1918 RoutemanGui(*g_pRouteMan).DeleteTrack(m_pSelectedTrack);
1920 if (TrackPropDlg::getInstanceFlag() && pTrackPropDialog &&
1921 (pTrackPropDialog->IsShown()) &&
1922 (m_pSelectedTrack == pTrackPropDialog->GetTrack())) {
1923 pTrackPropDialog->Hide();
1926 if (RoutePropDlgImpl::getInstanceFlag() && pRouteManagerDialog &&
1927 pRouteManagerDialog->IsShown()) {
1928 pRouteManagerDialog->UpdateTrkListCtrl();
1929 pRouteManagerDialog->UpdateRouteListCtrl();
1931 gFrame->InvalidateAllGL();
1932 gFrame->RefreshAllCanvas();
1937 case ID_TK_MENU_SENDTOPEER:
1938 if (m_pSelectedTrack) {
1940 dlg.SetTrack(m_pSelectedTrack);
1945 MdnsCache::GetInstance().
Validate();
1946 if (MdnsCache::GetInstance().GetCache().empty())
1947 dlg.SetScanOnCreate(
true);
1950 dlg.Create(NULL, -1, _(
"Send Track to OpenCPN Peer") + _T(
"..." ),
1956 case ID_RC_MENU_SCALE_IN:
1957 parent->parent_frame->DoStackDown(parent);
1959 parent->WarpPointer(r.x, r.y);
1962 case ID_RC_MENU_SCALE_OUT:
1963 parent->parent_frame->DoStackUp(parent);
1965 parent->WarpPointer(r.x, r.y);
1968 case ID_RC_MENU_ZOOM_IN:
1971 parent->WarpPointer(r.x, r.y);
1974 case ID_RC_MENU_ZOOM_OUT:
1977 parent->WarpPointer(r.x, r.y);
1980 case ID_RC_MENU_FINISH:
1981 parent->FinishRoute();
1983 parent->Refresh(
false);
1984 g_FlushNavobjChanges =
true;
1987 case ID_DEF_ZERO_XTE:
1988 g_pRouteMan->ZeroCurrentXTEToActivePoint();
1994 ArrayOfPlugInMenuItems item_array =
1995 g_pi_manager->GetPluginContextMenuItemArray();
1997 for (
unsigned int i = 0; i < item_array.GetCount(); i++) {
1999 int target_id = pimis->id;
2002 if (pimis->pmenu_item->GetSubMenu()) {
2003 const wxMenuItemList &items =
2004 pimis->pmenu_item->GetSubMenu()->GetMenuItems();
2005 for (wxMenuItemList::const_iterator it = items.begin();
2006 it != items.end(); ++it) {
2007 if ((*it)->GetId() ==
event.GetId()) {
2008 target_id = (*it)->GetId();
2014 if (pimis->m_pplugin && (target_id == event.GetId())) {
2017 if ((version_major * 100) + version_minor >= 120) {
2018 std::string object_type;
2019 std::string object_ident;
2021 if ((pimis->m_in_menu.IsSameAs(
"Waypoint")) && m_pFoundRoutePoint) {
2022 object_type =
"Waypoint";
2023 object_ident = m_pFoundRoutePoint->
m_GUID.ToStdString();
2024 }
else if ((pimis->m_in_menu.IsSameAs(
"Route")) &&
2026 object_type =
"Route";
2027 object_ident = m_pSelectedRoute->
m_GUID.ToStdString();
2028 }
else if ((pimis->m_in_menu.IsSameAs(
"Track")) &&
2030 object_type =
"Track";
2031 object_ident = m_pSelectedTrack->m_GUID.ToStdString();
2032 }
else if ((pimis->m_in_menu.IsSameAs(
"AIS")) && m_FoundAIS_MMSI) {
2033 object_type =
"AIS";
2034 wxString sAIS = wxString::Format(
"%d", m_FoundAIS_MMSI);
2035 object_ident = sAIS.ToStdString();
2041 ppi->OnContextMenuItemCallbackExt(target_id, object_ident,
2042 object_type, zlat, zlon);
2054 if ((event.GetId() >= ID_DEF_MENU_GROUPBASE) &&
2056 ID_DEF_MENU_GROUPBASE + (int)g_pGroupArray->GetCount())) {
2057 parent->SetGroupIndex(event.GetId() - ID_DEF_MENU_GROUPBASE);
2060 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.
virtual int GetAPIVersionMinor()
Returns the minor version number of the plugin API that this plugin supports.
virtual int GetAPIVersionMajor()
Returns the major version number of the plugin API that this plugin supports.
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.