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