27#include <wx/aui/aui.h>
28#include <wx/clipbrd.h>
29#include <wx/dynarray.h>
33#include <wx/graphics.h>
35#include <wx/listbook.h>
40#include "model/ais_target_data.h"
42#include "model/georef.h"
45#include "model/own_ship.h"
47#include "model/route.h"
48#include "model/routeman.h"
49#include "model/select.h"
50#include "model/track.h"
58#include "GoToPositionDialog.h"
61#include "ocpn_frame.h"
62#include "OCPNPlatform.h"
63#include "peer_client_dlg.h"
67#include "routemanagerdialog.h"
68#include "routeman_gui.h"
69#include "route_point_gui.h"
70#include "RoutePropDlgImpl.h"
73#include "SendToGpsDlg.h"
74#include "SendToPeerDlg.h"
78#include "TrackPropDlg.h"
83#include "androidUTIL.h"
88 ID_DEF_MENU_MAX_DETAIL = 1,
90 ID_DEF_MENU_SCALE_OUT,
94 ID_DEF_MENU_MOVE_BOAT_HERE,
95 ID_DEF_MENU_GOTO_HERE,
96 ID_DEF_MENU_GOTOPOSITION,
99 ID_WP_MENU_PROPERTIES,
101 ID_RT_MENU_DEACTIVATE,
105 ID_RT_MENU_SPLIT_LEG,
106 ID_RT_MENU_SPLIT_WPT,
109 ID_WPT_MENU_SENDTOGPS,
110 ID_WPT_MENU_SENDTONEWGPS,
111 ID_WPT_MENU_SENDTOPEER,
119 ID_RT_MENU_DEACTPOINT,
120 ID_RT_MENU_ACTNXTPOINT,
122 ID_RT_MENU_PROPERTIES,
123 ID_RT_MENU_SENDTOGPS,
124 ID_RT_MENU_SENDTONEWGPS,
125 ID_RT_MENU_SHOWNAMES,
126 ID_RT_MENU_RESEQUENCE,
127 ID_RT_MENU_SENDTOPEER,
128 ID_WP_MENU_SET_ANCHORWATCH,
129 ID_WP_MENU_CLEAR_ANCHORWATCH,
130 ID_DEF_MENU_AISTARGETLIST,
131 ID_DEF_MENU_AIS_CPAWARNING,
134 ID_RC_MENU_SCALE_OUT,
138 ID_DEF_MENU_AIS_QUERY,
140 ID_DEF_MENU_AISSHOWTRACK,
141 ID_DEF_MENU_ACTIVATE_MEASURE,
142 ID_DEF_MENU_DEACTIVATE_MEASURE,
143 ID_DEF_MENU_COPY_MMSI,
148 ID_DEF_MENU_CM93OFFSET_DIALOG,
150 ID_TK_MENU_PROPERTIES,
152 ID_TK_MENU_SENDTOPEER,
153 ID_WP_MENU_ADDITIONAL_INFO,
155 ID_DEF_MENU_QUILTREMOVE,
159 ID_DEF_MENU_TOGGLE_FULL,
160 ID_DEF_MENU_TIDEINFO,
161 ID_DEF_MENU_CURRENTINFO,
165 ID_DGB_MENU_NMEA_WINDOW,
167 ID_DEF_MENU_GROUPBASE,
176int CanvasMenuHandler::GetNextContextMenuId() {
177 return ID_DEF_MENU_LAST +
181wxFont CanvasMenuHandler::m_scaledFont;
184CanvasMenuHandler::CanvasMenuHandler(
ChartCanvas *parentCanvas,
187 int selectedAIS_MMSI,
188 void *selectedTCIndex, wxWindow *nmea_log)
189 : m_nmea_log(nmea_log) {
190 parent = parentCanvas;
191 m_pSelectedRoute = selectedRoute;
192 m_pSelectedTrack = selectedTrack;
193 m_pFoundRoutePoint = selectedPoint;
194 m_FoundAIS_MMSI = selectedAIS_MMSI;
195 m_pIDXCandidate = selectedTCIndex;
196 if (!m_scaledFont.IsOk()) {
198 m_scaledFont = *qFont;
204CanvasMenuHandler::~CanvasMenuHandler() {}
210void CanvasMenuHandler::PrepareMenuItem(wxMenuItem *item) {
211#if defined(__WXMSW__)
212 wxColour ctrl_back_color = GetGlobalColor(
"DILG1");
213 item->SetBackgroundColour(ctrl_back_color);
214 wxColour menu_text_color = GetGlobalColor(_T (
"UITX1" ));
215 item->SetTextColour(menu_text_color);
219void CanvasMenuHandler::MenuPrepend1(wxMenu *menu,
int id, wxString label) {
220 wxMenuItem *item =
new wxMenuItem(menu,
id, label);
221#if defined(__WXMSW__)
222 item->SetFont(m_scaledFont);
227 item->SetFont(sFont);
230 PrepareMenuItem(item);
232 if (g_btouch) menu->InsertSeparator(0);
236void CanvasMenuHandler::MenuAppend1(wxMenu *menu,
int id, wxString label) {
237 wxMenuItem *item =
new wxMenuItem(menu,
id, label);
238#if defined(__WXMSW__)
239 item->SetFont(m_scaledFont);
244 item->SetFont(sFont);
247 PrepareMenuItem(item);
250 if (g_btouch) menu->AppendSeparator();
253void CanvasMenuHandler::SetMenuItemFont1(wxMenuItem *item) {
254#if defined(__WXMSW__)
255 item->SetFont(m_scaledFont);
258#if defined(__ANDROID__)
260 item->SetFont(*qFont);
263 PrepareMenuItem(item);
266void CanvasMenuHandler::CanvasPopupMenu(
int x,
int y,
int seltype) {
267 wxMenu *contextMenu =
new wxMenu;
268 wxMenu *menuWaypoint = NULL;
269 wxMenu *menuRoute = NULL;
270 wxMenu *menuTrack = NULL;
271 wxMenu *menuAIS = NULL;
273 wxMenu *subMenuChart =
new wxMenu;
274 wxMenu *subMenuUndo =
new wxMenu(
"Undo...Ctrl-Z");
277 wxMenu *subMenuRedo =
new wxMenu(
"Redo...Shift-Ctrl-Z");
279 wxMenu *subMenuRedo =
new wxMenu(
"Redo...Ctrl-Y");
281 wxMenu *subMenuDebug =
new wxMenu(
"");
282 MenuAppend1(subMenuDebug, ID_DGB_MENU_NMEA_WINDOW, _(
"Show Data Monitor"));
284 wxMenu *menuFocus = contextMenu;
289 if (!g_bBasicMenus || (seltype != SELTYPE_ROUTECREATE)) {
290 bool bsubMenus =
false;
293 if (parent->undo->AnythingToUndo()) {
295 wxMenuItem *subMenuItemundo =
296 contextMenu->AppendSubMenu(subMenuUndo, _(
"Undo"));
299 undoItem << _(
"Undo") <<
" "
300 << parent->undo->GetNextUndoableAction()->Description();
301 MenuAppend1(subMenuUndo, ID_UNDO, undoItem);
303 if (parent->undo->AnythingToRedo()) {
305 wxMenuItem *subMenuItemRedo =
306 contextMenu->AppendSubMenu(subMenuRedo, _(
"Redo"));
309 redoItem << _(
"Redo") <<
" "
310 << parent->undo->GetNextRedoableAction()->Description();
311 MenuAppend1(subMenuRedo, ID_REDO, redoItem);
314 if (parent->undo->AnythingToUndo()) {
316 undoItem << _(
"Undo") <<
" "
317 << parent->undo->GetNextUndoableAction()->Description();
318 MenuAppend1(contextMenu, ID_UNDO, _menuText(undoItem,
"Ctrl-Z"));
321 if (parent->undo->AnythingToRedo()) {
323 redoItem << _(
"Redo") <<
" "
324 << parent->undo->GetNextRedoableAction()->Description();
326 MenuAppend1(contextMenu, ID_REDO, _menuText(redoItem,
"Shift-Ctrl-Z"));
328 MenuAppend1(contextMenu, ID_REDO, _menuText(redoItem,
"Ctrl-Y"));
334 if (seltype == SELTYPE_ROUTECREATE) {
335 MenuAppend1(contextMenu, ID_RC_MENU_FINISH,
336 _menuText(_(
"End Route"),
"Esc"));
339 if (!parent->m_pMouseRoute) {
340 if (parent->m_bMeasure_Active)
341 MenuAppend1(contextMenu, ID_DEF_MENU_DEACTIVATE_MEASURE,
342 _menuText(_(
"Measure Off"),
"Esc"));
344 MenuAppend1(contextMenu, ID_DEF_MENU_ACTIVATE_MEASURE,
345 _menuText(_(
"Measure"),
"M"));
348 bool ais_areanotice =
false;
349 if (g_pAIS && parent->GetShowAIS() && g_bShowAreaNotices) {
352 for (
const auto &target : g_pAIS->GetAreaNoticeSourcesList()) {
353 auto target_data = target.second;
354 if (!target_data->area_notices.empty()) {
355 for (
auto &ani : target_data->area_notices) {
359 for (Ais8_001_22_SubAreaList::iterator sa =
360 area_notice.sub_areas.begin();
361 sa != area_notice.sub_areas.end(); ++sa) {
363 case AIS8_001_22_SHAPE_CIRCLE: {
364 wxPoint target_point;
367 bbox.Expand(target_point);
368 if (sa->radius_m > 0.0) bbox.EnLarge(sa->radius_m * vp_scale);
371 case AIS8_001_22_SHAPE_RECT:
372 case AIS8_001_22_SHAPE_POLYGON:
373 case AIS8_001_22_SHAPE_POLYLINE: {
374 double lat = sa->latitude;
375 double lon = sa->longitude;
376 for (
int i = 0; i < 4; ++i) {
377 ll_gc_ll(lat, lon, sa->angles[i], sa->dists_m[i] / 1852.0,
379 wxPoint target_point;
381 bbox.Expand(target_point);
385 case AIS8_001_22_SHAPE_SECTOR: {
386 double lat1 = sa->latitude;
387 double lon1 = sa->longitude;
389 wxPoint target_point;
391 bbox.Expand(target_point);
392 for (
int i = 0; i < 18; ++i) {
396 i * (sa->right_bound_deg - sa->left_bound_deg) / 18,
397 sa->radius_m / 1852.0, &lat, &lon);
399 bbox.Expand(target_point);
401 ll_gc_ll(lat1, lon1, sa->right_bound_deg, sa->radius_m / 1852.0,
404 bbox.Expand(target_point);
410 if (bbox.GetValid() && bbox.PointInBox(x, y)) {
411 ais_areanotice =
true;
420 if (parent->GetpCurrentStack())
421 nChartStack = parent->GetpCurrentStack()->nEntry;
423 if (!parent->GetVP().b_quilt) {
424 if (nChartStack > 1) {
425 MenuAppend1(contextMenu, ID_DEF_MENU_MAX_DETAIL, _(
"Max Detail Here"));
426 MenuAppend1(contextMenu, ID_DEF_MENU_SCALE_IN,
427 _menuText(_(
"Scale In"),
"Ctrl-Left"));
428 MenuAppend1(contextMenu, ID_DEF_MENU_SCALE_OUT,
429 _menuText(_(
"Scale Out"),
"Ctrl-Right"));
432 if ((parent->m_singleChart &&
433 (parent->m_singleChart->GetChartFamily() == CHART_FAMILY_VECTOR)) ||
435 MenuAppend1(contextMenu, ID_DEF_MENU_QUERY,
436 _(
"Object Query") + _T(
"..." ));
441 parent->m_pQuilt->GetChartAtPix(parent->GetVP(), wxPoint(x, y));
442 if ((pChartTest && (pChartTest->GetChartFamily() == CHART_FAMILY_VECTOR)) ||
444 MenuAppend1(contextMenu, ID_DEF_MENU_QUERY,
445 _(
"Object Query") + _T(
"..." ));
448 if (!g_bBasicMenus && (nChartStack > 1)) {
449 MenuAppend1(contextMenu, ID_DEF_MENU_SCALE_IN,
450 _menuText(_(
"Scale In"),
"Ctrl-Left"));
451 MenuAppend1(contextMenu, ID_DEF_MENU_SCALE_OUT,
452 _menuText(_(
"Scale Out"),
"Ctrl-Right"));
458 if (!g_bBasicMenus || (seltype != SELTYPE_ROUTECREATE)) {
459 bool b_dm_add =
true;
460 if (g_btouch && parent->IsMeasureActive()) b_dm_add =
false;
463 MenuAppend1(contextMenu, ID_DEF_MENU_DROP_WP,
464 _menuText(_(
"Drop Mark"),
"Ctrl-M"));
465 MenuAppend1(contextMenu, ID_DEF_MENU_NEW_RT,
466 _menuText(_(
"New Route..."),
"Ctrl-R"));
470 MenuAppend1(contextMenu, ID_DEF_MENU_MOVE_BOAT_HERE, _(
"Move Boat Here"));
473 if (!g_bBasicMenus && !g_pRouteMan->GetpActiveRoute() &&
474 (!(seltype & SELTYPE_MARKPOINT) ||
475 (m_pFoundRoutePoint && m_pFoundRoutePoint->
m_bIsInLayer)))
476 MenuAppend1(contextMenu, ID_DEF_MENU_GOTO_HERE, _(
"Navigate To Here"));
479 MenuAppend1(contextMenu, ID_DEF_MENU_GOTOPOSITION,
480 _(
"Center view") +
"...");
482 if (!g_bBasicMenus) {
483 if (parent->GetVP().b_quilt) {
484 if (parent->GetUpMode() == NORTH_UP_MODE) {
485 MenuAppend1(contextMenu, ID_DEF_MENU_COGUP, _(
"Course Up Mode"));
486 if (!std::isnan(gHdt))
487 MenuAppend1(contextMenu, ID_DEF_MENU_HEADUP, _(
"Heading Up Mode"));
489 MenuAppend1(contextMenu, ID_DEF_MENU_NORTHUP, _(
"North Up Mode"));
492 if (parent->m_singleChart &&
493 (fabs(parent->m_singleChart->GetChartSkew()) > .01) && !g_bskew_comp)
494 MenuAppend1(contextMenu, ID_DEF_MENU_NORTHUP, _(
"Chart Up Mode"));
496 MenuAppend1(contextMenu, ID_DEF_MENU_NORTHUP, _(
"North Up Mode"));
500 if (!g_bBasicMenus) {
501 bool full_toggle_added =
false;
504 MenuAppend1(contextMenu, ID_DEF_MENU_TOGGLE_FULL,
505 _(
"Toggle Full Screen"));
506 full_toggle_added =
true;
509 if (!full_toggle_added) {
511 MenuAppend1(contextMenu, ID_DEF_MENU_TOGGLE_FULL,
512 _(
"Toggle Full Screen"));
516 if (g_pRouteMan->IsAnyRouteActive() &&
517 g_pRouteMan->GetCurrentXTEToActivePoint() > 0.)
518 MenuAppend1(contextMenu, ID_DEF_ZERO_XTE, _(
"Zero XTE"));
521 int pasteBuffer = kml->ParsePasteBuffer();
522 if (pasteBuffer != KML_PASTE_INVALID) {
523 switch (pasteBuffer) {
524 case KML_PASTE_WAYPOINT: {
525 MenuAppend1(contextMenu, ID_PASTE_WAYPOINT, _(
"Paste Waypoint"));
528 case KML_PASTE_ROUTE: {
529 MenuAppend1(contextMenu, ID_PASTE_ROUTE, _(
"Paste Route"));
532 case KML_PASTE_TRACK: {
533 MenuAppend1(contextMenu, ID_PASTE_TRACK, _(
"Paste Track"));
536 case KML_PASTE_ROUTE_TRACK: {
537 MenuAppend1(contextMenu, ID_PASTE_ROUTE, _(
"Paste Route"));
538 MenuAppend1(contextMenu, ID_PASTE_TRACK, _(
"Paste Track"));
545 if (!parent->GetVP().b_quilt && parent->m_singleChart &&
546 (parent->m_singleChart->GetChartType() == CHART_TYPE_CM93COMP)) {
547 MenuAppend1(contextMenu, ID_DEF_MENU_CM93OFFSET_DIALOG,
548 _(
"CM93 Offset Dialog..."));
572 wxMenuItem *subItemChart =
573 contextMenu->AppendSubMenu(subMenuChart, _(
"Chart Groups"));
574 if (g_btouch) contextMenu->AppendSeparator();
576 SetMenuItemFont1(subItemChart);
580 MenuAppend1(subMenuChart, wxID_CANCEL, _(
"temporary"));
582 wxMenuItem *subItem0 = subMenuChart->AppendRadioItem(
583 ID_DEF_MENU_GROUPBASE, _(
"All Active Charts"));
585 SetMenuItemFont1(subItem0);
587 for (
unsigned int i = 0; i <
g_pGroupArray->GetCount(); i++) {
588 subItem0 = subMenuChart->AppendRadioItem(
589 ID_DEF_MENU_GROUPBASE + i + 1,
g_pGroupArray->Item(i)->m_group_name);
590 SetMenuItemFont1(subItem0);
594 subMenuChart->Remove(wxID_CANCEL);
596 subMenuChart->Check(ID_DEF_MENU_GROUPBASE + parent->m_groupIndex,
true);
600 menuFocus = contextMenu;
603 if (!g_bBasicMenus || (seltype != SELTYPE_ROUTECREATE)) {
605 if (parent->GetShowAIS() && (seltype & SELTYPE_AISTARGET)) {
606 auto myptarget = g_pAIS->Get_Target_Data_From_MMSI(m_FoundAIS_MMSI);
607 if (!g_bBasicMenus && myptarget) {
608 name = myptarget->GetFullName();
609 if (name.IsEmpty()) name.Printf(
"%d", m_FoundAIS_MMSI);
610 name.Prepend(
" ( ").Append(
" )");
612 name = wxEmptyString;
613 menuAIS =
new wxMenu(_(
"AIS") + name);
614 MenuAppend1(menuAIS, ID_DEF_MENU_AIS_QUERY, _(
"Target Query..."));
615 if (myptarget && myptarget->bCPA_Valid &&
616 (myptarget->n_alert_state != AIS_ALERT_SET)) {
617 if (myptarget->b_show_AIS_CPA)
618 MenuAppend1(menuAIS, ID_DEF_MENU_AIS_CPA, _(
"Hide Target CPA"));
620 MenuAppend1(menuAIS, ID_DEF_MENU_AIS_CPA, _(
"Show Target CPA"));
622 MenuAppend1(menuAIS, ID_DEF_MENU_AISTARGETLIST, _(
"Target List..."));
623 if (myptarget->Class != AIS_METEO ) {
624 if (myptarget && !myptarget->b_PersistTrack) {
625 if (myptarget->b_show_track)
626 MenuAppend1(menuAIS, ID_DEF_MENU_AISSHOWTRACK,
627 _(
"Hide Target Track"));
629 MenuAppend1(menuAIS, ID_DEF_MENU_AISSHOWTRACK,
630 _(
"Show Target Track"));
634 MenuAppend1(menuAIS, ID_DEF_MENU_COPY_MMSI, _(
"Copy Target MMSI"));
635 menuAIS->AppendSeparator();
637 if (!parent->GetVP().b_quilt) {
638 if ((parent->m_singleChart &&
639 (parent->m_singleChart->GetChartFamily() ==
640 CHART_FAMILY_VECTOR))) {
641 MenuAppend1(menuAIS, ID_DEF_MENU_QUERY, _(
"Object Query..."));
646 parent->m_pQuilt->GetChartAtPix(parent->GetVP(), wxPoint(x, y));
648 (pChartTest->GetChartFamily() == CHART_FAMILY_VECTOR))) {
649 MenuAppend1(menuAIS, ID_DEF_MENU_QUERY, _(
"Object Query..."));
655 bool enable_list =
true;
657 double char_x = gFrame->GetSize().x / gFrame->GetCharWidth();
658 double char_y = gFrame->GetSize().y / gFrame->GetCharWidth();
659 double char_min = wxMin(char_x, char_y);
660 if (char_min < 100) enable_list =
false;
664 if (wxMin(size_x, size_y) < 100)
668 MenuAppend1(contextMenu, ID_DEF_MENU_AISTARGETLIST,
669 _(
"AIS target list") +
"...");
671 wxString nextCPAstatus = g_bCPAWarn ? _(
"Hide") : _(
"Show");
672 MenuAppend1(contextMenu, ID_DEF_MENU_AIS_CPAWARNING,
673 _menuText(nextCPAstatus +
" " + _(
"CPA alarm "),
"W"));
677 if (g_enable_root_menu_debug) {
678 wxMenuItem *subItemDebug =
679 contextMenu->AppendSubMenu(subMenuDebug, _(
"Debug"));
680 if (g_btouch) contextMenu->AppendSeparator();
681 SetMenuItemFont1(subItemDebug);
684 if (seltype & SELTYPE_ROUTESEGMENT) {
685 if (!g_bBasicMenus && m_pSelectedRoute) {
687 if (name.IsEmpty()) name = _(
"Unnamed Route");
688 name.Prepend(
" ( ").Append(
" )");
690 name = wxEmptyString;
692 if (m_pSelectedRoute && m_pSelectedRoute->
m_bIsInLayer) blay =
true;
695 menuRoute =
new wxMenu(_(
"Layer Route") + name);
696 MenuAppend1(menuRoute, ID_RT_MENU_PROPERTIES,
697 _(
"Properties") + _T(
"..." ));
698 if (m_pSelectedRoute) {
699 if (m_pSelectedRoute->IsActive()) {
700 int indexActive = m_pSelectedRoute->GetIndexOf(
702 if ((indexActive + 1) <= m_pSelectedRoute->GetnPoints()) {
703 MenuAppend1(menuRoute, ID_RT_MENU_ACTNXTPOINT,
704 _(
"Activate Next Waypoint"));
706 MenuAppend1(menuRoute, ID_RT_MENU_DEACTIVATE, _(
"Deactivate"));
707 MenuAppend1(menuRoute, ID_DEF_ZERO_XTE, _(
"Zero XTE"));
709 MenuAppend1(menuRoute, ID_RT_MENU_ACTIVATE, _(
"Activate"));
713 menuRoute =
new wxMenu(_(
"Route") + name);
714 MenuAppend1(menuRoute, ID_RT_MENU_PROPERTIES,
715 _(
"Properties") + _T(
"..." ));
716 if (m_pSelectedRoute) {
717 if (m_pSelectedRoute->IsActive()) {
718 int indexActive = m_pSelectedRoute->GetIndexOf(
720 if ((indexActive + 1) <= m_pSelectedRoute->GetnPoints()) {
721 MenuAppend1(menuRoute, ID_RT_MENU_ACTNXTPOINT,
722 _(
"Activate Next Waypoint"));
724 MenuAppend1(menuRoute, ID_RT_MENU_DEACTIVATE, _(
"Deactivate"));
725 MenuAppend1(menuRoute, ID_DEF_ZERO_XTE, _(
"Zero XTE"));
727 MenuAppend1(menuRoute, ID_RT_MENU_ACTIVATE, _(
"Activate"));
730 MenuAppend1(menuRoute, ID_RT_MENU_INSERT, _(
"Insert Waypoint"));
731 MenuAppend1(menuRoute, ID_RT_MENU_APPEND, _(
"Append Waypoint"));
732 if (!(seltype & SELTYPE_ROUTEPOINT) && m_pSelectedRoute) {
733 m_SelectedIdx = m_pSelectedRoute->GetIndexOf(m_pFoundRoutePoint);
734 if (m_SelectedIdx > 1 &&
735 m_SelectedIdx < m_pSelectedRoute->GetnPoints() - 1)
736 MenuAppend1(menuRoute, ID_RT_MENU_SPLIT_LEG, _(
"Split around Leg"));
738 MenuAppend1(menuRoute, ID_RT_MENU_COPY, _(
"Copy as KML") + _T(
"..." ));
739 MenuAppend1(menuRoute, ID_RT_MENU_DELETE, _(
"Delete") + _T(
"..." ));
740 MenuAppend1(menuRoute, ID_RT_MENU_REVERSE, _(
"Reverse..."));
741 if (m_pSelectedRoute) {
742 if (m_pSelectedRoute->AreWaypointNamesVisible())
743 MenuAppend1(menuRoute, ID_RT_MENU_SHOWNAMES,
744 _(
"Hide Waypoint Names"));
746 MenuAppend1(menuRoute, ID_RT_MENU_SHOWNAMES,
747 _(
"Show Waypoint Names"));
749 MenuAppend1(menuRoute, ID_RT_MENU_RESEQUENCE,
750 _(
"Resequence Waypoints..."));
753 wxString port = parent->FindValidUploadPort();
754 parent->m_active_upload_port = port;
755 wxString item = _(
"Send to GPS");
756 if (!port.IsEmpty()) {
761 MenuAppend1(menuRoute, ID_RT_MENU_SENDTOGPS, item);
763 if (!port.IsEmpty()) {
764 wxString item = _(
"Send to new GPS");
765 MenuAppend1(menuRoute, ID_RT_MENU_SENDTONEWGPS, item);
768 wxString itemstp = SYMBOL_STP_TITLE;
769 MenuAppend1(menuRoute, ID_RT_MENU_SENDTOPEER, itemstp);
772 if (menuFocus != menuAIS) menuFocus = menuRoute;
775 if (seltype & SELTYPE_TRACKSEGMENT) {
776 name = wxEmptyString;
777 if (!g_bBasicMenus && m_pSelectedTrack)
778 name =
" ( " + m_pSelectedTrack->GetName(
true) +
" )";
780 name = wxEmptyString;
782 if (m_pSelectedTrack && m_pSelectedTrack->m_bIsInLayer) blay =
true;
785 menuTrack =
new wxMenu(_(
"Layer Track") + name);
786 MenuAppend1(menuTrack, ID_TK_MENU_PROPERTIES,
787 _(
"Properties") + _T(
"..." ));
789 menuTrack =
new wxMenu(_(
"Track") + name);
790 MenuAppend1(menuTrack, ID_TK_MENU_PROPERTIES,
791 _(
"Properties") + _T(
"..." ));
792 MenuAppend1(menuTrack, ID_TK_MENU_COPY, _(
"Copy as KML"));
793 MenuAppend1(menuTrack, ID_TK_MENU_DELETE, _(
"Delete") + _T(
"..." ));
796 wxString itemstp = SYMBOL_STP_TITLE;
797 MenuAppend1(menuTrack, ID_TK_MENU_SENDTOPEER, itemstp);
800 if (menuFocus != menuAIS) menuFocus = menuTrack;
803 if (seltype & SELTYPE_ROUTEPOINT) {
804 if (!g_bBasicMenus && m_pFoundRoutePoint) {
805 name = m_pFoundRoutePoint->GetName();
806 if (name.IsEmpty()) name = _(
"Unnamed Waypoint");
807 name.Prepend(
" ( ").Append(
" )");
809 name = wxEmptyString;
811 if (m_pFoundRoutePoint && m_pFoundRoutePoint->
m_bIsInLayer) blay =
true;
814 menuWaypoint =
new wxMenu(_(
"Layer Waypoint") + name);
815 MenuAppend1(menuWaypoint, ID_WP_MENU_PROPERTIES,
816 _(
"Properties") + _T(
"..." ));
818 if (m_pSelectedRoute && m_pSelectedRoute->IsActive())
819 MenuAppend1(menuWaypoint, ID_RT_MENU_ACTPOINT, _(
"Activate"));
821 menuWaypoint =
new wxMenu(_(
"Waypoint") + name);
822 MenuAppend1(menuWaypoint, ID_WP_MENU_PROPERTIES,
823 _(
"Properties") + _T(
"..." ));
824 if (m_pSelectedRoute && m_pSelectedRoute->IsActive()) {
826 MenuAppend1(menuWaypoint, ID_RT_MENU_ACTPOINT, _(
"Activate"));
829 if (m_pSelectedRoute && m_pSelectedRoute->IsActive()) {
831 int indexActive = m_pSelectedRoute->GetIndexOf(
833 if ((indexActive + 1) <= m_pSelectedRoute->GetnPoints())
834 MenuAppend1(menuWaypoint, ID_RT_MENU_ACTNXTPOINT,
835 _(
"Activate Next Waypoint"));
838 if (m_pSelectedRoute && m_pSelectedRoute->GetnPoints() > 2) {
839 MenuAppend1(menuWaypoint, ID_RT_MENU_REMPOINT, _(
"Remove from Route"));
841 m_SelectedIdx = m_pSelectedRoute->GetIndexOf(m_pFoundRoutePoint);
842 if (m_SelectedIdx > 1 && m_SelectedIdx < m_pSelectedRoute->GetnPoints())
843 MenuAppend1(menuWaypoint, ID_RT_MENU_SPLIT_WPT,
844 _(
"Split Route at Waypoint"));
847 MenuAppend1(menuWaypoint, ID_WPT_MENU_COPY, _(
"Copy as KML"));
849 if (m_pFoundRoutePoint && m_pFoundRoutePoint->GetIconName() !=
"mob")
850 MenuAppend1(menuWaypoint, ID_RT_MENU_DELPOINT, _(
"Delete"));
853 wxString port = parent->FindValidUploadPort();
854 parent->m_active_upload_port = port;
855 wxString item = _(
"Send to GPS");
856 if (!port.IsEmpty()) {
861 MenuAppend1(menuWaypoint, ID_WPT_MENU_SENDTOGPS, item);
863 if (!port.IsEmpty()) {
864 wxString item = _(
"Send to new GPS");
865 MenuAppend1(menuWaypoint, ID_WPT_MENU_SENDTONEWGPS, item);
868 MenuAppend1(menuWaypoint, ID_WPT_MENU_SENDTOPEER,
873 if (menuFocus != menuAIS) menuFocus = menuWaypoint;
876 if (seltype & SELTYPE_MARKPOINT) {
877 if (!g_bBasicMenus && m_pFoundRoutePoint) {
878 name = m_pFoundRoutePoint->GetName();
879 if (name.IsEmpty()) name = _(
"Unnamed Mark");
880 name.Prepend(
" ( ").Append(
" )");
882 name = wxEmptyString;
884 if (m_pFoundRoutePoint && m_pFoundRoutePoint->
m_bIsInLayer) blay =
true;
887 menuWaypoint =
new wxMenu(_(
"Layer Waypoint") + name);
888 MenuAppend1(menuWaypoint, ID_WP_MENU_PROPERTIES,
889 _(
"Properties") + _T(
"..." ));
891 menuWaypoint =
new wxMenu(_(
"Mark") + name);
892 MenuAppend1(menuWaypoint, ID_WP_MENU_PROPERTIES,
893 _(
"Properties") + _T(
"..." ));
895 if (!g_pRouteMan->GetpActiveRoute())
896 MenuAppend1(menuWaypoint, ID_WP_MENU_GOTO, _(
"Navigate To This"));
898 MenuAppend1(menuWaypoint, ID_WPT_MENU_COPY, _(
"Copy as KML"));
900 if (m_pFoundRoutePoint && m_pFoundRoutePoint->GetIconName() !=
"mob")
901 MenuAppend1(menuWaypoint, ID_WP_MENU_DELPOINT, _(
"Delete"));
904 wxString port = parent->FindValidUploadPort();
905 parent->m_active_upload_port = port;
906 wxString item = _(
"Send to GPS");
907 if (!port.IsEmpty()) {
912 MenuAppend1(menuWaypoint, ID_WPT_MENU_SENDTOGPS, item);
914 MenuAppend1(menuWaypoint, ID_WPT_MENU_SENDTOPEER,
918 if ((m_pFoundRoutePoint == pAnchorWatchPoint1) ||
919 (m_pFoundRoutePoint == pAnchorWatchPoint2))
920 MenuAppend1(menuWaypoint, ID_WP_MENU_CLEAR_ANCHORWATCH,
921 _(
"Clear Anchor Watch"));
923 if (m_pFoundRoutePoint && !(m_pFoundRoutePoint->
m_bIsInLayer) &&
924 ((NULL == pAnchorWatchPoint1) || (NULL == pAnchorWatchPoint2))) {
927 DistanceBearingMercator(m_pFoundRoutePoint->m_lat,
928 m_pFoundRoutePoint->m_lon, gLat, gLon, &brg,
930 if (dist * 1852. <= g_nAWMax)
931 MenuAppend1(menuWaypoint, ID_WP_MENU_SET_ANCHORWATCH,
932 _(
"Set Anchor Watch"));
937 if (menuFocus != menuAIS) menuFocus = menuWaypoint;
941 AddPluginContextMenuItems(contextMenu, menuRoute, menuTrack, menuWaypoint,
945 enum { WPMENU = 1, TKMENU = 2, RTMENU = 4, MMMENU = 8 };
947 if (!g_bBasicMenus && menuFocus != contextMenu) {
948 if (global_color_scheme != GLOBAL_COLOR_SCHEME_DUSK &&
949 global_color_scheme != GLOBAL_COLOR_SCHEME_NIGHT) {
950 menuFocus->AppendSeparator();
953 wxMenuItem *subMenu1;
954 if (menuWaypoint && menuFocus != menuWaypoint) {
956 menuFocus->AppendSubMenu(menuWaypoint, menuWaypoint->GetTitle());
957 SetMenuItemFont1(subMenu1);
960 menuWaypoint->SetTitle(wxEmptyString);
963 if (menuTrack && menuFocus != menuTrack) {
964 subMenu1 = menuFocus->AppendSubMenu(menuTrack, menuTrack->GetTitle());
965 SetMenuItemFont1(subMenu1);
968 menuTrack->SetTitle(wxEmptyString);
971 if (menuRoute && menuFocus != menuRoute) {
972 subMenu1 = menuFocus->AppendSubMenu(menuRoute, menuRoute->GetTitle());
973 SetMenuItemFont1(subMenu1);
976 menuRoute->SetTitle(wxEmptyString);
979 subMenu1 = menuFocus->AppendSubMenu(contextMenu, _(
"Main Menu"));
980 SetMenuItemFont1(subMenu1);
984 if (!subMenuChart->GetMenuItemCount()) contextMenu->Destroy(subItemChart);
989 if (seltype & SELTYPE_TIDEPOINT) {
990 menuFocus->AppendSeparator();
992 MenuAppend1(menuFocus, ID_DEF_MENU_TIDEINFO, _(
"Show Tide Information"));
995 if (seltype & SELTYPE_CURRENTPOINT) {
996 if (!bsep) menuFocus->AppendSeparator();
997 MenuAppend1(menuFocus, ID_DEF_MENU_CURRENTINFO,
998 _(
"Show Current Information"));
1004 androidEnableBackButton(
false);
1005 androidEnableOptionsMenu(
false);
1013 parent->PopupMenu(menuFocus, x, y);
1016 androidEnableBackButton(
true);
1017 androidEnableOptionsMenu(
true);
1024 if (!(sub_menu & MMMENU))
delete contextMenu;
1025 if (!(sub_menu & RTMENU))
delete menuRoute;
1026 if (!(sub_menu & TKMENU))
delete menuTrack;
1027 if (!(sub_menu & WPMENU))
delete menuWaypoint;
1030void CanvasMenuHandler::AddPluginContextMenuItems(wxMenu *contextMenu,
1033 wxMenu *menuWaypoint,
1036 g_pi_manager->PrepareAllPluginContextMenus();
1039 ArrayOfPlugInMenuItems item_array =
1040 g_pi_manager->GetPluginContextMenuItemArray();
1042 for (
unsigned int i = 0; i < item_array.GetCount(); i++) {
1044 if (!pimis->b_viz)
continue;
1046 wxMenu *submenu = NULL;
1047 if (pimis->pmenu_item->GetSubMenu()) {
1049 auto submenu_proto = pimis->pmenu_item->GetSubMenu();
1050 submenu =
new wxMenu();
1051 const wxMenuItemList &items =
1052 pimis->pmenu_item->GetSubMenu()->GetMenuItems();
1053 for (wxMenuItemList::const_iterator it = items.begin(); it != items.end();
1055 int id = (*it)->GetId();
1057 new wxMenuItem(submenu,
id, (*it)->GetItemLabelText(),
1058 (*it)->GetHelp(), (*it)->GetKind());
1061 psmi->SetFont(m_scaledFont);
1066 psmi->SetFont(sFont);
1069 PrepareMenuItem(psmi);
1070 submenu->Append(psmi);
1071 psmi->Check((*it)->IsChecked());
1075 wxMenuItem *pmi =
new wxMenuItem(
1076 contextMenu, pimis->id, pimis->pmenu_item->GetItemLabelText(),
1077 pimis->pmenu_item->GetHelp(), pimis->pmenu_item->GetKind(), submenu);
1079 pmi->SetFont(m_scaledFont);
1084 pmi->SetFont(sFont);
1087 PrepareMenuItem(pmi);
1089 wxMenu *dst = contextMenu;
1090 if (pimis->m_in_menu ==
"Waypoint")
1092 else if (pimis->m_in_menu ==
"Route")
1094 else if (pimis->m_in_menu ==
"Track")
1096 else if (pimis->m_in_menu ==
"AIS")
1101 dst->Enable(pimis->id, !pimis->b_grey);
1106void CanvasMenuHandler::PopupMenuHandler(wxCommandEvent &event) {
1113 bool dupFirstWpt =
true, showRPD;
1118 switch (event.GetId()) {
1119 case ID_DEF_MENU_MAX_DETAIL:
1122 parent->ClearbFollow();
1124 parent->parent_frame->DoChartUpdate();
1126 parent->SelectChartFromStack(0,
false, CHART_TYPE_DONTCARE,
1127 CHART_FAMILY_RASTER);
1130 case ID_DEF_MENU_SCALE_IN:
1131 parent->DoCanvasStackDelta(-1);
1134 case ID_DEF_MENU_SCALE_OUT:
1135 parent->DoCanvasStackDelta(1);
1139 parent->undo->UndoLastAction();
1140 parent->InvalidateGL();
1141 parent->Refresh(
false);
1145 parent->undo->RedoNextAction();
1146 parent->InvalidateGL();
1147 parent->Refresh(
false);
1150 case ID_DEF_MENU_MOVE_BOAT_HERE:
1153 gFrame->UpdateStatusBar();
1156 case ID_DEF_MENU_GOTO_HERE: {
1158 wxEmptyString, wxEmptyString);
1159 pSelect->AddSelectableRoutePoint(zlat, zlon, pWP_dest);
1162 wxEmptyString, wxEmptyString);
1163 pSelect->AddSelectableRoutePoint(gLat, gLon, pWP_src);
1166 pRouteList->Append(temp_route);
1168 temp_route->AddPoint(pWP_src);
1169 temp_route->AddPoint(pWP_dest);
1171 pSelect->AddSelectableRouteSegment(gLat, gLon, zlat, zlon, pWP_src,
1172 pWP_dest, temp_route);
1181 if (g_pRouteMan->GetpActiveRoute()) g_pRouteMan->DeactivateRoute();
1188 case ID_DEF_MENU_DROP_WP: {
1190 wxEmptyString, wxEmptyString);
1192 pSelect->AddSelectableRoutePoint(zlat, zlon, pWP);
1193 NavObj_dB::GetInstance().InsertRoutePoint(pWP);
1198 if (RouteManagerDialog::getInstanceFlag()) {
1199 if (pRouteManagerDialog && pRouteManagerDialog->IsShown()) {
1200 pRouteManagerDialog->UpdateWptListCtrl();
1204 parent->undo->BeforeUndoableAction(Undo_CreateWaypoint, pWP,
1205 Undo_HasParent, NULL);
1206 parent->undo->AfterUndoableAction(NULL);
1207 gFrame->RefreshAllCanvas(
false);
1208 gFrame->InvalidateAllGL();
1209 g_FlushNavobjChanges =
true;
1213 case ID_DEF_MENU_NEW_RT: {
1214 parent->StartRoute();
1218 case ID_DEF_MENU_AISTARGETLIST:
1219 parent->ShowAISTargetList();
1222 case ID_DEF_MENU_AIS_CPAWARNING:
1223 parent->ToggleCPAWarn();
1226 case ID_WP_MENU_GOTO: {
1228 wxEmptyString, wxEmptyString);
1229 pSelect->AddSelectableRoutePoint(gLat, gLon, pWP_src);
1232 pRouteList->Append(temp_route);
1234 temp_route->AddPoint(pWP_src);
1235 temp_route->AddPoint(m_pFoundRoutePoint);
1236 m_pFoundRoutePoint->SetShared(
true);
1238 pSelect->AddSelectableRouteSegment(gLat, gLon, m_pFoundRoutePoint->m_lat,
1239 m_pFoundRoutePoint->m_lon, pWP_src,
1240 m_pFoundRoutePoint, temp_route);
1242 wxString name = m_pFoundRoutePoint->GetName();
1243 if (name.IsEmpty()) name = _(
"(Unnamed Waypoint)");
1244 wxString rteName = _(
"Go to ");
1245 rteName.Append(name);
1252 if (g_pRouteMan->GetpActiveRoute()) g_pRouteMan->DeactivateRoute();
1259 case ID_DEF_MENU_COGUP:
1260 parent->SetUpMode(COURSE_UP_MODE);
1263 case ID_DEF_MENU_HEADUP:
1264 parent->SetUpMode(HEAD_UP_MODE);
1267 case ID_DEF_MENU_NORTHUP:
1268 parent->SetUpMode(NORTH_UP_MODE);
1271 case ID_DEF_MENU_TOGGLE_FULL:
1272 gFrame->ToggleFullScreen();
1275 case ID_DEF_MENU_GOTOPOSITION:
1276 if (NULL == pGoToPositionDialog)
1279 pGoToPositionDialog->SetCanvas(parent);
1280 pGoToPositionDialog->CheckPasteBufferForPosition();
1281 pGoToPositionDialog->Show();
1284 case ID_WP_MENU_DELPOINT: {
1285 if (m_pFoundRoutePoint == pAnchorWatchPoint1) {
1286 pAnchorWatchPoint1 = NULL;
1288 }
else if (m_pFoundRoutePoint == pAnchorWatchPoint2) {
1289 pAnchorWatchPoint2 = NULL;
1293 if (m_pFoundRoutePoint && !(m_pFoundRoutePoint->
m_bIsInLayer) &&
1294 (m_pFoundRoutePoint->GetIconName() !=
"mob")) {
1298 wxArrayPtrVoid *proute_array =
1301 pWayPointMan->DestroyWaypoint(m_pFoundRoutePoint);
1302 delete proute_array;
1304 parent->undo->BeforeUndoableAction(
1305 Undo_DeleteWaypoint, m_pFoundRoutePoint, Undo_IsOrphanded,
1307 NavObj_dB::GetInstance().DeleteRoutePoint(m_pFoundRoutePoint);
1308 pSelect->DeleteSelectablePoint(m_pFoundRoutePoint,
1309 SELTYPE_ROUTEPOINT);
1310 if (NULL != pWayPointMan)
1312 parent->undo->AfterUndoableAction(NULL);
1315 if (g_pMarkInfoDialog) {
1316 g_pMarkInfoDialog->ClearData();
1319 if (RouteManagerDialog::getInstanceFlag()) {
1320 if (pRouteManagerDialog) {
1321 if (pRouteManagerDialog->IsShown())
1322 pRouteManagerDialog->UpdateWptListCtrl();
1326 gFrame->RefreshAllCanvas(
false);
1327 gFrame->InvalidateAllGL();
1331 case ID_WP_MENU_PROPERTIES:
1332 parent->ShowMarkPropertiesDialog(m_pFoundRoutePoint);
1335 case ID_WP_MENU_CLEAR_ANCHORWATCH: {
1336 wxString guid = wxEmptyString;
1337 if (pAnchorWatchPoint1 == m_pFoundRoutePoint) {
1338 pAnchorWatchPoint1 = NULL;
1341 }
else if (pAnchorWatchPoint2 == m_pFoundRoutePoint) {
1342 pAnchorWatchPoint2 = NULL;
1346 if (!guid.IsEmpty()) {
1349 wxString msg_id(
"OCPN_ANCHOR_WATCH_CLEARED");
1350 SendJSONMessageToAllPlugins(msg_id, v);
1355 case ID_WP_MENU_SET_ANCHORWATCH: {
1356 wxString guid = wxEmptyString;
1357 if (pAnchorWatchPoint1 == NULL) {
1358 pAnchorWatchPoint1 = m_pFoundRoutePoint;
1359 g_AW1GUID = pAnchorWatchPoint1->
m_GUID;
1362 nn = m_pFoundRoutePoint->GetName();
1364 nn.Printf(
"%d m", g_nAWDefault);
1365 m_pFoundRoutePoint->SetName(nn);
1367 }
else if (pAnchorWatchPoint2 == NULL) {
1368 pAnchorWatchPoint2 = m_pFoundRoutePoint;
1369 g_AW2GUID = pAnchorWatchPoint2->
m_GUID;
1372 nn = m_pFoundRoutePoint->GetName();
1374 nn.Printf(
"%d m", g_nAWDefault);
1375 m_pFoundRoutePoint->SetName(nn);
1378 if (!guid.IsEmpty()) {
1381 wxString msg_id(
"OCPN_ANCHOR_WATCH_SET");
1382 SendJSONMessageToAllPlugins(msg_id, v);
1387 case ID_DEF_MENU_ACTIVATE_MEASURE:
1388 parent->StartMeasureRoute();
1391 case ID_DEF_MENU_DEACTIVATE_MEASURE:
1392 parent->CancelMeasureRoute();
1394 parent->InvalidateGL();
1395 parent->Refresh(
false);
1398 case ID_DEF_MENU_CM93OFFSET_DIALOG: {
1404 if (!parent->GetVP().b_quilt && parent->m_singleChart &&
1405 (parent->m_singleChart->GetChartType() == CHART_TYPE_CM93COMP)) {
1417 case ID_DEF_MENU_QUERY: {
1418 parent->ShowObjectQueryWindow(popx, popy, zlat, zlon);
1421 case ID_DEF_MENU_AIS_QUERY: {
1422 ShowAISTargetQueryDialog(parent, m_FoundAIS_MMSI);
1426 case ID_DEF_MENU_AIS_CPA: {
1427 auto myptarget = g_pAIS->Get_Target_Data_From_MMSI(m_FoundAIS_MMSI);
1428 if (myptarget) myptarget->Toggle_AIS_CPA();
1432 case ID_DEF_MENU_AISSHOWTRACK: {
1433 auto myptarget = g_pAIS->Get_Target_Data_From_MMSI(m_FoundAIS_MMSI);
1434 if (myptarget) myptarget->ToggleShowTrack();
1438 case ID_DEF_MENU_COPY_MMSI: {
1440 if (wxTheClipboard->Open()) {
1441 wxTheClipboard->SetData(
1442 new wxTextDataObject(wxString::Format(
"%09d", m_FoundAIS_MMSI)));
1443 wxTheClipboard->Close();
1448 case ID_DEF_MENU_QUILTREMOVE: {
1449 if (parent->GetVP().b_quilt) {
1450 int dbIndex = parent->m_pQuilt->GetChartdbIndexAtPix(
1451 parent->GetVP(), wxPoint(popx, popy));
1452 parent->RemoveChartFromQuilt(dbIndex);
1460 case ID_DEF_MENU_CURRENTINFO: {
1461 parent->
DrawTCWindow(popx, popy, (
void *)m_pIDXCandidate);
1462 parent->Refresh(
false);
1467 case ID_DEF_MENU_TIDEINFO: {
1468 parent->
DrawTCWindow(popx, popy, (
void *)m_pIDXCandidate);
1469 parent->Refresh(
false);
1474 case ID_DGB_MENU_NMEA_WINDOW:
1476 m_nmea_log->Raise();
1479 case ID_RT_MENU_REVERSE: {
1483 OCPNMessageBox(parent, g_pRouteMan->GetRouteReverseMessage(),
1484 _(
"Rename Waypoints?"), wxYES_NO | wxCANCEL);
1486 if (ask_return != wxID_CANCEL) {
1487 pSelect->DeleteAllSelectableRouteSegments(m_pSelectedRoute);
1488 m_pSelectedRoute->Reverse(ask_return == wxID_YES);
1489 pSelect->AddAllSelectableRouteSegments(m_pSelectedRoute);
1491 NavObj_dB::GetInstance().UpdateRoute(m_pSelectedRoute);
1493 if (pRoutePropDialog && (pRoutePropDialog->IsShown())) {
1494 pRoutePropDialog->SetRouteAndUpdate(m_pSelectedRoute);
1497 gFrame->InvalidateAllGL();
1498 gFrame->RefreshAllCanvas();
1503 case ID_RT_MENU_SHOWNAMES: {
1504 if (m_pSelectedRoute) {
1505 m_pSelectedRoute->ShowWaypointNames(
1506 !m_pSelectedRoute->AreWaypointNamesVisible());
1512 case ID_RT_MENU_RESEQUENCE: {
1513 if (m_pSelectedRoute) {
1517 OCPNMessageBox(parent, g_pRouteMan->GetRouteResequenceMessage(),
1518 _(
"Rename Waypoints?"), wxYES_NO | wxCANCEL);
1520 if (ask_return != wxID_CANCEL) {
1521 m_pSelectedRoute->RenameRoutePoints();
1524 gFrame->InvalidateAllGL();
1525 gFrame->RefreshAllCanvas();
1531 case ID_RT_MENU_DELETE: {
1532 bool confirmed = RouteGui::OnDelete(parent);
1535 if (g_pRouteMan->GetpActiveRoute() == m_pSelectedRoute)
1536 g_pRouteMan->DeactivateRoute();
1540 NavObj_dB::GetInstance().DeleteRoute(m_pSelectedRoute);
1541 if (!g_pRouteMan->
DeleteRoute(m_pSelectedRoute))
break;
1543 if (RouteManagerDialog::getInstanceFlag()) {
1544 if (pRouteManagerDialog && pRouteManagerDialog->IsShown())
1545 pRouteManagerDialog->UpdateRouteListCtrl();
1548 if (g_pMarkInfoDialog && g_pMarkInfoDialog->IsShown()) {
1549 g_pMarkInfoDialog->ValidateMark();
1550 g_pMarkInfoDialog->UpdateProperties();
1553 parent->undo->InvalidateUndo();
1555 gFrame->InvalidateAllGL();
1556 gFrame->RefreshAllCanvas();
1561 case ID_RT_MENU_ACTIVATE: {
1562 if (g_pRouteMan->GetpActiveRoute()) g_pRouteMan->DeactivateRoute();
1568 if (m_pSelectedRoute) {
1570 best_point = g_pRouteMan->FindBestActivatePoint(
1571 m_pSelectedRoute, gLat, gLon, gCog, gSog);
1573 best_point = m_pSelectedRoute->GetPoint(2);
1582 case ID_RT_MENU_DEACTIVATE:
1583 g_pRouteMan->DeactivateRoute();
1588 case ID_RT_MENU_INSERT: {
1590 bool rename =
false;
1591 m_pSelectedRoute->InsertPointAfter(m_pFoundRoutePoint, zlat, zlon,
1594 pSelect->DeleteAllSelectableRoutePoints(m_pSelectedRoute);
1595 pSelect->DeleteAllSelectableRouteSegments(m_pSelectedRoute);
1597 pSelect->AddAllSelectableRouteSegments(m_pSelectedRoute);
1598 pSelect->AddAllSelectableRoutePoints(m_pSelectedRoute);
1611 NavObj_dB::GetInstance().UpdateRoute(m_pSelectedRoute);
1613 if (pRoutePropDialog && (pRoutePropDialog->IsShown())) {
1614 pRoutePropDialog->SetRouteAndUpdate(m_pSelectedRoute,
true);
1620 case ID_RT_MENU_APPEND:
1624 parent->m_pMouseRoute = m_pSelectedRoute;
1625 parent->m_routeState = m_pSelectedRoute->GetnPoints() + 1;
1627 m_pSelectedRoute->GetnPoints();
1628 parent->m_pMouseRoute->SetHiLite(50);
1630 pLast = m_pSelectedRoute->GetLastPoint();
1632 parent->m_prev_rlat = pLast->m_lat;
1633 parent->m_prev_rlon = pLast->m_lon;
1634 parent->m_prev_pMousePoint = pLast;
1636 parent->m_bAppendingRoute =
true;
1638 parent->SetCursor(*parent->pCursorPencil);
1640 androidSetRouteAnnunciator(
true);
1643 parent->HideGlobalToolbar();
1647 case ID_RT_MENU_SPLIT_LEG:
1649 dupFirstWpt =
false;
1650 case ID_RT_MENU_SPLIT_WPT:
1652 showRPD = (pRoutePropDialog && pRoutePropDialog->IsShown());
1654 if (g_pRouteMan->GetpActiveRoute() == m_pSelectedRoute)
1655 g_pRouteMan->DeactivateRoute();
1657 m_pHead =
new Route();
1658 m_pTail =
new Route();
1659 m_pHead->CloneRoute(m_pSelectedRoute, 1, m_SelectedIdx, _(
"_A"));
1660 m_pTail->CloneRoute(m_pSelectedRoute, m_SelectedIdx + splitMode,
1661 m_pSelectedRoute->GetnPoints(), _(
"_B"), dupFirstWpt);
1662 pRouteList->Append(m_pHead);
1663 NavObj_dB::GetInstance().InsertRoute(m_pHead);
1665 pRouteList->Append(m_pTail);
1666 NavObj_dB::GetInstance().InsertRoute(m_pTail);
1668 NavObj_dB::GetInstance().DeleteRoute(m_pSelectedRoute);
1670 pSelect->DeleteAllSelectableRoutePoints(m_pSelectedRoute);
1671 pSelect->DeleteAllSelectableRouteSegments(m_pSelectedRoute);
1673 pSelect->AddAllSelectableRouteSegments(m_pTail);
1674 pSelect->AddAllSelectableRoutePoints(m_pTail);
1675 pSelect->AddAllSelectableRouteSegments(m_pHead);
1676 pSelect->AddAllSelectableRoutePoints(m_pHead);
1679 pRoutePropDialog->SetRouteAndUpdate(m_pHead);
1680 pRoutePropDialog->Show();
1682 if (RouteManagerDialog::getInstanceFlag() && pRouteManagerDialog &&
1683 (pRouteManagerDialog->IsShown()))
1684 pRouteManagerDialog->UpdateRouteListCtrl();
1687 case ID_RT_MENU_COPY:
1688 if (m_pSelectedRoute) Kml::CopyRouteToClipboard(m_pSelectedRoute);
1691 case ID_TK_MENU_COPY:
1692 if (m_pSelectedTrack) Kml::CopyTrackToClipboard(m_pSelectedTrack);
1695 case ID_WPT_MENU_COPY:
1696 if (m_pFoundRoutePoint) Kml::CopyWaypointToClipboard(m_pFoundRoutePoint);
1699 case ID_WPT_MENU_SENDTOGPS:
1700 if (m_pFoundRoutePoint) {
1701 if (parent->m_active_upload_port.Length())
1703 .SendToGPS(parent->m_active_upload_port.BeforeFirst(
' '), NULL);
1706 dlg.SetWaypoint(m_pFoundRoutePoint);
1710 dlg.Create(NULL, -1, _(
"Send to GPS") + _T(
"..." ),
"");
1716 case ID_WPT_MENU_SENDTONEWGPS:
1717 if (m_pFoundRoutePoint) {
1719 dlg.SetWaypoint(m_pFoundRoutePoint);
1721 dlg.Create(NULL, -1, _(
"Send to GPS") + _T(
"..." ),
"");
1726 case ID_WPT_MENU_SENDTOPEER:
1727 if (m_pFoundRoutePoint) {
1729 dlg.SetWaypoint(m_pFoundRoutePoint);
1734 MdnsCache::GetInstance().
Validate();
1735 if (MdnsCache::GetInstance().GetCache().empty())
1736 dlg.SetScanOnCreate(
true);
1739 dlg.Create(NULL, -1, _(
"Send Waypoint to OpenCPN Peer") + _T(
"..." ),
1745 case ID_RT_MENU_SENDTOGPS:
1746 if (m_pSelectedRoute) {
1747 if (parent->m_active_upload_port.Length())
1749 .SendToGPS(parent->m_active_upload_port.BeforeFirst(
' '),
true,
1753 dlg.SetRoute(m_pSelectedRoute);
1755 dlg.Create(NULL, -1, _(
"Send to GPS") + _T(
"..." ),
"");
1761 case ID_RT_MENU_SENDTONEWGPS:
1762 if (m_pSelectedRoute) {
1764 dlg.SetRoute(m_pSelectedRoute);
1766 dlg.Create(NULL, -1, _(
"Send to GPS") + _T(
"..." ),
"");
1771 case ID_RT_MENU_SENDTOPEER:
1772 if (m_pSelectedRoute) {
1774 dlg.SetRoute(m_pSelectedRoute);
1779 MdnsCache::GetInstance().
Validate();
1780 if (MdnsCache::GetInstance().GetCache().empty())
1781 dlg.SetScanOnCreate(
true);
1784 dlg.Create(NULL, -1, _(
"Send Route to OpenCPN Peer") + _T(
"..." ),
"");
1789 case ID_PASTE_WAYPOINT:
1790 pupHandler_PasteWaypoint();
1793 case ID_PASTE_ROUTE:
1794 pupHandler_PasteRoute();
1797 case ID_PASTE_TRACK:
1798 pupHandler_PasteTrack();
1801 case ID_RT_MENU_DELPOINT:
1802 if (m_pSelectedRoute) {
1805 pWayPointMan->DestroyWaypoint(m_pFoundRoutePoint);
1807 if (pRoutePropDialog && (pRoutePropDialog->IsShown())) {
1810 if (g_pRouteMan->IsRouteValid(m_pSelectedRoute)) {
1811 pRoutePropDialog->SetRouteAndUpdate(m_pSelectedRoute,
true);
1813 pRoutePropDialog->Hide();
1816 if (RouteManagerDialog::getInstanceFlag()) {
1817 if (pRouteManagerDialog && pRouteManagerDialog->IsShown()) {
1818 pRouteManagerDialog->UpdateWptListCtrl();
1819 pRouteManagerDialog->UpdateRouteListCtrl();
1823 gFrame->InvalidateAllGL();
1824 gFrame->RefreshAllCanvas(
true);
1829 case ID_RT_MENU_REMPOINT:
1830 if (m_pSelectedRoute) {
1832 g_pRouteMan->RemovePointFromRoute(m_pFoundRoutePoint, m_pSelectedRoute,
1833 parent->m_routeState);
1834 gFrame->InvalidateAllGL();
1835 gFrame->RefreshAllCanvas();
1839 case ID_RT_MENU_ACTPOINT:
1840 if (g_pRouteMan->GetpActiveRoute() == m_pSelectedRoute) {
1847 case ID_RT_MENU_DEACTPOINT:
1850 case ID_RT_MENU_ACTNXTPOINT:
1851 if (g_pRouteMan->GetpActiveRoute() == m_pSelectedRoute) {
1858 case ID_RT_MENU_PROPERTIES: {
1859 parent->ShowRoutePropertiesDialog(_(
"Route Properties"),
1864 case ID_TK_MENU_PROPERTIES: {
1865 parent->ShowTrackPropertiesDialog(m_pSelectedTrack);
1869 case ID_TK_MENU_DELETE: {
1870 int dlg_return = wxID_YES;
1871 if (g_bConfirmObjectDelete) {
1872 dlg_return = OCPNMessageBox(
1873 parent, _(
"Are you sure you want to delete this track?"),
1874 _(
"OpenCPN Track Delete"),
1875 (
long)wxYES_NO | wxCANCEL | wxYES_DEFAULT);
1878 if (dlg_return == wxID_YES) {
1879 if (m_pSelectedTrack == g_pActiveTrack)
1880 m_pSelectedTrack = parent->parent_frame->TrackOff();
1881 g_pAIS->DeletePersistentTrack(m_pSelectedTrack);
1883 NavObj_dB::GetInstance().DeleteTrack(m_pSelectedTrack);
1884 RoutemanGui(*g_pRouteMan).DeleteTrack(m_pSelectedTrack);
1886 if (TrackPropDlg::getInstanceFlag() && pTrackPropDialog &&
1887 (pTrackPropDialog->IsShown()) &&
1888 (m_pSelectedTrack == pTrackPropDialog->GetTrack())) {
1889 pTrackPropDialog->Hide();
1892 if (RoutePropDlgImpl::getInstanceFlag() && pRouteManagerDialog &&
1893 pRouteManagerDialog->IsShown()) {
1894 pRouteManagerDialog->UpdateTrkListCtrl();
1895 pRouteManagerDialog->UpdateRouteListCtrl();
1897 gFrame->InvalidateAllGL();
1898 gFrame->RefreshAllCanvas();
1903 case ID_TK_MENU_SENDTOPEER:
1904 if (m_pSelectedTrack) {
1906 dlg.SetTrack(m_pSelectedTrack);
1911 MdnsCache::GetInstance().
Validate();
1912 if (MdnsCache::GetInstance().GetCache().empty())
1913 dlg.SetScanOnCreate(
true);
1916 dlg.Create(NULL, -1, _(
"Send Track to OpenCPN Peer") + _T(
"..." ),
"");
1921 case ID_RC_MENU_SCALE_IN:
1922 parent->parent_frame->DoStackDown(parent);
1924 parent->WarpPointer(r.x, r.y);
1927 case ID_RC_MENU_SCALE_OUT:
1928 parent->parent_frame->DoStackUp(parent);
1930 parent->WarpPointer(r.x, r.y);
1933 case ID_RC_MENU_ZOOM_IN:
1936 parent->WarpPointer(r.x, r.y);
1939 case ID_RC_MENU_ZOOM_OUT:
1942 parent->WarpPointer(r.x, r.y);
1945 case ID_RC_MENU_FINISH:
1946 parent->FinishRoute();
1948 parent->Refresh(
false);
1949 g_FlushNavobjChanges =
true;
1952 case ID_DEF_ZERO_XTE:
1953 g_pRouteMan->ZeroCurrentXTEToActivePoint();
1959 ArrayOfPlugInMenuItems item_array =
1960 g_pi_manager->GetPluginContextMenuItemArray();
1962 for (
unsigned int i = 0; i < item_array.GetCount(); i++) {
1964 int target_id = pimis->id;
1967 if (pimis->pmenu_item->GetSubMenu()) {
1968 const wxMenuItemList &items =
1969 pimis->pmenu_item->GetSubMenu()->GetMenuItems();
1970 for (wxMenuItemList::const_iterator it = items.begin();
1971 it != items.end(); ++it) {
1972 if ((*it)->GetId() ==
event.GetId()) {
1973 target_id = (*it)->GetId();
1979 if (pimis->m_pplugin && (target_id == event.GetId())) {
1980 if (pimis->extended) {
1981 std::string object_type;
1982 std::string object_ident;
1984 if ((pimis->m_in_menu.IsSameAs(
"Waypoint")) && m_pFoundRoutePoint) {
1985 object_type =
"Waypoint";
1986 object_ident = m_pFoundRoutePoint->
m_GUID.ToStdString();
1987 }
else if ((pimis->m_in_menu.IsSameAs(
"Route")) &&
1989 object_type =
"Route";
1990 object_ident = m_pSelectedRoute->
m_GUID.ToStdString();
1991 }
else if ((pimis->m_in_menu.IsSameAs(
"Track")) &&
1993 object_type =
"Track";
1994 object_ident = m_pSelectedTrack->m_GUID.ToStdString();
1995 }
else if ((pimis->m_in_menu.IsSameAs(
"AIS")) && m_FoundAIS_MMSI) {
1996 object_type =
"AIS";
1997 wxString sAIS = wxString::Format(
"%d", m_FoundAIS_MMSI);
1998 object_ident = sAIS.ToStdString();
2004 ppi->OnContextMenuItemCallbackExt(target_id, object_ident,
2005 object_type, zlat, zlon);
2016 if ((event.GetId() >= ID_DEF_MENU_GROUPBASE) &&
2019 parent->SetGroupIndex(event.GetId() - ID_DEF_MENU_GROUPBASE);
2022 parent->InvalidateGL();
Class AisDecoder and helpers.
Global state for AIS decoder.
Charts database management
ChartGroupArray * g_pGroupArray
Global instance.
Basic chart info storage.
Generic Chart canvas base.
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.
void DrawTCWindow(int x, int y, void *pIDX)
Legacy tide dialog creation method.
void Validate()
Check that all entries are accessible, remove stale ones.
Represents a waypoint or mark within the navigation system.
wxString m_GUID
Globally Unique Identifier for the waypoint.
bool m_bIsolatedMark
Flag indicating if the waypoint is a standalone mark.
bool m_bIsInLayer
Flag indicating if the waypoint belongs to a layer.
Represents a navigational route in the navigation system.
bool m_bRtIsSelected
Flag indicating whether this route is currently selected in the UI.
wxString m_RouteStartString
Name or description of the route's starting point.
bool m_bDeleteOnArrival
Flag indicating whether the route should be deleted once navigation reaches the end.
wxString m_RouteEndString
Name or description of the route's ending point.
RoutePoint * m_pRouteActivePoint
Pointer to the currently active waypoint within this route.
wxString m_RouteNameString
User-assigned name for the route.
wxString m_GUID
Globally unique identifier for this route.
bool m_bIsInLayer
Flag indicating whether this route belongs to a layer.
int m_lastMousePointIndex
Index of the most recently interacted with route point.
bool ActivateRoutePoint(Route *pA, RoutePoint *pRP)
Activates a specific waypoint within a route for navigation.
wxArrayPtrVoid * GetRouteArrayContaining(RoutePoint *pWP)
Find all routes that contain the given waypoint.
bool ActivateNextPoint(Route *pr, bool skipped)
Activates the next waypoint in a route when the current waypoint is reached.
bool DeleteRoute(Route *pRoute)
bool ActivateRoute(Route *pRouteToActivate, RoutePoint *pStartPoint=NULL)
Activates a route for navigation.
Dialog for sending routes/waypoints to a GPS device.
Dialog for sending navigation objects to peer devices.
Represents a track, which is a series of connected track points.
bool RemoveRoutePoint(RoutePoint *prp)
Remove a routepoint from list if present, deallocate it all cases.
Represents a composite CM93 chart covering multiple scales.
virtual void OnContextMenuItemCallback(int id)
Handles context menu item selection.
The JSON value class implementation.
CM93OffsetDialog * g_pCM93OffsetDialog
Global instance.
Class cm93chart and helpers – CM93 chart state.
Global variables stored in configuration file.
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.
double vLat
Virtual lat from chcanv popup.
double vLon
Virtual lon from chcanv popup.
double g_androidDPmm
Only used used by ANDROID
Miscellaneous globals primarely used by gui layer.
MdnsCache mDNS host lookups cache.
Tools to send data to plugins.
PlugInManager and helper classes – Mostly gui parts (dialogs) and plugin API stuff.