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