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