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>
83#include "user_colors.h"
86#include "androidUTIL.h"
91 ID_DEF_MENU_MAX_DETAIL = 1,
93 ID_DEF_MENU_SCALE_OUT,
97 ID_DEF_MENU_MOVE_BOAT_HERE,
98 ID_DEF_MENU_GOTO_HERE,
99 ID_DEF_MENU_GOTOPOSITION,
102 ID_WP_MENU_PROPERTIES,
104 ID_RT_MENU_DEACTIVATE,
108 ID_RT_MENU_SPLIT_LEG,
109 ID_RT_MENU_SPLIT_WPT,
112 ID_WPT_MENU_SENDTOGPS,
113 ID_WPT_MENU_SENDTONEWGPS,
114 ID_WPT_MENU_SENDTOPEER,
122 ID_RT_MENU_DEACTPOINT,
123 ID_RT_MENU_ACTNXTPOINT,
125 ID_RT_MENU_PROPERTIES,
126 ID_RT_MENU_SENDTOGPS,
127 ID_RT_MENU_SENDTONEWGPS,
128 ID_RT_MENU_SHOWNAMES,
129 ID_RT_MENU_RESEQUENCE,
130 ID_RT_MENU_SENDTOPEER,
131 ID_WP_MENU_SET_ANCHORWATCH,
132 ID_WP_MENU_CLEAR_ANCHORWATCH,
133 ID_DEF_MENU_AISTARGETLIST,
134 ID_DEF_MENU_AIS_CPAWARNING,
137 ID_RC_MENU_SCALE_OUT,
141 ID_DEF_MENU_AIS_QUERY,
143 ID_DEF_MENU_AISSHOWTRACK,
144 ID_DEF_MENU_ACTIVATE_MEASURE,
145 ID_DEF_MENU_DEACTIVATE_MEASURE,
146 ID_DEF_MENU_COPY_MMSI,
151 ID_DEF_MENU_CM93OFFSET_DIALOG,
153 ID_TK_MENU_PROPERTIES,
155 ID_TK_MENU_SENDTOPEER,
156 ID_WP_MENU_ADDITIONAL_INFO,
158 ID_DEF_MENU_QUILTREMOVE,
162 ID_DEF_MENU_TOGGLE_FULL,
163 ID_DEF_MENU_TIDEINFO,
164 ID_DEF_MENU_CURRENTINFO,
168 ID_DGB_MENU_NMEA_WINDOW,
170 ID_DEF_MENU_GROUPBASE,
177static wxString _menuText(wxString name, wxString shortcut) {
181 menutext <<
"\t" << shortcut;
189int CanvasMenuHandler::GetNextContextMenuId() {
190 return ID_DEF_MENU_LAST +
194wxFont CanvasMenuHandler::m_scaledFont;
197CanvasMenuHandler::CanvasMenuHandler(
ChartCanvas *parentCanvas,
200 int selectedAIS_MMSI,
201 void *selectedTCIndex, wxWindow *nmea_log)
202 : m_nmea_log(nmea_log) {
203 parent = parentCanvas;
204 m_pSelectedRoute = selectedRoute;
205 m_pSelectedTrack = selectedTrack;
206 m_pFoundRoutePoint = selectedPoint;
207 m_FoundAIS_MMSI = selectedAIS_MMSI;
208 m_pIDXCandidate = selectedTCIndex;
209 if (!m_scaledFont.IsOk()) {
211 m_scaledFont = *qFont;
217CanvasMenuHandler::~CanvasMenuHandler() {}
223void CanvasMenuHandler::PrepareMenuItem(wxMenuItem *item) {
224#if defined(__WXMSW__)
225 wxColour ctrl_back_color = GetGlobalColor(
"DILG1");
226 item->SetBackgroundColour(ctrl_back_color);
227 wxColour menu_text_color = GetGlobalColor(
"UITX1");
228 item->SetTextColour(menu_text_color);
232void CanvasMenuHandler::MenuPrepend1(wxMenu *menu,
int id, wxString label) {
233 wxMenuItem *item =
new wxMenuItem(menu,
id, label);
234#if defined(__WXMSW__)
235 item->SetFont(m_scaledFont);
240 item->SetFont(sFont);
243 PrepareMenuItem(item);
245 if (g_btouch) menu->InsertSeparator(0);
249void CanvasMenuHandler::MenuAppend1(wxMenu *menu,
int id, wxString label) {
250 wxMenuItem *item =
new wxMenuItem(menu,
id, label);
251#if defined(__WXMSW__)
252 item->SetFont(m_scaledFont);
257 item->SetFont(sFont);
260 PrepareMenuItem(item);
263 if (g_btouch) menu->AppendSeparator();
266void CanvasMenuHandler::SetMenuItemFont1(wxMenuItem *item) {
267#if defined(__WXMSW__)
268 item->SetFont(m_scaledFont);
271#if defined(__ANDROID__)
273 item->SetFont(*qFont);
276 PrepareMenuItem(item);
279void CanvasMenuHandler::CanvasPopupMenu(
int x,
int y,
int seltype) {
280 wxMenu *contextMenu =
new wxMenu;
281 wxMenu *menuWaypoint = NULL;
282 wxMenu *menuRoute = NULL;
283 wxMenu *menuTrack = NULL;
284 wxMenu *menuAIS = NULL;
286 wxMenu *subMenuChart =
new wxMenu;
287 wxMenu *subMenuUndo =
new wxMenu(
"Undo...Ctrl-Z");
290 wxMenu *subMenuRedo =
new wxMenu(
"Redo...Shift-Ctrl-Z");
292 wxMenu *subMenuRedo =
new wxMenu(
"Redo...Ctrl-Y");
294 wxMenu *subMenuDebug =
new wxMenu(
"");
295 MenuAppend1(subMenuDebug, ID_DGB_MENU_NMEA_WINDOW, _(
"Show Data Monitor"));
297 wxMenu *menuFocus = contextMenu;
302 if (!g_bBasicMenus || (seltype != SELTYPE_ROUTECREATE)) {
303 bool bsubMenus =
false;
306 if (parent->undo->AnythingToUndo()) {
308 wxMenuItem *subMenuItemundo =
309 contextMenu->AppendSubMenu(subMenuUndo, _(
"Undo"));
312 undoItem << _(
"Undo") <<
" "
313 << parent->undo->GetNextUndoableAction()->Description();
314 MenuAppend1(subMenuUndo, ID_UNDO, undoItem);
316 if (parent->undo->AnythingToRedo()) {
318 wxMenuItem *subMenuItemRedo =
319 contextMenu->AppendSubMenu(subMenuRedo, _(
"Redo"));
322 redoItem << _(
"Redo") <<
" "
323 << parent->undo->GetNextRedoableAction()->Description();
324 MenuAppend1(subMenuRedo, ID_REDO, redoItem);
327 if (parent->undo->AnythingToUndo()) {
329 undoItem << _(
"Undo") <<
" "
330 << parent->undo->GetNextUndoableAction()->Description();
331 MenuAppend1(contextMenu, ID_UNDO, _menuText(undoItem,
"Ctrl-Z"));
334 if (parent->undo->AnythingToRedo()) {
336 redoItem << _(
"Redo") <<
" "
337 << parent->undo->GetNextRedoableAction()->Description();
339 MenuAppend1(contextMenu, ID_REDO, _menuText(redoItem,
"Shift-Ctrl-Z"));
341 MenuAppend1(contextMenu, ID_REDO, _menuText(redoItem,
"Ctrl-Y"));
347 if (seltype == SELTYPE_ROUTECREATE) {
348 MenuAppend1(contextMenu, ID_RC_MENU_FINISH,
349 _menuText(_(
"End Route"),
"Esc"));
352 if (!parent->m_pMouseRoute) {
353 if (parent->m_bMeasure_Active)
354 MenuAppend1(contextMenu, ID_DEF_MENU_DEACTIVATE_MEASURE,
355 _menuText(_(
"Measure Off"),
"Esc"));
357 MenuAppend1(contextMenu, ID_DEF_MENU_ACTIVATE_MEASURE,
358 _menuText(_(
"Measure"),
"M"));
361 bool ais_areanotice =
false;
362 if (
g_pAIS && parent->GetShowAIS() && g_bShowAreaNotices) {
365 for (
const auto &target :
g_pAIS->GetAreaNoticeSourcesList()) {
366 auto target_data = target.second;
367 if (!target_data->area_notices.empty()) {
368 for (
auto &ani : target_data->area_notices) {
372 for (Ais8_001_22_SubAreaList::iterator sa =
373 area_notice.sub_areas.begin();
374 sa != area_notice.sub_areas.end(); ++sa) {
376 case AIS8_001_22_SHAPE_CIRCLE: {
377 wxPoint target_point;
380 bbox.Expand(target_point);
381 if (sa->radius_m > 0.0) bbox.EnLarge(sa->radius_m * vp_scale);
384 case AIS8_001_22_SHAPE_RECT:
385 case AIS8_001_22_SHAPE_POLYGON:
386 case AIS8_001_22_SHAPE_POLYLINE: {
387 double lat = sa->latitude;
388 double lon = sa->longitude;
389 for (
int i = 0; i < 4; ++i) {
390 ll_gc_ll(lat, lon, sa->angles[i], sa->dists_m[i] / 1852.0,
392 wxPoint target_point;
394 bbox.Expand(target_point);
398 case AIS8_001_22_SHAPE_SECTOR: {
399 double lat1 = sa->latitude;
400 double lon1 = sa->longitude;
402 wxPoint target_point;
404 bbox.Expand(target_point);
405 for (
int i = 0; i < 18; ++i) {
409 i * (sa->right_bound_deg - sa->left_bound_deg) / 18,
410 sa->radius_m / 1852.0, &lat, &lon);
412 bbox.Expand(target_point);
414 ll_gc_ll(lat1, lon1, sa->right_bound_deg, sa->radius_m / 1852.0,
417 bbox.Expand(target_point);
423 if (bbox.GetValid() && bbox.PointInBox(x, y)) {
424 ais_areanotice =
true;
433 if (parent->GetpCurrentStack())
434 nChartStack = parent->GetpCurrentStack()->nEntry;
436 if (!parent->GetVP().b_quilt) {
437 if (nChartStack > 1) {
438 MenuAppend1(contextMenu, ID_DEF_MENU_MAX_DETAIL, _(
"Max Detail Here"));
439 MenuAppend1(contextMenu, ID_DEF_MENU_SCALE_IN,
440 _menuText(_(
"Scale In"),
"Ctrl-Left"));
441 MenuAppend1(contextMenu, ID_DEF_MENU_SCALE_OUT,
442 _menuText(_(
"Scale Out"),
"Ctrl-Right"));
445 if ((parent->m_singleChart &&
446 (parent->m_singleChart->GetChartFamily() == CHART_FAMILY_VECTOR)) ||
448 MenuAppend1(contextMenu, ID_DEF_MENU_QUERY, _(
"Object Query") +
"...");
453 parent->m_pQuilt->GetChartAtPix(parent->GetVP(), wxPoint(x, y));
454 if ((pChartTest && (pChartTest->GetChartFamily() == CHART_FAMILY_VECTOR)) ||
456 MenuAppend1(contextMenu, ID_DEF_MENU_QUERY, _(
"Object Query") +
"...");
459 if (!g_bBasicMenus && (nChartStack > 1)) {
460 MenuAppend1(contextMenu, ID_DEF_MENU_SCALE_IN,
461 _menuText(_(
"Scale In"),
"Ctrl-Left"));
462 MenuAppend1(contextMenu, ID_DEF_MENU_SCALE_OUT,
463 _menuText(_(
"Scale Out"),
"Ctrl-Right"));
469 if (!g_bBasicMenus || (seltype != SELTYPE_ROUTECREATE)) {
470 bool b_dm_add =
true;
471 if (g_btouch && parent->IsMeasureActive()) b_dm_add =
false;
474 MenuAppend1(contextMenu, ID_DEF_MENU_DROP_WP,
475 _menuText(_(
"Drop Mark"),
"Ctrl-M"));
476 MenuAppend1(contextMenu, ID_DEF_MENU_NEW_RT,
477 _menuText(_(
"New Route..."),
"Ctrl-R"));
481 MenuAppend1(contextMenu, ID_DEF_MENU_MOVE_BOAT_HERE, _(
"Move Boat Here"));
484 if (!g_bBasicMenus && !
g_pRouteMan->GetpActiveRoute() &&
485 (!(seltype & SELTYPE_MARKPOINT) ||
486 (m_pFoundRoutePoint && m_pFoundRoutePoint->
m_bIsInLayer)))
487 MenuAppend1(contextMenu, ID_DEF_MENU_GOTO_HERE, _(
"Navigate To Here"));
490 MenuAppend1(contextMenu, ID_DEF_MENU_GOTOPOSITION,
491 _(
"Center view") +
"...");
493 if (!g_bBasicMenus) {
494 if (parent->GetVP().b_quilt) {
495 if (parent->GetUpMode() == NORTH_UP_MODE) {
496 MenuAppend1(contextMenu, ID_DEF_MENU_COGUP, _(
"Course Up Mode"));
497 if (!std::isnan(
gHdt))
498 MenuAppend1(contextMenu, ID_DEF_MENU_HEADUP, _(
"Heading Up Mode"));
500 MenuAppend1(contextMenu, ID_DEF_MENU_NORTHUP, _(
"North Up Mode"));
503 if (parent->m_singleChart &&
504 (fabs(parent->m_singleChart->GetChartSkew()) > .01) && !g_bskew_comp)
505 MenuAppend1(contextMenu, ID_DEF_MENU_NORTHUP, _(
"Chart Up Mode"));
507 MenuAppend1(contextMenu, ID_DEF_MENU_NORTHUP, _(
"North Up Mode"));
511 if (!g_bBasicMenus) {
512 bool full_toggle_added =
false;
515 MenuAppend1(contextMenu, ID_DEF_MENU_TOGGLE_FULL,
516 _(
"Toggle Full Screen"));
517 full_toggle_added =
true;
520 if (!full_toggle_added) {
522 MenuAppend1(contextMenu, ID_DEF_MENU_TOGGLE_FULL,
523 _(
"Toggle Full Screen"));
529 MenuAppend1(contextMenu, ID_DEF_ZERO_XTE, _(
"Zero XTE"));
532 int pasteBuffer = kml->ParsePasteBuffer();
533 if (pasteBuffer != KML_PASTE_INVALID) {
534 switch (pasteBuffer) {
535 case KML_PASTE_WAYPOINT: {
536 MenuAppend1(contextMenu, ID_PASTE_WAYPOINT, _(
"Paste Waypoint"));
539 case KML_PASTE_ROUTE: {
540 MenuAppend1(contextMenu, ID_PASTE_ROUTE, _(
"Paste Route"));
543 case KML_PASTE_TRACK: {
544 MenuAppend1(contextMenu, ID_PASTE_TRACK, _(
"Paste Track"));
547 case KML_PASTE_ROUTE_TRACK: {
548 MenuAppend1(contextMenu, ID_PASTE_ROUTE, _(
"Paste Route"));
549 MenuAppend1(contextMenu, ID_PASTE_TRACK, _(
"Paste Track"));
556 if (!parent->GetVP().b_quilt && parent->m_singleChart &&
557 (parent->m_singleChart->GetChartType() == CHART_TYPE_CM93COMP)) {
558 MenuAppend1(contextMenu, ID_DEF_MENU_CM93OFFSET_DIALOG,
559 _(
"CM93 Offset Dialog..."));
583 wxMenuItem *subItemChart =
584 contextMenu->AppendSubMenu(subMenuChart, _(
"Chart Groups"));
585 if (g_btouch) contextMenu->AppendSeparator();
587 SetMenuItemFont1(subItemChart);
591 MenuAppend1(subMenuChart, wxID_CANCEL, _(
"temporary"));
593 wxMenuItem *subItem0 = subMenuChart->AppendRadioItem(
594 ID_DEF_MENU_GROUPBASE, _(
"All Active Charts"));
596 SetMenuItemFont1(subItem0);
598 for (
unsigned int i = 0; i <
g_pGroupArray->GetCount(); i++) {
599 subItem0 = subMenuChart->AppendRadioItem(
600 ID_DEF_MENU_GROUPBASE + i + 1,
g_pGroupArray->Item(i)->m_group_name);
601 SetMenuItemFont1(subItem0);
605 subMenuChart->Remove(wxID_CANCEL);
607 subMenuChart->Check(ID_DEF_MENU_GROUPBASE + parent->m_groupIndex,
true);
611 menuFocus = contextMenu;
614 std::unique_ptr<HostApi> host_api =
GetHostApi();
615 auto *api_121 =
dynamic_cast<HostApi121 *
>(host_api.get());
617 if (!g_bBasicMenus || (seltype != SELTYPE_ROUTECREATE)) {
619 if (api_121 && parent->GetShowAIS() &&
620 (seltype & SELTYPE_AISTARGET &&
621 !(api_121->GetContextMenuMask() &
622 api_121->kContextMenuDisableAistarget))) {
623 auto myptarget =
g_pAIS->Get_Target_Data_From_MMSI(m_FoundAIS_MMSI);
624 if (!g_bBasicMenus && myptarget) {
625 name = myptarget->GetFullName();
626 if (name.IsEmpty()) name.Printf(
"%d", m_FoundAIS_MMSI);
627 name.Prepend(
" ( ").Append(
" )");
629 name = wxEmptyString;
630 menuAIS =
new wxMenu(_(
"AIS") + name);
631 MenuAppend1(menuAIS, ID_DEF_MENU_AIS_QUERY, _(
"Target Query..."));
632 if (myptarget && myptarget->bCPA_Valid &&
633 (myptarget->n_alert_state != AIS_ALERT_SET)) {
634 if (myptarget->b_show_AIS_CPA)
635 MenuAppend1(menuAIS, ID_DEF_MENU_AIS_CPA, _(
"Hide Target CPA"));
637 MenuAppend1(menuAIS, ID_DEF_MENU_AIS_CPA, _(
"Show Target CPA"));
639 MenuAppend1(menuAIS, ID_DEF_MENU_AISTARGETLIST, _(
"Target List..."));
640 if (myptarget->Class != AIS_METEO ) {
641 if (myptarget && !myptarget->b_PersistTrack) {
642 if (myptarget->b_show_track)
643 MenuAppend1(menuAIS, ID_DEF_MENU_AISSHOWTRACK,
644 _(
"Hide Target Track"));
646 MenuAppend1(menuAIS, ID_DEF_MENU_AISSHOWTRACK,
647 _(
"Show Target Track"));
651 MenuAppend1(menuAIS, ID_DEF_MENU_COPY_MMSI, _(
"Copy Target MMSI"));
652 menuAIS->AppendSeparator();
654 if (!parent->GetVP().b_quilt) {
655 if ((parent->m_singleChart &&
656 (parent->m_singleChart->GetChartFamily() ==
657 CHART_FAMILY_VECTOR))) {
658 MenuAppend1(menuAIS, ID_DEF_MENU_QUERY, _(
"Object Query..."));
663 parent->m_pQuilt->GetChartAtPix(parent->GetVP(), wxPoint(x, y));
665 (pChartTest->GetChartFamily() == CHART_FAMILY_VECTOR))) {
666 MenuAppend1(menuAIS, ID_DEF_MENU_QUERY, _(
"Object Query..."));
672 bool enable_list =
true;
674 double char_x = wxTheApp->GetTopWindow()->GetSize().x /
675 wxTheApp->GetTopWindow()->GetCharWidth();
676 double char_y = wxTheApp->GetTopWindow()->GetSize().y /
677 wxTheApp->GetTopWindow()->GetCharWidth();
678 double char_min = wxMin(char_x, char_y);
679 if (char_min < 100) enable_list =
false;
681 double size_x = wxTheApp->GetTopWindow()->GetSize().x /
g_androidDPmm;
682 double size_y = wxTheApp->GetTopWindow()->GetSize().y /
g_androidDPmm;
683 if (wxMin(size_x, size_y) < 100)
687 MenuAppend1(contextMenu, ID_DEF_MENU_AISTARGETLIST,
688 _(
"AIS target list") +
"...");
690 wxString nextCPAstatus = g_bCPAWarn ? _(
"Hide") : _(
"Show");
691 MenuAppend1(contextMenu, ID_DEF_MENU_AIS_CPAWARNING,
692 _menuText(nextCPAstatus +
" " + _(
"CPA alarm "),
"W"));
696 if (g_enable_root_menu_debug) {
697 wxMenuItem *subItemDebug =
698 contextMenu->AppendSubMenu(subMenuDebug, _(
"Debug"));
699 if (g_btouch) contextMenu->AppendSeparator();
700 SetMenuItemFont1(subItemDebug);
703 if (seltype & SELTYPE_ROUTESEGMENT &&
704 !(api_121->GetContextMenuMask() & api_121->kContextMenuDisableRoute)) {
705 if (!g_bBasicMenus && m_pSelectedRoute) {
707 if (name.IsEmpty()) name = _(
"Unnamed Route");
708 name.Prepend(
" ( ").Append(
" )");
710 name = wxEmptyString;
712 if (m_pSelectedRoute && m_pSelectedRoute->
m_bIsInLayer) blay =
true;
715 menuRoute =
new wxMenu(_(
"Layer Route") + name);
716 MenuAppend1(menuRoute, ID_RT_MENU_PROPERTIES, _(
"Properties") +
"...");
717 if (m_pSelectedRoute) {
718 if (m_pSelectedRoute->IsActive()) {
719 int indexActive = m_pSelectedRoute->GetIndexOf(
721 if ((indexActive + 1) <= m_pSelectedRoute->GetnPoints()) {
722 MenuAppend1(menuRoute, ID_RT_MENU_ACTNXTPOINT,
723 _(
"Activate Next Waypoint"));
725 MenuAppend1(menuRoute, ID_RT_MENU_DEACTIVATE, _(
"Deactivate"));
726 MenuAppend1(menuRoute, ID_DEF_ZERO_XTE, _(
"Zero XTE"));
728 MenuAppend1(menuRoute, ID_RT_MENU_ACTIVATE, _(
"Activate"));
732 menuRoute =
new wxMenu(_(
"Route") + name);
733 MenuAppend1(menuRoute, ID_RT_MENU_PROPERTIES, _(
"Properties") +
"...");
734 if (m_pSelectedRoute) {
735 if (m_pSelectedRoute->IsActive()) {
736 int indexActive = m_pSelectedRoute->GetIndexOf(
738 if ((indexActive + 1) <= m_pSelectedRoute->GetnPoints()) {
739 MenuAppend1(menuRoute, ID_RT_MENU_ACTNXTPOINT,
740 _(
"Activate Next Waypoint"));
742 MenuAppend1(menuRoute, ID_RT_MENU_DEACTIVATE, _(
"Deactivate"));
743 MenuAppend1(menuRoute, ID_DEF_ZERO_XTE, _(
"Zero XTE"));
745 MenuAppend1(menuRoute, ID_RT_MENU_ACTIVATE, _(
"Activate"));
748 MenuAppend1(menuRoute, ID_RT_MENU_INSERT, _(
"Insert Waypoint"));
749 MenuAppend1(menuRoute, ID_RT_MENU_APPEND, _(
"Append Waypoint"));
750 if (!(seltype & SELTYPE_ROUTEPOINT) && m_pSelectedRoute) {
751 m_SelectedIdx = m_pSelectedRoute->GetIndexOf(m_pFoundRoutePoint);
752 if (m_SelectedIdx > 1 &&
753 m_SelectedIdx < m_pSelectedRoute->GetnPoints() - 1)
754 MenuAppend1(menuRoute, ID_RT_MENU_SPLIT_LEG, _(
"Split around Leg"));
756 MenuAppend1(menuRoute, ID_RT_MENU_COPY, _(
"Copy as KML") +
"...");
757 MenuAppend1(menuRoute, ID_RT_MENU_DELETE, _(
"Delete") +
"...");
758 MenuAppend1(menuRoute, ID_RT_MENU_REVERSE, _(
"Reverse..."));
759 if (m_pSelectedRoute) {
760 if (m_pSelectedRoute->AreWaypointNamesVisible())
761 MenuAppend1(menuRoute, ID_RT_MENU_SHOWNAMES,
762 _(
"Hide Waypoint Names"));
764 MenuAppend1(menuRoute, ID_RT_MENU_SHOWNAMES,
765 _(
"Show Waypoint Names"));
767 MenuAppend1(menuRoute, ID_RT_MENU_RESEQUENCE,
768 _(
"Resequence Waypoints..."));
771 wxString port = parent->FindValidUploadPort();
772 parent->m_active_upload_port = port;
773 wxString item = _(
"Send to GPS");
774 if (!port.IsEmpty()) {
779 MenuAppend1(menuRoute, ID_RT_MENU_SENDTOGPS, item);
781 if (!port.IsEmpty()) {
782 wxString item = _(
"Send to new GPS");
783 MenuAppend1(menuRoute, ID_RT_MENU_SENDTONEWGPS, item);
786 wxString itemstp = SYMBOL_STP_TITLE;
787 MenuAppend1(menuRoute, ID_RT_MENU_SENDTOPEER, itemstp);
790 if (menuFocus != menuAIS) menuFocus = menuRoute;
793 if (seltype & SELTYPE_TRACKSEGMENT &&
794 !(api_121->GetContextMenuMask() & api_121->kContextMenuDisableTrack)) {
795 name = wxEmptyString;
796 if (!g_bBasicMenus && m_pSelectedTrack)
797 name =
" ( " + m_pSelectedTrack->GetName(
true) +
" )";
799 name = wxEmptyString;
801 if (m_pSelectedTrack && m_pSelectedTrack->m_bIsInLayer) blay =
true;
804 menuTrack =
new wxMenu(_(
"Layer Track") + name);
805 MenuAppend1(menuTrack, ID_TK_MENU_PROPERTIES, _(
"Properties") +
"...");
807 menuTrack =
new wxMenu(_(
"Track") + name);
808 MenuAppend1(menuTrack, ID_TK_MENU_PROPERTIES, _(
"Properties") +
"...");
809 MenuAppend1(menuTrack, ID_TK_MENU_COPY, _(
"Copy as KML"));
810 MenuAppend1(menuTrack, ID_TK_MENU_DELETE, _(
"Delete") +
"...");
813 wxString itemstp = SYMBOL_STP_TITLE;
814 MenuAppend1(menuTrack, ID_TK_MENU_SENDTOPEER, itemstp);
817 if (menuFocus != menuAIS) menuFocus = menuTrack;
820 if (seltype & SELTYPE_ROUTEPOINT &&
821 !(api_121->GetContextMenuMask() &
822 api_121->kContextMenuDisableWaypoint)) {
823 if (!g_bBasicMenus && m_pFoundRoutePoint) {
824 name = m_pFoundRoutePoint->GetName();
825 if (name.IsEmpty()) name = _(
"Unnamed Waypoint");
826 name.Prepend(
" ( ").Append(
" )");
828 name = wxEmptyString;
830 if (m_pFoundRoutePoint && m_pFoundRoutePoint->
m_bIsInLayer) blay =
true;
833 menuWaypoint =
new wxMenu(_(
"Layer Waypoint") + name);
834 MenuAppend1(menuWaypoint, ID_WP_MENU_PROPERTIES,
835 _(
"Properties") +
"...");
837 if (m_pSelectedRoute && m_pSelectedRoute->IsActive())
838 MenuAppend1(menuWaypoint, ID_RT_MENU_ACTPOINT, _(
"Activate"));
840 menuWaypoint =
new wxMenu(_(
"Waypoint") + name);
841 MenuAppend1(menuWaypoint, ID_WP_MENU_PROPERTIES,
842 _(
"Properties") +
"...");
843 if (m_pSelectedRoute && m_pSelectedRoute->IsActive()) {
845 MenuAppend1(menuWaypoint, ID_RT_MENU_ACTPOINT, _(
"Activate"));
848 if (m_pSelectedRoute && m_pSelectedRoute->IsActive()) {
850 int indexActive = m_pSelectedRoute->GetIndexOf(
852 if ((indexActive + 1) <= m_pSelectedRoute->GetnPoints())
853 MenuAppend1(menuWaypoint, ID_RT_MENU_ACTNXTPOINT,
854 _(
"Activate Next Waypoint"));
857 if (m_pSelectedRoute && m_pSelectedRoute->GetnPoints() > 2) {
858 MenuAppend1(menuWaypoint, ID_RT_MENU_REMPOINT,
859 _(
"Remove from Route"));
861 m_SelectedIdx = m_pSelectedRoute->GetIndexOf(m_pFoundRoutePoint);
862 if (m_SelectedIdx > 1 &&
863 m_SelectedIdx < m_pSelectedRoute->GetnPoints())
864 MenuAppend1(menuWaypoint, ID_RT_MENU_SPLIT_WPT,
865 _(
"Split Route at Waypoint"));
868 MenuAppend1(menuWaypoint, ID_WPT_MENU_COPY, _(
"Copy as KML"));
870 if (m_pFoundRoutePoint && m_pFoundRoutePoint->GetIconName() !=
"mob")
871 MenuAppend1(menuWaypoint, ID_RT_MENU_DELPOINT, _(
"Delete"));
874 wxString port = parent->FindValidUploadPort();
875 parent->m_active_upload_port = port;
876 wxString item = _(
"Send to GPS");
877 if (!port.IsEmpty()) {
882 MenuAppend1(menuWaypoint, ID_WPT_MENU_SENDTOGPS, item);
884 if (!port.IsEmpty()) {
885 wxString item = _(
"Send to new GPS");
886 MenuAppend1(menuWaypoint, ID_WPT_MENU_SENDTONEWGPS, item);
889 MenuAppend1(menuWaypoint, ID_WPT_MENU_SENDTOPEER,
894 if (menuFocus != menuAIS) menuFocus = menuWaypoint;
897 if (seltype & SELTYPE_MARKPOINT &&
898 !(api_121->GetContextMenuMask() &
899 api_121->kContextMenuDisableWaypoint)) {
900 if (!g_bBasicMenus && m_pFoundRoutePoint) {
901 name = m_pFoundRoutePoint->GetName();
902 if (name.IsEmpty()) name = _(
"Unnamed Mark");
903 name.Prepend(
" ( ").Append(
" )");
905 name = wxEmptyString;
907 if (m_pFoundRoutePoint && m_pFoundRoutePoint->
m_bIsInLayer) blay =
true;
910 menuWaypoint =
new wxMenu(_(
"Layer Waypoint") + name);
911 MenuAppend1(menuWaypoint, ID_WP_MENU_PROPERTIES,
912 _(
"Properties") +
"...");
914 menuWaypoint =
new wxMenu(_(
"Mark") + name);
915 MenuAppend1(menuWaypoint, ID_WP_MENU_PROPERTIES,
916 _(
"Properties") +
"...");
919 MenuAppend1(menuWaypoint, ID_WP_MENU_GOTO, _(
"Navigate To This"));
921 MenuAppend1(menuWaypoint, ID_WPT_MENU_COPY, _(
"Copy as KML"));
923 if (m_pFoundRoutePoint && m_pFoundRoutePoint->GetIconName() !=
"mob")
924 MenuAppend1(menuWaypoint, ID_WP_MENU_DELPOINT, _(
"Delete"));
927 wxString port = parent->FindValidUploadPort();
928 parent->m_active_upload_port = port;
929 wxString item = _(
"Send to GPS");
930 if (!port.IsEmpty()) {
935 MenuAppend1(menuWaypoint, ID_WPT_MENU_SENDTOGPS, item);
937 MenuAppend1(menuWaypoint, ID_WPT_MENU_SENDTOPEER,
943 MenuAppend1(menuWaypoint, ID_WP_MENU_CLEAR_ANCHORWATCH,
944 _(
"Clear Anchor Watch"));
946 if (m_pFoundRoutePoint && !(m_pFoundRoutePoint->
m_bIsInLayer) &&
950 DistanceBearingMercator(m_pFoundRoutePoint->m_lat,
951 m_pFoundRoutePoint->m_lon,
gLat,
gLon, &brg,
953 if (dist * 1852. <= g_nAWMax)
954 MenuAppend1(menuWaypoint, ID_WP_MENU_SET_ANCHORWATCH,
955 _(
"Set Anchor Watch"));
960 if (menuFocus != menuAIS) menuFocus = menuWaypoint;
964 AddPluginContextMenuItems(contextMenu, menuRoute, menuTrack, menuWaypoint,
968 enum { WPMENU = 1, TKMENU = 2, RTMENU = 4, MMMENU = 8 };
970 if (!g_bBasicMenus && menuFocus != contextMenu) {
971 if (global_color_scheme != GLOBAL_COLOR_SCHEME_DUSK &&
972 global_color_scheme != GLOBAL_COLOR_SCHEME_NIGHT) {
973 menuFocus->AppendSeparator();
976 wxMenuItem *subMenu1;
977 if (menuWaypoint && menuFocus != menuWaypoint) {
979 menuFocus->AppendSubMenu(menuWaypoint, menuWaypoint->GetTitle());
980 SetMenuItemFont1(subMenu1);
983 menuWaypoint->SetTitle(wxEmptyString);
986 if (menuTrack && menuFocus != menuTrack) {
987 subMenu1 = menuFocus->AppendSubMenu(menuTrack, menuTrack->GetTitle());
988 SetMenuItemFont1(subMenu1);
991 menuTrack->SetTitle(wxEmptyString);
994 if (menuRoute && menuFocus != menuRoute) {
995 subMenu1 = menuFocus->AppendSubMenu(menuRoute, menuRoute->GetTitle());
996 SetMenuItemFont1(subMenu1);
999 menuRoute->SetTitle(wxEmptyString);
1002 subMenu1 = menuFocus->AppendSubMenu(contextMenu, _(
"Main Menu"));
1003 SetMenuItemFont1(subMenu1);
1007 if (!subMenuChart->GetMenuItemCount()) contextMenu->Destroy(subItemChart);
1012 if (seltype & SELTYPE_TIDEPOINT) {
1013 menuFocus->AppendSeparator();
1015 MenuAppend1(menuFocus, ID_DEF_MENU_TIDEINFO, _(
"Show Tide Information"));
1018 if (seltype & SELTYPE_CURRENTPOINT) {
1019 if (!bsep) menuFocus->AppendSeparator();
1020 MenuAppend1(menuFocus, ID_DEF_MENU_CURRENTINFO,
1021 _(
"Show Current Information"));
1027 androidEnableBackButton(
false);
1028 androidEnableOptionsMenu(
false);
1036 parent->PopupMenu(menuFocus, x, y);
1039 androidEnableBackButton(
true);
1040 androidEnableOptionsMenu(
true);
1047 if (!(sub_menu & MMMENU))
delete contextMenu;
1048 if (!(sub_menu & RTMENU))
delete menuRoute;
1049 if (!(sub_menu & TKMENU))
delete menuTrack;
1050 if (!(sub_menu & WPMENU))
delete menuWaypoint;
1054void CanvasMenuHandler::AddPluginContextMenuItems(wxMenu *contextMenu,
1057 wxMenu *menuWaypoint,
1063 ArrayOfPlugInMenuItems item_array =
1066 for (
unsigned int i = 0; i < item_array.GetCount(); i++) {
1068 if (!pimis->b_viz)
continue;
1070 wxMenu *submenu = NULL;
1071 if (pimis->pmenu_item->GetSubMenu()) {
1073 auto submenu_proto = pimis->pmenu_item->GetSubMenu();
1074 submenu =
new wxMenu();
1075 const wxMenuItemList &items =
1076 pimis->pmenu_item->GetSubMenu()->GetMenuItems();
1077 for (wxMenuItemList::const_iterator it = items.begin(); it != items.end();
1079 int id = (*it)->GetId();
1081 new wxMenuItem(submenu,
id, (*it)->GetItemLabelText(),
1082 (*it)->GetHelp(), (*it)->GetKind());
1085 psmi->SetFont(m_scaledFont);
1090 psmi->SetFont(sFont);
1093 PrepareMenuItem(psmi);
1094 submenu->Append(psmi);
1095 psmi->Check((*it)->IsChecked());
1099 wxMenuItem *pmi =
new wxMenuItem(
1100 contextMenu, pimis->id, pimis->pmenu_item->GetItemLabelText(),
1101 pimis->pmenu_item->GetHelp(), pimis->pmenu_item->GetKind(), submenu);
1103 pmi->SetFont(m_scaledFont);
1108 pmi->SetFont(sFont);
1111 PrepareMenuItem(pmi);
1113 wxMenu *dst = contextMenu;
1114 if (pimis->m_in_menu ==
"Waypoint")
1116 else if (pimis->m_in_menu ==
"Route")
1118 else if (pimis->m_in_menu ==
"Track")
1120 else if (pimis->m_in_menu ==
"AIS")
1125 dst->Enable(pimis->id, !pimis->b_grey);
1130void CanvasMenuHandler::PopupMenuHandler(wxCommandEvent &event) {
1137 bool dupFirstWpt =
true, showRPD;
1142 switch (event.GetId()) {
1143 case ID_DEF_MENU_MAX_DETAIL:
1146 parent->ClearbFollow();
1148 top_frame::Get()->DoChartUpdate();
1150 parent->SelectChartFromStack(0,
false, CHART_TYPE_DONTCARE,
1151 CHART_FAMILY_RASTER);
1154 case ID_DEF_MENU_SCALE_IN:
1155 parent->DoCanvasStackDelta(-1);
1158 case ID_DEF_MENU_SCALE_OUT:
1159 parent->DoCanvasStackDelta(1);
1163 parent->undo->UndoLastAction();
1164 parent->InvalidateGL();
1165 parent->Refresh(
false);
1169 parent->undo->RedoNextAction();
1170 parent->InvalidateGL();
1171 parent->Refresh(
false);
1174 case ID_DEF_MENU_MOVE_BOAT_HERE:
1177 top_frame::Get()->UpdateStatusBar();
1180 case ID_DEF_MENU_GOTO_HERE: {
1182 wxEmptyString, wxEmptyString);
1183 pSelect->AddSelectableRoutePoint(zlat, zlon, pWP_dest);
1186 wxEmptyString, wxEmptyString);
1192 temp_route->AddPoint(pWP_src);
1193 temp_route->AddPoint(pWP_dest);
1196 pWP_dest, temp_route);
1212 case ID_DEF_MENU_DROP_WP: {
1214 wxEmptyString, wxEmptyString);
1216 pSelect->AddSelectableRoutePoint(zlat, zlon, pWP);
1217 NavObj_dB::GetInstance().InsertRoutePoint(pWP);
1222 if (RouteManagerDialog::getInstanceFlag()) {
1228 parent->undo->BeforeUndoableAction(Undo_CreateWaypoint, pWP,
1229 Undo_HasParent, NULL);
1230 parent->undo->AfterUndoableAction(NULL);
1231 top_frame::Get()->RefreshAllCanvas(
false);
1232 top_frame::Get()->InvalidateAllGL();
1233 g_FlushNavobjChanges =
true;
1237 case ID_DEF_MENU_NEW_RT: {
1238 parent->StartRoute();
1242 case ID_DEF_MENU_AISTARGETLIST:
1243 parent->ShowAISTargetList();
1246 case ID_DEF_MENU_AIS_CPAWARNING:
1247 parent->ToggleCPAWarn();
1250 case ID_WP_MENU_GOTO: {
1252 wxEmptyString, wxEmptyString);
1258 temp_route->AddPoint(pWP_src);
1259 temp_route->AddPoint(m_pFoundRoutePoint);
1260 m_pFoundRoutePoint->SetShared(
true);
1262 pSelect->AddSelectableRouteSegment(
gLat,
gLon, m_pFoundRoutePoint->m_lat,
1263 m_pFoundRoutePoint->m_lon, pWP_src,
1264 m_pFoundRoutePoint, temp_route);
1266 wxString name = m_pFoundRoutePoint->GetName();
1267 if (name.IsEmpty()) name = _(
"(Unnamed Waypoint)");
1268 wxString rteName = _(
"Go to ");
1269 rteName.Append(name);
1283 case ID_DEF_MENU_COGUP:
1284 parent->SetUpMode(COURSE_UP_MODE);
1287 case ID_DEF_MENU_HEADUP:
1288 parent->SetUpMode(HEAD_UP_MODE);
1291 case ID_DEF_MENU_NORTHUP:
1292 parent->SetUpMode(NORTH_UP_MODE);
1295 case ID_DEF_MENU_TOGGLE_FULL:
1296 top_frame::Get()->ToggleFullScreen();
1299 case ID_DEF_MENU_GOTOPOSITION:
1308 case ID_WP_MENU_DELPOINT: {
1317 if (m_pFoundRoutePoint && !(m_pFoundRoutePoint->
m_bIsInLayer) &&
1318 (m_pFoundRoutePoint->GetIconName() !=
"mob")) {
1322 wxArrayPtrVoid *proute_array =
1325 pWayPointMan->DestroyWaypoint(m_pFoundRoutePoint);
1326 delete proute_array;
1328 parent->undo->BeforeUndoableAction(
1329 Undo_DeleteWaypoint, m_pFoundRoutePoint, Undo_IsOrphanded,
1331 NavObj_dB::GetInstance().DeleteRoutePoint(m_pFoundRoutePoint);
1332 pSelect->DeleteSelectablePoint(m_pFoundRoutePoint,
1333 SELTYPE_ROUTEPOINT);
1334 if (NULL != pWayPointMan)
1336 parent->undo->AfterUndoableAction(NULL);
1343 if (RouteManagerDialog::getInstanceFlag()) {
1349 top_frame::Get()->RefreshAllCanvas(
false);
1350 top_frame::Get()->InvalidateAllGL();
1354 case ID_WP_MENU_PROPERTIES:
1355 parent->ShowMarkPropertiesDialog(m_pFoundRoutePoint);
1358 case ID_WP_MENU_CLEAR_ANCHORWATCH: {
1359 wxString guid = wxEmptyString;
1369 if (!guid.IsEmpty()) {
1372 wxString msg_id(
"OCPN_ANCHOR_WATCH_CLEARED");
1373 SendJSONMessageToAllPlugins(msg_id, v);
1378 case ID_WP_MENU_SET_ANCHORWATCH: {
1379 wxString guid = wxEmptyString;
1385 nn = m_pFoundRoutePoint->GetName();
1387 nn.Printf(
"%d m", g_nAWDefault);
1388 m_pFoundRoutePoint->SetName(nn);
1395 nn = m_pFoundRoutePoint->GetName();
1397 nn.Printf(
"%d m", g_nAWDefault);
1398 m_pFoundRoutePoint->SetName(nn);
1401 if (!guid.IsEmpty()) {
1404 wxString msg_id(
"OCPN_ANCHOR_WATCH_SET");
1405 SendJSONMessageToAllPlugins(msg_id, v);
1410 case ID_DEF_MENU_ACTIVATE_MEASURE:
1411 parent->StartMeasureRoute();
1414 case ID_DEF_MENU_DEACTIVATE_MEASURE:
1415 parent->CancelMeasureRoute();
1417 parent->InvalidateGL();
1418 parent->Refresh(
false);
1421 case ID_DEF_MENU_CM93OFFSET_DIALOG: {
1427 if (!parent->GetVP().b_quilt && parent->m_singleChart &&
1428 (parent->m_singleChart->GetChartType() == CHART_TYPE_CM93COMP)) {
1440 case ID_DEF_MENU_QUERY: {
1441 parent->ShowObjectQueryWindow(popx, popy, zlat, zlon);
1444 case ID_DEF_MENU_AIS_QUERY: {
1445 ShowAISTargetQueryDialog(parent, m_FoundAIS_MMSI);
1449 case ID_DEF_MENU_AIS_CPA: {
1450 auto myptarget =
g_pAIS->Get_Target_Data_From_MMSI(m_FoundAIS_MMSI);
1451 if (myptarget) myptarget->Toggle_AIS_CPA();
1455 case ID_DEF_MENU_AISSHOWTRACK: {
1456 auto myptarget =
g_pAIS->Get_Target_Data_From_MMSI(m_FoundAIS_MMSI);
1457 if (myptarget) myptarget->ToggleShowTrack();
1461 case ID_DEF_MENU_COPY_MMSI: {
1463 if (wxTheClipboard->Open()) {
1464 wxTheClipboard->SetData(
1465 new wxTextDataObject(wxString::Format(
"%09d", m_FoundAIS_MMSI)));
1466 wxTheClipboard->Close();
1471 case ID_DEF_MENU_QUILTREMOVE: {
1472 if (parent->GetVP().b_quilt) {
1473 int dbIndex = parent->m_pQuilt->GetChartdbIndexAtPix(
1474 parent->GetVP(), wxPoint(popx, popy));
1475 parent->RemoveChartFromQuilt(dbIndex);
1483 case ID_DEF_MENU_CURRENTINFO: {
1484 parent->
DrawTCWindow(popx, popy, (
void *)m_pIDXCandidate);
1485 parent->Refresh(
false);
1490 case ID_DEF_MENU_TIDEINFO: {
1491 parent->
DrawTCWindow(popx, popy, (
void *)m_pIDXCandidate);
1492 parent->Refresh(
false);
1497 case ID_DGB_MENU_NMEA_WINDOW:
1499 m_nmea_log->Raise();
1502 case ID_RT_MENU_REVERSE: {
1506 OCPNMessageBox(parent,
g_pRouteMan->GetRouteReverseMessage(),
1507 _(
"Rename Waypoints?"), wxYES_NO | wxCANCEL);
1509 if (ask_return != wxID_CANCEL) {
1510 pSelect->DeleteAllSelectableRouteSegments(m_pSelectedRoute);
1511 m_pSelectedRoute->Reverse(ask_return == wxID_YES);
1512 pSelect->AddAllSelectableRouteSegments(m_pSelectedRoute);
1514 NavObj_dB::GetInstance().UpdateRoute(m_pSelectedRoute);
1520 top_frame::Get()->InvalidateAllGL();
1521 top_frame::Get()->RefreshAllCanvas();
1526 case ID_RT_MENU_SHOWNAMES: {
1527 if (m_pSelectedRoute) {
1528 m_pSelectedRoute->ShowWaypointNames(
1529 !m_pSelectedRoute->AreWaypointNamesVisible());
1535 case ID_RT_MENU_RESEQUENCE: {
1536 if (m_pSelectedRoute) {
1540 OCPNMessageBox(parent,
g_pRouteMan->GetRouteResequenceMessage(),
1541 _(
"Rename Waypoints?"), wxYES_NO | wxCANCEL);
1543 if (ask_return != wxID_CANCEL) {
1544 m_pSelectedRoute->RenameRoutePoints();
1547 top_frame::Get()->InvalidateAllGL();
1548 top_frame::Get()->RefreshAllCanvas();
1554 case ID_RT_MENU_DELETE: {
1555 bool confirmed = RouteGui::OnDelete(parent);
1558 if (
g_pRouteMan->GetpActiveRoute() == m_pSelectedRoute)
1563 NavObj_dB::GetInstance().DeleteRoute(m_pSelectedRoute);
1566 if (RouteManagerDialog::getInstanceFlag()) {
1576 parent->undo->InvalidateUndo();
1578 top_frame::Get()->InvalidateAllGL();
1579 top_frame::Get()->RefreshAllCanvas();
1584 case ID_RT_MENU_ACTIVATE: {
1591 if (m_pSelectedRoute) {
1596 best_point = m_pSelectedRoute->GetPoint(2);
1605 case ID_RT_MENU_DEACTIVATE:
1611 case ID_RT_MENU_INSERT: {
1613 bool rename =
false;
1614 m_pSelectedRoute->InsertPointAfter(m_pFoundRoutePoint, zlat, zlon,
1617 pSelect->DeleteAllSelectableRoutePoints(m_pSelectedRoute);
1618 pSelect->DeleteAllSelectableRouteSegments(m_pSelectedRoute);
1620 pSelect->AddAllSelectableRouteSegments(m_pSelectedRoute);
1621 pSelect->AddAllSelectableRoutePoints(m_pSelectedRoute);
1634 NavObj_dB::GetInstance().UpdateRoute(m_pSelectedRoute);
1643 case ID_RT_MENU_APPEND:
1647 parent->m_pMouseRoute = m_pSelectedRoute;
1648 parent->m_routeState = m_pSelectedRoute->GetnPoints() + 1;
1650 m_pSelectedRoute->GetnPoints();
1651 parent->m_pMouseRoute->SetHiLite(50);
1653 pLast = m_pSelectedRoute->GetLastPoint();
1655 parent->m_prev_rlat = pLast->m_lat;
1656 parent->m_prev_rlon = pLast->m_lon;
1657 parent->m_prev_pMousePoint = pLast;
1659 parent->m_bAppendingRoute =
true;
1661 parent->SetCursor(*parent->pCursorPencil);
1663 androidSetRouteAnnunciator(
true);
1666 parent->HideGlobalToolbar();
1670 case ID_RT_MENU_SPLIT_LEG:
1672 dupFirstWpt =
false;
1673 case ID_RT_MENU_SPLIT_WPT:
1677 if (
g_pRouteMan->GetpActiveRoute() == m_pSelectedRoute)
1680 m_pHead =
new Route();
1681 m_pTail =
new Route();
1682 m_pHead->CloneRoute(m_pSelectedRoute, 1, m_SelectedIdx, _(
"_A"));
1683 m_pTail->CloneRoute(m_pSelectedRoute, m_SelectedIdx + splitMode,
1684 m_pSelectedRoute->GetnPoints(), _(
"_B"), dupFirstWpt);
1686 NavObj_dB::GetInstance().InsertRoute(m_pHead);
1689 NavObj_dB::GetInstance().InsertRoute(m_pTail);
1691 NavObj_dB::GetInstance().DeleteRoute(m_pSelectedRoute);
1693 pSelect->DeleteAllSelectableRoutePoints(m_pSelectedRoute);
1694 pSelect->DeleteAllSelectableRouteSegments(m_pSelectedRoute);
1696 pSelect->AddAllSelectableRouteSegments(m_pTail);
1697 pSelect->AddAllSelectableRoutePoints(m_pTail);
1698 pSelect->AddAllSelectableRouteSegments(m_pHead);
1699 pSelect->AddAllSelectableRoutePoints(m_pHead);
1710 case ID_RT_MENU_COPY:
1711 if (m_pSelectedRoute) Kml::CopyRouteToClipboard(m_pSelectedRoute);
1714 case ID_TK_MENU_COPY:
1715 if (m_pSelectedTrack) Kml::CopyTrackToClipboard(m_pSelectedTrack);
1718 case ID_WPT_MENU_COPY:
1719 if (m_pFoundRoutePoint) Kml::CopyWaypointToClipboard(m_pFoundRoutePoint);
1722 case ID_WPT_MENU_SENDTOGPS:
1723 if (m_pFoundRoutePoint) {
1724 if (parent->m_active_upload_port.Length())
1726 .SendToGPS(parent->m_active_upload_port.BeforeFirst(
' '), NULL);
1729 dlg.SetWaypoint(m_pFoundRoutePoint);
1733 dlg.Create(NULL, -1, _(
"Send to GPS") +
"...",
"");
1739 case ID_WPT_MENU_SENDTONEWGPS:
1740 if (m_pFoundRoutePoint) {
1742 dlg.SetWaypoint(m_pFoundRoutePoint);
1744 dlg.Create(NULL, -1, _(
"Send to GPS") +
"...",
"");
1749 case ID_WPT_MENU_SENDTOPEER:
1750 if (m_pFoundRoutePoint) {
1752 dlg.SetWaypoint(m_pFoundRoutePoint);
1757 MdnsCache::GetInstance().
Validate();
1758 if (MdnsCache::GetInstance().GetCache().empty())
1759 dlg.SetScanOnCreate(
true);
1762 dlg.Create(NULL, -1, _(
"Send Waypoint to OpenCPN Peer") +
"...",
"");
1767 case ID_RT_MENU_SENDTOGPS:
1768 if (m_pSelectedRoute) {
1769 if (parent->m_active_upload_port.Length())
1771 .SendToGPS(parent->m_active_upload_port.BeforeFirst(
' '),
true,
1775 dlg.SetRoute(m_pSelectedRoute);
1777 dlg.Create(NULL, -1, _(
"Send to GPS") +
"...",
"");
1783 case ID_RT_MENU_SENDTONEWGPS:
1784 if (m_pSelectedRoute) {
1786 dlg.SetRoute(m_pSelectedRoute);
1788 dlg.Create(NULL, -1, _(
"Send to GPS") +
"...",
"");
1793 case ID_RT_MENU_SENDTOPEER:
1794 if (m_pSelectedRoute) {
1796 dlg.SetRoute(m_pSelectedRoute);
1801 MdnsCache::GetInstance().
Validate();
1802 if (MdnsCache::GetInstance().GetCache().empty())
1803 dlg.SetScanOnCreate(
true);
1806 dlg.Create(NULL, -1, _(
"Send Route to OpenCPN Peer") +
"...",
"");
1811 case ID_PASTE_WAYPOINT:
1812 pupHandler_PasteWaypoint();
1815 case ID_PASTE_ROUTE:
1816 pupHandler_PasteRoute();
1819 case ID_PASTE_TRACK:
1820 pupHandler_PasteTrack();
1823 case ID_RT_MENU_DELPOINT:
1824 if (m_pSelectedRoute) {
1827 pWayPointMan->DestroyWaypoint(m_pFoundRoutePoint);
1832 if (
g_pRouteMan->IsRouteValid(m_pSelectedRoute)) {
1838 if (RouteManagerDialog::getInstanceFlag()) {
1845 top_frame::Get()->InvalidateAllGL();
1846 top_frame::Get()->RefreshAllCanvas(
true);
1851 case ID_RT_MENU_REMPOINT:
1852 if (m_pSelectedRoute) {
1854 g_pRouteMan->RemovePointFromRoute(m_pFoundRoutePoint, m_pSelectedRoute,
1855 parent->m_routeState);
1856 top_frame::Get()->InvalidateAllGL();
1857 top_frame::Get()->RefreshAllCanvas();
1861 case ID_RT_MENU_ACTPOINT:
1862 if (
g_pRouteMan->GetpActiveRoute() == m_pSelectedRoute) {
1869 case ID_RT_MENU_DEACTPOINT:
1872 case ID_RT_MENU_ACTNXTPOINT:
1873 if (
g_pRouteMan->GetpActiveRoute() == m_pSelectedRoute) {
1880 case ID_RT_MENU_PROPERTIES: {
1881 parent->ShowRoutePropertiesDialog(_(
"Route Properties"),
1886 case ID_TK_MENU_PROPERTIES: {
1887 parent->ShowTrackPropertiesDialog(m_pSelectedTrack);
1891 case ID_TK_MENU_DELETE: {
1892 int dlg_return = wxID_YES;
1893 if (g_bConfirmObjectDelete) {
1894 dlg_return = OCPNMessageBox(
1895 parent, _(
"Are you sure you want to delete this track?"),
1896 _(
"OpenCPN Track Delete"),
1897 (
long)wxYES_NO | wxCANCEL | wxYES_DEFAULT);
1900 if (dlg_return == wxID_YES) {
1902 m_pSelectedTrack = top_frame::Get()->TrackOff();
1903 g_pAIS->DeletePersistentTrack(m_pSelectedTrack);
1905 NavObj_dB::GetInstance().DeleteTrack(m_pSelectedTrack);
1906 RoutemanGui(*g_pRouteMan).DeleteTrack(m_pSelectedTrack);
1919 top_frame::Get()->InvalidateAllGL();
1920 top_frame::Get()->RefreshAllCanvas();
1925 case ID_TK_MENU_SENDTOPEER:
1926 if (m_pSelectedTrack) {
1928 dlg.SetTrack(m_pSelectedTrack);
1933 MdnsCache::GetInstance().
Validate();
1934 if (MdnsCache::GetInstance().GetCache().empty())
1935 dlg.SetScanOnCreate(
true);
1938 dlg.Create(NULL, -1, _(
"Send Track to OpenCPN Peer") +
"...",
"");
1943 case ID_RC_MENU_SCALE_IN:
1944 top_frame::Get()->DoStackDown(parent);
1946 parent->WarpPointer(r.x, r.y);
1949 case ID_RC_MENU_SCALE_OUT:
1950 top_frame::Get()->DoStackUp(parent);
1952 parent->WarpPointer(r.x, r.y);
1955 case ID_RC_MENU_ZOOM_IN:
1958 parent->WarpPointer(r.x, r.y);
1961 case ID_RC_MENU_ZOOM_OUT:
1964 parent->WarpPointer(r.x, r.y);
1967 case ID_RC_MENU_FINISH:
1968 parent->FinishRoute();
1970 parent->Refresh(
false);
1971 g_FlushNavobjChanges =
true;
1974 case ID_DEF_ZERO_XTE:
1981 ArrayOfPlugInMenuItems item_array =
1984 for (
unsigned int i = 0; i < item_array.GetCount(); i++) {
1986 int target_id = pimis->id;
1989 if (pimis->pmenu_item->GetSubMenu()) {
1990 const wxMenuItemList &items =
1991 pimis->pmenu_item->GetSubMenu()->GetMenuItems();
1992 for (wxMenuItemList::const_iterator it = items.begin();
1993 it != items.end(); ++it) {
1994 if ((*it)->GetId() ==
event.GetId()) {
1995 target_id = (*it)->GetId();
2001 if (pimis->m_pplugin && (target_id == event.GetId())) {
2002 if (pimis->extended) {
2003 std::string object_type;
2004 std::string object_ident;
2006 if ((pimis->m_in_menu.IsSameAs(
"Waypoint")) && m_pFoundRoutePoint) {
2007 object_type =
"Waypoint";
2008 object_ident = m_pFoundRoutePoint->
m_GUID.ToStdString();
2009 }
else if ((pimis->m_in_menu.IsSameAs(
"Route")) &&
2011 object_type =
"Route";
2012 object_ident = m_pSelectedRoute->
m_GUID.ToStdString();
2013 }
else if ((pimis->m_in_menu.IsSameAs(
"Track")) &&
2015 object_type =
"Track";
2016 object_ident = m_pSelectedTrack->m_GUID.ToStdString();
2017 }
else if ((pimis->m_in_menu.IsSameAs(
"AIS")) && m_FoundAIS_MMSI) {
2018 object_type =
"AIS";
2019 wxString sAIS = wxString::Format(
"%d", m_FoundAIS_MMSI);
2020 object_ident = sAIS.ToStdString();
2026 ppi->OnContextMenuItemCallbackExt(target_id, object_ident,
2027 object_type, zlat, zlon);
2038 if ((event.GetId() >= ID_DEF_MENU_GROUPBASE) &&
2041 parent->SetGroupIndex(event.GetId() - ID_DEF_MENU_GROUPBASE);
2044 parent->InvalidateGL();
AisDecoder * g_pAIS
Global instance.
Class AisDecoder and helpers.
Global state for AIS decoder.
std::unique_ptr< HostApi > GetHostApi()
HostApi factory,.
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.
bool SetVPScale(double sc, bool b_refresh=true)
Sets the viewport scale while maintaining the center point.
float GetVPScale() override
Return ViewPort scale factor, in physical pixels per meter.
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.
GoToPositionDialog * pGoToPositionDialog
Global instance.
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, not persisted in configuration file.
Read and write KML Format.
MarkInfoDlg * g_pMarkInfoDialog
global instance
Waypoint properties maintenance dialog.
MySQL based storage for routes, tracks, etc.
bool bGPSValid
Indicate whether the Global Navigation Satellite System (GNSS) has a valid position.
double gHdt
True heading in degrees (0-359.99).
double gLat
Vessel's current latitude in decimal degrees.
double gCog
Course over ground in degrees (0-359.99).
double gSog
Speed over ground in knots.
double gLon
Vessel's current longitude in decimal degrees.
Position, course, speed, etc.
Confirm peer transfer PIN code dialog.
Tools to send data to plugins.
PlugInManager * g_pi_manager
Global instance.
PlugInManager and helper classes – Mostly gui parts (dialogs) and plugin API stuff.
Purpose: Track and Trackpoint drawing stuff.
RoutePropDlgImpl * pRoutePropDialog
Global instance.
RoutePoint * pAnchorWatchPoint2
Global instance.
Routeman * g_pRouteMan
Global instance.
RouteList * pRouteList
Global instance.
RoutePoint * pAnchorWatchPoint1
Global instance.
RouteManagerDialog * pRouteManagerDialog
Global instance.
Select * pSelect
Global instance.
Selected route, segment, waypoint, etc.
Send route/waypoint to GPS dialog.
Send Route/Waypoint/Track to peer dialog.
Tide and Current Manager @TODO Add original author copyright.
Abstract gFrame/MyFrame interface.
ActiveTrack * g_pActiveTrack
global instance
Recorded track abstraction.
Track and Trackpoint drawing stuff.
TrackPropDlg * pTrackPropDialog
Global instance.
Framework for Undo features.