OpenCPN Partial API docs
Loading...
Searching...
No Matches
routemanagerdialog.cpp
1/*
2 This program is free software; you can redistribute it and/or
3 modify it under the terms of the GNU General Public License
4 as published by the Free Software Foundation; either version 2
5 of the License, or (at your option) any later version.
6
7 This program is distributed in the hope that it will be useful,
8 but WITHOUT ANY WARRANTY; without even the implied warranty of
9 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 GNU General Public License for more details.
11
12 You should have received a copy of the GNU General Public License
13 along with this program; if not, write to the Free Software
14 Foundation, Inc., 51 Franklin Street, Fifth Floor,
15 Boston, MA 02110-1301, USA.
16
17 ---
18 Copyright (C) 2010, Anders Lund <anders@alweb.dk>
19 */
20
21#include "config.h"
22
23#include "routemanagerdialog.h"
24
25// For compilers that support precompilation, includes "wx/wx.h".
26#include <wx/wxprec.h>
27
28#ifndef WX_PRECOMP
29#include <wx/wx.h>
30#endif
31
32#include <wx/filename.h>
33#include <wx/stdpaths.h>
34#include <wx/progdlg.h>
35#include <wx/clipbrd.h>
36
37#include <iostream>
38#include <vector>
39#include <algorithm>
40
41#include "styles.h"
42#include "dychart.h"
43#include "navutil.h"
44#include "MarkInfo.h"
45#include "RoutePropDlgImpl.h"
46#include "routeman.h"
47#include "routeman_gui.h"
48#include "route_point_gui.h"
49#include "georef.h"
50#include "chartbase.h"
51#include "Layer.h"
52#include "SendToGpsDlg.h"
53#include "TrackPropDlg.h"
54#include "ais_decoder.h"
55#include "OCPNPlatform.h"
56#include "track.h"
57#include "route.h"
58#include "chcanv.h"
59#include "navutil_base.h"
60#include "svg_utils.h"
61#include "ocpn_frame.h"
62#include "own_ship.h"
63#include "config_vars.h"
64#include "mDNS_query.h"
65#include "SendToPeerDlg.h"
66
67#ifdef __OCPN__ANDROID__
68#include "androidUTIL.h"
69#endif
70
71#define DIALOG_MARGIN 3
72
73enum { rmVISIBLE = 0, rmROUTENAME, rmROUTEDESC }; // RMColumns;
74enum { colTRKVISIBLE = 0, colTRKNAME, colTRKLENGTH };
75enum { colLAYVISIBLE = 0, colLAYNAME, colLAYITEMS, colLAYPERSIST };
76enum { colWPTICON = 0, colWPTSCALE, colWPTNAME, colWPTDIST };
77
78// GLOBALS :0
79extern RouteList *pRouteList;
80extern std::vector<Track*> g_TrackList;
81extern LayerList *pLayerList;
82extern wxString GetLayerName(int id);
83extern RoutePropDlgImpl *pRoutePropDialog;
84extern TrackPropDlg *pTrackPropDialog;
85extern Routeman *g_pRouteMan;
86extern MyConfig *pConfig;
87extern ActiveTrack *g_pActiveTrack;
88extern WayPointman *pWayPointMan;
89extern MarkInfoDlg *g_pMarkInfoDialog;
90extern MyFrame *gFrame;
91extern Select *pSelect;
92extern bool g_bShowLayers;
93extern wxString g_default_wp_icon;
94extern AisDecoder *g_pAIS;
95extern OCPNPlatform *g_Platform;
96extern bool g_bOverruleScaMin;
97extern std::vector<std::shared_ptr<ocpn_DNS_record_t>> g_DNS_cache;
98
99// Helper for conditional file name separator
100void appendOSDirSlash(wxString *pString);
101
102static int SortRouteTrack(const int order, const wxString &it1,
103 const wxString &it2) {
104 if (order & 1) return it2.CmpNoCase(it1);
105
106 return it1.CmpNoCase(it2);
107}
108
109// sort callback. Sort by route name.
110static int sort_route_name_dir;
111#if wxCHECK_VERSION(2, 9, 0)
112static int wxCALLBACK SortRoutesOnName(wxIntPtr item1, wxIntPtr item2,
113 wxIntPtr list)
114#else
115int wxCALLBACK SortRoutesOnName(long item1, long item2, long list)
116#endif
117{
118 return SortRouteTrack(sort_route_name_dir, ((Route *)item1)->GetName(),
119 ((Route *)item2)->GetName());
120}
121
122// sort callback. Sort by route Destination.
123static int sort_route_to_dir;
124#if wxCHECK_VERSION(2, 9, 0)
125static int wxCALLBACK SortRoutesOnTo(wxIntPtr item1, wxIntPtr item2,
126 wxIntPtr list)
127#else
128int wxCALLBACK SortRoutesOnTo(long item1, long item2, long list)
129#endif
130{
131 return SortRouteTrack(sort_route_to_dir, ((Route *)item1)->GetTo(),
132 ((Route *)item2)->GetTo());
133}
134
135// sort callback. Sort by track name.
136static int sort_track_name_dir;
137#if wxCHECK_VERSION(2, 9, 0)
138static int wxCALLBACK SortTracksOnName(wxIntPtr item1, wxIntPtr item2,
139 wxIntPtr list)
140#else
141int wxCALLBACK SortTracksOnName(long item1, long item2, long list)
142#endif
143{
144 return SortRouteTrack(sort_track_name_dir, ((Track *)item1)->GetName(),
145 ((Track *)item2)->GetName());
146}
147
148static int SortDouble(const int order, const double &it1, const double &it2) {
149 double l1;
150 double l2;
151
152 if (order & 1) {
153 l1 = it2;
154 l2 = it1;
155 } else {
156 l1 = it1;
157 l2 = it2;
158 }
159
160 if (l1 == l2) return 0;
161 if (l2 < l1) return 1;
162 return -1;
163}
164
165// sort callback. Sort by track length.
166static int sort_track_len_dir;
167#if wxCHECK_VERSION(2, 9, 0)
168static int wxCALLBACK SortTracksOnDistance(wxIntPtr item1, wxIntPtr item2,
169 wxIntPtr list)
170#else
171int wxCALLBACK SortTracksOnDistance(long item1, long item2, long list)
172#endif
173{
174 return SortDouble(sort_track_len_dir, ((Track *)item1)->Length(),
175 ((Track *)item2)->Length());
176}
177
178static int sort_wp_key;
179static int sort_track_key;
180
181// sort callback. Sort by wpt name.
182static int sort_wp_name_dir;
183#if wxCHECK_VERSION(2, 9, 0)
184static int wxCALLBACK SortWaypointsOnName(wxIntPtr item1, wxIntPtr item2,
185 wxIntPtr list)
186#else
187int wxCALLBACK SortWaypointsOnName(long item1, long item2, long list)
188#endif
189
190{
191 RoutePoint *pRP1 = (RoutePoint *)item1;
192 RoutePoint *pRP2 = (RoutePoint *)item2;
193
194 if (pRP1 && pRP2) {
195 if (sort_wp_name_dir & 1)
196 return pRP2->GetName().CmpNoCase(pRP1->GetName());
197 else
198 return pRP1->GetName().CmpNoCase(pRP2->GetName());
199 } else
200 return 0;
201}
202
203// sort callback. Sort by wpt distance.
204static int sort_wp_len_dir;
205#if wxCHECK_VERSION(2, 9, 0)
206static int wxCALLBACK SortWaypointsOnDistance(wxIntPtr item1, wxIntPtr item2,
207 wxIntPtr list)
208#else
209int wxCALLBACK SortWaypointsOnDistance(long item1, long item2, long list)
210#endif
211{
212 double dst1, dst2;
213 DistanceBearingMercator(((RoutePoint *)item1)->m_lat,
214 ((RoutePoint *)item1)->m_lon, gLat, gLon, NULL,
215 &dst1);
216 DistanceBearingMercator(((RoutePoint *)item2)->m_lat,
217 ((RoutePoint *)item2)->m_lon, gLat, gLon, NULL,
218 &dst2);
219 return SortDouble(sort_wp_len_dir, dst1, dst2);
220}
221
222// sort callback. Sort by layer name.
223static int sort_layer_name_dir;
224#if wxCHECK_VERSION(2, 9, 0)
225static int wxCALLBACK SortLayersOnName(wxIntPtr item1, wxIntPtr item2,
226 wxIntPtr list)
227#else
228int wxCALLBACK SortLayersOnName(long item1, long item2, long list)
229#endif
230{
231 return SortRouteTrack(sort_layer_name_dir, ((Layer *)item1)->m_LayerName,
232 ((Layer *)item2)->m_LayerName);
233}
234
235// sort callback. Sort by layer size.
236static int sort_layer_len_dir;
237#if wxCHECK_VERSION(2, 9, 0)
238static int wxCALLBACK SortLayersOnSize(wxIntPtr item1, wxIntPtr item2,
239 wxIntPtr list)
240#else
241int wxCALLBACK SortLayersOnSize(long item1, long item2, long list)
242#endif
243{
244 return SortDouble(sort_layer_len_dir, ((Layer *)item1)->m_NoOfItems,
245 ((Layer *)item2)->m_NoOfItems);
246}
247
248// event table. Mostly empty, because I find it much easier to see what is
249// connected to what using Connect() where possible, so that it is visible in
250// the code.
251BEGIN_EVENT_TABLE(RouteManagerDialog, wxFrame)
252EVT_NOTEBOOK_PAGE_CHANGED(
253 wxID_ANY,
254 RouteManagerDialog::OnTabSwitch) // This should work under Windows :-(
255EVT_CLOSE(RouteManagerDialog::OnClose)
256EVT_COMMAND(wxID_OK, wxEVT_COMMAND_BUTTON_CLICKED, RouteManagerDialog::OnOK)
257EVT_CHAR_HOOK(RouteManagerDialog::OnKey)
258END_EVENT_TABLE()
259
260void RouteManagerDialog::OnKey(wxKeyEvent &ke) {
261 if (ke.GetKeyCode() == WXK_ESCAPE)
262 Close(true);
263 else
264 ke.Skip();
265}
266
267void RouteManagerDialog::OnTabSwitch(wxNotebookEvent &event) {
268 if (!m_pNotebook) return;
269 int current_page = m_pNotebook->GetSelection();
270 if (current_page == 3) {
271 if (btnImport) btnImport->Enable(false);
272 if (btnExport) btnExport->Enable(false);
273 if (btnExportViz) btnExportViz->Enable(false);
274 } else {
275 if (btnImport) btnImport->Enable(true);
276 if (btnExport) btnExport->Enable(true);
277 if (btnExportViz) btnExportViz->Enable(true);
278 }
279 event.Skip(); // remove if using event table... why?
280}
281
282// implementation
283
284bool RouteManagerDialog::instanceFlag = false;
285RouteManagerDialog *RouteManagerDialog::single = NULL;
286
287RouteManagerDialog *RouteManagerDialog::getInstance(wxWindow *parent) {
288 if (!instanceFlag) {
289 single = new RouteManagerDialog(parent);
290 instanceFlag = true;
291 return single;
292 } else {
293 return single;
294 }
295}
296
297RouteManagerDialog::RouteManagerDialog(wxWindow *parent) {
298 long style =
299 wxDEFAULT_FRAME_STYLE | wxRESIZE_BORDER | wxFRAME_FLOAT_ON_PARENT;
300
301 wxFrame::Create(parent, -1, wxString(_("Route & Mark Manager")),
302 wxDefaultPosition, wxDefaultSize, style);
303
304 wxFont *qFont = GetOCPNScaledFont(_("Dialog"));
305 SetFont(*qFont);
306
307 m_lastWptItem = -1;
308 m_lastTrkItem = -1;
309 m_lastRteItem = -1;
310 sort_wp_key = SORT_ON_NAME;
311 sort_track_key = SORT_ON_NAME;
312
313 btnImport = NULL;
314 btnExport = NULL;
315 btnExportViz = NULL;
316
317 Create();
318}
319
320void RouteManagerDialog::Create() {
321 // Get a text height metric for reference
322 int char_width, char_height;
323 GetTextExtent(_T("W"), &char_width, &char_height);
324 m_charWidth = char_width;
325
326 wxBoxSizer *itemBoxSizer1 = new wxBoxSizer(wxVERTICAL);
327 SetSizer(itemBoxSizer1);
328
329 m_pNotebook = new wxNotebook(this, wxID_ANY, wxDefaultPosition,
330 wxSize(-1, -1), wxNB_TOP);
331 itemBoxSizer1->Add(m_pNotebook, 1, wxALL | wxEXPAND, 5);
332
333 // Create "Routes" panel
334 m_pPanelRte = new wxPanel(m_pNotebook, wxID_ANY, wxDefaultPosition,
335 wxDefaultSize, wxNO_BORDER | wxTAB_TRAVERSAL);
336
337 wxBoxSizer *sbsRoutes = new wxBoxSizer(wxHORIZONTAL);
338 m_pPanelRte->SetSizer(sbsRoutes);
339 m_pNotebook->AddPage(m_pPanelRte, _("Routes"));
340
341 sort_wp_len_dir = 1;
342 sort_wp_name_dir = 0;
343 sort_track_len_dir = 1;
344 sort_route_to_dir = 0;
345 sort_track_name_dir = 0;
346 sort_route_name_dir = 0;
347 sort_layer_name_dir = 0;
348 sort_layer_len_dir = 1;
349
350 m_listIconSize = 2 * GetCharHeight();
351
352 // Setup GUI
353 wxBoxSizer *bSizerRteContents;
354 bSizerRteContents = new wxBoxSizer(wxVERTICAL);
355
356 wxFlexGridSizer *fgSizerFilterRte;
357 fgSizerFilterRte = new wxFlexGridSizer(0, 2, 0, 0);
358 fgSizerFilterRte->AddGrowableCol(1);
359 fgSizerFilterRte->SetFlexibleDirection(wxBOTH);
360 fgSizerFilterRte->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_SPECIFIED);
361
362 m_stFilterRte = new wxStaticText(m_pPanelRte, wxID_ANY, _("Filter"),
363 wxDefaultPosition, wxDefaultSize, 0);
364 m_stFilterRte->Wrap(-1);
365 fgSizerFilterRte->Add(m_stFilterRte, 0, wxALL, 5);
366
367 m_tFilterRte = new wxTextCtrl(m_pPanelRte, wxID_ANY, wxEmptyString,
368 wxDefaultPosition, wxDefaultSize, 0);
369 fgSizerFilterRte->Add(m_tFilterRte, 1, wxALL | wxEXPAND, 5);
370
371 bSizerRteContents->Add(fgSizerFilterRte, 0, wxEXPAND, 5);
372 m_tFilterRte->Connect(
373 wxEVT_COMMAND_TEXT_UPDATED,
374 wxCommandEventHandler(RouteManagerDialog::OnFilterChanged), NULL, this);
375
376 m_cbShowAllRte = new wxCheckBox(m_pPanelRte, wxID_ANY, _("Show all routes"));
377 bSizerRteContents->Add(m_cbShowAllRte, 0, wxEXPAND | wxLEFT, 5);
378 m_cbShowAllRte->Connect(
379 wxEVT_COMMAND_CHECKBOX_CLICKED,
380 wxCommandEventHandler(RouteManagerDialog::OnShowAllRteCBClicked), NULL,
381 this);
382
383 m_pRouteListCtrl =
384 new wxListCtrl(m_pPanelRte, -1, wxDefaultPosition, wxSize(-1, -1),
385 wxLC_REPORT | wxLC_SORT_ASCENDING | wxLC_HRULES |
386 wxBORDER_SUNKEN /*|wxLC_VRULES*/);
387#ifdef __OCPN__ANDROID__
388 m_pRouteListCtrl->GetHandle()->setStyleSheet(getAdjustedDialogStyleSheet());
389#endif
390
391 m_pRouteListCtrl->Connect(
392 wxEVT_COMMAND_LIST_ITEM_SELECTED,
393 wxListEventHandler(RouteManagerDialog::OnRteSelected), NULL, this);
394 m_pRouteListCtrl->Connect(
395 wxEVT_COMMAND_LIST_ITEM_DESELECTED,
396 wxListEventHandler(RouteManagerDialog::OnRteSelected), NULL, this);
397 m_pRouteListCtrl->Connect(
398 wxEVT_COMMAND_LIST_ITEM_ACTIVATED,
399 wxListEventHandler(RouteManagerDialog::OnRteDefaultAction), NULL, this);
400 m_pRouteListCtrl->Connect(
401 wxEVT_LEFT_DOWN,
402 wxMouseEventHandler(RouteManagerDialog::OnRteToggleVisibility), NULL,
403 this);
404 m_pRouteListCtrl->Connect(
405 wxEVT_COMMAND_LIST_COL_CLICK,
406 wxListEventHandler(RouteManagerDialog::OnRteColumnClicked), NULL, this);
407 bSizerRteContents->Add(m_pRouteListCtrl, 1, wxEXPAND | wxALL, DIALOG_MARGIN);
408 sbsRoutes->Add(bSizerRteContents, 1, wxEXPAND, 5);
409
410 // Columns: visibility ctrl, name
411 // note that under MSW for SetColumnWidth() to work we need to create the
412 // items with images initially even if we specify dummy image id
413 m_pRouteListCtrl->InsertColumn(rmVISIBLE, _("Show"), wxLIST_FORMAT_LEFT,
414 10 /*4 * char_width*/);
415 m_pRouteListCtrl->InsertColumn(rmROUTENAME, _("Route Name"),
416 wxLIST_FORMAT_LEFT, 15 * char_width);
417 m_pRouteListCtrl->InsertColumn(rmROUTEDESC, _("From <-> To"),
418 wxLIST_FORMAT_LEFT, 10 * char_width);
419
420 // Buttons: Delete, Properties...
421 wxBoxSizer *bsRouteButtons = new wxBoxSizer(wxVERTICAL);
422 sbsRoutes->Add(bsRouteButtons, 0, wxEXPAND);
423
424 wxScrolledWindow *winr = new wxScrolledWindow(
425 m_pPanelRte, wxID_ANY, wxDefaultPosition, wxDefaultSize,
426 wxNO_BORDER | wxTAB_TRAVERSAL | wxVSCROLL);
427 winr->SetScrollRate(0, 5);
428
429 bsRouteButtons->Add(winr, 1, wxALL | wxEXPAND, DIALOG_MARGIN);
430
431 wxBoxSizer *bsRouteButtonsInner = new wxBoxSizer(wxVERTICAL);
432 winr->SetSizer(bsRouteButtonsInner);
433
434 btnRteProperties = new wxButton(winr, -1, _("&Properties") + _T("..."));
435 bsRouteButtonsInner->Add(btnRteProperties, 0, wxALL | wxEXPAND,
436 DIALOG_MARGIN);
437 btnRteProperties->Connect(
438 wxEVT_COMMAND_BUTTON_CLICKED,
439 wxCommandEventHandler(RouteManagerDialog::OnRtePropertiesClick), NULL,
440 this);
441
442 btnRteActivate = new wxButton(winr, -1, _("&Activate"));
443 bsRouteButtonsInner->Add(btnRteActivate, 0, wxALL | wxEXPAND, DIALOG_MARGIN);
444 btnRteActivate->Connect(
445 wxEVT_COMMAND_BUTTON_CLICKED,
446 wxCommandEventHandler(RouteManagerDialog::OnRteActivateClick), NULL,
447 this);
448 btnRteActivate->Connect(
449 wxEVT_LEFT_DOWN,
450 wxMouseEventHandler(RouteManagerDialog::OnRteBtnLeftDown), NULL, this);
451
452 btnRteZoomto = new wxButton(winr, -1, _("&Center View"));
453 bsRouteButtonsInner->Add(btnRteZoomto, 0, wxALL | wxEXPAND, DIALOG_MARGIN);
454 btnRteZoomto->Connect(
455 wxEVT_COMMAND_BUTTON_CLICKED,
456 wxCommandEventHandler(RouteManagerDialog::OnRteZoomtoClick), NULL, this);
457 btnRteZoomto->Connect(
458 wxEVT_LEFT_DOWN,
459 wxMouseEventHandler(RouteManagerDialog::OnRteBtnLeftDown), NULL, this);
460
461 btnRteReverse = new wxButton(winr, -1, _("&Reverse"));
462 bsRouteButtonsInner->Add(btnRteReverse, 0, wxALL | wxEXPAND, DIALOG_MARGIN);
463 btnRteReverse->Connect(
464 wxEVT_COMMAND_BUTTON_CLICKED,
465 wxCommandEventHandler(RouteManagerDialog::OnRteReverseClick), NULL, this);
466
467 btnRteDelete = new wxButton(winr, -1, _("&Delete"));
468 bsRouteButtonsInner->Add(btnRteDelete, 0, wxALL | wxEXPAND, DIALOG_MARGIN);
469 btnRteDelete->Connect(
470 wxEVT_COMMAND_BUTTON_CLICKED,
471 wxCommandEventHandler(RouteManagerDialog::OnRteDeleteClick), NULL, this);
472
473 btnRteExport = new wxButton(winr, -1, _("&Export selected..."));
474 bsRouteButtonsInner->Add(btnRteExport, 0, wxALL | wxEXPAND, DIALOG_MARGIN);
475 btnRteExport->Connect(
476 wxEVT_COMMAND_BUTTON_CLICKED,
477 wxCommandEventHandler(RouteManagerDialog::OnRteExportClick), NULL, this);
478
479 btnRteResequence = new wxButton(winr, -1, _("&Resequence Waypoints"));
480 bsRouteButtonsInner->Add(btnRteResequence, 0, wxALL | wxEXPAND,
481 DIALOG_MARGIN);
482 btnRteResequence->Connect(
483 wxEVT_COMMAND_BUTTON_CLICKED,
484 wxCommandEventHandler(RouteManagerDialog::OnRteResequenceClick), NULL,
485 this);
486
487 btnRteSendToPeer = new wxButton(winr, -1, _("Send to &Peer"));
488 bsRouteButtonsInner->Add(btnRteSendToPeer, 0, wxALL | wxEXPAND,
489 DIALOG_MARGIN);
490 btnRteSendToPeer->Connect(
491 wxEVT_COMMAND_BUTTON_CLICKED,
492 wxCommandEventHandler(RouteManagerDialog::OnRteSendToPeerClick), NULL,
493 this);
494
495 btnRteSendToGPS = new wxButton(winr, -1, _("&Send to GPS"));
496 bsRouteButtonsInner->Add(btnRteSendToGPS, 0, wxALL | wxEXPAND, DIALOG_MARGIN);
497 btnRteSendToGPS->Connect(
498 wxEVT_COMMAND_BUTTON_CLICKED,
499 wxCommandEventHandler(RouteManagerDialog::OnRteSendToGPSClick), NULL,
500 this);
501
502 bsRouteButtonsInner->AddSpacer(10);
503
504 btnRteDeleteAll = new wxButton(winr, -1, _("&Delete All"));
505 bsRouteButtonsInner->Add(btnRteDeleteAll, 0, wxALL | wxEXPAND, DIALOG_MARGIN);
506 btnRteDeleteAll->Connect(
507 wxEVT_COMMAND_BUTTON_CLICKED,
508 wxCommandEventHandler(RouteManagerDialog::OnRteDeleteAllClick), NULL,
509 this);
510
511 // Create "Tracks" panel
512 m_pPanelTrk = new wxPanel(m_pNotebook, wxID_ANY, wxDefaultPosition,
513 wxDefaultSize, wxNO_BORDER | wxTAB_TRAVERSAL);
514 wxBoxSizer *sbsTracks = new wxBoxSizer(wxHORIZONTAL);
515 m_pPanelTrk->SetSizer(sbsTracks);
516 m_pNotebook->AddPage(m_pPanelTrk, _("Tracks"));
517
518 wxBoxSizer *bSizerTrkContents;
519 bSizerTrkContents = new wxBoxSizer(wxVERTICAL);
520
521 wxFlexGridSizer *fgSizerFilterTrk;
522 fgSizerFilterTrk = new wxFlexGridSizer(0, 2, 0, 0);
523 fgSizerFilterTrk->AddGrowableCol(1);
524 fgSizerFilterTrk->SetFlexibleDirection(wxBOTH);
525 fgSizerFilterTrk->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_SPECIFIED);
526
527 m_stFilterTrk = new wxStaticText(m_pPanelTrk, wxID_ANY, _("Filter"),
528 wxDefaultPosition, wxDefaultSize, 0);
529 m_stFilterTrk->Wrap(-1);
530 fgSizerFilterTrk->Add(m_stFilterTrk, 0, wxALL, 5);
531
532 m_tFilterTrk = new wxTextCtrl(m_pPanelTrk, wxID_ANY, wxEmptyString,
533 wxDefaultPosition, wxDefaultSize, 0);
534 fgSizerFilterTrk->Add(m_tFilterTrk, 1, wxALL | wxEXPAND, 5);
535
536 bSizerTrkContents->Add(fgSizerFilterTrk, 0, wxEXPAND, 5);
537 m_tFilterTrk->Connect(
538 wxEVT_COMMAND_TEXT_UPDATED,
539 wxCommandEventHandler(RouteManagerDialog::OnFilterChanged), NULL, this);
540
541 m_cbShowAllTrk = new wxCheckBox(m_pPanelTrk, wxID_ANY, _("Show all tracks"));
542 bSizerTrkContents->Add(m_cbShowAllTrk, 0, wxEXPAND | wxLEFT, 5);
543 m_cbShowAllTrk->Connect(
544 wxEVT_COMMAND_CHECKBOX_CLICKED,
545 wxCommandEventHandler(RouteManagerDialog::OnShowAllTrkCBClicked), NULL,
546 this);
547
548 m_pTrkListCtrl =
549 new wxListCtrl(m_pPanelTrk, -1, wxDefaultPosition, wxDefaultSize,
550 wxLC_REPORT | wxLC_SORT_ASCENDING | wxLC_HRULES |
551 wxBORDER_SUNKEN /*|wxLC_VRULES*/);
552
553#ifdef __OCPN__ANDROID__
554 m_pTrkListCtrl->GetHandle()->setStyleSheet(getAdjustedDialogStyleSheet());
555#endif
556
557 m_pTrkListCtrl->Connect(wxEVT_COMMAND_LIST_ITEM_SELECTED,
558 wxListEventHandler(RouteManagerDialog::OnTrkSelected),
559 NULL, this);
560 m_pTrkListCtrl->Connect(wxEVT_COMMAND_LIST_ITEM_DESELECTED,
561 wxListEventHandler(RouteManagerDialog::OnTrkSelected),
562 NULL, this);
563 m_pTrkListCtrl->Connect(
564 wxEVT_COMMAND_LIST_ITEM_ACTIVATED,
565 wxListEventHandler(RouteManagerDialog::OnTrkDefaultAction), NULL, this);
566 m_pTrkListCtrl->Connect(
567 wxEVT_LEFT_DOWN,
568 wxMouseEventHandler(RouteManagerDialog::OnTrkToggleVisibility), NULL,
569 this);
570 m_pTrkListCtrl->Connect(
571 wxEVT_COMMAND_LIST_COL_CLICK,
572 wxListEventHandler(RouteManagerDialog::OnTrkColumnClicked), NULL, this);
573 m_pTrkListCtrl->Connect(
574 wxEVT_COMMAND_LIST_ITEM_RIGHT_CLICK,
575 wxListEventHandler(RouteManagerDialog::OnTrkRightClick), NULL, this);
576 this->Connect(wxEVT_COMMAND_MENU_SELECTED,
577 wxCommandEventHandler(RouteManagerDialog::OnTrkMenuSelected),
578 NULL, this);
579
580 bSizerTrkContents->Add(m_pTrkListCtrl, 1, wxEXPAND | wxALL, DIALOG_MARGIN);
581 sbsTracks->Add(bSizerTrkContents, 1, wxEXPAND, 5);
582
583 m_pTrkListCtrl->InsertColumn(colTRKVISIBLE, _("Show"), wxLIST_FORMAT_LEFT,
584 4 * char_width);
585 m_pTrkListCtrl->InsertColumn(colTRKNAME, _("Track Name"), wxLIST_FORMAT_LEFT,
586 20 * char_width);
587 m_pTrkListCtrl->InsertColumn(colTRKLENGTH, _("Length"), wxLIST_FORMAT_LEFT,
588 5 * char_width);
589
590 wxBoxSizer *bsTrkButtons = new wxBoxSizer(wxVERTICAL);
591 sbsTracks->Add(bsTrkButtons, 0, wxEXPAND);
592
593 wxScrolledWindow *wint = new wxScrolledWindow(
594 m_pPanelTrk, wxID_ANY, wxDefaultPosition, wxDefaultSize,
595 wxNO_BORDER | wxTAB_TRAVERSAL | wxVSCROLL);
596 wint->SetScrollRate(0, 5);
597
598 bsTrkButtons->Add(wint, 1, wxALL | wxEXPAND, DIALOG_MARGIN);
599
600 wxBoxSizer *bsTrkButtonsInner = new wxBoxSizer(wxVERTICAL);
601 wint->SetSizer(bsTrkButtonsInner);
602
603 btnTrkNew = new wxButton(wint, -1, _("&Start Track"));
604 bsTrkButtonsInner->Add(btnTrkNew, 0, wxALL | wxEXPAND, DIALOG_MARGIN);
605 btnTrkNew->Connect(wxEVT_COMMAND_BUTTON_CLICKED,
606 wxCommandEventHandler(RouteManagerDialog::OnTrkNewClick),
607 NULL, this);
608
609 btnTrkProperties = new wxButton(wint, -1, _("&Properties"));
610 bsTrkButtonsInner->Add(btnTrkProperties, 0, wxALL | wxEXPAND, DIALOG_MARGIN);
611 btnTrkProperties->Connect(
612 wxEVT_COMMAND_BUTTON_CLICKED,
613 wxCommandEventHandler(RouteManagerDialog::OnTrkPropertiesClick), NULL,
614 this);
615
616 btnTrkDelete = new wxButton(wint, -1, _("&Delete"));
617 bsTrkButtonsInner->Add(btnTrkDelete, 0, wxALL | wxEXPAND, DIALOG_MARGIN);
618 btnTrkDelete->Connect(
619 wxEVT_COMMAND_BUTTON_CLICKED,
620 wxCommandEventHandler(RouteManagerDialog::OnTrkDeleteClick), NULL, this);
621
622 btnTrkExport = new wxButton(wint, -1, _("&Export selected..."));
623 bsTrkButtonsInner->Add(btnTrkExport, 0, wxALL | wxEXPAND, DIALOG_MARGIN);
624 btnTrkExport->Connect(
625 wxEVT_COMMAND_BUTTON_CLICKED,
626 wxCommandEventHandler(RouteManagerDialog::OnTrkExportClick), NULL, this);
627
628 btnTrkRouteFromTrack = new wxButton(wint, -1, _("Route from Track"));
629 bsTrkButtonsInner->Add(btnTrkRouteFromTrack, 0, wxALL | wxEXPAND,
630 DIALOG_MARGIN);
631 btnTrkRouteFromTrack->Connect(
632 wxEVT_COMMAND_BUTTON_CLICKED,
633 wxCommandEventHandler(RouteManagerDialog::OnTrkRouteFromTrackClick), NULL,
634 this);
635
636 btnTrkSendToPeer = new wxButton(wint, -1, _("Send to &Peer"));
637 bsTrkButtonsInner->Add(btnTrkSendToPeer, 0, wxALL | wxEXPAND,
638 DIALOG_MARGIN);
639 btnTrkSendToPeer->Connect(
640 wxEVT_COMMAND_BUTTON_CLICKED,
641 wxCommandEventHandler(RouteManagerDialog::OnTrkSendToPeerClick), NULL,
642 this);
643
644 bsTrkButtonsInner->AddSpacer(10);
645
646 btnTrkDeleteAll = new wxButton(wint, -1, _("&Delete All"));
647 bsTrkButtonsInner->Add(btnTrkDeleteAll, 0, wxALL | wxEXPAND, DIALOG_MARGIN);
648 btnTrkDeleteAll->Connect(
649 wxEVT_COMMAND_BUTTON_CLICKED,
650 wxCommandEventHandler(RouteManagerDialog::OnTrkDeleteAllClick), NULL,
651 this);
652
653 // Create "Waypoints" panel
654 m_pPanelWpt = new wxPanel(m_pNotebook, wxID_ANY, wxDefaultPosition,
655 wxDefaultSize, wxNO_BORDER | wxTAB_TRAVERSAL);
656 wxBoxSizer *sbsWpts = new wxBoxSizer(wxHORIZONTAL);
657 m_pPanelWpt->SetSizer(sbsWpts);
658 m_pNotebook->AddPage(m_pPanelWpt, _("Waypoints"));
659
660 wxBoxSizer *bSizerWptContents;
661 bSizerWptContents = new wxBoxSizer(wxVERTICAL);
662
663 wxFlexGridSizer *fgSizerFilterWpt;
664 fgSizerFilterWpt = new wxFlexGridSizer(0, 2, 0, 0);
665 fgSizerFilterWpt->AddGrowableCol(1);
666 fgSizerFilterWpt->SetFlexibleDirection(wxBOTH);
667 fgSizerFilterWpt->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_SPECIFIED);
668
669 m_stFilterWpt = new wxStaticText(m_pPanelWpt, wxID_ANY, _("Filter"),
670 wxDefaultPosition, wxDefaultSize, 0);
671 m_stFilterWpt->Wrap(-1);
672 fgSizerFilterWpt->Add(m_stFilterWpt, 0, wxALL, 5);
673
674 m_tFilterWpt = new wxTextCtrl(m_pPanelWpt, wxID_ANY, wxEmptyString,
675 wxDefaultPosition, wxDefaultSize, 0);
676 fgSizerFilterWpt->Add(m_tFilterWpt, 1, wxALL | wxEXPAND, 5);
677
678 bSizerWptContents->Add(fgSizerFilterWpt, 0, wxEXPAND, 5);
679 m_tFilterWpt->Connect(
680 wxEVT_COMMAND_TEXT_UPDATED,
681 wxCommandEventHandler(RouteManagerDialog::OnFilterChanged), NULL, this);
682
683 m_cbShowAllWP =
684 new wxCheckBox(m_pPanelWpt, wxID_ANY, _("Show all waypoints"));
685 bSizerWptContents->Add(m_cbShowAllWP, 0, wxEXPAND | wxLEFT, 5);
686 m_cbShowAllWP->Connect(
687 wxEVT_COMMAND_CHECKBOX_CLICKED,
688 wxCommandEventHandler(RouteManagerDialog::OnShowAllWpCBClicked), NULL,
689 this);
690
691 m_pWptListCtrl =
692 new wxListCtrl(m_pPanelWpt, -1, wxDefaultPosition, wxDefaultSize,
693 wxLC_REPORT | wxLC_SORT_ASCENDING | wxLC_HRULES |
694 wxBORDER_SUNKEN /*|wxLC_VRULES*/);
695#ifdef __OCPN__ANDROID__
696 m_pWptListCtrl->GetHandle()->setStyleSheet(getAdjustedDialogStyleSheet());
697#endif
698
699 m_pWptListCtrl->Connect(wxEVT_COMMAND_LIST_ITEM_SELECTED,
700 wxListEventHandler(RouteManagerDialog::OnWptSelected),
701 NULL, this);
702 m_pWptListCtrl->Connect(wxEVT_COMMAND_LIST_ITEM_DESELECTED,
703 wxListEventHandler(RouteManagerDialog::OnWptSelected),
704 NULL, this);
705 m_pWptListCtrl->Connect(
706 wxEVT_COMMAND_LIST_ITEM_ACTIVATED,
707 wxListEventHandler(RouteManagerDialog::OnWptDefaultAction), NULL, this);
708 m_pWptListCtrl->Connect(
709 wxEVT_LEFT_DOWN,
710 wxMouseEventHandler(RouteManagerDialog::OnWptToggleVisibility), NULL,
711 this);
712 m_pWptListCtrl->Connect(
713 wxEVT_COMMAND_LIST_COL_CLICK,
714 wxListEventHandler(RouteManagerDialog::OnWptColumnClicked), NULL, this);
715 bSizerWptContents->Add(m_pWptListCtrl, 1, wxEXPAND | wxALL, DIALOG_MARGIN);
716 sbsWpts->Add(bSizerWptContents, 1, wxEXPAND, 5);
717
718 m_pWptListCtrl->InsertColumn(colWPTICON, _("Icon"), wxLIST_FORMAT_LEFT,
719 4 * char_width);
720 m_pWptListCtrl->InsertColumn(colWPTSCALE, _("Scale"), wxLIST_FORMAT_LEFT,
721 8 * char_width);
722 m_pWptListCtrl->InsertColumn(colWPTNAME, _("Waypoint Name"),
723 wxLIST_FORMAT_LEFT, 15 * char_width);
724 m_pWptListCtrl->InsertColumn(colWPTDIST, _("Distance from own ship"),
725 wxLIST_FORMAT_LEFT, 14 * char_width);
726
727 wxBoxSizer *bsWptButtons = new wxBoxSizer(wxVERTICAL);
728 sbsWpts->Add(bsWptButtons, 0, wxEXPAND);
729
730 wxScrolledWindow *winw = new wxScrolledWindow(
731 m_pPanelWpt, wxID_ANY, wxDefaultPosition, wxDefaultSize,
732 wxNO_BORDER | wxTAB_TRAVERSAL | wxVSCROLL);
733 winw->SetScrollRate(0, 5);
734
735 bsWptButtons->Add(winw, 1, wxALL | wxEXPAND, DIALOG_MARGIN);
736
737 wxBoxSizer *bsWptButtonsInner = new wxBoxSizer(wxVERTICAL);
738 winw->SetSizer(bsWptButtonsInner);
739
740 btnWptNew = new wxButton(winw, -1, _("&New"));
741 bsWptButtonsInner->Add(btnWptNew, 0, wxALL | wxEXPAND, DIALOG_MARGIN);
742 btnWptNew->Connect(wxEVT_COMMAND_BUTTON_CLICKED,
743 wxCommandEventHandler(RouteManagerDialog::OnWptNewClick),
744 NULL, this);
745
746 btnWptProperties = new wxButton(winw, -1, _("&Properties"));
747 bsWptButtonsInner->Add(btnWptProperties, 0, wxALL | wxEXPAND, DIALOG_MARGIN);
748 btnWptProperties->Connect(
749 wxEVT_COMMAND_BUTTON_CLICKED,
750 wxCommandEventHandler(RouteManagerDialog::OnWptPropertiesClick), NULL,
751 this);
752
753 btnWptZoomto = new wxButton(winw, -1, _("&Center View"));
754 bsWptButtonsInner->Add(btnWptZoomto, 0, wxALL | wxEXPAND, DIALOG_MARGIN);
755 btnWptZoomto->Connect(
756 wxEVT_COMMAND_BUTTON_CLICKED,
757 wxCommandEventHandler(RouteManagerDialog::OnWptZoomtoClick), NULL, this);
758
759 btnWptDelete = new wxButton(winw, -1, _("&Delete"));
760 bsWptButtonsInner->Add(btnWptDelete, 0, wxALL | wxEXPAND, DIALOG_MARGIN);
761 btnWptDelete->Connect(
762 wxEVT_COMMAND_BUTTON_CLICKED,
763 wxCommandEventHandler(RouteManagerDialog::OnWptDeleteClick), NULL, this);
764
765 btnWptGoTo = new wxButton(winw, -1, _("&Go To"));
766 bsWptButtonsInner->Add(btnWptGoTo, 0, wxALL | wxEXPAND, DIALOG_MARGIN);
767 btnWptGoTo->Connect(wxEVT_COMMAND_BUTTON_CLICKED,
768 wxCommandEventHandler(RouteManagerDialog::OnWptGoToClick),
769 NULL, this);
770
771 btnWptExport = new wxButton(winw, -1, _("&Export selected..."));
772 bsWptButtonsInner->Add(btnWptExport, 0, wxALL | wxEXPAND, DIALOG_MARGIN);
773 btnWptExport->Connect(
774 wxEVT_COMMAND_BUTTON_CLICKED,
775 wxCommandEventHandler(RouteManagerDialog::OnWptExportClick), NULL, this);
776
777 btnWptSendToGPS = new wxButton(winw, -1, _("&Send to GPS"));
778 bsWptButtonsInner->Add(btnWptSendToGPS, 0, wxALL | wxEXPAND, DIALOG_MARGIN);
779 btnWptSendToGPS->Connect(
780 wxEVT_COMMAND_BUTTON_CLICKED,
781 wxCommandEventHandler(RouteManagerDialog::OnWptSendToGPSClick), NULL,
782 this);
783
784 btnWptSendToPeer = new wxButton(winw, -1, _("Send to &Peer"));
785 bsWptButtonsInner->Add(btnWptSendToPeer, 0, wxALL | wxEXPAND,
786 DIALOG_MARGIN);
787 btnWptSendToPeer->Connect(
788 wxEVT_COMMAND_BUTTON_CLICKED,
789 wxCommandEventHandler(RouteManagerDialog::OnWptSendToPeerClick), NULL,
790 this);
791
792 bsWptButtonsInner->AddSpacer(10);
793
794 btnWptDeleteAll = new wxButton(winw, -1, _("Delete All"));
795 bsWptButtonsInner->Add(btnWptDeleteAll, 0, wxALL | wxEXPAND, DIALOG_MARGIN);
796 btnWptDeleteAll->Connect(
797 wxEVT_COMMAND_BUTTON_CLICKED,
798 wxCommandEventHandler(RouteManagerDialog::OnWptDeleteAllClick), NULL,
799 this);
800
801 wxBoxSizer *itemBoxSizer5 = new wxBoxSizer(wxHORIZONTAL);
802 itemBoxSizer1->Add(itemBoxSizer5, 0, wxALL | wxEXPAND);
803
804 wxBoxSizer *itemBoxSizer6 = new wxBoxSizer(wxHORIZONTAL);
805 itemBoxSizer5->Add(itemBoxSizer6, 1, wxALL | wxEXPAND);
806
807 btnImport = new wxButton(this, -1, _("I&mport GPX..."));
808 itemBoxSizer6->Add(btnImport, 0, wxALL | wxALIGN_LEFT, DIALOG_MARGIN);
809 btnImport->Connect(wxEVT_COMMAND_BUTTON_CLICKED,
810 wxCommandEventHandler(RouteManagerDialog::OnImportClick),
811 NULL, this);
812 /*
813 * btnExport = new wxButton( this, -1, _("E&xport All...") );
814 * itemBoxSizer6->Add( btnExport, 0, wxALL | wxALIGN_LEFT, DIALOG_MARGIN );
815 * btnExport->Connect( wxEVT_COMMAND_BUTTON_CLICKED,
816 * wxCommandEventHandler(RouteManagerDialog::OnExportClick), NULL,
817 * this );
818 */
819 btnExportViz = new wxButton(this, -1, _("Export All Visible..."));
820 itemBoxSizer6->Add(btnExportViz, 0, wxALL | wxALIGN_LEFT, DIALOG_MARGIN);
821 btnExportViz->Connect(
822 wxEVT_COMMAND_BUTTON_CLICKED,
823 wxCommandEventHandler(RouteManagerDialog::OnExportVizClick), NULL, this);
824
825 // Dialog OK button
826 itemBoxSizer6->Add(0, 0, 1, wxEXPAND, 5); // Spacer
827 itemBoxSizer6->Add(new wxButton(this, wxID_OK), 0, wxALL, DIALOG_MARGIN);
828
829 // Create "Layers" panel
830 m_pPanelLay = new wxPanel(m_pNotebook, wxID_ANY, wxDefaultPosition,
831 wxDefaultSize, wxNO_BORDER | wxTAB_TRAVERSAL);
832 wxBoxSizer *sbsLayers = new wxBoxSizer(wxHORIZONTAL);
833 m_pPanelLay->SetSizer(sbsLayers);
834 m_pNotebook->AddPage(m_pPanelLay, _("Layers"));
835
836 wxBoxSizer *bSizerLayContents;
837 bSizerLayContents = new wxBoxSizer(wxVERTICAL);
838
839 wxFlexGridSizer *fgSizerFilterLay;
840 fgSizerFilterLay = new wxFlexGridSizer(0, 2, 0, 0);
841 fgSizerFilterLay->AddGrowableCol(1);
842 fgSizerFilterLay->SetFlexibleDirection(wxBOTH);
843 fgSizerFilterLay->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_SPECIFIED);
844
845 m_stFilterLay = new wxStaticText(m_pPanelLay, wxID_ANY, _("Filter"),
846 wxDefaultPosition, wxDefaultSize, 0);
847 m_stFilterLay->Wrap(-1);
848 fgSizerFilterLay->Add(m_stFilterLay, 0, wxALL, 5);
849
850 m_tFilterLay = new wxTextCtrl(m_pPanelLay, wxID_ANY, wxEmptyString,
851 wxDefaultPosition, wxDefaultSize, 0);
852 fgSizerFilterLay->Add(m_tFilterLay, 1, wxALL | wxEXPAND, 5);
853
854 bSizerLayContents->Add(fgSizerFilterLay, 0, wxEXPAND, 5);
855 m_tFilterLay->Connect(
856 wxEVT_COMMAND_TEXT_UPDATED,
857 wxCommandEventHandler(RouteManagerDialog::OnFilterChanged), NULL, this);
858
859 m_cbShowAllLay = new wxCheckBox(m_pPanelLay, wxID_ANY, _("Show all layers"));
860 bSizerLayContents->Add(m_cbShowAllLay, 0, wxEXPAND | wxLEFT, 5);
861 m_cbShowAllLay->Connect(
862 wxEVT_COMMAND_CHECKBOX_CLICKED,
863 wxCommandEventHandler(RouteManagerDialog::OnShowAllLayCBClicked), NULL,
864 this);
865
866 m_pLayListCtrl =
867 new wxListCtrl(m_pPanelLay, -1, wxDefaultPosition, wxDefaultSize,
868 wxLC_REPORT | wxLC_SINGLE_SEL | wxLC_SORT_ASCENDING |
869 wxLC_HRULES | wxBORDER_SUNKEN /*|wxLC_VRULES*/);
870#ifdef __OCPN__ANDROID__
871 m_pLayListCtrl->GetHandle()->setStyleSheet(getAdjustedDialogStyleSheet());
872#endif
873
874 m_pLayListCtrl->Connect(wxEVT_COMMAND_LIST_ITEM_SELECTED,
875 wxListEventHandler(RouteManagerDialog::OnLaySelected),
876 NULL, this);
877 m_pLayListCtrl->Connect(wxEVT_COMMAND_LIST_ITEM_DESELECTED,
878 wxListEventHandler(RouteManagerDialog::OnLaySelected),
879 NULL, this);
880 m_pLayListCtrl->Connect(
881 wxEVT_COMMAND_LIST_ITEM_ACTIVATED,
882 wxListEventHandler(RouteManagerDialog::OnLayDefaultAction), NULL, this);
883 m_pLayListCtrl->Connect(
884 wxEVT_LEFT_DOWN,
885 wxMouseEventHandler(RouteManagerDialog::OnLayToggleVisibility), NULL,
886 this);
887 m_pLayListCtrl->Connect(
888 wxEVT_COMMAND_LIST_COL_CLICK,
889 wxListEventHandler(RouteManagerDialog::OnLayColumnClicked), NULL, this);
890 bSizerLayContents->Add(m_pLayListCtrl, 1, wxEXPAND | wxALL, DIALOG_MARGIN);
891 sbsLayers->Add(bSizerLayContents, 1, wxEXPAND, 5);
892
893 m_pLayListCtrl->InsertColumn(colLAYVISIBLE, _T(""), wxLIST_FORMAT_LEFT,
894 4 * char_width);
895 m_pLayListCtrl->InsertColumn(colLAYNAME, _("Layer Name"), wxLIST_FORMAT_LEFT,
896 14 * char_width);
897 m_pLayListCtrl->InsertColumn(colLAYITEMS, _("No. of items"),
898 wxLIST_FORMAT_LEFT, 10 * char_width);
899 m_pLayListCtrl->InsertColumn(colLAYPERSIST, _("Layer type"),
900 wxLIST_FORMAT_LEFT, 10 * char_width);
901
902 wxBoxSizer *bsLayButtons = new wxBoxSizer(wxVERTICAL);
903 sbsLayers->Add(bsLayButtons, 0, wxEXPAND);
904
905 wxScrolledWindow *winl = new wxScrolledWindow(
906 m_pPanelLay, wxID_ANY, wxDefaultPosition, wxDefaultSize,
907 wxNO_BORDER | wxTAB_TRAVERSAL | wxVSCROLL);
908 winl->SetScrollRate(0, 5);
909
910 bsLayButtons->Add(winl, 1, wxALL | wxEXPAND, DIALOG_MARGIN);
911
912 wxBoxSizer *bsLayButtonsInner = new wxBoxSizer(wxVERTICAL);
913 winl->SetSizer(bsLayButtonsInner);
914
915 btnLayNew = new wxButton(winl, -1, _("Create Temporary layer"));
916 bsLayButtonsInner->Add(btnLayNew, 0, wxALL | wxEXPAND, DIALOG_MARGIN);
917 btnLayNew->Connect(wxEVT_COMMAND_BUTTON_CLICKED,
918 wxCommandEventHandler(RouteManagerDialog::OnLayNewClick),
919 NULL, this);
920
921 btnPerLayNew = new wxButton(winl, -1, _("Create Persistent layer"));
922 bsLayButtonsInner->Add(btnPerLayNew, 0, wxALL | wxEXPAND, DIALOG_MARGIN);
923 btnPerLayNew->Connect(
924 wxEVT_COMMAND_BUTTON_CLICKED,
925 wxCommandEventHandler(RouteManagerDialog::OnPerLayNewClick), NULL, this);
926
927 btnLayDelete = new wxButton(winl, -1, _("&Delete"));
928 bsLayButtonsInner->Add(btnLayDelete, 0, wxALL | wxEXPAND, DIALOG_MARGIN);
929 btnLayDelete->Connect(
930 wxEVT_COMMAND_BUTTON_CLICKED,
931 wxCommandEventHandler(RouteManagerDialog::OnLayDeleteClick), NULL, this);
932
933 cbLayToggleChart = new wxCheckBox(winl, -1, _("Show on chart"));
934 bsLayButtonsInner->Add(cbLayToggleChart, 0, wxALL | wxEXPAND, DIALOG_MARGIN);
935 cbLayToggleChart->Connect(
936 wxEVT_COMMAND_CHECKBOX_CLICKED,
937 wxCommandEventHandler(RouteManagerDialog::OnLayToggleChartClick), NULL,
938 this);
939
940 cbLayToggleNames =
941 new wxCheckBox(winl, -1, _("Show WPT names"), wxDefaultPosition,
942 wxDefaultSize, wxCHK_3STATE);
943
944 bsLayButtonsInner->Add(cbLayToggleNames, 0, wxALL | wxEXPAND, DIALOG_MARGIN);
945 cbLayToggleNames->Connect(
946 wxEVT_COMMAND_CHECKBOX_CLICKED,
947 wxCommandEventHandler(RouteManagerDialog::OnLayToggleNamesClick), NULL,
948 this);
949
950 cbLayToggleListing = new wxCheckBox(winl, -1, _("List contents"));
951 bsLayButtonsInner->Add(cbLayToggleListing, 0, wxALL | wxEXPAND,
952 DIALOG_MARGIN);
953 cbLayToggleListing->Connect(
954 wxEVT_COMMAND_CHECKBOX_CLICKED,
955 wxCommandEventHandler(RouteManagerDialog::OnLayToggleListingClick), NULL,
956 this);
957
958 RecalculateSize();
959
960 int imageRefSize = m_charWidth * 2; // g_Platform->GetDisplayDPmm() * 4;
961 wxImageList *imglist = new wxImageList(imageRefSize, imageRefSize, true, 1);
962
963 // Load eye icons
964 wxString UserIconPath = g_Platform->GetSharedDataDir() + _T("uidata") +
965 wxFileName::GetPathSeparator();
966 wxImage iconSVG =
967 LoadSVG(UserIconPath + _T("eye.svg"), imageRefSize, imageRefSize)
968 .ConvertToImage();
969 if (iconSVG.IsOk()) {
970 iconSVG.Resize(wxSize(imageRefSize, imageRefSize),
971 wxPoint(0, 0)); // Avoid wxImageList size asserts
972 imglist->Add(wxBitmap(iconSVG));
973 }
974
975 iconSVG = LoadSVG(UserIconPath + _T("eyex.svg"), imageRefSize, imageRefSize)
976 .ConvertToImage();
977 if (iconSVG.IsOk()) {
978 iconSVG.Resize(wxSize(imageRefSize, imageRefSize), wxPoint(0, 0));
979 imglist->Add(wxBitmap(iconSVG));
980 }
981
982 iconSVG =
983 LoadSVG(UserIconPath + _T("eyeGray.svg"), imageRefSize, imageRefSize)
984 .ConvertToImage();
985 if (iconSVG.IsOk()) {
986 iconSVG.Resize(wxSize(imageRefSize, imageRefSize), wxPoint(0, 0));
987 imglist->Add(wxBitmap(iconSVG));
988 }
989
990 m_pRouteListCtrl->AssignImageList(imglist, wxIMAGE_LIST_SMALL);
991
992#ifdef __OCPN__ANDROID__
993 m_pRouteListCtrl->GetHandle()->setIconSize(QSize(imageRefSize, imageRefSize));
994#endif
995
996 // Assign will handle destroy, Set will not. It's OK, that's what we want
997 m_pTrkListCtrl->SetImageList(imglist, wxIMAGE_LIST_SMALL);
998 m_pWptListCtrl->SetImageList(
999 pWayPointMan->Getpmarkicon_image_list(m_listIconSize),
1000 wxIMAGE_LIST_SMALL);
1001 m_pLayListCtrl->SetImageList(imglist, wxIMAGE_LIST_SMALL);
1002
1003 SetColorScheme();
1004
1005 UpdateLists();
1006
1007 // This should work under Linux :-(
1008 // m_pNotebook->Connect(wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED,
1009 // wxNotebookEventHandler(RouteManagerDialog::OnTabSwitch), NULL, this);
1010
1011 m_bNeedConfigFlush = false;
1012}
1013
1014RouteManagerDialog::~RouteManagerDialog() {
1015 delete m_pRouteListCtrl;
1016 delete m_pTrkListCtrl;
1017 delete m_pWptListCtrl;
1018 delete m_pLayListCtrl;
1019
1020 delete btnRteDelete;
1021 delete btnRteResequence;
1022 delete btnRteExport;
1023 delete btnRteZoomto;
1024 delete btnRteProperties;
1025 delete btnRteActivate;
1026 delete btnRteReverse;
1027 delete btnRteSendToGPS;
1028 delete btnRteDeleteAll;
1029 delete btnTrkNew;
1030 delete btnTrkProperties;
1031 delete btnTrkDelete;
1032 delete btnTrkExport;
1033 delete btnTrkRouteFromTrack;
1034 delete btnTrkDeleteAll;
1035 delete btnWptNew;
1036 delete btnWptProperties;
1037 delete btnWptZoomto;
1038 delete btnWptDelete;
1039 delete btnWptGoTo;
1040 delete btnWptExport;
1041 delete btnWptSendToGPS;
1042 delete btnWptDeleteAll;
1043 delete btnLayNew;
1044 // delete btnLayProperties;
1045 delete cbLayToggleChart;
1046 delete cbLayToggleListing;
1047 delete cbLayToggleNames;
1048 delete btnLayDelete;
1049 delete btnImport;
1050 delete btnExport;
1051 delete btnExportViz;
1052 btnImport = NULL;
1053 btnExport = NULL;
1054 btnExportViz = NULL;
1055
1056 delete m_pNotebook;
1057 instanceFlag = false;
1058}
1059
1060void RouteManagerDialog::RecalculateSize() {
1061 // All of this dialog layout is expandable, so we need to set a specific size
1062 // target for the onscreen display. The size will then be adjusted so that it
1063 // fits within the parent's client area, with some padding
1064
1065 // Get a text height metric for reference
1066 int char_width, char_height;
1067 GetTextExtent(_T("W"), &char_width, &char_height);
1068
1069 wxSize sz;
1070 sz.x = 60 * char_width;
1071 sz.y = 30 * char_height;
1072
1073 wxSize dsize = GetParent()->GetClientSize();
1074 sz.y = wxMin(sz.y, dsize.y - (0 * char_height));
1075 sz.x = wxMin(sz.x, dsize.x - (0 * char_height));
1076 SetClientSize(sz);
1077
1078 wxSize fsize = GetSize();
1079 fsize.y = wxMin(fsize.y, dsize.y - (0 * char_height));
1080 fsize.x = wxMin(fsize.x, dsize.x - (0 * char_height));
1081 SetSize(fsize);
1082
1083 CentreOnParent();
1084}
1085
1086void RouteManagerDialog::OnClose(wxCloseEvent &event) {
1087#ifdef __WXGTK__
1088 gFrame->Raise();
1089#endif
1090 Hide();
1091 // pRouteManagerDialog = NULL;
1092}
1093
1094void RouteManagerDialog::OnOK(wxCommandEvent &event) {
1095#ifdef __WXGTK__
1096 gFrame->Raise();
1097#endif
1098 Hide();
1099}
1100
1101void RouteManagerDialog::SetColorScheme() { DimeControl(this); }
1102
1103void RouteManagerDialog::OnShowAllRteCBClicked(wxCommandEvent &event) {
1104 bool viz = m_cbShowAllRte->GetValue();
1105 long item = -1;
1106 for (;;) {
1107 item = m_pRouteListCtrl->GetNextItem(item, wxLIST_NEXT_ALL,
1108 wxLIST_STATE_DONTCARE);
1109 if (item == -1) break;
1110
1111 Route *pR = (Route *)m_pRouteListCtrl->GetItemData(item);
1112
1113 pR->SetVisible(viz, viz);
1114 pR->SetSharedWPViz(viz);
1115
1116 m_pRouteListCtrl->SetItemImage(item, !viz); // visible
1117
1118 pConfig->UpdateRoute(pR);
1119 }
1120
1121 UpdateWptListCtrlViz();
1122
1123 gFrame->RefreshAllCanvas();
1124}
1125
1126void RouteManagerDialog::OnShowAllWpCBClicked(wxCommandEvent &event) {
1127 bool viz = m_cbShowAllWP->GetValue();
1128 long item = -1;
1129 for (;;) {
1130 item = m_pWptListCtrl->GetNextItem(item, wxLIST_NEXT_ALL,
1131 wxLIST_STATE_DONTCARE);
1132 if (item == -1) break;
1133
1134 RoutePoint *pRP = (RoutePoint *)m_pWptListCtrl->GetItemData(item);
1135
1136 if (!pRP->IsSharedInVisibleRoute()) {
1137 pRP->SetVisible(viz);
1138 } else
1139 pRP->SetVisible(true);
1140
1141 m_pWptListCtrl->SetItemImage(item, RoutePointGui(*pRP).GetIconImageIndex());
1142 pConfig->UpdateWayPoint(pRP);
1143 }
1144
1145 gFrame->RefreshAllCanvas();
1146}
1147
1148void RouteManagerDialog::OnShowAllTrkCBClicked(wxCommandEvent &event) {
1149 bool viz = m_cbShowAllTrk->GetValue();
1150 long item = -1;
1151 for (;;) {
1152 item = m_pTrkListCtrl->GetNextItem(item, wxLIST_NEXT_ALL,
1153 wxLIST_STATE_DONTCARE);
1154 if (item == -1) break;
1155
1156 Track *track = (Track *)m_pTrkListCtrl->GetItemData(item);
1157
1158 track->SetVisible(viz);
1159 m_pTrkListCtrl->SetItemImage(item, track->IsVisible() ? 0 : 1);
1160 }
1161
1162 gFrame->RefreshAllCanvas();
1163}
1164
1165void RouteManagerDialog::OnShowAllLayCBClicked(wxCommandEvent &event) {
1166 bool viz = m_cbShowAllLay->GetValue();
1167 long item = -1;
1168 for (;;) {
1169 item = m_pLayListCtrl->GetNextItem(item, wxLIST_NEXT_ALL,
1170 wxLIST_STATE_DONTCARE);
1171 if (item == -1) break;
1172
1173 Layer *layer = (Layer *)m_pLayListCtrl->GetItemData(item);
1174
1175 layer->SetVisibleOnChart(viz);
1176 m_pLayListCtrl->SetItemImage(item, layer->IsVisibleOnChart() ? 0 : 1);
1177
1178 ToggleLayerContentsOnChart(layer);
1179 }
1180
1181 gFrame->RefreshAllCanvas();
1182}
1183
1184void RouteManagerDialog::UpdateRouteListCtrl() {
1185 // if an item was selected, make it selected again if it still exist
1186 long item = -1;
1187 item = m_pRouteListCtrl->GetNextItem(item, wxLIST_NEXT_ALL,
1188 wxLIST_STATE_SELECTED);
1189 wxUIntPtr selected_id = wxUIntPtr(0);
1190 if (item != -1) selected_id = m_pRouteListCtrl->GetItemData(item);
1191
1192 // Delete existing items
1193 m_pRouteListCtrl->DeleteAllItems();
1194
1195 // then add routes to the listctrl
1196 RouteList::iterator it;
1197 int index = 0;
1198 int list_index = 0;
1199 bool bpartialViz = false;
1200
1201 for (it = (*pRouteList).begin(); it != (*pRouteList).end(); ++it, ++index) {
1202 if (!(*it)->IsListed()) continue;
1203
1204 if (!(*it)->GetName().Upper().Contains(m_tFilterRte->GetValue().Upper())) {
1205 continue;
1206 }
1207
1208 wxListItem li;
1209 li.SetId(list_index);
1210 li.SetImage((*it)->IsVisible() ? 0 : 1);
1211 li.SetData(*it);
1212 li.SetText(_T(""));
1213 li.SetAlign(wxLIST_FORMAT_LEFT);
1214
1215 if ((*it)->m_bRtIsActive) {
1216 wxFont font = *wxNORMAL_FONT;
1217 font.SetWeight(wxFONTWEIGHT_BOLD);
1218 li.SetFont(font);
1219 }
1220
1221 long idx = m_pRouteListCtrl->InsertItem(li);
1222
1223 wxString name = (*it)->m_RouteNameString;
1224 if (name.IsEmpty()) name = _("(Unnamed Route)");
1225 m_pRouteListCtrl->SetItem(idx, rmROUTENAME, name);
1226
1227 wxString startend = (*it)->m_RouteStartString;
1228 if (!(*it)->m_RouteEndString.IsEmpty())
1229 startend.append(_(" - ") + (*it)->m_RouteEndString);
1230 m_pRouteListCtrl->SetItem(idx, rmROUTEDESC, startend);
1231
1232 wxListItem lic;
1233 lic.SetId(list_index);
1234 lic.SetColumn(1);
1235 lic.SetAlign(wxLIST_FORMAT_LEFT);
1236 m_pRouteListCtrl->SetItem(lic);
1237
1238 lic.SetColumn(2);
1239 lic.SetAlign(wxLIST_FORMAT_LEFT);
1240 m_pRouteListCtrl->SetItem(lic);
1241
1242 // Keep track if any are invisible
1243 if (!(*it)->IsVisible()) bpartialViz = true;
1244
1245 list_index++;
1246 }
1247
1248 m_pRouteListCtrl->SortItems(SortRoutesOnName, (wxIntPtr)NULL);
1249
1250 m_pRouteListCtrl->SetColumnWidth(0, 4 * m_charWidth);
1251
1252 // restore selection if possible
1253 // NOTE this will select a different item, if one is deleted
1254 // (the next route will get that index).
1255 if (selected_id != wxUIntPtr(0)) {
1256 item = m_pRouteListCtrl->FindItem(-1, selected_id);
1257 m_pRouteListCtrl->SetItemState(
1258 item, wxLIST_STATE_SELECTED | wxLIST_STATE_FOCUSED,
1259 wxLIST_STATE_SELECTED | wxLIST_STATE_FOCUSED);
1260 }
1261
1262 if ((m_lastRteItem >= 0) && (m_pRouteListCtrl->GetItemCount()))
1263 m_pRouteListCtrl->EnsureVisible(m_lastRteItem);
1264 UpdateRteButtons();
1265
1266 // If any route is invisible, then "show all" cb must be clear.
1267 m_cbShowAllRte->SetValue(!bpartialViz);
1268}
1269
1270void RouteManagerDialog::UpdateRteButtons() {
1271 // enable/disable buttons
1272 long selected_index_index =
1273 m_pRouteListCtrl->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
1274 bool enable1 = m_pRouteListCtrl->GetSelectedItemCount() == 1;
1275 bool enablemultiple = m_pRouteListCtrl->GetSelectedItemCount() >= 1;
1276
1277 m_lastRteItem = selected_index_index;
1278
1279 btnRteDelete->Enable(m_pRouteListCtrl->GetSelectedItemCount() > 0);
1280 btnRteZoomto->Enable(enable1);
1281 btnRteProperties->Enable(enable1);
1282 btnRteReverse->Enable(enable1);
1283 btnRteExport->Enable(enablemultiple);
1284 btnRteResequence->Enable(enable1);
1285 btnRteSendToGPS->Enable(enable1);
1286 btnRteDeleteAll->Enable(m_pRouteListCtrl->GetItemCount() > 0);
1287 btnRteSendToPeer->Enable(enablemultiple);
1288
1289 // set activate button text
1290 Route *route = NULL;
1291 if (enable1)
1292 route = (Route *)m_pRouteListCtrl->GetItemData(selected_index_index);
1293
1294 if (!g_pRouteMan->IsAnyRouteActive()) {
1295 btnRteActivate->Enable(enable1);
1296 if (enable1) btnRteActivate->SetLabel(_("Activate"));
1297
1298 } else {
1299 if (enable1) {
1300 if (route && route->m_bRtIsActive) {
1301 btnRteActivate->Enable(enable1);
1302 btnRteActivate->SetLabel(_("Deactivate"));
1303 } else
1304 btnRteActivate->Enable(false);
1305 } else
1306 btnRteActivate->Enable(false);
1307 }
1308}
1309
1310void RouteManagerDialog::MakeAllRoutesInvisible() {
1311 RouteList::iterator it;
1312 long index = 0;
1313 for (it = (*pRouteList).begin(); it != (*pRouteList).end(); ++it, ++index) {
1314 if ((*it)->IsVisible()) { // avoid config updating as much as possible!
1315 (*it)->SetVisible(false);
1316 m_pRouteListCtrl->SetItemImage(m_pRouteListCtrl->FindItem(-1, index),
1317 1); // Likely not same order :0
1318 pConfig->UpdateRoute(*it); // auch, flushes config to disk. FIXME
1319 }
1320 }
1321}
1322
1323void RouteManagerDialog::ZoomtoRoute(Route *route) {
1324 // Calculate bbox center
1325 LLBBox RBBox = route->GetBBox();
1326 double clat = (RBBox.GetMinLat() + RBBox.GetMaxLat()) / 2;
1327 double clon = (RBBox.GetMinLon() + RBBox.GetMaxLon()) / 2;
1328
1329 // Calculate ppm
1330 double rw, rh, ppm; // route width, height, final ppm scale to use
1331 int ww, wh; // chart window width, height
1332 // route bbox width in nm
1333 DistanceBearingMercator(RBBox.GetMinLat(), RBBox.GetMinLon(),
1334 RBBox.GetMinLat(), RBBox.GetMaxLon(), NULL, &rw);
1335 // route bbox height in nm
1336 DistanceBearingMercator(RBBox.GetMinLat(), RBBox.GetMinLon(),
1337 RBBox.GetMaxLat(), RBBox.GetMinLon(), NULL, &rh);
1338
1339 gFrame->GetPrimaryCanvas()->GetSize(&ww, &wh);
1340
1341 ppm = wxMin(ww / (rw * 1852), wh / (rh * 1852)) * (100 - fabs(clat)) / 90;
1342
1343 ppm = wxMin(ppm, 1.0);
1344
1345 gFrame->JumpToPosition(gFrame->GetPrimaryCanvas(), clat, clon, ppm);
1346
1347 m_bNeedConfigFlush = true;
1348}
1349
1350// BEGIN Event handlers
1351void RouteManagerDialog::OnRteDeleteClick(wxCommandEvent &event) {
1352 RouteList list;
1353
1354 int answer = OCPNMessageBox(
1355 this, _("Are you sure you want to delete the selected object(s)"),
1356 wxString(_("OpenCPN Alert")), wxYES_NO);
1357 if (answer != wxID_YES) return;
1358
1359 bool busy = false;
1360 if (m_pRouteListCtrl->GetSelectedItemCount()) {
1361 ::wxBeginBusyCursor();
1362 gFrame->CancelAllMouseRoute();
1363 m_bNeedConfigFlush = true;
1364 busy = true;
1365 }
1366
1367 long item = -1;
1368 for (;;) {
1369 item = m_pRouteListCtrl->GetNextItem(item, wxLIST_NEXT_ALL,
1370 wxLIST_STATE_SELECTED);
1371 if (item == -1) break;
1372
1373 Route *proute_to_delete = (Route *)m_pRouteListCtrl->GetItemData(item);
1374
1375 if (proute_to_delete) list.Append(proute_to_delete);
1376 }
1377
1378 if (busy) {
1379 for (unsigned int i = 0; i < list.GetCount(); i++) {
1380 Route *route = list.Item(i)->GetData();
1381 if (route) {
1382 pConfig->DeleteConfigRoute(route);
1383 g_pRouteMan->DeleteRoute(route, NavObjectChanges::getInstance());
1384 }
1385 }
1386
1387 m_lastRteItem = -1;
1388 UpdateRouteListCtrl();
1389 UpdateTrkListCtrl();
1390
1391 gFrame->InvalidateAllCanvasUndo();
1392 gFrame->RefreshAllCanvas();
1393 ::wxEndBusyCursor();
1394 }
1395}
1396
1397void RouteManagerDialog::OnRteDeleteAllClick(wxCommandEvent &event) {
1398 int dialog_ret =
1399 OCPNMessageBox(this, _("Are you sure you want to delete <ALL> routes?"),
1400 wxString(_("OpenCPN Alert")), wxYES_NO);
1401
1402 if (dialog_ret == wxID_YES) {
1403 if (g_pRouteMan->GetpActiveRoute()) g_pRouteMan->DeactivateRoute();
1404
1405 gFrame->CancelAllMouseRoute();
1406
1407 g_pRouteMan->DeleteAllRoutes(NavObjectChanges::getInstance());
1408 // TODO Seth
1409 // m_pSelectedRoute = NULL;
1410 // m_pFoundRoutePoint = NULL;
1411 // m_pFoundRoutePointSecond = NULL;
1412
1413 m_lastRteItem = -1;
1414 UpdateRouteListCtrl();
1415
1416 // Also need to update the track list control, since routes and tracks
1417 // share a common global list (pRouteList)
1418 UpdateTrkListCtrl();
1419
1420 if (pRoutePropDialog) pRoutePropDialog->Hide();
1421 gFrame->InvalidateAllCanvasUndo();
1422 gFrame->RefreshAllCanvas();
1423
1424 m_bNeedConfigFlush = true;
1425 }
1426}
1427
1428void RouteManagerDialog::OnRtePropertiesClick(wxCommandEvent &event) {
1429 // Show routeproperties dialog for selected route
1430 long item = -1;
1431 item = m_pRouteListCtrl->GetNextItem(item, wxLIST_NEXT_ALL,
1432 wxLIST_STATE_SELECTED);
1433 if (item == -1) return;
1434
1435 Route *route = (Route *)m_pRouteListCtrl->GetItemData(item);
1436
1437 if (!route) return;
1438
1439 pRoutePropDialog = RoutePropDlgImpl::getInstance(GetParent());
1440
1441 pRoutePropDialog->SetRouteAndUpdate(route);
1442
1443 if (!pRoutePropDialog->IsShown()) pRoutePropDialog->Show();
1444
1445 m_bNeedConfigFlush = true;
1446}
1447
1448void RouteManagerDialog::OnRteZoomtoClick(wxCommandEvent &event) {
1449 // Zoom into the bounding box of the selected route
1450 long item = -1;
1451 item = m_pRouteListCtrl->GetNextItem(item, wxLIST_NEXT_ALL,
1452 wxLIST_STATE_SELECTED);
1453 if (item == -1) return;
1454
1455 // optionally make this route exclusively visible
1456 if (m_bCtrlDown) MakeAllRoutesInvisible();
1457
1458 Route *route = (Route *)m_pRouteListCtrl->GetItemData(item);
1459
1460 if (!route) return;
1461
1462 // Ensure route is visible
1463 if (!route->IsVisible()) {
1464 route->SetVisible(true);
1465 m_pRouteListCtrl->SetItemImage(item, route->IsVisible() ? 0 : 1);
1466 pConfig->UpdateRoute(route);
1467 }
1468
1469 ZoomtoRoute(route);
1470}
1471
1472void RouteManagerDialog::OnRteReverseClick(wxCommandEvent &event) {
1473 // Reverse selected route
1474 long item = -1;
1475 item = m_pRouteListCtrl->GetNextItem(item, wxLIST_NEXT_ALL,
1476 wxLIST_STATE_SELECTED);
1477 if (item == -1) return;
1478
1479 Route *route = (Route *)m_pRouteListCtrl->GetItemData(item);
1480
1481 if (!route) return;
1482 if (route->m_bIsInLayer) return;
1483
1484 int ask_return = OCPNMessageBox(this, g_pRouteMan->GetRouteReverseMessage(),
1485 _("Rename Waypoints?"), wxYES_NO | wxCANCEL);
1486 if (ask_return != wxID_CANCEL) {
1487 bool rename = (ask_return == wxID_YES);
1488
1489 pSelect->DeleteAllSelectableRouteSegments(route);
1490 route->Reverse(rename);
1491 pSelect->AddAllSelectableRouteSegments(route);
1492
1493 // update column 2 - create a UpdateRouteItem(index) instead?
1494 wxString startend = route->m_RouteStartString;
1495 if (!route->m_RouteEndString.IsEmpty())
1496 startend.append(_(" - ") + route->m_RouteEndString);
1497 m_pRouteListCtrl->SetItem(item, 2, startend);
1498
1499 pConfig->UpdateRoute(route);
1500 gFrame->RefreshAllCanvas();
1501 }
1502
1503 m_bNeedConfigFlush = true;
1504}
1505
1506void RouteManagerDialog::OnRteExportClick(wxCommandEvent &event) {
1507 RouteList list;
1508
1509 wxString suggested_name = _T("routes");
1510
1511 long item = -1;
1512 for (;;) {
1513 item = m_pRouteListCtrl->GetNextItem(item, wxLIST_NEXT_ALL,
1514 wxLIST_STATE_SELECTED);
1515 if (item == -1) break;
1516
1517 Route *proute_to_export = (Route *)m_pRouteListCtrl->GetItemData(item);
1518
1519 if (proute_to_export) {
1520 list.Append(proute_to_export);
1521 if (proute_to_export->m_RouteNameString != wxEmptyString)
1522 suggested_name = proute_to_export->m_RouteNameString;
1523 }
1524 }
1525
1526 ExportGPXRoutes(this, &list, suggested_name);
1527}
1528
1529void RouteManagerDialog::OnRteResequenceClick(wxCommandEvent &event) {
1530 long item = -1;
1531 item = m_pRouteListCtrl->GetNextItem(item, wxLIST_NEXT_ALL,
1532 wxLIST_STATE_SELECTED);
1533 if (item == -1) return;
1534
1535 Route *route = (Route *)m_pRouteListCtrl->GetItemData(item);
1536
1537 if (!route) return;
1538 if (route->m_bIsInLayer) return;
1539 route->RenameRoutePoints();
1540}
1541
1542void RouteManagerDialog::OnRteSendToPeerClick(wxCommandEvent &event) {
1543 std::vector<Route*> list;
1544 long item = -1;
1545 for (;;) {
1546 item = m_pRouteListCtrl->GetNextItem(item, wxLIST_NEXT_ALL,
1547 wxLIST_STATE_SELECTED);
1548 if (item == -1) break;
1549
1550 Route *proute = (Route *)m_pRouteListCtrl->GetItemData(item);
1551
1552 if (proute) {
1553 list.push_back(proute);
1554 }
1555 }
1556 if (!list.empty()) {
1557 g_Platform->ShowBusySpinner();
1558 FindAllOCPNServers(2);
1559 g_Platform->HideBusySpinner();
1560
1561 // Count viable servers.
1562 int n_servers = 0;
1563 for (unsigned int i=0; i < g_DNS_cache.size(); i++){
1564 wxString item(g_DNS_cache[i]->hostname.c_str());
1565
1566 //skip "self"
1567 if (!g_hostname.IsSameAs(item.BeforeFirst('.'))) {
1568 n_servers++;
1569 }
1570 }
1571
1572 if(n_servers == 0){
1573 OCPNMessageBox(NULL,
1574 _("No OpenCPN servers found on this network."),
1575 _("OpenCPN Send Route(s)"), wxOK, 5);
1576
1577 return;
1578 }
1579
1580 SendToPeerDlg dlg;
1581 for (auto r : list) {
1582 dlg.SetRoute(r);
1583 }
1584
1585 dlg.Create(NULL, -1, _("Send Route(s) to OpenCPN Peer") + _T( "..." ), _T(""));
1586 dlg.ShowModal();
1587 }
1588}
1589
1590void RouteManagerDialog::OnWptSendToPeerClick(wxCommandEvent &event) {
1591 std::vector<RoutePoint*> list;
1592 long item = -1;
1593 for (;;) {
1594 item = m_pWptListCtrl->GetNextItem(item, wxLIST_NEXT_ALL,
1595 wxLIST_STATE_SELECTED);
1596 if (item == -1) break;
1597
1598 RoutePoint *proutep = (RoutePoint *)m_pWptListCtrl->GetItemData(item);
1599
1600 if (proutep) {
1601 list.push_back(proutep);
1602 }
1603 }
1604 if (!list.empty()) {
1605 g_Platform->ShowBusySpinner();
1606 FindAllOCPNServers(2);
1607 g_Platform->HideBusySpinner();
1608
1609 // Count viable servers.
1610 int n_servers = 0;
1611 for (unsigned int i=0; i < g_DNS_cache.size(); i++){
1612 wxString item(g_DNS_cache[i]->hostname.c_str());
1613
1614 //skip "self"
1615 if (!g_hostname.IsSameAs(item.BeforeFirst('.'))) {
1616 n_servers++;
1617 }
1618 }
1619
1620 if(n_servers == 0){
1621 OCPNMessageBox(NULL,
1622 _("No OpenCPN servers found on this network."),
1623 _("OpenCPN Send Waypoint(s)"), wxOK, 5);
1624
1625 return;
1626 }
1627
1628 SendToPeerDlg dlg;
1629 for (auto r : list) {
1630 dlg.SetWaypoint(r);
1631 }
1632
1633 dlg.Create(NULL, -1, _("Send Waypoint(s) to OpenCPN Peer") + _T( "..." ), _T(""));
1634 dlg.ShowModal();
1635 }
1636}
1637
1638void RouteManagerDialog::OnTrkSendToPeerClick(wxCommandEvent &event) {
1639 std::vector<Track*> list;
1640 long item = -1;
1641 for (;;) {
1642 item = m_pTrkListCtrl->GetNextItem(item, wxLIST_NEXT_ALL,
1643 wxLIST_STATE_SELECTED);
1644 if (item == -1) break;
1645
1646 Track *ptrk = (Track *)m_pTrkListCtrl->GetItemData(item);
1647
1648 if (ptrk) {
1649 list.push_back(ptrk);
1650 }
1651 }
1652 if (!list.empty()) {
1653 g_Platform->ShowBusySpinner();
1654 FindAllOCPNServers(2);
1655 g_Platform->HideBusySpinner();
1656
1657 // Count viable servers.
1658 int n_servers = 0;
1659 for (unsigned int i=0; i < g_DNS_cache.size(); i++){
1660 wxString item(g_DNS_cache[i]->hostname.c_str());
1661
1662 //skip "self"
1663 if (!g_hostname.IsSameAs(item.BeforeFirst('.'))) {
1664 n_servers++;
1665 }
1666 }
1667
1668 if(n_servers == 0){
1669 OCPNMessageBox(NULL,
1670 _("No OpenCPN servers found on this network."),
1671 _("OpenCPN Send Track(s)"), wxOK, 5);
1672
1673 return;
1674 }
1675
1676 SendToPeerDlg dlg;
1677 for (auto r : list) {
1678 dlg.SetTrack(r);
1679 }
1680
1681 dlg.Create(NULL, -1, _("Send Track(s) to OpenCPN Peer") + _T( "..." ), _T(""));
1682 dlg.ShowModal();
1683 }
1684}
1685
1686void RouteManagerDialog::OnRteActivateClick(wxCommandEvent &event) {
1687 // Activate the selected route, unless it already is
1688 long item = -1;
1689 item = m_pRouteListCtrl->GetNextItem(item, wxLIST_NEXT_ALL,
1690 wxLIST_STATE_SELECTED);
1691 if (item == -1) return;
1692
1693 if (m_bCtrlDown) MakeAllRoutesInvisible();
1694
1695 Route *route = (Route *)m_pRouteListCtrl->GetItemData(item);
1696
1697 if (!route) return;
1698
1699 if (!route->m_bRtIsActive) {
1700 if (!route->IsVisible()) {
1701 route->SetVisible(true);
1702 m_pRouteListCtrl->SetItemImage(item, 0, 0);
1703 }
1704
1705 ZoomtoRoute(route);
1706
1707 RoutePoint *best_point =
1708 g_pRouteMan->FindBestActivatePoint(route, gLat, gLon, gCog, gSog);
1709 g_pRouteMan->ActivateRoute(route, best_point);
1710 // g_pRouteMan->ActivateRoute(route);
1711 } else
1712 g_pRouteMan->DeactivateRoute();
1713
1714 UpdateRouteListCtrl();
1715
1716 pConfig->UpdateRoute(route);
1717
1718 gFrame->RefreshAllCanvas();
1719
1720 // btnRteActivate->SetLabel(route->m_bRtIsActive ? _("Deactivate") :
1721 // _("Activate"));
1722
1723 m_bNeedConfigFlush = true;
1724}
1725
1726void RouteManagerDialog::OnRteToggleVisibility(wxMouseEvent &event) {
1727 wxPoint pos = event.GetPosition();
1728 int flags = 0;
1729 long clicked_index = m_pRouteListCtrl->HitTest(pos, flags);
1730
1731 // Clicking Visibility column?
1732 if (clicked_index > -1 &&
1733 event.GetX() < m_pRouteListCtrl->GetColumnWidth(rmVISIBLE)) {
1734 // Process the clicked item
1735 Route *route = (Route *)m_pRouteListCtrl->GetItemData(clicked_index);
1736
1737 route->SetVisible(!route->IsVisible());
1738
1739 m_pRouteListCtrl->SetItemImage(clicked_index, route->IsVisible() ? 0 : 1);
1740
1741 ::wxBeginBusyCursor();
1742
1743 pConfig->UpdateRoute(route);
1744 gFrame->RefreshAllCanvas();
1745
1746 // We need to update the waypoint list control since the visibility of
1747 // shared waypoints might have changed.
1748 if (g_pRouteMan->DoesRouteContainSharedPoints(route))
1749 UpdateWptListCtrlViz();
1750
1751 // Manage "show all" checkbox
1752 bool viz = true;
1753 long item = -1;
1754 for (;;) {
1755 item = m_pRouteListCtrl->GetNextItem(item, wxLIST_NEXT_ALL,
1756 wxLIST_STATE_DONTCARE);
1757 if (item == -1) break;
1758
1759 Route *pR = (Route *)m_pRouteListCtrl->GetItemData(item);
1760
1761 if (!pR->IsVisible()) {
1762 viz = false;
1763 break;
1764 }
1765 }
1766 m_cbShowAllRte->SetValue(viz);
1767
1768 ::wxEndBusyCursor();
1769 }
1770
1771 // Allow wx to process...
1772 event.Skip();
1773}
1774
1775void RouteManagerDialog::OnRteBtnLeftDown(wxMouseEvent &event) {
1776 m_bCtrlDown = event.ControlDown();
1777 event.Skip();
1778}
1779
1780void RouteManagerDialog::OnRteSelected(wxListEvent &event) {
1781 long clicked_index = event.m_itemIndex;
1782 // Process the clicked item
1783 Route *route = (Route *)m_pRouteListCtrl->GetItemData(clicked_index);
1784 // route->SetVisible(!route->IsVisible());
1785 m_pRouteListCtrl->SetItemImage(clicked_index, route->IsVisible() ? 0 : 1);
1786 // pConfig->UpdateRoute(route);
1787
1788 gFrame->RefreshAllCanvas();
1789
1790 UpdateRteButtons();
1791}
1792
1793void RouteManagerDialog::OnRteColumnClicked(wxListEvent &event) {
1794 if (event.m_col == 1) {
1795 sort_route_name_dir++;
1796
1797 m_pRouteListCtrl->SortItems(SortRoutesOnName, (wxIntPtr)NULL);
1798 } else if (event.m_col == 2) {
1799 sort_route_to_dir++;
1800 m_pRouteListCtrl->SortItems(SortRoutesOnTo, (wxIntPtr)NULL);
1801 }
1802}
1803
1804void RouteManagerDialog::OnRteSendToGPSClick(wxCommandEvent &event) {
1805 long item = -1;
1806 item = m_pRouteListCtrl->GetNextItem(item, wxLIST_NEXT_ALL,
1807 wxLIST_STATE_SELECTED);
1808 if (item == -1) return;
1809
1810 Route *route = (Route *)m_pRouteListCtrl->GetItemData(item);
1811
1812 if (!route) return;
1813
1814 SendToGpsDlg *pdlg = new SendToGpsDlg();
1815 pdlg->SetRoute(route);
1816
1817 wxFont fo = GetOCPNGUIScaledFont(_T("Dialog"));
1818 pdlg->SetFont(fo);
1819
1820 wxString source;
1821 pdlg->Create(NULL, -1, _("Send to GPS") + _T( "..." ), source);
1822
1823#ifdef __WXOSX__
1824 HideWithEffect(wxSHOW_EFFECT_BLEND);
1825#endif
1826
1827 pdlg->ShowModal();
1828
1829#ifdef __WXOSX__
1830 ShowWithEffect(wxSHOW_EFFECT_BLEND);
1831#endif
1832
1833 pdlg->Destroy();
1834}
1835
1836void RouteManagerDialog::OnRteDefaultAction(wxListEvent &event) {
1837 wxCommandEvent evt;
1838 OnRtePropertiesClick(evt);
1839}
1840
1841void RouteManagerDialog::OnTrkDefaultAction(wxListEvent &event) {
1842 wxCommandEvent evt;
1843 OnTrkPropertiesClick(evt);
1844}
1845
1846void RouteManagerDialog::OnTrkRightClick(wxListEvent &event) {
1847 wxMenu menu;
1848 wxMenuItem *mergeItem = menu.Append(TRACK_MERGE, _("&Merge Selected Tracks"));
1849 mergeItem->Enable(m_pTrkListCtrl->GetSelectedItemCount() > 1);
1850 wxMenuItem *cleanItem = menu.Append(TRACK_CLEAN, _("Reduce Data..."));
1851 cleanItem->Enable(m_pTrkListCtrl->GetSelectedItemCount() == 1);
1852 wxMenuItem *copyItem = menu.Append(TRACK_COPY_TEXT, _("&Copy as text"));
1853 copyItem->Enable(m_pTrkListCtrl->GetSelectedItemCount() > 0);
1854 PopupMenu(&menu);
1855}
1856
1857static bool CompareTracks(Track *track1, Track *track2) {
1858 TrackPoint *start1 = track1->GetPoint(0);
1859 TrackPoint *start2 = track2->GetPoint(0);
1860 return start1->GetCreateTime() < start2->GetCreateTime();
1861}
1862
1863void RouteManagerDialog::OnTrkMenuSelected(wxCommandEvent &event) {
1864 int item = -1;
1865
1866 switch (event.GetId()) {
1867 case TRACK_CLEAN: {
1868 item = m_pTrkListCtrl->GetNextItem(item, wxLIST_NEXT_ALL,
1869 wxLIST_STATE_SELECTED);
1870 if (item == -1) break;
1871 Track *track = (Track *)m_pTrkListCtrl->GetItemData(item);
1872 if (track->IsRunning()) {
1873 wxBell();
1874 break;
1875 }
1876
1877 const wxString choices[] = {_T("5.0"), _T("10.0"), _T("20.0"), _T("50.0"),
1878 _T("100.0")};
1879
1880 wxSingleChoiceDialog precisionDlg(this,
1881 _("Select the maximum error allowed "
1882 "(in meters)\nafter data reduction:"),
1883 _("Reduce Data Precision"), 5, choices);
1884#ifdef __WXOSX__
1885 precisionDlg.ShowWindowModal();
1886 while (precisionDlg.IsShown()) {
1887 wxMilliSleep(10);
1888 wxYield();
1889 }
1890 int result = precisionDlg.GetReturnCode();
1891#else
1892 int result = precisionDlg.ShowModal();
1893#endif
1894 if (result == wxID_CANCEL) break;
1895 double precision = 5.0;
1896 switch (precisionDlg.GetSelection()) {
1897 case 0:
1898 precision = 5.0;
1899 break;
1900 case 1:
1901 precision = 10.0;
1902 break;
1903 case 2:
1904 precision = 20.0;
1905 break;
1906 case 3:
1907 precision = 50.0;
1908 break;
1909 case 4:
1910 precision = 100.0;
1911 break;
1912 }
1913
1914 int pointsBefore = track->GetnPoints();
1915
1916 int reduction = track->Simplify(precision);
1917 gFrame->Refresh(false);
1918
1919 reduction = 100 * reduction / pointsBefore;
1920 wxString msg = wxString::Format(
1921 _("The amount of data used by the track\n was reduced by %d%%."),
1922 reduction);
1923 OCPNMessageBox(this, msg, _("OpenCPN info"), wxICON_INFORMATION | wxOK);
1924
1925 UpdateTrkListCtrl();
1926 UpdateRouteListCtrl();
1927
1928 break;
1929 }
1930
1931 case TRACK_COPY_TEXT: {
1932 wxString csvString;
1933 while (1) {
1934 item = m_pTrkListCtrl->GetNextItem(item, wxLIST_NEXT_ALL,
1935 wxLIST_STATE_SELECTED);
1936 if (item == -1) break;
1937 Track *track = (Track *)m_pTrkListCtrl->GetItemData(item);
1938 csvString << track->GetName() << _T("\t")
1939 << wxString::Format(_T("%.1f"), track->Length()) << _T("\t")
1940 << _T("\n");
1941 }
1942
1943 if (wxTheClipboard->Open()) {
1944 wxTextDataObject *data = new wxTextDataObject;
1945 data->SetText(csvString);
1946 wxTheClipboard->SetData(data);
1947 wxTheClipboard->Close();
1948 }
1949
1950 break;
1951 }
1952
1953 case TRACK_MERGE: {
1954 Track *targetTrack = NULL;
1955 TrackPoint *tPoint;
1956 TrackPoint *newPoint;
1957 TrackPoint *lastPoint;
1958 std::vector<Track *> mergeList;
1959 std::vector<Track *> deleteList;
1960 bool runningSkipped = false;
1961
1962 ::wxBeginBusyCursor();
1963
1964 while (1) {
1965 item = m_pTrkListCtrl->GetNextItem(item, wxLIST_NEXT_ALL,
1966 wxLIST_STATE_SELECTED);
1967 if (item == -1) break;
1968 Track *track = (Track *)m_pTrkListCtrl->GetItemData(item);
1969 mergeList.push_back(track);
1970 }
1971
1972 std::sort(mergeList.begin(), mergeList.end(), CompareTracks);
1973
1974 targetTrack = mergeList[0];
1975 lastPoint = targetTrack->GetLastPoint();
1976
1977 for (auto const &mergeTrack : mergeList) {
1978 if (mergeTrack == *mergeList.begin()) continue;
1979
1980 if (mergeTrack->IsRunning()) {
1981 runningSkipped = true;
1982 continue;
1983 }
1984
1985 for (int i = 0; i < mergeTrack->GetnPoints(); i++) {
1986 tPoint = mergeTrack->GetPoint(i);
1987 newPoint = new TrackPoint(tPoint->m_lat, tPoint->m_lon,
1988 tPoint->GetCreateTime());
1989
1990 targetTrack->AddPoint(newPoint);
1991
1992 pSelect->AddSelectableTrackSegment(lastPoint->m_lat, lastPoint->m_lon,
1993 newPoint->m_lat, newPoint->m_lon,
1994 lastPoint, newPoint, targetTrack);
1995
1996 lastPoint = newPoint;
1997 }
1998 deleteList.push_back(mergeTrack);
1999 }
2000
2001 for (auto const &deleteTrack : deleteList) {
2002 g_pAIS->DeletePersistentTrack(deleteTrack);
2003 pConfig->DeleteConfigTrack(deleteTrack);
2004 RoutemanGui(*g_pRouteMan).DeleteTrack(deleteTrack);
2005 }
2006
2007 mergeList.clear();
2008 deleteList.clear();
2009
2010 ::wxEndBusyCursor();
2011
2012 UpdateTrkListCtrl();
2013 UpdateRouteListCtrl();
2014 gFrame->RefreshAllCanvas();
2015
2016 if (runningSkipped) {
2017 wxMessageDialog skipWarning(
2018 this,
2019 _("The currently running Track was not merged.\nYou can merge it "
2020 "later when it is completed."),
2021 _T("Warning"), wxCANCEL | wxICON_WARNING);
2022 skipWarning.ShowModal();
2023 }
2024
2025 break;
2026 }
2027 }
2028}
2029
2030void RouteManagerDialog::UpdateTrkListCtrl() {
2031 // if an item was selected, make it selected again if it still exist
2032 long item = -1;
2033 item =
2034 m_pTrkListCtrl->GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
2035
2036 wxUIntPtr selected_id = wxUIntPtr(0);
2037 if (item != -1) selected_id = m_pTrkListCtrl->GetItemData(item);
2038
2039 // Delete existing items
2040 m_pTrkListCtrl->DeleteAllItems();
2041
2042 // then add tracks to the listctrl
2043 std::vector<Track*>::iterator it;
2044 int index = 0;
2045 int list_index = 0;
2046 bool bpartialViz = false;
2047
2048 for (Track *trk : g_TrackList) {
2049 if (!trk->IsVisible()) bpartialViz = true;
2050
2051 if (!trk->IsListed()) continue;
2052
2053 if (!trk->GetName(true).Upper().Contains(
2054 m_tFilterTrk->GetValue().Upper())) {
2055 continue;
2056 }
2057
2058 wxListItem li;
2059 li.SetId(list_index);
2060 li.SetImage(trk->IsVisible() ? 0 : 1);
2061 li.SetData(trk);
2062 li.SetText(_T(""));
2063
2064 if (g_pActiveTrack == trk) {
2065 wxFont font = *wxNORMAL_FONT;
2066 font.SetWeight(wxFONTWEIGHT_BOLD);
2067 li.SetFont(font);
2068 }
2069 long idx = m_pTrkListCtrl->InsertItem(li);
2070
2071 m_pTrkListCtrl->SetItem(idx, colTRKNAME, trk->GetName(true));
2072
2073 wxString len;
2074 len.Printf(wxT("%5.2f"), trk->Length());
2075 m_pTrkListCtrl->SetItem(idx, colTRKLENGTH, len);
2076
2077 wxListItem lic;
2078 lic.SetId(list_index);
2079 lic.SetColumn(1);
2080 lic.SetAlign(wxLIST_FORMAT_LEFT);
2081 m_pTrkListCtrl->SetItem(lic);
2082
2083 lic.SetColumn(2);
2084 lic.SetAlign(wxLIST_FORMAT_LEFT);
2085 m_pTrkListCtrl->SetItem(lic);
2086
2087 list_index++;
2088 }
2089
2090 switch (sort_track_key) {
2091 case SORT_ON_DISTANCE:
2092 m_pTrkListCtrl->SortItems(SortTracksOnDistance, (wxIntPtr)NULL);
2093 break;
2094 case SORT_ON_NAME:
2095 default:
2096 m_pTrkListCtrl->SortItems(SortTracksOnName, (wxIntPtr)NULL);
2097 break;
2098 }
2099
2100 m_pTrkListCtrl->SetColumnWidth(0, 4 * m_charWidth);
2101
2102 // restore selection if possible
2103 // NOTE this will select a different item, if one is deleted
2104 // (the next route will get that index).
2105 if (selected_id != wxUIntPtr(0)) {
2106 item = m_pTrkListCtrl->FindItem(-1, selected_id);
2107 m_pTrkListCtrl->SetItemState(item,
2108 wxLIST_STATE_SELECTED | wxLIST_STATE_FOCUSED,
2109 wxLIST_STATE_SELECTED | wxLIST_STATE_FOCUSED);
2110 }
2111
2112 if ((m_lastTrkItem >= 0) && (m_pTrkListCtrl->GetItemCount()))
2113 m_pTrkListCtrl->EnsureVisible(m_lastTrkItem);
2114
2115 m_cbShowAllTrk->SetValue(!bpartialViz);
2116 UpdateTrkButtons();
2117}
2118
2119void RouteManagerDialog::OnTrkSelected(wxListEvent &event) {
2120 UpdateTrkButtons();
2121}
2122
2123void RouteManagerDialog::OnTrkColumnClicked(wxListEvent &event) {
2124 if (event.m_col == 1) {
2125 sort_track_key = SORT_ON_NAME;
2126 sort_track_name_dir++;
2127 m_pTrkListCtrl->SortItems(SortTracksOnName, (wxIntPtr)NULL);
2128 } else if (event.m_col == 2) {
2129 sort_track_key = SORT_ON_DISTANCE;
2130 sort_track_len_dir++;
2131 m_pTrkListCtrl->SortItems(SortTracksOnDistance, (wxIntPtr)NULL);
2132 }
2133}
2134
2135void RouteManagerDialog::UpdateTrkButtons() {
2136 long item = -1;
2137 item =
2138 m_pTrkListCtrl->GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
2139 int items = m_pTrkListCtrl->GetSelectedItemCount();
2140
2141 m_lastTrkItem = item;
2142
2143 btnTrkProperties->Enable(items == 1);
2144 btnTrkDelete->Enable(items >= 1);
2145 btnTrkExport->Enable(items >= 1);
2146 btnTrkRouteFromTrack->Enable(items == 1);
2147 btnTrkDeleteAll->Enable(m_pTrkListCtrl->GetItemCount() > 0);
2148 btnTrkSendToPeer->Enable(items >= 1);
2149}
2150
2151void RouteManagerDialog::OnTrkToggleVisibility(wxMouseEvent &event) {
2152 wxPoint pos = event.GetPosition();
2153 int flags = 0;
2154 long clicked_index = m_pTrkListCtrl->HitTest(pos, flags);
2155
2156 // Clicking Visibility column?
2157 if (clicked_index > -1 &&
2158 event.GetX() < m_pTrkListCtrl->GetColumnWidth(colTRKVISIBLE)) {
2159 // Process the clicked item
2160 Track *track = (Track *)m_pTrkListCtrl->GetItemData(clicked_index);
2161 if (track) {
2162 track->SetVisible(!track->IsVisible());
2163 m_pTrkListCtrl->SetItemImage(clicked_index, track->IsVisible() ? 0 : 1);
2164 }
2165
2166 // Manage "show all" checkbox
2167 bool viz = true;
2168 long item = -1;
2169 for (;;) {
2170 item = m_pTrkListCtrl->GetNextItem(item, wxLIST_NEXT_ALL,
2171 wxLIST_STATE_DONTCARE);
2172 if (item == -1) break;
2173
2174 Track *track = (Track *)m_pTrkListCtrl->GetItemData(item);
2175
2176 if (!track->IsVisible()) {
2177 viz = false;
2178 break;
2179 }
2180 }
2181 m_cbShowAllTrk->SetValue(viz);
2182
2183 gFrame->RefreshAllCanvas();
2184 }
2185
2186 // Allow wx to process...
2187 event.Skip();
2188}
2189
2190void RouteManagerDialog::OnTrkNewClick(wxCommandEvent &event) {
2191 gFrame->TrackOff();
2192 if (pConfig && pConfig->IsChangesFileDirty()) {
2193 pConfig->UpdateNavObj(true);
2194 }
2195
2196 gFrame->TrackOn();
2197
2198 UpdateTrkListCtrl();
2199}
2200
2201void RouteManagerDialog::OnTrkPropertiesClick(wxCommandEvent &event) {
2202 // Show trackproperties dialog for selected track
2203 long item = -1;
2204 item =
2205 m_pTrkListCtrl->GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
2206 if (item == -1) return;
2207
2208 Track *track = (Track *)m_pTrkListCtrl->GetItemData(item);
2209
2210 if (!track) return;
2211
2212 pTrackPropDialog = TrackPropDlg::getInstance(GetParent());
2213 pTrackPropDialog->SetTrackAndUpdate(track);
2214
2215 if (!pTrackPropDialog->IsShown()) pTrackPropDialog->Show();
2216 UpdateTrkListCtrl();
2217
2218 m_bNeedConfigFlush = true;
2219}
2220
2221void RouteManagerDialog::OnTrkDeleteClick(wxCommandEvent &event) {
2222 std::vector<Track*> list;
2223
2224 int answer = OCPNMessageBox(
2225 this, _("Are you sure you want to delete the selected object(s)"),
2226 wxString(_("OpenCPN Alert")), wxYES_NO);
2227 if (answer != wxID_YES) return;
2228
2229 bool busy = false;
2230 if (m_pTrkListCtrl->GetSelectedItemCount()) {
2231 ::wxBeginBusyCursor();
2232 m_bNeedConfigFlush = true;
2233 busy = true;
2234 }
2235
2236 long item = -1;
2237 for (;;) {
2238 item = m_pTrkListCtrl->GetNextItem(item, wxLIST_NEXT_ALL,
2239 wxLIST_STATE_SELECTED);
2240 if (item == -1) break;
2241
2242 Track *ptrack_to_delete = (Track *)m_pTrkListCtrl->GetItemData(item);
2243
2244 if (ptrack_to_delete) list.push_back(ptrack_to_delete);
2245 }
2246
2247 if (busy) {
2248 for (unsigned int i = 0; i < list.size(); i++) {
2249 Track *track = list.at(i);
2250 if (track) {
2251 g_pAIS->DeletePersistentTrack(track);
2252 pConfig->DeleteConfigTrack(track);
2253 RoutemanGui(*g_pRouteMan).DeleteTrack(track);
2254 }
2255 }
2256
2257 m_lastTrkItem = -1;
2258 // UpdateRouteListCtrl();
2259 UpdateTrkListCtrl();
2260
2261 if (pConfig && pConfig->IsChangesFileDirty()) {
2262 pConfig->UpdateNavObj(true);
2263 }
2264
2265 gFrame->InvalidateAllCanvasUndo();
2266 gFrame->RefreshAllCanvas();
2267 ::wxEndBusyCursor();
2268 }
2269}
2270
2271void RouteManagerDialog::OnTrkExportClick(wxCommandEvent &event) {
2272 std::vector<Track*> list;
2273 wxString suggested_name = _T("tracks");
2274
2275 long item = -1;
2276 for (;;) {
2277 item = m_pTrkListCtrl->GetNextItem(item, wxLIST_NEXT_ALL,
2278 wxLIST_STATE_SELECTED);
2279 if (item == -1) break;
2280
2281 Track *ptrack_to_export = (Track *)m_pTrkListCtrl->GetItemData(item);
2282
2283 if (ptrack_to_export) {
2284 list.push_back(ptrack_to_export);
2285 if (ptrack_to_export->GetName() != wxEmptyString)
2286 suggested_name = ptrack_to_export->GetName();
2287 }
2288 }
2289
2290 ExportGPXTracks(this, &list, suggested_name);
2291}
2292
2293void RouteManagerDialog::TrackToRoute(Track *track) {
2294 if (!track) return;
2295 if (track->m_bIsInLayer) return;
2296
2297 wxGenericProgressDialog pprog(_("OpenCPN Converting Track to Route...."),
2298 _("Processing Waypoints..."), 101, NULL,
2299 wxPD_AUTO_HIDE | wxPD_SMOOTH |
2300 wxPD_ELAPSED_TIME | wxPD_ESTIMATED_TIME |
2301 wxPD_REMAINING_TIME);
2302
2303 ::wxBeginBusyCursor();
2304
2305 Route *route = track->RouteFromTrack(&pprog);
2306
2307 pRouteList->Append(route);
2308
2309 pprog.Update(101, _("Done."));
2310
2311 gFrame->RefreshAllCanvas();
2312
2313 ::wxEndBusyCursor();
2314}
2315
2316void RouteManagerDialog::OnTrkRouteFromTrackClick(wxCommandEvent &event) {
2317 long item = -1;
2318 item =
2319 m_pTrkListCtrl->GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
2320 if (item == -1) return;
2321
2322 Track *track = (Track *)m_pTrkListCtrl->GetItemData(item);
2323
2324 TrackToRoute(track);
2325
2326 UpdateRouteListCtrl();
2327}
2328
2329void RouteManagerDialog::OnTrkDeleteAllClick(wxCommandEvent &event) {
2330 int dialog_ret =
2331 OCPNMessageBox(this, _("Are you sure you want to delete <ALL> tracks?"),
2332 wxString(_("OpenCPN Alert")), wxYES_NO);
2333
2334 if (dialog_ret == wxID_YES) {
2335 RoutemanGui(*g_pRouteMan).DeleteAllTracks();
2336 }
2337
2338 m_lastTrkItem = -1;
2339 m_lastRteItem = -1;
2340
2341 UpdateTrkListCtrl();
2342
2343 // Also need to update the route list control, since routes and tracks
2344 // share a common global list (pRouteList)
2345 UpdateRouteListCtrl();
2346
2347 if (pRoutePropDialog) pRoutePropDialog->Hide();
2348
2349 gFrame->RefreshAllCanvas();
2350
2351 m_bNeedConfigFlush = true;
2352}
2353
2354void RouteManagerDialog::UpdateWptListCtrl(RoutePoint *rp_select,
2355 bool b_retain_sort) {
2356 wxIntPtr selected_id = wxUIntPtr(0);
2357 long item = -1;
2358
2359 if (NULL == rp_select) {
2360 // if an item was selected, make it selected again if it still exists
2361 item = m_pWptListCtrl->GetNextItem(item, wxLIST_NEXT_ALL,
2362 wxLIST_STATE_SELECTED);
2363
2364 if (item != -1) selected_id = m_pWptListCtrl->GetItemData(item);
2365 }
2366
2367 // Freshen the image list
2368 m_pWptListCtrl->SetImageList(
2369 pWayPointMan->Getpmarkicon_image_list(m_listIconSize),
2370 wxIMAGE_LIST_SMALL);
2371
2372 m_pWptListCtrl->DeleteAllItems();
2373
2374 wxRoutePointListNode *node = pWayPointMan->GetWaypointList()->GetFirst();
2375
2376 int index = 0;
2377 bool b_anyHidden = false;
2378 while (node) {
2379 RoutePoint *rp = node->GetData();
2380 if (rp && rp->IsListed()) {
2381 if (rp->m_bIsInRoute && !rp->IsShared()) {
2382 node = node->GetNext();
2383 continue;
2384 }
2385
2386 if (!rp->GetName().Upper().Contains(m_tFilterWpt->GetValue().Upper())) {
2387 node = node->GetNext();
2388 continue;
2389 }
2390
2391 wxListItem li;
2392 li.SetId(index);
2393 li.SetImage(RoutePointGui(*rp).GetIconImageIndex());
2394 li.SetData(rp);
2395 li.SetText(_T(""));
2396 long idx = m_pWptListCtrl->InsertItem(li);
2397
2398 wxString scamin = wxString::Format(_T("%i"), (int)rp->GetScaMin());
2399 if (!rp->GetUseSca()) scamin = _("Always");
2400 if (g_bOverruleScaMin) scamin = _("Overruled");
2401 m_pWptListCtrl->SetItem(idx, colWPTSCALE, scamin);
2402
2403 wxString name = rp->GetName();
2404 if (name.IsEmpty()) name = _("(Unnamed Waypoint)");
2405 m_pWptListCtrl->SetItem(idx, colWPTNAME, name);
2406
2407 double dst;
2408 DistanceBearingMercator(rp->m_lat, rp->m_lon, gLat, gLon, NULL, &dst);
2409 wxString dist;
2410 dist.Printf(_T("%5.2f ") + getUsrDistanceUnit(), toUsrDistance(dst));
2411 m_pWptListCtrl->SetItem(idx, colWPTDIST, dist);
2412
2413 if (rp == rp_select) selected_id = (wxIntPtr)rp_select;
2414
2415 wxListItem lic;
2416 lic.SetId(index);
2417 lic.SetColumn(1);
2418 lic.SetAlign(wxLIST_FORMAT_LEFT);
2419 m_pWptListCtrl->SetItem(lic);
2420
2421 lic.SetColumn(2);
2422 lic.SetAlign(wxLIST_FORMAT_LEFT);
2423 m_pWptListCtrl->SetItem(lic);
2424
2425 if (!rp->IsVisible()) b_anyHidden = true;
2426
2427 index++;
2428 }
2429
2430 node = node->GetNext();
2431 }
2432
2433 if (!b_retain_sort) {
2434 m_pWptListCtrl->SortItems(SortWaypointsOnName,
2435 reinterpret_cast<wxIntPtr>(m_pWptListCtrl));
2436 sort_wp_key = SORT_ON_NAME;
2437 } else {
2438 switch (sort_wp_key) {
2439 case SORT_ON_NAME:
2440 m_pWptListCtrl->SortItems(SortWaypointsOnName,
2441 reinterpret_cast<wxIntPtr>(m_pWptListCtrl));
2442 break;
2443 case SORT_ON_DISTANCE:
2444 m_pWptListCtrl->SortItems(SortWaypointsOnDistance,
2445 reinterpret_cast<wxIntPtr>(m_pWptListCtrl));
2446 break;
2447 }
2448 }
2449
2450 if (selected_id != wxUIntPtr(0)) {
2451 item = m_pWptListCtrl->FindItem(-1, selected_id);
2452 m_pWptListCtrl->SetItemState(item,
2453 wxLIST_STATE_SELECTED | wxLIST_STATE_FOCUSED,
2454 wxLIST_STATE_SELECTED | wxLIST_STATE_FOCUSED);
2455 }
2456
2457 if ((m_lastWptItem >= 0) && (m_pWptListCtrl->GetItemCount()))
2458 m_pWptListCtrl->EnsureVisible(m_lastWptItem);
2459
2460 if (pWayPointMan->Getpmarkicon_image_list(m_listIconSize)->GetImageCount()) {
2461 int iwidth, iheight;
2462 pWayPointMan->Getpmarkicon_image_list(m_listIconSize)
2463 ->GetSize(0, iwidth, iheight);
2464
2465 m_pWptListCtrl->SetColumnWidth(0, wxMax(iwidth + 4, 4 * m_charWidth));
2466 }
2467
2468 UpdateWptButtons();
2469
2470 m_cbShowAllWP->SetValue(!b_anyHidden);
2471}
2472
2473void RouteManagerDialog::UpdateWptListCtrlViz() {
2474 long item = -1;
2475 for (;;) {
2476 item = m_pWptListCtrl->GetNextItem(item, wxLIST_NEXT_ALL,
2477 wxLIST_STATE_DONTCARE);
2478 if (item == -1) break;
2479
2480 RoutePoint *pRP = (RoutePoint *)m_pWptListCtrl->GetItemData(item);
2481 int imageIndex = RoutePointGui(*pRP).GetIconImageIndex();
2482
2483 m_pWptListCtrl->SetItemImage(item, imageIndex);
2484 }
2485}
2486
2487void RouteManagerDialog::OnWptDefaultAction(wxListEvent &event) {
2488 wxCommandEvent evt;
2489 OnWptPropertiesClick(evt);
2490}
2491
2492void RouteManagerDialog::OnWptSelected(wxListEvent &event) {
2493 UpdateWptButtons();
2494}
2495
2496void RouteManagerDialog::OnWptColumnClicked(wxListEvent &event) {
2497 if (event.m_col == NAME_COLUMN) {
2498 sort_wp_name_dir++;
2499 m_pWptListCtrl->SortItems(SortWaypointsOnName,
2500 reinterpret_cast<wxIntPtr>(m_pWptListCtrl));
2501 sort_wp_key = SORT_ON_NAME;
2502 } else {
2503 if (event.m_col == DISTANCE_COLUMN) {
2504 sort_wp_len_dir++;
2505 m_pWptListCtrl->SortItems(SortWaypointsOnDistance,
2506 reinterpret_cast<wxIntPtr>(m_pWptListCtrl));
2507 sort_wp_key = SORT_ON_DISTANCE;
2508 }
2509 }
2510 UpdateWptListCtrl();
2511}
2512
2513void RouteManagerDialog::UpdateWptButtons() {
2514 long item = -1;
2515 item =
2516 m_pWptListCtrl->GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
2517 bool enable1 = (m_pWptListCtrl->GetSelectedItemCount() == 1);
2518 bool enablemultiple = (m_pWptListCtrl->GetSelectedItemCount() >= 1);
2519
2520 if (enable1)
2521 m_lastWptItem = item;
2522 else
2523 m_lastWptItem = -1;
2524
2525 // Check selection to see if it is in a layer
2526 // If so, disable the "delete" button
2527 bool b_delete_enable = true;
2528 item = -1;
2529 for (;;) {
2530 item = m_pWptListCtrl->GetNextItem(item, wxLIST_NEXT_ALL,
2531 wxLIST_STATE_SELECTED);
2532 if (item == -1) break;
2533
2534 RoutePoint *wp = (RoutePoint *)m_pWptListCtrl->GetItemData(item);
2535
2536 if (wp && wp->m_bIsInLayer) {
2537 b_delete_enable = false;
2538 break;
2539 }
2540 }
2541
2542 btnWptProperties->Enable(enable1);
2543 btnWptZoomto->Enable(enable1);
2544 btnWptDeleteAll->Enable(m_pWptListCtrl->GetItemCount() > 0);
2545 btnWptDelete->Enable(b_delete_enable && enablemultiple);
2546 btnWptGoTo->Enable(enable1);
2547 btnWptExport->Enable(enablemultiple);
2548 btnWptSendToGPS->Enable(enable1);
2549 btnWptSendToPeer->Enable(enablemultiple);
2550}
2551
2552void RouteManagerDialog::OnWptToggleVisibility(wxMouseEvent &event) {
2553 wxPoint pos = event.GetPosition();
2554 int flags = 0;
2555 long clicked_index = m_pWptListCtrl->HitTest(pos, flags);
2556
2557 // Clicking Visibility column?
2558 if (clicked_index > -1 &&
2559 event.GetX() < m_pWptListCtrl->GetColumnWidth(colTRKVISIBLE)) {
2560 // Process the clicked item
2561 RoutePoint *wp = (RoutePoint *)m_pWptListCtrl->GetItemData(clicked_index);
2562
2563 if (!wp->IsSharedInVisibleRoute()) {
2564 wp->SetVisible(!wp->IsVisible());
2565 m_pWptListCtrl->SetItemImage(clicked_index, RoutePointGui(*wp).GetIconImageIndex());
2566
2567 pConfig->UpdateWayPoint(wp);
2568 }
2569
2570 // Manage "show all" checkbox
2571 bool viz = true;
2572 long item = -1;
2573 for (;;) {
2574 item = m_pWptListCtrl->GetNextItem(item, wxLIST_NEXT_ALL,
2575 wxLIST_STATE_DONTCARE);
2576 if (item == -1) break;
2577
2578 RoutePoint *wp = (RoutePoint *)m_pWptListCtrl->GetItemData(item);
2579
2580 if (!wp->IsVisible()) {
2581 viz = false;
2582 break;
2583 }
2584 }
2585 m_cbShowAllWP->SetValue(viz);
2586
2587 gFrame->RefreshAllCanvas();
2588 } else // clicked on ScaMin column??
2589 if (clicked_index > -1 &&
2590 event.GetX() > m_pWptListCtrl->GetColumnWidth(colTRKVISIBLE) &&
2591 event.GetX() < (m_pWptListCtrl->GetColumnWidth(colTRKVISIBLE) +
2592 m_pWptListCtrl->GetColumnWidth(colWPTSCALE)) &&
2593 !g_bOverruleScaMin) {
2594 RoutePoint *wp = (RoutePoint *)m_pWptListCtrl->GetItemData(clicked_index);
2595 wp->SetUseSca(!wp->GetUseSca());
2596 pConfig->UpdateWayPoint(wp);
2597 gFrame->RefreshAllCanvas();
2598 wxString scamin = wxString::Format(_T("%i"), (int)wp->GetScaMin());
2599 if (!wp->GetUseSca()) scamin = _("Always");
2600 m_pWptListCtrl->SetItem(clicked_index, colWPTSCALE, scamin);
2601 }
2602
2603 // Allow wx to process...
2604 event.Skip();
2605}
2606
2607void RouteManagerDialog::OnWptNewClick(wxCommandEvent &event) {
2608 RoutePoint *pWP = new RoutePoint(gLat, gLon, g_default_wp_icon, wxEmptyString,
2609 wxEmptyString);
2610 pWP->m_bIsolatedMark = true; // This is an isolated mark
2611 pSelect->AddSelectableRoutePoint(gLat, gLon, pWP);
2612 pConfig->AddNewWayPoint(pWP, -1); // use auto next num
2613 gFrame->RefreshAllCanvas();
2614
2615 // g_pMarkInfoDialog = MarkInfoImpl::getInstance( GetParent() );
2616 if (!g_pMarkInfoDialog) // There is one global instance of the MarkProp
2617 // Dialog
2618 g_pMarkInfoDialog = new MarkInfoDlg(GetParent());
2619
2620 g_pMarkInfoDialog->SetRoutePoint(pWP);
2621 g_pMarkInfoDialog->UpdateProperties();
2622
2623 WptShowPropertiesDialog(pWP, GetParent());
2624}
2625
2626void RouteManagerDialog::OnWptPropertiesClick(wxCommandEvent &event) {
2627 long item = -1;
2628 item =
2629 m_pWptListCtrl->GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
2630 if (item == -1) return;
2631
2632 RoutePoint *wp = (RoutePoint *)m_pWptListCtrl->GetItemData(item);
2633
2634 if (!wp) return;
2635
2636 WptShowPropertiesDialog(wp, GetParent());
2637
2638 UpdateWptListCtrl();
2639 m_bNeedConfigFlush = true;
2640}
2641
2642void RouteManagerDialog::WptShowPropertiesDialog(RoutePoint *wp,
2643 wxWindow *parent) {
2644 if (!g_pMarkInfoDialog) // There is one global instance of the MarkProp
2645 // Dialog
2646 g_pMarkInfoDialog = new MarkInfoDlg(parent);
2647
2648 g_pMarkInfoDialog->SetRoutePoint(wp);
2649 g_pMarkInfoDialog->UpdateProperties();
2650 if (wp->m_bIsInLayer) {
2651 wxString caption(wxString::Format(_T("%s, %s: %s"),
2652 _("Waypoint Properties"), _("Layer"),
2653 GetLayerName(wp->m_LayerID)));
2654 g_pMarkInfoDialog->SetDialogTitle(caption);
2655 } else
2656 g_pMarkInfoDialog->SetDialogTitle(_("Waypoint Properties"));
2657
2658 if (!g_pMarkInfoDialog->IsShown()) g_pMarkInfoDialog->Show();
2659 g_pMarkInfoDialog->Raise();
2660}
2661
2662void RouteManagerDialog::OnWptZoomtoClick(wxCommandEvent &event) {
2663 long item = -1;
2664 item =
2665 m_pWptListCtrl->GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
2666 if (item == -1) return;
2667
2668 RoutePoint *wp = (RoutePoint *)m_pWptListCtrl->GetItemData(item);
2669
2670 if (!wp) return;
2671
2672 gFrame->JumpToPosition(gFrame->GetPrimaryCanvas(), wp->m_lat, wp->m_lon,
2673 gFrame->GetPrimaryCanvas()->GetVPScale());
2674}
2675
2676void RouteManagerDialog::OnWptDeleteClick(wxCommandEvent &event) {
2677 RoutePointList list;
2678
2679 int answer = OCPNMessageBox(
2680 this, _("Are you sure you want to delete the selected object(s)"),
2681 wxString(_("OpenCPN Alert")), wxYES_NO);
2682 if (answer != wxID_YES) return;
2683
2684 bool busy = false;
2685 if (m_pWptListCtrl->GetSelectedItemCount()) {
2686 ::wxBeginBusyCursor();
2687 m_bNeedConfigFlush = true;
2688 busy = true;
2689 }
2690
2691 long item = -1;
2692 long item_last_selected = -1;
2693 for (;;) {
2694 item = m_pWptListCtrl->GetNextItem(item, wxLIST_NEXT_ALL,
2695 wxLIST_STATE_SELECTED);
2696 if (item == -1) break;
2697
2698 item_last_selected = item;
2699 RoutePoint *wp = (RoutePoint *)m_pWptListCtrl->GetItemData(item);
2700
2701 if (wp && !wp->m_bIsInLayer) list.Append(wp);
2702 }
2703
2704 if (busy) {
2705 for (unsigned int i = 0; i < list.GetCount(); i++) {
2706 RoutePoint *wp = list.Item(i)->GetData();
2707 if (wp) {
2708 if (wp->m_bIsInRoute) {
2709 if (wxID_YES ==
2710 OCPNMessageBox(this,
2711 _("The waypoint you want to delete is used in a "
2712 "route, do you really want to delete it?"),
2713 _("OpenCPN Alert"), wxYES_NO))
2714 pWayPointMan->DestroyWaypoint(wp);
2715 } else
2716 pWayPointMan->DestroyWaypoint(wp);
2717 }
2718 }
2719
2720 long item_next =
2721 m_pWptListCtrl->GetNextItem(item_last_selected); // next in list
2722 RoutePoint *wp_next = NULL;
2723 if (item_next > -1)
2724 wp_next = (RoutePoint *)m_pWptListCtrl->GetItemData(item_next);
2725
2726 m_lastWptItem = item_next;
2727
2728 UpdateRouteListCtrl();
2729 UpdateTrkListCtrl();
2730 UpdateWptListCtrl(wp_next, true);
2731
2732 if (g_pMarkInfoDialog) {
2733 g_pMarkInfoDialog->SetRoutePoint(NULL);
2734 g_pMarkInfoDialog->UpdateProperties();
2735 }
2736
2737 gFrame->InvalidateAllCanvasUndo();
2738 gFrame->RefreshAllCanvas();
2739 ::wxEndBusyCursor();
2740 }
2741}
2742
2743void RouteManagerDialog::OnWptGoToClick(wxCommandEvent &event) {
2744 long item = -1;
2745 item =
2746 m_pWptListCtrl->GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
2747 if (item == -1) return;
2748
2749 RoutePoint *wp = (RoutePoint *)m_pWptListCtrl->GetItemData(item);
2750
2751 if (!wp) return;
2752
2753 RoutePoint *pWP_src = new RoutePoint(gLat, gLon, g_default_wp_icon,
2754 wxEmptyString, wxEmptyString);
2755 pSelect->AddSelectableRoutePoint(gLat, gLon, pWP_src);
2756
2757 Route *temp_route = new Route();
2758 pRouteList->Append(temp_route);
2759
2760 temp_route->AddPoint(pWP_src);
2761 temp_route->AddPoint(wp);
2762
2763 pSelect->AddSelectableRouteSegment(gLat, gLon, wp->m_lat, wp->m_lon, pWP_src,
2764 wp, temp_route);
2765
2766 wxString name = wp->GetName();
2767 if (name.IsEmpty()) name = _("(Unnamed Waypoint)");
2768 wxString rteName = _("Go to ");
2769 rteName.Append(name);
2770 temp_route->m_RouteNameString = rteName;
2771 temp_route->m_RouteStartString = _("Here");
2772
2773 temp_route->m_RouteEndString = name;
2774 temp_route->m_bDeleteOnArrival = true;
2775
2776 if (g_pRouteMan->GetpActiveRoute()) g_pRouteMan->DeactivateRoute();
2777
2778 g_pRouteMan->ActivateRoute(temp_route, wp);
2779
2780 UpdateRouteListCtrl();
2781}
2782
2783void RouteManagerDialog::OnWptExportClick(wxCommandEvent &event) {
2784 RoutePointList list;
2785
2786 wxString suggested_name = _T("waypoints");
2787
2788 long item = -1;
2789 for (;;) {
2790 item = m_pWptListCtrl->GetNextItem(item, wxLIST_NEXT_ALL,
2791 wxLIST_STATE_SELECTED);
2792 if (item == -1) break;
2793
2794 RoutePoint *wp = (RoutePoint *)m_pWptListCtrl->GetItemData(item);
2795
2796 if (wp && !wp->m_bIsInLayer) {
2797 list.Append(wp);
2798 if (wp->GetName() != wxEmptyString) suggested_name = wp->GetName();
2799 }
2800 }
2801
2802 ExportGPXWaypoints(this, &list, suggested_name);
2803}
2804
2805void RouteManagerDialog::OnWptSendToGPSClick(wxCommandEvent &event) {
2806 long item = -1;
2807 item =
2808 m_pWptListCtrl->GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
2809 if (item == -1) return;
2810
2811 RoutePoint *wp = (RoutePoint *)m_pWptListCtrl->GetItemData(item);
2812
2813 if (!wp) return;
2814
2815 SendToGpsDlg *pdlg = new SendToGpsDlg();
2816 pdlg->SetWaypoint(wp);
2817
2818 wxString source;
2819 pdlg->Create(NULL, -1, _("Send to GPS") + _T( "..." ), source);
2820
2821#ifdef __WXOSX__
2822 HideWithEffect(wxSHOW_EFFECT_BLEND);
2823#endif
2824 pdlg->ShowModal();
2825#ifdef __WXOSX__
2826 ShowWithEffect(wxSHOW_EFFECT_BLEND);
2827#endif
2828
2829 delete pdlg;
2830}
2831
2832void RouteManagerDialog::OnWptDeleteAllClick(wxCommandEvent &event) {
2833 wxString prompt;
2834 int buttons, type;
2835 if (!pWayPointMan->SharedWptsExist()) {
2836 prompt = _("Are you sure you want to delete <ALL> waypoints?");
2837 buttons = wxYES_NO;
2838 type = 1;
2839 } else {
2840 prompt =
2841 _("There are some waypoints used in routes or anchor alarms.\n Do you "
2842 "want to delete them as well?\n This will change the routes and "
2843 "disable the anchor alarms.\n Answering No keeps the waypoints used "
2844 "in routes or alarms.");
2845 buttons = wxYES_NO | wxCANCEL;
2846 type = 2;
2847 }
2848 int answer =
2849 OCPNMessageBox(this, prompt, wxString(_("OpenCPN Alert")), buttons);
2850 if (answer == wxID_YES) pWayPointMan->DeleteAllWaypoints(true);
2851 if (answer == wxID_NO && type == 2)
2852 pWayPointMan->DeleteAllWaypoints(false); // only delete unused waypoints
2853
2854 if (g_pMarkInfoDialog) {
2855 g_pMarkInfoDialog->SetRoutePoint(NULL);
2856 g_pMarkInfoDialog->UpdateProperties();
2857 }
2858
2859 m_lastWptItem = -1;
2860 UpdateRouteListCtrl();
2861 UpdateWptListCtrl();
2862 gFrame->InvalidateAllCanvasUndo();
2863 gFrame->RefreshAllCanvas();
2864}
2865
2866void RouteManagerDialog::OnLaySelected(wxListEvent &event) {
2867 UpdateLayButtons();
2868}
2869
2870void RouteManagerDialog::OnLayColumnClicked(wxListEvent &event) {
2871 if (event.m_col == 1) {
2872 sort_layer_name_dir++;
2873 m_pLayListCtrl->SortItems(SortLayersOnName, (wxIntPtr)NULL);
2874 } else if (event.m_col == 2) {
2875 sort_layer_len_dir++;
2876 m_pLayListCtrl->SortItems(SortLayersOnSize, (wxIntPtr)NULL);
2877 }
2878}
2879
2880void RouteManagerDialog::UpdateLayButtons() {
2881 long item = -1;
2882 item =
2883 m_pLayListCtrl->GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
2884 bool enable = (item != -1);
2885
2886 // btnLayProperties->Enable(false);
2887 btnLayDelete->Enable(enable);
2888 cbLayToggleChart->Enable(enable);
2889 cbLayToggleListing->Enable(enable);
2890 cbLayToggleNames->Enable(enable);
2891
2892 if (item >= 0) {
2893 cbLayToggleChart->SetValue(
2894 ((Layer *)m_pLayListCtrl->GetItemData(item))->IsVisibleOnChart());
2895
2896 cbLayToggleNames->Set3StateValue(
2897 ((Layer *)m_pLayListCtrl->GetItemData(item))->HasVisibleNames());
2898
2899 cbLayToggleListing->SetValue(
2900 ((Layer *)m_pLayListCtrl->GetItemData(item))->IsVisibleOnListing());
2901
2902 } else {
2903 cbLayToggleChart->SetValue(true);
2904 cbLayToggleNames->Set3StateValue(wxCHK_UNDETERMINED);
2905 cbLayToggleListing->SetValue(true);
2906 }
2907}
2908
2909void RouteManagerDialog::OnLayToggleVisibility(wxMouseEvent &event) {
2910 wxPoint pos = event.GetPosition();
2911 int flags = 0;
2912 long clicked_index = m_pLayListCtrl->HitTest(pos, flags);
2913
2914 // Clicking Visibility column?
2915 if (clicked_index > -1 &&
2916 event.GetX() < m_pLayListCtrl->GetColumnWidth(colLAYVISIBLE)) {
2917 // Process the clicked item
2918 Layer *layer = (Layer *)m_pLayListCtrl->GetItemData(clicked_index);
2919
2920 layer->SetVisibleOnChart(!layer->IsVisibleOnChart());
2921 m_pLayListCtrl->SetItemImage(clicked_index,
2922 layer->IsVisibleOnChart() ? 0 : 1);
2923
2924 // Manage "show all" checkbox
2925 bool viz = true;
2926 long item = -1;
2927 for (;;) {
2928 item = m_pLayListCtrl->GetNextItem(item, wxLIST_NEXT_ALL,
2929 wxLIST_STATE_DONTCARE);
2930 if (item == -1) break;
2931
2932 Layer *layer = (Layer *)m_pLayListCtrl->GetItemData(item);
2933
2934 if (!layer->IsVisibleOnChart()) {
2935 viz = false;
2936 break;
2937 }
2938 }
2939 m_cbShowAllLay->SetValue(viz);
2940
2941 ToggleLayerContentsOnChart(layer);
2942 }
2943
2944 // Allow wx to process...
2945 event.Skip();
2946}
2947
2948void RouteManagerDialog::UpdateLists() {
2949 UpdateRouteListCtrl();
2950 UpdateTrkListCtrl();
2951 UpdateWptListCtrl();
2952 UpdateLayListCtrl();
2953}
2954
2955void RouteManagerDialog::OnLayNewClick(wxCommandEvent &event) {
2956 AddNewLayer(false); // Temporary layer
2957}
2958
2959void RouteManagerDialog::OnPerLayNewClick(wxCommandEvent &event) {
2960 AddNewLayer(true); // Persistent layer
2961}
2962
2963void RouteManagerDialog::AddNewLayer(bool isPersistent) {
2964 bool show_flag = g_bShowLayers;
2965 g_bShowLayers = true;
2966
2967 UI_ImportGPX(this, true, _T(""), true, isPersistent);
2968
2969 g_bShowLayers = show_flag;
2970 UpdateLists();
2971 gFrame->RefreshAllCanvas();
2972}
2973
2974void RouteManagerDialog::OnLayPropertiesClick(wxCommandEvent &event) {
2975 // Show layer properties dialog for selected layer - todo
2976 long item = -1;
2977 item =
2978 m_pLayListCtrl->GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
2979 if (item == -1) return;
2980}
2981
2982void RouteManagerDialog::OnLayDeleteClick(wxCommandEvent &event) {
2983 long item = -1;
2984 item =
2985 m_pLayListCtrl->GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
2986 if (item == -1) return;
2987
2988 Layer *layer = (Layer *)m_pLayListCtrl->GetItemData(item);
2989
2990 if (!layer) return;
2991 // Check if this file is a persistent layer.
2992 // If added in this session the listctrl file path is origin dir and not yet
2993 // /layers
2994 bool ispers = false;
2995 wxString destf, f, name, ext;
2996 f = layer->m_LayerFileName;
2997 wxFileName::SplitPath(f, NULL, NULL, &name, &ext);
2998 destf = g_Platform->GetPrivateDataDir();
2999 appendOSDirSlash(&destf);
3000 destf.Append(_T("layers"));
3001 appendOSDirSlash(&destf);
3002 destf << name << _T(".") << ext;
3003
3004 wxString prompt = _(
3005 "Are you sure you want to delete this layer and <ALL> of its contents?");
3006 if (wxFileExists(destf)) {
3007 prompt.Append(_T("\n"));
3008 prompt.Append(
3009 _("The file will also be deleted from OpenCPN's layer directory."));
3010 prompt.Append(_T("\n (") + destf + _T(")" ));
3011 ispers = true;
3012 }
3013 int answer =
3014 OCPNMessageBox(this, prompt, wxString(_("OpenCPN Alert")), wxYES_NO);
3015 if (answer == wxID_NO) return;
3016
3017 // Delete a persistent layer file if present
3018 if (ispers) {
3019 wxString remMSG;
3020 if (wxRemoveFile(destf))
3021 remMSG.sprintf(_T("Layer file: %s is deleted"), destf);
3022 else
3023 remMSG.sprintf(_T("Error deleting Layer file: %s"), destf);
3024
3025 wxLogMessage(remMSG);
3026 }
3027
3028 // Process Tracks and Routes in this layer
3029 wxRouteListNode *node1 = pRouteList->GetFirst();
3030 while (node1) {
3031 Route *pRoute = node1->GetData();
3032 wxRouteListNode *next_node = node1->GetNext();
3033 if (pRoute->m_bIsInLayer && (pRoute->m_LayerID == layer->m_LayerID)) {
3034 pRoute->m_bIsInLayer = false;
3035 pRoute->m_LayerID = 0;
3036 g_pRouteMan->DeleteRoute(pRoute, NavObjectChanges::getInstance());
3037 }
3038 node1 = next_node;
3039 }
3040
3041 for (Track *pTrack : g_TrackList) {
3042 if (pTrack->m_bIsInLayer && (pTrack->m_LayerID == layer->m_LayerID)) {
3043 pTrack->m_bIsInLayer = false;
3044 pTrack->m_LayerID = 0;
3045 RoutemanGui(*g_pRouteMan).DeleteTrack(pTrack);
3046 }
3047 }
3048
3049 // Process waypoints in this layer
3050 wxRoutePointListNode *node = pWayPointMan->GetWaypointList()->GetFirst();
3051 wxRoutePointListNode *node3;
3052
3053 while (node) {
3054 node3 = node->GetNext();
3055 RoutePoint *rp = node->GetData();
3056 if (rp && (rp->m_LayerID == layer->m_LayerID)) {
3057 rp->m_bIsInLayer = false;
3058 rp->m_LayerID = 0;
3059 pWayPointMan->DestroyWaypoint(
3060 rp, false); // no need to update the change set on layer ops
3061 }
3062
3063 node = node3;
3064 node3 = NULL;
3065 }
3066
3067 if (g_pMarkInfoDialog) {
3068 g_pMarkInfoDialog->SetRoutePoint(NULL);
3069 g_pMarkInfoDialog->UpdateProperties();
3070 }
3071
3072 pLayerList->DeleteObject(layer);
3073
3074 UpdateLists();
3075
3076 gFrame->RefreshAllCanvas();
3077
3078 m_bNeedConfigFlush = false;
3079}
3080
3081void RouteManagerDialog::OnLayToggleChartClick(wxCommandEvent &event) {
3082 // Toggle visibility on chart for selected layer
3083 long item = -1;
3084 item =
3085 m_pLayListCtrl->GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
3086 if (item == -1) return;
3087
3088 Layer *layer = (Layer *)m_pLayListCtrl->GetItemData(item);
3089
3090 if (!layer) return;
3091
3092 layer->SetVisibleOnChart(!layer->IsVisibleOnChart());
3093 m_pLayListCtrl->SetItemImage(item, layer->IsVisibleOnChart() ? 0 : 1);
3094
3095 ToggleLayerContentsOnChart(layer);
3096}
3097
3098void RouteManagerDialog::ToggleLayerContentsOnChart(Layer *layer) {
3099 // Process Tracks and Routes in this layer
3100 wxRouteListNode *node1 = pRouteList->GetFirst();
3101 while (node1) {
3102 Route *pRoute = node1->GetData();
3103 if (pRoute->m_bIsInLayer && (pRoute->m_LayerID == layer->m_LayerID)) {
3104 pRoute->SetVisible(layer->IsVisibleOnChart());
3105 pConfig->UpdateRoute(pRoute);
3106 }
3107 node1 = node1->GetNext();
3108 }
3109
3110 for (Track* pTrack : g_TrackList) {
3111 if (pTrack->m_bIsInLayer && (pTrack->m_LayerID == layer->m_LayerID))
3112 pTrack->SetVisible(layer->IsVisibleOnChart());
3113 }
3114
3115 // Process waypoints in this layer
3116 wxRoutePointListNode *node = pWayPointMan->GetWaypointList()->GetFirst();
3117
3118 while (node) {
3119 RoutePoint *rp = node->GetData();
3120 if (rp && (rp->m_LayerID == layer->m_LayerID)) {
3121 rp->SetVisible(layer->IsVisibleOnChart());
3122 }
3123
3124 node = node->GetNext();
3125 }
3126 UpdateLists();
3127
3128 UpdateLayButtons();
3129
3130 gFrame->RefreshAllCanvas();
3131}
3132
3133void RouteManagerDialog::OnLayToggleNamesClick(wxCommandEvent &event) {
3134 // Toggle WPT names visibility on chart for selected layer
3135 long item = -1;
3136 item =
3137 m_pLayListCtrl->GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
3138 if (item == -1) return;
3139
3140 Layer *layer = (Layer *)m_pLayListCtrl->GetItemData(item);
3141
3142 if (!layer) return;
3143
3144 layer->SetVisibleNames(cbLayToggleNames->Get3StateValue());
3145
3146 ToggleLayerContentsNames(layer);
3147}
3148
3149void RouteManagerDialog::ToggleLayerContentsNames(Layer *layer) {
3150 // Process Tracks and Routes in this layer
3151 wxRouteListNode *node1 = pRouteList->GetFirst();
3152 while (node1) {
3153 Route *pRoute = node1->GetData();
3154 if (pRoute->m_bIsInLayer && (pRoute->m_LayerID == layer->m_LayerID)) {
3155 wxRoutePointListNode *node = pRoute->pRoutePointList->GetFirst();
3156 RoutePoint *prp1 = node->GetData();
3157 while (node) {
3158 if (layer->HasVisibleNames() == wxCHK_UNDETERMINED) {
3159 prp1->m_bShowName = prp1->m_bShowNameData;
3160 } else {
3161 prp1->m_bShowName = (layer->HasVisibleNames() == wxCHK_CHECKED);
3162 }
3163 node = node->GetNext();
3164 }
3165 }
3166 node1 = node1->GetNext();
3167 }
3168
3169 // Process waypoints in this layer
3170 wxRoutePointListNode *node = pWayPointMan->GetWaypointList()->GetFirst();
3171
3172 while (node) {
3173 RoutePoint *rp = node->GetData();
3174 if (rp && (rp->m_LayerID == layer->m_LayerID)) {
3175 rp->SetNameShown(layer->HasVisibleNames() == wxCHK_CHECKED ||
3176 (rp->m_bShowNameData &&
3177 layer->HasVisibleNames() == wxCHK_UNDETERMINED));
3178 }
3179
3180 node = node->GetNext();
3181 }
3182
3183 UpdateLayButtons();
3184
3185 gFrame->RefreshAllCanvas();
3186}
3187
3188void RouteManagerDialog::OnLayToggleListingClick(wxCommandEvent &event) {
3189 // Toggle visibility on listing for selected layer
3190 long item = -1;
3191 item =
3192 m_pLayListCtrl->GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
3193 if (item == -1) return;
3194
3195 Layer *layer = (Layer *)m_pLayListCtrl->GetItemData(item);
3196
3197 if (!layer) return;
3198
3199 layer->SetVisibleOnListing(!layer->IsVisibleOnListing());
3200
3201 ToggleLayerContentsOnListing(layer);
3202}
3203
3204void RouteManagerDialog::ToggleLayerContentsOnListing(Layer *layer) {
3205 ::wxBeginBusyCursor();
3206
3207 // Process Tracks and Routes in this layer
3208 wxRouteListNode *node1 = pRouteList->GetFirst();
3209 while (node1) {
3210 Route *pRoute = node1->GetData();
3211 if (pRoute->m_bIsInLayer && (pRoute->m_LayerID == layer->m_LayerID)) {
3212 pRoute->SetListed(layer->IsVisibleOnListing());
3213 }
3214 node1 = node1->GetNext();
3215 }
3216
3217 for (Track *pTrack : g_TrackList) {
3218 if (pTrack->m_bIsInLayer && (pTrack->m_LayerID == layer->m_LayerID))
3219 pTrack->SetListed(layer->IsVisibleOnListing());
3220 }
3221
3222 // Process waypoints in this layer
3223 // n.b. If the waypoint belongs to a track, and is not shared, then do not
3224 // list it. This is a performance optimization, allowing large track support.
3225
3226 wxRoutePointListNode *node = pWayPointMan->GetWaypointList()->GetFirst();
3227
3228 while (node) {
3229 RoutePoint *rp = node->GetData();
3230 if (rp && rp->m_bIsolatedMark && (rp->m_LayerID == layer->m_LayerID)) {
3231 rp->SetListed(layer->IsVisibleOnListing());
3232 }
3233
3234 node = node->GetNext();
3235 }
3236
3237 UpdateLists();
3238
3239 ::wxEndBusyCursor();
3240
3241 gFrame->RefreshAllCanvas();
3242}
3243
3244void RouteManagerDialog::OnLayDefaultAction(wxListEvent &event) {
3245 wxCommandEvent evt;
3246 OnLayPropertiesClick(evt);
3247}
3248
3249void RouteManagerDialog::UpdateLayListCtrl() {
3250 // if an item was selected, make it selected again if it still exist
3251 long item = -1;
3252 item =
3253 m_pLayListCtrl->GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
3254
3255 wxUIntPtr selected_id = wxUIntPtr(0);
3256 if (item != -1) selected_id = m_pLayListCtrl->GetItemData(item);
3257
3258 // Delete existing items
3259 m_pLayListCtrl->DeleteAllItems();
3260
3261 // then add routes to the listctrl
3262 LayerList::iterator it;
3263 int index = 0;
3264 bool b_anyHidden = false;
3265 for (it = (*pLayerList).begin(); it != (*pLayerList).end(); ++it, ++index) {
3266 Layer *lay = (Layer *)(*it);
3267
3268 if (!lay->m_LayerName.Upper().Contains(m_tFilterLay->GetValue().Upper())) {
3269 continue;
3270 }
3271
3272 wxListItem li;
3273 li.SetId(index);
3274 li.SetImage(lay->IsVisibleOnChart() ? 0 : 1);
3275 li.SetData(lay);
3276 li.SetText(_T(""));
3277
3278 long idx = m_pLayListCtrl->InsertItem(li);
3279
3280 wxString name = lay->m_LayerName;
3281 if (name.IsEmpty()) {
3282 // RoutePoint *rp = trk->GetPoint(1);
3283 // if (rp)
3284 // name = rp->m_CreateTime.FormatISODate() + _T(" ") +
3285 // rp->m_CreateTime.FormatISOTime(); //name =
3286 // rp->m_CreateTime.Format();
3287 // else
3288 name = _("(Unnamed Layer)");
3289 }
3290 m_pLayListCtrl->SetItem(idx, colLAYNAME, name);
3291
3292 wxString len;
3293 len.Printf(wxT("%d"), (int)lay->m_NoOfItems);
3294 m_pLayListCtrl->SetItem(idx, colLAYITEMS, len);
3295 m_pLayListCtrl->SetItem(idx, colLAYPERSIST, lay->m_LayerType);
3296
3297 wxListItem lic;
3298 lic.SetId(index);
3299 lic.SetColumn(1);
3300 lic.SetAlign(wxLIST_FORMAT_LEFT);
3301 m_pLayListCtrl->SetItem(lic);
3302
3303 lic.SetColumn(2);
3304 lic.SetAlign(wxLIST_FORMAT_LEFT);
3305 m_pLayListCtrl->SetItem(lic);
3306
3307 if (!lay->IsVisibleOnChart()) b_anyHidden = true;
3308 }
3309
3310 m_pLayListCtrl->SortItems(SortLayersOnName,
3311 reinterpret_cast<wxIntPtr>(m_pLayListCtrl));
3312 m_pLayListCtrl->SetColumnWidth(0, 4 * m_charWidth);
3313
3314 // restore selection if possible
3315 // NOTE this will select a different item, if one is deleted
3316 // (the next route will get that index).
3317 if (selected_id != wxUIntPtr(0)) {
3318 item = m_pLayListCtrl->FindItem(-1, selected_id);
3319 m_pLayListCtrl->SetItemState(item,
3320 wxLIST_STATE_SELECTED | wxLIST_STATE_FOCUSED,
3321 wxLIST_STATE_SELECTED | wxLIST_STATE_FOCUSED);
3322 }
3323 UpdateLayButtons();
3324
3325 m_cbShowAllLay->SetValue(!b_anyHidden);
3326}
3327
3328void RouteManagerDialog::OnImportClick(wxCommandEvent &event) {
3329 // Import routes
3330 // FIXME there is no way to instruct this function about what to import.
3331 // Suggest to add that!
3332
3333 UI_ImportGPX(this);
3334
3335 UpdateLists();
3336
3337 gFrame->RefreshAllCanvas();
3338}
3339void RouteManagerDialog::OnExportClick(wxCommandEvent &event) {
3340 ExportGPX(this);
3341}
3342
3343void RouteManagerDialog::OnExportVizClick(wxCommandEvent &event) {
3344 ExportGPX(this, true, true); // only visible objects, layers included
3345}
3346
3347void RouteManagerDialog::OnFilterChanged(wxCommandEvent &event) {
3348 if (event.GetEventObject() == m_tFilterWpt) {
3349 UpdateWptListCtrl(NULL, true);
3350 } else if (event.GetEventObject() == m_tFilterRte) {
3351 UpdateRouteListCtrl();
3352 } else if (event.GetEventObject() == m_tFilterTrk) {
3353 UpdateTrkListCtrl();
3354 } else if (event.GetEventObject() == m_tFilterLay) {
3355 UpdateLayListCtrl();
3356 }
3357}
3358
3359// END Event handlers
Definition: Layer.h:32
Class MarkInfoDef.
Definition: MarkInfo.h:197
Definition: route.h:70
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