OpenCPN Partial API docs
TrackPropDlg.cpp
1 /***************************************************************************
2  *
3  * Project: OpenCPN
4  * Purpose: Track Properties Dialog
5  * Author: David Register
6  *
7  ***************************************************************************
8  * Copyright (C) 2013 by David S. Register *
9  * *
10  * This program is free software; you can redistribute it and/or modify *
11  * it under the terms of the GNU General Public License as published by *
12  * the Free Software Foundation; either version 2 of the License, or *
13  * (at your option) any later version. *
14  * *
15  * This program is distributed in the hope that it will be useful, *
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18  * GNU General Public License for more details. *
19  * *
20  * You should have received a copy of the GNU General Public License *
21  * along with this program; if not, write to the *
22  * Free Software Foundation, Inc., *
23  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
24  **************************************************************************/
25 #include "config.h"
26 
27 #include "model/georef.h"
28 #include "model/navutil_base.h"
29 #include "model/own_ship.h"
30 #include "model/route.h"
31 #include "model/routeman.h"
32 #include "model/select.h"
33 #include "model/track.h"
34 
35 #include "chcanv.h"
36 #include "displays.h"
37 #include "gui_lib.h"
38 #include "navutil.h"
39 #include "ocpn_frame.h"
40 #include "OCPNPlatform.h"
41 #include "pluginmanager.h"
42 #include "routemanagerdialog.h"
43 #include "routeman_gui.h"
44 #include "trackprintout.h"
45 #include "TrackPropDlg.h"
46 
47 #ifdef __ANDROID__
48 #include "androidUTIL.h"
49 #endif
50 
51 #define UTCINPUT 0
52 #define LTINPUT 1 // i.e. this PC local time
53 #define LMTINPUT 2 // i.e. the remote location LMT time
54 #define INPUT_FORMAT 1
55 #define DISPLAY_FORMAT 2
56 #define TIMESTAMP_FORMAT 3
57 
58 extern std::vector<Track*> g_TrackList;
59 extern ActiveTrack* g_pActiveTrack;
60 extern Routeman* g_pRouteMan;
61 extern RouteManagerDialog* pRouteManagerDialog;
62 extern MyConfig* pConfig;
63 extern MyFrame* gFrame;
64 extern PlugInManager* g_pi_manager;
65 
66 wxString timestamp2s(wxDateTime ts, int tz_selection, long LMT_offset,
67  int format) {
68  wxString s = _T("");
69  wxString f;
70  if (format == INPUT_FORMAT)
71  f = _T("%x %H:%M");
72  else if (format == TIMESTAMP_FORMAT)
73  f = _T("%x %H:%M:%S");
74  else
75  f = _T(" %x %H:%M");
76  switch (tz_selection) {
77  case UTCINPUT:
78  s.Append(ts.Format(f));
79  if (format != INPUT_FORMAT) s.Append(_T(" UT"));
80  break;
81  case LTINPUT:
82  s.Append(ts.FromUTC().Format(f));
83  break;
84  case LMTINPUT:
85  wxTimeSpan lmt(0, 0, (int)LMT_offset, 0);
86  s.Append(ts.Add(lmt).Format(f));
87  if (format != INPUT_FORMAT) s.Append(_T(" LMT"));
88  }
89  return (s);
90 }
91 
93 bool TrackPropDlg::instanceFlag = false;
94 TrackPropDlg* TrackPropDlg::single = NULL;
95 TrackPropDlg* TrackPropDlg::getInstance(wxWindow* parent, wxWindowID id,
96  const wxString& title,
97  const wxPoint& pos, const wxSize& size,
98  long style) {
99  if (!instanceFlag) {
100  single = new TrackPropDlg(parent, id, title, pos, size, style);
101  instanceFlag = true;
102  return single;
103  } else {
104  return single;
105  }
106 }
107 
108 TrackPropDlg::TrackPropDlg(wxWindow* parent, wxWindowID id,
109  const wxString& title, const wxPoint& pos,
110  const wxSize& size, long style)
111  : DIALOG_PARENT(parent, id, title, pos, size, style) {
112  wxFont* qFont = GetOCPNScaledFont(_("Dialog"));
113  SetFont(*qFont);
114 
115  SetWindowStyleFlag(style);
116 
117  m_scrolledWindowLinks = NULL;
118  m_tDescription = NULL;
119 
120  m_bcompact = false;
121 
122 #ifdef __ANDROID__
123  m_bcompact = true;
124  CreateControlsCompact();
125 #else
126  CreateControls();
127 #endif
128 
129  RecalculateSize();
130 
131  // Centre( );
132 
133  // Connect Events
134  m_sdbBtmBtnsSizerCancel->Connect(
135  wxEVT_COMMAND_BUTTON_CLICKED,
136  wxCommandEventHandler(TrackPropDlg::OnCancelBtnClick), NULL, this);
137  m_sdbBtmBtnsSizerOK->Connect(
138  wxEVT_COMMAND_BUTTON_CLICKED,
139  wxCommandEventHandler(TrackPropDlg::OnOKBtnClick), NULL, this);
140  if (m_sdbBtmBtnsSizerPrint)
141  m_sdbBtmBtnsSizerPrint->Connect(
142  wxEVT_COMMAND_BUTTON_CLICKED,
143  wxCommandEventHandler(TrackPropDlg::OnPrintBtnClick), NULL, this);
144  m_sdbBtmBtnsSizerSplit->Connect(
145  wxEVT_COMMAND_BUTTON_CLICKED,
146  wxCommandEventHandler(TrackPropDlg::OnSplitBtnClick), NULL, this);
147  m_sdbBtmBtnsSizerExtend->Connect(
148  wxEVT_COMMAND_BUTTON_CLICKED,
149  wxCommandEventHandler(TrackPropDlg::OnExtendBtnClick), NULL, this);
150  m_sdbBtmBtnsSizerToRoute->Connect(
151  wxEVT_COMMAND_BUTTON_CLICKED,
152  wxCommandEventHandler(TrackPropDlg::OnToRouteBtnClick), NULL, this);
153  if (m_sdbBtmBtnsSizerExport)
154  m_sdbBtmBtnsSizerExport->Connect(
155  wxEVT_COMMAND_BUTTON_CLICKED,
156  wxCommandEventHandler(TrackPropDlg::OnExportBtnClick), NULL, this);
157  m_lcPoints->Connect(wxEVT_COMMAND_LIST_ITEM_SELECTED,
158  wxListEventHandler(TrackPropDlg::OnTrackPropListClick),
159  NULL, this);
160  Connect(wxEVT_COMMAND_LIST_ITEM_RIGHT_CLICK,
161  wxListEventHandler(TrackPropDlg::OnTrackPropRightClick), NULL, this);
162  Connect(wxEVT_COMMAND_MENU_SELECTED,
163  wxCommandEventHandler(TrackPropDlg::OnTrackPropMenuSelected), NULL,
164  this);
165 
166 #ifdef __WXOSX__
167  Connect(wxEVT_ACTIVATE,
168  wxActivateEventHandler(TrackPropDlg::OnActivate),
169  NULL, this);
170 #endif
171 
172  if (!m_bcompact) {
173  m_buttonAddLink->Connect(wxEVT_COMMAND_BUTTON_CLICKED,
174  wxCommandEventHandler(TrackPropDlg::OnAddLink),
175  NULL, this);
176  m_toggleBtnEdit->Connect(
177  wxEVT_COMMAND_TOGGLEBUTTON_CLICKED,
178  wxCommandEventHandler(TrackPropDlg::OnEditLinkToggle), NULL, this);
179  }
180 
181  if (m_rbShowTimeUTC)
182  m_rbShowTimeUTC->Connect(wxEVT_COMMAND_RADIOBUTTON_SELECTED,
183  wxCommandEventHandler(TrackPropDlg::OnShowTimeTZ),
184  NULL, this);
185  if (m_rbShowTimePC)
186  m_rbShowTimePC->Connect(wxEVT_COMMAND_RADIOBUTTON_SELECTED,
187  wxCommandEventHandler(TrackPropDlg::OnShowTimeTZ),
188  NULL, this);
189  if (m_rbShowTimeLocal)
190  m_rbShowTimeLocal->Connect(
191  wxEVT_COMMAND_RADIOBUTTON_SELECTED,
192  wxCommandEventHandler(TrackPropDlg::OnShowTimeTZ), NULL, this);
193 
194  m_pMyLinkList = NULL;
195 }
196 
197 TrackPropDlg::~TrackPropDlg() {
198  // Disconnect Events
199  m_sdbBtmBtnsSizerCancel->Disconnect(
200  wxEVT_COMMAND_BUTTON_CLICKED,
201  wxCommandEventHandler(TrackPropDlg::OnCancelBtnClick), NULL, this);
202  m_sdbBtmBtnsSizerOK->Disconnect(
203  wxEVT_COMMAND_BUTTON_CLICKED,
204  wxCommandEventHandler(TrackPropDlg::OnOKBtnClick), NULL, this);
205  if (m_sdbBtmBtnsSizerPrint)
206  m_sdbBtmBtnsSizerPrint->Disconnect(
207  wxEVT_COMMAND_BUTTON_CLICKED,
208  wxCommandEventHandler(TrackPropDlg::OnPrintBtnClick), NULL, this);
209  m_sdbBtmBtnsSizerSplit->Disconnect(
210  wxEVT_COMMAND_BUTTON_CLICKED,
211  wxCommandEventHandler(TrackPropDlg::OnSplitBtnClick), NULL, this);
212  m_sdbBtmBtnsSizerExtend->Disconnect(
213  wxEVT_COMMAND_BUTTON_CLICKED,
214  wxCommandEventHandler(TrackPropDlg::OnExtendBtnClick), NULL, this);
215  m_sdbBtmBtnsSizerToRoute->Disconnect(
216  wxEVT_COMMAND_BUTTON_CLICKED,
217  wxCommandEventHandler(TrackPropDlg::OnToRouteBtnClick), NULL, this);
218  if (m_sdbBtmBtnsSizerExport)
219  m_sdbBtmBtnsSizerExport->Disconnect(
220  wxEVT_COMMAND_BUTTON_CLICKED,
221  wxCommandEventHandler(TrackPropDlg::OnExportBtnClick), NULL, this);
222  m_lcPoints->Disconnect(wxEVT_COMMAND_LIST_ITEM_SELECTED,
223  wxListEventHandler(TrackPropDlg::OnTrackPropListClick),
224  NULL, this);
225  Disconnect(wxEVT_COMMAND_LIST_ITEM_RIGHT_CLICK,
226  wxListEventHandler(TrackPropDlg::OnTrackPropRightClick), NULL,
227  this);
228  Disconnect(wxEVT_COMMAND_MENU_SELECTED,
229  wxCommandEventHandler(TrackPropDlg::OnTrackPropMenuSelected), NULL,
230  this);
231 
232  Disconnect(wxID_ANY, wxEVT_COMMAND_MENU_SELECTED,
233  wxCommandEventHandler(TrackPropDlg::OnDeleteLink));
234  Disconnect(wxID_ANY, wxEVT_COMMAND_MENU_SELECTED,
235  wxCommandEventHandler(TrackPropDlg::OnEditLink));
236  Disconnect(wxID_ANY, wxEVT_COMMAND_MENU_SELECTED,
237  wxCommandEventHandler(TrackPropDlg::OnAddLink));
238 
239  if (!m_bcompact) {
240  m_buttonAddLink->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED,
241  wxCommandEventHandler(TrackPropDlg::OnAddLink),
242  NULL, this);
243  m_toggleBtnEdit->Disconnect(
244  wxEVT_COMMAND_TOGGLEBUTTON_CLICKED,
245  wxCommandEventHandler(TrackPropDlg::OnEditLinkToggle), NULL, this);
246  }
247 
248  if (m_rbShowTimeUTC)
249  m_rbShowTimeUTC->Disconnect(
250  wxEVT_COMMAND_RADIOBUTTON_SELECTED,
251  wxCommandEventHandler(TrackPropDlg::OnShowTimeTZ), NULL, this);
252  if (m_rbShowTimePC)
253  m_rbShowTimePC->Disconnect(
254  wxEVT_COMMAND_RADIOBUTTON_SELECTED,
255  wxCommandEventHandler(TrackPropDlg::OnShowTimeTZ), NULL, this);
256  if (m_rbShowTimeLocal)
257  m_rbShowTimeLocal->Disconnect(
258  wxEVT_COMMAND_RADIOBUTTON_SELECTED,
259  wxCommandEventHandler(TrackPropDlg::OnShowTimeTZ), NULL, this);
260 
261  instanceFlag = false;
262 }
263 
264 void TrackPropDlg::OnActivate(wxActivateEvent& event){
265  DIALOG_PARENT* pWin = wxDynamicCast(event.GetEventObject(), DIALOG_PARENT);
266  long int style = pWin->GetWindowStyle();
267  if (event.GetActive())
268  pWin->SetWindowStyle(style | wxSTAY_ON_TOP);
269  else
270  pWin->SetWindowStyle(style ^ wxSTAY_ON_TOP);
271 }
272 
273 
274 void TrackPropDlg::RecalculateSize(void) {
275  // Make an estimate of the dialog size, without scrollbars showing
276 
277  wxSize esize;
278  esize.x = GetCharWidth() * 110;
279  esize.y = GetCharHeight() * 40;
280 
281  wxSize dsize = GetParent()->GetClientSize();
282  esize.y = wxMin(esize.y, dsize.y - (2 * GetCharHeight()));
283  esize.x = wxMin(esize.x, dsize.x - (2 * GetCharHeight()));
284  SetClientSize(esize);
285 
286  wxSize fsize = GetSize();
287  fsize.y = wxMin(fsize.y, dsize.y - (2 * GetCharHeight()));
288  fsize.x = wxMin(fsize.x, dsize.x - (2 * GetCharHeight()));
289  SetSize(fsize);
290 
291  if (m_bcompact) {
292  int sy = GetCharHeight() * m_lcPoints->GetItemCount();
293  sy = wxMax(sy, 250);
294  sy = wxMin(sy, 500);
295  m_lcPoints->SetSize(wxSize(GetClientSize().x - 40, sy));
296 
297  if (m_lcPoints->GetItemCount()) Layout();
298  }
299 
300  Centre();
301 }
302 
303 static void addColumns(wxListCtrl* lctrl, int dx) {
304  lctrl->InsertColumn(0, _("Leg"), wxLIST_FORMAT_LEFT, dx * 6);
305  lctrl->InsertColumn(1, _("Distance"), wxLIST_FORMAT_LEFT, dx * 10);
306  lctrl->InsertColumn(2, _("Bearing"), wxLIST_FORMAT_LEFT, dx * 8);
307  lctrl->InsertColumn(3, _("Latitude"), wxLIST_FORMAT_LEFT, dx * 11);
308  lctrl->InsertColumn(4, _("Longitude"), wxLIST_FORMAT_LEFT, dx * 11);
309  // Width of timestamp is typically 19 characters: 'MM/DD/YYYY HH:MM:SS'.
310  lctrl->InsertColumn(5, _("Timestamp"), wxLIST_FORMAT_LEFT, dx * 19);
311  lctrl->InsertColumn(6, _("Speed"), wxLIST_FORMAT_CENTER, dx * 8);
312 
313  lctrl->SetMinSize(wxSize(-1, 50));
314 }
315 
316 void TrackPropDlg::CreateControlsCompact() {
317  wxBoxSizer* itemBoxSizer1 = new wxBoxSizer(wxVERTICAL);
318  SetSizer(itemBoxSizer1);
319 
320  itemDialog1 = new wxScrolledWindow(this, wxID_ANY, wxDefaultPosition,
321  wxSize(-1, -1), wxVSCROLL);
322  itemDialog1->SetScrollRate(0, 1);
323 
324 #ifdef __ANDROID__
325  // Set Dialog Font by custom crafted Qt Stylesheet.
326  wxFont* qFont = GetOCPNScaledFont(_("Dialog"));
327 
328  wxString wqs = getFontQtStylesheet(qFont);
329  wxCharBuffer sbuf = wqs.ToUTF8();
330  QString qsb = QString(sbuf.data());
331 
332  QString qsbq = getQtStyleSheet(); // basic scrollbars, etc
333 
334  itemDialog1->GetHandle()->setStyleSheet(qsb +
335  qsbq); // Concatenated style sheets
336 
337 #endif
338  itemBoxSizer1->Add(itemDialog1, 1, wxEXPAND | wxALL, 0);
339 
340  wxBoxSizer* itemBoxSizer2 = new wxBoxSizer(wxVERTICAL);
341  itemDialog1->SetSizer(itemBoxSizer2);
342 
343  wxStaticText* itemStaticText4 = new wxStaticText(
344  itemDialog1, wxID_STATIC, _("Name"), wxDefaultPosition, wxDefaultSize, 0);
345  itemBoxSizer2->Add(itemStaticText4, 0,
346  wxALIGN_LEFT | wxLEFT | wxRIGHT | wxTOP, 5);
347 
348  m_tName = new wxTextCtrl(itemDialog1, wxID_ANY, _T(""), wxDefaultPosition,
349  wxSize(400, -1), 0);
350  itemBoxSizer2->Add(m_tName, 0, wxALIGN_LEFT | wxLEFT | wxRIGHT | wxBOTTOM, 5);
351 
352  wxStaticText* itemStaticText7 =
353  new wxStaticText(itemDialog1, wxID_STATIC, _("Depart From"),
354  wxDefaultPosition, wxDefaultSize, 0);
355  itemBoxSizer2->Add(itemStaticText7, 0,
356  wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT,
357  5);
358 
359  m_tFrom = new wxTextCtrl(itemDialog1, wxID_ANY, _T(""), wxDefaultPosition,
360  wxSize(-1, -1), 0);
361  itemBoxSizer2->Add(m_tFrom, 0,
362  wxEXPAND | wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL |
363  wxLEFT | wxRIGHT | wxBOTTOM,
364  5);
365 
366  wxStaticText* itemStaticText8 =
367  new wxStaticText(itemDialog1, wxID_STATIC, _("Destination"),
368  wxDefaultPosition, wxDefaultSize, 0);
369  itemBoxSizer2->Add(itemStaticText8, 0,
370  wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT,
371  5);
372 
373  m_tTo = new wxTextCtrl(itemDialog1, wxID_ANY, _T(""), wxDefaultPosition,
374  wxSize(-1, -1), 0);
375  itemBoxSizer2->Add(m_tTo, 0,
376  wxEXPAND | wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL |
377  wxLEFT | wxRIGHT | wxBOTTOM,
378  5);
379 
380  m_cbShow = new wxCheckBox(itemDialog1, wxID_ANY, _("Show on chart"),
381  wxDefaultPosition, wxDefaultSize, 0);
382  itemBoxSizer2->Add(m_cbShow, 0, wxALL, 5);
383 
384  wxFlexGridSizer* itemFlexGridSizer6a = new wxFlexGridSizer(4, 2, 0, 0);
385  itemFlexGridSizer6a->AddGrowableCol(1, 0);
386 
387  itemBoxSizer2->Add(itemFlexGridSizer6a, 0, wxEXPAND | wxALIGN_LEFT | wxALL,
388  5);
389 
390  wxStaticText* itemStaticText11 =
391  new wxStaticText(itemDialog1, wxID_STATIC, _("Total distance"),
392  wxDefaultPosition, wxDefaultSize, 0);
393  itemFlexGridSizer6a->Add(
394  itemStaticText11, 0,
395  wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT | wxTOP, 5);
396 
397  m_tTotDistance =
398  new wxTextCtrl(itemDialog1, wxID_ANY, _T(""), wxDefaultPosition,
399  wxSize(-1, -1), wxTE_READONLY);
400  itemFlexGridSizer6a->Add(m_tTotDistance, 0,
401  wxEXPAND | wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL |
402  wxLEFT | wxRIGHT | wxBOTTOM,
403  5);
404 
405  m_stAvgSpeed = new wxStaticText(itemDialog1, wxID_STATIC, _("Avg. speed"),
406  wxDefaultPosition, wxDefaultSize, 0);
407  itemFlexGridSizer6a->Add(
408  m_stAvgSpeed, 0,
409  wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT | wxTOP, 5);
410 
411  m_tAvgSpeed = new wxTextCtrl(itemDialog1, wxID_ANY, _T(""), wxDefaultPosition,
412  wxSize(150, -1), wxTE_PROCESS_ENTER);
413  itemFlexGridSizer6a->Add(
414  m_tAvgSpeed, 0,
415  wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT | wxBOTTOM, 5);
416 
417  m_stTimeEnroute =
418  new wxStaticText(itemDialog1, wxID_STATIC, _("Time Enroute"),
419  wxDefaultPosition, wxDefaultSize, 0);
420  itemFlexGridSizer6a->Add(
421  m_stTimeEnroute, 0,
422  wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT | wxTOP, 5);
423 
424  m_tTimeEnroute =
425  new wxTextCtrl(itemDialog1, wxID_ANY, _T(""), wxDefaultPosition,
426  wxSize(-1, -1), wxTE_READONLY);
427  itemFlexGridSizer6a->Add(m_tTimeEnroute, 0,
428  wxEXPAND | wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL |
429  wxLEFT | wxRIGHT | wxBOTTOM,
430  5);
431 
432  /*
433  m_StartTimeLabel = new wxStaticText( itemDialog1, wxID_STATIC,
434  _("Departure Time"), wxDefaultPosition, wxDefaultSize, 0 );
435  itemFlexGridSizer6a->Add( m_StartTimeLabel, 0,
436  wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT | wxTOP,
437  5 );
438 
439  m_StartTimeCtl = new wxTextCtrl( itemDialog1, ID_STARTTIMECTL, _T(""),
440  wxDefaultPosition, wxSize( -1, -1 ), wxTE_PROCESS_ENTER );
441  itemFlexGridSizer6a->Add( m_StartTimeCtl, 0,
442  wxEXPAND | wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxLEFT |
443  wxRIGHT | wxBOTTOM, 5 );
444  */
445 
446  wxString pDispTimeZone[] = {_("UTC"), _("Local @ PC"), _("LMT @ Location")};
447 
448  wxStaticText* itemStaticText12b =
449  new wxStaticText(itemDialog1, wxID_STATIC, _("Time shown as"),
450  wxDefaultPosition, wxDefaultSize, 0);
451  itemBoxSizer2->Add(itemStaticText12b, 0, wxEXPAND | wxALL, 5);
452 
453  m_rbShowTimeUTC =
454  new wxRadioButton(itemDialog1, wxID_ANY, _("UTC"), wxDefaultPosition,
455  wxDefaultSize, wxRB_GROUP);
456  itemBoxSizer2->Add(
457  m_rbShowTimeUTC, 0,
458  wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT | wxBOTTOM, 5);
459 
460  m_rbShowTimePC = new wxRadioButton(itemDialog1, wxID_ANY, _("Local @ PC"));
461  itemBoxSizer2->Add(
462  m_rbShowTimePC, 0,
463  wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT | wxBOTTOM, 5);
464 
465  m_rbShowTimeLocal =
466  new wxRadioButton(itemDialog1, wxID_ANY, _("LMT @ Location"));
467  itemBoxSizer2->Add(
468  m_rbShowTimeLocal, 0,
469  wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT | wxBOTTOM, 5);
470 
471  wxFlexGridSizer* itemFlexGridSizer6b = new wxFlexGridSizer(3, 2, 0, 0);
472  itemBoxSizer2->Add(itemFlexGridSizer6b, 0, wxEXPAND | wxALIGN_LEFT | wxALL,
473  5);
474 
475  wxStaticText* m_staticText1 =
476  new wxStaticText(itemDialog1, wxID_ANY, _("Color") + _T(":"),
477  wxDefaultPosition, wxDefaultSize, 0);
478  itemFlexGridSizer6b->Add(m_staticText1, 0, wxALIGN_CENTER_VERTICAL | wxALL,
479  5);
480 
481  wxString m_chColorChoices[] = {
482  _("Default color"), _("Black"), _("Dark Red"), _("Dark Green"),
483  _("Dark Yellow"), _("Dark Blue"), _("Dark Magenta"), _("Dark Cyan"),
484  _("Light Gray"), _("Dark Gray"), _("Red"), _("Green"),
485  _("Yellow"), _("Blue"), _("Magenta"), _("Cyan"),
486  _("White")};
487  int m_chColorNChoices = sizeof(m_chColorChoices) / sizeof(wxString);
488  m_cColor =
489  new wxChoice(itemDialog1, wxID_ANY, wxDefaultPosition, wxSize(250, -1),
490  m_chColorNChoices, m_chColorChoices, 0);
491  m_cColor->SetSelection(0);
492  itemFlexGridSizer6b->Add(m_cColor, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
493 
494  wxStaticText* staticTextStyle =
495  new wxStaticText(itemDialog1, wxID_ANY, _("Style") + _T(":"),
496  wxDefaultPosition, wxDefaultSize, 0);
497  itemFlexGridSizer6b->Add(staticTextStyle, 0, wxALIGN_CENTER_VERTICAL | wxALL,
498  5);
499 
500  wxString m_chStyleChoices[] = {_("Default"), _("Solid"),
501  _("Dot"), _("Long dash"),
502  _("Short dash")};
503  int m_chStyleNChoices = sizeof(m_chStyleChoices) / sizeof(wxString);
504  m_cStyle =
505  new wxChoice(itemDialog1, wxID_ANY, wxDefaultPosition, wxDefaultSize,
506  m_chStyleNChoices, m_chStyleChoices, 0);
507  m_cStyle->SetSelection(0);
508  itemFlexGridSizer6b->Add(m_cStyle, 0,
509  wxEXPAND | wxALIGN_CENTER_VERTICAL | wxALL, 5);
510 
511 #ifdef ocpnUSE_GLES // linestipple is emulated poorly
512  staticTextStyle->Hide();
513  m_cStyle->Hide();
514 #endif
515 
516  m_stWidth = new wxStaticText(itemDialog1, wxID_ANY, _("Width") + _T(":"),
517  wxDefaultPosition, wxDefaultSize, 0);
518  itemFlexGridSizer6b->Add(m_stWidth, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
519 
520  wxString m_chWidthChoices[] = {_("Default"), _("1 pixel"), _("2 pixels"),
521  _("3 pixels"), _("4 pixels"), _("5 pixels"),
522  _("6 pixels"), _("7 pixels"), _("8 pixels"),
523  _("9 pixels"), _("10 pixels")};
524  int m_chWidthNChoices = sizeof(m_chWidthChoices) / sizeof(wxString);
525  m_cWidth =
526  new wxChoice(itemDialog1, wxID_ANY, wxDefaultPosition, wxSize(150, -1),
527  m_chWidthNChoices, m_chWidthChoices, 0);
528  m_cWidth->SetSelection(0);
529  itemFlexGridSizer6b->Add(m_cWidth, 0,
530  wxEXPAND | wxALIGN_CENTER_VERTICAL | wxALL, 5);
531 
532  wxStaticBox* itemStaticBoxSizer14Static =
533  new wxStaticBox(itemDialog1, wxID_ANY, _("Waypoints"));
534  wxStaticBoxSizer* m_pListSizer =
535  new wxStaticBoxSizer(itemStaticBoxSizer14Static, wxVERTICAL);
536  itemBoxSizer2->Add(m_pListSizer, 1, wxEXPAND | wxALL, 1);
537 
538  wxScrolledWindow* itemlistWin =
539  new wxScrolledWindow(itemDialog1, wxID_ANY, wxDefaultPosition,
540  wxDefaultSize, wxHSCROLL | wxVSCROLL);
541  itemlistWin->SetScrollRate(2, 2);
542 
543  m_pListSizer->Add(itemlistWin, 0, wxEXPAND | wxALL, 6);
544 
545  long flags = wxLC_REPORT | wxLC_HRULES | wxLC_VRULES | wxLC_EDIT_LABELS;
546 #ifndef __WXQT__ // Does not support Virtual list boxes....
547  flags |= wxLC_VIRTUAL;
548 #endif
549 
550  m_lcPoints = new OCPNTrackListCtrl(itemlistWin, wxID_ANY, wxDefaultPosition,
551  wxSize(100, 500), flags);
552  addColumns(m_lcPoints, GetCharWidth());
553 
554  // sbSizerPoints->Add( m_lcPoints, 1, wxALL|wxEXPAND, 5 );
555 
556 #ifdef __ANDROID__
557  m_lcPoints->GetHandle()->setStyleSheet(getQtStyleSheet());
558 #endif
559 
560  // Buttons, etc...
561 
562  wxBoxSizer* itemBoxSizerBottom = new wxBoxSizer(wxVERTICAL);
563  itemBoxSizer1->Add(itemBoxSizerBottom, 0, wxALIGN_LEFT | wxALL | wxEXPAND, 5);
564 
565  int n_col = 3;
566 
567  wxFlexGridSizer* itemBoxSizerAux = new wxFlexGridSizer(0, n_col, 0, 0);
568  itemBoxSizerAux->SetFlexibleDirection(wxBOTH);
569  itemBoxSizerAux->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_SPECIFIED);
570 
571  itemBoxSizerBottom->Add(itemBoxSizerAux, 1, wxALIGN_LEFT | wxALL, 5);
572 
573 #ifndef __ANDROID__
574 
575  m_sdbBtmBtnsSizerPrint = new wxButton(this, wxID_ANY, _("Print"),
576  wxDefaultPosition, wxDefaultSize, 0);
577  itemBoxSizerAux->Add(m_sdbBtmBtnsSizerPrint, 0,
578  wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 5);
579  m_sdbBtmBtnsSizerPrint->Enable(true);
580 #else
581  m_sdbBtmBtnsSizerPrint = NULL;
582 #endif
583 
584  m_sdbBtmBtnsSizerSplit = new wxButton(this, wxID_ANY, _("Split"),
585  wxDefaultPosition, wxDefaultSize, 0);
586  itemBoxSizerAux->Add(m_sdbBtmBtnsSizerSplit, 0,
587  wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 5);
588  m_sdbBtmBtnsSizerSplit->Enable(false);
589 
590  m_sdbBtmBtnsSizerExtend = new wxButton(this, wxID_ANY, _("Extend"),
591  wxDefaultPosition, wxDefaultSize, 0);
592  itemBoxSizerAux->Add(m_sdbBtmBtnsSizerExtend, 0,
593  wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 5);
594 
595  m_sdbBtmBtnsSizerToRoute = new wxButton(this, wxID_ANY, _("To route"),
596  wxDefaultPosition, wxDefaultSize, 0);
597  itemBoxSizerAux->Add(m_sdbBtmBtnsSizerToRoute, 0,
598  wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 5);
599 
600  m_sdbBtmBtnsSizerExport = NULL;
601  // m_sdbBtmBtnsSizerExport = new wxButton( this, wxID_ANY, _("Export"),
602  // wxDefaultPosition, wxDefaultSize, 0 ); itemBoxSizerAux->Add(
603  // m_sdbBtmBtnsSizerExport, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL |
604  // wxALL, 5 );
605 
606  wxBoxSizer* itemBoxSizer16 = new wxBoxSizer(wxHORIZONTAL);
607  itemBoxSizerBottom->Add(itemBoxSizer16, 0, wxALIGN_RIGHT | wxALL, 5);
608 
609  m_sdbBtmBtnsSizerCancel = new wxButton(this, wxID_CANCEL, _("Cancel"),
610  wxDefaultPosition, wxDefaultSize, 0);
611  itemBoxSizer16->Add(m_sdbBtmBtnsSizerCancel, 0,
612  wxALIGN_RIGHT | wxALIGN_BOTTOM | wxALL, 5);
613 
614  m_sdbBtmBtnsSizerOK =
615  new wxButton(this, wxID_OK, _("OK"), wxDefaultPosition, wxDefaultSize, 0);
616  itemBoxSizer16->Add(m_sdbBtmBtnsSizerOK, 0,
617  wxALIGN_RIGHT | wxALIGN_BOTTOM | wxALL, 5);
618  m_sdbBtmBtnsSizerOK->SetDefault();
619 
620  int char_size = GetCharWidth();
621  // Set the maximum size of the entire dialog
622  int width, height;
623  width = g_monitor_info[g_current_monitor].width;
624  height = g_monitor_info[g_current_monitor].height;
625  SetSizeHints(-1, -1, width - 100, height - 100);
626 }
627 
628 void TrackPropDlg::CreateControls(void) {
629  wxBoxSizer* bSizerMain;
630  bSizerMain = new wxBoxSizer(wxVERTICAL);
631  SetSizer(bSizerMain);
632 
633  m_notebook1 =
634  new wxNotebook(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0);
635 
636  bSizerMain->Add(m_notebook1, 1, wxEXPAND | wxALL, 5);
637 
638  wxPanel* m_panel0 =
639  new wxPanel(m_notebook1, wxID_ANY, wxDefaultPosition, wxDefaultSize);
640  m_notebook1->AddPage(m_panel0, _("Basic"), true);
641 
642  wxBoxSizer* bSizer0 = new wxBoxSizer(wxVERTICAL);
643  m_panel0->SetSizer(bSizer0);
644 
645  wxBoxSizer* bSizer1 = new wxBoxSizer(wxVERTICAL);
646  bSizer0->Add(bSizer1, 1, wxEXPAND | wxALL, 5);
647 
648  m_panelBasic = new wxScrolledWindow(m_panel0, wxID_ANY, wxDefaultPosition,
649  wxSize(-1, -1),
650  wxHSCROLL | wxVSCROLL | wxTAB_TRAVERSAL);
651 
652 #ifdef __ANDROID__
653  // Set Dialog Font by custom crafted Qt Stylesheet.
654  wxFont* qFont = GetOCPNScaledFont(_("Dialog"));
655 
656  wxString wqs = getFontQtStylesheet(qFont);
657  wxCharBuffer sbuf = wqs.ToUTF8();
658  QString qsb = QString(sbuf.data());
659 
660  QString qsbq = getQtStyleSheet(); // basic scrollbars, etc
661 
662  m_panelBasic->GetHandle()->setStyleSheet(qsb +
663  qsbq); // Concatenated style sheets
664 
665 #endif
666 
667  //#ifdef __ANDROID__
668  // m_panelBasic->GetHandle()->setStyleSheet( getQtStyleSheet());
669  //#endif
670 
671  wxBoxSizer* bSizerBasic = new wxBoxSizer(wxVERTICAL);
672  m_panelBasic->SetSizer(bSizerBasic);
673 
674  bSizer1->Add(m_panelBasic, 1, wxEXPAND | wxALL, 5);
675 
676  wxBoxSizer* bSizerName;
677  bSizerName = new wxBoxSizer(wxHORIZONTAL);
678  bSizerBasic->Add(bSizerName, 0, wxALL | wxEXPAND, 5);
679 
680  m_stName = new wxStaticText(m_panelBasic, wxID_ANY, _("Name"),
681  wxDefaultPosition, wxDefaultSize, 0);
682  // m_stName->Wrap( -1 );
683  bSizerName->Add(m_stName, 0, wxALL, 5);
684 
685  m_tName = new wxTextCtrl(m_panelBasic, wxID_ANY, wxEmptyString,
686  wxDefaultPosition, wxDefaultSize, 0);
687  bSizerName->Add(m_tName, 1, 0, 5);
688 
689  wxBoxSizer* bSizerFromTo;
690  bSizerFromTo = new wxBoxSizer(wxHORIZONTAL);
691  bSizerBasic->Add(bSizerFromTo, 0, wxALL | wxEXPAND, 5);
692 
693  m_stFrom = new wxStaticText(m_panelBasic, wxID_ANY, _("From"),
694  wxDefaultPosition, wxDefaultSize, 0);
695  // m_stFrom->Wrap( -1 );
696  bSizerFromTo->Add(m_stFrom, 0, wxALL, 5);
697 
698  m_tFrom = new wxTextCtrl(m_panelBasic, wxID_ANY, wxEmptyString,
699  wxDefaultPosition, wxDefaultSize, 0);
700  bSizerFromTo->Add(m_tFrom, 1, 0, 5);
701 
702  m_stTo = new wxStaticText(m_panelBasic, wxID_ANY, _("To"), wxDefaultPosition,
703  wxDefaultSize, 0);
704  // m_stTo->Wrap( -1 );
705  bSizerFromTo->Add(m_stTo, 0, wxALL, 5);
706 
707  m_tTo = new wxTextCtrl(m_panelBasic, wxID_ANY, wxEmptyString,
708  wxDefaultPosition, wxDefaultSize, 0);
709  bSizerFromTo->Add(m_tTo, 1, 0, 5);
710 
711  wxStaticBoxSizer* sbSizerParams;
712  sbSizerParams = new wxStaticBoxSizer(
713  new wxStaticBox(m_panelBasic, wxID_ANY, _("Display parameters")),
714  wxHORIZONTAL);
715  bSizerBasic->Add(sbSizerParams, 0, wxALL | wxEXPAND, 5);
716 
717  m_cbShow = new wxCheckBox(m_panelBasic, wxID_ANY, _("Show on chart"),
718  wxDefaultPosition, wxDefaultSize, 0);
719  sbSizerParams->Add(m_cbShow, 0, wxALL, 5);
720 
721  m_stColor = new wxStaticText(m_panelBasic, wxID_ANY, _("Color"),
722  wxDefaultPosition, wxDefaultSize, 0);
723  // m_stColor->Wrap( -1 );
724  sbSizerParams->Add(m_stColor, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
725 
726  wxString m_cColorChoices[] = {
727  _("Default color"), _("Black"), _("Dark Red"), _("Dark Green"),
728  _("Dark Yellow"), _("Dark Blue"), _("Dark Magenta"), _("Dark Cyan"),
729  _("Light Gray"), _("Dark Gray"), _("Red"), _("Green"),
730  _("Yellow"), _("Blue"), _("Magenta"), _("Cyan"),
731  _("White")};
732  int m_cColorNChoices = sizeof(m_cColorChoices) / sizeof(wxString);
733  m_cColor = new wxChoice(m_panelBasic, wxID_ANY, wxDefaultPosition,
734  wxDefaultSize, m_cColorNChoices, m_cColorChoices, 0);
735  m_cColor->SetSelection(0);
736  sbSizerParams->Add(m_cColor, 1, 0, 5);
737 
738  m_stStyle = new wxStaticText(m_panelBasic, wxID_ANY, _("Style"),
739  wxDefaultPosition, wxDefaultSize, 0);
740  // m_stStyle->Wrap( -1 );
741  sbSizerParams->Add(m_stStyle, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
742 
743  wxString m_cStyleChoices[] = {_("Default"), _("Solid"), _("Dot"),
744  _("Long dash"), _("Short dash")};
745  int m_cStyleNChoices = sizeof(m_cStyleChoices) / sizeof(wxString);
746  m_cStyle = new wxChoice(m_panelBasic, wxID_ANY, wxDefaultPosition,
747  wxDefaultSize, m_cStyleNChoices, m_cStyleChoices, 0);
748  m_cStyle->SetSelection(0);
749  sbSizerParams->Add(m_cStyle, 1, 0, 5);
750 
751  m_stWidth = new wxStaticText(m_panelBasic, wxID_ANY, _("Width"),
752  wxDefaultPosition, wxDefaultSize, 0);
753  // m_stWidth->Wrap( -1 );
754  sbSizerParams->Add(m_stWidth, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
755 
756  wxString m_cWidthChoices[] = {_("Default"), _("1 pixel"), _("2 pixels"),
757  _("3 pixels"), _("4 pixels"), _("5 pixels"),
758  _("6 pixels"), _("7 pixels"), _("8 pixels"),
759  _("9 pixels"), _("10 pixels")};
760  int m_cWidthNChoices = sizeof(m_cWidthChoices) / sizeof(wxString);
761  m_cWidth = new wxChoice(m_panelBasic, wxID_ANY, wxDefaultPosition,
762  wxDefaultSize, m_cWidthNChoices, m_cWidthChoices, 0);
763  m_cWidth->SetSelection(0);
764  sbSizerParams->Add(m_cWidth, 1, 0, 5);
765 
766  wxStaticBoxSizer* sbSizerStats;
767  sbSizerStats = new wxStaticBoxSizer(
768  new wxStaticBox(m_panelBasic, wxID_ANY, _("Statistics")), wxVERTICAL);
769  bSizerBasic->Add(sbSizerStats, 0, wxALL | wxEXPAND, 5);
770 
771  wxBoxSizer* bSizerStats;
772  bSizerStats = new wxBoxSizer(wxHORIZONTAL);
773 
774  m_stTotDistance =
775  new wxStaticText(m_panelBasic, wxID_ANY, _("Total distance"),
776  wxDefaultPosition, wxDefaultSize, 0);
777  // m_stTotDistance->Wrap( -1 );
778  bSizerStats->Add(m_stTotDistance, 0, wxALL, 5);
779 
780  m_tTotDistance =
781  new wxTextCtrl(m_panelBasic, wxID_ANY, wxEmptyString, wxDefaultPosition,
782  wxDefaultSize, wxTE_READONLY);
783  bSizerStats->Add(m_tTotDistance, 1, 0, 5);
784 
785  m_stAvgSpeed = new wxStaticText(m_panelBasic, wxID_ANY, _("Avg. speed"),
786  wxDefaultPosition, wxDefaultSize, 0);
787  // m_stAvgSpeed->Wrap( -1 );
788  bSizerStats->Add(m_stAvgSpeed, 0, wxALL, 5);
789 
790  m_tAvgSpeed = new wxTextCtrl(m_panelBasic, wxID_ANY, wxEmptyString,
791  wxDefaultPosition, wxDefaultSize, wxTE_READONLY);
792  bSizerStats->Add(m_tAvgSpeed, 1, 0, 5);
793 
794  m_stTimeEnroute = new wxStaticText(m_panelBasic, wxID_ANY, _("Time enroute"),
795  wxDefaultPosition, wxDefaultSize, 0);
796  // m_stTimeEnroute->Wrap( -1 );
797  bSizerStats->Add(m_stTimeEnroute, 0, wxALL, 5);
798 
799  m_tTimeEnroute =
800  new wxTextCtrl(m_panelBasic, wxID_ANY, wxEmptyString, wxDefaultPosition,
801  wxDefaultSize, wxTE_READONLY);
802  bSizerStats->Add(m_tTimeEnroute, 2, 0, 5);
803 
804  sbSizerStats->Add(bSizerStats, 0, wxEXPAND, 5);
805 
806  wxStaticBoxSizer* sbSizerPoints;
807  sbSizerPoints = new wxStaticBoxSizer(
808  new wxStaticBox(m_panel0, wxID_ANY, _("Recorded points")), wxVERTICAL);
809  bSizer1->Add(sbSizerPoints, 1, wxALL | wxEXPAND, 5);
810 
811  wxBoxSizer* bSizerShowTime;
812  bSizerShowTime = new wxBoxSizer(wxHORIZONTAL);
813 
814  m_stShowTime = new wxStaticText(m_panel0, wxID_ANY, _("Time shown as"),
815  wxDefaultPosition, wxDefaultSize, 0);
816  // m_stShowTime->Wrap( -1 );
817  bSizerShowTime->Add(m_stShowTime, 0, wxALL, 5);
818 
819  m_rbShowTimeUTC = new wxRadioButton(m_panel0, wxID_ANY, _("UTC"),
820  wxDefaultPosition, wxDefaultSize, 0);
821  bSizerShowTime->Add(m_rbShowTimeUTC, 0,
822  wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT, 5);
823 
824  m_rbShowTimePC = new wxRadioButton(m_panel0, wxID_ANY, _("Local @ PC"),
825  wxDefaultPosition, wxDefaultSize, 0);
826  bSizerShowTime->Add(m_rbShowTimePC, 0,
827  wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT, 5);
828 
829  m_rbShowTimeLocal =
830  new wxRadioButton(m_panel0, wxID_ANY, _("LMT @ Track Start"),
831  wxDefaultPosition, wxDefaultSize, 0);
832  bSizerShowTime->Add(m_rbShowTimeLocal, 0,
833  wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT, 5);
834 
835  m_rbShowTimePC->SetValue(true);
836 
837  sbSizerPoints->Add(bSizerShowTime, 0, wxEXPAND, 5);
838 
839  long flags = wxLC_REPORT | wxLC_HRULES | wxLC_VRULES | wxLC_EDIT_LABELS;
840 #ifndef __WXQT__ // Does not support Virtual list boxes....
841  flags |= wxLC_VIRTUAL;
842 #endif
843 
844  m_lcPoints = new OCPNTrackListCtrl(m_panel0, wxID_ANY, wxDefaultPosition,
845  wxDefaultSize, flags);
846  addColumns(m_lcPoints, GetCharWidth());
847 
848  sbSizerPoints->Add(m_lcPoints, 1, wxALL | wxEXPAND, 5);
849 
850 #ifdef __ANDROID__
851  m_lcPoints->GetHandle()->setStyleSheet(getQtStyleSheet());
852 #endif
853 
854  // m_lcPoints = new OCPNTrackListCtrl( m_panel0, wxID_ANY,
855  // wxDefaultPosition, wxDefaultSize,
856  // wxLC_REPORT | wxLC_HRULES |
857  // wxLC_VRULES | wxLC_EDIT_LABELS |
858  // wxLC_VIRTUAL );
859  //
860  // m_lcPoints->Hide();
861  // m_rbShowTimeUTC = NULL;
862  // m_rbShowTimePC = NULL;
863  // m_rbShowTimeLocal = NULL;
864 
865  m_panelAdvanced = new wxScrolledWindow(
866  m_notebook1, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL);
867 
868  wxBoxSizer* bSizerAdvanced;
869  bSizerAdvanced = new wxBoxSizer(wxVERTICAL);
870 
871  m_stDescription =
872  new wxStaticText(m_panelAdvanced, wxID_ANY, _("Description"),
873  wxDefaultPosition, wxDefaultSize, 0);
874  // m_stDescription->Wrap( -1 );
875  bSizerAdvanced->Add(m_stDescription, 0, wxALL, 5);
876 
877  m_tDescription =
878  new wxTextCtrl(m_panelAdvanced, wxID_ANY, wxEmptyString,
879  wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE);
880  bSizerAdvanced->Add(m_tDescription, 1, wxALL | wxEXPAND, 5);
881 
882  sbSizerLinks = new wxStaticBoxSizer(
883  new wxStaticBox(m_panelAdvanced, wxID_ANY, _("Links")), wxVERTICAL);
884 
885  m_scrolledWindowLinks =
886  new wxScrolledWindow(m_panelAdvanced, wxID_ANY, wxDefaultPosition,
887  wxDefaultSize, wxHSCROLL | wxVSCROLL);
888  m_scrolledWindowLinks->SetScrollRate(5, 5);
889  bSizerLinks = new wxBoxSizer(wxVERTICAL);
890 
891  m_hyperlink1 =
892  new wxHyperlinkCtrl(m_scrolledWindowLinks, wxID_ANY, _("wxFB Website"),
893  wxT("http://www.wxformbuilder.org"),
894  wxDefaultPosition, wxDefaultSize, wxHL_DEFAULT_STYLE);
895  m_menuLink = new wxMenu();
896  m_menuItemEdit =
897  new wxMenuItem(m_menuLink, ID_TRK_MENU_EDIT, wxString(_("Edit")),
898  wxEmptyString, wxITEM_NORMAL);
899  m_menuLink->Append(m_menuItemEdit);
900 
901  m_menuItemAdd =
902  new wxMenuItem(m_menuLink, ID_TRK_MENU_ADD, wxString(_("Add new")),
903  wxEmptyString, wxITEM_NORMAL);
904  m_menuLink->Append(m_menuItemAdd);
905 
906  m_menuItemDelete =
907  new wxMenuItem(m_menuLink, ID_TRK_MENU_DELETE, wxString(_("Delete")),
908  wxEmptyString, wxITEM_NORMAL);
909  m_menuLink->Append(m_menuItemDelete);
910 
911  m_hyperlink1->Connect(
912  wxEVT_RIGHT_DOWN,
913  wxMouseEventHandler(TrackPropDlg::m_hyperlink1OnContextMenu), NULL, this);
914 
915  bSizerLinks->Add(m_hyperlink1, 0, wxALL, 5);
916 
917  m_scrolledWindowLinks->SetSizer(bSizerLinks);
918  m_scrolledWindowLinks->Layout();
919  bSizerLinks->Fit(m_scrolledWindowLinks);
920  sbSizerLinks->Add(m_scrolledWindowLinks, 1, wxEXPAND | wxALL, 5);
921 
922  wxBoxSizer* bSizerLinkBtns;
923  bSizerLinkBtns = new wxBoxSizer(wxHORIZONTAL);
924 
925  m_buttonAddLink =
926  new wxButton(m_panelAdvanced, wxID_ANY, _("Add"), wxDefaultPosition,
927  wxDefaultSize, wxBU_EXACTFIT);
928  bSizerLinkBtns->Add(m_buttonAddLink, 0, wxALL, 5);
929 
930  m_toggleBtnEdit = new wxToggleButton(m_panelAdvanced, wxID_ANY, _("Edit"),
931  wxDefaultPosition, wxDefaultSize, 0);
932  bSizerLinkBtns->Add(m_toggleBtnEdit, 0, wxALL, 5);
933 
934  m_staticTextEditEnabled = new wxStaticText(
935  m_panelAdvanced, wxID_ANY, _("Links are opened in the default browser."),
936  wxDefaultPosition, wxDefaultSize, 0);
937  // m_staticTextEditEnabled->Wrap( -1 );
938  bSizerLinkBtns->Add(m_staticTextEditEnabled, 0,
939  wxALIGN_CENTER_VERTICAL | wxALL, 5);
940 
941  sbSizerLinks->Add(bSizerLinkBtns, 0, wxEXPAND, 5);
942 
943  bSizerAdvanced->Add(sbSizerLinks, 1, wxEXPAND, 5);
944 
945  m_panelAdvanced->SetSizer(bSizerAdvanced);
946  m_notebook1->AddPage(m_panelAdvanced, _("Advanced"), false);
947 
948  // Buttons, etc...
949 
950  wxBoxSizer* itemBoxSizerBottom = new wxBoxSizer(wxVERTICAL);
951  bSizerMain->Add(itemBoxSizerBottom, 0, wxALIGN_LEFT | wxALL | wxEXPAND, 5);
952 
953  // wxBoxSizer* itemBoxSizerAux = new wxBoxSizer( wxHORIZONTAL );
954 
955  int n_col = 5;
956 
957  wxFlexGridSizer* itemBoxSizerAux = new wxFlexGridSizer(0, n_col, 0, 0);
958  itemBoxSizerAux->SetFlexibleDirection(wxBOTH);
959  itemBoxSizerAux->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_SPECIFIED);
960 
961  itemBoxSizerBottom->Add(itemBoxSizerAux, 1, wxALIGN_LEFT | wxALL, 5);
962 
963 #ifndef __ANDROID__
964 
965  m_sdbBtmBtnsSizerPrint = new wxButton(this, wxID_ANY, _("Print"),
966  wxDefaultPosition, wxDefaultSize, 0);
967  itemBoxSizerAux->Add(m_sdbBtmBtnsSizerPrint, 0,
968  wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 5);
969  m_sdbBtmBtnsSizerPrint->Enable(true);
970 #else
971  m_sdbBtmBtnsSizerPrint = NULL;
972 #endif
973 
974  m_sdbBtmBtnsSizerSplit = new wxButton(this, wxID_ANY, _("Split"),
975  wxDefaultPosition, wxDefaultSize, 0);
976  itemBoxSizerAux->Add(m_sdbBtmBtnsSizerSplit, 0,
977  wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 5);
978  m_sdbBtmBtnsSizerSplit->Enable(false);
979 
980  m_sdbBtmBtnsSizerExtend = new wxButton(this, wxID_ANY, _("Extend track"),
981  wxDefaultPosition, wxDefaultSize, 0);
982  itemBoxSizerAux->Add(m_sdbBtmBtnsSizerExtend, 0,
983  wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 5);
984 
985  m_sdbBtmBtnsSizerToRoute = new wxButton(this, wxID_ANY, _("To route"),
986  wxDefaultPosition, wxDefaultSize, 0);
987  itemBoxSizerAux->Add(m_sdbBtmBtnsSizerToRoute, 0,
988  wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 5);
989 
990  m_sdbBtmBtnsSizerExport = new wxButton(this, wxID_ANY, _("Export"),
991  wxDefaultPosition, wxDefaultSize, 0);
992  itemBoxSizerAux->Add(m_sdbBtmBtnsSizerExport, 0,
993  wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 5);
994 
995  wxBoxSizer* itemBoxSizer16 = new wxBoxSizer(wxHORIZONTAL);
996  itemBoxSizerBottom->Add(itemBoxSizer16, 0, wxALIGN_RIGHT | wxALL, 5);
997 
998  m_sdbBtmBtnsSizerCancel = new wxButton(this, wxID_CANCEL, _("Cancel"),
999  wxDefaultPosition, wxDefaultSize, 0);
1000  itemBoxSizer16->Add(m_sdbBtmBtnsSizerCancel, 0, wxALIGN_BOTTOM | wxALL, 5);
1001 
1002  m_sdbBtmBtnsSizerOK =
1003  new wxButton(this, wxID_OK, _("OK"), wxDefaultPosition, wxDefaultSize, 0);
1004  itemBoxSizer16->Add(m_sdbBtmBtnsSizerOK, 0, wxALIGN_BOTTOM | wxALL, 5);
1005  m_sdbBtmBtnsSizerOK->SetDefault();
1006 
1007  // Make it look nice and add the needed non-standard buttons
1008  int w1, w2, h;
1009  ((wxWindowBase*)m_stName)->GetSize(&w1, &h);
1010  ((wxWindowBase*)m_stFrom)->GetSize(&w2, &h);
1011  ((wxWindowBase*)m_stName)->SetMinSize(wxSize(wxMax(w1, w2), h));
1012  ((wxWindowBase*)m_stFrom)->SetMinSize(wxSize(wxMax(w1, w2), h));
1013 
1014  m_panelBasic->SetScrollRate(5, 5);
1015  m_panelAdvanced->SetScrollRate(5, 5);
1016 }
1017 
1018 void TrackPropDlg::SetTrackAndUpdate(Track* pt) {
1019  m_pTrack = pt;
1020 
1021  m_lcPoints->DeleteAllItems();
1022 
1023  if (m_pMyLinkList) delete m_pMyLinkList;
1024  m_pMyLinkList = new HyperlinkList();
1025 
1026  int NbrOfLinks = m_pTrack->m_HyperlinkList->GetCount();
1027  if (NbrOfLinks > 0) {
1028  wxHyperlinkListNode* linknode = m_pTrack->m_HyperlinkList->GetFirst();
1029  while (linknode) {
1030  Hyperlink* link = linknode->GetData();
1031 
1032  Hyperlink* h = new Hyperlink();
1033  h->DescrText = link->DescrText;
1034  h->Link = link->Link;
1035  h->LType = link->LType;
1036 
1037  m_pMyLinkList->Append(h);
1038 
1039  linknode = linknode->GetNext();
1040  }
1041  }
1042 
1043  InitializeList();
1044  UpdateProperties();
1045 
1046  RecalculateSize();
1047 }
1048 
1049 void TrackPropDlg::InitializeList() {
1050  if (NULL == m_pTrack) return;
1051 
1052  m_lcPoints->m_pTrack = m_pTrack;
1053 
1054  if (m_pTrack->GetnPoints()) {
1055  TrackPoint* prp = m_pTrack->GetPoint(0);
1056  if (prp)
1057  m_lcPoints->m_LMT_Offset = long((prp->m_lon) * 3600. / 15.); // estimated
1058  else
1059  m_lcPoints->m_LMT_Offset = 0;
1060  }
1061 
1062  if (m_lcPoints->IsVirtual())
1063  m_lcPoints->SetItemCount(m_pTrack->GetnPoints());
1064 
1065  else {
1066  for (int in = 0; in < m_pTrack->GetnPoints(); in++) {
1067  wxListItem item;
1068  item.SetId(in);
1069 
1070  m_lcPoints->InsertItem(item);
1071  for (int j = 0; j < 7; j++) {
1072  item.SetColumn(j);
1073  item.SetText(m_lcPoints->OnGetItemText(in, j));
1074  m_lcPoints->SetItem(item);
1075  }
1076  }
1077  }
1078 }
1079 
1081  if (NULL == m_pTrack) return false;
1082 
1083  ::wxBeginBusyCursor();
1084 
1085  if (m_scrolledWindowLinks) {
1086  wxWindowList kids = m_scrolledWindowLinks->GetChildren();
1087  for (unsigned int i = 0; i < kids.GetCount(); i++) {
1088  wxWindowListNode* node = kids.Item(i);
1089  wxWindow* win = node->GetData();
1090 
1091  if (win->IsKindOf(CLASSINFO(wxHyperlinkCtrl))) {
1092  ((wxHyperlinkCtrl*)win)
1093  ->Disconnect(
1094  wxEVT_COMMAND_HYPERLINK,
1095  wxHyperlinkEventHandler(TrackPropDlg::OnHyperLinkClick));
1096  ((wxHyperlinkCtrl*)win)
1097  ->Disconnect(
1098  wxEVT_RIGHT_DOWN,
1099  wxMouseEventHandler(TrackPropDlg::m_hyperlinkContextMenu));
1100  win->Destroy();
1101  }
1102  }
1104  int NbrOfLinks = m_pTrack->m_HyperlinkList->GetCount();
1105  HyperlinkList* hyperlinklist = m_pTrack->m_HyperlinkList;
1106  // int len = 0;
1107  if (NbrOfLinks > 0) {
1108  wxHyperlinkListNode* linknode = hyperlinklist->GetFirst();
1109  while (linknode) {
1110  Hyperlink* link = linknode->GetData();
1111  wxString Link = link->Link;
1112  wxString Descr = link->DescrText;
1113 
1114  wxHyperlinkCtrl* ctrl = new wxHyperlinkCtrl(
1115  m_scrolledWindowLinks, wxID_ANY, Descr, Link, wxDefaultPosition,
1116  wxDefaultSize, wxHL_DEFAULT_STYLE);
1117  ctrl->Connect(wxEVT_COMMAND_HYPERLINK,
1118  wxHyperlinkEventHandler(TrackPropDlg::OnHyperLinkClick),
1119  NULL, this);
1120  if (!m_pTrack->m_bIsInLayer)
1121  ctrl->Connect(
1122  wxEVT_RIGHT_DOWN,
1123  wxMouseEventHandler(TrackPropDlg::m_hyperlinkContextMenu), NULL,
1124  this);
1125 
1126  bSizerLinks->Add(ctrl, 0, wxALL, 5);
1127 
1128  linknode = linknode->GetNext();
1129  }
1130  }
1131  bSizerLinks->Fit(m_scrolledWindowLinks);
1132  }
1133 
1134  m_tName->SetValue(m_pTrack->GetName());
1135  m_tFrom->SetValue(m_pTrack->m_TrackStartString);
1136  m_tTo->SetValue(m_pTrack->m_TrackEndString);
1137  if (m_tDescription) m_tDescription->SetValue(m_pTrack->m_TrackDescription);
1138 
1139  m_tTotDistance->SetValue(_T(""));
1140  m_tTimeEnroute->SetValue(_T(""));
1141 
1142  m_sdbBtmBtnsSizerSplit->Enable(false);
1143  m_sdbBtmBtnsSizerExtend->Enable(false);
1144 
1145  // Calculate AVG speed if we are showing a track and total time
1146  TrackPoint* last_point = m_pTrack->GetLastPoint();
1147  TrackPoint* first_point = m_pTrack->GetPoint(0);
1148  double trackLength = m_pTrack->Length();
1149  double total_seconds = 0.;
1150 
1151  wxString speed(_T("--"));
1152 
1153  if (last_point && first_point) {
1154  if (last_point->GetCreateTime().IsValid() &&
1155  first_point->GetCreateTime().IsValid()) {
1156  total_seconds = last_point->GetCreateTime()
1157  .Subtract(first_point->GetCreateTime())
1158  .GetSeconds()
1159  .ToDouble();
1160  if (total_seconds != 0.) {
1161  m_avgspeed = trackLength / total_seconds * 3600;
1162  } else {
1163  m_avgspeed = 0;
1164  }
1165  speed.Printf(_T("%5.2f"), toUsrSpeed(m_avgspeed));
1166  }
1167  }
1168 
1169  m_tAvgSpeed->SetValue(speed);
1170 
1171  // Total length
1172  wxString slen;
1173  slen.Printf(wxT("%5.2f ") + getUsrDistanceUnit(), toUsrDistance(trackLength));
1174 
1175  m_tTotDistance->SetValue(slen);
1176 
1177  // Time
1178  wxString time_form;
1179  wxTimeSpan time(0, 0, (int)total_seconds, 0);
1180  //TODO Construct a readable time string, e.g. "xx Days, 15:34"
1181  if (total_seconds > 3600. * 24.)
1182  time_form = time.Format("%H:%M");
1183  else if (total_seconds > 0.)
1184  time_form = time.Format("%H:%M");
1185  else
1186  time_form = _T("--");
1187  m_tTimeEnroute->SetValue(time_form);
1188 
1189  m_cbShow->SetValue(m_pTrack->IsVisible());
1190 
1191  if (m_pTrack->m_Colour == wxEmptyString)
1192  m_cColor->Select(0);
1193  else {
1194  for (unsigned int i = 0; i < sizeof(::GpxxColorNames) / sizeof(wxString);
1195  i++) {
1196  if (m_pTrack->m_Colour == ::GpxxColorNames[i]) {
1197  m_cColor->Select(i + 1);
1198  break;
1199  }
1200  }
1201  }
1202 
1203  for (unsigned int i = 0; i < sizeof(::StyleValues) / sizeof(int); i++) {
1204  if (m_pTrack->m_style == ::StyleValues[i]) {
1205  m_cStyle->Select(i);
1206  break;
1207  }
1208  }
1209 
1210  for (unsigned int i = 0; i < sizeof(::WidthValues) / sizeof(int); i++) {
1211  if (m_pTrack->m_width == ::WidthValues[i]) {
1212  m_cWidth->Select(i);
1213  break;
1214  }
1215  }
1216 
1217  if (m_pTrack->m_bIsInLayer) {
1218  m_tName->SetEditable(false);
1219  m_tFrom->SetEditable(false);
1220  m_tTo->SetEditable(false);
1221  if (m_tDescription) m_tDescription->SetEditable(false);
1222  m_cbShow->Enable(false);
1223  m_cColor->Enable(false);
1224  m_cStyle->Enable(false);
1225  m_cWidth->Enable(false);
1226  m_sdbBtmBtnsSizerExtend->Enable(false);
1227  m_sdbBtmBtnsSizerSplit->Enable(false);
1228  SetTitle(wxString::Format(_T("%s, %s: %d"), _("Track properties"),
1229  _T("Layer"), m_pTrack->m_LayerID));
1230  } else {
1231  m_tName->SetEditable(true);
1232  m_tFrom->SetEditable(true);
1233  m_tTo->SetEditable(true);
1234  if (m_tDescription) m_tDescription->SetEditable(true);
1235  m_cbShow->Enable(true);
1236  m_cColor->Enable(true);
1237  m_cStyle->Enable(true);
1238  m_cWidth->Enable(true);
1239 
1240  m_sdbBtmBtnsSizerExtend->Enable(IsThisTrackExtendable());
1241  // m_sdbBtmBtnsSizerSplit->Enable( false );
1242  SetTitle(_("Track properties"));
1243  }
1244 
1245  ::wxEndBusyCursor();
1246 
1247  return true;
1248 }
1249 
1250 bool TrackPropDlg::IsThisTrackExtendable() {
1251  m_pExtendTrack = NULL;
1252  m_pExtendPoint = NULL;
1253  if (m_pTrack == g_pActiveTrack || m_pTrack->m_bIsInLayer) {
1254  return false;
1255  }
1256 
1257  TrackPoint* pLastPoint = m_pTrack->GetPoint(0);
1258  if (!pLastPoint->GetCreateTime().IsValid()) {
1259  return false;
1260  }
1261 
1262  for (Track* ptrack : g_TrackList) {
1263  if (ptrack->IsVisible() && (ptrack->m_GUID != m_pTrack->m_GUID)) {
1264  TrackPoint* track_node = ptrack->GetLastPoint();
1265  if (track_node) {
1266  if (track_node->GetCreateTime().IsValid()) {
1267  if (track_node->GetCreateTime() <= pLastPoint->GetCreateTime()) {
1268  if (!m_pExtendPoint ||
1269  track_node->GetCreateTime() > m_pExtendPoint->GetCreateTime()) {
1270  m_pExtendPoint = track_node;
1271  m_pExtendTrack = ptrack;
1272  }
1273  }
1274  }
1275  }
1276  }
1277  }
1278  if (m_pExtendTrack) {
1279  return (!m_pExtendTrack->m_bIsInLayer);
1280  } else {
1281  return false;
1282  }
1283 }
1284 
1285 void TrackPropDlg::OnExtendBtnClick(wxCommandEvent& event) {
1286  TrackPoint* pFirstPoint = m_pTrack->GetPoint(0);
1287 
1288  if (IsThisTrackExtendable()) {
1289  int begin = 0;
1290  if (pFirstPoint->GetCreateTime() == m_pExtendPoint->GetCreateTime()) {
1291  begin = 1;
1292  }
1293  pSelect->DeleteAllSelectableTrackSegments(m_pExtendTrack);
1294  m_pExtendTrack->Clone(m_pTrack, begin, m_pTrack->GetnPoints(), _("_plus"));
1295  pSelect->AddAllSelectableTrackSegments(m_pExtendTrack);
1296  pSelect->DeleteAllSelectableTrackSegments(m_pTrack);
1297  RoutemanGui(*g_pRouteMan).DeleteTrack(m_pTrack);
1298 
1299  SetTrackAndUpdate(m_pExtendTrack);
1300  UpdateProperties();
1301 
1302  if (pRouteManagerDialog && pRouteManagerDialog->IsShown()) {
1303  pRouteManagerDialog->UpdateTrkListCtrl();
1304  }
1305  }
1306 }
1307 
1308 void TrackPropDlg::OnSplitBtnClick(wxCommandEvent& event) {
1309  m_sdbBtmBtnsSizerSplit->Enable(false);
1310 
1311  if (m_pTrack->m_bIsInLayer) {
1312  return;
1313  }
1314 
1315  if ((m_nSelected > 1) && (m_nSelected < m_pTrack->GetnPoints())) {
1316  Track* pHead = new Track();
1317  Track* pTail = new Track();
1318  pHead->Clone(m_pTrack, 0, m_nSelected - 1, _("_A"));
1319  pTail->Clone(m_pTrack, m_nSelected - 1, m_pTrack->GetnPoints(), _("_B"));
1320  g_TrackList.push_back(pHead);
1321  pConfig->AddNewTrack(pHead);
1322 
1323  g_TrackList.push_back(pTail);
1324  pConfig->AddNewTrack(pTail);
1325 
1326  pConfig->DeleteConfigTrack(m_pTrack);
1327 
1328  pSelect->DeleteAllSelectableTrackSegments(m_pTrack);
1329  RoutemanGui(*g_pRouteMan).DeleteTrack(m_pTrack);
1330  pSelect->AddAllSelectableTrackSegments(pTail);
1331  pSelect->AddAllSelectableTrackSegments(pHead);
1332 
1333  SetTrackAndUpdate(pTail);
1334  UpdateProperties();
1335 
1336  if (pRouteManagerDialog && pRouteManagerDialog->IsShown()) {
1337  pRouteManagerDialog->UpdateTrkListCtrl();
1338  }
1339  }
1340 }
1341 
1342 void TrackPropDlg::OnTrackPropCopyTxtClick(wxCommandEvent& event) {
1343  wxString tab("\t", wxConvUTF8);
1344  wxString eol("\n", wxConvUTF8);
1345  wxString csvString;
1346 
1347  csvString << this->GetTitle() << eol << _("Name") << tab
1348  << m_pTrack->GetName() << eol << _("Depart From") << tab
1349  << m_pTrack->m_TrackStartString << eol << _("Destination") << tab
1350  << m_pTrack->m_TrackEndString << eol << _("Total distance") << tab
1351  << m_tTotDistance->GetValue() << eol << _("Speed") << tab
1352  << m_tAvgSpeed->GetValue() << eol
1353  << _("Departure Time") + _T(" ") + _("(m/d/y h:m)") << tab
1354  << m_pTrack->GetPoint(1)->GetCreateTime().Format() << eol
1355  << _("Time enroute") << tab << m_tTimeEnroute->GetValue() << eol
1356  << eol;
1357 
1358  int noCols;
1359  int noRows;
1360  noCols = m_lcPoints->GetColumnCount();
1361  noRows = m_lcPoints->GetItemCount();
1362  wxListItem item;
1363  item.SetMask(wxLIST_MASK_TEXT);
1364 
1365  for (int i = 0; i < noCols; i++) {
1366  m_lcPoints->GetColumn(i, item);
1367  csvString << item.GetText() << tab;
1368  }
1369  csvString << eol;
1370 
1371  for (int j = 0; j < noRows; j++) {
1372  item.SetId(j);
1373  for (int i = 0; i < noCols; i++) {
1374  item.SetColumn(i);
1375  m_lcPoints->GetItem(item);
1376  csvString << item.GetText() << tab;
1377  }
1378  csvString << eol;
1379  }
1380 
1381  if (wxTheClipboard->Open()) {
1382  wxTextDataObject* data = new wxTextDataObject;
1383  data->SetText(csvString);
1384  wxTheClipboard->SetData(data);
1385  wxTheClipboard->Close();
1386  }
1387 }
1388 
1389 void TrackPropDlg::OnPrintBtnClick(wxCommandEvent& event) {
1390  TrackPrintSelection* dlg =
1391  new TrackPrintSelection(this, m_pTrack, m_lcPoints);
1392  DimeControl(dlg);
1393  dlg->ShowWindowModalThenDo([this, dlg](int retcode) {
1394  if (retcode == wxID_OK) {
1395  }
1396  });
1397 }
1398 
1399 void TrackPropDlg::OnTrackPropRightClick(wxListEvent& event) {
1400  wxMenu menu;
1401 
1402  wxMenuItem* copyItem =
1403  menu.Append(ID_RCLK_MENU_COPY_TEXT, _("&Copy all as text"));
1404 
1405  PopupMenu(&menu);
1406 }
1407 
1408 void TrackPropDlg::OnTrackPropListClick(wxListEvent& event) {
1409  long itemno = -1;
1410  m_nSelected = 0;
1411 
1412  int selected_no;
1413  itemno =
1414  m_lcPoints->GetNextItem(itemno, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
1415  if (itemno == -1)
1416  selected_no = 0;
1417  else
1418  selected_no = itemno;
1419 
1420  m_pTrack->m_HighlightedTrackPoint = -1;
1421 
1422  if (itemno >= 0) {
1423  TrackPoint* prp = m_pTrack->GetPoint(itemno);
1424  if (prp) {
1425  m_pTrack->m_HighlightedTrackPoint = itemno; // highlight the trackpoint
1426 
1427  if (!(m_pTrack->m_bIsInLayer) && !(m_pTrack == g_pActiveTrack)) {
1428  m_nSelected = selected_no + 1;
1429  m_sdbBtmBtnsSizerSplit->Enable(true);
1430  }
1431  if (gFrame->GetFocusCanvas()) {
1432  gFrame->JumpToPosition(gFrame->GetFocusCanvas(), prp->m_lat,
1433  prp->m_lon,
1434  gFrame->GetFocusCanvas()->GetVPScale());
1435  }
1436 #ifdef __WXMSW__
1437  if (m_lcPoints) m_lcPoints->SetFocus();
1438 #endif
1439  }
1440  }
1441  if (selected_no == 0 || selected_no == m_pTrack->GetnPoints() - 1)
1442  m_sdbBtmBtnsSizerSplit->Enable(false);
1443 }
1444 
1445 void TrackPropDlg::OnTrackPropMenuSelected(wxCommandEvent& event) {
1446  switch (event.GetId()) {
1447  case ID_RCLK_MENU_COPY_TEXT:
1448  OnTrackPropCopyTxtClick(event);
1449  break;
1450  }
1451 }
1452 
1453 void TrackPropDlg::OnToRouteBtnClick(wxCommandEvent& event) {
1454  pRouteManagerDialog->TrackToRoute(m_pTrack);
1455  if (NULL != pRouteManagerDialog && pRouteManagerDialog->IsVisible())
1456  pRouteManagerDialog->UpdateRouteListCtrl();
1457 }
1458 
1459 void TrackPropDlg::OnExportBtnClick(wxCommandEvent& event) {
1460  wxString suggested_name = _("track");
1461  std::vector<Track*> list = { m_pTrack };
1462  if (m_pTrack->GetName() != wxEmptyString)
1463  suggested_name = m_pTrack->GetName();
1464  ExportGPXTracks(this, &list, suggested_name);
1465 }
1466 
1467 void TrackPropDlg::m_hyperlinkContextMenu(wxMouseEvent& event) {
1468  m_pEditedLink = (wxHyperlinkCtrl*)event.GetEventObject();
1469  Connect(
1470  wxEVT_COMMAND_MENU_SELECTED,
1471  (wxObjectEventFunction)(wxEventFunction)&TrackPropDlg::PopupMenuHandler);
1472  m_scrolledWindowLinks->PopupMenu(
1473  m_menuLink, m_pEditedLink->GetPosition().x + event.GetPosition().x,
1474  m_pEditedLink->GetPosition().y + event.GetPosition().y);
1475 }
1476 
1477 void TrackPropDlg::PopupMenuHandler(wxCommandEvent& event) {
1478  switch (event.GetId()) {
1479  case ID_TRK_MENU_ADD:
1480  OnAddLink(event);
1481  break;
1482  case ID_TRK_MENU_EDIT:
1483  OnEditLink(event);
1484  break;
1485  case ID_TRK_MENU_DELETE:
1486  OnDeleteLink(event);
1487  break;
1488  default:
1489  break;
1490  }
1491 }
1492 
1493 void TrackPropDlg::OnDeleteLink(wxCommandEvent& event) {
1494  wxHyperlinkListNode* nodeToDelete = NULL;
1495  wxString findurl = m_pEditedLink->GetURL();
1496  wxString findlabel = m_pEditedLink->GetLabel();
1497 
1498  wxWindowList kids = m_scrolledWindowLinks->GetChildren();
1499  for (unsigned int i = 0; i < kids.GetCount(); i++) {
1500  wxWindowListNode* node = kids.Item(i);
1501  wxWindow* win = node->GetData();
1502 
1503  if (win->IsKindOf(CLASSINFO(wxHyperlinkCtrl))) {
1504  ((wxHyperlinkCtrl*)win)
1505  ->Disconnect(wxEVT_COMMAND_HYPERLINK,
1506  wxHyperlinkEventHandler(TrackPropDlg::OnHyperLinkClick));
1507  ((wxHyperlinkCtrl*)win)
1508  ->Disconnect(
1509  wxEVT_RIGHT_DOWN,
1510  wxMouseEventHandler(TrackPropDlg::m_hyperlinkContextMenu));
1511  win->Destroy();
1512  }
1513  }
1514 
1516  int NbrOfLinks = m_pTrack->m_HyperlinkList->GetCount();
1517  HyperlinkList* hyperlinklist = m_pTrack->m_HyperlinkList;
1518  // int len = 0;
1519  if (NbrOfLinks > 0) {
1520  wxHyperlinkListNode* linknode = hyperlinklist->GetFirst();
1521  while (linknode) {
1522  Hyperlink* link = linknode->GetData();
1523  wxString Link = link->Link;
1524  wxString Descr = link->DescrText;
1525  if (Link == findurl &&
1526  (Descr == findlabel || (Link == findlabel && Descr == wxEmptyString)))
1527  nodeToDelete = linknode;
1528  else {
1529  wxHyperlinkCtrl* ctrl = new wxHyperlinkCtrl(
1530  m_scrolledWindowLinks, wxID_ANY, Descr, Link, wxDefaultPosition,
1531  wxDefaultSize, wxHL_DEFAULT_STYLE);
1532  ctrl->Connect(wxEVT_COMMAND_HYPERLINK,
1533  wxHyperlinkEventHandler(TrackPropDlg::OnHyperLinkClick),
1534  NULL, this);
1535  ctrl->Connect(wxEVT_RIGHT_DOWN,
1536  wxMouseEventHandler(TrackPropDlg::m_hyperlinkContextMenu),
1537  NULL, this);
1538 
1539  bSizerLinks->Add(ctrl, 0, wxALL, 5);
1540  }
1541  linknode = linknode->GetNext();
1542  }
1543  }
1544  if (nodeToDelete) hyperlinklist->DeleteNode(nodeToDelete);
1545  m_scrolledWindowLinks->InvalidateBestSize();
1546  m_scrolledWindowLinks->Layout();
1547  sbSizerLinks->Layout();
1548  // event.Skip();
1549 }
1550 
1551 void TrackPropDlg::OnEditLink(wxCommandEvent& event) {
1552  wxString findurl = m_pEditedLink->GetURL();
1553  wxString findlabel = m_pEditedLink->GetLabel();
1554 
1555  LinkPropImpl* LinkPropDlg = new LinkPropImpl(this);
1556  LinkPropDlg->m_textCtrlLinkDescription->SetValue(findlabel);
1557  LinkPropDlg->m_textCtrlLinkUrl->SetValue(findurl);
1558  DimeControl(LinkPropDlg);
1559  LinkPropDlg->ShowWindowModalThenDo([this, LinkPropDlg, findurl,
1560  findlabel](int retcode) {
1561  if (retcode == wxID_OK) {
1562  int NbrOfLinks = m_pTrack->m_HyperlinkList->GetCount();
1563  HyperlinkList* hyperlinklist = m_pTrack->m_HyperlinkList;
1564  // int len = 0;
1565  if (NbrOfLinks > 0) {
1566  wxHyperlinkListNode* linknode = hyperlinklist->GetFirst();
1567  while (linknode) {
1568  Hyperlink* link = linknode->GetData();
1569  wxString Link = link->Link;
1570  wxString Descr = link->DescrText;
1571  if (Link == findurl &&
1572  (Descr == findlabel ||
1573  (Link == findlabel && Descr == wxEmptyString))) {
1574  link->Link = LinkPropDlg->m_textCtrlLinkUrl->GetValue();
1575  link->DescrText =
1576  LinkPropDlg->m_textCtrlLinkDescription->GetValue();
1577  wxHyperlinkCtrl* h =
1578  (wxHyperlinkCtrl*)m_scrolledWindowLinks->FindWindowByLabel(
1579  findlabel);
1580  if (h) {
1581  h->SetLabel(LinkPropDlg->m_textCtrlLinkDescription->GetValue());
1582  h->SetURL(LinkPropDlg->m_textCtrlLinkUrl->GetValue());
1583  }
1584  }
1585  linknode = linknode->GetNext();
1586  }
1587  }
1588 
1589  m_scrolledWindowLinks->InvalidateBestSize();
1590  m_scrolledWindowLinks->Layout();
1591  sbSizerLinks->Layout();
1592  }
1593  });
1594  // event.Skip();
1595 }
1596 
1597 void TrackPropDlg::OnAddLink(wxCommandEvent& event) {
1598  LinkPropImpl* LinkPropDlg = new LinkPropImpl(this);
1599  LinkPropDlg->m_textCtrlLinkDescription->SetValue(wxEmptyString);
1600  LinkPropDlg->m_textCtrlLinkUrl->SetValue(wxEmptyString);
1601  DimeControl(LinkPropDlg);
1602  LinkPropDlg->ShowWindowModalThenDo([this, LinkPropDlg](int retcode) {
1603  if (retcode == wxID_OK) {
1604  wxString desc = LinkPropDlg->m_textCtrlLinkDescription->GetValue();
1605  if (desc == wxEmptyString)
1606  desc = LinkPropDlg->m_textCtrlLinkUrl->GetValue();
1607  wxHyperlinkCtrl* ctrl = new wxHyperlinkCtrl(
1608  m_scrolledWindowLinks, wxID_ANY, desc,
1609  LinkPropDlg->m_textCtrlLinkUrl->GetValue(), wxDefaultPosition,
1610  wxDefaultSize, wxHL_DEFAULT_STYLE);
1611  ctrl->Connect(wxEVT_COMMAND_HYPERLINK,
1612  wxHyperlinkEventHandler(TrackPropDlg::OnHyperLinkClick),
1613  NULL, this);
1614  ctrl->Connect(wxEVT_RIGHT_DOWN,
1615  wxMouseEventHandler(TrackPropDlg::m_hyperlinkContextMenu),
1616  NULL, this);
1617 
1618  bSizerLinks->Add(ctrl, 0, wxALL, 5);
1619  bSizerLinks->Fit(m_scrolledWindowLinks);
1620  // this->Fit();
1621 
1622  Hyperlink* h = new Hyperlink();
1623  h->DescrText = LinkPropDlg->m_textCtrlLinkDescription->GetValue();
1624  h->Link = LinkPropDlg->m_textCtrlLinkUrl->GetValue();
1625  h->LType = wxEmptyString;
1626  m_pTrack->m_HyperlinkList->Append(h);
1627  }
1628  });
1629  // sbSizerLinks->Layout();
1630 
1631  m_scrolledWindowLinks->InvalidateBestSize();
1632  m_scrolledWindowLinks->Layout();
1633  sbSizerLinks->Layout();
1634 
1635  // event.Skip();
1636 }
1637 
1638 void TrackPropDlg::OnEditLinkToggle(wxCommandEvent& event) {
1639  if (m_toggleBtnEdit->GetValue())
1640  m_staticTextEditEnabled->SetLabel(_("Links are opened for editing."));
1641  else
1642  m_staticTextEditEnabled->SetLabel(
1643  _("Links are opened in the default browser."));
1644  event.Skip();
1645 }
1646 
1647 void TrackPropDlg::OnHyperLinkClick(wxHyperlinkEvent& event) {
1648  if (m_toggleBtnEdit->GetValue()) {
1649  m_pEditedLink = (wxHyperlinkCtrl*)event.GetEventObject();
1650  OnEditLink(event);
1651  event.Skip(false);
1652  return;
1653  }
1654  // Windows has trouble handling local file URLs with embedded anchor
1655  // points, e.g file://testfile.html#point1 The trouble is with the
1656  // wxLaunchDefaultBrowser with verb "open" Workaround is to probe the
1657  // registry to get the default browser, and open directly
1658  //
1659  // But, we will do this only if the URL contains the anchor point charater
1660  // '#' What a hack......
1661 
1662 #ifdef __WXMSW__
1663 
1664  wxString cc = event.GetURL();
1665  if (cc.Find(_T("#")) != wxNOT_FOUND) {
1666  wxRegKey RegKey(
1667  wxString(_T("HKEY_CLASSES_ROOT\\HTTP\\shell\\open\\command")));
1668  if (RegKey.Exists()) {
1669  wxString command_line;
1670  RegKey.QueryValue(wxString(_T("")), command_line);
1671 
1672  // Remove "
1673  command_line.Replace(wxString(_T("\"")), wxString(_T("")));
1674 
1675  // Strip arguments
1676  int l = command_line.Find(_T(".exe"));
1677  if (wxNOT_FOUND == l) l = command_line.Find(_T(".EXE"));
1678 
1679  if (wxNOT_FOUND != l) {
1680  wxString cl = command_line.Mid(0, l + 4);
1681  cl += _T(" ");
1682  cc.Prepend(_T("\""));
1683  cc.Append(_T("\""));
1684  cl += cc;
1685  wxExecute(cl); // Async, so Fire and Forget...
1686  }
1687  }
1688  } else
1689  event.Skip();
1690 #else
1691  wxString url = event.GetURL();
1692  url.Replace(_T(" "), _T("%20"));
1693  ::wxLaunchDefaultBrowser(url);
1694 // event.Skip();
1695 #endif
1696 }
1697 
1698 void TrackPropDlg::OnShowTimeTZ(wxCommandEvent& event) {
1699  if (m_rbShowTimeUTC && m_rbShowTimeUTC->GetValue())
1700  m_lcPoints->m_tz_selection = UTCINPUT;
1701  else if (m_rbShowTimePC && m_rbShowTimePC->GetValue())
1702  m_lcPoints->m_tz_selection = LTINPUT;
1703  else
1704  m_lcPoints->m_tz_selection = LMTINPUT;
1705  m_lcPoints->DeleteAllItems();
1706  InitializeList();
1707 }
1708 
1709 bool TrackPropDlg::SaveChanges(void) {
1710  if (m_pTrack && !m_pTrack->m_bIsInLayer) {
1711  // Get User input Text Fields
1712  m_pTrack->SetName(m_tName->GetValue());
1713  m_pTrack->m_TrackStartString = m_tFrom->GetValue();
1714  m_pTrack->m_TrackEndString = m_tTo->GetValue();
1715  if (m_tDescription)
1716  m_pTrack->m_TrackDescription = m_tDescription->GetValue();
1717  m_pTrack->SetVisible(m_cbShow->GetValue());
1718  if (m_cColor->GetSelection() == 0)
1719  m_pTrack->m_Colour = wxEmptyString;
1720  else
1721  m_pTrack->m_Colour = ::GpxxColorNames[m_cColor->GetSelection() - 1];
1722  m_pTrack->m_style = (wxPenStyle)::StyleValues[m_cStyle->GetSelection()];
1723  m_pTrack->m_width = ::WidthValues[m_cWidth->GetSelection()];
1724 
1725  pConfig->UpdateTrack(m_pTrack);
1726  pConfig->UpdateSettings();
1727  }
1728 
1729  if (m_pTrack && m_pTrack->IsRunning()) {
1730  wxJSONValue v;
1731  v[_T("Changed")] = true;
1732  v[_T("Name")] = m_pTrack->GetName();
1733  v[_T("GUID")] = m_pTrack->m_GUID;
1734  wxString msg_id(_T("OCPN_TRK_ACTIVATED"));
1735  g_pi_manager->SendJSONMessageToAllPlugins(msg_id, v);
1736  }
1737 
1738  return true;
1739 }
1740 
1741 void TrackPropDlg::OnOKBtnClick(wxCommandEvent& event) {
1742  // Look in the track list to be sure the track is still available
1743  // (May have been deleted by RouteManagerDialog...)
1744 
1745  bool b_found_track =
1746  std::find(g_TrackList.begin(), g_TrackList.end(), m_pTrack) !=
1747  g_TrackList.end();
1748 
1749  if (b_found_track) {
1750  SaveChanges(); // write changes to globals and update config
1751  m_pTrack->ClearHighlights();
1752  }
1753 
1754  m_bStartNow = false;
1755 
1756  if (pRouteManagerDialog && pRouteManagerDialog->IsShown())
1757  pRouteManagerDialog->UpdateTrkListCtrl();
1758 
1759  Hide();
1760  gFrame->InvalidateAllGL();
1761  gFrame->RefreshAllCanvas(false);
1762 
1763  event.Skip();
1764 }
1765 
1766 void TrackPropDlg::OnCancelBtnClick(wxCommandEvent& event) {
1767  bool b_found_track =
1768  std::find(g_TrackList.begin(), g_TrackList.end(), m_pTrack) !=
1769  g_TrackList.end();
1770 
1771  if (b_found_track) m_pTrack->ClearHighlights();
1772 
1773  Hide();
1774  gFrame->InvalidateAllGL();
1775  gFrame->RefreshAllCanvas(false);
1776 
1777  event.Skip();
1778 }
1779 
1780 //--------------------------------------------------------------------------------------
1781 // OCPNTrackListCtrl Implementation
1782 //---------------------------------------------------------------------------------------
1783 
1784 OCPNTrackListCtrl::OCPNTrackListCtrl(wxWindow* parent, wxWindowID id,
1785  const wxPoint& pos, const wxSize& size,
1786  long style)
1787  : wxListCtrl(parent, id, pos, size, style) {
1788  m_parent = parent;
1789  m_tz_selection = LTINPUT;
1790  m_LMT_Offset = 0;
1791 }
1792 
1793 OCPNTrackListCtrl::~OCPNTrackListCtrl() {}
1794 
1795 wxString OCPNTrackListCtrl::OnGetItemText(long item, long column) const {
1796  wxString ret;
1797 
1798  if (item < 0 || item >= m_pTrack->GetnPoints()) return wxEmptyString;
1799 
1800  TrackPoint* this_point = m_pTrack->GetPoint(item);
1801  TrackPoint* prev_point = item > 0 ? m_pTrack->GetPoint(item - 1) : NULL;
1802 
1803  if (!this_point) return wxEmptyString;
1804 
1805  double gt_brg, gt_leg_dist;
1806  double slat, slon;
1807  if (item == 0) {
1808  slat = gLat;
1809  slon = gLon;
1810  } else {
1811  slat = prev_point->m_lat;
1812  slon = prev_point->m_lon;
1813  }
1814 
1815  switch (column) {
1816  case 0:
1817  if (item == 0)
1818  ret = _T("---");
1819  else
1820  ret.Printf(_T("%ld"), item);
1821  break;
1822 
1823  case 1:
1824  DistanceBearingMercator(this_point->m_lat, this_point->m_lon, slat, slon,
1825  &gt_brg, &gt_leg_dist);
1826 
1827  ret.Printf(_T("%6.2f ") + getUsrDistanceUnit(),
1828  toUsrDistance(gt_leg_dist));
1829  break;
1830 
1831  case 2:
1832  DistanceBearingMercator(this_point->m_lat, this_point->m_lon, slat, slon,
1833  &gt_brg, &gt_leg_dist);
1834  ret.Printf("%03.0f %cT", gt_brg, 0x00B0);
1835  break;
1836 
1837  case 3:
1838  ret = toSDMM(1, this_point->m_lat, 1);
1839  break;
1840 
1841  case 4:
1842  ret = toSDMM(2, this_point->m_lon, 1);
1843  break;
1844 
1845  case 5: {
1846  wxDateTime timestamp = this_point->GetCreateTime();
1847  if (timestamp.IsValid())
1848  ret = timestamp2s(timestamp, m_tz_selection, m_LMT_Offset,
1849  TIMESTAMP_FORMAT);
1850  else
1851  ret = _T("----");
1852  } break;
1853 
1854  case 6:
1855  if ((item > 0) && this_point->GetCreateTime().IsValid() &&
1856  prev_point->GetCreateTime().IsValid()) {
1857  DistanceBearingMercator(this_point->m_lat, this_point->m_lon, slat,
1858  slon, &gt_brg, &gt_leg_dist);
1859  double speed = 0.;
1860  double seconds = this_point->GetCreateTime()
1861  .Subtract(prev_point->GetCreateTime())
1862  .GetSeconds()
1863  .ToDouble();
1864 
1865  if (seconds > 0.) speed = gt_leg_dist / seconds * 3600;
1866 
1867  ret.Printf(_T("%5.2f"), toUsrSpeed(speed));
1868  } else
1869  ret = _("--");
1870  break;
1871 
1872  default:
1873  break;
1874  }
1875 
1876  return ret;
1877 }
1878 
1879 int OCPNTrackListCtrl::OnGetItemColumnImage(long item, long column) const {
1880  return -1;
1881 }
Class LinkPropImpl.
Definition: LinkPropDlg.h:89
Class TrackPropDlg.
Definition: TrackPropDlg.h:93
bool UpdateProperties()
void OnDeleteLink(wxCommandEvent &event)
Definition: track.h:78
General purpose GUI support.