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 "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
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 wxWindowList kids = m_scrolledWindowLinks->GetChildren();
1099 for (unsigned int i = 0; i < kids.GetCount(); i++) {
1100 wxWindowListNode* node = kids.Item(i);
1101 wxWindow* win = node->GetData();
1102
1103 auto link_win = dynamic_cast<wxHyperlinkCtrl*>(win);
1104 if (link_win) {
1105 link_win->Disconnect(
1106 wxEVT_COMMAND_HYPERLINK,
1107 wxHyperlinkEventHandler(TrackPropDlg::OnHyperLinkClick));
1108 link_win->Disconnect(
1109 wxEVT_RIGHT_DOWN,
1110 wxMouseEventHandler(TrackPropDlg::m_hyperlinkContextMenu));
1111 win->Destroy();
1112 }
1113 }
1115 int NbrOfLinks = m_pTrack->m_TrackHyperlinkList->size();
1116 HyperlinkList* list = m_pTrack->m_TrackHyperlinkList;
1117 // int len = 0;
1118 if (NbrOfLinks > 0) {
1119 for (auto it = list->begin(); it != list->end(); ++it) {
1120 Hyperlink* link = *it;
1121 wxString Link = link->Link;
1122 wxString Descr = link->DescrText;
1123
1124 wxHyperlinkCtrl* ctrl = new wxHyperlinkCtrl(
1125 m_scrolledWindowLinks, wxID_ANY, Descr, Link, wxDefaultPosition,
1126 wxDefaultSize, wxHL_DEFAULT_STYLE);
1127 ctrl->Connect(wxEVT_COMMAND_HYPERLINK,
1128 wxHyperlinkEventHandler(TrackPropDlg::OnHyperLinkClick),
1129 NULL, this);
1130 if (!m_pTrack->m_bIsInLayer)
1131 ctrl->Connect(
1132 wxEVT_RIGHT_DOWN,
1133 wxMouseEventHandler(TrackPropDlg::m_hyperlinkContextMenu), NULL,
1134 this);
1135
1136 bSizerLinks->Add(ctrl, 0, wxALL, 5);
1137 }
1138 }
1139 bSizerLinks->Fit(m_scrolledWindowLinks);
1140 }
1141
1142 m_tName->SetValue(m_pTrack->GetName());
1143 m_tFrom->SetValue(m_pTrack->m_TrackStartString);
1144 m_tTo->SetValue(m_pTrack->m_TrackEndString);
1145 if (m_tDescription) m_tDescription->SetValue(m_pTrack->m_TrackDescription);
1146
1147 m_tTotDistance->SetValue("");
1148 m_tTimeEnroute->SetValue("");
1149
1150 m_sdbBtmBtnsSizerSplit->Enable(false);
1151 m_sdbBtmBtnsSizerExtend->Enable(false);
1152
1153 // Calculate AVG speed if we are showing a track and total time
1154 TrackPoint* last_point = m_pTrack->GetLastPoint();
1155 TrackPoint* first_point = m_pTrack->GetPoint(0);
1156 double trackLength = m_pTrack->Length();
1157 double total_seconds = 0.;
1158
1159 wxString speed("--");
1160
1161 if (last_point && first_point) {
1162 if (last_point->GetCreateTime().IsValid() &&
1163 first_point->GetCreateTime().IsValid()) {
1164 total_seconds = last_point->GetCreateTime()
1165 .Subtract(first_point->GetCreateTime())
1166 .GetSeconds()
1167 .ToDouble();
1168 if (total_seconds != 0.) {
1169 m_avgspeed = trackLength / total_seconds * 3600;
1170 } else {
1171 m_avgspeed = 0;
1172 }
1173 speed.Printf("%5.2f", toUsrSpeed(m_avgspeed));
1174 }
1175 }
1176
1177 m_tAvgSpeed->SetValue(speed);
1178
1179 // Total length
1180 wxString slen;
1181 slen.Printf("%5.2f " + getUsrDistanceUnit(), toUsrDistance(trackLength));
1182
1183 m_tTotDistance->SetValue(slen);
1184
1185 // Time
1186 wxString time_form;
1187 wxTimeSpan time(0, 0, (int)total_seconds, 0);
1188 // TODO Construct a readable time string, e.g. "xx Days, 15:34"
1189 if (total_seconds > 3600. * 24.)
1190 time_form = time.Format("%H:%M");
1191 else if (total_seconds > 0.)
1192 time_form = time.Format("%H:%M");
1193 else
1194 time_form = "--";
1195 m_tTimeEnroute->SetValue(time_form);
1196
1197 m_cbShow->SetValue(m_pTrack->IsVisible());
1198
1199 if (m_pTrack->m_Colour == "")
1200 m_cColor->Select(0);
1201 else {
1202 for (unsigned int i = 0; i < sizeof(::GpxxColorNames) / sizeof(wxString);
1203 i++) {
1204 if (m_pTrack->m_Colour == ::GpxxColorNames[i]) {
1205 m_cColor->Select(i + 1);
1206 break;
1207 }
1208 }
1209 }
1210
1211 for (unsigned int i = 0; i < sizeof(::StyleValues) / sizeof(int); i++) {
1212 if (m_pTrack->m_style == ::StyleValues[i]) {
1213 m_cStyle->Select(i);
1214 break;
1215 }
1216 }
1217
1218 for (unsigned int i = 0; i < sizeof(::WidthValues) / sizeof(int); i++) {
1219 if (m_pTrack->m_width == ::WidthValues[i]) {
1220 m_cWidth->Select(i);
1221 break;
1222 }
1223 }
1224
1225 if (m_pTrack->m_bIsInLayer) {
1226 m_tName->SetEditable(false);
1227 m_tFrom->SetEditable(false);
1228 m_tTo->SetEditable(false);
1229 if (m_tDescription) m_tDescription->SetEditable(false);
1230 m_cbShow->Enable(false);
1231 m_cColor->Enable(false);
1232 m_cStyle->Enable(false);
1233 m_cWidth->Enable(false);
1234 m_sdbBtmBtnsSizerExtend->Enable(false);
1235 m_sdbBtmBtnsSizerSplit->Enable(false);
1236 SetTitle(wxString::Format("%s, %s: %d", _("Track properties"), "Layer",
1237 m_pTrack->m_LayerID));
1238 } else {
1239 m_tName->SetEditable(true);
1240 m_tFrom->SetEditable(true);
1241 m_tTo->SetEditable(true);
1242 if (m_tDescription) m_tDescription->SetEditable(true);
1243 m_cbShow->Enable(true);
1244 m_cColor->Enable(true);
1245 m_cStyle->Enable(true);
1246 m_cWidth->Enable(true);
1247
1248 m_sdbBtmBtnsSizerExtend->Enable(IsThisTrackExtendable());
1249 // m_sdbBtmBtnsSizerSplit->Enable( false );
1250 SetTitle(_("Track properties"));
1251 }
1252
1253 ::wxEndBusyCursor();
1254
1255 return true;
1256}
1257
1258bool TrackPropDlg::IsThisTrackExtendable() {
1259 m_pExtendTrack = NULL;
1260 m_pExtendPoint = NULL;
1261 if (m_pTrack == g_pActiveTrack || m_pTrack->m_bIsInLayer) {
1262 return false;
1263 }
1264
1265 TrackPoint* pLastPoint = m_pTrack->GetPoint(0);
1266 if (!pLastPoint->GetCreateTime().IsValid()) {
1267 return false;
1268 }
1269
1270 for (Track* ptrack : g_TrackList) {
1271 if (ptrack->IsVisible() && (ptrack->m_GUID != m_pTrack->m_GUID)) {
1272 TrackPoint* track_node = ptrack->GetLastPoint();
1273 if (track_node) {
1274 if (track_node->GetCreateTime().IsValid()) {
1275 if (track_node->GetCreateTime() <= pLastPoint->GetCreateTime()) {
1276 if (!m_pExtendPoint ||
1277 track_node->GetCreateTime() > m_pExtendPoint->GetCreateTime()) {
1278 m_pExtendPoint = track_node;
1279 m_pExtendTrack = ptrack;
1280 }
1281 }
1282 }
1283 }
1284 }
1285 }
1286 if (m_pExtendTrack) {
1287 return (!m_pExtendTrack->m_bIsInLayer);
1288 } else {
1289 return false;
1290 }
1291}
1292
1293void TrackPropDlg::OnExtendBtnClick(wxCommandEvent& event) {
1294 TrackPoint* pFirstPoint = m_pTrack->GetPoint(0);
1295
1296 if (IsThisTrackExtendable()) {
1297 int begin = 0;
1298 if (pFirstPoint->GetCreateTime() == m_pExtendPoint->GetCreateTime()) {
1299 begin = 1;
1300 }
1301 pSelect->DeleteAllSelectableTrackSegments(m_pExtendTrack);
1302 m_pExtendTrack->Clone(m_pTrack, begin, m_pTrack->GetnPoints(), _("_plus"));
1303 pSelect->AddAllSelectableTrackSegments(m_pExtendTrack);
1304 pSelect->DeleteAllSelectableTrackSegments(m_pTrack);
1305 NavObj_dB::GetInstance().DeleteTrack(m_pTrack);
1306 RoutemanGui(*g_pRouteMan).DeleteTrack(m_pTrack);
1307
1308 SetTrackAndUpdate(m_pExtendTrack);
1309 NavObj_dB::GetInstance().UpdateTrack(m_pTrack);
1311
1312 if (pRouteManagerDialog && pRouteManagerDialog->IsShown()) {
1313 pRouteManagerDialog->UpdateTrkListCtrl();
1314 }
1315 }
1316}
1317
1318void TrackPropDlg::OnSplitBtnClick(wxCommandEvent& event) {
1319 m_sdbBtmBtnsSizerSplit->Enable(false);
1320
1321 if (m_pTrack->m_bIsInLayer) {
1322 return;
1323 }
1324
1325 if ((m_nSelected > 1) && (m_nSelected < m_pTrack->GetnPoints())) {
1326 Track* pHead = new Track();
1327 Track* pTail = new Track();
1328 pHead->Clone(m_pTrack, 0, m_nSelected - 1, _("_A"));
1329 pTail->Clone(m_pTrack, m_nSelected - 1, m_pTrack->GetnPoints(), _("_B"));
1330
1331 g_TrackList.push_back(pHead);
1332 NavObj_dB::GetInstance().InsertTrack(pHead);
1333
1334 g_TrackList.push_back(pTail);
1335 NavObj_dB::GetInstance().InsertTrack(pTail);
1336
1337 NavObj_dB::GetInstance().DeleteTrack(m_pTrack);
1338
1339 pSelect->DeleteAllSelectableTrackSegments(m_pTrack);
1340 RoutemanGui(*g_pRouteMan).DeleteTrack(m_pTrack);
1341 pSelect->AddAllSelectableTrackSegments(pTail);
1342 pSelect->AddAllSelectableTrackSegments(pHead);
1343
1344 SetTrackAndUpdate(pTail);
1346
1347 if (pRouteManagerDialog && pRouteManagerDialog->IsShown()) {
1348 pRouteManagerDialog->UpdateTrkListCtrl();
1349 }
1350 }
1351}
1352
1353void TrackPropDlg::OnTrackPropCopyTxtClick(wxCommandEvent& event) {
1354 wxString tab("\t", wxConvUTF8);
1355 wxString eol("\n", wxConvUTF8);
1356 wxString csvString;
1357
1358 csvString << this->GetTitle() << eol << _("Name") << tab
1359 << m_pTrack->GetName() << eol << _("Depart From") << tab
1360 << m_pTrack->m_TrackStartString << eol << _("Destination") << tab
1361 << m_pTrack->m_TrackEndString << eol << _("Total distance") << tab
1362 << m_tTotDistance->GetValue() << eol << _("Speed") << tab
1363 << m_tAvgSpeed->GetValue() << eol
1364 << _("Departure Time") + " " + _("(m/d/y h:m)") << tab
1365 << m_pTrack->GetPoint(1)->GetCreateTime().Format() << eol
1366 << _("Time enroute") << tab << m_tTimeEnroute->GetValue() << eol
1367 << eol;
1368
1369 int noCols;
1370 int noRows;
1371 noCols = m_lcPoints->GetColumnCount();
1372 noRows = m_lcPoints->GetItemCount();
1373 wxListItem item;
1374 item.SetMask(wxLIST_MASK_TEXT);
1375
1376 for (int i = 0; i < noCols; i++) {
1377 m_lcPoints->GetColumn(i, item);
1378 csvString << item.GetText() << tab;
1379 }
1380 csvString << eol;
1381
1382 for (int j = 0; j < noRows; j++) {
1383 item.SetId(j);
1384 for (int i = 0; i < noCols; i++) {
1385 item.SetColumn(i);
1386 m_lcPoints->GetItem(item);
1387 csvString << item.GetText() << tab;
1388 }
1389 csvString << eol;
1390 }
1391
1392 if (wxTheClipboard->Open()) {
1393 wxTextDataObject* data = new wxTextDataObject;
1394 data->SetText(csvString);
1395 wxTheClipboard->SetData(data);
1396 wxTheClipboard->Close();
1397 }
1398}
1399
1400void TrackPropDlg::OnPrintBtnClick(wxCommandEvent& event) {
1401 static std::set<int> s_options; // keep selected options
1402 TrackPrintDialog dlg(this, s_options);
1403 int result = dlg.ShowModal();
1404
1405 if (result == wxID_OK) {
1406 dlg.GetSelected(s_options);
1407 TrackPrintout printout(m_pTrack, m_lcPoints, s_options);
1408 auto& printer = PrintDialog::GetInstance();
1409 printer.Initialize(wxPORTRAIT);
1410 printer.EnablePageNumbers(true);
1411 printer.Print(this, &printout);
1412 }
1413}
1414
1415void TrackPropDlg::OnTrackPropRightClick(wxListEvent& event) {
1416 wxMenu menu;
1417
1418 wxMenuItem* copyItem =
1419 menu.Append(ID_RCLK_MENU_COPY_TEXT, _("&Copy all as text"));
1420
1421 PopupMenu(&menu);
1422}
1423
1424void TrackPropDlg::OnTrackPropListClick(wxListEvent& event) {
1425 long itemno = -1;
1426 m_nSelected = 0;
1427
1428 int selected_no;
1429 itemno =
1430 m_lcPoints->GetNextItem(itemno, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
1431 if (itemno == -1)
1432 selected_no = 0;
1433 else
1434 selected_no = itemno;
1435
1436 m_pTrack->m_HighlightedTrackPoint = -1;
1437
1438 if (itemno >= 0) {
1439 TrackPoint* prp = m_pTrack->GetPoint(itemno);
1440 if (prp) {
1441 m_pTrack->m_HighlightedTrackPoint = itemno; // highlight the trackpoint
1442
1443 if (!(m_pTrack->m_bIsInLayer) && !(m_pTrack == g_pActiveTrack)) {
1444 m_nSelected = selected_no + 1;
1445 m_sdbBtmBtnsSizerSplit->Enable(true);
1446 }
1447 top_frame::Get()->JumpToPosition(prp->m_lat, prp->m_lon);
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 nlohmann::json v;
1735 v["Changed"] = true;
1736 v["Name"] = m_pTrack->GetName();
1737 v["GUID"] = m_pTrack->m_GUID;
1738 SendJsonMessageToAllPlugins("OCPN_TRK_ACTIVATED", v);
1739 }
1740
1741 return true;
1742}
1743
1744void TrackPropDlg::OnOKBtnClick(wxCommandEvent& event) {
1745 // Look in the track list to be sure the track is still available
1746 // (May have been deleted by RouteManagerDialog...)
1747
1748 bool b_found_track = std::find(g_TrackList.begin(), g_TrackList.end(),
1749 m_pTrack) != g_TrackList.end();
1750
1751 if (b_found_track) {
1752 SaveChanges(); // write changes to globals and update config
1753 m_pTrack->ClearHighlights();
1754 }
1755
1756 m_bStartNow = false;
1757
1758 if (pRouteManagerDialog && pRouteManagerDialog->IsShown())
1759 pRouteManagerDialog->UpdateTrkListCtrl();
1760
1761 Hide();
1762 top_frame::Get()->InvalidateAllGL();
1763 top_frame::Get()->RefreshAllCanvas(false);
1764
1765 event.Skip();
1766}
1767
1768void TrackPropDlg::OnCancelBtnClick(wxCommandEvent& event) {
1769 bool b_found_track = std::find(g_TrackList.begin(), g_TrackList.end(),
1770 m_pTrack) != g_TrackList.end();
1771
1772 if (b_found_track) m_pTrack->ClearHighlights();
1773
1774 Hide();
1775 top_frame::Get()->InvalidateAllGL();
1776 top_frame::Get()->RefreshAllCanvas(false);
1777
1778 event.Skip();
1779}
1780
1781//--------------------------------------------------------------------------------------
1782// OCPNTrackListCtrl Implementation
1783//---------------------------------------------------------------------------------------
1784
1785OCPNTrackListCtrl::OCPNTrackListCtrl(wxWindow* parent, wxWindowID id,
1786 const wxPoint& pos, const wxSize& size,
1787 long style)
1788 : wxListCtrl(parent, id, pos, size, style) {
1789 m_parent = parent;
1790 m_tz_selection = GLOBAL_SETTINGS_INPUT;
1791 m_LMT_Offset = 0;
1792}
1793
1794OCPNTrackListCtrl::~OCPNTrackListCtrl() {}
1795
1797 if (m_pTrack->GetnPoints()) {
1798 TrackPoint* prp = m_pTrack->GetPoint(0);
1799 if (prp) return prp->m_lon;
1800 }
1801 return NAN;
1802}
1803
1804wxString OCPNTrackListCtrl::OnGetItemText(long item, long column) const {
1805 wxString ret;
1806
1807 if (item < 0 || item >= m_pTrack->GetnPoints()) return "";
1808
1809 TrackPoint* this_point = m_pTrack->GetPoint(item);
1810 TrackPoint* prev_point = item > 0 ? m_pTrack->GetPoint(item - 1) : NULL;
1811
1812 if (!this_point) return "";
1813
1814 double gt_brg, gt_leg_dist;
1815 double slat, slon;
1816 if (item == 0) {
1817 slat = gLat;
1818 slon = gLon;
1819 } else {
1820 slat = prev_point->m_lat;
1821 slon = prev_point->m_lon;
1822 }
1823
1824 switch (column) {
1825 case 0:
1826 if (item == 0)
1827 ret = "---";
1828 else
1829 ret.Printf("%ld", item);
1830 break;
1831
1832 case 1:
1833 DistanceBearingMercator(this_point->m_lat, this_point->m_lon, slat, slon,
1834 &gt_brg, &gt_leg_dist);
1835
1836 ret.Printf("%6.2f " + getUsrDistanceUnit(), toUsrDistance(gt_leg_dist));
1837 break;
1838
1839 case 2:
1840 DistanceBearingMercator(this_point->m_lat, this_point->m_lon, slat, slon,
1841 &gt_brg, &gt_leg_dist);
1842 ret.Printf("%03.0f %cT", gt_brg, 0x00B0);
1843 break;
1844
1845 case 3:
1846 ret = toSDMM(1, this_point->m_lat, 1);
1847 break;
1848
1849 case 4:
1850 ret = toSDMM(2, this_point->m_lon, 1);
1851 break;
1852
1853 case 5: {
1854 wxDateTime timestamp = this_point->GetCreateTime();
1855 if (timestamp.IsValid()) {
1858 .SetTimezone(getDatetimeTimezoneSelector(m_tz_selection))
1860 ret = ocpn::toUsrDateTimeFormat(timestamp.FromUTC(), opts);
1861 } else
1862 ret = "----";
1863 } break;
1864
1865 case 6:
1866 if ((item > 0) && this_point->GetCreateTime().IsValid() &&
1867 prev_point->GetCreateTime().IsValid()) {
1868 DistanceBearingMercator(this_point->m_lat, this_point->m_lon, slat,
1869 slon, &gt_brg, &gt_leg_dist);
1870 double speed = 0.;
1871 double seconds = this_point->GetCreateTime()
1872 .Subtract(prev_point->GetCreateTime())
1873 .GetSeconds()
1874 .ToDouble();
1875
1876 if (seconds > 0.) speed = gt_leg_dist / seconds * 3600;
1877
1878 ret.Printf("%5.2f", toUsrSpeed(speed));
1879 } else
1880 ret = _("--");
1881 break;
1882
1883 default:
1884 break;
1885 }
1886
1887 return ret;
1888}
1889
1890int OCPNTrackListCtrl::OnGetItemColumnImage(long item, long column) const {
1891 return -1;
1892}
Generic Chart canvas base.
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:139
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
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./*#end#*‍/.
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.
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.
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.
#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.