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