OpenCPN Partial API docs
Loading...
Searching...
No Matches
track_prop_dlg.cpp
Go to the documentation of this file.
1/***************************************************************************
2 * Copyright (C) 2013 by David S. Register *
3 * *
4 * This program is free software; you can redistribute it and/or modify *
5 * it under the terms of the GNU General Public License as published by *
6 * the Free Software Foundation; either version 2 of the License, or *
7 * (at your option) any later version. *
8 * *
9 * This program is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12 * GNU General Public License for more details. *
13 * *
14 * You should have received a copy of the GNU General Public License *
15 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
16 * along with this program; if not, see <https://www.gnu.org/licenses/>. *
17 **************************************************************************/
18
25#include "config.h"
26
27#include "gl_headers.h" // Must be included before anything using GL stuff
28
29#include "model/georef.h"
30#include "model/gui_vars.h"
31#include "model/navobj_db.h"
32#include "model/navutil_base.h"
33#include "model/own_ship.h"
34#include "model/plugin_comm.h"
35#include "model/route.h"
36#include "model/routeman.h"
37#include "model/select.h"
38#include "model/track.h"
39
40#include "chcanv.h"
41#include "gui_lib.h"
42#include "navutil.h"
43#include "ocpn_frame.h"
44#include "ocpn_platform.h"
45#include "pluginmanager.h"
46#include "print_dialog.h"
47#include "routemanagerdialog.h"
48#include "routeman_gui.h"
49#include "track_printout.h"
50#include "track_prop_dlg.h"
51
52#ifdef __ANDROID__
53#include "androidUTIL.h"
54#endif
55
56#define UTCINPUT 0
57#define LTINPUT \
58 1
59#define LMTINPUT \
60 2
62#define GLOBAL_SETTINGS_INPUT 3
63
64#define INPUT_FORMAT 1
65#define DISPLAY_FORMAT 2
66#define TIMESTAMP_FORMAT 3
67
69
71
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";
260 default:
261 return "";
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() {
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, "", 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, "", 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, "", 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 = new wxTextCtrl(itemDialog1, wxID_ANY, "", wxDefaultPosition,
400 wxSize(-1, -1), wxTE_READONLY);
401 itemFlexGridSizer6a->Add(m_tTotDistance, 0,
402 wxEXPAND | wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL |
403 wxLEFT | wxRIGHT | wxBOTTOM,
404 5);
405
406 m_stAvgSpeed = new wxStaticText(itemDialog1, wxID_STATIC, _("Avg. speed"),
407 wxDefaultPosition, wxDefaultSize, 0);
408 itemFlexGridSizer6a->Add(
409 m_stAvgSpeed, 0,
410 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT | wxTOP, 5);
411
412 m_tAvgSpeed = new wxTextCtrl(itemDialog1, wxID_ANY, "", wxDefaultPosition,
413 wxSize(150, -1), wxTE_PROCESS_ENTER);
414 itemFlexGridSizer6a->Add(
415 m_tAvgSpeed, 0,
416 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT | wxBOTTOM, 5);
417
418 m_stTimeEnroute =
419 new wxStaticText(itemDialog1, wxID_STATIC, _("Time Enroute"),
420 wxDefaultPosition, wxDefaultSize, 0);
421 itemFlexGridSizer6a->Add(
422 m_stTimeEnroute, 0,
423 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT | wxTOP, 5);
424
425 m_tTimeEnroute = new wxTextCtrl(itemDialog1, wxID_ANY, "", wxDefaultPosition,
426 wxSize(-1, -1), wxTE_READONLY);
427 itemFlexGridSizer6a->Add(m_tTimeEnroute, 0,
428 wxEXPAND | wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL |
429 wxLEFT | wxRIGHT | wxBOTTOM,
430 5);
431
432 /*
433 m_StartTimeLabel = new wxStaticText( itemDialog1, wxID_STATIC,
434 _("Departure Time"), wxDefaultPosition, wxDefaultSize, 0 );
435 itemFlexGridSizer6a->Add( m_StartTimeLabel, 0,
436 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT | wxTOP,
437 5 );
438
439 m_StartTimeCtl = new wxTextCtrl( itemDialog1, ID_STARTTIMECTL, "",
440 wxDefaultPosition, wxSize( -1, -1 ), wxTE_PROCESS_ENTER );
441 itemFlexGridSizer6a->Add( m_StartTimeCtl, 0,
442 wxEXPAND | wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxLEFT |
443 wxRIGHT | wxBOTTOM, 5 );
444 */
445
446 wxString pDispTimeZone[] = {_("UTC"), _("Local Time"), _("LMT@Location"),
447 _("Honor Global Settings")};
448
449 wxStaticText* itemStaticText12b =
450 new wxStaticText(itemDialog1, wxID_STATIC, _("Time shown as"),
451 wxDefaultPosition, wxDefaultSize, 0);
452 itemBoxSizer2->Add(itemStaticText12b, 0, wxEXPAND | wxALL, 5);
453
454 m_rbShowTimeUTC =
455 new wxRadioButton(itemDialog1, wxID_ANY, _("UTC"), wxDefaultPosition,
456 wxDefaultSize, wxRB_GROUP);
457 itemBoxSizer2->Add(
458 m_rbShowTimeUTC, 0,
459 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT | wxBOTTOM, 5);
460
461 m_rbShowTimePC = new wxRadioButton(itemDialog1, wxID_ANY, _("Local Time"));
462 itemBoxSizer2->Add(
464 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT | wxBOTTOM, 5);
465
467 new wxRadioButton(itemDialog1, wxID_ANY, _("LMT@Location"));
468 itemBoxSizer2->Add(
470 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT | wxBOTTOM, 5);
471
473 new wxRadioButton(itemDialog1, wxID_ANY, _("Honor Global Settings"));
474 itemBoxSizer2->Add(
476 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT | wxBOTTOM, 5);
477
478 wxFlexGridSizer* itemFlexGridSizer6b = new wxFlexGridSizer(3, 2, 0, 0);
479 itemBoxSizer2->Add(itemFlexGridSizer6b, 0, wxEXPAND | wxALIGN_LEFT | wxALL,
480 5);
481
482 wxStaticText* m_staticText1 =
483 new wxStaticText(itemDialog1, wxID_ANY, _("Color") + ":",
484 wxDefaultPosition, wxDefaultSize, 0);
485 itemFlexGridSizer6b->Add(m_staticText1, 0, wxALIGN_CENTER_VERTICAL | wxALL,
486 5);
487
488 wxString m_chColorChoices[] = {
489 _("Default color"), _("Black"), _("Dark Red"), _("Dark Green"),
490 _("Dark Yellow"), _("Dark Blue"), _("Dark Magenta"), _("Dark Cyan"),
491 _("Light Gray"), _("Dark Gray"), _("Red"), _("Green"),
492 _("Yellow"), _("Blue"), _("Magenta"), _("Cyan"),
493 _("White")};
494 int m_chColorNChoices = sizeof(m_chColorChoices) / sizeof(wxString);
495 m_cColor =
496 new wxChoice(itemDialog1, wxID_ANY, wxDefaultPosition, wxSize(250, -1),
497 m_chColorNChoices, m_chColorChoices, 0);
498 m_cColor->SetSelection(0);
499 itemFlexGridSizer6b->Add(m_cColor, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
500
501 wxStaticText* staticTextStyle =
502 new wxStaticText(itemDialog1, wxID_ANY, _("Style") + ":",
503 wxDefaultPosition, wxDefaultSize, 0);
504 itemFlexGridSizer6b->Add(staticTextStyle, 0, wxALIGN_CENTER_VERTICAL | wxALL,
505 5);
506
507 wxString m_chStyleChoices[] = {_("Default"), _("Solid"), _("Dot"),
508 _("Long dash"), _("Short dash")};
509 int m_chStyleNChoices = sizeof(m_chStyleChoices) / sizeof(wxString);
510 m_cStyle =
511 new wxChoice(itemDialog1, wxID_ANY, wxDefaultPosition, wxDefaultSize,
512 m_chStyleNChoices, m_chStyleChoices, 0);
513 m_cStyle->SetSelection(0);
514 itemFlexGridSizer6b->Add(m_cStyle, 0,
515 wxEXPAND | wxALIGN_CENTER_VERTICAL | wxALL, 5);
516
517#ifdef ocpnUSE_GLES // linestipple is emulated poorly
518 staticTextStyle->Hide();
519 m_cStyle->Hide();
520#endif
521
522 m_stWidth = new wxStaticText(itemDialog1, wxID_ANY, _("Width") + ":",
523 wxDefaultPosition, wxDefaultSize, 0);
524 itemFlexGridSizer6b->Add(m_stWidth, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
525
526 wxString m_chWidthChoices[] = {_("Default"), _("1 pixel"), _("2 pixels"),
527 _("3 pixels"), _("4 pixels"), _("5 pixels"),
528 _("6 pixels"), _("7 pixels"), _("8 pixels"),
529 _("9 pixels"), _("10 pixels")};
530 int m_chWidthNChoices = sizeof(m_chWidthChoices) / sizeof(wxString);
531 m_cWidth =
532 new wxChoice(itemDialog1, wxID_ANY, wxDefaultPosition, wxSize(150, -1),
533 m_chWidthNChoices, m_chWidthChoices, 0);
534 m_cWidth->SetSelection(0);
535 itemFlexGridSizer6b->Add(m_cWidth, 0,
536 wxEXPAND | wxALIGN_CENTER_VERTICAL | wxALL, 5);
537
538 wxStaticBox* itemStaticBoxSizer14Static =
539 new wxStaticBox(itemDialog1, wxID_ANY, _("Waypoints"));
540 wxStaticBoxSizer* m_pListSizer =
541 new wxStaticBoxSizer(itemStaticBoxSizer14Static, wxVERTICAL);
542 itemBoxSizer2->Add(m_pListSizer, 1, wxEXPAND | wxALL, 1);
543
544 wxScrolledWindow* itemlistWin =
545 new wxScrolledWindow(itemDialog1, wxID_ANY, wxDefaultPosition,
546 wxDefaultSize, wxHSCROLL | wxVSCROLL);
547 itemlistWin->SetScrollRate(2, 2);
548
549 m_pListSizer->Add(itemlistWin, 0, wxEXPAND | wxALL, 6);
550
551 long flags = wxLC_REPORT | wxLC_HRULES | wxLC_VRULES | wxLC_EDIT_LABELS;
552#ifndef __WXQT__ // Does not support Virtual list boxes....
553 flags |= wxLC_VIRTUAL;
554#endif
555
556 m_lcPoints = new OCPNTrackListCtrl(itemlistWin, wxID_ANY, wxDefaultPosition,
557 wxSize(100, 500), flags);
558 addColumns(m_lcPoints, GetCharWidth());
559
560 // sbSizerPoints->Add( m_lcPoints, 1, wxALL|wxEXPAND, 5 );
561
562#ifdef __ANDROID__
563 m_lcPoints->GetHandle()->setStyleSheet(getQtStyleSheet());
564#endif
565
566 // Buttons, etc...
567
568 wxBoxSizer* itemBoxSizerBottom = new wxBoxSizer(wxVERTICAL);
569 itemBoxSizer1->Add(itemBoxSizerBottom, 0, wxALIGN_LEFT | wxALL | wxEXPAND, 5);
570
571 int n_col = 3;
572
573 wxFlexGridSizer* itemBoxSizerAux = new wxFlexGridSizer(0, n_col, 0, 0);
574 itemBoxSizerAux->SetFlexibleDirection(wxBOTH);
575 itemBoxSizerAux->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_SPECIFIED);
576
577 itemBoxSizerBottom->Add(itemBoxSizerAux, 1, wxALIGN_LEFT | wxALL, 5);
578
579#ifndef __ANDROID__
580
581 m_sdbBtmBtnsSizerPrint = new wxButton(this, wxID_ANY, _("Print"),
582 wxDefaultPosition, wxDefaultSize, 0);
583 itemBoxSizerAux->Add(m_sdbBtmBtnsSizerPrint, 0,
584 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 5);
585 m_sdbBtmBtnsSizerPrint->Enable(true);
586#else
587 m_sdbBtmBtnsSizerPrint = NULL;
588#endif
589
590 m_sdbBtmBtnsSizerSplit = new wxButton(this, wxID_ANY, _("Split"),
591 wxDefaultPosition, wxDefaultSize, 0);
592 itemBoxSizerAux->Add(m_sdbBtmBtnsSizerSplit, 0,
593 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 5);
594 m_sdbBtmBtnsSizerSplit->Enable(false);
595
596 m_sdbBtmBtnsSizerExtend = new wxButton(this, wxID_ANY, _("Extend"),
597 wxDefaultPosition, wxDefaultSize, 0);
598 m_sdbBtmBtnsSizerExtend->SetToolTip(
599 _("Extends this track by connecting it to another track.\n"
600 "Disabled when the track is active, the track is in a layer, or no "
601 "suitable track to connect to exists.\n"
602 "A suitable track is one that is visible, is different from this "
603 "track, and has its last point's timestamp earlier than or equal to "
604 "this track's first point's timestamp."));
605 itemBoxSizerAux->Add(m_sdbBtmBtnsSizerExtend, 0,
606 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 5);
607
608 m_sdbBtmBtnsSizerToRoute = new wxButton(this, wxID_ANY, _("To route"),
609 wxDefaultPosition, wxDefaultSize, 0);
610 itemBoxSizerAux->Add(m_sdbBtmBtnsSizerToRoute, 0,
611 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 5);
612
613 m_sdbBtmBtnsSizerExport = NULL;
614 // m_sdbBtmBtnsSizerExport = new wxButton( this, wxID_ANY, _("Export"),
615 // wxDefaultPosition, wxDefaultSize, 0 ); itemBoxSizerAux->Add(
616 // m_sdbBtmBtnsSizerExport, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL |
617 // wxALL, 5 );
618
619 wxBoxSizer* itemBoxSizer16 = new wxBoxSizer(wxHORIZONTAL);
620 itemBoxSizerBottom->Add(itemBoxSizer16, 0, wxALIGN_RIGHT | wxALL, 5);
621
622 m_sdbBtmBtnsSizerCancel = new wxButton(this, wxID_CANCEL, _("Cancel"),
623 wxDefaultPosition, wxDefaultSize, 0);
624 itemBoxSizer16->Add(m_sdbBtmBtnsSizerCancel, 0,
625 wxALIGN_RIGHT | wxALIGN_BOTTOM | wxALL, 5);
626
627 m_sdbBtmBtnsSizerOK =
628 new wxButton(this, wxID_OK, _("OK"), wxDefaultPosition, wxDefaultSize, 0);
629 itemBoxSizer16->Add(m_sdbBtmBtnsSizerOK, 0,
630 wxALIGN_RIGHT | wxALIGN_BOTTOM | wxALL, 5);
631 m_sdbBtmBtnsSizerOK->SetDefault();
632
633 int char_size = GetCharWidth();
634 // Set the maximum size of the entire dialog
635 int width, height;
636 width = g_monitor_info[g_current_monitor].width;
637 height = g_monitor_info[g_current_monitor].height;
638 SetSizeHints(-1, -1, width - 100, height - 100);
639}
640
641void TrackPropDlg::CreateControls() {
642 wxBoxSizer* bSizerMain;
643 bSizerMain = new wxBoxSizer(wxVERTICAL);
644 SetSizer(bSizerMain);
645
646 m_notebook1 =
647 new wxNotebook(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0);
648
649 bSizerMain->Add(m_notebook1, 1, wxEXPAND | wxALL, 5);
650
651 wxPanel* m_panel0 =
652 new wxPanel(m_notebook1, wxID_ANY, wxDefaultPosition, wxDefaultSize);
653 m_notebook1->AddPage(m_panel0, _("Basic"), true);
654
655 wxBoxSizer* bSizer0 = new wxBoxSizer(wxVERTICAL);
656 m_panel0->SetSizer(bSizer0);
657
658 wxBoxSizer* bSizer1 = new wxBoxSizer(wxVERTICAL);
659 bSizer0->Add(bSizer1, 1, wxEXPAND | wxALL, 5);
660
661 m_panelBasic = new wxScrolledWindow(m_panel0, wxID_ANY, wxDefaultPosition,
662 wxSize(-1, -1),
663 wxHSCROLL | wxVSCROLL | wxTAB_TRAVERSAL);
664
665#ifdef __ANDROID__
666 // Set Dialog Font by custom crafted Qt Stylesheet.
667 wxFont* qFont = GetOCPNScaledFont(_("Dialog"));
668
669 wxString wqs = getFontQtStylesheet(qFont);
670 wxCharBuffer sbuf = wqs.ToUTF8();
671 QString qsb = QString(sbuf.data());
672
673 QString qsbq = getQtStyleSheet(); // basic scrollbars, etc
674
675 m_panelBasic->GetHandle()->setStyleSheet(qsb +
676 qsbq); // Concatenated style sheets
677
678#endif
679
680 // #ifdef __ANDROID__
681 // m_panelBasic->GetHandle()->setStyleSheet( getQtStyleSheet());
682 // #endif
683
684 wxBoxSizer* bSizerBasic = new wxBoxSizer(wxVERTICAL);
685 m_panelBasic->SetSizer(bSizerBasic);
686
687 bSizer1->Add(m_panelBasic, 1, wxEXPAND | wxALL, 5);
688
689 wxBoxSizer* bSizerName;
690 bSizerName = new wxBoxSizer(wxHORIZONTAL);
691 bSizerBasic->Add(bSizerName, 0, wxALL | wxEXPAND, 5);
692
693 m_stName = new wxStaticText(m_panelBasic, wxID_ANY, _("Name"),
694 wxDefaultPosition, wxDefaultSize, 0);
695 // m_stName->Wrap( -1 );
696 bSizerName->Add(m_stName, 0, wxALL, 5);
697
698 m_tName = new wxTextCtrl(m_panelBasic, wxID_ANY, "", wxDefaultPosition,
699 wxDefaultSize, 0);
700 bSizerName->Add(m_tName, 1, 0, 5);
701
702 wxBoxSizer* bSizerFromTo;
703 bSizerFromTo = new wxBoxSizer(wxHORIZONTAL);
704 bSizerBasic->Add(bSizerFromTo, 0, wxALL | wxEXPAND, 5);
705
706 m_stFrom = new wxStaticText(m_panelBasic, wxID_ANY, _("From"),
707 wxDefaultPosition, wxDefaultSize, 0);
708 // m_stFrom->Wrap( -1 );
709 bSizerFromTo->Add(m_stFrom, 0, wxALL, 5);
710
711 m_tFrom = new wxTextCtrl(m_panelBasic, wxID_ANY, "", wxDefaultPosition,
712 wxDefaultSize, 0);
713 bSizerFromTo->Add(m_tFrom, 1, 0, 5);
714
715 m_stTo = new wxStaticText(m_panelBasic, wxID_ANY, _("To"), wxDefaultPosition,
716 wxDefaultSize, 0);
717 // m_stTo->Wrap( -1 );
718 bSizerFromTo->Add(m_stTo, 0, wxALL, 5);
719
720 m_tTo = new wxTextCtrl(m_panelBasic, wxID_ANY, "", wxDefaultPosition,
721 wxDefaultSize, 0);
722 bSizerFromTo->Add(m_tTo, 1, 0, 5);
723
724 wxStaticBoxSizer* sbSizerParams;
725 sbSizerParams = new wxStaticBoxSizer(
726 new wxStaticBox(m_panelBasic, wxID_ANY, _("Display parameters")),
727 wxHORIZONTAL);
728 bSizerBasic->Add(sbSizerParams, 0, wxALL | wxEXPAND, 5);
729
730 m_cbShow = new wxCheckBox(m_panelBasic, wxID_ANY, _("Show on chart"),
731 wxDefaultPosition, wxDefaultSize, 0);
732 sbSizerParams->Add(m_cbShow, 0, wxALL, 5);
733
734 m_stColor = new wxStaticText(m_panelBasic, wxID_ANY, _("Color"),
735 wxDefaultPosition, wxDefaultSize, 0);
736 // m_stColor->Wrap( -1 );
737 sbSizerParams->Add(m_stColor, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
738
739 wxString m_cColorChoices[] = {
740 _("Default color"), _("Black"), _("Dark Red"), _("Dark Green"),
741 _("Dark Yellow"), _("Dark Blue"), _("Dark Magenta"), _("Dark Cyan"),
742 _("Light Gray"), _("Dark Gray"), _("Red"), _("Green"),
743 _("Yellow"), _("Blue"), _("Magenta"), _("Cyan"),
744 _("White")};
745 int m_cColorNChoices = sizeof(m_cColorChoices) / sizeof(wxString);
746 m_cColor = new wxChoice(m_panelBasic, wxID_ANY, wxDefaultPosition,
747 wxDefaultSize, m_cColorNChoices, m_cColorChoices, 0);
748 m_cColor->SetSelection(0);
749 sbSizerParams->Add(m_cColor, 1, 0, 5);
750
751 m_stStyle = new wxStaticText(m_panelBasic, wxID_ANY, _("Style"),
752 wxDefaultPosition, wxDefaultSize, 0);
753 // m_stStyle->Wrap( -1 );
754 sbSizerParams->Add(m_stStyle, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
755
756 wxString m_cStyleChoices[] = {_("Default"), _("Solid"), _("Dot"),
757 _("Long dash"), _("Short dash")};
758 int m_cStyleNChoices = sizeof(m_cStyleChoices) / sizeof(wxString);
759 m_cStyle = new wxChoice(m_panelBasic, wxID_ANY, wxDefaultPosition,
760 wxDefaultSize, m_cStyleNChoices, m_cStyleChoices, 0);
761 m_cStyle->SetSelection(0);
762 sbSizerParams->Add(m_cStyle, 1, 0, 5);
763
764 m_stWidth = new wxStaticText(m_panelBasic, wxID_ANY, _("Width"),
765 wxDefaultPosition, wxDefaultSize, 0);
766 // m_stWidth->Wrap( -1 );
767 sbSizerParams->Add(m_stWidth, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
768
769 wxString m_cWidthChoices[] = {_("Default"), _("1 pixel"), _("2 pixels"),
770 _("3 pixels"), _("4 pixels"), _("5 pixels"),
771 _("6 pixels"), _("7 pixels"), _("8 pixels"),
772 _("9 pixels"), _("10 pixels")};
773 int m_cWidthNChoices = sizeof(m_cWidthChoices) / sizeof(wxString);
774 m_cWidth = new wxChoice(m_panelBasic, wxID_ANY, wxDefaultPosition,
775 wxDefaultSize, m_cWidthNChoices, m_cWidthChoices, 0);
776 m_cWidth->SetSelection(0);
777 sbSizerParams->Add(m_cWidth, 1, 0, 5);
778
779 wxStaticBoxSizer* sbSizerStats;
780 sbSizerStats = new wxStaticBoxSizer(
781 new wxStaticBox(m_panelBasic, wxID_ANY, _("Statistics")), wxVERTICAL);
782 bSizerBasic->Add(sbSizerStats, 0, wxALL | wxEXPAND, 5);
783
784 wxBoxSizer* bSizerStats;
785 bSizerStats = new wxBoxSizer(wxHORIZONTAL);
786
787 m_stTotDistance =
788 new wxStaticText(m_panelBasic, wxID_ANY, _("Total distance"),
789 wxDefaultPosition, wxDefaultSize, 0);
790 // m_stTotDistance->Wrap( -1 );
791 bSizerStats->Add(m_stTotDistance, 0, wxALL, 5);
792
793 m_tTotDistance = new wxTextCtrl(m_panelBasic, wxID_ANY, "", wxDefaultPosition,
794 wxDefaultSize, wxTE_READONLY);
795 bSizerStats->Add(m_tTotDistance, 1, 0, 5);
796
797 m_stAvgSpeed = new wxStaticText(m_panelBasic, wxID_ANY, _("Avg. speed"),
798 wxDefaultPosition, wxDefaultSize, 0);
799 // m_stAvgSpeed->Wrap( -1 );
800 bSizerStats->Add(m_stAvgSpeed, 0, wxALL, 5);
801
802 m_tAvgSpeed = new wxTextCtrl(m_panelBasic, wxID_ANY, "", wxDefaultPosition,
803 wxDefaultSize, wxTE_READONLY);
804 bSizerStats->Add(m_tAvgSpeed, 1, 0, 5);
805
806 m_stTimeEnroute = new wxStaticText(m_panelBasic, wxID_ANY, _("Time enroute"),
807 wxDefaultPosition, wxDefaultSize, 0);
808 // m_stTimeEnroute->Wrap( -1 );
809 bSizerStats->Add(m_stTimeEnroute, 0, wxALL, 5);
810
811 m_tTimeEnroute = new wxTextCtrl(m_panelBasic, wxID_ANY, "", wxDefaultPosition,
812 wxDefaultSize, wxTE_READONLY);
813 bSizerStats->Add(m_tTimeEnroute, 2, 0, 5);
814
815 sbSizerStats->Add(bSizerStats, 0, wxEXPAND, 5);
816
817 wxStaticBoxSizer* sbSizerPoints;
818 sbSizerPoints = new wxStaticBoxSizer(
819 new wxStaticBox(m_panel0, wxID_ANY, _("Recorded points")), wxVERTICAL);
820 bSizer1->Add(sbSizerPoints, 1, wxALL | wxEXPAND, 5);
821
822 wxBoxSizer* bSizerShowTime;
823 bSizerShowTime = new wxBoxSizer(wxHORIZONTAL);
824
825 m_stShowTime = new wxStaticText(m_panel0, wxID_ANY, _("Time shown as"),
826 wxDefaultPosition, wxDefaultSize, 0);
827 // m_stShowTime->Wrap( -1 );
828 bSizerShowTime->Add(m_stShowTime, 0, wxALL, 5);
829
830 m_rbShowTimeUTC = new wxRadioButton(m_panel0, wxID_ANY, _("UTC"),
831 wxDefaultPosition, wxDefaultSize, 0);
832 bSizerShowTime->Add(m_rbShowTimeUTC, 0,
833 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT,
834 5);
835
836 m_rbShowTimePC = new wxRadioButton(m_panel0, wxID_ANY, _("Local Time"),
837 wxDefaultPosition, wxDefaultSize, 0);
838 bSizerShowTime->Add(m_rbShowTimePC, 0,
839 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT,
840 5);
841
843 new wxRadioButton(m_panel0, wxID_ANY, _("LMT@Track Start"),
844 wxDefaultPosition, wxDefaultSize, 0);
845 bSizerShowTime->Add(m_rbShowTimeLocal, 0,
846 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT,
847 5);
848
850 new wxRadioButton(m_panel0, wxID_ANY, _("Honor Global Settings"),
851 wxDefaultPosition, wxDefaultSize, 0);
852 bSizerShowTime->Add(m_rbShowTimeGlobalSettings, 0,
853 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT,
854 5);
855
856 m_rbShowTimeGlobalSettings->SetValue(true);
857
858 sbSizerPoints->Add(bSizerShowTime, 0, wxEXPAND, 5);
859
860 long flags = wxLC_REPORT | wxLC_HRULES | wxLC_VRULES | wxLC_EDIT_LABELS;
861#ifndef __WXQT__ // Does not support Virtual list boxes....
862 flags |= wxLC_VIRTUAL;
863#endif
864
865 m_lcPoints = new OCPNTrackListCtrl(m_panel0, wxID_ANY, wxDefaultPosition,
866 wxDefaultSize, flags);
867 addColumns(m_lcPoints, GetCharWidth());
868
869 sbSizerPoints->Add(m_lcPoints, 1, wxALL | wxEXPAND, 5);
870
871#ifdef __ANDROID__
872 m_lcPoints->GetHandle()->setStyleSheet(getQtStyleSheet());
873#endif
874
875 // m_lcPoints = new OCPNTrackListCtrl( m_panel0, wxID_ANY,
876 // wxDefaultPosition, wxDefaultSize,
877 // wxLC_REPORT | wxLC_HRULES |
878 // wxLC_VRULES | wxLC_EDIT_LABELS |
879 // wxLC_VIRTUAL );
880 //
881 // m_lcPoints->Hide();
882 // m_rbShowTimeUTC = NULL;
883 // m_rbShowTimePC = NULL;
884 // m_rbShowTimeLocal = NULL;
885
886 m_panelAdvanced = new wxScrolledWindow(
887 m_notebook1, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL);
888
889 wxBoxSizer* bSizerAdvanced;
890 bSizerAdvanced = new wxBoxSizer(wxVERTICAL);
891
892 m_stDescription =
893 new wxStaticText(m_panelAdvanced, wxID_ANY, _("Description"),
894 wxDefaultPosition, wxDefaultSize, 0);
895 // m_stDescription->Wrap( -1 );
896 bSizerAdvanced->Add(m_stDescription, 0, wxALL, 5);
897
898 m_tDescription =
899 new wxTextCtrl(m_panelAdvanced, wxID_ANY, "", wxDefaultPosition,
900 wxDefaultSize, wxTE_MULTILINE);
901 bSizerAdvanced->Add(m_tDescription, 1, wxALL | wxEXPAND, 5);
902
903 sbSizerLinks = new wxStaticBoxSizer(
904 new wxStaticBox(m_panelAdvanced, wxID_ANY, _("Links")), wxVERTICAL);
905
906 m_scrolledWindowLinks =
907 new wxScrolledWindow(m_panelAdvanced, wxID_ANY, wxDefaultPosition,
908 wxDefaultSize, wxHSCROLL | wxVSCROLL);
909 m_scrolledWindowLinks->SetScrollRate(5, 5);
910 bSizerLinks = new wxBoxSizer(wxVERTICAL);
911
912 m_hyperlink1 =
913 new wxHyperlinkCtrl(m_scrolledWindowLinks, wxID_ANY, _("wxFB Website"),
914 "http://www.wxformbuilder.org", wxDefaultPosition,
915 wxDefaultSize, wxHL_DEFAULT_STYLE);
916 m_menuLink = new wxMenu();
917 m_menuItemEdit = new wxMenuItem(m_menuLink, ID_TRK_MENU_EDIT,
918 wxString(_("Edit")), "", wxITEM_NORMAL);
919 m_menuLink->Append(m_menuItemEdit);
920
921 m_menuItemAdd = new wxMenuItem(m_menuLink, ID_TRK_MENU_ADD,
922 wxString(_("Add new")), "", wxITEM_NORMAL);
923 m_menuLink->Append(m_menuItemAdd);
924
925 m_menuItemDelete = new wxMenuItem(m_menuLink, ID_TRK_MENU_DELETE,
926 wxString(_("Delete")), "", wxITEM_NORMAL);
927 m_menuLink->Append(m_menuItemDelete);
928
929 m_hyperlink1->Connect(
930 wxEVT_RIGHT_DOWN,
931 wxMouseEventHandler(TrackPropDlg::m_hyperlink1OnContextMenu), NULL, this);
932
933 bSizerLinks->Add(m_hyperlink1, 0, wxALL, 5);
934
935 m_scrolledWindowLinks->SetSizer(bSizerLinks);
936 m_scrolledWindowLinks->Layout();
937 bSizerLinks->Fit(m_scrolledWindowLinks);
938 sbSizerLinks->Add(m_scrolledWindowLinks, 1, wxEXPAND | wxALL, 5);
939
940 wxBoxSizer* bSizerLinkBtns;
941 bSizerLinkBtns = new wxBoxSizer(wxHORIZONTAL);
942
943 m_buttonAddLink =
944 new wxButton(m_panelAdvanced, wxID_ANY, _("Add"), wxDefaultPosition,
945 wxDefaultSize, wxBU_EXACTFIT);
946 bSizerLinkBtns->Add(m_buttonAddLink, 0, wxALL, 5);
947
948 m_toggleBtnEdit = new wxToggleButton(m_panelAdvanced, wxID_ANY, _("Edit"),
949 wxDefaultPosition, wxDefaultSize, 0);
950 bSizerLinkBtns->Add(m_toggleBtnEdit, 0, wxALL, 5);
951
952 m_staticTextEditEnabled = new wxStaticText(
953 m_panelAdvanced, wxID_ANY, _("Links are opened in the default browser."),
954 wxDefaultPosition, wxDefaultSize, 0);
955 // m_staticTextEditEnabled->Wrap( -1 );
956 bSizerLinkBtns->Add(m_staticTextEditEnabled, 0,
957 wxALIGN_CENTER_VERTICAL | wxALL, 5);
958
959 sbSizerLinks->Add(bSizerLinkBtns, 0, wxEXPAND, 5);
960
961 bSizerAdvanced->Add(sbSizerLinks, 1, wxEXPAND, 5);
962
963 m_panelAdvanced->SetSizer(bSizerAdvanced);
964 m_notebook1->AddPage(m_panelAdvanced, _("Advanced"), false);
965
966 // Buttons, etc...
967
968 wxBoxSizer* itemBoxSizerBottom = new wxBoxSizer(wxVERTICAL);
969 bSizerMain->Add(itemBoxSizerBottom, 0, wxALIGN_LEFT | wxALL | wxEXPAND, 5);
970
971 // wxBoxSizer* itemBoxSizerAux = new wxBoxSizer( wxHORIZONTAL );
972
973 int n_col = 5;
974
975 wxFlexGridSizer* itemBoxSizerAux = new wxFlexGridSizer(0, n_col, 0, 0);
976 itemBoxSizerAux->SetFlexibleDirection(wxBOTH);
977 itemBoxSizerAux->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_SPECIFIED);
978
979 itemBoxSizerBottom->Add(itemBoxSizerAux, 1, wxALIGN_LEFT | wxALL, 5);
980
981#ifndef __ANDROID__
982
983 m_sdbBtmBtnsSizerPrint = new wxButton(this, wxID_ANY, _("Print"),
984 wxDefaultPosition, wxDefaultSize, 0);
985 itemBoxSizerAux->Add(m_sdbBtmBtnsSizerPrint, 0,
986 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 5);
987 m_sdbBtmBtnsSizerPrint->Enable(true);
988#else
989 m_sdbBtmBtnsSizerPrint = NULL;
990#endif
991
992 m_sdbBtmBtnsSizerSplit = new wxButton(this, wxID_ANY, _("Split"),
993 wxDefaultPosition, wxDefaultSize, 0);
994 itemBoxSizerAux->Add(m_sdbBtmBtnsSizerSplit, 0,
995 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 5);
996 m_sdbBtmBtnsSizerSplit->Enable(false);
997
998 m_sdbBtmBtnsSizerExtend = new wxButton(this, wxID_ANY, _("Extend track"),
999 wxDefaultPosition, wxDefaultSize, 0);
1000 itemBoxSizerAux->Add(m_sdbBtmBtnsSizerExtend, 0,
1001 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 5);
1002
1003 m_sdbBtmBtnsSizerToRoute = new wxButton(this, wxID_ANY, _("To route"),
1004 wxDefaultPosition, wxDefaultSize, 0);
1005 itemBoxSizerAux->Add(m_sdbBtmBtnsSizerToRoute, 0,
1006 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 5);
1007
1008 m_sdbBtmBtnsSizerExport = new wxButton(this, wxID_ANY, _("Export"),
1009 wxDefaultPosition, wxDefaultSize, 0);
1010 itemBoxSizerAux->Add(m_sdbBtmBtnsSizerExport, 0,
1011 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 5);
1012
1013 wxBoxSizer* itemBoxSizer16 = new wxBoxSizer(wxHORIZONTAL);
1014 itemBoxSizerBottom->Add(itemBoxSizer16, 0, wxALIGN_RIGHT | wxALL, 5);
1015
1016 m_sdbBtmBtnsSizerCancel = new wxButton(this, wxID_CANCEL, _("Cancel"),
1017 wxDefaultPosition, wxDefaultSize, 0);
1018 itemBoxSizer16->Add(m_sdbBtmBtnsSizerCancel, 0, wxALIGN_BOTTOM | wxALL, 5);
1019
1020 m_sdbBtmBtnsSizerOK =
1021 new wxButton(this, wxID_OK, _("OK"), wxDefaultPosition, wxDefaultSize, 0);
1022 itemBoxSizer16->Add(m_sdbBtmBtnsSizerOK, 0, wxALIGN_BOTTOM | wxALL, 5);
1023 m_sdbBtmBtnsSizerOK->SetDefault();
1024
1025 // Make it look nice and add the needed non-standard buttons
1026 int w1, w2, h;
1027 ((wxWindowBase*)m_stName)->GetSize(&w1, &h);
1028 ((wxWindowBase*)m_stFrom)->GetSize(&w2, &h);
1029 ((wxWindowBase*)m_stName)->SetMinSize(wxSize(wxMax(w1, w2), h));
1030 ((wxWindowBase*)m_stFrom)->SetMinSize(wxSize(wxMax(w1, w2), h));
1031
1032 m_panelBasic->SetScrollRate(5, 5);
1033 m_panelAdvanced->SetScrollRate(5, 5);
1034}
1035
1036void TrackPropDlg::SetTrackAndUpdate(Track* pt) {
1037 m_pTrack = pt;
1038
1039 m_lcPoints->DeleteAllItems();
1040
1041 if (m_pMyLinkList) delete m_pMyLinkList;
1042 m_pMyLinkList = new HyperlinkList();
1043
1044 for (Hyperlink* link : *m_pTrack->m_TrackHyperlinkList) {
1045 Hyperlink* h = new Hyperlink();
1046 h->DescrText = link->DescrText;
1047 h->Link = link->Link;
1048 h->LType = link->LType;
1049
1050 m_pMyLinkList->push_back(h);
1051 }
1052
1053 InitializeList();
1055
1056 RecalculateSize();
1057}
1058void TrackPropDlg::InitializeList() {
1059 if (NULL == m_pTrack) return;
1060
1061 m_lcPoints->m_pTrack = m_pTrack;
1062
1063 if (m_pTrack->GetnPoints()) {
1064 TrackPoint* prp = m_pTrack->GetPoint(0);
1065 if (prp)
1066 m_lcPoints->m_LMT_Offset = long((prp->m_lon) * 3600. / 15.); // estimated
1067 else
1068 m_lcPoints->m_LMT_Offset = 0;
1069 }
1070
1071 if (m_lcPoints->IsVirtual())
1072 m_lcPoints->SetItemCount(m_pTrack->GetnPoints());
1073
1074 else {
1075 for (int in = 0; in < m_pTrack->GetnPoints(); in++) {
1076 wxListItem item;
1077 item.SetId(in);
1078
1079 m_lcPoints->InsertItem(item);
1080 for (int j = 0; j < 7; j++) {
1081 item.SetColumn(j);
1082 item.SetText(m_lcPoints->OnGetItemText(in, j));
1083 m_lcPoints->SetItem(item);
1084 }
1085 }
1086 }
1087}
1088
1090 if (NULL == m_pTrack) return false;
1091
1092 ::wxBeginBusyCursor();
1093
1094 if (m_scrolledWindowLinks) {
1095 wxWindowList kids = m_scrolledWindowLinks->GetChildren();
1096 for (unsigned int i = 0; i < kids.GetCount(); i++) {
1097 wxWindowListNode* node = kids.Item(i);
1098 wxWindow* win = node->GetData();
1099
1100 auto link_win = dynamic_cast<wxHyperlinkCtrl*>(win);
1101 if (link_win) {
1102 link_win->Disconnect(
1103 wxEVT_COMMAND_HYPERLINK,
1104 wxHyperlinkEventHandler(TrackPropDlg::OnHyperLinkClick));
1105 link_win->Disconnect(
1106 wxEVT_RIGHT_DOWN,
1107 wxMouseEventHandler(TrackPropDlg::m_hyperlinkContextMenu));
1108 win->Destroy();
1109 }
1110 }
1112 int NbrOfLinks = m_pTrack->m_TrackHyperlinkList->size();
1113 HyperlinkList* list = m_pTrack->m_TrackHyperlinkList;
1114 // int len = 0;
1115 if (NbrOfLinks > 0) {
1116 for (auto it = list->begin(); it != list->end(); ++it) {
1117 Hyperlink* link = *it;
1118 wxString Link = link->Link;
1119 wxString Descr = link->DescrText;
1120
1121 wxHyperlinkCtrl* ctrl = new wxHyperlinkCtrl(
1122 m_scrolledWindowLinks, wxID_ANY, Descr, Link, wxDefaultPosition,
1123 wxDefaultSize, wxHL_DEFAULT_STYLE);
1124 ctrl->Connect(wxEVT_COMMAND_HYPERLINK,
1125 wxHyperlinkEventHandler(TrackPropDlg::OnHyperLinkClick),
1126 NULL, this);
1127 if (!m_pTrack->m_bIsInLayer)
1128 ctrl->Connect(
1129 wxEVT_RIGHT_DOWN,
1130 wxMouseEventHandler(TrackPropDlg::m_hyperlinkContextMenu), NULL,
1131 this);
1132
1133 bSizerLinks->Add(ctrl, 0, wxALL, 5);
1134 }
1135 }
1136 bSizerLinks->Fit(m_scrolledWindowLinks);
1137 }
1138
1139 m_tName->SetValue(m_pTrack->GetName());
1140 m_tFrom->SetValue(m_pTrack->m_TrackStartString);
1141 m_tTo->SetValue(m_pTrack->m_TrackEndString);
1142 if (m_tDescription) m_tDescription->SetValue(m_pTrack->m_TrackDescription);
1143
1144 m_tTotDistance->SetValue("");
1145 m_tTimeEnroute->SetValue("");
1146
1147 m_sdbBtmBtnsSizerSplit->Enable(false);
1148 m_sdbBtmBtnsSizerExtend->Enable(false);
1149
1150 // Calculate AVG speed if we are showing a track and total time
1151 TrackPoint* last_point = m_pTrack->GetLastPoint();
1152 TrackPoint* first_point = m_pTrack->GetPoint(0);
1153 double trackLength = m_pTrack->Length();
1154 double total_seconds = 0.;
1155
1156 wxString speed("--");
1157
1158 if (last_point && first_point) {
1159 if (last_point->GetCreateTime().IsValid() &&
1160 first_point->GetCreateTime().IsValid()) {
1161 total_seconds = last_point->GetCreateTime()
1162 .Subtract(first_point->GetCreateTime())
1163 .GetSeconds()
1164 .ToDouble();
1165 if (total_seconds != 0.) {
1166 m_avgspeed = trackLength / total_seconds * 3600;
1167 } else {
1168 m_avgspeed = 0;
1169 }
1170 speed.Printf("%5.2f", toUsrSpeed(m_avgspeed));
1171 }
1172 }
1173
1174 m_tAvgSpeed->SetValue(speed);
1175
1176 // Total length
1177 wxString slen;
1178 slen.Printf("%5.2f " + getUsrDistanceUnit(), toUsrDistance(trackLength));
1179
1180 m_tTotDistance->SetValue(slen);
1181
1182 // Time
1183 wxString time_form;
1184 wxTimeSpan time(0, 0, (int)total_seconds, 0);
1185 // TODO Construct a readable time string, e.g. "xx Days, 15:34"
1186 if (total_seconds > 3600. * 24.)
1187 time_form = time.Format("%H:%M");
1188 else if (total_seconds > 0.)
1189 time_form = time.Format("%H:%M");
1190 else
1191 time_form = "--";
1192 m_tTimeEnroute->SetValue(time_form);
1193
1194 m_cbShow->SetValue(m_pTrack->IsVisible());
1195
1196 if (m_pTrack->m_Colour == "")
1197 m_cColor->Select(0);
1198 else {
1199 for (unsigned int i = 0; i < sizeof(::GpxxColorNames) / sizeof(wxString);
1200 i++) {
1201 if (m_pTrack->m_Colour == ::GpxxColorNames[i]) {
1202 m_cColor->Select(i + 1);
1203 break;
1204 }
1205 }
1206 }
1207
1208 for (unsigned int i = 0; i < sizeof(::StyleValues) / sizeof(int); i++) {
1209 if (m_pTrack->m_style == ::StyleValues[i]) {
1210 m_cStyle->Select(i);
1211 break;
1212 }
1213 }
1214
1215 for (unsigned int i = 0; i < sizeof(::WidthValues) / sizeof(int); i++) {
1216 if (m_pTrack->m_width == ::WidthValues[i]) {
1217 m_cWidth->Select(i);
1218 break;
1219 }
1220 }
1221
1222 if (m_pTrack->m_bIsInLayer) {
1223 m_tName->SetEditable(false);
1224 m_tFrom->SetEditable(false);
1225 m_tTo->SetEditable(false);
1226 if (m_tDescription) m_tDescription->SetEditable(false);
1227 m_cbShow->Enable(false);
1228 m_cColor->Enable(false);
1229 m_cStyle->Enable(false);
1230 m_cWidth->Enable(false);
1231 m_sdbBtmBtnsSizerExtend->Enable(false);
1232 m_sdbBtmBtnsSizerSplit->Enable(false);
1233 SetTitle(wxString::Format("%s, %s: %d", _("Track properties"), "Layer",
1234 m_pTrack->m_LayerID));
1235 } else {
1236 m_tName->SetEditable(true);
1237 m_tFrom->SetEditable(true);
1238 m_tTo->SetEditable(true);
1239 if (m_tDescription) m_tDescription->SetEditable(true);
1240 m_cbShow->Enable(true);
1241 m_cColor->Enable(true);
1242 m_cStyle->Enable(true);
1243 m_cWidth->Enable(true);
1244
1245 m_sdbBtmBtnsSizerExtend->Enable(IsThisTrackExtendable());
1246 // m_sdbBtmBtnsSizerSplit->Enable( false );
1247 SetTitle(_("Track properties"));
1248 }
1249
1250 ::wxEndBusyCursor();
1251
1252 return true;
1253}
1254
1255bool TrackPropDlg::IsThisTrackExtendable() {
1256 m_pExtendTrack = NULL;
1257 m_pExtendPoint = NULL;
1258 if (m_pTrack == g_pActiveTrack || m_pTrack->m_bIsInLayer) {
1259 return false;
1260 }
1261
1262 TrackPoint* pLastPoint = m_pTrack->GetPoint(0);
1263 if (!pLastPoint->GetCreateTime().IsValid()) {
1264 return false;
1265 }
1266
1267 for (Track* ptrack : g_TrackList) {
1268 if (ptrack->IsVisible() && (ptrack->m_GUID != m_pTrack->m_GUID)) {
1269 TrackPoint* track_node = ptrack->GetLastPoint();
1270 if (track_node) {
1271 if (track_node->GetCreateTime().IsValid()) {
1272 if (track_node->GetCreateTime() <= pLastPoint->GetCreateTime()) {
1273 if (!m_pExtendPoint ||
1274 track_node->GetCreateTime() > m_pExtendPoint->GetCreateTime()) {
1275 m_pExtendPoint = track_node;
1276 m_pExtendTrack = ptrack;
1277 }
1278 }
1279 }
1280 }
1281 }
1282 }
1283 if (m_pExtendTrack) {
1284 return (!m_pExtendTrack->m_bIsInLayer);
1285 } else {
1286 return false;
1287 }
1288}
1289
1290void TrackPropDlg::OnExtendBtnClick(wxCommandEvent& event) {
1291 TrackPoint* pFirstPoint = m_pTrack->GetPoint(0);
1292
1293 if (IsThisTrackExtendable()) {
1294 int begin = 0;
1295 if (pFirstPoint->GetCreateTime() == m_pExtendPoint->GetCreateTime()) {
1296 begin = 1;
1297 }
1298 pSelect->DeleteAllSelectableTrackSegments(m_pExtendTrack);
1299 m_pExtendTrack->Clone(m_pTrack, begin, m_pTrack->GetnPoints(), _("_plus"));
1300 pSelect->AddAllSelectableTrackSegments(m_pExtendTrack);
1301 pSelect->DeleteAllSelectableTrackSegments(m_pTrack);
1302 NavObj_dB::GetInstance().DeleteTrack(m_pTrack);
1303 RoutemanGui(*g_pRouteMan).DeleteTrack(m_pTrack);
1304
1305 SetTrackAndUpdate(m_pExtendTrack);
1306 NavObj_dB::GetInstance().UpdateTrack(m_pTrack);
1308
1309 if (pRouteManagerDialog && pRouteManagerDialog->IsShown()) {
1310 pRouteManagerDialog->UpdateTrkListCtrl();
1311 }
1312 }
1313}
1314
1315void TrackPropDlg::OnSplitBtnClick(wxCommandEvent& event) {
1316 m_sdbBtmBtnsSizerSplit->Enable(false);
1317
1318 if (m_pTrack->m_bIsInLayer) {
1319 return;
1320 }
1321
1322 if ((m_nSelected > 1) && (m_nSelected < m_pTrack->GetnPoints())) {
1323 Track* pHead = new Track();
1324 Track* pTail = new Track();
1325 pHead->Clone(m_pTrack, 0, m_nSelected - 1, _("_A"));
1326 pTail->Clone(m_pTrack, m_nSelected - 1, m_pTrack->GetnPoints(), _("_B"));
1327
1328 g_TrackList.push_back(pHead);
1329 NavObj_dB::GetInstance().InsertTrack(pHead);
1330
1331 g_TrackList.push_back(pTail);
1332 NavObj_dB::GetInstance().InsertTrack(pTail);
1333
1334 NavObj_dB::GetInstance().DeleteTrack(m_pTrack);
1335
1336 pSelect->DeleteAllSelectableTrackSegments(m_pTrack);
1337 RoutemanGui(*g_pRouteMan).DeleteTrack(m_pTrack);
1338 pSelect->AddAllSelectableTrackSegments(pTail);
1339 pSelect->AddAllSelectableTrackSegments(pHead);
1340
1341 SetTrackAndUpdate(pTail);
1343
1344 if (pRouteManagerDialog && pRouteManagerDialog->IsShown()) {
1345 pRouteManagerDialog->UpdateTrkListCtrl();
1346 }
1347 }
1348}
1349
1350void TrackPropDlg::OnTrackPropCopyTxtClick(wxCommandEvent& event) {
1351 wxString tab("\t", wxConvUTF8);
1352 wxString eol("\n", wxConvUTF8);
1353 wxString csvString;
1354
1355 csvString << this->GetTitle() << eol << _("Name") << tab
1356 << m_pTrack->GetName() << eol << _("Depart From") << tab
1357 << m_pTrack->m_TrackStartString << eol << _("Destination") << tab
1358 << m_pTrack->m_TrackEndString << eol << _("Total distance") << tab
1359 << m_tTotDistance->GetValue() << eol << _("Speed") << tab
1360 << m_tAvgSpeed->GetValue() << eol
1361 << _("Departure Time") + " " + _("(m/d/y h:m)") << tab
1362 << m_pTrack->GetPoint(1)->GetCreateTime().Format() << eol
1363 << _("Time enroute") << tab << m_tTimeEnroute->GetValue() << eol
1364 << eol;
1365
1366 int noCols;
1367 int noRows;
1368 noCols = m_lcPoints->GetColumnCount();
1369 noRows = m_lcPoints->GetItemCount();
1370 wxListItem item;
1371 item.SetMask(wxLIST_MASK_TEXT);
1372
1373 for (int i = 0; i < noCols; i++) {
1374 m_lcPoints->GetColumn(i, item);
1375 csvString << item.GetText() << tab;
1376 }
1377 csvString << eol;
1378
1379 for (int j = 0; j < noRows; j++) {
1380 item.SetId(j);
1381 for (int i = 0; i < noCols; i++) {
1382 item.SetColumn(i);
1383 m_lcPoints->GetItem(item);
1384 csvString << item.GetText() << tab;
1385 }
1386 csvString << eol;
1387 }
1388
1389 if (wxTheClipboard->Open()) {
1390 wxTextDataObject* data = new wxTextDataObject;
1391 data->SetText(csvString);
1392 wxTheClipboard->SetData(data);
1393 wxTheClipboard->Close();
1394 }
1395}
1396
1397void TrackPropDlg::OnPrintBtnClick(wxCommandEvent& event) {
1398 static std::set<int> s_options; // keep selected options
1399 TrackPrintDialog dlg(this, s_options);
1400 int result = dlg.ShowModal();
1401
1402 if (result == wxID_OK) {
1403 dlg.GetSelected(s_options);
1404 TrackPrintout printout(m_pTrack, m_lcPoints, s_options);
1405 auto& printer = PrintDialog::GetInstance();
1406 printer.Initialize(wxPORTRAIT);
1407 printer.EnablePageNumbers(true);
1408 printer.Print(this, &printout);
1409 }
1410}
1411
1412void TrackPropDlg::OnTrackPropRightClick(wxListEvent& event) {
1413 wxMenu menu;
1414
1415 wxMenuItem* copyItem =
1416 menu.Append(ID_RCLK_MENU_COPY_TEXT, _("&Copy all as text"));
1417
1418 PopupMenu(&menu);
1419}
1420
1421void TrackPropDlg::OnTrackPropListClick(wxListEvent& event) {
1422 long itemno = -1;
1423 m_nSelected = 0;
1424
1425 int selected_no;
1426 itemno =
1427 m_lcPoints->GetNextItem(itemno, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
1428 if (itemno == -1)
1429 selected_no = 0;
1430 else
1431 selected_no = itemno;
1432
1433 m_pTrack->m_HighlightedTrackPoint = -1;
1434
1435 if (itemno >= 0) {
1436 TrackPoint* prp = m_pTrack->GetPoint(itemno);
1437 if (prp) {
1438 m_pTrack->m_HighlightedTrackPoint = itemno; // highlight the trackpoint
1439
1440 if (!(m_pTrack->m_bIsInLayer) && !(m_pTrack == g_pActiveTrack)) {
1441 m_nSelected = selected_no + 1;
1442 m_sdbBtmBtnsSizerSplit->Enable(true);
1443 }
1444 if (gFrame->GetFocusCanvas()) {
1445 gFrame->JumpToPosition(gFrame->GetFocusCanvas(), prp->m_lat, prp->m_lon,
1446 gFrame->GetFocusCanvas()->GetVPScale());
1447 }
1448#ifdef __WXMSW__
1449 if (m_lcPoints) m_lcPoints->SetFocus();
1450#endif
1451 }
1452 }
1453 if (selected_no == 0 || selected_no == m_pTrack->GetnPoints() - 1)
1454 m_sdbBtmBtnsSizerSplit->Enable(false);
1455}
1456
1457void TrackPropDlg::OnTrackPropMenuSelected(wxCommandEvent& event) {
1458 switch (event.GetId()) {
1459 case ID_RCLK_MENU_COPY_TEXT:
1460 OnTrackPropCopyTxtClick(event);
1461 break;
1462 }
1463}
1464
1465void TrackPropDlg::OnToRouteBtnClick(wxCommandEvent& event) {
1466 pRouteManagerDialog->TrackToRoute(m_pTrack);
1467 if (NULL != pRouteManagerDialog && pRouteManagerDialog->IsVisible())
1468 pRouteManagerDialog->UpdateRouteListCtrl();
1469}
1470
1471void TrackPropDlg::OnExportBtnClick(wxCommandEvent& event) {
1472 wxString suggested_name = _("track");
1473 std::vector<Track*> list = {m_pTrack};
1474 if (m_pTrack->GetName() != "") suggested_name = m_pTrack->GetName();
1475 ExportGPXTracks(this, &list, suggested_name);
1476}
1477
1478void TrackPropDlg::m_hyperlinkContextMenu(wxMouseEvent& event) {
1479 m_pEditedLink = (wxHyperlinkCtrl*)event.GetEventObject();
1480 Connect(
1481 wxEVT_COMMAND_MENU_SELECTED,
1482 (wxObjectEventFunction)(wxEventFunction)&TrackPropDlg::PopupMenuHandler);
1483 m_scrolledWindowLinks->PopupMenu(
1484 m_menuLink, m_pEditedLink->GetPosition().x + event.GetPosition().x,
1485 m_pEditedLink->GetPosition().y + event.GetPosition().y);
1486}
1487
1488void TrackPropDlg::PopupMenuHandler(wxCommandEvent& event) {
1489 switch (event.GetId()) {
1490 case ID_TRK_MENU_ADD:
1491 OnAddLink(event);
1492 break;
1493 case ID_TRK_MENU_EDIT:
1494 OnEditLink(event);
1495 break;
1496 case ID_TRK_MENU_DELETE:
1497 OnDeleteLink(event);
1498 break;
1499 default:
1500 break;
1501 }
1502}
1503
1504void TrackPropDlg::OnDeleteLink(wxCommandEvent& event) {
1505 wxString findurl = m_pEditedLink->GetURL();
1506 wxString findlabel = m_pEditedLink->GetLabel();
1507
1508 wxWindowList kids = m_scrolledWindowLinks->GetChildren();
1509 for (unsigned int i = 0; i < kids.GetCount(); i++) {
1510 wxWindowListNode* node = kids.Item(i);
1511 wxWindow* win = node->GetData();
1512
1513 auto link_win = dynamic_cast<wxHyperlinkCtrl*>(win);
1514 if (link_win) {
1515 link_win->Disconnect(
1516 wxEVT_COMMAND_HYPERLINK,
1517 wxHyperlinkEventHandler(TrackPropDlg::OnHyperLinkClick));
1518 link_win->Disconnect(
1519 wxEVT_RIGHT_DOWN,
1520 wxMouseEventHandler(TrackPropDlg::m_hyperlinkContextMenu));
1521 win->Destroy();
1522 }
1523 }
1524
1525 HyperlinkList* list = m_pTrack->m_TrackHyperlinkList;
1526 auto nodeToDelete = list->end();
1527 for (auto it = list->begin(); it != list->end(); it++) {
1528 Hyperlink* link = *it;
1529 wxString Link = link->Link;
1530 wxString Descr = link->DescrText;
1531 if (Link == findurl &&
1532 (Descr == findlabel || (Link == findlabel && Descr == "")))
1533 nodeToDelete = it;
1534 else {
1535 wxHyperlinkCtrl* ctrl = new wxHyperlinkCtrl(
1536 m_scrolledWindowLinks, wxID_ANY, Descr, Link, wxDefaultPosition,
1537 wxDefaultSize, wxHL_DEFAULT_STYLE);
1538 ctrl->Connect(wxEVT_COMMAND_HYPERLINK,
1539 wxHyperlinkEventHandler(TrackPropDlg::OnHyperLinkClick),
1540 NULL, this);
1541 ctrl->Connect(wxEVT_RIGHT_DOWN,
1542 wxMouseEventHandler(TrackPropDlg::m_hyperlinkContextMenu),
1543 NULL, this);
1544
1545 bSizerLinks->Add(ctrl, 0, wxALL, 5);
1546 }
1547 }
1548 if (nodeToDelete != list->end()) list->erase(nodeToDelete);
1549 m_scrolledWindowLinks->InvalidateBestSize();
1550 m_scrolledWindowLinks->Layout();
1551 sbSizerLinks->Layout();
1552 // event.Skip();
1553}
1554
1555void TrackPropDlg::OnEditLink(wxCommandEvent& event) {
1556 wxString findurl = m_pEditedLink->GetURL();
1557 wxString findlabel = m_pEditedLink->GetLabel();
1558
1559 LinkPropImpl* LinkPropDlg = new LinkPropImpl(this);
1560 LinkPropDlg->m_textCtrlLinkDescription->SetValue(findlabel);
1561 LinkPropDlg->m_textCtrlLinkUrl->SetValue(findurl);
1562 DimeControl(LinkPropDlg);
1563 LinkPropDlg->ShowWindowModalThenDo([this, LinkPropDlg, findurl,
1564 findlabel](int retcode) {
1565 if (retcode == wxID_OK) {
1566 int NbrOfLinks = m_pTrack->m_TrackHyperlinkList->size();
1567 HyperlinkList* list = m_pTrack->m_TrackHyperlinkList;
1568 // int len = 0;
1569 if (NbrOfLinks > 0) {
1570 for (auto it = list->begin(); it != list->end(); it++) {
1571 Hyperlink* link = *it;
1572 wxString Link = link->Link;
1573 wxString Descr = link->DescrText;
1574 if (Link == findurl &&
1575 (Descr == findlabel || (Link == findlabel && Descr == ""))) {
1576 link->Link = LinkPropDlg->m_textCtrlLinkUrl->GetValue();
1577 link->DescrText =
1578 LinkPropDlg->m_textCtrlLinkDescription->GetValue();
1579 wxHyperlinkCtrl* h =
1580 (wxHyperlinkCtrl*)m_scrolledWindowLinks->FindWindowByLabel(
1581 findlabel);
1582 if (h) {
1583 h->SetLabel(LinkPropDlg->m_textCtrlLinkDescription->GetValue());
1584 h->SetURL(LinkPropDlg->m_textCtrlLinkUrl->GetValue());
1585 }
1586 }
1587 }
1588 }
1589
1590 m_scrolledWindowLinks->InvalidateBestSize();
1591 m_scrolledWindowLinks->Layout();
1592 sbSizerLinks->Layout();
1593 }
1594 });
1595 // event.Skip();
1596}
1597
1598void TrackPropDlg::OnAddLink(wxCommandEvent& event) {
1599 LinkPropImpl* LinkPropDlg = new LinkPropImpl(this);
1600 LinkPropDlg->m_textCtrlLinkDescription->SetValue("");
1601 LinkPropDlg->m_textCtrlLinkUrl->SetValue("");
1602 DimeControl(LinkPropDlg);
1603 LinkPropDlg->ShowWindowModalThenDo([this, LinkPropDlg](int retcode) {
1604 if (retcode == wxID_OK) {
1605 wxString desc = LinkPropDlg->m_textCtrlLinkDescription->GetValue();
1606 if (desc == "") desc = LinkPropDlg->m_textCtrlLinkUrl->GetValue();
1607 wxHyperlinkCtrl* ctrl = new wxHyperlinkCtrl(
1608 m_scrolledWindowLinks, wxID_ANY, desc,
1609 LinkPropDlg->m_textCtrlLinkUrl->GetValue(), wxDefaultPosition,
1610 wxDefaultSize, wxHL_DEFAULT_STYLE);
1611 ctrl->Connect(wxEVT_COMMAND_HYPERLINK,
1612 wxHyperlinkEventHandler(TrackPropDlg::OnHyperLinkClick),
1613 NULL, this);
1614 ctrl->Connect(wxEVT_RIGHT_DOWN,
1615 wxMouseEventHandler(TrackPropDlg::m_hyperlinkContextMenu),
1616 NULL, this);
1617
1618 bSizerLinks->Add(ctrl, 0, wxALL, 5);
1619 bSizerLinks->Fit(m_scrolledWindowLinks);
1620 // this->Fit();
1621
1622 Hyperlink* h = new Hyperlink();
1623 h->DescrText = LinkPropDlg->m_textCtrlLinkDescription->GetValue();
1624 h->Link = LinkPropDlg->m_textCtrlLinkUrl->GetValue();
1625 h->LType = "";
1626 m_pTrack->m_TrackHyperlinkList->push_back(h);
1627 }
1628 });
1629 // sbSizerLinks->Layout();
1630
1631 m_scrolledWindowLinks->InvalidateBestSize();
1632 m_scrolledWindowLinks->Layout();
1633 sbSizerLinks->Layout();
1634
1635 // event.Skip();
1636}
1637
1638void TrackPropDlg::OnEditLinkToggle(wxCommandEvent& event) {
1639 if (m_toggleBtnEdit->GetValue())
1640 m_staticTextEditEnabled->SetLabel(_("Links are opened for editing."));
1641 else
1642 m_staticTextEditEnabled->SetLabel(
1643 _("Links are opened in the default browser."));
1644 event.Skip();
1645}
1646
1647void TrackPropDlg::OnHyperLinkClick(wxHyperlinkEvent& event) {
1648 if (m_toggleBtnEdit->GetValue()) {
1649 m_pEditedLink = (wxHyperlinkCtrl*)event.GetEventObject();
1650 OnEditLink(event);
1651 event.Skip(false);
1652 return;
1653 }
1654 // Windows has trouble handling local file URLs with embedded anchor
1655 // points, e.g file://testfile.html#point1 The trouble is with the
1656 // wxLaunchDefaultBrowser with verb "open" Workaround is to probe the
1657 // registry to get the default browser, and open directly
1658 //
1659 // But, we will do this only if the URL contains the anchor point charater
1660 // '#' What a hack......
1661
1662#ifdef __WXMSW__
1663
1664 wxString cc = event.GetURL();
1665 if (cc.Find("#") != wxNOT_FOUND) {
1666 wxRegKey RegKey(wxString("HKEY_CLASSES_ROOT\\HTTP\\shell\\open\\command"));
1667 if (RegKey.Exists()) {
1668 wxString command_line;
1669 RegKey.QueryValue(wxString(""), command_line);
1670
1671 // Remove "
1672 command_line.Replace(wxString("\""), wxString(""));
1673
1674 // Strip arguments
1675 int l = command_line.Find(".exe");
1676 if (wxNOT_FOUND == l) l = command_line.Find(".EXE");
1677
1678 if (wxNOT_FOUND != l) {
1679 wxString cl = command_line.Mid(0, l + 4);
1680 cl += " ";
1681 cc.Prepend("\"");
1682 cc.Append("\"");
1683 cl += cc;
1684 wxExecute(cl); // Async, so Fire and Forget...
1685 }
1686 }
1687 } else
1688 event.Skip();
1689#else
1690 wxString url = event.GetURL();
1691 url.Replace(" ", "%20");
1692 ::wxLaunchDefaultBrowser(url);
1693// event.Skip();
1694#endif
1695}
1696
1697void TrackPropDlg::OnShowTimeTZ(wxCommandEvent& event) {
1698 if (m_rbShowTimeUTC && m_rbShowTimeUTC->GetValue())
1699 m_lcPoints->m_tz_selection = UTCINPUT;
1700 else if (m_rbShowTimePC && m_rbShowTimePC->GetValue())
1701 m_lcPoints->m_tz_selection = LTINPUT;
1702 else if (m_rbShowTimeLocal && m_rbShowTimeLocal->GetValue())
1703 m_lcPoints->m_tz_selection = LMTINPUT;
1706 else
1707 throw std::logic_error("Unexpected time zone selection");
1708 m_lcPoints->DeleteAllItems();
1709 InitializeList();
1710}
1711
1712bool TrackPropDlg::SaveChanges() {
1713 if (m_pTrack && !m_pTrack->m_bIsInLayer) {
1714 // Get User input Text Fields
1715 m_pTrack->SetName(m_tName->GetValue());
1716 m_pTrack->m_TrackStartString = m_tFrom->GetValue();
1717 m_pTrack->m_TrackEndString = m_tTo->GetValue();
1718 if (m_tDescription)
1719 m_pTrack->m_TrackDescription = m_tDescription->GetValue();
1720 m_pTrack->SetVisible(m_cbShow->GetValue());
1721 if (m_cColor->GetSelection() == 0)
1722 m_pTrack->m_Colour = "";
1723 else
1724 m_pTrack->m_Colour = ::GpxxColorNames[m_cColor->GetSelection() - 1];
1725 m_pTrack->m_style = (wxPenStyle)::StyleValues[m_cStyle->GetSelection()];
1726 m_pTrack->m_width = ::WidthValues[m_cWidth->GetSelection()];
1727
1728 NavObj_dB::GetInstance().UpdateDBTrackAttributes(m_pTrack);
1729
1730 pConfig->UpdateSettings();
1731 }
1732
1733 if (m_pTrack && m_pTrack->IsRunning()) {
1734 wxJSONValue v;
1735 v["Changed"] = true;
1736 v["Name"] = m_pTrack->GetName();
1737 v["GUID"] = m_pTrack->m_GUID;
1738 wxString msg_id("OCPN_TRK_ACTIVATED");
1739 SendJSONMessageToAllPlugins(msg_id, v);
1740 }
1741
1742 return true;
1743}
1744
1745void TrackPropDlg::OnOKBtnClick(wxCommandEvent& event) {
1746 // Look in the track list to be sure the track is still available
1747 // (May have been deleted by RouteManagerDialog...)
1748
1749 bool b_found_track = std::find(g_TrackList.begin(), g_TrackList.end(),
1750 m_pTrack) != g_TrackList.end();
1751
1752 if (b_found_track) {
1753 SaveChanges(); // write changes to globals and update config
1754 m_pTrack->ClearHighlights();
1755 }
1756
1757 m_bStartNow = false;
1758
1759 if (pRouteManagerDialog && pRouteManagerDialog->IsShown())
1760 pRouteManagerDialog->UpdateTrkListCtrl();
1761
1762 Hide();
1763 gFrame->InvalidateAllGL();
1764 gFrame->RefreshAllCanvas(false);
1765
1766 event.Skip();
1767}
1768
1769void TrackPropDlg::OnCancelBtnClick(wxCommandEvent& event) {
1770 bool b_found_track = std::find(g_TrackList.begin(), g_TrackList.end(),
1771 m_pTrack) != g_TrackList.end();
1772
1773 if (b_found_track) m_pTrack->ClearHighlights();
1774
1775 Hide();
1776 gFrame->InvalidateAllGL();
1777 gFrame->RefreshAllCanvas(false);
1778
1779 event.Skip();
1780}
1781
1782//--------------------------------------------------------------------------------------
1783// OCPNTrackListCtrl Implementation
1784//---------------------------------------------------------------------------------------
1785
1786OCPNTrackListCtrl::OCPNTrackListCtrl(wxWindow* parent, wxWindowID id,
1787 const wxPoint& pos, const wxSize& size,
1788 long style)
1789 : wxListCtrl(parent, id, pos, size, style) {
1790 m_parent = parent;
1791 m_tz_selection = GLOBAL_SETTINGS_INPUT;
1792 m_LMT_Offset = 0;
1793}
1794
1795OCPNTrackListCtrl::~OCPNTrackListCtrl() {}
1796
1798 if (m_pTrack->GetnPoints()) {
1799 TrackPoint* prp = m_pTrack->GetPoint(0);
1800 if (prp) return prp->m_lon;
1801 }
1802 return NAN;
1803}
1804
1805wxString OCPNTrackListCtrl::OnGetItemText(long item, long column) const {
1806 wxString ret;
1807
1808 if (item < 0 || item >= m_pTrack->GetnPoints()) return "";
1809
1810 TrackPoint* this_point = m_pTrack->GetPoint(item);
1811 TrackPoint* prev_point = item > 0 ? m_pTrack->GetPoint(item - 1) : NULL;
1812
1813 if (!this_point) return "";
1814
1815 double gt_brg, gt_leg_dist;
1816 double slat, slon;
1817 if (item == 0) {
1818 slat = gLat;
1819 slon = gLon;
1820 } else {
1821 slat = prev_point->m_lat;
1822 slon = prev_point->m_lon;
1823 }
1824
1825 switch (column) {
1826 case 0:
1827 if (item == 0)
1828 ret = "---";
1829 else
1830 ret.Printf("%ld", item);
1831 break;
1832
1833 case 1:
1834 DistanceBearingMercator(this_point->m_lat, this_point->m_lon, slat, slon,
1835 &gt_brg, &gt_leg_dist);
1836
1837 ret.Printf("%6.2f " + getUsrDistanceUnit(), toUsrDistance(gt_leg_dist));
1838 break;
1839
1840 case 2:
1841 DistanceBearingMercator(this_point->m_lat, this_point->m_lon, slat, slon,
1842 &gt_brg, &gt_leg_dist);
1843 ret.Printf("%03.0f %cT", gt_brg, 0x00B0);
1844 break;
1845
1846 case 3:
1847 ret = toSDMM(1, this_point->m_lat, 1);
1848 break;
1849
1850 case 4:
1851 ret = toSDMM(2, this_point->m_lon, 1);
1852 break;
1853
1854 case 5: {
1855 wxDateTime timestamp = this_point->GetCreateTime();
1856 if (timestamp.IsValid()) {
1859 .SetTimezone(getDatetimeTimezoneSelector(m_tz_selection))
1861 ret = ocpn::toUsrDateTimeFormat(timestamp.FromUTC(), opts);
1862 } else
1863 ret = "----";
1864 } break;
1865
1866 case 6:
1867 if ((item > 0) && this_point->GetCreateTime().IsValid() &&
1868 prev_point->GetCreateTime().IsValid()) {
1869 DistanceBearingMercator(this_point->m_lat, this_point->m_lon, slat,
1870 slon, &gt_brg, &gt_leg_dist);
1871 double speed = 0.;
1872 double seconds = this_point->GetCreateTime()
1873 .Subtract(prev_point->GetCreateTime())
1874 .GetSeconds()
1875 .ToDouble();
1876
1877 if (seconds > 0.) speed = gt_leg_dist / seconds * 3600;
1878
1879 ret.Printf("%5.2f", toUsrSpeed(speed));
1880 } else
1881 ret = _("--");
1882 break;
1883
1884 default:
1885 break;
1886 }
1887
1888 return ret;
1889}
1890
1891int OCPNTrackListCtrl::OnGetItemColumnImage(long item, long column) const {
1892 return -1;
1893}
Generic Chart canvas base.
float GetVPScale()
Return the ViewPort scale factor, in physical pixels per meter.
Definition chcanv.h:472
Class LinkPropImpl.
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:59
wxDateTime GetCreateTime(void)
Retrieves the creation timestamp of a track point as a wxDateTime object.
Definition track.cpp:138
Input dialog with track print selection.
Printout a table with track selected information.
Class TrackPropDlg.
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:117
The JSON value class implementation.
Definition jsonval.h:84
std::vector< OCPN_MonitorInfo > g_monitor_info
Information about the monitors connected to the system.
Definition displays.cpp:45
OpenCPN Georef utility.
Platform independent GL includes.
wxFont * GetOCPNScaledFont(wxString item, int default_size)
Retrieves a font from FontMgr, optionally scaled for physical readability.
Definition gui_lib.cpp:61
General purpose GUI support.
size_t g_current_monitor
Current monitor displaying main application frame.
Definition gui_vars.cpp:75
Miscellaneous globals primarely used by gui layer, not persisted in configuration file.
MySQL based storage for routes, tracks, etc.
Utility functions.
double toUsrDistance(double nm_distance, int unit)
Convert a distance from nautical miles (NMi) to user display units.
Navigation Utility Functions without GUI dependencies.
OpenCPN top window.
OpenCPN Platform specific support utilities.
double gLat
Vessel's current latitude in decimal degrees.
Definition own_ship.cpp:26
double gLon
Vessel's current longitude in decimal degrees.
Definition own_ship.cpp:27
Position, course, speed, etc.
Tools to send data to plugins.
PlugInManager and helper classes – Mostly gui parts (dialogs) and plugin API stuff.
Generic, styled prit dialog.
Route abstraction.
#define LMTINPUT
Format date/time using the remote location LMT time.
#define GLOBAL_SETTINGS_INPUT
Format date/time according to global OpenCPN settings.
#define UTCINPUT
Format date/time in UTC.
#define LTINPUT
Format date/time using timezone configured in the operating system./*#end#*‍/.
Route Manager.
Routeman drawing stuff.
Manage routes dialog.
Select * pSelect
Global instance.
Definition select.cpp:36
Selected route, segment, waypoint, etc.
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.
ActiveTrack * g_pActiveTrack
global instance
Definition track.cpp:99
std::vector< Track * > g_TrackList
Global instance.
Definition track.cpp:96
Recorded track abstraction.
Track print dialog.
#define LMTINPUT
Format date/time using Local Mean Time (LMT) at a given point./*#end#*‍/.
#define GLOBAL_SETTINGS_INPUT
Format date/time according to global OpenCPN settings.
#define UTCINPUT
Format date/time in UTC.
#define LTINPUT
Format date/time using timezone configured in the operating system./*#end#*‍/.
TrackPropDlg * pTrackPropDialog
Global instance.
Track Properties Dialog.