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;
972 enum { WPMENU = 1, TKMENU = 2, RTMENU = 4, MMMENU = 8 };
974 if (!g_bBasicMenus && menuFocus != contextMenu) {
975 if (global_color_scheme != GLOBAL_COLOR_SCHEME_DUSK &&
976 global_color_scheme != GLOBAL_COLOR_SCHEME_NIGHT) {
977 menuFocus->AppendSeparator();
979 wxMenuItem *subMenu1;
980 if (menuWaypoint && menuFocus != menuWaypoint) {
982 menuFocus->AppendSubMenu(menuWaypoint, menuWaypoint->GetTitle());
983 SetMenuItemFont1(subMenu1);
986 menuWaypoint->SetTitle(wxEmptyString);
989 if (menuTrack && menuFocus != menuTrack) {
990 subMenu1 = menuFocus->AppendSubMenu(menuTrack, menuTrack->GetTitle());
991 SetMenuItemFont1(subMenu1);
994 menuTrack->SetTitle(wxEmptyString);
997 if (menuRoute && menuFocus != menuRoute) {
998 subMenu1 = menuFocus->AppendSubMenu(menuRoute, menuRoute->GetTitle());
999 SetMenuItemFont1(subMenu1);
1002 menuRoute->SetTitle(wxEmptyString);
1005 subMenu1 = menuFocus->AppendSubMenu(contextMenu, _(
"Main Menu"));
1006 SetMenuItemFont1(subMenu1);
1010 if (!subMenuChart->GetMenuItemCount()) contextMenu->Destroy(subItemChart);
1015 if (seltype & SELTYPE_TIDEPOINT) {
1016 menuFocus->AppendSeparator();
1018 MenuAppend1(menuFocus, ID_DEF_MENU_TIDEINFO, _(
"Show Tide Information"));
1021 if (seltype & SELTYPE_CURRENTPOINT) {
1022 if (!bsep) menuFocus->AppendSeparator();
1023 MenuAppend1(menuFocus, ID_DEF_MENU_CURRENTINFO,
1024 _(
"Show Current Information"));
1028 g_pi_manager->PrepareAllPluginContextMenus();
1031 ArrayOfPlugInMenuItems item_array =
1032 g_pi_manager->GetPluginContextMenuItemArray();
1034 for (
unsigned int i = 0; i < item_array.GetCount(); i++) {
1036 if (!pimis->b_viz)
continue;
1038 wxMenu *submenu = NULL;
1039 if (pimis->pmenu_item->GetSubMenu()) {
1040 submenu =
new wxMenu();
1041 const wxMenuItemList &items =
1042 pimis->pmenu_item->GetSubMenu()->GetMenuItems();
1043 for (wxMenuItemList::const_iterator it = items.begin(); it != items.end();
1046 for (
unsigned int j = 0; j < item_array.GetCount(); j++) {
1048 if (pimis->pmenu_item == *it)
id = pimis->id;
1051 wxMenuItem *pmi =
new wxMenuItem(submenu,
id,
1052#
if wxCHECK_VERSION(3, 0, 0)
1053 (*it)->GetItemLabelText(),
1057 (*it)->GetHelp(), (*it)->GetKind());
1060 pmi->SetFont(m_scaledFont);
1065 pmi->SetFont(sFont);
1068 PrepareMenuItem(pmi);
1069 submenu->Append(pmi);
1070 pmi->Check((*it)->IsChecked());
1074 wxMenuItem *pmi =
new wxMenuItem(contextMenu, pimis->id,
1075#
if wxCHECK_VERSION(3, 0, 0)
1076 pimis->pmenu_item->GetItemLabelText(),
1078 pimis->pmenu_item->GetLabel(),
1080 pimis->pmenu_item->GetHelp(),
1081 pimis->pmenu_item->GetKind(), submenu);
1083 pmi->SetFont(m_scaledFont);
1088 pmi->SetFont(sFont);
1091 PrepareMenuItem(pmi);
1093 wxMenu *dst = contextMenu;
1094 if (pimis->m_in_menu ==
"Waypoint")
1096 else if (pimis->m_in_menu ==
"Route")
1098 else if (pimis->m_in_menu ==
"Track")
1100 else if (pimis->m_in_menu ==
"AIS")
1105 dst->Enable(pimis->id, !pimis->b_grey);
1112 androidEnableBackButton(
false);
1113 androidEnableOptionsMenu(
false);
1121 parent->PopupMenu(menuFocus, x, y);
1124 androidEnableBackButton(
true);
1125 androidEnableOptionsMenu(
true);
1132 if (!(sub_menu & MMMENU))
delete contextMenu;
1133 if (!(sub_menu & RTMENU))
delete menuRoute;
1134 if (!(sub_menu & TKMENU))
delete menuTrack;
1135 if (!(sub_menu & WPMENU))
delete menuWaypoint;
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 pConfig->AddNewWayPoint(pWP, -1);
1229 if (RouteManagerDialog::getInstanceFlag()) {
1230 if (pRouteManagerDialog && pRouteManagerDialog->IsShown()) {
1231 pRouteManagerDialog->UpdateWptListCtrl();
1235 parent->undo->BeforeUndoableAction(Undo_CreateWaypoint, pWP,
1236 Undo_HasParent, NULL);
1237 parent->undo->AfterUndoableAction(NULL);
1238 gFrame->RefreshAllCanvas(
false);
1239 gFrame->InvalidateAllGL();
1240 g_FlushNavobjChanges =
true;
1244 case ID_DEF_MENU_NEW_RT: {
1245 parent->StartRoute();
1249 case ID_DEF_MENU_AISTARGETLIST:
1250 parent->ShowAISTargetList();
1253 case ID_DEF_MENU_AIS_CPAWARNING:
1254 parent->ToggleCPAWarn();
1257 case ID_WP_MENU_GOTO: {
1259 wxEmptyString, wxEmptyString);
1260 pSelect->AddSelectableRoutePoint(gLat, gLon, pWP_src);
1263 pRouteList->Append(temp_route);
1265 temp_route->AddPoint(pWP_src);
1266 temp_route->AddPoint(m_pFoundRoutePoint);
1267 m_pFoundRoutePoint->SetShared(
true);
1269 pSelect->AddSelectableRouteSegment(gLat, gLon, m_pFoundRoutePoint->m_lat,
1270 m_pFoundRoutePoint->m_lon, pWP_src,
1271 m_pFoundRoutePoint, temp_route);
1273 wxString name = m_pFoundRoutePoint->GetName();
1274 if (name.IsEmpty()) name = _(
"(Unnamed Waypoint)");
1275 wxString rteName = _(
"Go to ");
1276 rteName.Append(name);
1283 if (g_pRouteMan->GetpActiveRoute()) g_pRouteMan->DeactivateRoute();
1290 case ID_DEF_MENU_COGUP:
1291 parent->SetUpMode(COURSE_UP_MODE);
1294 case ID_DEF_MENU_HEADUP:
1295 parent->SetUpMode(HEAD_UP_MODE);
1298 case ID_DEF_MENU_NORTHUP:
1299 parent->SetUpMode(NORTH_UP_MODE);
1302 case ID_DEF_MENU_TOGGLE_FULL:
1303 gFrame->ToggleFullScreen();
1306 case ID_DEF_MENU_GOTOPOSITION:
1307 if (NULL == pGoToPositionDialog)
1310 pGoToPositionDialog->SetCanvas(parent);
1311 pGoToPositionDialog->CheckPasteBufferForPosition();
1312 pGoToPositionDialog->Show();
1315 case ID_WP_MENU_DELPOINT: {
1316 if (m_pFoundRoutePoint == pAnchorWatchPoint1) {
1317 pAnchorWatchPoint1 = NULL;
1319 }
else if (m_pFoundRoutePoint == pAnchorWatchPoint2) {
1320 pAnchorWatchPoint2 = NULL;
1324 if (m_pFoundRoutePoint && !(m_pFoundRoutePoint->
m_bIsInLayer) &&
1325 (m_pFoundRoutePoint->GetIconName() != _T(
"mob"))) {
1329 wxArrayPtrVoid *proute_array =
1332 pWayPointMan->DestroyWaypoint(m_pFoundRoutePoint);
1333 delete proute_array;
1335 parent->undo->BeforeUndoableAction(
1336 Undo_DeleteWaypoint, m_pFoundRoutePoint, Undo_IsOrphanded,
1338 pConfig->DeleteWayPoint(m_pFoundRoutePoint);
1339 pSelect->DeleteSelectablePoint(m_pFoundRoutePoint,
1340 SELTYPE_ROUTEPOINT);
1341 if (NULL != pWayPointMan)
1343 parent->undo->AfterUndoableAction(NULL);
1346 if (g_pMarkInfoDialog) {
1347 g_pMarkInfoDialog->ClearData();
1350 if (RouteManagerDialog::getInstanceFlag()) {
1351 if (pRouteManagerDialog) {
1352 if (pRouteManagerDialog->IsShown())
1353 pRouteManagerDialog->UpdateWptListCtrl();
1357 gFrame->RefreshAllCanvas(
false);
1358 gFrame->InvalidateAllGL();
1362 case ID_WP_MENU_PROPERTIES:
1363 parent->ShowMarkPropertiesDialog(m_pFoundRoutePoint);
1366 case ID_WP_MENU_CLEAR_ANCHORWATCH: {
1367 wxString guid = wxEmptyString;
1368 if (pAnchorWatchPoint1 == m_pFoundRoutePoint) {
1369 pAnchorWatchPoint1 = NULL;
1372 }
else if (pAnchorWatchPoint2 == m_pFoundRoutePoint) {
1373 pAnchorWatchPoint2 = NULL;
1377 if (!guid.IsEmpty()) {
1379 v[_T(
"GUID")] = guid;
1380 wxString msg_id(_T(
"OCPN_ANCHOR_WATCH_CLEARED"));
1381 SendJSONMessageToAllPlugins(msg_id, v);
1386 case ID_WP_MENU_SET_ANCHORWATCH: {
1387 wxString guid = wxEmptyString;
1388 if (pAnchorWatchPoint1 == NULL) {
1389 pAnchorWatchPoint1 = m_pFoundRoutePoint;
1390 g_AW1GUID = pAnchorWatchPoint1->
m_GUID;
1393 nn = m_pFoundRoutePoint->GetName();
1395 nn.Printf(_T(
"%d m"), g_nAWDefault);
1396 m_pFoundRoutePoint->SetName(nn);
1398 }
else if (pAnchorWatchPoint2 == NULL) {
1399 pAnchorWatchPoint2 = m_pFoundRoutePoint;
1400 g_AW2GUID = pAnchorWatchPoint2->
m_GUID;
1403 nn = m_pFoundRoutePoint->GetName();
1405 nn.Printf(_T(
"%d m"), g_nAWDefault);
1406 m_pFoundRoutePoint->SetName(nn);
1409 if (!guid.IsEmpty()) {
1411 v[_T(
"GUID")] = guid;
1412 wxString msg_id(_T(
"OCPN_ANCHOR_WATCH_SET"));
1413 SendJSONMessageToAllPlugins(msg_id, v);
1418 case ID_DEF_MENU_ACTIVATE_MEASURE:
1419 parent->StartMeasureRoute();
1422 case ID_DEF_MENU_DEACTIVATE_MEASURE:
1423 parent->CancelMeasureRoute();
1425 parent->InvalidateGL();
1426 parent->Refresh(
false);
1429 case ID_DEF_MENU_CM93OFFSET_DIALOG: {
1430 if (NULL == g_pCM93OffsetDialog) {
1435 if (!parent->GetVP().b_quilt && parent->m_singleChart &&
1436 (parent->m_singleChart->GetChartType() == CHART_TYPE_CM93COMP)) {
1440 if (g_pCM93OffsetDialog) {
1441 g_pCM93OffsetDialog->SetCM93Chart(pch);
1442 g_pCM93OffsetDialog->Show();
1443 g_pCM93OffsetDialog->UpdateMCOVRList(parent->GetVP());
1448 case ID_DEF_MENU_QUERY: {
1449 parent->ShowObjectQueryWindow(popx, popy, zlat, zlon);
1452 case ID_DEF_MENU_AIS_QUERY: {
1453 ShowAISTargetQueryDialog(parent, m_FoundAIS_MMSI);
1457 case ID_DEF_MENU_AIS_CPA: {
1458 auto myptarget = g_pAIS->Get_Target_Data_From_MMSI(m_FoundAIS_MMSI);
1459 if (myptarget) myptarget->Toggle_AIS_CPA();
1463 case ID_DEF_MENU_AISSHOWTRACK: {
1464 auto myptarget = g_pAIS->Get_Target_Data_From_MMSI(m_FoundAIS_MMSI);
1465 if (myptarget) myptarget->ToggleShowTrack();
1469 case ID_DEF_MENU_COPY_MMSI: {
1471 if (wxTheClipboard->Open()) {
1472 wxTheClipboard->SetData(
new wxTextDataObject(
1473 wxString::Format(wxT(
"%09d"), m_FoundAIS_MMSI)));
1474 wxTheClipboard->Close();
1479 case ID_DEF_MENU_QUILTREMOVE: {
1480 if (parent->GetVP().b_quilt) {
1481 int dbIndex = parent->m_pQuilt->GetChartdbIndexAtPix(
1482 parent->GetVP(), wxPoint(popx, popy));
1483 parent->RemoveChartFromQuilt(dbIndex);
1491 case ID_DEF_MENU_CURRENTINFO: {
1492 parent->DrawTCWindow(popx, popy, (
void *)m_pIDXCandidate);
1493 parent->Refresh(
false);
1498 case ID_DEF_MENU_TIDEINFO: {
1499 parent->DrawTCWindow(popx, popy, (
void *)m_pIDXCandidate);
1500 parent->Refresh(
false);
1505 case ID_DGB_MENU_NMEA_WINDOW:
1507 m_nmea_log->Raise();
1510 case ID_RT_MENU_REVERSE: {
1514 OCPNMessageBox(parent, g_pRouteMan->GetRouteReverseMessage(),
1515 _(
"Rename Waypoints?"), wxYES_NO | wxCANCEL);
1517 if (ask_return != wxID_CANCEL) {
1518 pSelect->DeleteAllSelectableRouteSegments(m_pSelectedRoute);
1519 m_pSelectedRoute->Reverse(ask_return == wxID_YES);
1520 pSelect->AddAllSelectableRouteSegments(m_pSelectedRoute);
1522 pConfig->UpdateRoute(m_pSelectedRoute);
1524 if (pRoutePropDialog && (pRoutePropDialog->IsShown())) {
1525 pRoutePropDialog->SetRouteAndUpdate(m_pSelectedRoute);
1528 gFrame->InvalidateAllGL();
1529 gFrame->RefreshAllCanvas();
1534 case ID_RT_MENU_SHOWNAMES: {
1535 if (m_pSelectedRoute) {
1536 m_pSelectedRoute->ShowWaypointNames(
1537 !m_pSelectedRoute->AreWaypointNamesVisible());
1543 case ID_RT_MENU_RESEQUENCE: {
1544 if (m_pSelectedRoute) {
1548 OCPNMessageBox(parent, g_pRouteMan->GetRouteResequenceMessage(),
1549 _(
"Rename Waypoints?"), wxYES_NO | wxCANCEL);
1551 if (ask_return != wxID_CANCEL) {
1552 m_pSelectedRoute->RenameRoutePoints();
1555 gFrame->InvalidateAllGL();
1556 gFrame->RefreshAllCanvas();
1562 case ID_RT_MENU_DELETE: {
1563 bool confirmed = RouteGui::OnDelete(parent);
1566 if (g_pRouteMan->GetpActiveRoute() == m_pSelectedRoute)
1567 g_pRouteMan->DeactivateRoute();
1572 NavObjectChanges::getInstance()))
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 pConfig->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 pConfig->AddNewRoute(m_pHead);
1698 pRouteList->Append(m_pTail);
1699 pConfig->AddNewRoute(m_pTail);
1701 pConfig->DeleteConfigRoute(m_pSelectedRoute);
1703 pSelect->DeleteAllSelectableRoutePoints(m_pSelectedRoute);
1704 pSelect->DeleteAllSelectableRouteSegments(m_pSelectedRoute);
1706 NavObjectChanges::getInstance());
1707 pSelect->AddAllSelectableRouteSegments(m_pTail);
1708 pSelect->AddAllSelectableRoutePoints(m_pTail);
1709 pSelect->AddAllSelectableRouteSegments(m_pHead);
1710 pSelect->AddAllSelectableRoutePoints(m_pHead);
1713 pRoutePropDialog->SetRouteAndUpdate(m_pHead);
1714 pRoutePropDialog->Show();
1716 if (RouteManagerDialog::getInstanceFlag() && pRouteManagerDialog &&
1717 (pRouteManagerDialog->IsShown()))
1718 pRouteManagerDialog->UpdateRouteListCtrl();
1721 case ID_RT_MENU_COPY:
1722 if (m_pSelectedRoute) Kml::CopyRouteToClipboard(m_pSelectedRoute);
1725 case ID_TK_MENU_COPY:
1726 if (m_pSelectedTrack) Kml::CopyTrackToClipboard(m_pSelectedTrack);
1729 case ID_WPT_MENU_COPY:
1730 if (m_pFoundRoutePoint) Kml::CopyWaypointToClipboard(m_pFoundRoutePoint);
1733 case ID_WPT_MENU_SENDTOGPS:
1734 if (m_pFoundRoutePoint) {
1735 if (parent->m_active_upload_port.Length())
1737 .SendToGPS(parent->m_active_upload_port.BeforeFirst(
' '), NULL);
1740 dlg.SetWaypoint(m_pFoundRoutePoint);
1744 dlg.Create(NULL, -1, _(
"Send to GPS") + _T(
"..." ), _T(
""));
1750 case ID_WPT_MENU_SENDTONEWGPS:
1751 if (m_pFoundRoutePoint) {
1753 dlg.SetWaypoint(m_pFoundRoutePoint);
1755 dlg.Create(NULL, -1, _(
"Send to GPS") + _T(
"..." ), _T(
""));
1760 case ID_WPT_MENU_SENDTOPEER:
1761 if (m_pFoundRoutePoint) {
1763 dlg.SetWaypoint(m_pFoundRoutePoint);
1768 MdnsCache::GetInstance().
Validate();
1769 if (MdnsCache::GetInstance().GetCache().empty())
1770 dlg.SetScanOnCreate(
true);
1773 dlg.Create(NULL, -1, _(
"Send Waypoint to OpenCPN Peer") + _T(
"..." ),
1779 case ID_RT_MENU_SENDTOGPS:
1780 if (m_pSelectedRoute) {
1781 if (parent->m_active_upload_port.Length())
1783 .SendToGPS(parent->m_active_upload_port.BeforeFirst(
' '),
true,
1787 dlg.SetRoute(m_pSelectedRoute);
1789 dlg.Create(NULL, -1, _(
"Send to GPS") + _T(
"..." ), _T(
""));
1795 case ID_RT_MENU_SENDTONEWGPS:
1796 if (m_pSelectedRoute) {
1798 dlg.SetRoute(m_pSelectedRoute);
1800 dlg.Create(NULL, -1, _(
"Send to GPS") + _T(
"..." ), _T(
""));
1805 case ID_RT_MENU_SENDTOPEER:
1806 if (m_pSelectedRoute) {
1808 dlg.SetRoute(m_pSelectedRoute);
1813 MdnsCache::GetInstance().
Validate();
1814 if (MdnsCache::GetInstance().GetCache().empty())
1815 dlg.SetScanOnCreate(
true);
1818 dlg.Create(NULL, -1, _(
"Send Route to OpenCPN Peer") + _T(
"..." ),
1824 case ID_PASTE_WAYPOINT:
1825 pupHandler_PasteWaypoint();
1828 case ID_PASTE_ROUTE:
1829 pupHandler_PasteRoute();
1832 case ID_PASTE_TRACK:
1833 pupHandler_PasteTrack();
1836 case ID_RT_MENU_DELPOINT:
1837 if (m_pSelectedRoute) {
1840 pWayPointMan->DestroyWaypoint(m_pFoundRoutePoint);
1842 if (pRoutePropDialog && (pRoutePropDialog->IsShown())) {
1845 if (g_pRouteMan->IsRouteValid(m_pSelectedRoute)) {
1846 pRoutePropDialog->SetRouteAndUpdate(m_pSelectedRoute,
true);
1848 pRoutePropDialog->Hide();
1851 if (RouteManagerDialog::getInstanceFlag()) {
1852 if (pRouteManagerDialog && pRouteManagerDialog->IsShown()) {
1853 pRouteManagerDialog->UpdateWptListCtrl();
1854 pRouteManagerDialog->UpdateRouteListCtrl();
1858 gFrame->InvalidateAllGL();
1859 gFrame->RefreshAllCanvas(
true);
1864 case ID_RT_MENU_REMPOINT:
1865 if (m_pSelectedRoute) {
1867 g_pRouteMan->RemovePointFromRoute(m_pFoundRoutePoint, m_pSelectedRoute,
1868 parent->m_routeState);
1869 gFrame->InvalidateAllGL();
1870 gFrame->RefreshAllCanvas();
1874 case ID_RT_MENU_ACTPOINT:
1875 if (g_pRouteMan->GetpActiveRoute() == m_pSelectedRoute) {
1882 case ID_RT_MENU_DEACTPOINT:
1885 case ID_RT_MENU_ACTNXTPOINT:
1886 if (g_pRouteMan->GetpActiveRoute() == m_pSelectedRoute) {
1893 case ID_RT_MENU_PROPERTIES: {
1894 parent->ShowRoutePropertiesDialog(_(
"Route Properties"),
1899 case ID_TK_MENU_PROPERTIES: {
1900 parent->ShowTrackPropertiesDialog(m_pSelectedTrack);
1904 case ID_TK_MENU_DELETE: {
1905 int dlg_return = wxID_YES;
1906 if (g_bConfirmObjectDelete) {
1907 dlg_return = OCPNMessageBox(
1908 parent, _(
"Are you sure you want to delete this track?"),
1909 _(
"OpenCPN Track Delete"),
1910 (
long)wxYES_NO | wxCANCEL | wxYES_DEFAULT);
1913 if (dlg_return == wxID_YES) {
1914 if (m_pSelectedTrack == g_pActiveTrack)
1915 m_pSelectedTrack = parent->parent_frame->TrackOff();
1916 g_pAIS->DeletePersistentTrack(m_pSelectedTrack);
1918 NavObj_dB::GetInstance().DeleteTrack(m_pSelectedTrack);
1919 RoutemanGui(*g_pRouteMan).DeleteTrack(m_pSelectedTrack);
1921 if (TrackPropDlg::getInstanceFlag() && pTrackPropDialog &&
1922 (pTrackPropDialog->IsShown()) &&
1923 (m_pSelectedTrack == pTrackPropDialog->GetTrack())) {
1924 pTrackPropDialog->Hide();
1927 if (RoutePropDlgImpl::getInstanceFlag() && pRouteManagerDialog &&
1928 pRouteManagerDialog->IsShown()) {
1929 pRouteManagerDialog->UpdateTrkListCtrl();
1930 pRouteManagerDialog->UpdateRouteListCtrl();
1932 gFrame->InvalidateAllGL();
1933 gFrame->RefreshAllCanvas();
1938 case ID_TK_MENU_SENDTOPEER:
1939 if (m_pSelectedTrack) {
1941 dlg.SetTrack(m_pSelectedTrack);
1946 MdnsCache::GetInstance().
Validate();
1947 if (MdnsCache::GetInstance().GetCache().empty())
1948 dlg.SetScanOnCreate(
true);
1951 dlg.Create(NULL, -1, _(
"Send Track to OpenCPN Peer") + _T(
"..." ),
1957 case ID_RC_MENU_SCALE_IN:
1958 parent->parent_frame->DoStackDown(parent);
1960 parent->WarpPointer(r.x, r.y);
1963 case ID_RC_MENU_SCALE_OUT:
1964 parent->parent_frame->DoStackUp(parent);
1966 parent->WarpPointer(r.x, r.y);
1969 case ID_RC_MENU_ZOOM_IN:
1972 parent->WarpPointer(r.x, r.y);
1975 case ID_RC_MENU_ZOOM_OUT:
1978 parent->WarpPointer(r.x, r.y);
1981 case ID_RC_MENU_FINISH:
1982 parent->FinishRoute();
1984 parent->Refresh(
false);
1985 g_FlushNavobjChanges =
true;
1988 case ID_DEF_ZERO_XTE:
1989 g_pRouteMan->ZeroCurrentXTEToActivePoint();
1995 ArrayOfPlugInMenuItems item_array =
1996 g_pi_manager->GetPluginContextMenuItemArray();
1998 for (
unsigned int i = 0; i < item_array.GetCount(); i++) {
2001 if (pimis->id == event.GetId()) {
2002 if (pimis->m_pplugin)
2013 if ((event.GetId() >= ID_DEF_MENU_GROUPBASE) &&
2015 ID_DEF_MENU_GROUPBASE + (
int)g_pGroupArray->GetCount())) {
2016 parent->SetGroupIndex(event.GetId() - ID_DEF_MENU_GROUPBASE);
2019 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.
bool m_bIsInLayer
Flag indicating whether this route belongs to a layer.
int m_lastMousePointIndex
Index of the most recently interacted with route point.
bool ActivateRoutePoint(Route *pA, RoutePoint *pRP)
Activates a specific waypoint within a route for navigation.
wxArrayPtrVoid * GetRouteArrayContaining(RoutePoint *pWP)
Find all routes that contain the given waypoint.
bool ActivateNextPoint(Route *pr, bool skipped)
Activates the next waypoint in a route when the current waypoint is reached.
bool DeleteRoute(Route *pRoute, NavObjectChanges *nav_obj_changes)
bool ActivateRoute(Route *pRouteToActivate, RoutePoint *pStartPoint=NULL)
Activates a route for navigation.
Dialog for sending routes/waypoints to a GPS device.
Dialog for sending navigation objects to peer devices.
Represents a track, which is a series of connected track points.
bool RemoveRoutePoint(RoutePoint *prp)
Remove a routepoint from list if present, deallocate it all cases.
Represents a composite CM93 chart covering multiple scales.
virtual void OnContextMenuItemCallback(int id)
Handles context menu item selection.
The JSON value class implementation.
Hooks into gui available in model.
wxFont * GetOCPNScaledFont(wxString item, int default_size)
Retrieves a font from FontMgr, optionally scaled for physical readability.
wxFont GetOCPNGUIScaledFont(wxString item)
Retrieves a font optimized for touch and high-resolution interfaces.
MdnsCache mDNS host lookups cache.
Tools to send data to plugins.