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>
85#include "androidUTIL.h"
90 ID_DEF_MENU_MAX_DETAIL = 1,
92 ID_DEF_MENU_SCALE_OUT,
96 ID_DEF_MENU_MOVE_BOAT_HERE,
97 ID_DEF_MENU_GOTO_HERE,
98 ID_DEF_MENU_GOTOPOSITION,
101 ID_WP_MENU_PROPERTIES,
103 ID_RT_MENU_DEACTIVATE,
107 ID_RT_MENU_SPLIT_LEG,
108 ID_RT_MENU_SPLIT_WPT,
111 ID_WPT_MENU_SENDTOGPS,
112 ID_WPT_MENU_SENDTONEWGPS,
113 ID_WPT_MENU_SENDTOPEER,
121 ID_RT_MENU_DEACTPOINT,
122 ID_RT_MENU_ACTNXTPOINT,
124 ID_RT_MENU_PROPERTIES,
125 ID_RT_MENU_SENDTOGPS,
126 ID_RT_MENU_SENDTONEWGPS,
127 ID_RT_MENU_SHOWNAMES,
128 ID_RT_MENU_RESEQUENCE,
129 ID_RT_MENU_SENDTOPEER,
130 ID_WP_MENU_SET_ANCHORWATCH,
131 ID_WP_MENU_CLEAR_ANCHORWATCH,
132 ID_DEF_MENU_AISTARGETLIST,
133 ID_DEF_MENU_AIS_CPAWARNING,
136 ID_RC_MENU_SCALE_OUT,
140 ID_DEF_MENU_AIS_QUERY,
142 ID_DEF_MENU_AISSHOWTRACK,
143 ID_DEF_MENU_ACTIVATE_MEASURE,
144 ID_DEF_MENU_DEACTIVATE_MEASURE,
145 ID_DEF_MENU_COPY_MMSI,
150 ID_DEF_MENU_CM93OFFSET_DIALOG,
152 ID_TK_MENU_PROPERTIES,
154 ID_TK_MENU_SENDTOPEER,
155 ID_WP_MENU_ADDITIONAL_INFO,
157 ID_DEF_MENU_QUILTREMOVE,
161 ID_DEF_MENU_TOGGLE_FULL,
162 ID_DEF_MENU_TIDEINFO,
163 ID_DEF_MENU_CURRENTINFO,
167 ID_DGB_MENU_NMEA_WINDOW,
169 ID_DEF_MENU_GROUPBASE,
178int CanvasMenuHandler::GetNextContextMenuId() {
179 return ID_DEF_MENU_LAST +
183wxFont CanvasMenuHandler::m_scaledFont;
186CanvasMenuHandler::CanvasMenuHandler(
ChartCanvas *parentCanvas,
189 int selectedAIS_MMSI,
190 void *selectedTCIndex, wxWindow *nmea_log)
191 : m_nmea_log(nmea_log) {
192 parent = parentCanvas;
193 m_pSelectedRoute = selectedRoute;
194 m_pSelectedTrack = selectedTrack;
195 m_pFoundRoutePoint = selectedPoint;
196 m_FoundAIS_MMSI = selectedAIS_MMSI;
197 m_pIDXCandidate = selectedTCIndex;
198 if (!m_scaledFont.IsOk()) {
200 m_scaledFont = *qFont;
206CanvasMenuHandler::~CanvasMenuHandler() {}
212void CanvasMenuHandler::PrepareMenuItem(wxMenuItem *item) {
213#if defined(__WXMSW__)
214 wxColour ctrl_back_color = GetGlobalColor(
"DILG1");
215 item->SetBackgroundColour(ctrl_back_color);
216 wxColour menu_text_color = GetGlobalColor(
"UITX1");
217 item->SetTextColour(menu_text_color);
221void CanvasMenuHandler::MenuPrepend1(wxMenu *menu,
int id, wxString label) {
222 wxMenuItem *item =
new wxMenuItem(menu,
id, label);
223#if defined(__WXMSW__)
224 item->SetFont(m_scaledFont);
229 item->SetFont(sFont);
232 PrepareMenuItem(item);
234 if (g_btouch) menu->InsertSeparator(0);
238void CanvasMenuHandler::MenuAppend1(wxMenu *menu,
int id, wxString label) {
239 wxMenuItem *item =
new wxMenuItem(menu,
id, label);
240#if defined(__WXMSW__)
241 item->SetFont(m_scaledFont);
246 item->SetFont(sFont);
249 PrepareMenuItem(item);
252 if (g_btouch) menu->AppendSeparator();
255void CanvasMenuHandler::SetMenuItemFont1(wxMenuItem *item) {
256#if defined(__WXMSW__)
257 item->SetFont(m_scaledFont);
260#if defined(__ANDROID__)
262 item->SetFont(*qFont);
265 PrepareMenuItem(item);
268void CanvasMenuHandler::CanvasPopupMenu(
int x,
int y,
int seltype) {
269 wxMenu *contextMenu =
new wxMenu;
270 wxMenu *menuWaypoint = NULL;
271 wxMenu *menuRoute = NULL;
272 wxMenu *menuTrack = NULL;
273 wxMenu *menuAIS = NULL;
275 wxMenu *subMenuChart =
new wxMenu;
276 wxMenu *subMenuUndo =
new wxMenu(
"Undo...Ctrl-Z");
279 wxMenu *subMenuRedo =
new wxMenu(
"Redo...Shift-Ctrl-Z");
281 wxMenu *subMenuRedo =
new wxMenu(
"Redo...Ctrl-Y");
283 wxMenu *subMenuDebug =
new wxMenu(
"");
284 MenuAppend1(subMenuDebug, ID_DGB_MENU_NMEA_WINDOW, _(
"Show Data Monitor"));
286 wxMenu *menuFocus = contextMenu;
291 if (!g_bBasicMenus || (seltype != SELTYPE_ROUTECREATE)) {
292 bool bsubMenus =
false;
295 if (parent->undo->AnythingToUndo()) {
297 wxMenuItem *subMenuItemundo =
298 contextMenu->AppendSubMenu(subMenuUndo, _(
"Undo"));
301 undoItem << _(
"Undo") <<
" "
302 << parent->undo->GetNextUndoableAction()->Description();
303 MenuAppend1(subMenuUndo, ID_UNDO, undoItem);
305 if (parent->undo->AnythingToRedo()) {
307 wxMenuItem *subMenuItemRedo =
308 contextMenu->AppendSubMenu(subMenuRedo, _(
"Redo"));
311 redoItem << _(
"Redo") <<
" "
312 << parent->undo->GetNextRedoableAction()->Description();
313 MenuAppend1(subMenuRedo, ID_REDO, redoItem);
316 if (parent->undo->AnythingToUndo()) {
318 undoItem << _(
"Undo") <<
" "
319 << parent->undo->GetNextUndoableAction()->Description();
320 MenuAppend1(contextMenu, ID_UNDO, _menuText(undoItem,
"Ctrl-Z"));
323 if (parent->undo->AnythingToRedo()) {
325 redoItem << _(
"Redo") <<
" "
326 << parent->undo->GetNextRedoableAction()->Description();
328 MenuAppend1(contextMenu, ID_REDO, _menuText(redoItem,
"Shift-Ctrl-Z"));
330 MenuAppend1(contextMenu, ID_REDO, _menuText(redoItem,
"Ctrl-Y"));
336 if (seltype == SELTYPE_ROUTECREATE) {
337 MenuAppend1(contextMenu, ID_RC_MENU_FINISH,
338 _menuText(_(
"End Route"),
"Esc"));
341 if (!parent->m_pMouseRoute) {
342 if (parent->m_bMeasure_Active)
343 MenuAppend1(contextMenu, ID_DEF_MENU_DEACTIVATE_MEASURE,
344 _menuText(_(
"Measure Off"),
"Esc"));
346 MenuAppend1(contextMenu, ID_DEF_MENU_ACTIVATE_MEASURE,
347 _menuText(_(
"Measure"),
"M"));
350 bool ais_areanotice =
false;
351 if (
g_pAIS && parent->GetShowAIS() && g_bShowAreaNotices) {
354 for (
const auto &target :
g_pAIS->GetAreaNoticeSourcesList()) {
355 auto target_data = target.second;
356 if (!target_data->area_notices.empty()) {
357 for (
auto &ani : target_data->area_notices) {
361 for (Ais8_001_22_SubAreaList::iterator sa =
362 area_notice.sub_areas.begin();
363 sa != area_notice.sub_areas.end(); ++sa) {
365 case AIS8_001_22_SHAPE_CIRCLE: {
366 wxPoint target_point;
369 bbox.Expand(target_point);
370 if (sa->radius_m > 0.0) bbox.EnLarge(sa->radius_m * vp_scale);
373 case AIS8_001_22_SHAPE_RECT:
374 case AIS8_001_22_SHAPE_POLYGON:
375 case AIS8_001_22_SHAPE_POLYLINE: {
376 double lat = sa->latitude;
377 double lon = sa->longitude;
378 for (
int i = 0; i < 4; ++i) {
379 ll_gc_ll(lat, lon, sa->angles[i], sa->dists_m[i] / 1852.0,
381 wxPoint target_point;
383 bbox.Expand(target_point);
387 case AIS8_001_22_SHAPE_SECTOR: {
388 double lat1 = sa->latitude;
389 double lon1 = sa->longitude;
391 wxPoint target_point;
393 bbox.Expand(target_point);
394 for (
int i = 0; i < 18; ++i) {
398 i * (sa->right_bound_deg - sa->left_bound_deg) / 18,
399 sa->radius_m / 1852.0, &lat, &lon);
401 bbox.Expand(target_point);
403 ll_gc_ll(lat1, lon1, sa->right_bound_deg, sa->radius_m / 1852.0,
406 bbox.Expand(target_point);
412 if (bbox.GetValid() && bbox.PointInBox(x, y)) {
413 ais_areanotice =
true;
422 if (parent->GetpCurrentStack())
423 nChartStack = parent->GetpCurrentStack()->nEntry;
425 if (!parent->GetVP().b_quilt) {
426 if (nChartStack > 1) {
427 MenuAppend1(contextMenu, ID_DEF_MENU_MAX_DETAIL, _(
"Max Detail Here"));
428 MenuAppend1(contextMenu, ID_DEF_MENU_SCALE_IN,
429 _menuText(_(
"Scale In"),
"Ctrl-Left"));
430 MenuAppend1(contextMenu, ID_DEF_MENU_SCALE_OUT,
431 _menuText(_(
"Scale Out"),
"Ctrl-Right"));
434 if ((parent->m_singleChart &&
435 (parent->m_singleChart->GetChartFamily() == CHART_FAMILY_VECTOR)) ||
437 MenuAppend1(contextMenu, ID_DEF_MENU_QUERY, _(
"Object Query") +
"...");
442 parent->m_pQuilt->GetChartAtPix(parent->GetVP(), wxPoint(x, y));
443 if ((pChartTest && (pChartTest->GetChartFamily() == CHART_FAMILY_VECTOR)) ||
445 MenuAppend1(contextMenu, ID_DEF_MENU_QUERY, _(
"Object Query") +
"...");
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"));
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 std::unique_ptr<HostApi> host_api =
GetHostApi();
604 auto *api_121 =
dynamic_cast<HostApi121 *
>(host_api.get());
606 if (!g_bBasicMenus || (seltype != SELTYPE_ROUTECREATE)) {
608 if (api_121 && parent->GetShowAIS() &&
609 (seltype & SELTYPE_AISTARGET &&
610 !(api_121->GetContextMenuMask() &
611 api_121->kContextMenuDisableAistarget))) {
612 auto myptarget =
g_pAIS->Get_Target_Data_From_MMSI(m_FoundAIS_MMSI);
613 if (!g_bBasicMenus && myptarget) {
614 name = myptarget->GetFullName();
615 if (name.IsEmpty()) name.Printf(
"%d", m_FoundAIS_MMSI);
616 name.Prepend(
" ( ").Append(
" )");
618 name = wxEmptyString;
619 menuAIS =
new wxMenu(_(
"AIS") + name);
620 MenuAppend1(menuAIS, ID_DEF_MENU_AIS_QUERY, _(
"Target Query..."));
621 if (myptarget && myptarget->bCPA_Valid &&
622 (myptarget->n_alert_state != AIS_ALERT_SET)) {
623 if (myptarget->b_show_AIS_CPA)
624 MenuAppend1(menuAIS, ID_DEF_MENU_AIS_CPA, _(
"Hide Target CPA"));
626 MenuAppend1(menuAIS, ID_DEF_MENU_AIS_CPA, _(
"Show Target CPA"));
628 MenuAppend1(menuAIS, ID_DEF_MENU_AISTARGETLIST, _(
"Target List..."));
629 if (myptarget->Class != AIS_METEO ) {
630 if (myptarget && !myptarget->b_PersistTrack) {
631 if (myptarget->b_show_track)
632 MenuAppend1(menuAIS, ID_DEF_MENU_AISSHOWTRACK,
633 _(
"Hide Target Track"));
635 MenuAppend1(menuAIS, ID_DEF_MENU_AISSHOWTRACK,
636 _(
"Show Target Track"));
640 MenuAppend1(menuAIS, ID_DEF_MENU_COPY_MMSI, _(
"Copy Target MMSI"));
641 menuAIS->AppendSeparator();
643 if (!parent->GetVP().b_quilt) {
644 if ((parent->m_singleChart &&
645 (parent->m_singleChart->GetChartFamily() ==
646 CHART_FAMILY_VECTOR))) {
647 MenuAppend1(menuAIS, ID_DEF_MENU_QUERY, _(
"Object Query..."));
652 parent->m_pQuilt->GetChartAtPix(parent->GetVP(), wxPoint(x, y));
654 (pChartTest->GetChartFamily() == CHART_FAMILY_VECTOR))) {
655 MenuAppend1(menuAIS, ID_DEF_MENU_QUERY, _(
"Object Query..."));
661 bool enable_list =
true;
663 double char_x = gFrame->GetSize().x / gFrame->GetCharWidth();
664 double char_y = gFrame->GetSize().y / gFrame->GetCharWidth();
665 double char_min = wxMin(char_x, char_y);
666 if (char_min < 100) enable_list =
false;
670 if (wxMin(size_x, size_y) < 100)
674 MenuAppend1(contextMenu, ID_DEF_MENU_AISTARGETLIST,
675 _(
"AIS target list") +
"...");
677 wxString nextCPAstatus = g_bCPAWarn ? _(
"Hide") : _(
"Show");
678 MenuAppend1(contextMenu, ID_DEF_MENU_AIS_CPAWARNING,
679 _menuText(nextCPAstatus +
" " + _(
"CPA alarm "),
"W"));
683 if (g_enable_root_menu_debug) {
684 wxMenuItem *subItemDebug =
685 contextMenu->AppendSubMenu(subMenuDebug, _(
"Debug"));
686 if (g_btouch) contextMenu->AppendSeparator();
687 SetMenuItemFont1(subItemDebug);
690 if (seltype & SELTYPE_ROUTESEGMENT &&
691 !(api_121->GetContextMenuMask() & api_121->kContextMenuDisableRoute)) {
692 if (!g_bBasicMenus && m_pSelectedRoute) {
694 if (name.IsEmpty()) name = _(
"Unnamed Route");
695 name.Prepend(
" ( ").Append(
" )");
697 name = wxEmptyString;
699 if (m_pSelectedRoute && m_pSelectedRoute->
m_bIsInLayer) blay =
true;
702 menuRoute =
new wxMenu(_(
"Layer Route") + name);
703 MenuAppend1(menuRoute, ID_RT_MENU_PROPERTIES, _(
"Properties") +
"...");
704 if (m_pSelectedRoute) {
705 if (m_pSelectedRoute->IsActive()) {
706 int indexActive = m_pSelectedRoute->GetIndexOf(
708 if ((indexActive + 1) <= m_pSelectedRoute->GetnPoints()) {
709 MenuAppend1(menuRoute, ID_RT_MENU_ACTNXTPOINT,
710 _(
"Activate Next Waypoint"));
712 MenuAppend1(menuRoute, ID_RT_MENU_DEACTIVATE, _(
"Deactivate"));
713 MenuAppend1(menuRoute, ID_DEF_ZERO_XTE, _(
"Zero XTE"));
715 MenuAppend1(menuRoute, ID_RT_MENU_ACTIVATE, _(
"Activate"));
719 menuRoute =
new wxMenu(_(
"Route") + name);
720 MenuAppend1(menuRoute, ID_RT_MENU_PROPERTIES, _(
"Properties") +
"...");
721 if (m_pSelectedRoute) {
722 if (m_pSelectedRoute->IsActive()) {
723 int indexActive = m_pSelectedRoute->GetIndexOf(
725 if ((indexActive + 1) <= m_pSelectedRoute->GetnPoints()) {
726 MenuAppend1(menuRoute, ID_RT_MENU_ACTNXTPOINT,
727 _(
"Activate Next Waypoint"));
729 MenuAppend1(menuRoute, ID_RT_MENU_DEACTIVATE, _(
"Deactivate"));
730 MenuAppend1(menuRoute, ID_DEF_ZERO_XTE, _(
"Zero XTE"));
732 MenuAppend1(menuRoute, ID_RT_MENU_ACTIVATE, _(
"Activate"));
735 MenuAppend1(menuRoute, ID_RT_MENU_INSERT, _(
"Insert Waypoint"));
736 MenuAppend1(menuRoute, ID_RT_MENU_APPEND, _(
"Append Waypoint"));
737 if (!(seltype & SELTYPE_ROUTEPOINT) && m_pSelectedRoute) {
738 m_SelectedIdx = m_pSelectedRoute->GetIndexOf(m_pFoundRoutePoint);
739 if (m_SelectedIdx > 1 &&
740 m_SelectedIdx < m_pSelectedRoute->GetnPoints() - 1)
741 MenuAppend1(menuRoute, ID_RT_MENU_SPLIT_LEG, _(
"Split around Leg"));
743 MenuAppend1(menuRoute, ID_RT_MENU_COPY, _(
"Copy as KML") +
"...");
744 MenuAppend1(menuRoute, ID_RT_MENU_DELETE, _(
"Delete") +
"...");
745 MenuAppend1(menuRoute, ID_RT_MENU_REVERSE, _(
"Reverse..."));
746 if (m_pSelectedRoute) {
747 if (m_pSelectedRoute->AreWaypointNamesVisible())
748 MenuAppend1(menuRoute, ID_RT_MENU_SHOWNAMES,
749 _(
"Hide Waypoint Names"));
751 MenuAppend1(menuRoute, ID_RT_MENU_SHOWNAMES,
752 _(
"Show Waypoint Names"));
754 MenuAppend1(menuRoute, ID_RT_MENU_RESEQUENCE,
755 _(
"Resequence Waypoints..."));
758 wxString port = parent->FindValidUploadPort();
759 parent->m_active_upload_port = port;
760 wxString item = _(
"Send to GPS");
761 if (!port.IsEmpty()) {
766 MenuAppend1(menuRoute, ID_RT_MENU_SENDTOGPS, item);
768 if (!port.IsEmpty()) {
769 wxString item = _(
"Send to new GPS");
770 MenuAppend1(menuRoute, ID_RT_MENU_SENDTONEWGPS, item);
773 wxString itemstp = SYMBOL_STP_TITLE;
774 MenuAppend1(menuRoute, ID_RT_MENU_SENDTOPEER, itemstp);
777 if (menuFocus != menuAIS) menuFocus = menuRoute;
780 if (seltype & SELTYPE_TRACKSEGMENT &&
781 !(api_121->GetContextMenuMask() & api_121->kContextMenuDisableTrack)) {
782 name = wxEmptyString;
783 if (!g_bBasicMenus && m_pSelectedTrack)
784 name =
" ( " + m_pSelectedTrack->GetName(
true) +
" )";
786 name = wxEmptyString;
788 if (m_pSelectedTrack && m_pSelectedTrack->m_bIsInLayer) blay =
true;
791 menuTrack =
new wxMenu(_(
"Layer Track") + name);
792 MenuAppend1(menuTrack, ID_TK_MENU_PROPERTIES, _(
"Properties") +
"...");
794 menuTrack =
new wxMenu(_(
"Track") + name);
795 MenuAppend1(menuTrack, ID_TK_MENU_PROPERTIES, _(
"Properties") +
"...");
796 MenuAppend1(menuTrack, ID_TK_MENU_COPY, _(
"Copy as KML"));
797 MenuAppend1(menuTrack, ID_TK_MENU_DELETE, _(
"Delete") +
"...");
800 wxString itemstp = SYMBOL_STP_TITLE;
801 MenuAppend1(menuTrack, ID_TK_MENU_SENDTOPEER, itemstp);
804 if (menuFocus != menuAIS) menuFocus = menuTrack;
807 if (seltype & SELTYPE_ROUTEPOINT &&
808 !(api_121->GetContextMenuMask() &
809 api_121->kContextMenuDisableWaypoint)) {
810 if (!g_bBasicMenus && m_pFoundRoutePoint) {
811 name = m_pFoundRoutePoint->GetName();
812 if (name.IsEmpty()) name = _(
"Unnamed Waypoint");
813 name.Prepend(
" ( ").Append(
" )");
815 name = wxEmptyString;
817 if (m_pFoundRoutePoint && m_pFoundRoutePoint->
m_bIsInLayer) blay =
true;
820 menuWaypoint =
new wxMenu(_(
"Layer Waypoint") + name);
821 MenuAppend1(menuWaypoint, ID_WP_MENU_PROPERTIES,
822 _(
"Properties") +
"...");
824 if (m_pSelectedRoute && m_pSelectedRoute->IsActive())
825 MenuAppend1(menuWaypoint, ID_RT_MENU_ACTPOINT, _(
"Activate"));
827 menuWaypoint =
new wxMenu(_(
"Waypoint") + name);
828 MenuAppend1(menuWaypoint, ID_WP_MENU_PROPERTIES,
829 _(
"Properties") +
"...");
830 if (m_pSelectedRoute && m_pSelectedRoute->IsActive()) {
832 MenuAppend1(menuWaypoint, ID_RT_MENU_ACTPOINT, _(
"Activate"));
835 if (m_pSelectedRoute && m_pSelectedRoute->IsActive()) {
837 int indexActive = m_pSelectedRoute->GetIndexOf(
839 if ((indexActive + 1) <= m_pSelectedRoute->GetnPoints())
840 MenuAppend1(menuWaypoint, ID_RT_MENU_ACTNXTPOINT,
841 _(
"Activate Next Waypoint"));
844 if (m_pSelectedRoute && m_pSelectedRoute->GetnPoints() > 2) {
845 MenuAppend1(menuWaypoint, ID_RT_MENU_REMPOINT,
846 _(
"Remove from Route"));
848 m_SelectedIdx = m_pSelectedRoute->GetIndexOf(m_pFoundRoutePoint);
849 if (m_SelectedIdx > 1 &&
850 m_SelectedIdx < m_pSelectedRoute->GetnPoints())
851 MenuAppend1(menuWaypoint, ID_RT_MENU_SPLIT_WPT,
852 _(
"Split Route at Waypoint"));
855 MenuAppend1(menuWaypoint, ID_WPT_MENU_COPY, _(
"Copy as KML"));
857 if (m_pFoundRoutePoint && m_pFoundRoutePoint->GetIconName() !=
"mob")
858 MenuAppend1(menuWaypoint, ID_RT_MENU_DELPOINT, _(
"Delete"));
861 wxString port = parent->FindValidUploadPort();
862 parent->m_active_upload_port = port;
863 wxString item = _(
"Send to GPS");
864 if (!port.IsEmpty()) {
869 MenuAppend1(menuWaypoint, ID_WPT_MENU_SENDTOGPS, item);
871 if (!port.IsEmpty()) {
872 wxString item = _(
"Send to new GPS");
873 MenuAppend1(menuWaypoint, ID_WPT_MENU_SENDTONEWGPS, item);
876 MenuAppend1(menuWaypoint, ID_WPT_MENU_SENDTOPEER,
881 if (menuFocus != menuAIS) menuFocus = menuWaypoint;
884 if (seltype & SELTYPE_MARKPOINT &&
885 !(api_121->GetContextMenuMask() &
886 api_121->kContextMenuDisableWaypoint)) {
887 if (!g_bBasicMenus && m_pFoundRoutePoint) {
888 name = m_pFoundRoutePoint->GetName();
889 if (name.IsEmpty()) name = _(
"Unnamed Mark");
890 name.Prepend(
" ( ").Append(
" )");
892 name = wxEmptyString;
894 if (m_pFoundRoutePoint && m_pFoundRoutePoint->
m_bIsInLayer) blay =
true;
897 menuWaypoint =
new wxMenu(_(
"Layer Waypoint") + name);
898 MenuAppend1(menuWaypoint, ID_WP_MENU_PROPERTIES,
899 _(
"Properties") +
"...");
901 menuWaypoint =
new wxMenu(_(
"Mark") + name);
902 MenuAppend1(menuWaypoint, ID_WP_MENU_PROPERTIES,
903 _(
"Properties") +
"...");
906 MenuAppend1(menuWaypoint, ID_WP_MENU_GOTO, _(
"Navigate To This"));
908 MenuAppend1(menuWaypoint, ID_WPT_MENU_COPY, _(
"Copy as KML"));
910 if (m_pFoundRoutePoint && m_pFoundRoutePoint->GetIconName() !=
"mob")
911 MenuAppend1(menuWaypoint, ID_WP_MENU_DELPOINT, _(
"Delete"));
914 wxString port = parent->FindValidUploadPort();
915 parent->m_active_upload_port = port;
916 wxString item = _(
"Send to GPS");
917 if (!port.IsEmpty()) {
922 MenuAppend1(menuWaypoint, ID_WPT_MENU_SENDTOGPS, item);
924 MenuAppend1(menuWaypoint, ID_WPT_MENU_SENDTOPEER,
930 MenuAppend1(menuWaypoint, ID_WP_MENU_CLEAR_ANCHORWATCH,
931 _(
"Clear Anchor Watch"));
933 if (m_pFoundRoutePoint && !(m_pFoundRoutePoint->
m_bIsInLayer) &&
937 DistanceBearingMercator(m_pFoundRoutePoint->m_lat,
938 m_pFoundRoutePoint->m_lon,
gLat,
gLon, &brg,
940 if (dist * 1852. <= g_nAWMax)
941 MenuAppend1(menuWaypoint, ID_WP_MENU_SET_ANCHORWATCH,
942 _(
"Set Anchor Watch"));
947 if (menuFocus != menuAIS) menuFocus = menuWaypoint;
951 AddPluginContextMenuItems(contextMenu, menuRoute, menuTrack, menuWaypoint,
955 enum { WPMENU = 1, TKMENU = 2, RTMENU = 4, MMMENU = 8 };
957 if (!g_bBasicMenus && menuFocus != contextMenu) {
958 if (global_color_scheme != GLOBAL_COLOR_SCHEME_DUSK &&
959 global_color_scheme != GLOBAL_COLOR_SCHEME_NIGHT) {
960 menuFocus->AppendSeparator();
963 wxMenuItem *subMenu1;
964 if (menuWaypoint && menuFocus != menuWaypoint) {
966 menuFocus->AppendSubMenu(menuWaypoint, menuWaypoint->GetTitle());
967 SetMenuItemFont1(subMenu1);
970 menuWaypoint->SetTitle(wxEmptyString);
973 if (menuTrack && menuFocus != menuTrack) {
974 subMenu1 = menuFocus->AppendSubMenu(menuTrack, menuTrack->GetTitle());
975 SetMenuItemFont1(subMenu1);
978 menuTrack->SetTitle(wxEmptyString);
981 if (menuRoute && menuFocus != menuRoute) {
982 subMenu1 = menuFocus->AppendSubMenu(menuRoute, menuRoute->GetTitle());
983 SetMenuItemFont1(subMenu1);
986 menuRoute->SetTitle(wxEmptyString);
989 subMenu1 = menuFocus->AppendSubMenu(contextMenu, _(
"Main Menu"));
990 SetMenuItemFont1(subMenu1);
994 if (!subMenuChart->GetMenuItemCount()) contextMenu->Destroy(subItemChart);
999 if (seltype & SELTYPE_TIDEPOINT) {
1000 menuFocus->AppendSeparator();
1002 MenuAppend1(menuFocus, ID_DEF_MENU_TIDEINFO, _(
"Show Tide Information"));
1005 if (seltype & SELTYPE_CURRENTPOINT) {
1006 if (!bsep) menuFocus->AppendSeparator();
1007 MenuAppend1(menuFocus, ID_DEF_MENU_CURRENTINFO,
1008 _(
"Show Current Information"));
1014 androidEnableBackButton(
false);
1015 androidEnableOptionsMenu(
false);
1023 parent->PopupMenu(menuFocus, x, y);
1026 androidEnableBackButton(
true);
1027 androidEnableOptionsMenu(
true);
1034 if (!(sub_menu & MMMENU))
delete contextMenu;
1035 if (!(sub_menu & RTMENU))
delete menuRoute;
1036 if (!(sub_menu & TKMENU))
delete menuTrack;
1037 if (!(sub_menu & WPMENU))
delete menuWaypoint;
1041void CanvasMenuHandler::AddPluginContextMenuItems(wxMenu *contextMenu,
1044 wxMenu *menuWaypoint,
1050 ArrayOfPlugInMenuItems item_array =
1053 for (
unsigned int i = 0; i < item_array.GetCount(); i++) {
1055 if (!pimis->b_viz)
continue;
1057 wxMenu *submenu = NULL;
1058 if (pimis->pmenu_item->GetSubMenu()) {
1060 auto submenu_proto = pimis->pmenu_item->GetSubMenu();
1061 submenu =
new wxMenu();
1062 const wxMenuItemList &items =
1063 pimis->pmenu_item->GetSubMenu()->GetMenuItems();
1064 for (wxMenuItemList::const_iterator it = items.begin(); it != items.end();
1066 int id = (*it)->GetId();
1068 new wxMenuItem(submenu,
id, (*it)->GetItemLabelText(),
1069 (*it)->GetHelp(), (*it)->GetKind());
1072 psmi->SetFont(m_scaledFont);
1077 psmi->SetFont(sFont);
1080 PrepareMenuItem(psmi);
1081 submenu->Append(psmi);
1082 psmi->Check((*it)->IsChecked());
1086 wxMenuItem *pmi =
new wxMenuItem(
1087 contextMenu, pimis->id, pimis->pmenu_item->GetItemLabelText(),
1088 pimis->pmenu_item->GetHelp(), pimis->pmenu_item->GetKind(), submenu);
1090 pmi->SetFont(m_scaledFont);
1095 pmi->SetFont(sFont);
1098 PrepareMenuItem(pmi);
1100 wxMenu *dst = contextMenu;
1101 if (pimis->m_in_menu ==
"Waypoint")
1103 else if (pimis->m_in_menu ==
"Route")
1105 else if (pimis->m_in_menu ==
"Track")
1107 else if (pimis->m_in_menu ==
"AIS")
1112 dst->Enable(pimis->id, !pimis->b_grey);
1117void CanvasMenuHandler::PopupMenuHandler(wxCommandEvent &event) {
1124 bool dupFirstWpt =
true, showRPD;
1129 switch (event.GetId()) {
1130 case ID_DEF_MENU_MAX_DETAIL:
1133 parent->ClearbFollow();
1135 parent->parent_frame->DoChartUpdate();
1137 parent->SelectChartFromStack(0,
false, CHART_TYPE_DONTCARE,
1138 CHART_FAMILY_RASTER);
1141 case ID_DEF_MENU_SCALE_IN:
1142 parent->DoCanvasStackDelta(-1);
1145 case ID_DEF_MENU_SCALE_OUT:
1146 parent->DoCanvasStackDelta(1);
1150 parent->undo->UndoLastAction();
1151 parent->InvalidateGL();
1152 parent->Refresh(
false);
1156 parent->undo->RedoNextAction();
1157 parent->InvalidateGL();
1158 parent->Refresh(
false);
1161 case ID_DEF_MENU_MOVE_BOAT_HERE:
1164 gFrame->UpdateStatusBar();
1167 case ID_DEF_MENU_GOTO_HERE: {
1169 wxEmptyString, wxEmptyString);
1170 pSelect->AddSelectableRoutePoint(zlat, zlon, pWP_dest);
1173 wxEmptyString, wxEmptyString);
1179 temp_route->AddPoint(pWP_src);
1180 temp_route->AddPoint(pWP_dest);
1183 pWP_dest, temp_route);
1199 case ID_DEF_MENU_DROP_WP: {
1201 wxEmptyString, wxEmptyString);
1203 pSelect->AddSelectableRoutePoint(zlat, zlon, pWP);
1204 NavObj_dB::GetInstance().InsertRoutePoint(pWP);
1209 if (RouteManagerDialog::getInstanceFlag()) {
1210 if (pRouteManagerDialog && pRouteManagerDialog->IsShown()) {
1211 pRouteManagerDialog->UpdateWptListCtrl();
1215 parent->undo->BeforeUndoableAction(Undo_CreateWaypoint, pWP,
1216 Undo_HasParent, NULL);
1217 parent->undo->AfterUndoableAction(NULL);
1218 gFrame->RefreshAllCanvas(
false);
1219 gFrame->InvalidateAllGL();
1220 g_FlushNavobjChanges =
true;
1224 case ID_DEF_MENU_NEW_RT: {
1225 parent->StartRoute();
1229 case ID_DEF_MENU_AISTARGETLIST:
1230 parent->ShowAISTargetList();
1233 case ID_DEF_MENU_AIS_CPAWARNING:
1234 parent->ToggleCPAWarn();
1237 case ID_WP_MENU_GOTO: {
1239 wxEmptyString, wxEmptyString);
1245 temp_route->AddPoint(pWP_src);
1246 temp_route->AddPoint(m_pFoundRoutePoint);
1247 m_pFoundRoutePoint->SetShared(
true);
1249 pSelect->AddSelectableRouteSegment(
gLat,
gLon, m_pFoundRoutePoint->m_lat,
1250 m_pFoundRoutePoint->m_lon, pWP_src,
1251 m_pFoundRoutePoint, temp_route);
1253 wxString name = m_pFoundRoutePoint->GetName();
1254 if (name.IsEmpty()) name = _(
"(Unnamed Waypoint)");
1255 wxString rteName = _(
"Go to ");
1256 rteName.Append(name);
1270 case ID_DEF_MENU_COGUP:
1271 parent->SetUpMode(COURSE_UP_MODE);
1274 case ID_DEF_MENU_HEADUP:
1275 parent->SetUpMode(HEAD_UP_MODE);
1278 case ID_DEF_MENU_NORTHUP:
1279 parent->SetUpMode(NORTH_UP_MODE);
1282 case ID_DEF_MENU_TOGGLE_FULL:
1283 gFrame->ToggleFullScreen();
1286 case ID_DEF_MENU_GOTOPOSITION:
1295 case ID_WP_MENU_DELPOINT: {
1304 if (m_pFoundRoutePoint && !(m_pFoundRoutePoint->
m_bIsInLayer) &&
1305 (m_pFoundRoutePoint->GetIconName() !=
"mob")) {
1309 wxArrayPtrVoid *proute_array =
1312 pWayPointMan->DestroyWaypoint(m_pFoundRoutePoint);
1313 delete proute_array;
1315 parent->undo->BeforeUndoableAction(
1316 Undo_DeleteWaypoint, m_pFoundRoutePoint, Undo_IsOrphanded,
1318 NavObj_dB::GetInstance().DeleteRoutePoint(m_pFoundRoutePoint);
1319 pSelect->DeleteSelectablePoint(m_pFoundRoutePoint,
1320 SELTYPE_ROUTEPOINT);
1321 if (NULL != pWayPointMan)
1323 parent->undo->AfterUndoableAction(NULL);
1330 if (RouteManagerDialog::getInstanceFlag()) {
1331 if (pRouteManagerDialog) {
1332 if (pRouteManagerDialog->IsShown())
1333 pRouteManagerDialog->UpdateWptListCtrl();
1337 gFrame->RefreshAllCanvas(
false);
1338 gFrame->InvalidateAllGL();
1342 case ID_WP_MENU_PROPERTIES:
1343 parent->ShowMarkPropertiesDialog(m_pFoundRoutePoint);
1346 case ID_WP_MENU_CLEAR_ANCHORWATCH: {
1347 wxString guid = wxEmptyString;
1357 if (!guid.IsEmpty()) {
1360 wxString msg_id(
"OCPN_ANCHOR_WATCH_CLEARED");
1361 SendJSONMessageToAllPlugins(msg_id, v);
1366 case ID_WP_MENU_SET_ANCHORWATCH: {
1367 wxString guid = wxEmptyString;
1373 nn = m_pFoundRoutePoint->GetName();
1375 nn.Printf(
"%d m", g_nAWDefault);
1376 m_pFoundRoutePoint->SetName(nn);
1383 nn = m_pFoundRoutePoint->GetName();
1385 nn.Printf(
"%d m", g_nAWDefault);
1386 m_pFoundRoutePoint->SetName(nn);
1389 if (!guid.IsEmpty()) {
1392 wxString msg_id(
"OCPN_ANCHOR_WATCH_SET");
1393 SendJSONMessageToAllPlugins(msg_id, v);
1398 case ID_DEF_MENU_ACTIVATE_MEASURE:
1399 parent->StartMeasureRoute();
1402 case ID_DEF_MENU_DEACTIVATE_MEASURE:
1403 parent->CancelMeasureRoute();
1405 parent->InvalidateGL();
1406 parent->Refresh(
false);
1409 case ID_DEF_MENU_CM93OFFSET_DIALOG: {
1415 if (!parent->GetVP().b_quilt && parent->m_singleChart &&
1416 (parent->m_singleChart->GetChartType() == CHART_TYPE_CM93COMP)) {
1428 case ID_DEF_MENU_QUERY: {
1429 parent->ShowObjectQueryWindow(popx, popy, zlat, zlon);
1432 case ID_DEF_MENU_AIS_QUERY: {
1433 ShowAISTargetQueryDialog(parent, m_FoundAIS_MMSI);
1437 case ID_DEF_MENU_AIS_CPA: {
1438 auto myptarget =
g_pAIS->Get_Target_Data_From_MMSI(m_FoundAIS_MMSI);
1439 if (myptarget) myptarget->Toggle_AIS_CPA();
1443 case ID_DEF_MENU_AISSHOWTRACK: {
1444 auto myptarget =
g_pAIS->Get_Target_Data_From_MMSI(m_FoundAIS_MMSI);
1445 if (myptarget) myptarget->ToggleShowTrack();
1449 case ID_DEF_MENU_COPY_MMSI: {
1451 if (wxTheClipboard->Open()) {
1452 wxTheClipboard->SetData(
1453 new wxTextDataObject(wxString::Format(
"%09d", m_FoundAIS_MMSI)));
1454 wxTheClipboard->Close();
1459 case ID_DEF_MENU_QUILTREMOVE: {
1460 if (parent->GetVP().b_quilt) {
1461 int dbIndex = parent->m_pQuilt->GetChartdbIndexAtPix(
1462 parent->GetVP(), wxPoint(popx, popy));
1463 parent->RemoveChartFromQuilt(dbIndex);
1471 case ID_DEF_MENU_CURRENTINFO: {
1472 parent->
DrawTCWindow(popx, popy, (
void *)m_pIDXCandidate);
1473 parent->Refresh(
false);
1478 case ID_DEF_MENU_TIDEINFO: {
1479 parent->
DrawTCWindow(popx, popy, (
void *)m_pIDXCandidate);
1480 parent->Refresh(
false);
1485 case ID_DGB_MENU_NMEA_WINDOW:
1487 m_nmea_log->Raise();
1490 case ID_RT_MENU_REVERSE: {
1494 OCPNMessageBox(parent,
g_pRouteMan->GetRouteReverseMessage(),
1495 _(
"Rename Waypoints?"), wxYES_NO | wxCANCEL);
1497 if (ask_return != wxID_CANCEL) {
1498 pSelect->DeleteAllSelectableRouteSegments(m_pSelectedRoute);
1499 m_pSelectedRoute->Reverse(ask_return == wxID_YES);
1500 pSelect->AddAllSelectableRouteSegments(m_pSelectedRoute);
1502 NavObj_dB::GetInstance().UpdateRoute(m_pSelectedRoute);
1508 gFrame->InvalidateAllGL();
1509 gFrame->RefreshAllCanvas();
1514 case ID_RT_MENU_SHOWNAMES: {
1515 if (m_pSelectedRoute) {
1516 m_pSelectedRoute->ShowWaypointNames(
1517 !m_pSelectedRoute->AreWaypointNamesVisible());
1523 case ID_RT_MENU_RESEQUENCE: {
1524 if (m_pSelectedRoute) {
1528 OCPNMessageBox(parent,
g_pRouteMan->GetRouteResequenceMessage(),
1529 _(
"Rename Waypoints?"), wxYES_NO | wxCANCEL);
1531 if (ask_return != wxID_CANCEL) {
1532 m_pSelectedRoute->RenameRoutePoints();
1535 gFrame->InvalidateAllGL();
1536 gFrame->RefreshAllCanvas();
1542 case ID_RT_MENU_DELETE: {
1543 bool confirmed = RouteGui::OnDelete(parent);
1546 if (
g_pRouteMan->GetpActiveRoute() == m_pSelectedRoute)
1551 NavObj_dB::GetInstance().DeleteRoute(m_pSelectedRoute);
1554 if (RouteManagerDialog::getInstanceFlag()) {
1555 if (pRouteManagerDialog && pRouteManagerDialog->IsShown())
1556 pRouteManagerDialog->UpdateRouteListCtrl();
1564 parent->undo->InvalidateUndo();
1566 gFrame->InvalidateAllGL();
1567 gFrame->RefreshAllCanvas();
1572 case ID_RT_MENU_ACTIVATE: {
1579 if (m_pSelectedRoute) {
1584 best_point = m_pSelectedRoute->GetPoint(2);
1593 case ID_RT_MENU_DEACTIVATE:
1599 case ID_RT_MENU_INSERT: {
1601 bool rename =
false;
1602 m_pSelectedRoute->InsertPointAfter(m_pFoundRoutePoint, zlat, zlon,
1605 pSelect->DeleteAllSelectableRoutePoints(m_pSelectedRoute);
1606 pSelect->DeleteAllSelectableRouteSegments(m_pSelectedRoute);
1608 pSelect->AddAllSelectableRouteSegments(m_pSelectedRoute);
1609 pSelect->AddAllSelectableRoutePoints(m_pSelectedRoute);
1622 NavObj_dB::GetInstance().UpdateRoute(m_pSelectedRoute);
1631 case ID_RT_MENU_APPEND:
1635 parent->m_pMouseRoute = m_pSelectedRoute;
1636 parent->m_routeState = m_pSelectedRoute->GetnPoints() + 1;
1638 m_pSelectedRoute->GetnPoints();
1639 parent->m_pMouseRoute->SetHiLite(50);
1641 pLast = m_pSelectedRoute->GetLastPoint();
1643 parent->m_prev_rlat = pLast->m_lat;
1644 parent->m_prev_rlon = pLast->m_lon;
1645 parent->m_prev_pMousePoint = pLast;
1647 parent->m_bAppendingRoute =
true;
1649 parent->SetCursor(*parent->pCursorPencil);
1651 androidSetRouteAnnunciator(
true);
1654 parent->HideGlobalToolbar();
1658 case ID_RT_MENU_SPLIT_LEG:
1660 dupFirstWpt =
false;
1661 case ID_RT_MENU_SPLIT_WPT:
1665 if (
g_pRouteMan->GetpActiveRoute() == m_pSelectedRoute)
1668 m_pHead =
new Route();
1669 m_pTail =
new Route();
1670 m_pHead->CloneRoute(m_pSelectedRoute, 1, m_SelectedIdx, _(
"_A"));
1671 m_pTail->CloneRoute(m_pSelectedRoute, m_SelectedIdx + splitMode,
1672 m_pSelectedRoute->GetnPoints(), _(
"_B"), dupFirstWpt);
1674 NavObj_dB::GetInstance().InsertRoute(m_pHead);
1677 NavObj_dB::GetInstance().InsertRoute(m_pTail);
1679 NavObj_dB::GetInstance().DeleteRoute(m_pSelectedRoute);
1681 pSelect->DeleteAllSelectableRoutePoints(m_pSelectedRoute);
1682 pSelect->DeleteAllSelectableRouteSegments(m_pSelectedRoute);
1684 pSelect->AddAllSelectableRouteSegments(m_pTail);
1685 pSelect->AddAllSelectableRoutePoints(m_pTail);
1686 pSelect->AddAllSelectableRouteSegments(m_pHead);
1687 pSelect->AddAllSelectableRoutePoints(m_pHead);
1693 if (RouteManagerDialog::getInstanceFlag() && pRouteManagerDialog &&
1694 (pRouteManagerDialog->IsShown()))
1695 pRouteManagerDialog->UpdateRouteListCtrl();
1698 case ID_RT_MENU_COPY:
1699 if (m_pSelectedRoute) Kml::CopyRouteToClipboard(m_pSelectedRoute);
1702 case ID_TK_MENU_COPY:
1703 if (m_pSelectedTrack) Kml::CopyTrackToClipboard(m_pSelectedTrack);
1706 case ID_WPT_MENU_COPY:
1707 if (m_pFoundRoutePoint) Kml::CopyWaypointToClipboard(m_pFoundRoutePoint);
1710 case ID_WPT_MENU_SENDTOGPS:
1711 if (m_pFoundRoutePoint) {
1712 if (parent->m_active_upload_port.Length())
1714 .SendToGPS(parent->m_active_upload_port.BeforeFirst(
' '), NULL);
1717 dlg.SetWaypoint(m_pFoundRoutePoint);
1721 dlg.Create(NULL, -1, _(
"Send to GPS") +
"...",
"");
1727 case ID_WPT_MENU_SENDTONEWGPS:
1728 if (m_pFoundRoutePoint) {
1730 dlg.SetWaypoint(m_pFoundRoutePoint);
1732 dlg.Create(NULL, -1, _(
"Send to GPS") +
"...",
"");
1737 case ID_WPT_MENU_SENDTOPEER:
1738 if (m_pFoundRoutePoint) {
1740 dlg.SetWaypoint(m_pFoundRoutePoint);
1745 MdnsCache::GetInstance().
Validate();
1746 if (MdnsCache::GetInstance().GetCache().empty())
1747 dlg.SetScanOnCreate(
true);
1750 dlg.Create(NULL, -1, _(
"Send Waypoint to OpenCPN Peer") +
"...",
"");
1755 case ID_RT_MENU_SENDTOGPS:
1756 if (m_pSelectedRoute) {
1757 if (parent->m_active_upload_port.Length())
1759 .SendToGPS(parent->m_active_upload_port.BeforeFirst(
' '),
true,
1763 dlg.SetRoute(m_pSelectedRoute);
1765 dlg.Create(NULL, -1, _(
"Send to GPS") +
"...",
"");
1771 case ID_RT_MENU_SENDTONEWGPS:
1772 if (m_pSelectedRoute) {
1774 dlg.SetRoute(m_pSelectedRoute);
1776 dlg.Create(NULL, -1, _(
"Send to GPS") +
"...",
"");
1781 case ID_RT_MENU_SENDTOPEER:
1782 if (m_pSelectedRoute) {
1784 dlg.SetRoute(m_pSelectedRoute);
1789 MdnsCache::GetInstance().
Validate();
1790 if (MdnsCache::GetInstance().GetCache().empty())
1791 dlg.SetScanOnCreate(
true);
1794 dlg.Create(NULL, -1, _(
"Send Route to OpenCPN Peer") +
"...",
"");
1799 case ID_PASTE_WAYPOINT:
1800 pupHandler_PasteWaypoint();
1803 case ID_PASTE_ROUTE:
1804 pupHandler_PasteRoute();
1807 case ID_PASTE_TRACK:
1808 pupHandler_PasteTrack();
1811 case ID_RT_MENU_DELPOINT:
1812 if (m_pSelectedRoute) {
1815 pWayPointMan->DestroyWaypoint(m_pFoundRoutePoint);
1820 if (
g_pRouteMan->IsRouteValid(m_pSelectedRoute)) {
1826 if (RouteManagerDialog::getInstanceFlag()) {
1827 if (pRouteManagerDialog && pRouteManagerDialog->IsShown()) {
1828 pRouteManagerDialog->UpdateWptListCtrl();
1829 pRouteManagerDialog->UpdateRouteListCtrl();
1833 gFrame->InvalidateAllGL();
1834 gFrame->RefreshAllCanvas(
true);
1839 case ID_RT_MENU_REMPOINT:
1840 if (m_pSelectedRoute) {
1842 g_pRouteMan->RemovePointFromRoute(m_pFoundRoutePoint, m_pSelectedRoute,
1843 parent->m_routeState);
1844 gFrame->InvalidateAllGL();
1845 gFrame->RefreshAllCanvas();
1849 case ID_RT_MENU_ACTPOINT:
1850 if (
g_pRouteMan->GetpActiveRoute() == m_pSelectedRoute) {
1857 case ID_RT_MENU_DEACTPOINT:
1860 case ID_RT_MENU_ACTNXTPOINT:
1861 if (
g_pRouteMan->GetpActiveRoute() == m_pSelectedRoute) {
1868 case ID_RT_MENU_PROPERTIES: {
1869 parent->ShowRoutePropertiesDialog(_(
"Route Properties"),
1874 case ID_TK_MENU_PROPERTIES: {
1875 parent->ShowTrackPropertiesDialog(m_pSelectedTrack);
1879 case ID_TK_MENU_DELETE: {
1880 int dlg_return = wxID_YES;
1881 if (g_bConfirmObjectDelete) {
1882 dlg_return = OCPNMessageBox(
1883 parent, _(
"Are you sure you want to delete this track?"),
1884 _(
"OpenCPN Track Delete"),
1885 (
long)wxYES_NO | wxCANCEL | wxYES_DEFAULT);
1888 if (dlg_return == wxID_YES) {
1890 m_pSelectedTrack = parent->parent_frame->TrackOff();
1891 g_pAIS->DeletePersistentTrack(m_pSelectedTrack);
1893 NavObj_dB::GetInstance().DeleteTrack(m_pSelectedTrack);
1894 RoutemanGui(*g_pRouteMan).DeleteTrack(m_pSelectedTrack);
1902 if (RoutePropDlgImpl::getInstanceFlag() && pRouteManagerDialog &&
1903 pRouteManagerDialog->IsShown()) {
1904 pRouteManagerDialog->UpdateTrkListCtrl();
1905 pRouteManagerDialog->UpdateRouteListCtrl();
1907 gFrame->InvalidateAllGL();
1908 gFrame->RefreshAllCanvas();
1913 case ID_TK_MENU_SENDTOPEER:
1914 if (m_pSelectedTrack) {
1916 dlg.SetTrack(m_pSelectedTrack);
1921 MdnsCache::GetInstance().
Validate();
1922 if (MdnsCache::GetInstance().GetCache().empty())
1923 dlg.SetScanOnCreate(
true);
1926 dlg.Create(NULL, -1, _(
"Send Track to OpenCPN Peer") +
"...",
"");
1931 case ID_RC_MENU_SCALE_IN:
1932 parent->parent_frame->DoStackDown(parent);
1934 parent->WarpPointer(r.x, r.y);
1937 case ID_RC_MENU_SCALE_OUT:
1938 parent->parent_frame->DoStackUp(parent);
1940 parent->WarpPointer(r.x, r.y);
1943 case ID_RC_MENU_ZOOM_IN:
1946 parent->WarpPointer(r.x, r.y);
1949 case ID_RC_MENU_ZOOM_OUT:
1952 parent->WarpPointer(r.x, r.y);
1955 case ID_RC_MENU_FINISH:
1956 parent->FinishRoute();
1958 parent->Refresh(
false);
1959 g_FlushNavobjChanges =
true;
1962 case ID_DEF_ZERO_XTE:
1969 ArrayOfPlugInMenuItems item_array =
1972 for (
unsigned int i = 0; i < item_array.GetCount(); i++) {
1974 int target_id = pimis->id;
1977 if (pimis->pmenu_item->GetSubMenu()) {
1978 const wxMenuItemList &items =
1979 pimis->pmenu_item->GetSubMenu()->GetMenuItems();
1980 for (wxMenuItemList::const_iterator it = items.begin();
1981 it != items.end(); ++it) {
1982 if ((*it)->GetId() ==
event.GetId()) {
1983 target_id = (*it)->GetId();
1989 if (pimis->m_pplugin && (target_id == event.GetId())) {
1990 if (pimis->extended) {
1991 std::string object_type;
1992 std::string object_ident;
1994 if ((pimis->m_in_menu.IsSameAs(
"Waypoint")) && m_pFoundRoutePoint) {
1995 object_type =
"Waypoint";
1996 object_ident = m_pFoundRoutePoint->
m_GUID.ToStdString();
1997 }
else if ((pimis->m_in_menu.IsSameAs(
"Route")) &&
1999 object_type =
"Route";
2000 object_ident = m_pSelectedRoute->
m_GUID.ToStdString();
2001 }
else if ((pimis->m_in_menu.IsSameAs(
"Track")) &&
2003 object_type =
"Track";
2004 object_ident = m_pSelectedTrack->m_GUID.ToStdString();
2005 }
else if ((pimis->m_in_menu.IsSameAs(
"AIS")) && m_FoundAIS_MMSI) {
2006 object_type =
"AIS";
2007 wxString sAIS = wxString::Format(
"%d", m_FoundAIS_MMSI);
2008 object_ident = sAIS.ToStdString();
2014 ppi->OnContextMenuItemCallbackExt(target_id, object_ident,
2015 object_type, zlat, zlon);
2026 if ((event.GetId() >= ID_DEF_MENU_GROUPBASE) &&
2029 parent->SetGroupIndex(event.GetId() - ID_DEF_MENU_GROUPBASE);
2032 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.
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.
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.
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.
ActiveTrack * g_pActiveTrack
global instance
Recorded track abstraction.
Track and Trackpoint drawing stuff.
TrackPropDlg * pTrackPropDialog
Global instance.
Framework for Undo features.