OpenCPN Partial API docs
Loading...
Searching...
No Matches
canvasMenu.cpp
1/***************************************************************************
2 *
3 * Project: OpenCPN
4 * Purpose: CanvasMenuHandler
5 * Author: David Register
6 *
7 ***************************************************************************
8 * Copyright (C) 2015 by David S. Register *
9 * *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
24 **************************************************************************/
25
26// For compilers that support precompilation, includes "wx.h".
27#include <wx/wxprec.h>
28
29#include <wx/aui/aui.h>
30#include <wx/clipbrd.h>
31#include <wx/dynarray.h>
32#include <wx/event.h>
33#include <wx/font.h>
34#include <wx/gdicmn.h>
35#include <wx/graphics.h>
36#include <wx/image.h>
37#include <wx/listbook.h>
38#include <wx/listimpl.cpp>
39#include <wx/menu.h>
40
41#include "FontMgr.h"
42#include "MarkInfo.h"
43#include "Quilt.h"
44#include "route.h"
45#include "RoutePropDlgImpl.h"
46#include "SendToGpsDlg.h"
47#include "SendToPeerDlg.h"
48#include "TCWin.h"
49#include "track.h"
50#include "TrackPropDlg.h"
51#include "ais.h"
52#include "ais_decoder.h"
53#include "ais_target_data.h"
54#include "canvasMenu.h"
55#include "chartdb.h"
56#include "chcanv.h"
57#include "cm93.h" // for chart outline draw
58#include "config.h"
59#include "config_vars.h"
60#include "cutil.h"
61#include "georef.h"
62#include "kml.h"
63#include "navutil.h"
64#include "nav_object_database.h"
65#include "ocpn_frame.h"
66#include "own_ship.h"
67#include "pluginmanager.h"
68#include "route_gui.h"
69#include "route_point_gui.h"
70#include "routeman.h"
71#include "routeman_gui.h"
72#include "routemanagerdialog.h"
73#include "s52plib.h"
74#include "s57chart.h" // for ArrayOfS57Obj
75#include "styles.h"
76#include "tcmgr.h"
77#include "tide_time.h"
78#include "track_gui.h"
79#include "undo.h"
80#include "peer_client.h"
81#include "mDNS_query.h"
82#include "OCPNPlatform.h"
83
84#ifdef __OCPN__ANDROID__
85#include "androidUTIL.h"
86#endif
87
88// ----------------------------------------------------------------------------
89// Useful Prototypes
90// ----------------------------------------------------------------------------
91extern void pupHandler_PasteRoute();
92extern void pupHandler_PasteTrack();
93extern void pupHandler_PasteWaypoint();
94
95extern AisDecoder *g_pAIS;
96extern bool g_bShowAreaNotices;
97extern bool bGPSValid;
98extern Routeman *g_pRouteMan;
99extern bool g_bskew_comp;
100extern double vLat, vLon;
101extern MyFrame *gFrame;
102extern ChartGroupArray *g_pGroupArray;
103extern PlugInManager *g_pi_manager;
104extern int g_nAWMax;
105extern int g_nAWDefault;
106extern RoutePoint *pAnchorWatchPoint1;
107extern RoutePoint *pAnchorWatchPoint2;
108extern wxString g_AW1GUID;
109extern wxString g_AW2GUID;
110extern int g_click_stop;
111extern RouteManagerDialog *pRouteManagerDialog;
112extern MarkInfoDlg *g_pMarkInfoDialog;
113extern RoutePropDlgImpl *pRoutePropDialog;
114extern ActiveTrack *g_pActiveTrack;
115extern bool g_bConfirmObjectDelete;
116extern WayPointman *pWayPointMan;
117extern MyConfig *pConfig;
118extern Select *pSelect;
119extern OCPNPlatform* g_Platform;
120
121extern CM93OffsetDialog *g_pCM93OffsetDialog;
122
123extern GoToPositionDialog *pGoToPositionDialog;
124extern RouteList *pRouteList;
125extern wxString g_default_wp_icon;
126extern bool g_btouch;
127extern bool g_bBasicMenus;
128extern TrackPropDlg *pTrackPropDialog;
129extern double gHdt;
130extern bool g_FlushNavobjChanges;
131extern ColorScheme global_color_scheme;
132extern std::vector<std::shared_ptr<ocpn_DNS_record_t>> g_DNS_cache;
133extern wxDateTime g_DNS_cache_time;
134
135// Constants for right click menus
136enum {
137 ID_DEF_MENU_MAX_DETAIL = 1,
138 ID_DEF_MENU_SCALE_IN,
139 ID_DEF_MENU_SCALE_OUT,
140 ID_DEF_MENU_DROP_WP,
141 ID_DEF_MENU_NEW_RT,
142 ID_DEF_MENU_QUERY,
143 ID_DEF_MENU_MOVE_BOAT_HERE,
144 ID_DEF_MENU_GOTO_HERE,
145 ID_DEF_MENU_GOTOPOSITION,
146
147 ID_WP_MENU_GOTO,
148 ID_WP_MENU_DELPOINT,
149 ID_WP_MENU_PROPERTIES,
150 ID_RT_MENU_ACTIVATE,
151 ID_RT_MENU_DEACTIVATE,
152 ID_RT_MENU_INSERT,
153 ID_RT_MENU_APPEND,
154 ID_RT_MENU_COPY,
155 ID_RT_MENU_SPLIT_LEG,
156 ID_RT_MENU_SPLIT_WPT,
157 ID_TK_MENU_COPY,
158 ID_WPT_MENU_COPY,
159 ID_WPT_MENU_SENDTOGPS,
160 ID_WPT_MENU_SENDTONEWGPS,
161 ID_PASTE_WAYPOINT,
162 ID_PASTE_ROUTE,
163 ID_PASTE_TRACK,
164 ID_RT_MENU_DELETE,
165 ID_RT_MENU_REVERSE,
166 ID_RT_MENU_DELPOINT,
167 ID_RT_MENU_ACTPOINT,
168 ID_RT_MENU_DEACTPOINT,
169 ID_RT_MENU_ACTNXTPOINT,
170 ID_RT_MENU_REMPOINT,
171 ID_RT_MENU_PROPERTIES,
172 ID_RT_MENU_SENDTOGPS,
173 ID_RT_MENU_SENDTONEWGPS,
174 ID_RT_MENU_SHOWNAMES,
175 ID_RT_MENU_RESEQUENCE,
176 ID_RT_MENU_SENDTOPEER,
177 ID_WP_MENU_SET_ANCHORWATCH,
178 ID_WP_MENU_CLEAR_ANCHORWATCH,
179 ID_DEF_MENU_AISTARGETLIST,
180
181 ID_RC_MENU_SCALE_IN,
182 ID_RC_MENU_SCALE_OUT,
183 ID_RC_MENU_ZOOM_IN,
184 ID_RC_MENU_ZOOM_OUT,
185 ID_RC_MENU_FINISH,
186 ID_DEF_MENU_AIS_QUERY,
187 ID_DEF_MENU_AIS_CPA,
188 ID_DEF_MENU_AISSHOWTRACK,
189 ID_DEF_MENU_ACTIVATE_MEASURE,
190 ID_DEF_MENU_DEACTIVATE_MEASURE,
191 ID_DEF_MENU_COPY_MMSI,
192
193 ID_UNDO,
194 ID_REDO,
195
196 ID_DEF_MENU_CM93OFFSET_DIALOG,
197
198 ID_TK_MENU_PROPERTIES,
199 ID_TK_MENU_DELETE,
200 ID_WP_MENU_ADDITIONAL_INFO,
201
202 ID_DEF_MENU_QUILTREMOVE,
203 ID_DEF_MENU_COGUP,
204 ID_DEF_MENU_NORTHUP,
205 ID_DEF_MENU_HEADUP,
206 ID_DEF_MENU_TOGGLE_FULL,
207 ID_DEF_MENU_TIDEINFO,
208 ID_DEF_MENU_CURRENTINFO,
209 ID_DEF_ZERO_XTE,
210
211 ID_DEF_MENU_GROUPBASE, // Must be last entry, as chart group identifiers are
212 // created dynamically
213
214 ID_DEF_MENU_LAST
215};
216
217//------------------------------------------------------------------------------
218// CanvasMenuHandler Implementation
219//------------------------------------------------------------------------------
220int CanvasMenuHandler::GetNextContextMenuId() {
221 return ID_DEF_MENU_LAST +
222 100; // Allowing for 100 dynamic menu item identifiers
223}
224
225wxFont CanvasMenuHandler::m_scaledFont;
226
227// Define a constructor for my canvas
228CanvasMenuHandler::CanvasMenuHandler(ChartCanvas *parentCanvas,
229 Route *selectedRoute, Track *selectedTrack,
230 RoutePoint *selectedPoint,
231 int selectedAIS_MMSI,
232 void *selectedTCIndex)
233
234{
235 parent = parentCanvas;
236 m_pSelectedRoute = selectedRoute;
237 m_pSelectedTrack = selectedTrack;
238 m_pFoundRoutePoint = selectedPoint;
239 m_FoundAIS_MMSI = selectedAIS_MMSI;
240 m_pIDXCandidate = selectedTCIndex;
241 if (!m_scaledFont.IsOk()){
242 wxFont *qFont = GetOCPNScaledFont(_("Menu"));
243 m_scaledFont = *qFont;
244 }
245
246 m_DIPFactor =g_Platform->GetDisplayDIPMult(gFrame);
247
248}
249
250CanvasMenuHandler::~CanvasMenuHandler() {}
251
252//-------------------------------------------------------------------------------
253// Popup Menu Handling
254//-------------------------------------------------------------------------------
255
256void CanvasMenuHandler::PrepareMenuItem( wxMenuItem *item ){
257#if defined(__WXMSW__)
258 if (m_DIPFactor == 1.0){
259 wxColour ctrl_back_color = GetGlobalColor(_T("DILG1")); // Control Background
260 item->SetBackgroundColour(ctrl_back_color);
261 wxColour menu_text_color = GetGlobalColor(_T ( "UITX1" ));
262 item->SetTextColour(menu_text_color);
263 }
264#endif
265}
266
267void CanvasMenuHandler::MenuPrepend1(wxMenu *menu, int id, wxString label) {
268 wxMenuItem *item = new wxMenuItem(menu, id, label);
269#if defined(__WXMSW__)
270 if (m_DIPFactor == 1.0)
271 item->SetFont(m_scaledFont);
272#endif
273
274#ifdef __OCPN__ANDROID__
275 wxFont sFont = GetOCPNGUIScaledFont(_("Menu"));
276 item->SetFont(sFont);
277#endif
278
279 PrepareMenuItem( item );
280
281 if (g_btouch) menu->InsertSeparator(0);
282 menu->Prepend(item);
283}
284
285void CanvasMenuHandler::MenuAppend1(wxMenu *menu, int id, wxString label) {
286 wxMenuItem *item = new wxMenuItem(menu, id, label);
287#if defined(__WXMSW__)
288 if (m_DIPFactor == 1.0)
289 item->SetFont(m_scaledFont);
290#endif
291
292#ifdef __OCPN__ANDROID__
293 wxFont sFont = GetOCPNGUIScaledFont(_T("Menu"));
294 item->SetFont(sFont);
295#endif
296
297 PrepareMenuItem( item );
298
299 menu->Append(item);
300 if (g_btouch) menu->AppendSeparator();
301}
302
303void CanvasMenuHandler::SetMenuItemFont1(wxMenuItem *item) {
304#if defined(__WXMSW__)
305 if (m_DIPFactor == 1.0)
306 item->SetFont(m_scaledFont);
307#endif
308
309#if defined(__OCPN__ANDROID__)
310 wxFont *qFont = GetOCPNScaledFont(_("Menu"));
311 item->SetFont(*qFont);
312#endif
313
314 PrepareMenuItem( item );
315}
316
317void CanvasMenuHandler::CanvasPopupMenu(int x, int y, int seltype) {
318 wxMenu *contextMenu = new wxMenu;
319 wxMenu *menuWaypoint = NULL;
320 wxMenu *menuRoute = NULL;
321 wxMenu *menuTrack = NULL;
322 wxMenu *menuAIS = NULL;
323
324 wxMenu *subMenuChart = new wxMenu;
325 wxMenu *subMenuUndo = new wxMenu("Undo...Ctrl-Z");
326
327#ifdef __WXOSX__
328 wxMenu *subMenuRedo = new wxMenu("Redo...Shift-Ctrl-Z");
329#else
330 wxMenu *subMenuRedo = new wxMenu("Redo...Ctrl-Y");
331#endif
332
333 wxMenu *menuFocus = contextMenu; // This is the one that will be shown
334
335 popx = x;
336 popy = y;
337
338 if (!g_bBasicMenus || (seltype != SELTYPE_ROUTECREATE)) {
339
340 bool bsubMenus = false;
341
342 if (bsubMenus){
343 if (parent->undo->AnythingToUndo()) {
344 // Undo SubMenu
345 wxMenuItem *subMenuItemundo =
346 contextMenu->AppendSubMenu(subMenuUndo, _("Undo"));
347
348 wxString undoItem;
349 undoItem << _("Undo") << _T(" ")
350 << parent->undo->GetNextUndoableAction()->Description();
351 MenuAppend1(subMenuUndo, ID_UNDO, undoItem);
352 }
353 if (parent->undo->AnythingToRedo()) {
354 // Redo SubMenu
355 wxMenuItem *subMenuItemRedo =
356 contextMenu->AppendSubMenu(subMenuRedo, _("Redo"));
357
358 wxString redoItem;
359 redoItem << _("Redo") << _T(" ")
360 << parent->undo->GetNextRedoableAction()->Description();
361 MenuAppend1(subMenuRedo, ID_REDO, redoItem);
362 }
363 }
364 else {
365 if (parent->undo->AnythingToUndo()) {
366 wxString undoItem;
367 undoItem << _("Undo") << _T(" ")
368 << parent->undo->GetNextUndoableAction()->Description();
369 MenuAppend1(contextMenu, ID_UNDO, _menuText(undoItem, _T("Ctrl-Z")));
370 }
371
372 if (parent->undo->AnythingToRedo()) {
373 wxString redoItem;
374 redoItem << _("Redo") << _T(" ")
375 << parent->undo->GetNextRedoableAction()->Description();
376#ifdef __WXOSX__
377 MenuAppend1(contextMenu, ID_REDO, _menuText(redoItem, _T("Shift-Ctrl-Z")));
378#else
379 MenuAppend1(contextMenu, ID_REDO, _menuText(redoItem, _T("Ctrl-Y")));
380#endif
381 }
382 }
383 }
384
385 if (seltype == SELTYPE_ROUTECREATE) {
386 MenuAppend1(contextMenu, ID_RC_MENU_FINISH,
387 _menuText(_("End Route"), _T("Esc")));
388 }
389
390 if (!parent->m_pMouseRoute) {
391 if (parent->m_bMeasure_Active)
392 MenuAppend1(contextMenu, ID_DEF_MENU_DEACTIVATE_MEASURE,
393 _menuText(_("Measure Off"), _T("Esc")));
394 else
395 MenuAppend1(contextMenu, ID_DEF_MENU_ACTIVATE_MEASURE,
396 _menuText(_("Measure"), _T("M")));
397 }
398
399
400 bool ais_areanotice = false;
401 if (g_pAIS && parent->GetShowAIS() && g_bShowAreaNotices) {
402 float vp_scale = parent->GetVPScale();
403
404 for (const auto &target : g_pAIS->GetAreaNoticeSourcesList()) {
405 auto target_data = target.second;
406 if (!target_data->area_notices.empty()) {
407 for (auto &ani : target_data->area_notices) {
408 Ais8_001_22 &area_notice = ani.second;
409 BoundingBox bbox;
410
411 for (Ais8_001_22_SubAreaList::iterator sa =
412 area_notice.sub_areas.begin();
413 sa != area_notice.sub_areas.end(); ++sa) {
414 switch (sa->shape) {
415 case AIS8_001_22_SHAPE_CIRCLE: {
416 wxPoint target_point;
417 parent->GetCanvasPointPix(sa->latitude, sa->longitude,
418 &target_point);
419 bbox.Expand(target_point);
420 if (sa->radius_m > 0.0) bbox.EnLarge(sa->radius_m * vp_scale);
421 break;
422 }
423 case AIS8_001_22_SHAPE_POLYGON:
424 case AIS8_001_22_SHAPE_POLYLINE: {
425 double lat = sa->latitude;
426 double lon = sa->longitude;
427 for (int i = 0; i < 4; ++i) {
428 ll_gc_ll(lat, lon, sa->angles[i], sa->dists_m[i] / 1852.0,
429 &lat, &lon);
430 wxPoint target_point;
431 parent->GetCanvasPointPix(lat, lon, &target_point);
432 bbox.Expand(target_point);
433 }
434 }
435 }
436 }
437
438 if (bbox.PointInBox(x, y)) {
439 ais_areanotice = true;
440 break;
441 }
442 }
443 }
444 }
445 }
446
447 int nChartStack = 0;
448 if (parent->GetpCurrentStack())
449 nChartStack = parent->GetpCurrentStack()->nEntry;
450
451 if (!parent->GetVP().b_quilt) {
452 if (nChartStack > 1) {
453 MenuAppend1(contextMenu, ID_DEF_MENU_MAX_DETAIL, _("Max Detail Here"));
454 MenuAppend1(contextMenu, ID_DEF_MENU_SCALE_IN,
455 _menuText(_("Scale In"), _T("Ctrl-Left")));
456 MenuAppend1(contextMenu, ID_DEF_MENU_SCALE_OUT,
457 _menuText(_("Scale Out"), _T("Ctrl-Right")));
458 }
459
460 if ((parent->m_singleChart &&
461 (parent->m_singleChart->GetChartFamily() == CHART_FAMILY_VECTOR)) ||
462 ais_areanotice) {
463 MenuAppend1(contextMenu, ID_DEF_MENU_QUERY,
464 _("Object Query") + _T( "..." ));
465 }
466
467 } else {
468 ChartBase *pChartTest =
469 parent->m_pQuilt->GetChartAtPix(parent->GetVP(), wxPoint(x, y));
470 if ((pChartTest && (pChartTest->GetChartFamily() == CHART_FAMILY_VECTOR)) ||
471 ais_areanotice) {
472 MenuAppend1(contextMenu, ID_DEF_MENU_QUERY,
473 _("Object Query") + _T( "..." ));
474 } else {
475#ifndef __OCPN__ANDROID__
476 if (!g_bBasicMenus && (nChartStack > 1)) {
477 MenuAppend1(contextMenu, ID_DEF_MENU_SCALE_IN,
478 _menuText(_("Scale In"), _T("Ctrl-Left")));
479 MenuAppend1(contextMenu, ID_DEF_MENU_SCALE_OUT,
480 _menuText(_("Scale Out"), _T("Ctrl-Right")));
481 }
482#endif
483 }
484 }
485
486 if (!g_bBasicMenus || (seltype != SELTYPE_ROUTECREATE)) {
487 MenuAppend1(contextMenu, ID_DEF_MENU_DROP_WP,
488 _menuText(_("Drop Mark"), _T("Ctrl-M")));
489 MenuAppend1(contextMenu, ID_DEF_MENU_NEW_RT,
490 _menuText(_("New Route..."), _T("Ctrl-R")));
491
492 if (!bGPSValid)
493 MenuAppend1(contextMenu, ID_DEF_MENU_MOVE_BOAT_HERE, _("Move Boat Here"));
494 }
495
496 if (!g_bBasicMenus &&
497 (!(g_pRouteMan->GetpActiveRoute() || (seltype & SELTYPE_MARKPOINT))))
498 MenuAppend1(contextMenu, ID_DEF_MENU_GOTO_HERE, _("Navigate To Here"));
499
500 if (!g_bBasicMenus)
501 MenuAppend1(contextMenu, ID_DEF_MENU_GOTOPOSITION,
502 _("Center view") + _T("..."));
503
504 if (!g_bBasicMenus) {
505 if (parent->GetVP().b_quilt) {
506 if (parent->GetUpMode() == NORTH_UP_MODE) {
507 MenuAppend1(contextMenu, ID_DEF_MENU_COGUP, _("Course Up Mode"));
508 if (!std::isnan(gHdt))
509 MenuAppend1(contextMenu, ID_DEF_MENU_HEADUP, _("Heading Up Mode"));
510 } else {
511 MenuAppend1(contextMenu, ID_DEF_MENU_NORTHUP, _("North Up Mode"));
512 }
513 } else {
514 if (parent->m_singleChart &&
515 (fabs(parent->m_singleChart->GetChartSkew()) > .01) && !g_bskew_comp)
516 MenuAppend1(contextMenu, ID_DEF_MENU_NORTHUP, _("Chart Up Mode"));
517 else
518 MenuAppend1(contextMenu, ID_DEF_MENU_NORTHUP, _("North Up Mode"));
519 }
520 }
521
522 if (!g_bBasicMenus) {
523 bool full_toggle_added = false;
524#ifndef __OCPN__ANDROID__
525 if (g_btouch) {
526 MenuAppend1(contextMenu, ID_DEF_MENU_TOGGLE_FULL,
527 _("Toggle Full Screen"));
528 full_toggle_added = true;
529 }
530
531 if (!full_toggle_added) {
532 // if(gFrame->IsFullScreen())
533 MenuAppend1(contextMenu, ID_DEF_MENU_TOGGLE_FULL,
534 _("Toggle Full Screen"));
535 }
536#endif
537
538 if (g_pRouteMan->IsAnyRouteActive() &&
539 g_pRouteMan->GetCurrentXTEToActivePoint() > 0.)
540 MenuAppend1(contextMenu, ID_DEF_ZERO_XTE, _("Zero XTE"));
541
542 Kml *kml = new Kml;
543 int pasteBuffer = kml->ParsePasteBuffer();
544 if (pasteBuffer != KML_PASTE_INVALID) {
545 switch (pasteBuffer) {
546 case KML_PASTE_WAYPOINT: {
547 MenuAppend1(contextMenu, ID_PASTE_WAYPOINT, _("Paste Waypoint"));
548 break;
549 }
550 case KML_PASTE_ROUTE: {
551 MenuAppend1(contextMenu, ID_PASTE_ROUTE, _("Paste Route"));
552 break;
553 }
554 case KML_PASTE_TRACK: {
555 MenuAppend1(contextMenu, ID_PASTE_TRACK, _("Paste Track"));
556 break;
557 }
558 case KML_PASTE_ROUTE_TRACK: {
559 MenuAppend1(contextMenu, ID_PASTE_ROUTE, _("Paste Route"));
560 MenuAppend1(contextMenu, ID_PASTE_TRACK, _("Paste Track"));
561 break;
562 }
563 }
564 }
565 delete kml;
566
567 if (!parent->GetVP().b_quilt && parent->m_singleChart &&
568 (parent->m_singleChart->GetChartType() == CHART_TYPE_CM93COMP)) {
569 MenuAppend1(contextMenu, ID_DEF_MENU_CM93OFFSET_DIALOG,
570 _("CM93 Offset Dialog..."));
571 }
572
573 } // if( !g_bBasicMenus){
574
575#ifndef __OCPN__ANDROID__
576// TODO stack
577// if( ( parent->GetVP().b_quilt ) && ( pCurrentStack &&
578// pCurrentStack->b_valid ) ) {
579// int dbIndex = parent->m_pQuilt->GetChartdbIndexAtPix(
580// parent->GetVP(), wxPoint( popx, popy ) ); if( dbIndex != -1 )
581// MenuAppend1( contextMenu, ID_DEF_MENU_QUILTREMOVE, _( "Hide This
582// Chart" ) );
583// }
584#endif
585
586#ifdef __WXMSW__
587 // If we dismiss the context menu without action, we need to discard some
588 // mouse events.... Eat the next 2 button events, which happen as down-up on
589 // MSW XP
590 g_click_stop = 2;
591#endif
592
593 // ChartGroup SubMenu
594 wxMenuItem *subItemChart =
595 contextMenu->AppendSubMenu(subMenuChart, _("Chart Groups"));
596 if (g_btouch) contextMenu->AppendSeparator();
597
598 SetMenuItemFont1(subItemChart);
599
600 if (g_pGroupArray->GetCount()) {
601#ifdef __WXMSW__
602 MenuAppend1(subMenuChart, wxID_CANCEL, _("temporary"));
603#endif
604 wxMenuItem *subItem0 = subMenuChart->AppendRadioItem(
605 ID_DEF_MENU_GROUPBASE, _("All Active Charts"));
606
607 SetMenuItemFont1(subItem0);
608
609 for (unsigned int i = 0; i < g_pGroupArray->GetCount(); i++) {
610 subItem0 = subMenuChart->AppendRadioItem(
611 ID_DEF_MENU_GROUPBASE + i + 1, g_pGroupArray->Item(i)->m_group_name);
612 SetMenuItemFont1(subItem0);
613 }
614
615#ifdef __WXMSW__
616 subMenuChart->Remove(wxID_CANCEL);
617#endif
618 subMenuChart->Check(ID_DEF_MENU_GROUPBASE + parent->m_groupIndex, true);
619 }
620
621 // This is the default context menu
622 menuFocus = contextMenu;
623
624 wxString name;
625 if (!g_bBasicMenus || (seltype != SELTYPE_ROUTECREATE)) {
626 if (g_pAIS) {
627 if (parent->GetShowAIS() && (seltype & SELTYPE_AISTARGET)) {
628 auto myptarget = g_pAIS->Get_Target_Data_From_MMSI(m_FoundAIS_MMSI);
629 if (!g_bBasicMenus && myptarget) {
630 name = myptarget->GetFullName();
631 if (name.IsEmpty()) name.Printf(_T("%d"), m_FoundAIS_MMSI);
632 name.Prepend(_T(" ( ")).Append(_T(" )"));
633 } else
634 name = wxEmptyString;
635 menuAIS = new wxMenu(_("AIS") + name);
636 MenuAppend1(menuAIS, ID_DEF_MENU_AIS_QUERY, _("Target Query..."));
637 if (myptarget && myptarget->bCPA_Valid &&
638 (myptarget->n_alert_state != AIS_ALERT_SET)) {
639 if (myptarget->b_show_AIS_CPA)
640 MenuAppend1(menuAIS, ID_DEF_MENU_AIS_CPA, _("Hide Target CPA"));
641 else
642 MenuAppend1(menuAIS, ID_DEF_MENU_AIS_CPA, _("Show Target CPA"));
643 }
644 MenuAppend1(menuAIS, ID_DEF_MENU_AISTARGETLIST, _("Target List..."));
645 if (1 /*g_bAISShowTracks*/) {
646 if (myptarget && myptarget->b_show_track)
647 MenuAppend1(menuAIS, ID_DEF_MENU_AISSHOWTRACK,
648 _("Hide Target Track"));
649 else
650 MenuAppend1(menuAIS, ID_DEF_MENU_AISSHOWTRACK,
651 _("Show Target Track"));
652 }
653
654 MenuAppend1(menuAIS, ID_DEF_MENU_COPY_MMSI, _("Copy Target MMSI"));
655 menuAIS->AppendSeparator();
656
657 if (!parent->GetVP().b_quilt) {
658 if ((parent->m_singleChart &&
659 (parent->m_singleChart->GetChartFamily() ==
660 CHART_FAMILY_VECTOR))) {
661 MenuAppend1(menuAIS, ID_DEF_MENU_QUERY, _("Object Query..."));
662 }
663
664 } else {
665 ChartBase *pChartTest =
666 parent->m_pQuilt->GetChartAtPix(parent->GetVP(), wxPoint(x, y));
667 if ((pChartTest &&
668 (pChartTest->GetChartFamily() == CHART_FAMILY_VECTOR))) {
669 MenuAppend1(menuAIS, ID_DEF_MENU_QUERY, _("Object Query..."));
670 }
671 }
672
673 menuFocus = menuAIS;
674 } else
675 MenuAppend1(contextMenu, ID_DEF_MENU_AISTARGETLIST,
676 _("AIS target list") + _T("..."));
677 }
678 }
679
680 if (seltype & SELTYPE_ROUTESEGMENT) {
681 if (!g_bBasicMenus && m_pSelectedRoute) {
682 name = m_pSelectedRoute->m_RouteNameString;
683 if (name.IsEmpty()) name = _("Unnamed Route");
684 name.Prepend(_T(" ( ")).Append(_T(" )"));
685 } else
686 name = wxEmptyString;
687 bool blay = false;
688 if (m_pSelectedRoute && m_pSelectedRoute->m_bIsInLayer) blay = true;
689
690 if (blay) {
691 menuRoute = new wxMenu(_("Layer Route") + name);
692 MenuAppend1(menuRoute, ID_RT_MENU_PROPERTIES,
693 _("Properties") + _T( "..." ));
694 if (m_pSelectedRoute) {
695 if (m_pSelectedRoute->IsActive()) {
696 int indexActive = m_pSelectedRoute->GetIndexOf(
697 m_pSelectedRoute->m_pRouteActivePoint);
698 if ((indexActive + 1) <= m_pSelectedRoute->GetnPoints()) {
699 MenuAppend1(menuRoute, ID_RT_MENU_ACTNXTPOINT,
700 _("Activate Next Waypoint"));
701 }
702 MenuAppend1(menuRoute, ID_RT_MENU_DEACTIVATE, _("Deactivate"));
703 MenuAppend1(menuRoute, ID_DEF_ZERO_XTE, _("Zero XTE"));
704 } else {
705 MenuAppend1(menuRoute, ID_RT_MENU_ACTIVATE, _("Activate"));
706 }
707 }
708 } else {
709 menuRoute = new wxMenu(_("Route") + name);
710 MenuAppend1(menuRoute, ID_RT_MENU_PROPERTIES,
711 _("Properties") + _T( "..." ));
712 if (m_pSelectedRoute) {
713 if (m_pSelectedRoute->IsActive()) {
714 int indexActive = m_pSelectedRoute->GetIndexOf(
715 m_pSelectedRoute->m_pRouteActivePoint);
716 if ((indexActive + 1) <= m_pSelectedRoute->GetnPoints()) {
717 MenuAppend1(menuRoute, ID_RT_MENU_ACTNXTPOINT,
718 _("Activate Next Waypoint"));
719 }
720 MenuAppend1(menuRoute, ID_RT_MENU_DEACTIVATE, _("Deactivate"));
721 MenuAppend1(menuRoute, ID_DEF_ZERO_XTE, _("Zero XTE"));
722 } else {
723 MenuAppend1(menuRoute, ID_RT_MENU_ACTIVATE, _("Activate"));
724 }
725 }
726 MenuAppend1(menuRoute, ID_RT_MENU_INSERT, _("Insert Waypoint"));
727 MenuAppend1(menuRoute, ID_RT_MENU_APPEND, _("Append Waypoint"));
728 if (!(seltype & SELTYPE_ROUTEPOINT) && m_pSelectedRoute) {
729 m_SelectedIdx = m_pSelectedRoute->GetIndexOf(m_pFoundRoutePoint);
730 if (m_SelectedIdx > 1 &&
731 m_SelectedIdx < m_pSelectedRoute->GetnPoints() - 1)
732 MenuAppend1(menuRoute, ID_RT_MENU_SPLIT_LEG, _("Split around Leg"));
733 }
734 MenuAppend1(menuRoute, ID_RT_MENU_COPY, _("Copy as KML") + _T( "..." ));
735 MenuAppend1(menuRoute, ID_RT_MENU_DELETE, _("Delete") + _T( "..." ));
736 MenuAppend1(menuRoute, ID_RT_MENU_REVERSE, _("Reverse..."));
737 if (m_pSelectedRoute) {
738 if (m_pSelectedRoute->AreWaypointNamesVisible())
739 MenuAppend1(menuRoute, ID_RT_MENU_SHOWNAMES,
740 _("Hide Waypoint Names"));
741 else
742 MenuAppend1(menuRoute, ID_RT_MENU_SHOWNAMES,
743 _("Show Waypoint Names"));
744 }
745 MenuAppend1(menuRoute, ID_RT_MENU_RESEQUENCE,
746 _("Resequence Waypoints..."));
747
748 //#ifndef __OCPN__ANDROID__
749 wxString port = parent->FindValidUploadPort();
750 parent->m_active_upload_port = port;
751 wxString item = _("Send to GPS");
752 if (!port.IsEmpty()) {
753 item.Append(_T(" ( "));
754 item.Append(port);
755 item.Append(_T(" )"));
756 }
757 MenuAppend1(menuRoute, ID_RT_MENU_SENDTOGPS, item);
758
759 if (!port.IsEmpty()) {
760 wxString item = _("Send to new GPS");
761 MenuAppend1(menuRoute, ID_RT_MENU_SENDTONEWGPS, item);
762 }
763 //#endif
764 wxString itemstp = _("Send to...");
765 MenuAppend1(menuRoute, ID_RT_MENU_SENDTOPEER, itemstp);
766
767 }
768 // Eventually set this menu as the "focused context menu"
769 if (menuFocus != menuAIS) menuFocus = menuRoute;
770 }
771
772 if (seltype & SELTYPE_TRACKSEGMENT) {
773 name = wxEmptyString;
774 if (!g_bBasicMenus && m_pSelectedTrack)
775 name = _T(" ( ") + m_pSelectedTrack->GetName(true) + _T(" )");
776 else
777 name = wxEmptyString;
778 bool blay = false;
779 if (m_pSelectedTrack && m_pSelectedTrack->m_bIsInLayer) blay = true;
780
781 if (blay) {
782 menuTrack = new wxMenu(_("Layer Track") + name);
783 MenuAppend1(menuTrack, ID_TK_MENU_PROPERTIES,
784 _("Properties") + _T( "..." ));
785 } else {
786 menuTrack = new wxMenu(_("Track") + name);
787 MenuAppend1(menuTrack, ID_TK_MENU_PROPERTIES,
788 _("Properties") + _T( "..." ));
789 MenuAppend1(menuTrack, ID_TK_MENU_COPY, _("Copy as KML"));
790 MenuAppend1(menuTrack, ID_TK_MENU_DELETE, _("Delete") + _T( "..." ));
791 }
792 // Eventually set this menu as the "focused context menu"
793 if (menuFocus != menuAIS) menuFocus = menuTrack;
794 }
795
796 if (seltype & SELTYPE_ROUTEPOINT) {
797 if (!g_bBasicMenus && m_pFoundRoutePoint) {
798 name = m_pFoundRoutePoint->GetName();
799 if (name.IsEmpty()) name = _("Unnamed Waypoint");
800 name.Prepend(_T(" ( ")).Append(_T(" )"));
801 } else
802 name = wxEmptyString;
803 bool blay = false;
804 if (m_pFoundRoutePoint && m_pFoundRoutePoint->m_bIsInLayer) blay = true;
805
806 if (blay) {
807 menuWaypoint = new wxMenu(_("Layer Waypoint") + name);
808 MenuAppend1(menuWaypoint, ID_WP_MENU_PROPERTIES,
809 _("Properties") + _T( "..." ));
810
811 if (m_pSelectedRoute && m_pSelectedRoute->IsActive())
812 MenuAppend1(menuWaypoint, ID_RT_MENU_ACTPOINT, _("Activate"));
813 } else {
814 menuWaypoint = new wxMenu(_("Waypoint") + name);
815 MenuAppend1(menuWaypoint, ID_WP_MENU_PROPERTIES,
816 _("Properties") + _T( "..." ));
817 if (m_pSelectedRoute && m_pSelectedRoute->IsActive()) {
818 if (m_pSelectedRoute->m_pRouteActivePoint != m_pFoundRoutePoint)
819 MenuAppend1(menuWaypoint, ID_RT_MENU_ACTPOINT, _("Activate"));
820 }
821
822 if (m_pSelectedRoute && m_pSelectedRoute->IsActive()) {
823 if (m_pSelectedRoute->m_pRouteActivePoint == m_pFoundRoutePoint) {
824 int indexActive = m_pSelectedRoute->GetIndexOf(
825 m_pSelectedRoute->m_pRouteActivePoint);
826 if ((indexActive + 1) <= m_pSelectedRoute->GetnPoints())
827 MenuAppend1(menuWaypoint, ID_RT_MENU_ACTNXTPOINT,
828 _("Activate Next Waypoint"));
829 }
830 }
831 if (m_pSelectedRoute && m_pSelectedRoute->GetnPoints() > 2) {
832 MenuAppend1(menuWaypoint, ID_RT_MENU_REMPOINT, _("Remove from Route"));
833
834 m_SelectedIdx = m_pSelectedRoute->GetIndexOf(m_pFoundRoutePoint);
835 if (m_SelectedIdx > 1 && m_SelectedIdx < m_pSelectedRoute->GetnPoints())
836 MenuAppend1(menuWaypoint, ID_RT_MENU_SPLIT_WPT,
837 _("Split Route at Waypoint"));
838 }
839
840 MenuAppend1(menuWaypoint, ID_WPT_MENU_COPY, _("Copy as KML"));
841
842 if (m_pFoundRoutePoint && m_pFoundRoutePoint->GetIconName() != _T("mob"))
843 MenuAppend1(menuWaypoint, ID_RT_MENU_DELPOINT, _("Delete"));
844
845 //#ifndef __OCPN__ANDROID__
846 wxString port = parent->FindValidUploadPort();
847 parent->m_active_upload_port = port;
848 wxString item = _("Send to GPS");
849 if (!port.IsEmpty()) {
850 item.Append(_T(" ( "));
851 item.Append(port);
852 item.Append(_T(" )"));
853 }
854 MenuAppend1(menuWaypoint, ID_WPT_MENU_SENDTOGPS, item);
855
856 if (!port.IsEmpty()) {
857 wxString item = _("Send to new GPS");
858 MenuAppend1(menuWaypoint, ID_WPT_MENU_SENDTONEWGPS, item);
859 }
860 //#endif
861 }
862 // Eventually set this menu as the "focused context menu"
863 if (menuFocus != menuAIS) menuFocus = menuWaypoint;
864 }
865
866 if (seltype & SELTYPE_MARKPOINT) {
867 if (!g_bBasicMenus && m_pFoundRoutePoint) {
868 name = m_pFoundRoutePoint->GetName();
869 if (name.IsEmpty()) name = _("Unnamed Waypoint");
870 name.Prepend(_T(" ( ")).Append(_T(" )"));
871 } else
872 name = wxEmptyString;
873 bool blay = false;
874 if (m_pFoundRoutePoint && m_pFoundRoutePoint->m_bIsInLayer) blay = true;
875
876 if (blay) {
877 menuWaypoint = new wxMenu(_("Layer Waypoint") + name);
878 MenuAppend1(menuWaypoint, ID_WP_MENU_PROPERTIES,
879 _("Properties") + _T( "..." ));
880 } else {
881 menuWaypoint = new wxMenu(_("Waypoint") + name);
882 MenuAppend1(menuWaypoint, ID_WP_MENU_PROPERTIES,
883 _("Properties") + _T( "..." ));
884
885 if (!g_pRouteMan->GetpActiveRoute())
886 MenuAppend1(menuWaypoint, ID_WP_MENU_GOTO, _("Navigate To This"));
887
888 MenuAppend1(menuWaypoint, ID_WPT_MENU_COPY, _("Copy as KML"));
889
890 if (m_pFoundRoutePoint && m_pFoundRoutePoint->GetIconName() != _T("mob"))
891 MenuAppend1(menuWaypoint, ID_WP_MENU_DELPOINT, _("Delete"));
892
893 //#ifndef __OCPN__ANDROID__
894 wxString port = parent->FindValidUploadPort();
895 parent->m_active_upload_port = port;
896 wxString item = _("Send to GPS");
897 if (!port.IsEmpty()) {
898 item.Append(_T(" ( "));
899 item.Append(port);
900 item.Append(_T(" )"));
901 }
902 MenuAppend1(menuWaypoint, ID_WPT_MENU_SENDTOGPS, item);
903 //#endif
904
905 if ((m_pFoundRoutePoint == pAnchorWatchPoint1) ||
906 (m_pFoundRoutePoint == pAnchorWatchPoint2))
907 MenuAppend1(menuWaypoint, ID_WP_MENU_CLEAR_ANCHORWATCH,
908 _("Clear Anchor Watch"));
909 else {
910 if (m_pFoundRoutePoint && !(m_pFoundRoutePoint->m_bIsInLayer) &&
911 ((NULL == pAnchorWatchPoint1) || (NULL == pAnchorWatchPoint2))) {
912 double dist;
913 double brg;
914 DistanceBearingMercator(m_pFoundRoutePoint->m_lat,
915 m_pFoundRoutePoint->m_lon, gLat, gLon, &brg,
916 &dist);
917 if (dist * 1852. <= g_nAWMax)
918 MenuAppend1(menuWaypoint, ID_WP_MENU_SET_ANCHORWATCH,
919 _("Set Anchor Watch"));
920 }
921 }
922 }
923 // Eventually set this menu as the "focused context menu"
924 if (menuFocus != menuAIS) menuFocus = menuWaypoint;
925 }
926 /*add the relevant submenus*/
927 enum { WPMENU = 1, TKMENU = 2, RTMENU = 4, MMMENU = 8 };
928 int sub_menu = 0;
929 if (!g_bBasicMenus && menuFocus != contextMenu) {
930 if(global_color_scheme != GLOBAL_COLOR_SCHEME_DUSK &&
931 global_color_scheme != GLOBAL_COLOR_SCHEME_NIGHT ){
932 menuFocus->AppendSeparator();
933 }
934 wxMenuItem *subMenu1;
935 if (menuWaypoint && menuFocus != menuWaypoint) {
936 subMenu1 =
937 menuFocus->AppendSubMenu(menuWaypoint, menuWaypoint->GetTitle());
938 SetMenuItemFont1(subMenu1);
939 sub_menu |= WPMENU;
940#ifdef __WXMSW__
941 menuWaypoint->SetTitle(wxEmptyString);
942#endif
943 }
944 if (menuTrack && menuFocus != menuTrack) {
945 subMenu1 = menuFocus->AppendSubMenu(menuTrack, menuTrack->GetTitle());
946 SetMenuItemFont1(subMenu1);
947 sub_menu |= TKMENU;
948#ifdef __WXMSW__
949 menuTrack->SetTitle(wxEmptyString);
950#endif
951 }
952 if (menuRoute && menuFocus != menuRoute) {
953 subMenu1 = menuFocus->AppendSubMenu(menuRoute, menuRoute->GetTitle());
954 SetMenuItemFont1(subMenu1);
955 sub_menu |= RTMENU;
956#ifdef __WXMSW__
957 menuRoute->SetTitle(wxEmptyString);
958#endif
959 }
960 subMenu1 = menuFocus->AppendSubMenu(contextMenu, _("Main Menu"));
961 SetMenuItemFont1(subMenu1);
962 sub_menu |= MMMENU;
963 }
964
965 if (!subMenuChart->GetMenuItemCount()) contextMenu->Destroy(subItemChart);
966
967 // Add the Tide/Current selections if the item was not activated by shortcut
968 // in right-click handlers
969 bool bsep = false;
970 if (seltype & SELTYPE_TIDEPOINT) {
971 menuFocus->AppendSeparator();
972 bsep = true;
973 MenuAppend1(menuFocus, ID_DEF_MENU_TIDEINFO, _("Show Tide Information"));
974 }
975
976 if (seltype & SELTYPE_CURRENTPOINT) {
977 if (!bsep) menuFocus->AppendSeparator();
978 MenuAppend1(menuFocus, ID_DEF_MENU_CURRENTINFO,
979 _("Show Current Information"));
980 }
981
982 // Give the plugins a chance to update their menu items
983 g_pi_manager->PrepareAllPluginContextMenus();
984
985 // Add PlugIn Context Menu items
986 ArrayOfPlugInMenuItems item_array =
987 g_pi_manager->GetPluginContextMenuItemArray();
988
989 for (unsigned int i = 0; i < item_array.GetCount(); i++) {
990 PlugInMenuItemContainer *pimis = item_array[i];
991 if (!pimis->b_viz) continue;
992
993 wxMenu *submenu = NULL;
994 if (pimis->pmenu_item->GetSubMenu()) {
995 submenu = new wxMenu();
996 const wxMenuItemList &items =
997 pimis->pmenu_item->GetSubMenu()->GetMenuItems();
998 for (wxMenuItemList::const_iterator it = items.begin(); it != items.end();
999 ++it) {
1000 int id = -1;
1001 for (unsigned int j = 0; j < item_array.GetCount(); j++) {
1002 PlugInMenuItemContainer *pimis = item_array[j];
1003 if (pimis->pmenu_item == *it) id = pimis->id;
1004 }
1005
1006 wxMenuItem *pmi = new wxMenuItem(submenu, id,
1007#if wxCHECK_VERSION(3, 0, 0)
1008 (*it)->GetItemLabelText(),
1009#else
1010 (*it)->GetLabel(),
1011#endif
1012 (*it)->GetHelp(), (*it)->GetKind());
1013
1014#ifdef __WXMSW__
1015 if (m_DIPFactor == 1.0)
1016 pmi->SetFont(m_scaledFont);
1017#endif
1018 PrepareMenuItem( pmi );
1019 submenu->Append(pmi);
1020 pmi->Check((*it)->IsChecked());
1021 }
1022 }
1023
1024 wxMenuItem *pmi = new wxMenuItem(contextMenu, pimis->id,
1025#if wxCHECK_VERSION(3, 0, 0)
1026 pimis->pmenu_item->GetItemLabelText(),
1027#else
1028 pimis->pmenu_item->GetLabel(),
1029#endif
1030 pimis->pmenu_item->GetHelp(),
1031 pimis->pmenu_item->GetKind(), submenu);
1032#ifdef __WXMSW__
1033 if (m_DIPFactor == 1.0)
1034 pmi->SetFont(m_scaledFont);
1035#endif
1036
1037 PrepareMenuItem( pmi );
1038
1039 wxMenu *dst = contextMenu;
1040 if (pimis->m_in_menu == "Waypoint")
1041 dst = menuWaypoint;
1042 else if (pimis->m_in_menu == "Route")
1043 dst = menuRoute;
1044 else if (pimis->m_in_menu == "Track")
1045 dst = menuTrack;
1046 else if (pimis->m_in_menu == "AIS")
1047 dst = menuAIS;
1048
1049 if (dst != NULL) {
1050 dst->Append(pmi);
1051 dst->Enable(pimis->id, !pimis->b_grey);
1052 }
1053 }
1054
1055 // Invoke the correct focused drop-down menu
1056
1057#ifdef __OCPN__ANDROID__
1058 androidEnableBackButton(false);
1059 androidEnableOptionsMenu(false);
1060
1061 setMenuStyleSheet(menuRoute, GetOCPNGUIScaledFont(_T("Menu")));
1062 setMenuStyleSheet(menuWaypoint, GetOCPNGUIScaledFont(_T("Menu")));
1063 setMenuStyleSheet(menuTrack, GetOCPNGUIScaledFont(_T("Menu")));
1064 setMenuStyleSheet(menuAIS, GetOCPNGUIScaledFont(_T("Menu")));
1065#endif
1066
1067 parent->PopupMenu(menuFocus, x, y);
1068
1069#ifdef __OCPN__ANDROID__
1070 androidEnableBackButton(true);
1071 androidEnableOptionsMenu(true);
1072#endif
1073
1074 /* Cleanup if necessary.
1075 Do not delete menus witch are submenu as they will be deleted by their parent
1076 menu. This could create a crash*/
1077 delete menuAIS;
1078 if (!(sub_menu & MMMENU)) delete contextMenu;
1079 if (!(sub_menu & RTMENU)) delete menuRoute;
1080 if (!(sub_menu & TKMENU)) delete menuTrack;
1081 if (!(sub_menu & WPMENU)) delete menuWaypoint;
1082}
1083
1084void CanvasMenuHandler::PopupMenuHandler(wxCommandEvent &event) {
1085 RoutePoint *pLast;
1086
1087 wxPoint r;
1088 double zlat, zlon;
1089
1090 int splitMode = 0; // variables for split
1091 bool dupFirstWpt = true, showRPD;
1092
1093 parent->GetCanvasPixPoint(popx * parent->GetDisplayScale(),
1094 popy* parent->GetDisplayScale(),
1095 zlat, zlon);
1096
1097 switch (event.GetId()) {
1098 case ID_DEF_MENU_MAX_DETAIL:
1099 vLat = zlat;
1100 vLon = zlon;
1101 parent->ClearbFollow();
1102
1103 parent->parent_frame->DoChartUpdate();
1104
1105 parent->SelectChartFromStack(0, false, CHART_TYPE_DONTCARE,
1106 CHART_FAMILY_RASTER);
1107 break;
1108
1109 case ID_DEF_MENU_SCALE_IN:
1110 parent->DoCanvasStackDelta(-1);
1111 break;
1112
1113 case ID_DEF_MENU_SCALE_OUT:
1114 parent->DoCanvasStackDelta(1);
1115 break;
1116
1117 case ID_UNDO:
1118 parent->undo->UndoLastAction();
1119 parent->InvalidateGL();
1120 parent->Refresh(false);
1121 break;
1122
1123 case ID_REDO:
1124 parent->undo->RedoNextAction();
1125 parent->InvalidateGL();
1126 parent->Refresh(false);
1127 break;
1128
1129 case ID_DEF_MENU_MOVE_BOAT_HERE:
1130 gLat = zlat;
1131 gLon = zlon;
1132 gFrame->UpdateStatusBar();
1133 break;
1134
1135 case ID_DEF_MENU_GOTO_HERE: {
1136 RoutePoint *pWP_dest = new RoutePoint(zlat, zlon, g_default_wp_icon,
1137 wxEmptyString, wxEmptyString);
1138 pSelect->AddSelectableRoutePoint(zlat, zlon, pWP_dest);
1139
1140 RoutePoint *pWP_src = new RoutePoint(gLat, gLon, g_default_wp_icon,
1141 wxEmptyString, wxEmptyString);
1142 pSelect->AddSelectableRoutePoint(gLat, gLon, pWP_src);
1143
1144 Route *temp_route = new Route();
1145 pRouteList->Append(temp_route);
1146
1147 temp_route->AddPoint(pWP_src);
1148 temp_route->AddPoint(pWP_dest);
1149
1150 pSelect->AddSelectableRouteSegment(gLat, gLon, zlat, zlon, pWP_src,
1151 pWP_dest, temp_route);
1152
1153 temp_route->m_RouteNameString = _("Temporary GOTO Route");
1154 temp_route->m_RouteStartString = _("Here");
1155 ;
1156 temp_route->m_RouteEndString = _("There");
1157
1158 temp_route->m_bDeleteOnArrival = true;
1159
1160 if (g_pRouteMan->GetpActiveRoute()) g_pRouteMan->DeactivateRoute();
1161
1162 g_pRouteMan->ActivateRoute(temp_route, pWP_dest);
1163
1164 break;
1165 }
1166
1167 case ID_DEF_MENU_DROP_WP: {
1168 RoutePoint *pWP = new RoutePoint(zlat, zlon, g_default_wp_icon,
1169 wxEmptyString, wxEmptyString);
1170 pWP->m_bIsolatedMark = true; // This is an isolated mark
1171 pSelect->AddSelectableRoutePoint(zlat, zlon, pWP);
1172 pConfig->AddNewWayPoint(pWP, -1); // use auto next num
1173 if (!RoutePointGui(*pWP).IsVisibleSelectable(this->parent))
1174 RoutePointGui(*pWP).ShowScaleWarningMessage(parent);
1175
1176 if (RouteManagerDialog::getInstanceFlag()) {
1177 if (pRouteManagerDialog && pRouteManagerDialog->IsShown()) {
1178 pRouteManagerDialog->UpdateWptListCtrl();
1179 }
1180 }
1181
1182 parent->undo->BeforeUndoableAction(Undo_CreateWaypoint, pWP,
1183 Undo_HasParent, NULL);
1184 parent->undo->AfterUndoableAction(NULL);
1185 gFrame->RefreshAllCanvas(false);
1186 gFrame->InvalidateAllGL();
1187 g_FlushNavobjChanges = true;
1188 break;
1189 }
1190
1191 case ID_DEF_MENU_NEW_RT: {
1192 parent->StartRoute();
1193 break;
1194 }
1195
1196 case ID_DEF_MENU_AISTARGETLIST:
1197 parent->ShowAISTargetList();
1198 break;
1199
1200 case ID_WP_MENU_GOTO: {
1201 RoutePoint *pWP_src = new RoutePoint(gLat, gLon, g_default_wp_icon,
1202 wxEmptyString, wxEmptyString);
1203 pSelect->AddSelectableRoutePoint(gLat, gLon, pWP_src);
1204
1205 Route *temp_route = new Route();
1206 pRouteList->Append(temp_route);
1207
1208 temp_route->AddPoint(pWP_src);
1209 temp_route->AddPoint(m_pFoundRoutePoint);
1210 m_pFoundRoutePoint->SetShared(true);
1211
1212 pSelect->AddSelectableRouteSegment(gLat, gLon, m_pFoundRoutePoint->m_lat,
1213 m_pFoundRoutePoint->m_lon, pWP_src,
1214 m_pFoundRoutePoint, temp_route);
1215
1216 wxString name = m_pFoundRoutePoint->GetName();
1217 if (name.IsEmpty()) name = _("(Unnamed Waypoint)");
1218 wxString rteName = _("Go to ");
1219 rteName.Append(name);
1220 temp_route->m_RouteNameString = rteName;
1221 temp_route->m_RouteStartString = _("Here");
1222 ;
1223 temp_route->m_RouteEndString = name;
1224 temp_route->m_bDeleteOnArrival = true;
1225
1226 if (g_pRouteMan->GetpActiveRoute()) g_pRouteMan->DeactivateRoute();
1227
1228 g_pRouteMan->ActivateRoute(temp_route, m_pFoundRoutePoint);
1229
1230 break;
1231 }
1232
1233 case ID_DEF_MENU_COGUP:
1234 parent->SetUpMode(COURSE_UP_MODE);
1235 break;
1236
1237 case ID_DEF_MENU_HEADUP:
1238 parent->SetUpMode(HEAD_UP_MODE);
1239 break;
1240
1241 case ID_DEF_MENU_NORTHUP:
1242 parent->SetUpMode(NORTH_UP_MODE);
1243 break;
1244
1245 case ID_DEF_MENU_TOGGLE_FULL:
1246 gFrame->ToggleFullScreen();
1247 break;
1248
1249 case ID_DEF_MENU_GOTOPOSITION:
1250 if (NULL == pGoToPositionDialog) // There is one global instance of the
1251 // Go To Position Dialog
1252 pGoToPositionDialog = new GoToPositionDialog(parent);
1253 pGoToPositionDialog->SetCanvas(parent);
1254 pGoToPositionDialog->CheckPasteBufferForPosition();
1255 pGoToPositionDialog->Show();
1256 break;
1257
1258 case ID_WP_MENU_DELPOINT: {
1259 if (m_pFoundRoutePoint == pAnchorWatchPoint1) {
1260 pAnchorWatchPoint1 = NULL;
1261 g_AW1GUID.Clear();
1262 } else if (m_pFoundRoutePoint == pAnchorWatchPoint2) {
1263 pAnchorWatchPoint2 = NULL;
1264 g_AW2GUID.Clear();
1265 }
1266
1267 if (m_pFoundRoutePoint && !(m_pFoundRoutePoint->m_bIsInLayer) &&
1268 (m_pFoundRoutePoint->GetIconName() != _T("mob"))) {
1269 // If the WP belongs to an invisible route, we come here instead of to
1270 // ID_RT_MENU_DELPOINT
1271 // Check it, and if so then remove the point from its routes
1272 wxArrayPtrVoid *proute_array =
1273 g_pRouteMan->GetRouteArrayContaining(m_pFoundRoutePoint);
1274 if (proute_array) {
1275 pWayPointMan->DestroyWaypoint(m_pFoundRoutePoint);
1276 } else {
1277 parent->undo->BeforeUndoableAction(
1278 Undo_DeleteWaypoint, m_pFoundRoutePoint, Undo_IsOrphanded,
1279 NULL /*m_pFoundPoint*/);
1280 pConfig->DeleteWayPoint(m_pFoundRoutePoint);
1281 pSelect->DeleteSelectablePoint(m_pFoundRoutePoint,
1282 SELTYPE_ROUTEPOINT);
1283 if (NULL != pWayPointMan)
1284 pWayPointMan->RemoveRoutePoint(m_pFoundRoutePoint);
1285 parent->undo->AfterUndoableAction(NULL);
1286 }
1287
1288 if (g_pMarkInfoDialog) {
1289 g_pMarkInfoDialog->SetRoutePoint(NULL);
1290 g_pMarkInfoDialog->UpdateProperties();
1291 }
1292
1293 if(RouteManagerDialog::getInstanceFlag()){
1294 if (pRouteManagerDialog) {
1295 if (pRouteManagerDialog->IsShown())
1296 pRouteManagerDialog->UpdateWptListCtrl();
1297 }
1298 }
1299
1300 gFrame->RefreshAllCanvas(false);
1301 gFrame->InvalidateAllGL();
1302 }
1303 break;
1304 }
1305 case ID_WP_MENU_PROPERTIES:
1306 parent->ShowMarkPropertiesDialog(m_pFoundRoutePoint);
1307 break;
1308
1309 case ID_WP_MENU_CLEAR_ANCHORWATCH:
1310 if (pAnchorWatchPoint1 == m_pFoundRoutePoint) {
1311 pAnchorWatchPoint1 = NULL;
1312 g_AW1GUID.Clear();
1313 } else if (pAnchorWatchPoint2 == m_pFoundRoutePoint) {
1314 pAnchorWatchPoint2 = NULL;
1315 g_AW2GUID.Clear();
1316 }
1317 break;
1318
1319 case ID_WP_MENU_SET_ANCHORWATCH:
1320 if (pAnchorWatchPoint1 == NULL) {
1321 pAnchorWatchPoint1 = m_pFoundRoutePoint;
1322 g_AW1GUID = pAnchorWatchPoint1->m_GUID;
1323 wxString nn;
1324 nn = m_pFoundRoutePoint->GetName();
1325 if (nn.IsNull()) {
1326 nn.Printf(_T("%d m"), g_nAWDefault);
1327 m_pFoundRoutePoint->SetName(nn);
1328 }
1329 } else if (pAnchorWatchPoint2 == NULL) {
1330 pAnchorWatchPoint2 = m_pFoundRoutePoint;
1331 g_AW2GUID = pAnchorWatchPoint2->m_GUID;
1332 wxString nn;
1333 nn = m_pFoundRoutePoint->GetName();
1334 if (nn.IsNull()) {
1335 nn.Printf(_T("%d m"), g_nAWDefault);
1336 m_pFoundRoutePoint->SetName(nn);
1337 }
1338 }
1339 break;
1340
1341 case ID_DEF_MENU_ACTIVATE_MEASURE:
1342 parent->StartMeasureRoute();
1343 break;
1344
1345 case ID_DEF_MENU_DEACTIVATE_MEASURE:
1346 parent->CancelMeasureRoute();
1347 gFrame->SurfaceAllCanvasToolbars();
1348 parent->InvalidateGL();
1349 parent->Refresh(false);
1350 break;
1351
1352 case ID_DEF_MENU_CM93OFFSET_DIALOG: {
1353 if (NULL == g_pCM93OffsetDialog) {
1354 g_pCM93OffsetDialog = new CM93OffsetDialog(parent->parent_frame);
1355 }
1356
1357 cm93compchart *pch = NULL;
1358 if (!parent->GetVP().b_quilt && parent->m_singleChart &&
1359 (parent->m_singleChart->GetChartType() == CHART_TYPE_CM93COMP)) {
1360 pch = (cm93compchart *)parent->m_singleChart;
1361 }
1362
1363 if (g_pCM93OffsetDialog) {
1364 g_pCM93OffsetDialog->SetCM93Chart(pch);
1365 g_pCM93OffsetDialog->Show();
1366 g_pCM93OffsetDialog->UpdateMCOVRList(parent->GetVP());
1367 }
1368
1369 break;
1370 }
1371 case ID_DEF_MENU_QUERY: {
1372 parent->ShowObjectQueryWindow(popx, popy, zlat, zlon);
1373 break;
1374 }
1375 case ID_DEF_MENU_AIS_QUERY: {
1376 wxWindow *pwin = wxDynamicCast(parent, wxWindow);
1377 ShowAISTargetQueryDialog(pwin, m_FoundAIS_MMSI);
1378 break;
1379 }
1380
1381 case ID_DEF_MENU_AIS_CPA: {
1382 auto myptarget = g_pAIS->Get_Target_Data_From_MMSI(m_FoundAIS_MMSI);
1383 if (myptarget) myptarget->Toggle_AIS_CPA();
1384 break;
1385 }
1386
1387 case ID_DEF_MENU_AISSHOWTRACK: {
1388 auto myptarget = g_pAIS->Get_Target_Data_From_MMSI(m_FoundAIS_MMSI);
1389 if (myptarget) myptarget->ToggleShowTrack();
1390 break;
1391 }
1392
1393 case ID_DEF_MENU_COPY_MMSI: {
1394 // Write MMSI # as text to the clipboard
1395 if (wxTheClipboard->Open()) {
1396 wxTheClipboard->SetData(new wxTextDataObject(
1397 wxString::Format(wxT("%09d"), m_FoundAIS_MMSI)));
1398 wxTheClipboard->Close();
1399 }
1400 break;
1401 }
1402
1403 case ID_DEF_MENU_QUILTREMOVE: {
1404 if (parent->GetVP().b_quilt) {
1405 int dbIndex = parent->m_pQuilt->GetChartdbIndexAtPix(
1406 parent->GetVP(), wxPoint(popx, popy));
1407 parent->RemoveChartFromQuilt(dbIndex);
1408
1409 parent->ReloadVP();
1410 }
1411
1412 break;
1413 }
1414
1415 case ID_DEF_MENU_CURRENTINFO: {
1416 parent->DrawTCWindow(popx, popy, (void *)m_pIDXCandidate);
1417 parent->Refresh(false);
1418
1419 break;
1420 }
1421
1422 case ID_DEF_MENU_TIDEINFO: {
1423 parent->DrawTCWindow(popx, popy, (void *)m_pIDXCandidate);
1424 parent->Refresh(false);
1425
1426 break;
1427 }
1428 case ID_RT_MENU_REVERSE: {
1429 if (m_pSelectedRoute->m_bIsInLayer) break;
1430
1431 int ask_return =
1432 OCPNMessageBox(parent, g_pRouteMan->GetRouteReverseMessage(),
1433 _("Rename Waypoints?"), wxYES_NO | wxCANCEL);
1434
1435 if (ask_return != wxID_CANCEL) {
1436 pSelect->DeleteAllSelectableRouteSegments(m_pSelectedRoute);
1437 m_pSelectedRoute->Reverse(ask_return == wxID_YES);
1438 pSelect->AddAllSelectableRouteSegments(m_pSelectedRoute);
1439
1440 pConfig->UpdateRoute(m_pSelectedRoute);
1441
1442 if (pRoutePropDialog && (pRoutePropDialog->IsShown())) {
1443 pRoutePropDialog->SetRouteAndUpdate(m_pSelectedRoute);
1444 // pNew->UpdateProperties();
1445 }
1446 gFrame->InvalidateAllGL();
1447 gFrame->RefreshAllCanvas();
1448 }
1449 break;
1450 }
1451
1452 case ID_RT_MENU_SHOWNAMES: {
1453 if (m_pSelectedRoute) {
1454 m_pSelectedRoute->ShowWaypointNames(
1455 !m_pSelectedRoute->AreWaypointNamesVisible());
1456 }
1457
1458 break;
1459 }
1460
1461 case ID_RT_MENU_RESEQUENCE: {
1462 if (m_pSelectedRoute) {
1463 if (m_pSelectedRoute->m_bIsInLayer) break;
1464
1465 int ask_return =
1466 OCPNMessageBox(parent, g_pRouteMan->GetRouteResequenceMessage(),
1467 _("Rename Waypoints?"), wxYES_NO | wxCANCEL);
1468
1469 if (ask_return != wxID_CANCEL) {
1470 m_pSelectedRoute->RenameRoutePoints();
1471 }
1472
1473 gFrame->InvalidateAllGL();
1474 gFrame->RefreshAllCanvas();
1475 }
1476
1477 break;
1478 }
1479
1480 case ID_RT_MENU_DELETE: {
1481 int dlg_return = wxID_YES;
1482 if (g_bConfirmObjectDelete) {
1483 dlg_return = OCPNMessageBox(
1484 parent, _("Are you sure you want to delete this route?"),
1485 _("OpenCPN Route Delete"),
1486 (long)wxYES_NO | wxCANCEL | wxYES_DEFAULT);
1487 }
1488
1489 if (dlg_return == wxID_YES) {
1490 if (g_pRouteMan->GetpActiveRoute() == m_pSelectedRoute)
1491 g_pRouteMan->DeactivateRoute();
1492
1493 if (m_pSelectedRoute->m_bIsInLayer) break;
1494
1495 if (!g_pRouteMan->DeleteRoute(m_pSelectedRoute,
1496 NavObjectChanges::getInstance())) break;
1497
1498 if(RouteManagerDialog::getInstanceFlag()){
1499 if (pRouteManagerDialog && pRouteManagerDialog->IsShown())
1500 pRouteManagerDialog->UpdateRouteListCtrl();
1501 }
1502
1503 if (g_pMarkInfoDialog && g_pMarkInfoDialog->IsShown()) {
1504 g_pMarkInfoDialog->ValidateMark();
1505 g_pMarkInfoDialog->UpdateProperties();
1506 }
1507
1508 parent->undo->InvalidateUndo();
1509
1510 gFrame->InvalidateAllGL();
1511 gFrame->RefreshAllCanvas();
1512 }
1513 break;
1514 }
1515
1516 case ID_RT_MENU_ACTIVATE: {
1517 if (g_pRouteMan->GetpActiveRoute()) g_pRouteMan->DeactivateRoute();
1518
1519 // If this is an auto-created MOB route, always select the second point
1520 // (the MOB)
1521 // as the destination.
1522 RoutePoint *best_point;
1523 if (m_pSelectedRoute) {
1524 if (wxNOT_FOUND ==
1525 m_pSelectedRoute->m_RouteNameString.Find(_T("MOB"))) {
1526 best_point = g_pRouteMan->FindBestActivatePoint(
1527 m_pSelectedRoute, gLat, gLon, gCog, gSog);
1528 } else
1529 best_point = m_pSelectedRoute->GetPoint(2);
1530
1531 g_pRouteMan->ActivateRoute(m_pSelectedRoute, best_point);
1532 m_pSelectedRoute->m_bRtIsSelected = false;
1533 }
1534
1535 break;
1536 }
1537
1538 case ID_RT_MENU_DEACTIVATE:
1539 g_pRouteMan->DeactivateRoute();
1540 m_pSelectedRoute->m_bRtIsSelected = false;
1541
1542 break;
1543
1544 case ID_RT_MENU_INSERT: {
1545 if (m_pSelectedRoute->m_bIsInLayer) break;
1546 bool rename = false;
1547 m_pSelectedRoute->InsertPointAfter(m_pFoundRoutePoint, zlat, zlon,
1548 rename);
1549
1550 pSelect->DeleteAllSelectableRoutePoints(m_pSelectedRoute);
1551 pSelect->DeleteAllSelectableRouteSegments(m_pSelectedRoute);
1552
1553 pSelect->AddAllSelectableRouteSegments(m_pSelectedRoute);
1554 pSelect->AddAllSelectableRoutePoints(m_pSelectedRoute);
1555
1556 // As a special case (which comes up often)...
1557 // If the inserted waypoint is on the active leg of an active route
1558 /* if(m_pSelectedRoute->m_bRtIsActive)
1559 {
1560 if(m_pSelectedRoute->m_nRouteActivePoint == np + 1)
1561 {
1562 pNew_Point = m_pSelectedRoute->GetPoint(np + 2);
1563 pRouteMan->ActivateRoutePoint(m_pSelectedRoute, pNew_Point);
1564 }
1565 }
1566 */
1567 pConfig->UpdateRoute(m_pSelectedRoute);
1568
1569 if (pRoutePropDialog && (pRoutePropDialog->IsShown())) {
1570 pRoutePropDialog->SetRouteAndUpdate(m_pSelectedRoute, true);
1571 }
1572
1573 break;
1574 }
1575
1576 case ID_RT_MENU_APPEND:
1577
1578 if (m_pSelectedRoute->m_bIsInLayer) break;
1579
1580 parent->m_pMouseRoute = m_pSelectedRoute;
1581 parent->m_routeState = m_pSelectedRoute->GetnPoints() + 1;
1582 parent->m_pMouseRoute->m_lastMousePointIndex =
1583 m_pSelectedRoute->GetnPoints();
1584 parent->m_pMouseRoute->SetHiLite(50);
1585
1586 pLast = m_pSelectedRoute->GetLastPoint();
1587
1588 parent->m_prev_rlat = pLast->m_lat;
1589 parent->m_prev_rlon = pLast->m_lon;
1590 parent->m_prev_pMousePoint = pLast;
1591
1592 parent->m_bAppendingRoute = true;
1593
1594 parent->SetCursor(*parent->pCursorPencil);
1595#ifdef __OCPN__ANDROID__
1596 androidSetRouteAnnunciator(true);
1597#endif
1598
1599 parent->HideGlobalToolbar();
1600
1601 break;
1602
1603 case ID_RT_MENU_SPLIT_LEG: // split route around a leg
1604 splitMode++;
1605 dupFirstWpt = false;
1606 case ID_RT_MENU_SPLIT_WPT: // split route at a wpt
1607
1608 showRPD = (pRoutePropDialog && pRoutePropDialog->IsShown());
1609
1610 m_pHead = new Route();
1611 m_pTail = new Route();
1612 m_pHead->CloneRoute(m_pSelectedRoute, 1, m_SelectedIdx, _("_A"));
1613 m_pTail->CloneRoute(m_pSelectedRoute, m_SelectedIdx + splitMode,
1614 m_pSelectedRoute->GetnPoints(), _("_B"), dupFirstWpt);
1615 pRouteList->Append(m_pHead);
1616 pConfig->AddNewRoute(m_pHead);
1617
1618 pRouteList->Append(m_pTail);
1619 pConfig->AddNewRoute(m_pTail);
1620
1621 pConfig->DeleteConfigRoute(m_pSelectedRoute);
1622
1623 pSelect->DeleteAllSelectableRoutePoints(m_pSelectedRoute);
1624 pSelect->DeleteAllSelectableRouteSegments(m_pSelectedRoute);
1625 g_pRouteMan->DeleteRoute(m_pSelectedRoute,
1626 NavObjectChanges::getInstance());
1627 pSelect->AddAllSelectableRouteSegments(m_pTail);
1628 pSelect->AddAllSelectableRoutePoints(m_pTail);
1629 pSelect->AddAllSelectableRouteSegments(m_pHead);
1630 pSelect->AddAllSelectableRoutePoints(m_pHead);
1631
1632 if (showRPD) {
1633 pRoutePropDialog->SetRouteAndUpdate(m_pHead);
1634 pRoutePropDialog->Show();
1635 }
1636 if (RouteManagerDialog::getInstanceFlag() && pRouteManagerDialog &&
1637 (pRouteManagerDialog->IsShown()))
1638 pRouteManagerDialog->UpdateRouteListCtrl();
1639 break;
1640
1641 case ID_RT_MENU_COPY:
1642 if (m_pSelectedRoute) Kml::CopyRouteToClipboard(m_pSelectedRoute);
1643 break;
1644
1645 case ID_TK_MENU_COPY:
1646 if (m_pSelectedTrack) Kml::CopyTrackToClipboard(m_pSelectedTrack);
1647 break;
1648
1649 case ID_WPT_MENU_COPY:
1650 if (m_pFoundRoutePoint) Kml::CopyWaypointToClipboard(m_pFoundRoutePoint);
1651 break;
1652
1653 case ID_WPT_MENU_SENDTOGPS:
1654 if (m_pFoundRoutePoint) {
1655 if (parent->m_active_upload_port.Length())
1656 RoutePointGui(*m_pFoundRoutePoint).SendToGPS(
1657 parent->m_active_upload_port.BeforeFirst(' '), NULL);
1658 else {
1659 SendToGpsDlg dlg;
1660 dlg.SetWaypoint(m_pFoundRoutePoint);
1661 wxFont fo = GetOCPNGUIScaledFont(_T("Dialog"));
1662 dlg.SetFont(fo);
1663
1664 dlg.Create(NULL, -1, _("Send to GPS") + _T( "..." ), _T(""));
1665 dlg.ShowModal();
1666 }
1667 }
1668 break;
1669
1670 case ID_WPT_MENU_SENDTONEWGPS:
1671 if (m_pFoundRoutePoint) {
1672 SendToGpsDlg dlg;
1673 dlg.SetWaypoint(m_pFoundRoutePoint);
1674
1675 dlg.Create(NULL, -1, _("Send to GPS") + _T( "..." ), _T(""));
1676 dlg.ShowModal();
1677 }
1678 break;
1679
1680 case ID_RT_MENU_SENDTOGPS:
1681 if (m_pSelectedRoute) {
1682 if (parent->m_active_upload_port.Length())
1683 RouteGui(*m_pSelectedRoute).SendToGPS(
1684 parent->m_active_upload_port.BeforeFirst(' '), true, NULL);
1685 else {
1686 SendToGpsDlg dlg;
1687 dlg.SetRoute(m_pSelectedRoute);
1688
1689 dlg.Create(NULL, -1, _("Send to GPS") + _T( "..." ), _T(""));
1690 dlg.ShowModal();
1691 }
1692 }
1693 break;
1694
1695 case ID_RT_MENU_SENDTONEWGPS:
1696 if (m_pSelectedRoute) {
1697 SendToGpsDlg dlg;
1698 dlg.SetRoute(m_pSelectedRoute);
1699
1700 dlg.Create(NULL, -1, _("Send to GPS") + _T( "..." ), _T(""));
1701 dlg.ShowModal();
1702 }
1703 break;
1704
1705 case ID_RT_MENU_SENDTOPEER:
1706 if (m_pSelectedRoute) {
1707
1708 SendToPeerDlg dlg;
1709 dlg.SetRoute(m_pSelectedRoute);
1710
1711 // Perform initial scan, if necessary
1712
1713 // Check for stale cache...
1714 bool bDNScacheStale = true;
1715 wxDateTime tnow = wxDateTime::Now();
1716 if (g_DNS_cache_time.IsValid()){
1717 wxTimeSpan delta = tnow.Subtract(g_DNS_cache_time);
1718 if (delta.GetMinutes() < 5)
1719 bDNScacheStale = false;
1720 }
1721
1722 if ((g_DNS_cache.size() == 0) || bDNScacheStale)
1723 dlg.SetScanOnCreate(true);
1724
1725 dlg.SetScanTime(5); // seconds
1726 dlg.Create(NULL, -1, _("Send Route to OpenCPN Peer") + _T( "..." ), _T(""));
1727 dlg.ShowModal();
1728 }
1729 break;
1730
1731 case ID_PASTE_WAYPOINT:
1732 pupHandler_PasteWaypoint();
1733 break;
1734
1735 case ID_PASTE_ROUTE:
1736 pupHandler_PasteRoute();
1737 break;
1738
1739 case ID_PASTE_TRACK:
1740 pupHandler_PasteTrack();
1741 break;
1742
1743 case ID_RT_MENU_DELPOINT:
1744 if (m_pSelectedRoute) {
1745 if (m_pSelectedRoute->m_bIsInLayer) break;
1746
1747 pWayPointMan->DestroyWaypoint(m_pFoundRoutePoint);
1748
1749 if (pRoutePropDialog && (pRoutePropDialog->IsShown())) {
1750 // Selected route may have been deleted as one-point route, so
1751 // check it
1752 if (g_pRouteMan->IsRouteValid(m_pSelectedRoute)) {
1753 pRoutePropDialog->SetRouteAndUpdate(m_pSelectedRoute, true);
1754 } else
1755 pRoutePropDialog->Hide();
1756 }
1757
1758 if(RouteManagerDialog::getInstanceFlag()){
1759 if (pRouteManagerDialog && pRouteManagerDialog->IsShown()) {
1760 pRouteManagerDialog->UpdateWptListCtrl();
1761 pRouteManagerDialog->UpdateRouteListCtrl();
1762 }
1763 }
1764
1765 gFrame->InvalidateAllGL();
1766 gFrame->RefreshAllCanvas(true);
1767 }
1768
1769 break;
1770
1771 case ID_RT_MENU_REMPOINT:
1772 if (m_pSelectedRoute) {
1773 if (m_pSelectedRoute->m_bIsInLayer) break;
1774 g_pRouteMan->RemovePointFromRoute(m_pFoundRoutePoint, m_pSelectedRoute,
1775 parent->m_routeState);
1776 gFrame->InvalidateAllGL();
1777 gFrame->RefreshAllCanvas();
1778 }
1779 break;
1780
1781 case ID_RT_MENU_ACTPOINT:
1782 if (g_pRouteMan->GetpActiveRoute() == m_pSelectedRoute) {
1783 g_pRouteMan->ActivateRoutePoint(m_pSelectedRoute, m_pFoundRoutePoint);
1784 m_pSelectedRoute->m_bRtIsSelected = false;
1785 }
1786
1787 break;
1788
1789 case ID_RT_MENU_DEACTPOINT:
1790 break;
1791
1792 case ID_RT_MENU_ACTNXTPOINT:
1793 if (g_pRouteMan->GetpActiveRoute() == m_pSelectedRoute) {
1794 g_pRouteMan->ActivateNextPoint(m_pSelectedRoute, true);
1795 m_pSelectedRoute->m_bRtIsSelected = false;
1796 }
1797
1798 break;
1799
1800 case ID_RT_MENU_PROPERTIES: {
1801 parent->ShowRoutePropertiesDialog(_("Route Properties"),
1802 m_pSelectedRoute);
1803 break;
1804 }
1805
1806 case ID_TK_MENU_PROPERTIES: {
1807 parent->ShowTrackPropertiesDialog(m_pSelectedTrack);
1808 break;
1809 }
1810
1811 case ID_TK_MENU_DELETE: {
1812 int dlg_return = wxID_YES;
1813 if (g_bConfirmObjectDelete) {
1814 dlg_return = OCPNMessageBox(
1815 parent, _("Are you sure you want to delete this track?"),
1816 _("OpenCPN Track Delete"),
1817 (long)wxYES_NO | wxCANCEL | wxYES_DEFAULT);
1818 }
1819
1820 if (dlg_return == wxID_YES) {
1821 if (m_pSelectedTrack == g_pActiveTrack)
1822 m_pSelectedTrack = parent->parent_frame->TrackOff();
1823 g_pAIS->DeletePersistentTrack(m_pSelectedTrack);
1824 pConfig->DeleteConfigTrack(m_pSelectedTrack);
1825
1826 RoutemanGui(*g_pRouteMan).DeleteTrack(m_pSelectedTrack);
1827
1828 if (TrackPropDlg::getInstanceFlag() && pTrackPropDialog &&
1829 (pTrackPropDialog->IsShown()) &&
1830 (m_pSelectedTrack == pTrackPropDialog->GetTrack())) {
1831 pTrackPropDialog->Hide();
1832 }
1833
1834 if (RoutePropDlgImpl::getInstanceFlag() && pRouteManagerDialog &&
1835 pRouteManagerDialog->IsShown()) {
1836 pRouteManagerDialog->UpdateTrkListCtrl();
1837 pRouteManagerDialog->UpdateRouteListCtrl();
1838 }
1839 gFrame->InvalidateAllGL();
1840 gFrame->RefreshAllCanvas();
1841 }
1842 break;
1843 }
1844
1845 case ID_RC_MENU_SCALE_IN:
1846 parent->parent_frame->DoStackDown(parent);
1847 parent->GetCanvasPointPix(zlat, zlon, &r);
1848 parent->WarpPointer(r.x, r.y);
1849 break;
1850
1851 case ID_RC_MENU_SCALE_OUT:
1852 parent->parent_frame->DoStackUp(parent);
1853 parent->GetCanvasPointPix(zlat, zlon, &r);
1854 parent->WarpPointer(r.x, r.y);
1855 break;
1856
1857 case ID_RC_MENU_ZOOM_IN:
1858 parent->SetVPScale(parent->GetVPScale() * 2);
1859 parent->GetCanvasPointPix(zlat, zlon, &r);
1860 parent->WarpPointer(r.x, r.y);
1861 break;
1862
1863 case ID_RC_MENU_ZOOM_OUT:
1864 parent->SetVPScale(parent->GetVPScale() / 2);
1865 parent->GetCanvasPointPix(zlat, zlon, &r);
1866 parent->WarpPointer(r.x, r.y);
1867 break;
1868
1869 case ID_RC_MENU_FINISH:
1870 parent->FinishRoute();
1871 gFrame->SurfaceAllCanvasToolbars();
1872 parent->Refresh(false);
1873 g_FlushNavobjChanges = true;
1874 break;
1875
1876 case ID_DEF_ZERO_XTE:
1877 g_pRouteMan->ZeroCurrentXTEToActivePoint();
1878 break;
1879
1880 default: {
1881 // Look for PlugIn Context Menu selections
1882 // If found, make the callback
1883 ArrayOfPlugInMenuItems item_array =
1884 g_pi_manager->GetPluginContextMenuItemArray();
1885
1886 for (unsigned int i = 0; i < item_array.GetCount(); i++) {
1887 PlugInMenuItemContainer *pimis = item_array[i];
1888 {
1889 if (pimis->id == event.GetId()) {
1890 if (pimis->m_pplugin)
1891 pimis->m_pplugin->OnContextMenuItemCallback(pimis->id);
1892 }
1893 }
1894 }
1895
1896 break;
1897 }
1898 } // switch
1899
1900 // Chart Groups....
1901 if ((event.GetId() >= ID_DEF_MENU_GROUPBASE) &&
1902 (event.GetId() <=
1903 ID_DEF_MENU_GROUPBASE + (int)g_pGroupArray->GetCount())) {
1904 parent->SetGroupIndex(event.GetId() - ID_DEF_MENU_GROUPBASE);
1905 }
1906
1907 parent->InvalidateGL();
1908
1909 g_click_stop = 0; // Context menu was processed, all is well
1910}
Definition: kml.h:54
Class MarkInfoDef.
Definition: MarkInfo.h:197
void SurfaceAllCanvasToolbars(void)
Definition: route.h:70
bool ActivateRoutePoint(Route *pA, RoutePoint *pRP)
Definition: routeman.cpp:312
bool ActivateNextPoint(Route *pr, bool skipped)
Definition: routeman.cpp:387
bool DeleteRoute(Route *pRoute, NavObjectChanges *nav_obj_changes)
Definition: routeman.cpp:726
Definition: select.h:51
Route "Send to GPS..." Dialog Definition.
Definition: SendToGpsDlg.h:56
Route "Send to Peer..." Dialog Definition.
Definition: SendToPeerDlg.h:54
Class TrackPropDlg.
Definition: TrackPropDlg.h:87
Definition: track.h:79