OpenCPN Partial API docs
Loading...
Searching...
No Matches
TrackPropDlg.cpp
1/**************************************************************************
2 *
3 * Project: OpenCPN
4 * Purpose: Track Properties Dialog
5 * Author: David Register
6 *
7 ***************************************************************************
8 * Copyright (C) 2013 by David S. Register *
9 * *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
24 **************************************************************************/
25#include "config.h"
26
27#include "model/georef.h"
28#include "model/navutil_base.h"
29#include "model/own_ship.h"
30#include "model/plugin_comm.h"
31#include "model/route.h"
32#include "model/routeman.h"
33#include "model/select.h"
34#include "model/track.h"
35
36#include "chcanv.h"
37#include "displays.h"
38#include "gui_lib.h"
39#include "navutil.h"
40#include "ocpn_frame.h"
41#include "OCPNPlatform.h"
42#include "pluginmanager.h"
43#include "print_dialog.h"
44#include "routemanagerdialog.h"
45#include "routeman_gui.h"
46#include "track_printout.h"
47#include "TrackPropDlg.h"
48
49#ifdef __ANDROID__
50#include "androidUTIL.h"
51#endif
52
53#define UTCINPUT 0
54#define LTINPUT \
55 1
56#define LMTINPUT \
57 2
59#define GLOBAL_SETTINGS_INPUT 3
60
61#define INPUT_FORMAT 1
62#define DISPLAY_FORMAT 2
63#define TIMESTAMP_FORMAT 3
64
65extern std::vector<Track*> g_TrackList;
66extern ActiveTrack* g_pActiveTrack;
67extern Routeman* g_pRouteMan;
68extern RouteManagerDialog* pRouteManagerDialog;
69extern MyConfig* pConfig;
70extern MyFrame* gFrame;
71
73bool TrackPropDlg::instanceFlag = false;
74TrackPropDlg* TrackPropDlg::single = NULL;
75TrackPropDlg* TrackPropDlg::getInstance(wxWindow* parent, wxWindowID id,
76 const wxString& title,
77 const wxPoint& pos, const wxSize& size,
78 long style) {
79 if (!instanceFlag) {
80 single = new TrackPropDlg(parent, id, title, pos, size, style);
81 instanceFlag = true;
82 return single;
83 } else {
84 return single;
85 }
86}
87
88TrackPropDlg::TrackPropDlg(wxWindow* parent, wxWindowID id,
89 const wxString& title, const wxPoint& pos,
90 const wxSize& size, long style)
91 : DIALOG_PARENT(parent, id, title, pos, size, style) {
92 wxFont* qFont = GetOCPNScaledFont(_("Dialog"));
93 SetFont(*qFont);
94
95 SetWindowStyleFlag(style);
96
97 m_scrolledWindowLinks = NULL;
98 m_tDescription = NULL;
99
100 m_bcompact = false;
101
102#ifdef __ANDROID__
103 m_bcompact = true;
104 CreateControlsCompact();
105#else
106 CreateControls();
107#endif
108
109 RecalculateSize();
110
111 // Centre( );
112
113 // Connect Events
114 m_sdbBtmBtnsSizerCancel->Connect(
115 wxEVT_COMMAND_BUTTON_CLICKED,
116 wxCommandEventHandler(TrackPropDlg::OnCancelBtnClick), NULL, this);
117 m_sdbBtmBtnsSizerOK->Connect(
118 wxEVT_COMMAND_BUTTON_CLICKED,
119 wxCommandEventHandler(TrackPropDlg::OnOKBtnClick), NULL, this);
120 if (m_sdbBtmBtnsSizerPrint)
121 m_sdbBtmBtnsSizerPrint->Connect(
122 wxEVT_COMMAND_BUTTON_CLICKED,
123 wxCommandEventHandler(TrackPropDlg::OnPrintBtnClick), NULL, this);
124 m_sdbBtmBtnsSizerSplit->Connect(
125 wxEVT_COMMAND_BUTTON_CLICKED,
126 wxCommandEventHandler(TrackPropDlg::OnSplitBtnClick), NULL, this);
127 m_sdbBtmBtnsSizerExtend->Connect(
128 wxEVT_COMMAND_BUTTON_CLICKED,
129 wxCommandEventHandler(TrackPropDlg::OnExtendBtnClick), NULL, this);
130 m_sdbBtmBtnsSizerToRoute->Connect(
131 wxEVT_COMMAND_BUTTON_CLICKED,
132 wxCommandEventHandler(TrackPropDlg::OnToRouteBtnClick), NULL, this);
133 if (m_sdbBtmBtnsSizerExport)
134 m_sdbBtmBtnsSizerExport->Connect(
135 wxEVT_COMMAND_BUTTON_CLICKED,
136 wxCommandEventHandler(TrackPropDlg::OnExportBtnClick), NULL, this);
137 m_lcPoints->Connect(wxEVT_COMMAND_LIST_ITEM_SELECTED,
138 wxListEventHandler(TrackPropDlg::OnTrackPropListClick),
139 NULL, this);
140 Connect(wxEVT_COMMAND_LIST_ITEM_RIGHT_CLICK,
141 wxListEventHandler(TrackPropDlg::OnTrackPropRightClick), NULL, this);
142 Connect(wxEVT_COMMAND_MENU_SELECTED,
143 wxCommandEventHandler(TrackPropDlg::OnTrackPropMenuSelected), NULL,
144 this);
145
146#ifdef __WXOSX__
147 Connect(wxEVT_ACTIVATE, wxActivateEventHandler(TrackPropDlg::OnActivate),
148 NULL, this);
149#endif
150
151 if (!m_bcompact) {
152 m_buttonAddLink->Connect(wxEVT_COMMAND_BUTTON_CLICKED,
153 wxCommandEventHandler(TrackPropDlg::OnAddLink),
154 NULL, this);
155 m_toggleBtnEdit->Connect(
156 wxEVT_COMMAND_TOGGLEBUTTON_CLICKED,
157 wxCommandEventHandler(TrackPropDlg::OnEditLinkToggle), NULL, this);
158 }
159
160 if (m_rbShowTimeUTC)
161 m_rbShowTimeUTC->Connect(wxEVT_COMMAND_RADIOBUTTON_SELECTED,
162 wxCommandEventHandler(TrackPropDlg::OnShowTimeTZ),
163 NULL, this);
164 if (m_rbShowTimePC)
165 m_rbShowTimePC->Connect(wxEVT_COMMAND_RADIOBUTTON_SELECTED,
166 wxCommandEventHandler(TrackPropDlg::OnShowTimeTZ),
167 NULL, this);
168 if (m_rbShowTimeLocal)
169 m_rbShowTimeLocal->Connect(
170 wxEVT_COMMAND_RADIOBUTTON_SELECTED,
171 wxCommandEventHandler(TrackPropDlg::OnShowTimeTZ), NULL, this);
172
173 if (m_rbShowTimeGlobalSettings)
174 m_rbShowTimeGlobalSettings->Connect(
175 wxEVT_COMMAND_RADIOBUTTON_SELECTED,
176 wxCommandEventHandler(TrackPropDlg::OnShowTimeTZ), NULL, this);
177
178 m_pMyLinkList = NULL;
179}
180
181TrackPropDlg::~TrackPropDlg() {
182 // Disconnect Events
183 m_sdbBtmBtnsSizerCancel->Disconnect(
184 wxEVT_COMMAND_BUTTON_CLICKED,
185 wxCommandEventHandler(TrackPropDlg::OnCancelBtnClick), NULL, this);
186 m_sdbBtmBtnsSizerOK->Disconnect(
187 wxEVT_COMMAND_BUTTON_CLICKED,
188 wxCommandEventHandler(TrackPropDlg::OnOKBtnClick), NULL, this);
189 if (m_sdbBtmBtnsSizerPrint)
190 m_sdbBtmBtnsSizerPrint->Disconnect(
191 wxEVT_COMMAND_BUTTON_CLICKED,
192 wxCommandEventHandler(TrackPropDlg::OnPrintBtnClick), NULL, this);
193 m_sdbBtmBtnsSizerSplit->Disconnect(
194 wxEVT_COMMAND_BUTTON_CLICKED,
195 wxCommandEventHandler(TrackPropDlg::OnSplitBtnClick), NULL, this);
196 m_sdbBtmBtnsSizerExtend->Disconnect(
197 wxEVT_COMMAND_BUTTON_CLICKED,
198 wxCommandEventHandler(TrackPropDlg::OnExtendBtnClick), NULL, this);
199 m_sdbBtmBtnsSizerToRoute->Disconnect(
200 wxEVT_COMMAND_BUTTON_CLICKED,
201 wxCommandEventHandler(TrackPropDlg::OnToRouteBtnClick), NULL, this);
202 if (m_sdbBtmBtnsSizerExport)
203 m_sdbBtmBtnsSizerExport->Disconnect(
204 wxEVT_COMMAND_BUTTON_CLICKED,
205 wxCommandEventHandler(TrackPropDlg::OnExportBtnClick), NULL, this);
206 m_lcPoints->Disconnect(wxEVT_COMMAND_LIST_ITEM_SELECTED,
207 wxListEventHandler(TrackPropDlg::OnTrackPropListClick),
208 NULL, this);
209 Disconnect(wxEVT_COMMAND_LIST_ITEM_RIGHT_CLICK,
210 wxListEventHandler(TrackPropDlg::OnTrackPropRightClick), NULL,
211 this);
212 Disconnect(wxEVT_COMMAND_MENU_SELECTED,
213 wxCommandEventHandler(TrackPropDlg::OnTrackPropMenuSelected), NULL,
214 this);
215
216 Disconnect(wxID_ANY, wxEVT_COMMAND_MENU_SELECTED,
217 wxCommandEventHandler(TrackPropDlg::OnDeleteLink));
218 Disconnect(wxID_ANY, wxEVT_COMMAND_MENU_SELECTED,
219 wxCommandEventHandler(TrackPropDlg::OnEditLink));
220 Disconnect(wxID_ANY, wxEVT_COMMAND_MENU_SELECTED,
221 wxCommandEventHandler(TrackPropDlg::OnAddLink));
222
223 if (!m_bcompact) {
224 m_buttonAddLink->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED,
225 wxCommandEventHandler(TrackPropDlg::OnAddLink),
226 NULL, this);
227 m_toggleBtnEdit->Disconnect(
228 wxEVT_COMMAND_TOGGLEBUTTON_CLICKED,
229 wxCommandEventHandler(TrackPropDlg::OnEditLinkToggle), NULL, this);
230 }
231
232 if (m_rbShowTimeUTC)
233 m_rbShowTimeUTC->Disconnect(
234 wxEVT_COMMAND_RADIOBUTTON_SELECTED,
235 wxCommandEventHandler(TrackPropDlg::OnShowTimeTZ), NULL, this);
236 if (m_rbShowTimePC)
237 m_rbShowTimePC->Disconnect(
238 wxEVT_COMMAND_RADIOBUTTON_SELECTED,
239 wxCommandEventHandler(TrackPropDlg::OnShowTimeTZ), NULL, this);
241 m_rbShowTimeLocal->Disconnect(
242 wxEVT_COMMAND_RADIOBUTTON_SELECTED,
243 wxCommandEventHandler(TrackPropDlg::OnShowTimeTZ), NULL, this);
245 m_rbShowTimeGlobalSettings->Disconnect(
246 wxEVT_COMMAND_RADIOBUTTON_SELECTED,
247 wxCommandEventHandler(TrackPropDlg::OnShowTimeTZ), NULL, this);
248
249 instanceFlag = false;
250}
251
252static wxString getDatetimeTimezoneSelector(int selection) {
253 switch (selection) {
254 case UTCINPUT:
255 return "UTC";
256 case LTINPUT:
257 return "Local Time";
258 case LMTINPUT:
259 return "LMT";
260 case GLOBAL_SETTINGS_INPUT:
261 default:
262 return wxEmptyString;
263 }
264}
265
266void TrackPropDlg::OnActivate(wxActivateEvent& event) {
267 auto pWin = dynamic_cast<DIALOG_PARENT*>(event.GetEventObject());
268 long int style = pWin->GetWindowStyle();
269 if (event.GetActive())
270 pWin->SetWindowStyle(style | wxSTAY_ON_TOP);
271 else
272 pWin->SetWindowStyle(style ^ wxSTAY_ON_TOP);
273}
274
275void TrackPropDlg::RecalculateSize(void) {
276 // Make an estimate of the dialog size, without scrollbars showing
277
278 wxSize esize;
279 esize.x = GetCharWidth() * 110;
280 esize.y = GetCharHeight() * 40;
281
282 wxSize dsize = GetParent()->GetClientSize();
283 esize.y = wxMin(esize.y, dsize.y - (2 * GetCharHeight()));
284 esize.x = wxMin(esize.x, dsize.x - (2 * GetCharHeight()));
285 SetClientSize(esize);
286
287 wxSize fsize = GetSize();
288 fsize.y = wxMin(fsize.y, dsize.y - (2 * GetCharHeight()));
289 fsize.x = wxMin(fsize.x, dsize.x - (2 * GetCharHeight()));
290 SetSize(fsize);
291
292 if (m_bcompact) {
293 int sy = GetCharHeight() * m_lcPoints->GetItemCount();
294 sy = wxMax(sy, 250);
295 sy = wxMin(sy, 500);
296 m_lcPoints->SetSize(wxSize(GetClientSize().x - 40, sy));
297
298 if (m_lcPoints->GetItemCount()) Layout();
299 }
300
301 Centre();
302}
303
304static void addColumns(wxListCtrl* lctrl, int dx) {
305 lctrl->InsertColumn(0, _("Leg"), wxLIST_FORMAT_LEFT, dx * 6);
306 lctrl->InsertColumn(1, _("Distance"), wxLIST_FORMAT_LEFT, dx * 11);
307 lctrl->InsertColumn(2, _("Bearing"), wxLIST_FORMAT_LEFT, dx * 8);
308 // Width of lat/lon may be up to 15 characters: 'DDD° MM.MMMM' W'.
309 lctrl->InsertColumn(3, _("Latitude"), wxLIST_FORMAT_LEFT, dx * 15);
310 lctrl->InsertColumn(4, _("Longitude"), wxLIST_FORMAT_LEFT, dx * 15);
311 // Width of timestamp may be be up to 26 characters: 'MM/DD/YYYY HH:MM:SS PM
312 // UTC'.
313 lctrl->InsertColumn(5, _("Timestamp"), wxLIST_FORMAT_LEFT, dx * 26);
314 lctrl->InsertColumn(6, _("Speed"), wxLIST_FORMAT_CENTER, dx * 8);
315
316 lctrl->SetMinSize(wxSize(-1, 50));
317}
318
319void TrackPropDlg::CreateControlsCompact() {
320 wxBoxSizer* itemBoxSizer1 = new wxBoxSizer(wxVERTICAL);
321 SetSizer(itemBoxSizer1);
322
323 itemDialog1 = new wxScrolledWindow(this, wxID_ANY, wxDefaultPosition,
324 wxSize(-1, -1), wxVSCROLL);
325 itemDialog1->SetScrollRate(0, 1);
326
327#ifdef __ANDROID__
328 // Set Dialog Font by custom crafted Qt Stylesheet.
329 wxFont* qFont = GetOCPNScaledFont(_("Dialog"));
330
331 wxString wqs = getFontQtStylesheet(qFont);
332 wxCharBuffer sbuf = wqs.ToUTF8();
333 QString qsb = QString(sbuf.data());
334
335 QString qsbq = getQtStyleSheet(); // basic scrollbars, etc
336
337 itemDialog1->GetHandle()->setStyleSheet(qsb +
338 qsbq); // Concatenated style sheets
339
340#endif
341 itemBoxSizer1->Add(itemDialog1, 1, wxEXPAND | wxALL, 0);
342
343 wxBoxSizer* itemBoxSizer2 = new wxBoxSizer(wxVERTICAL);
344 itemDialog1->SetSizer(itemBoxSizer2);
345
346 wxStaticText* itemStaticText4 = new wxStaticText(
347 itemDialog1, wxID_STATIC, _("Name"), wxDefaultPosition, wxDefaultSize, 0);
348 itemBoxSizer2->Add(itemStaticText4, 0,
349 wxALIGN_LEFT | wxLEFT | wxRIGHT | wxTOP, 5);
350
351 m_tName = new wxTextCtrl(itemDialog1, wxID_ANY, _T(""), wxDefaultPosition,
352 wxSize(400, -1), 0);
353 itemBoxSizer2->Add(m_tName, 0, wxALIGN_LEFT | wxLEFT | wxRIGHT | wxBOTTOM, 5);
354
355 wxStaticText* itemStaticText7 =
356 new wxStaticText(itemDialog1, wxID_STATIC, _("Depart From"),
357 wxDefaultPosition, wxDefaultSize, 0);
358 itemBoxSizer2->Add(itemStaticText7, 0,
359 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT,
360 5);
361
362 m_tFrom = new wxTextCtrl(itemDialog1, wxID_ANY, _T(""), wxDefaultPosition,
363 wxSize(-1, -1), 0);
364 itemBoxSizer2->Add(m_tFrom, 0,
365 wxEXPAND | wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL |
366 wxLEFT | wxRIGHT | wxBOTTOM,
367 5);
368
369 wxStaticText* itemStaticText8 =
370 new wxStaticText(itemDialog1, wxID_STATIC, _("Destination"),
371 wxDefaultPosition, wxDefaultSize, 0);
372 itemBoxSizer2->Add(itemStaticText8, 0,
373 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT,
374 5);
375
376 m_tTo = new wxTextCtrl(itemDialog1, wxID_ANY, _T(""), wxDefaultPosition,
377 wxSize(-1, -1), 0);
378 itemBoxSizer2->Add(m_tTo, 0,
379 wxEXPAND | wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL |
380 wxLEFT | wxRIGHT | wxBOTTOM,
381 5);
382
383 m_cbShow = new wxCheckBox(itemDialog1, wxID_ANY, _("Show on chart"),
384 wxDefaultPosition, wxDefaultSize, 0);
385 itemBoxSizer2->Add(m_cbShow, 0, wxALL, 5);
386
387 wxFlexGridSizer* itemFlexGridSizer6a = new wxFlexGridSizer(4, 2, 0, 0);
388 itemFlexGridSizer6a->AddGrowableCol(1, 0);
389
390 itemBoxSizer2->Add(itemFlexGridSizer6a, 0, wxEXPAND | wxALIGN_LEFT | wxALL,
391 5);
392
393 wxStaticText* itemStaticText11 =
394 new wxStaticText(itemDialog1, wxID_STATIC, _("Total distance"),
395 wxDefaultPosition, wxDefaultSize, 0);
396 itemFlexGridSizer6a->Add(
397 itemStaticText11, 0,
398 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT | wxTOP, 5);
399
400 m_tTotDistance =
401 new wxTextCtrl(itemDialog1, wxID_ANY, _T(""), wxDefaultPosition,
402 wxSize(-1, -1), wxTE_READONLY);
403 itemFlexGridSizer6a->Add(m_tTotDistance, 0,
404 wxEXPAND | wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL |
405 wxLEFT | wxRIGHT | wxBOTTOM,
406 5);
407
408 m_stAvgSpeed = new wxStaticText(itemDialog1, wxID_STATIC, _("Avg. speed"),
409 wxDefaultPosition, wxDefaultSize, 0);
410 itemFlexGridSizer6a->Add(
411 m_stAvgSpeed, 0,
412 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT | wxTOP, 5);
413
414 m_tAvgSpeed = new wxTextCtrl(itemDialog1, wxID_ANY, _T(""), wxDefaultPosition,
415 wxSize(150, -1), wxTE_PROCESS_ENTER);
416 itemFlexGridSizer6a->Add(
417 m_tAvgSpeed, 0,
418 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT | wxBOTTOM, 5);
419
420 m_stTimeEnroute =
421 new wxStaticText(itemDialog1, wxID_STATIC, _("Time Enroute"),
422 wxDefaultPosition, wxDefaultSize, 0);
423 itemFlexGridSizer6a->Add(
424 m_stTimeEnroute, 0,
425 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT | wxTOP, 5);
426
427 m_tTimeEnroute =
428 new wxTextCtrl(itemDialog1, wxID_ANY, _T(""), 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, _T(""),
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") + _T(":"),
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") + _T(":"),
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") + _T(":"),
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(void) {
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, wxEmptyString,
702 wxDefaultPosition, 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, wxEmptyString,
715 wxDefaultPosition, 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, wxEmptyString,
724 wxDefaultPosition, 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 =
797 new wxTextCtrl(m_panelBasic, wxID_ANY, wxEmptyString, wxDefaultPosition,
798 wxDefaultSize, wxTE_READONLY);
799 bSizerStats->Add(m_tTotDistance, 1, 0, 5);
800
801 m_stAvgSpeed = new wxStaticText(m_panelBasic, wxID_ANY, _("Avg. speed"),
802 wxDefaultPosition, wxDefaultSize, 0);
803 // m_stAvgSpeed->Wrap( -1 );
804 bSizerStats->Add(m_stAvgSpeed, 0, wxALL, 5);
805
806 m_tAvgSpeed = new wxTextCtrl(m_panelBasic, wxID_ANY, wxEmptyString,
807 wxDefaultPosition, wxDefaultSize, wxTE_READONLY);
808 bSizerStats->Add(m_tAvgSpeed, 1, 0, 5);
809
810 m_stTimeEnroute = new wxStaticText(m_panelBasic, wxID_ANY, _("Time enroute"),
811 wxDefaultPosition, wxDefaultSize, 0);
812 // m_stTimeEnroute->Wrap( -1 );
813 bSizerStats->Add(m_stTimeEnroute, 0, wxALL, 5);
814
815 m_tTimeEnroute =
816 new wxTextCtrl(m_panelBasic, wxID_ANY, wxEmptyString, wxDefaultPosition,
817 wxDefaultSize, wxTE_READONLY);
818 bSizerStats->Add(m_tTimeEnroute, 2, 0, 5);
819
820 sbSizerStats->Add(bSizerStats, 0, wxEXPAND, 5);
821
822 wxStaticBoxSizer* sbSizerPoints;
823 sbSizerPoints = new wxStaticBoxSizer(
824 new wxStaticBox(m_panel0, wxID_ANY, _("Recorded points")), wxVERTICAL);
825 bSizer1->Add(sbSizerPoints, 1, wxALL | wxEXPAND, 5);
826
827 wxBoxSizer* bSizerShowTime;
828 bSizerShowTime = new wxBoxSizer(wxHORIZONTAL);
829
830 m_stShowTime = new wxStaticText(m_panel0, wxID_ANY, _("Time shown as"),
831 wxDefaultPosition, wxDefaultSize, 0);
832 // m_stShowTime->Wrap( -1 );
833 bSizerShowTime->Add(m_stShowTime, 0, wxALL, 5);
834
835 m_rbShowTimeUTC = new wxRadioButton(m_panel0, wxID_ANY, _("UTC"),
836 wxDefaultPosition, wxDefaultSize, 0);
837 bSizerShowTime->Add(m_rbShowTimeUTC, 0,
838 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT,
839 5);
840
841 m_rbShowTimePC = new wxRadioButton(m_panel0, wxID_ANY, _("Local Time"),
842 wxDefaultPosition, wxDefaultSize, 0);
843 bSizerShowTime->Add(m_rbShowTimePC, 0,
844 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT,
845 5);
846
848 new wxRadioButton(m_panel0, wxID_ANY, _("LMT@Track Start"),
849 wxDefaultPosition, wxDefaultSize, 0);
850 bSizerShowTime->Add(m_rbShowTimeLocal, 0,
851 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT,
852 5);
853
855 new wxRadioButton(m_panel0, wxID_ANY, _("Honor Global Settings"),
856 wxDefaultPosition, wxDefaultSize, 0);
857 bSizerShowTime->Add(m_rbShowTimeGlobalSettings, 0,
858 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT,
859 5);
860
861 m_rbShowTimeGlobalSettings->SetValue(true);
862
863 sbSizerPoints->Add(bSizerShowTime, 0, wxEXPAND, 5);
864
865 long flags = wxLC_REPORT | wxLC_HRULES | wxLC_VRULES | wxLC_EDIT_LABELS;
866#ifndef __WXQT__ // Does not support Virtual list boxes....
867 flags |= wxLC_VIRTUAL;
868#endif
869
870 m_lcPoints = new OCPNTrackListCtrl(m_panel0, wxID_ANY, wxDefaultPosition,
871 wxDefaultSize, flags);
872 addColumns(m_lcPoints, GetCharWidth());
873
874 sbSizerPoints->Add(m_lcPoints, 1, wxALL | wxEXPAND, 5);
875
876#ifdef __ANDROID__
877 m_lcPoints->GetHandle()->setStyleSheet(getQtStyleSheet());
878#endif
879
880 // m_lcPoints = new OCPNTrackListCtrl( m_panel0, wxID_ANY,
881 // wxDefaultPosition, wxDefaultSize,
882 // wxLC_REPORT | wxLC_HRULES |
883 // wxLC_VRULES | wxLC_EDIT_LABELS |
884 // wxLC_VIRTUAL );
885 //
886 // m_lcPoints->Hide();
887 // m_rbShowTimeUTC = NULL;
888 // m_rbShowTimePC = NULL;
889 // m_rbShowTimeLocal = NULL;
890
891 m_panelAdvanced = new wxScrolledWindow(
892 m_notebook1, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL);
893
894 wxBoxSizer* bSizerAdvanced;
895 bSizerAdvanced = new wxBoxSizer(wxVERTICAL);
896
897 m_stDescription =
898 new wxStaticText(m_panelAdvanced, wxID_ANY, _("Description"),
899 wxDefaultPosition, wxDefaultSize, 0);
900 // m_stDescription->Wrap( -1 );
901 bSizerAdvanced->Add(m_stDescription, 0, wxALL, 5);
902
903 m_tDescription =
904 new wxTextCtrl(m_panelAdvanced, wxID_ANY, wxEmptyString,
905 wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE);
906 bSizerAdvanced->Add(m_tDescription, 1, wxALL | wxEXPAND, 5);
907
908 sbSizerLinks = new wxStaticBoxSizer(
909 new wxStaticBox(m_panelAdvanced, wxID_ANY, _("Links")), wxVERTICAL);
910
911 m_scrolledWindowLinks =
912 new wxScrolledWindow(m_panelAdvanced, wxID_ANY, wxDefaultPosition,
913 wxDefaultSize, wxHSCROLL | wxVSCROLL);
914 m_scrolledWindowLinks->SetScrollRate(5, 5);
915 bSizerLinks = new wxBoxSizer(wxVERTICAL);
916
917 m_hyperlink1 =
918 new wxHyperlinkCtrl(m_scrolledWindowLinks, wxID_ANY, _("wxFB Website"),
919 wxT("http://www.wxformbuilder.org"),
920 wxDefaultPosition, wxDefaultSize, wxHL_DEFAULT_STYLE);
921 m_menuLink = new wxMenu();
922 m_menuItemEdit =
923 new wxMenuItem(m_menuLink, ID_TRK_MENU_EDIT, wxString(_("Edit")),
924 wxEmptyString, wxITEM_NORMAL);
925 m_menuLink->Append(m_menuItemEdit);
926
927 m_menuItemAdd =
928 new wxMenuItem(m_menuLink, ID_TRK_MENU_ADD, wxString(_("Add new")),
929 wxEmptyString, wxITEM_NORMAL);
930 m_menuLink->Append(m_menuItemAdd);
931
932 m_menuItemDelete =
933 new wxMenuItem(m_menuLink, ID_TRK_MENU_DELETE, wxString(_("Delete")),
934 wxEmptyString, wxITEM_NORMAL);
935 m_menuLink->Append(m_menuItemDelete);
936
937 m_hyperlink1->Connect(
938 wxEVT_RIGHT_DOWN,
939 wxMouseEventHandler(TrackPropDlg::m_hyperlink1OnContextMenu), NULL, this);
940
941 bSizerLinks->Add(m_hyperlink1, 0, wxALL, 5);
942
943 m_scrolledWindowLinks->SetSizer(bSizerLinks);
944 m_scrolledWindowLinks->Layout();
945 bSizerLinks->Fit(m_scrolledWindowLinks);
946 sbSizerLinks->Add(m_scrolledWindowLinks, 1, wxEXPAND | wxALL, 5);
947
948 wxBoxSizer* bSizerLinkBtns;
949 bSizerLinkBtns = new wxBoxSizer(wxHORIZONTAL);
950
951 m_buttonAddLink =
952 new wxButton(m_panelAdvanced, wxID_ANY, _("Add"), wxDefaultPosition,
953 wxDefaultSize, wxBU_EXACTFIT);
954 bSizerLinkBtns->Add(m_buttonAddLink, 0, wxALL, 5);
955
956 m_toggleBtnEdit = new wxToggleButton(m_panelAdvanced, wxID_ANY, _("Edit"),
957 wxDefaultPosition, wxDefaultSize, 0);
958 bSizerLinkBtns->Add(m_toggleBtnEdit, 0, wxALL, 5);
959
960 m_staticTextEditEnabled = new wxStaticText(
961 m_panelAdvanced, wxID_ANY, _("Links are opened in the default browser."),
962 wxDefaultPosition, wxDefaultSize, 0);
963 // m_staticTextEditEnabled->Wrap( -1 );
964 bSizerLinkBtns->Add(m_staticTextEditEnabled, 0,
965 wxALIGN_CENTER_VERTICAL | wxALL, 5);
966
967 sbSizerLinks->Add(bSizerLinkBtns, 0, wxEXPAND, 5);
968
969 bSizerAdvanced->Add(sbSizerLinks, 1, wxEXPAND, 5);
970
971 m_panelAdvanced->SetSizer(bSizerAdvanced);
972 m_notebook1->AddPage(m_panelAdvanced, _("Advanced"), false);
973
974 // Buttons, etc...
975
976 wxBoxSizer* itemBoxSizerBottom = new wxBoxSizer(wxVERTICAL);
977 bSizerMain->Add(itemBoxSizerBottom, 0, wxALIGN_LEFT | wxALL | wxEXPAND, 5);
978
979 // wxBoxSizer* itemBoxSizerAux = new wxBoxSizer( wxHORIZONTAL );
980
981 int n_col = 5;
982
983 wxFlexGridSizer* itemBoxSizerAux = new wxFlexGridSizer(0, n_col, 0, 0);
984 itemBoxSizerAux->SetFlexibleDirection(wxBOTH);
985 itemBoxSizerAux->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_SPECIFIED);
986
987 itemBoxSizerBottom->Add(itemBoxSizerAux, 1, wxALIGN_LEFT | wxALL, 5);
988
989#ifndef __ANDROID__
990
991 m_sdbBtmBtnsSizerPrint = new wxButton(this, wxID_ANY, _("Print"),
992 wxDefaultPosition, wxDefaultSize, 0);
993 itemBoxSizerAux->Add(m_sdbBtmBtnsSizerPrint, 0,
994 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 5);
995 m_sdbBtmBtnsSizerPrint->Enable(true);
996#else
997 m_sdbBtmBtnsSizerPrint = NULL;
998#endif
999
1000 m_sdbBtmBtnsSizerSplit = new wxButton(this, wxID_ANY, _("Split"),
1001 wxDefaultPosition, wxDefaultSize, 0);
1002 itemBoxSizerAux->Add(m_sdbBtmBtnsSizerSplit, 0,
1003 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 5);
1004 m_sdbBtmBtnsSizerSplit->Enable(false);
1005
1006 m_sdbBtmBtnsSizerExtend = new wxButton(this, wxID_ANY, _("Extend track"),
1007 wxDefaultPosition, wxDefaultSize, 0);
1008 itemBoxSizerAux->Add(m_sdbBtmBtnsSizerExtend, 0,
1009 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 5);
1010
1011 m_sdbBtmBtnsSizerToRoute = new wxButton(this, wxID_ANY, _("To route"),
1012 wxDefaultPosition, wxDefaultSize, 0);
1013 itemBoxSizerAux->Add(m_sdbBtmBtnsSizerToRoute, 0,
1014 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 5);
1015
1016 m_sdbBtmBtnsSizerExport = new wxButton(this, wxID_ANY, _("Export"),
1017 wxDefaultPosition, wxDefaultSize, 0);
1018 itemBoxSizerAux->Add(m_sdbBtmBtnsSizerExport, 0,
1019 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 5);
1020
1021 wxBoxSizer* itemBoxSizer16 = new wxBoxSizer(wxHORIZONTAL);
1022 itemBoxSizerBottom->Add(itemBoxSizer16, 0, wxALIGN_RIGHT | wxALL, 5);
1023
1024 m_sdbBtmBtnsSizerCancel = new wxButton(this, wxID_CANCEL, _("Cancel"),
1025 wxDefaultPosition, wxDefaultSize, 0);
1026 itemBoxSizer16->Add(m_sdbBtmBtnsSizerCancel, 0, wxALIGN_BOTTOM | wxALL, 5);
1027
1028 m_sdbBtmBtnsSizerOK =
1029 new wxButton(this, wxID_OK, _("OK"), wxDefaultPosition, wxDefaultSize, 0);
1030 itemBoxSizer16->Add(m_sdbBtmBtnsSizerOK, 0, wxALIGN_BOTTOM | wxALL, 5);
1031 m_sdbBtmBtnsSizerOK->SetDefault();
1032
1033 // Make it look nice and add the needed non-standard buttons
1034 int w1, w2, h;
1035 ((wxWindowBase*)m_stName)->GetSize(&w1, &h);
1036 ((wxWindowBase*)m_stFrom)->GetSize(&w2, &h);
1037 ((wxWindowBase*)m_stName)->SetMinSize(wxSize(wxMax(w1, w2), h));
1038 ((wxWindowBase*)m_stFrom)->SetMinSize(wxSize(wxMax(w1, w2), h));
1039
1040 m_panelBasic->SetScrollRate(5, 5);
1041 m_panelAdvanced->SetScrollRate(5, 5);
1042}
1043
1044void TrackPropDlg::SetTrackAndUpdate(Track* pt) {
1045 m_pTrack = pt;
1046
1047 m_lcPoints->DeleteAllItems();
1048
1049 if (m_pMyLinkList) delete m_pMyLinkList;
1050 m_pMyLinkList = new HyperlinkList();
1051
1052 int NbrOfLinks = m_pTrack->m_HyperlinkList->GetCount();
1053 if (NbrOfLinks > 0) {
1054 wxHyperlinkListNode* linknode = m_pTrack->m_HyperlinkList->GetFirst();
1055 while (linknode) {
1056 Hyperlink* link = linknode->GetData();
1057
1058 Hyperlink* h = new Hyperlink();
1059 h->DescrText = link->DescrText;
1060 h->Link = link->Link;
1061 h->LType = link->LType;
1062
1063 m_pMyLinkList->Append(h);
1064
1065 linknode = linknode->GetNext();
1066 }
1067 }
1068
1069 InitializeList();
1071
1072 RecalculateSize();
1073}
1074
1075void TrackPropDlg::InitializeList() {
1076 if (NULL == m_pTrack) return;
1077
1078 m_lcPoints->m_pTrack = m_pTrack;
1079
1080 if (m_pTrack->GetnPoints()) {
1081 TrackPoint* prp = m_pTrack->GetPoint(0);
1082 if (prp)
1083 m_lcPoints->m_LMT_Offset = long((prp->m_lon) * 3600. / 15.); // estimated
1084 else
1085 m_lcPoints->m_LMT_Offset = 0;
1086 }
1087
1088 if (m_lcPoints->IsVirtual())
1089 m_lcPoints->SetItemCount(m_pTrack->GetnPoints());
1090
1091 else {
1092 for (int in = 0; in < m_pTrack->GetnPoints(); in++) {
1093 wxListItem item;
1094 item.SetId(in);
1095
1096 m_lcPoints->InsertItem(item);
1097 for (int j = 0; j < 7; j++) {
1098 item.SetColumn(j);
1099 item.SetText(m_lcPoints->OnGetItemText(in, j));
1100 m_lcPoints->SetItem(item);
1101 }
1102 }
1103 }
1104}
1105
1107 if (NULL == m_pTrack) return false;
1108
1109 ::wxBeginBusyCursor();
1110
1111 if (m_scrolledWindowLinks) {
1112 wxWindowList kids = m_scrolledWindowLinks->GetChildren();
1113 for (unsigned int i = 0; i < kids.GetCount(); i++) {
1114 wxWindowListNode* node = kids.Item(i);
1115 wxWindow* win = node->GetData();
1116
1117 auto link_win = dynamic_cast<wxHyperlinkCtrl*>(win);
1118 if (link_win) {
1119 link_win->Disconnect(
1120 wxEVT_COMMAND_HYPERLINK,
1121 wxHyperlinkEventHandler(TrackPropDlg::OnHyperLinkClick));
1122 link_win->Disconnect(
1123 wxEVT_RIGHT_DOWN,
1124 wxMouseEventHandler(TrackPropDlg::m_hyperlinkContextMenu));
1125 win->Destroy();
1126 }
1127 }
1129 int NbrOfLinks = m_pTrack->m_HyperlinkList->GetCount();
1130 HyperlinkList* hyperlinklist = m_pTrack->m_HyperlinkList;
1131 // int len = 0;
1132 if (NbrOfLinks > 0) {
1133 wxHyperlinkListNode* linknode = hyperlinklist->GetFirst();
1134 while (linknode) {
1135 Hyperlink* link = linknode->GetData();
1136 wxString Link = link->Link;
1137 wxString Descr = link->DescrText;
1138
1139 wxHyperlinkCtrl* ctrl = new wxHyperlinkCtrl(
1140 m_scrolledWindowLinks, wxID_ANY, Descr, Link, wxDefaultPosition,
1141 wxDefaultSize, wxHL_DEFAULT_STYLE);
1142 ctrl->Connect(wxEVT_COMMAND_HYPERLINK,
1143 wxHyperlinkEventHandler(TrackPropDlg::OnHyperLinkClick),
1144 NULL, this);
1145 if (!m_pTrack->m_bIsInLayer)
1146 ctrl->Connect(
1147 wxEVT_RIGHT_DOWN,
1148 wxMouseEventHandler(TrackPropDlg::m_hyperlinkContextMenu), NULL,
1149 this);
1150
1151 bSizerLinks->Add(ctrl, 0, wxALL, 5);
1152
1153 linknode = linknode->GetNext();
1154 }
1155 }
1156 bSizerLinks->Fit(m_scrolledWindowLinks);
1157 }
1158
1159 m_tName->SetValue(m_pTrack->GetName());
1160 m_tFrom->SetValue(m_pTrack->m_TrackStartString);
1161 m_tTo->SetValue(m_pTrack->m_TrackEndString);
1162 if (m_tDescription) m_tDescription->SetValue(m_pTrack->m_TrackDescription);
1163
1164 m_tTotDistance->SetValue(_T(""));
1165 m_tTimeEnroute->SetValue(_T(""));
1166
1167 m_sdbBtmBtnsSizerSplit->Enable(false);
1168 m_sdbBtmBtnsSizerExtend->Enable(false);
1169
1170 // Calculate AVG speed if we are showing a track and total time
1171 TrackPoint* last_point = m_pTrack->GetLastPoint();
1172 TrackPoint* first_point = m_pTrack->GetPoint(0);
1173 double trackLength = m_pTrack->Length();
1174 double total_seconds = 0.;
1175
1176 wxString speed(_T("--"));
1177
1178 if (last_point && first_point) {
1179 if (last_point->GetCreateTime().IsValid() &&
1180 first_point->GetCreateTime().IsValid()) {
1181 total_seconds = last_point->GetCreateTime()
1182 .Subtract(first_point->GetCreateTime())
1183 .GetSeconds()
1184 .ToDouble();
1185 if (total_seconds != 0.) {
1186 m_avgspeed = trackLength / total_seconds * 3600;
1187 } else {
1188 m_avgspeed = 0;
1189 }
1190 speed.Printf(_T("%5.2f"), toUsrSpeed(m_avgspeed));
1191 }
1192 }
1193
1194 m_tAvgSpeed->SetValue(speed);
1195
1196 // Total length
1197 wxString slen;
1198 slen.Printf(wxT("%5.2f ") + getUsrDistanceUnit(), toUsrDistance(trackLength));
1199
1200 m_tTotDistance->SetValue(slen);
1201
1202 // Time
1203 wxString time_form;
1204 wxTimeSpan time(0, 0, (int)total_seconds, 0);
1205 // TODO Construct a readable time string, e.g. "xx Days, 15:34"
1206 if (total_seconds > 3600. * 24.)
1207 time_form = time.Format("%H:%M");
1208 else if (total_seconds > 0.)
1209 time_form = time.Format("%H:%M");
1210 else
1211 time_form = _T("--");
1212 m_tTimeEnroute->SetValue(time_form);
1213
1214 m_cbShow->SetValue(m_pTrack->IsVisible());
1215
1216 if (m_pTrack->m_Colour == wxEmptyString)
1217 m_cColor->Select(0);
1218 else {
1219 for (unsigned int i = 0; i < sizeof(::GpxxColorNames) / sizeof(wxString);
1220 i++) {
1221 if (m_pTrack->m_Colour == ::GpxxColorNames[i]) {
1222 m_cColor->Select(i + 1);
1223 break;
1224 }
1225 }
1226 }
1227
1228 for (unsigned int i = 0; i < sizeof(::StyleValues) / sizeof(int); i++) {
1229 if (m_pTrack->m_style == ::StyleValues[i]) {
1230 m_cStyle->Select(i);
1231 break;
1232 }
1233 }
1234
1235 for (unsigned int i = 0; i < sizeof(::WidthValues) / sizeof(int); i++) {
1236 if (m_pTrack->m_width == ::WidthValues[i]) {
1237 m_cWidth->Select(i);
1238 break;
1239 }
1240 }
1241
1242 if (m_pTrack->m_bIsInLayer) {
1243 m_tName->SetEditable(false);
1244 m_tFrom->SetEditable(false);
1245 m_tTo->SetEditable(false);
1246 if (m_tDescription) m_tDescription->SetEditable(false);
1247 m_cbShow->Enable(false);
1248 m_cColor->Enable(false);
1249 m_cStyle->Enable(false);
1250 m_cWidth->Enable(false);
1251 m_sdbBtmBtnsSizerExtend->Enable(false);
1252 m_sdbBtmBtnsSizerSplit->Enable(false);
1253 SetTitle(wxString::Format(_T("%s, %s: %d"), _("Track properties"),
1254 _T("Layer"), m_pTrack->m_LayerID));
1255 } else {
1256 m_tName->SetEditable(true);
1257 m_tFrom->SetEditable(true);
1258 m_tTo->SetEditable(true);
1259 if (m_tDescription) m_tDescription->SetEditable(true);
1260 m_cbShow->Enable(true);
1261 m_cColor->Enable(true);
1262 m_cStyle->Enable(true);
1263 m_cWidth->Enable(true);
1264
1265 m_sdbBtmBtnsSizerExtend->Enable(IsThisTrackExtendable());
1266 // m_sdbBtmBtnsSizerSplit->Enable( false );
1267 SetTitle(_("Track properties"));
1268 }
1269
1270 ::wxEndBusyCursor();
1271
1272 return true;
1273}
1274
1275bool TrackPropDlg::IsThisTrackExtendable() {
1276 m_pExtendTrack = NULL;
1277 m_pExtendPoint = NULL;
1278 if (m_pTrack == g_pActiveTrack || m_pTrack->m_bIsInLayer) {
1279 return false;
1280 }
1281
1282 TrackPoint* pLastPoint = m_pTrack->GetPoint(0);
1283 if (!pLastPoint->GetCreateTime().IsValid()) {
1284 return false;
1285 }
1286
1287 for (Track* ptrack : g_TrackList) {
1288 if (ptrack->IsVisible() && (ptrack->m_GUID != m_pTrack->m_GUID)) {
1289 TrackPoint* track_node = ptrack->GetLastPoint();
1290 if (track_node) {
1291 if (track_node->GetCreateTime().IsValid()) {
1292 if (track_node->GetCreateTime() <= pLastPoint->GetCreateTime()) {
1293 if (!m_pExtendPoint ||
1294 track_node->GetCreateTime() > m_pExtendPoint->GetCreateTime()) {
1295 m_pExtendPoint = track_node;
1296 m_pExtendTrack = ptrack;
1297 }
1298 }
1299 }
1300 }
1301 }
1302 }
1303 if (m_pExtendTrack) {
1304 return (!m_pExtendTrack->m_bIsInLayer);
1305 } else {
1306 return false;
1307 }
1308}
1309
1310void TrackPropDlg::OnExtendBtnClick(wxCommandEvent& event) {
1311 TrackPoint* pFirstPoint = m_pTrack->GetPoint(0);
1312
1313 if (IsThisTrackExtendable()) {
1314 int begin = 0;
1315 if (pFirstPoint->GetCreateTime() == m_pExtendPoint->GetCreateTime()) {
1316 begin = 1;
1317 }
1318 pSelect->DeleteAllSelectableTrackSegments(m_pExtendTrack);
1319 m_pExtendTrack->Clone(m_pTrack, begin, m_pTrack->GetnPoints(), _("_plus"));
1320 pSelect->AddAllSelectableTrackSegments(m_pExtendTrack);
1321 pSelect->DeleteAllSelectableTrackSegments(m_pTrack);
1322 RoutemanGui(*g_pRouteMan).DeleteTrack(m_pTrack);
1323
1324 SetTrackAndUpdate(m_pExtendTrack);
1326
1327 if (pRouteManagerDialog && pRouteManagerDialog->IsShown()) {
1328 pRouteManagerDialog->UpdateTrkListCtrl();
1329 }
1330 }
1331}
1332
1333void TrackPropDlg::OnSplitBtnClick(wxCommandEvent& event) {
1334 m_sdbBtmBtnsSizerSplit->Enable(false);
1335
1336 if (m_pTrack->m_bIsInLayer) {
1337 return;
1338 }
1339
1340 if ((m_nSelected > 1) && (m_nSelected < m_pTrack->GetnPoints())) {
1341 Track* pHead = new Track();
1342 Track* pTail = new Track();
1343 pHead->Clone(m_pTrack, 0, m_nSelected - 1, _("_A"));
1344 pTail->Clone(m_pTrack, m_nSelected - 1, m_pTrack->GetnPoints(), _("_B"));
1345 g_TrackList.push_back(pHead);
1346 pConfig->AddNewTrack(pHead);
1347
1348 g_TrackList.push_back(pTail);
1349 pConfig->AddNewTrack(pTail);
1350
1351 pConfig->DeleteConfigTrack(m_pTrack);
1352
1353 pSelect->DeleteAllSelectableTrackSegments(m_pTrack);
1354 RoutemanGui(*g_pRouteMan).DeleteTrack(m_pTrack);
1355 pSelect->AddAllSelectableTrackSegments(pTail);
1356 pSelect->AddAllSelectableTrackSegments(pHead);
1357
1358 SetTrackAndUpdate(pTail);
1360
1361 if (pRouteManagerDialog && pRouteManagerDialog->IsShown()) {
1362 pRouteManagerDialog->UpdateTrkListCtrl();
1363 }
1364 }
1365}
1366
1367void TrackPropDlg::OnTrackPropCopyTxtClick(wxCommandEvent& event) {
1368 wxString tab("\t", wxConvUTF8);
1369 wxString eol("\n", wxConvUTF8);
1370 wxString csvString;
1371
1372 csvString << this->GetTitle() << eol << _("Name") << tab
1373 << m_pTrack->GetName() << eol << _("Depart From") << tab
1374 << m_pTrack->m_TrackStartString << eol << _("Destination") << tab
1375 << m_pTrack->m_TrackEndString << eol << _("Total distance") << tab
1376 << m_tTotDistance->GetValue() << eol << _("Speed") << tab
1377 << m_tAvgSpeed->GetValue() << eol
1378 << _("Departure Time") + _T(" ") + _("(m/d/y h:m)") << tab
1379 << m_pTrack->GetPoint(1)->GetCreateTime().Format() << eol
1380 << _("Time enroute") << tab << m_tTimeEnroute->GetValue() << eol
1381 << eol;
1382
1383 int noCols;
1384 int noRows;
1385 noCols = m_lcPoints->GetColumnCount();
1386 noRows = m_lcPoints->GetItemCount();
1387 wxListItem item;
1388 item.SetMask(wxLIST_MASK_TEXT);
1389
1390 for (int i = 0; i < noCols; i++) {
1391 m_lcPoints->GetColumn(i, item);
1392 csvString << item.GetText() << tab;
1393 }
1394 csvString << eol;
1395
1396 for (int j = 0; j < noRows; j++) {
1397 item.SetId(j);
1398 for (int i = 0; i < noCols; i++) {
1399 item.SetColumn(i);
1400 m_lcPoints->GetItem(item);
1401 csvString << item.GetText() << tab;
1402 }
1403 csvString << eol;
1404 }
1405
1406 if (wxTheClipboard->Open()) {
1407 wxTextDataObject* data = new wxTextDataObject;
1408 data->SetText(csvString);
1409 wxTheClipboard->SetData(data);
1410 wxTheClipboard->Close();
1411 }
1412}
1413
1414void TrackPropDlg::OnPrintBtnClick(wxCommandEvent& event) {
1415 static std::set<int> s_options; // keep selected options
1416 TrackPrintDialog dlg(this, s_options);
1417 int result = dlg.ShowModal();
1418
1419 if (result == wxID_OK) {
1420 dlg.GetSelected(s_options);
1421 TrackPrintout printout(m_pTrack, m_lcPoints, s_options);
1422 auto& printer = PrintDialog::GetInstance();
1423 printer.Initialize(wxPORTRAIT);
1424 printer.EnablePageNumbers(true);
1425 printer.Print(this, &printout);
1426 }
1427}
1428
1429void TrackPropDlg::OnTrackPropRightClick(wxListEvent& event) {
1430 wxMenu menu;
1431
1432 wxMenuItem* copyItem =
1433 menu.Append(ID_RCLK_MENU_COPY_TEXT, _("&Copy all as text"));
1434
1435 PopupMenu(&menu);
1436}
1437
1438void TrackPropDlg::OnTrackPropListClick(wxListEvent& event) {
1439 long itemno = -1;
1440 m_nSelected = 0;
1441
1442 int selected_no;
1443 itemno =
1444 m_lcPoints->GetNextItem(itemno, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
1445 if (itemno == -1)
1446 selected_no = 0;
1447 else
1448 selected_no = itemno;
1449
1450 m_pTrack->m_HighlightedTrackPoint = -1;
1451
1452 if (itemno >= 0) {
1453 TrackPoint* prp = m_pTrack->GetPoint(itemno);
1454 if (prp) {
1455 m_pTrack->m_HighlightedTrackPoint = itemno; // highlight the trackpoint
1456
1457 if (!(m_pTrack->m_bIsInLayer) && !(m_pTrack == g_pActiveTrack)) {
1458 m_nSelected = selected_no + 1;
1459 m_sdbBtmBtnsSizerSplit->Enable(true);
1460 }
1461 if (gFrame->GetFocusCanvas()) {
1462 gFrame->JumpToPosition(gFrame->GetFocusCanvas(), prp->m_lat, prp->m_lon,
1463 gFrame->GetFocusCanvas()->GetVPScale());
1464 }
1465#ifdef __WXMSW__
1466 if (m_lcPoints) m_lcPoints->SetFocus();
1467#endif
1468 }
1469 }
1470 if (selected_no == 0 || selected_no == m_pTrack->GetnPoints() - 1)
1471 m_sdbBtmBtnsSizerSplit->Enable(false);
1472}
1473
1474void TrackPropDlg::OnTrackPropMenuSelected(wxCommandEvent& event) {
1475 switch (event.GetId()) {
1476 case ID_RCLK_MENU_COPY_TEXT:
1477 OnTrackPropCopyTxtClick(event);
1478 break;
1479 }
1480}
1481
1482void TrackPropDlg::OnToRouteBtnClick(wxCommandEvent& event) {
1483 pRouteManagerDialog->TrackToRoute(m_pTrack);
1484 if (NULL != pRouteManagerDialog && pRouteManagerDialog->IsVisible())
1485 pRouteManagerDialog->UpdateRouteListCtrl();
1486}
1487
1488void TrackPropDlg::OnExportBtnClick(wxCommandEvent& event) {
1489 wxString suggested_name = _("track");
1490 std::vector<Track*> list = {m_pTrack};
1491 if (m_pTrack->GetName() != wxEmptyString)
1492 suggested_name = m_pTrack->GetName();
1493 ExportGPXTracks(this, &list, suggested_name);
1494}
1495
1496void TrackPropDlg::m_hyperlinkContextMenu(wxMouseEvent& event) {
1497 m_pEditedLink = (wxHyperlinkCtrl*)event.GetEventObject();
1498 Connect(
1499 wxEVT_COMMAND_MENU_SELECTED,
1500 (wxObjectEventFunction)(wxEventFunction)&TrackPropDlg::PopupMenuHandler);
1501 m_scrolledWindowLinks->PopupMenu(
1502 m_menuLink, m_pEditedLink->GetPosition().x + event.GetPosition().x,
1503 m_pEditedLink->GetPosition().y + event.GetPosition().y);
1504}
1505
1506void TrackPropDlg::PopupMenuHandler(wxCommandEvent& event) {
1507 switch (event.GetId()) {
1508 case ID_TRK_MENU_ADD:
1509 OnAddLink(event);
1510 break;
1511 case ID_TRK_MENU_EDIT:
1512 OnEditLink(event);
1513 break;
1514 case ID_TRK_MENU_DELETE:
1515 OnDeleteLink(event);
1516 break;
1517 default:
1518 break;
1519 }
1520}
1521
1522void TrackPropDlg::OnDeleteLink(wxCommandEvent& event) {
1523 wxHyperlinkListNode* nodeToDelete = NULL;
1524 wxString findurl = m_pEditedLink->GetURL();
1525 wxString findlabel = m_pEditedLink->GetLabel();
1526
1527 wxWindowList kids = m_scrolledWindowLinks->GetChildren();
1528 for (unsigned int i = 0; i < kids.GetCount(); i++) {
1529 wxWindowListNode* node = kids.Item(i);
1530 wxWindow* win = node->GetData();
1531
1532 auto link_win = dynamic_cast<wxHyperlinkCtrl*>(win);
1533 if (link_win) {
1534 link_win->Disconnect(
1535 wxEVT_COMMAND_HYPERLINK,
1536 wxHyperlinkEventHandler(TrackPropDlg::OnHyperLinkClick));
1537 link_win->Disconnect(
1538 wxEVT_RIGHT_DOWN,
1539 wxMouseEventHandler(TrackPropDlg::m_hyperlinkContextMenu));
1540 win->Destroy();
1541 }
1542 }
1543
1545 int NbrOfLinks = m_pTrack->m_HyperlinkList->GetCount();
1546 HyperlinkList* hyperlinklist = m_pTrack->m_HyperlinkList;
1547 // int len = 0;
1548 if (NbrOfLinks > 0) {
1549 wxHyperlinkListNode* linknode = hyperlinklist->GetFirst();
1550 while (linknode) {
1551 Hyperlink* link = linknode->GetData();
1552 wxString Link = link->Link;
1553 wxString Descr = link->DescrText;
1554 if (Link == findurl &&
1555 (Descr == findlabel || (Link == findlabel && Descr == wxEmptyString)))
1556 nodeToDelete = linknode;
1557 else {
1558 wxHyperlinkCtrl* ctrl = new wxHyperlinkCtrl(
1559 m_scrolledWindowLinks, wxID_ANY, Descr, Link, wxDefaultPosition,
1560 wxDefaultSize, wxHL_DEFAULT_STYLE);
1561 ctrl->Connect(wxEVT_COMMAND_HYPERLINK,
1562 wxHyperlinkEventHandler(TrackPropDlg::OnHyperLinkClick),
1563 NULL, this);
1564 ctrl->Connect(wxEVT_RIGHT_DOWN,
1565 wxMouseEventHandler(TrackPropDlg::m_hyperlinkContextMenu),
1566 NULL, this);
1567
1568 bSizerLinks->Add(ctrl, 0, wxALL, 5);
1569 }
1570 linknode = linknode->GetNext();
1571 }
1572 }
1573 if (nodeToDelete) hyperlinklist->DeleteNode(nodeToDelete);
1574 m_scrolledWindowLinks->InvalidateBestSize();
1575 m_scrolledWindowLinks->Layout();
1576 sbSizerLinks->Layout();
1577 // event.Skip();
1578}
1579
1580void TrackPropDlg::OnEditLink(wxCommandEvent& event) {
1581 wxString findurl = m_pEditedLink->GetURL();
1582 wxString findlabel = m_pEditedLink->GetLabel();
1583
1584 LinkPropImpl* LinkPropDlg = new LinkPropImpl(this);
1585 LinkPropDlg->m_textCtrlLinkDescription->SetValue(findlabel);
1586 LinkPropDlg->m_textCtrlLinkUrl->SetValue(findurl);
1587 DimeControl(LinkPropDlg);
1588 LinkPropDlg->ShowWindowModalThenDo([this, LinkPropDlg, findurl,
1589 findlabel](int retcode) {
1590 if (retcode == wxID_OK) {
1591 int NbrOfLinks = m_pTrack->m_HyperlinkList->GetCount();
1592 HyperlinkList* hyperlinklist = m_pTrack->m_HyperlinkList;
1593 // int len = 0;
1594 if (NbrOfLinks > 0) {
1595 wxHyperlinkListNode* linknode = hyperlinklist->GetFirst();
1596 while (linknode) {
1597 Hyperlink* link = linknode->GetData();
1598 wxString Link = link->Link;
1599 wxString Descr = link->DescrText;
1600 if (Link == findurl &&
1601 (Descr == findlabel ||
1602 (Link == findlabel && Descr == wxEmptyString))) {
1603 link->Link = LinkPropDlg->m_textCtrlLinkUrl->GetValue();
1604 link->DescrText =
1605 LinkPropDlg->m_textCtrlLinkDescription->GetValue();
1606 wxHyperlinkCtrl* h =
1607 (wxHyperlinkCtrl*)m_scrolledWindowLinks->FindWindowByLabel(
1608 findlabel);
1609 if (h) {
1610 h->SetLabel(LinkPropDlg->m_textCtrlLinkDescription->GetValue());
1611 h->SetURL(LinkPropDlg->m_textCtrlLinkUrl->GetValue());
1612 }
1613 }
1614 linknode = linknode->GetNext();
1615 }
1616 }
1617
1618 m_scrolledWindowLinks->InvalidateBestSize();
1619 m_scrolledWindowLinks->Layout();
1620 sbSizerLinks->Layout();
1621 }
1622 });
1623 // event.Skip();
1624}
1625
1626void TrackPropDlg::OnAddLink(wxCommandEvent& event) {
1627 LinkPropImpl* LinkPropDlg = new LinkPropImpl(this);
1628 LinkPropDlg->m_textCtrlLinkDescription->SetValue(wxEmptyString);
1629 LinkPropDlg->m_textCtrlLinkUrl->SetValue(wxEmptyString);
1630 DimeControl(LinkPropDlg);
1631 LinkPropDlg->ShowWindowModalThenDo([this, LinkPropDlg](int retcode) {
1632 if (retcode == wxID_OK) {
1633 wxString desc = LinkPropDlg->m_textCtrlLinkDescription->GetValue();
1634 if (desc == wxEmptyString)
1635 desc = LinkPropDlg->m_textCtrlLinkUrl->GetValue();
1636 wxHyperlinkCtrl* ctrl = new wxHyperlinkCtrl(
1637 m_scrolledWindowLinks, wxID_ANY, desc,
1638 LinkPropDlg->m_textCtrlLinkUrl->GetValue(), wxDefaultPosition,
1639 wxDefaultSize, wxHL_DEFAULT_STYLE);
1640 ctrl->Connect(wxEVT_COMMAND_HYPERLINK,
1641 wxHyperlinkEventHandler(TrackPropDlg::OnHyperLinkClick),
1642 NULL, this);
1643 ctrl->Connect(wxEVT_RIGHT_DOWN,
1644 wxMouseEventHandler(TrackPropDlg::m_hyperlinkContextMenu),
1645 NULL, this);
1646
1647 bSizerLinks->Add(ctrl, 0, wxALL, 5);
1648 bSizerLinks->Fit(m_scrolledWindowLinks);
1649 // this->Fit();
1650
1651 Hyperlink* h = new Hyperlink();
1652 h->DescrText = LinkPropDlg->m_textCtrlLinkDescription->GetValue();
1653 h->Link = LinkPropDlg->m_textCtrlLinkUrl->GetValue();
1654 h->LType = wxEmptyString;
1655 m_pTrack->m_HyperlinkList->Append(h);
1656 }
1657 });
1658 // sbSizerLinks->Layout();
1659
1660 m_scrolledWindowLinks->InvalidateBestSize();
1661 m_scrolledWindowLinks->Layout();
1662 sbSizerLinks->Layout();
1663
1664 // event.Skip();
1665}
1666
1667void TrackPropDlg::OnEditLinkToggle(wxCommandEvent& event) {
1668 if (m_toggleBtnEdit->GetValue())
1669 m_staticTextEditEnabled->SetLabel(_("Links are opened for editing."));
1670 else
1671 m_staticTextEditEnabled->SetLabel(
1672 _("Links are opened in the default browser."));
1673 event.Skip();
1674}
1675
1676void TrackPropDlg::OnHyperLinkClick(wxHyperlinkEvent& event) {
1677 if (m_toggleBtnEdit->GetValue()) {
1678 m_pEditedLink = (wxHyperlinkCtrl*)event.GetEventObject();
1679 OnEditLink(event);
1680 event.Skip(false);
1681 return;
1682 }
1683 // Windows has trouble handling local file URLs with embedded anchor
1684 // points, e.g file://testfile.html#point1 The trouble is with the
1685 // wxLaunchDefaultBrowser with verb "open" Workaround is to probe the
1686 // registry to get the default browser, and open directly
1687 //
1688 // But, we will do this only if the URL contains the anchor point charater
1689 // '#' What a hack......
1690
1691#ifdef __WXMSW__
1692
1693 wxString cc = event.GetURL();
1694 if (cc.Find(_T("#")) != wxNOT_FOUND) {
1695 wxRegKey RegKey(
1696 wxString(_T("HKEY_CLASSES_ROOT\\HTTP\\shell\\open\\command")));
1697 if (RegKey.Exists()) {
1698 wxString command_line;
1699 RegKey.QueryValue(wxString(_T("")), command_line);
1700
1701 // Remove "
1702 command_line.Replace(wxString(_T("\"")), wxString(_T("")));
1703
1704 // Strip arguments
1705 int l = command_line.Find(_T(".exe"));
1706 if (wxNOT_FOUND == l) l = command_line.Find(_T(".EXE"));
1707
1708 if (wxNOT_FOUND != l) {
1709 wxString cl = command_line.Mid(0, l + 4);
1710 cl += _T(" ");
1711 cc.Prepend(_T("\""));
1712 cc.Append(_T("\""));
1713 cl += cc;
1714 wxExecute(cl); // Async, so Fire and Forget...
1715 }
1716 }
1717 } else
1718 event.Skip();
1719#else
1720 wxString url = event.GetURL();
1721 url.Replace(_T(" "), _T("%20"));
1722 ::wxLaunchDefaultBrowser(url);
1723// event.Skip();
1724#endif
1725}
1726
1727void TrackPropDlg::OnShowTimeTZ(wxCommandEvent& event) {
1728 if (m_rbShowTimeUTC && m_rbShowTimeUTC->GetValue())
1729 m_lcPoints->m_tz_selection = UTCINPUT;
1730 else if (m_rbShowTimePC && m_rbShowTimePC->GetValue())
1731 m_lcPoints->m_tz_selection = LTINPUT;
1732 else if (m_rbShowTimeLocal && m_rbShowTimeLocal->GetValue())
1733 m_lcPoints->m_tz_selection = LMTINPUT;
1735 m_lcPoints->m_tz_selection = GLOBAL_SETTINGS_INPUT;
1736 else
1737 throw std::logic_error("Unexpected time zone selection");
1738 m_lcPoints->DeleteAllItems();
1739 InitializeList();
1740}
1741
1742bool TrackPropDlg::SaveChanges(void) {
1743 if (m_pTrack && !m_pTrack->m_bIsInLayer) {
1744 // Get User input Text Fields
1745 m_pTrack->SetName(m_tName->GetValue());
1746 m_pTrack->m_TrackStartString = m_tFrom->GetValue();
1747 m_pTrack->m_TrackEndString = m_tTo->GetValue();
1748 if (m_tDescription)
1749 m_pTrack->m_TrackDescription = m_tDescription->GetValue();
1750 m_pTrack->SetVisible(m_cbShow->GetValue());
1751 if (m_cColor->GetSelection() == 0)
1752 m_pTrack->m_Colour = wxEmptyString;
1753 else
1754 m_pTrack->m_Colour = ::GpxxColorNames[m_cColor->GetSelection() - 1];
1755 m_pTrack->m_style = (wxPenStyle)::StyleValues[m_cStyle->GetSelection()];
1756 m_pTrack->m_width = ::WidthValues[m_cWidth->GetSelection()];
1757
1758 pConfig->UpdateTrack(m_pTrack);
1759 pConfig->UpdateSettings();
1760 }
1761
1762 if (m_pTrack && m_pTrack->IsRunning()) {
1763 wxJSONValue v;
1764 v[_T("Changed")] = true;
1765 v[_T("Name")] = m_pTrack->GetName();
1766 v[_T("GUID")] = m_pTrack->m_GUID;
1767 wxString msg_id(_T("OCPN_TRK_ACTIVATED"));
1768 SendJSONMessageToAllPlugins(msg_id, v);
1769 }
1770
1771 return true;
1772}
1773
1774void TrackPropDlg::OnOKBtnClick(wxCommandEvent& event) {
1775 // Look in the track list to be sure the track is still available
1776 // (May have been deleted by RouteManagerDialog...)
1777
1778 bool b_found_track = std::find(g_TrackList.begin(), g_TrackList.end(),
1779 m_pTrack) != g_TrackList.end();
1780
1781 if (b_found_track) {
1782 SaveChanges(); // write changes to globals and update config
1783 m_pTrack->ClearHighlights();
1784 }
1785
1786 m_bStartNow = false;
1787
1788 if (pRouteManagerDialog && pRouteManagerDialog->IsShown())
1789 pRouteManagerDialog->UpdateTrkListCtrl();
1790
1791 Hide();
1792 gFrame->InvalidateAllGL();
1793 gFrame->RefreshAllCanvas(false);
1794
1795 event.Skip();
1796}
1797
1798void TrackPropDlg::OnCancelBtnClick(wxCommandEvent& event) {
1799 bool b_found_track = std::find(g_TrackList.begin(), g_TrackList.end(),
1800 m_pTrack) != g_TrackList.end();
1801
1802 if (b_found_track) m_pTrack->ClearHighlights();
1803
1804 Hide();
1805 gFrame->InvalidateAllGL();
1806 gFrame->RefreshAllCanvas(false);
1807
1808 event.Skip();
1809}
1810
1811//--------------------------------------------------------------------------------------
1812// OCPNTrackListCtrl Implementation
1813//---------------------------------------------------------------------------------------
1814
1815OCPNTrackListCtrl::OCPNTrackListCtrl(wxWindow* parent, wxWindowID id,
1816 const wxPoint& pos, const wxSize& size,
1817 long style)
1818 : wxListCtrl(parent, id, pos, size, style) {
1819 m_parent = parent;
1820 m_tz_selection = GLOBAL_SETTINGS_INPUT;
1821 m_LMT_Offset = 0;
1822}
1823
1824OCPNTrackListCtrl::~OCPNTrackListCtrl() {}
1825
1827 if (m_pTrack->GetnPoints()) {
1828 TrackPoint* prp = m_pTrack->GetPoint(0);
1829 if (prp) return prp->m_lon;
1830 }
1831 return NAN;
1832}
1833
1834wxString OCPNTrackListCtrl::OnGetItemText(long item, long column) const {
1835 wxString ret;
1836
1837 if (item < 0 || item >= m_pTrack->GetnPoints()) return wxEmptyString;
1838
1839 TrackPoint* this_point = m_pTrack->GetPoint(item);
1840 TrackPoint* prev_point = item > 0 ? m_pTrack->GetPoint(item - 1) : NULL;
1841
1842 if (!this_point) return wxEmptyString;
1843
1844 double gt_brg, gt_leg_dist;
1845 double slat, slon;
1846 if (item == 0) {
1847 slat = gLat;
1848 slon = gLon;
1849 } else {
1850 slat = prev_point->m_lat;
1851 slon = prev_point->m_lon;
1852 }
1853
1854 switch (column) {
1855 case 0:
1856 if (item == 0)
1857 ret = _T("---");
1858 else
1859 ret.Printf(_T("%ld"), item);
1860 break;
1861
1862 case 1:
1863 DistanceBearingMercator(this_point->m_lat, this_point->m_lon, slat, slon,
1864 &gt_brg, &gt_leg_dist);
1865
1866 ret.Printf(_T("%6.2f ") + getUsrDistanceUnit(),
1867 toUsrDistance(gt_leg_dist));
1868 break;
1869
1870 case 2:
1871 DistanceBearingMercator(this_point->m_lat, this_point->m_lon, slat, slon,
1872 &gt_brg, &gt_leg_dist);
1873 ret.Printf("%03.0f %cT", gt_brg, 0x00B0);
1874 break;
1875
1876 case 3:
1877 ret = toSDMM(1, this_point->m_lat, 1);
1878 break;
1879
1880 case 4:
1881 ret = toSDMM(2, this_point->m_lon, 1);
1882 break;
1883
1884 case 5: {
1885 wxDateTime timestamp = this_point->GetCreateTime();
1886 if (timestamp.IsValid()) {
1889 .SetTimezone(getDatetimeTimezoneSelector(m_tz_selection))
1891 ret = ocpn::toUsrDateTimeFormat(timestamp.FromUTC(), opts);
1892 } else
1893 ret = _T("----");
1894 } break;
1895
1896 case 6:
1897 if ((item > 0) && this_point->GetCreateTime().IsValid() &&
1898 prev_point->GetCreateTime().IsValid()) {
1899 DistanceBearingMercator(this_point->m_lat, this_point->m_lon, slat,
1900 slon, &gt_brg, &gt_leg_dist);
1901 double speed = 0.;
1902 double seconds = this_point->GetCreateTime()
1903 .Subtract(prev_point->GetCreateTime())
1904 .GetSeconds()
1905 .ToDouble();
1906
1907 if (seconds > 0.) speed = gt_leg_dist / seconds * 3600;
1908
1909 ret.Printf(_T("%5.2f"), toUsrSpeed(speed));
1910 } else
1911 ret = _("--");
1912 break;
1913
1914 default:
1915 break;
1916 }
1917
1918 return ret;
1919}
1920
1921int OCPNTrackListCtrl::OnGetItemColumnImage(long item, long column) const {
1922 return -1;
1923}
Represents an active track that is currently being recorded.
Definition track.h:226
Class LinkPropImpl.
Definition LinkPropDlg.h:89
Main application frame.
Definition ocpn_frame.h:136
int m_tz_selection
The timezone to use when formatting date/time.
double getStartPointLongitude() const
Return the longitude at the start point of the track.
static PrintDialog & GetInstance()
Get instance to handle the print process,.
Represents a single point in a track.
Definition track.h:53
wxDateTime GetCreateTime(void)
Retrieves the creation timestamp of a track point as a wxDateTime object.
Definition track.cpp:139
Input dialog with track print selection.
Printout a table with track selected information.
Class TrackPropDlg.
bool UpdateProperties()
void OnDeleteLink(wxCommandEvent &event)
wxRadioButton * m_rbShowTimeLocal
Use Local Mean Time (LMT) at the location to format date/time.
wxRadioButton * m_rbShowTimePC
Use system timezone to format date/time, i.e.
wxRadioButton * m_rbShowTimeGlobalSettings
Honor OpenCPN global setting to format date/time.
Represents a track, which is a series of connected track points.
Definition track.h:111
The JSON value class implementation.
Definition jsonval.h:84
wxFont * GetOCPNScaledFont(wxString item, int default_size)
Retrieves a font from FontMgr, optionally scaled for physical readability.
Definition gui_lib.cpp:54
General purpose GUI support.
Tools to send data to plugins.
Configuration options for date and time formatting.
DateTimeFormatOptions & SetTimezone(const wxString &tz)
Sets the timezone mode for date/time display.
DateTimeFormatOptions & SetLongitude(double lon)
Sets the reference longitude for Local Mean Time (LMT) calculations.