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