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 "gl_headers.h" // Must be included before anything using GL stuff
28
29#include "model/georef.h"
30#include "model/gui_vars.h"
31#include "model/navobj_db.h"
32#include "model/navutil_base.h"
33#include "model/own_ship.h"
34#include "model/plugin_comm.h"
35#include "model/route.h"
36#include "model/routeman.h"
37#include "model/select.h"
38#include "model/track.h"
39
40#include "chcanv.h"
41#include "displays.h"
42#include "gui_lib.h"
43#include "navutil.h"
44#include "ocpn_platform.h"
45#include "pluginmanager.h"
46#include "print_dialog.h"
47#include "routemanagerdialog.h"
48#include "routeman_gui.h"
49#include "top_frame.h"
50#include "track_printout.h"
51#include "track_prop_dlg.h"
52
53#ifdef __ANDROID__
54#include "androidUTIL.h"
55#endif
56
57#define UTCINPUT 0
58#define LTINPUT \
59 1
60#define LMTINPUT \
61 2
63#define GLOBAL_SETTINGS_INPUT 3
64
65#define INPUT_FORMAT 1
66#define DISPLAY_FORMAT 2
67#define TIMESTAMP_FORMAT 3
68
70
72
73bool TrackPropDlg::instanceFlag = false;
74TrackPropDlg* TrackPropDlg::single = NULL;
75TrackPropDlg* TrackPropDlg::getInstance(wxWindow* parent, wxWindowID id,
76 const wxString& title,
77 const wxPoint& pos, const wxSize& size,
78 long style) {
79 if (!instanceFlag) {
80 single = new TrackPropDlg(parent, id, title, pos, size, style);
81 instanceFlag = true;
82 return single;
83 } else {
84 return single;
85 }
86}
87
88TrackPropDlg::TrackPropDlg(wxWindow* parent, wxWindowID id,
89 const wxString& title, const wxPoint& pos,
90 const wxSize& size, long style)
91 : DIALOG_PARENT(parent, id, title, pos, size, style) {
92 wxFont* qFont = GetOCPNScaledFont(_("Dialog"));
93 SetFont(*qFont);
94
95 SetWindowStyleFlag(style);
96
97 m_scrolledWindowLinks = NULL;
98 m_tDescription = NULL;
99
100 m_bcompact = false;
101
102#ifdef __ANDROID__
103 m_bcompact = true;
104 CreateControlsCompact();
105#else
106 CreateControls();
107#endif
108
109 RecalculateSize();
110
111 // Centre( );
112
113 // Connect Events
114 m_sdbBtmBtnsSizerCancel->Connect(
115 wxEVT_COMMAND_BUTTON_CLICKED,
116 wxCommandEventHandler(TrackPropDlg::OnCancelBtnClick), NULL, this);
117 m_sdbBtmBtnsSizerOK->Connect(
118 wxEVT_COMMAND_BUTTON_CLICKED,
119 wxCommandEventHandler(TrackPropDlg::OnOKBtnClick), NULL, this);
120 if (m_sdbBtmBtnsSizerPrint)
121 m_sdbBtmBtnsSizerPrint->Connect(
122 wxEVT_COMMAND_BUTTON_CLICKED,
123 wxCommandEventHandler(TrackPropDlg::OnPrintBtnClick), NULL, this);
124 m_sdbBtmBtnsSizerSplit->Connect(
125 wxEVT_COMMAND_BUTTON_CLICKED,
126 wxCommandEventHandler(TrackPropDlg::OnSplitBtnClick), NULL, this);
127 m_sdbBtmBtnsSizerExtend->Connect(
128 wxEVT_COMMAND_BUTTON_CLICKED,
129 wxCommandEventHandler(TrackPropDlg::OnExtendBtnClick), NULL, this);
130 m_sdbBtmBtnsSizerToRoute->Connect(
131 wxEVT_COMMAND_BUTTON_CLICKED,
132 wxCommandEventHandler(TrackPropDlg::OnToRouteBtnClick), NULL, this);
133 if (m_sdbBtmBtnsSizerExport)
134 m_sdbBtmBtnsSizerExport->Connect(
135 wxEVT_COMMAND_BUTTON_CLICKED,
136 wxCommandEventHandler(TrackPropDlg::OnExportBtnClick), NULL, this);
137 m_lcPoints->Connect(wxEVT_COMMAND_LIST_ITEM_SELECTED,
138 wxListEventHandler(TrackPropDlg::OnTrackPropListClick),
139 NULL, this);
140 Connect(wxEVT_COMMAND_LIST_ITEM_RIGHT_CLICK,
141 wxListEventHandler(TrackPropDlg::OnTrackPropRightClick), NULL, this);
142 Connect(wxEVT_COMMAND_MENU_SELECTED,
143 wxCommandEventHandler(TrackPropDlg::OnTrackPropMenuSelected), NULL,
144 this);
145
146#ifdef __WXOSX__
147 Connect(wxEVT_ACTIVATE, wxActivateEventHandler(TrackPropDlg::OnActivate),
148 NULL, this);
149#endif
150
151 if (!m_bcompact) {
152 m_buttonAddLink->Connect(wxEVT_COMMAND_BUTTON_CLICKED,
153 wxCommandEventHandler(TrackPropDlg::OnAddLink),
154 NULL, this);
155 m_toggleBtnEdit->Connect(
156 wxEVT_COMMAND_TOGGLEBUTTON_CLICKED,
157 wxCommandEventHandler(TrackPropDlg::OnEditLinkToggle), NULL, this);
158 }
159
160 if (m_rbShowTimeUTC)
161 m_rbShowTimeUTC->Connect(wxEVT_COMMAND_RADIOBUTTON_SELECTED,
162 wxCommandEventHandler(TrackPropDlg::OnShowTimeTZ),
163 NULL, this);
164 if (m_rbShowTimePC)
165 m_rbShowTimePC->Connect(wxEVT_COMMAND_RADIOBUTTON_SELECTED,
166 wxCommandEventHandler(TrackPropDlg::OnShowTimeTZ),
167 NULL, this);
168 if (m_rbShowTimeLocal)
169 m_rbShowTimeLocal->Connect(
170 wxEVT_COMMAND_RADIOBUTTON_SELECTED,
171 wxCommandEventHandler(TrackPropDlg::OnShowTimeTZ), NULL, this);
172
173 if (m_rbShowTimeGlobalSettings)
174 m_rbShowTimeGlobalSettings->Connect(
175 wxEVT_COMMAND_RADIOBUTTON_SELECTED,
176 wxCommandEventHandler(TrackPropDlg::OnShowTimeTZ), NULL, this);
177
178 m_pMyLinkList = NULL;
179}
180
181TrackPropDlg::~TrackPropDlg() {
182 // Disconnect Events
183 m_sdbBtmBtnsSizerCancel->Disconnect(
184 wxEVT_COMMAND_BUTTON_CLICKED,
185 wxCommandEventHandler(TrackPropDlg::OnCancelBtnClick), NULL, this);
186 m_sdbBtmBtnsSizerOK->Disconnect(
187 wxEVT_COMMAND_BUTTON_CLICKED,
188 wxCommandEventHandler(TrackPropDlg::OnOKBtnClick), NULL, this);
189 if (m_sdbBtmBtnsSizerPrint)
190 m_sdbBtmBtnsSizerPrint->Disconnect(
191 wxEVT_COMMAND_BUTTON_CLICKED,
192 wxCommandEventHandler(TrackPropDlg::OnPrintBtnClick), NULL, this);
193 m_sdbBtmBtnsSizerSplit->Disconnect(
194 wxEVT_COMMAND_BUTTON_CLICKED,
195 wxCommandEventHandler(TrackPropDlg::OnSplitBtnClick), NULL, this);
196 m_sdbBtmBtnsSizerExtend->Disconnect(
197 wxEVT_COMMAND_BUTTON_CLICKED,
198 wxCommandEventHandler(TrackPropDlg::OnExtendBtnClick), NULL, this);
199 m_sdbBtmBtnsSizerToRoute->Disconnect(
200 wxEVT_COMMAND_BUTTON_CLICKED,
201 wxCommandEventHandler(TrackPropDlg::OnToRouteBtnClick), NULL, this);
202 if (m_sdbBtmBtnsSizerExport)
203 m_sdbBtmBtnsSizerExport->Disconnect(
204 wxEVT_COMMAND_BUTTON_CLICKED,
205 wxCommandEventHandler(TrackPropDlg::OnExportBtnClick), NULL, this);
206 m_lcPoints->Disconnect(wxEVT_COMMAND_LIST_ITEM_SELECTED,
207 wxListEventHandler(TrackPropDlg::OnTrackPropListClick),
208 NULL, this);
209 Disconnect(wxEVT_COMMAND_LIST_ITEM_RIGHT_CLICK,
210 wxListEventHandler(TrackPropDlg::OnTrackPropRightClick), NULL,
211 this);
212 Disconnect(wxEVT_COMMAND_MENU_SELECTED,
213 wxCommandEventHandler(TrackPropDlg::OnTrackPropMenuSelected), NULL,
214 this);
215
216 Disconnect(wxID_ANY, wxEVT_COMMAND_MENU_SELECTED,
217 wxCommandEventHandler(TrackPropDlg::OnDeleteLink));
218 Disconnect(wxID_ANY, wxEVT_COMMAND_MENU_SELECTED,
219 wxCommandEventHandler(TrackPropDlg::OnEditLink));
220 Disconnect(wxID_ANY, wxEVT_COMMAND_MENU_SELECTED,
221 wxCommandEventHandler(TrackPropDlg::OnAddLink));
222
223 if (!m_bcompact) {
224 m_buttonAddLink->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED,
225 wxCommandEventHandler(TrackPropDlg::OnAddLink),
226 NULL, this);
227 m_toggleBtnEdit->Disconnect(
228 wxEVT_COMMAND_TOGGLEBUTTON_CLICKED,
229 wxCommandEventHandler(TrackPropDlg::OnEditLinkToggle), NULL, this);
230 }
231
232 if (m_rbShowTimeUTC)
233 m_rbShowTimeUTC->Disconnect(
234 wxEVT_COMMAND_RADIOBUTTON_SELECTED,
235 wxCommandEventHandler(TrackPropDlg::OnShowTimeTZ), NULL, this);
236 if (m_rbShowTimePC)
237 m_rbShowTimePC->Disconnect(
238 wxEVT_COMMAND_RADIOBUTTON_SELECTED,
239 wxCommandEventHandler(TrackPropDlg::OnShowTimeTZ), NULL, this);
241 m_rbShowTimeLocal->Disconnect(
242 wxEVT_COMMAND_RADIOBUTTON_SELECTED,
243 wxCommandEventHandler(TrackPropDlg::OnShowTimeTZ), NULL, this);
245 m_rbShowTimeGlobalSettings->Disconnect(
246 wxEVT_COMMAND_RADIOBUTTON_SELECTED,
247 wxCommandEventHandler(TrackPropDlg::OnShowTimeTZ), NULL, this);
248
249 instanceFlag = false;
250}
251
252static wxString getDatetimeTimezoneSelector(int selection) {
253 switch (selection) {
254 case UTCINPUT:
255 return "UTC";
256 case LTINPUT:
257 return "Local Time";
258 case LMTINPUT:
259 return "LMT";
261 default:
262 return "";
263 }
264}
265
266void TrackPropDlg::OnActivate(wxActivateEvent& event) {
267 auto pWin = dynamic_cast<DIALOG_PARENT*>(event.GetEventObject());
268 long int style = pWin->GetWindowStyle();
269 if (event.GetActive())
270 pWin->SetWindowStyle(style | wxSTAY_ON_TOP);
271 else
272 pWin->SetWindowStyle(style ^ wxSTAY_ON_TOP);
273}
274
275void TrackPropDlg::RecalculateSize() {
276 // Make an estimate of the dialog size, without scrollbars showing
277
278 wxSize esize;
279 esize.x = GetCharWidth() * 110;
280 esize.y = GetCharHeight() * 40;
281
282 wxSize dsize = GetParent()->GetClientSize();
283 esize.y = wxMin(esize.y, dsize.y - (2 * GetCharHeight()));
284 esize.x = wxMin(esize.x, dsize.x - (2 * GetCharHeight()));
285 SetClientSize(esize);
286
287 wxSize fsize = GetSize();
288 fsize.y = wxMin(fsize.y, dsize.y - (2 * GetCharHeight()));
289 fsize.x = wxMin(fsize.x, dsize.x - (2 * GetCharHeight()));
290 SetSize(fsize);
291
292 if (m_bcompact) {
293 int sy = GetCharHeight() * m_lcPoints->GetItemCount();
294 sy = wxMax(sy, 250);
295 sy = wxMin(sy, 500);
296 m_lcPoints->SetSize(wxSize(GetClientSize().x - 40, sy));
297
298 if (m_lcPoints->GetItemCount()) Layout();
299 }
300
301 Centre();
302}
303
304static void addColumns(wxListCtrl* lctrl, int dx) {
305 lctrl->InsertColumn(0, _("Leg"), wxLIST_FORMAT_LEFT, dx * 6);
306 lctrl->InsertColumn(1, _("Distance"), wxLIST_FORMAT_LEFT, dx * 11);
307 lctrl->InsertColumn(2, _("Bearing"), wxLIST_FORMAT_LEFT, dx * 8);
308 // Width of lat/lon may be up to 15 characters: 'DDD° MM.MMMM' W'.
309 lctrl->InsertColumn(3, _("Latitude"), wxLIST_FORMAT_LEFT, dx * 15);
310 lctrl->InsertColumn(4, _("Longitude"), wxLIST_FORMAT_LEFT, dx * 15);
311 // Width of timestamp may be be up to 26 characters: 'MM/DD/YYYY HH:MM:SS PM
312 // UTC'.
313 lctrl->InsertColumn(5, _("Timestamp"), wxLIST_FORMAT_LEFT, dx * 26);
314 lctrl->InsertColumn(6, _("Speed"), wxLIST_FORMAT_CENTER, dx * 8);
315
316 lctrl->SetMinSize(wxSize(-1, 50));
317}
318
319void TrackPropDlg::CreateControlsCompact() {
320 wxBoxSizer* itemBoxSizer1 = new wxBoxSizer(wxVERTICAL);
321 SetSizer(itemBoxSizer1);
322
323 itemDialog1 = new wxScrolledWindow(this, wxID_ANY, wxDefaultPosition,
324 wxSize(-1, -1), wxVSCROLL);
325 itemDialog1->SetScrollRate(0, 1);
326
327#ifdef __ANDROID__
328 // Set Dialog Font by custom crafted Qt Stylesheet.
329 wxFont* qFont = GetOCPNScaledFont(_("Dialog"));
330
331 wxString wqs = getFontQtStylesheet(qFont);
332 wxCharBuffer sbuf = wqs.ToUTF8();
333 QString qsb = QString(sbuf.data());
334
335 QString qsbq = getQtStyleSheet(); // basic scrollbars, etc
336
337 itemDialog1->GetHandle()->setStyleSheet(qsb +
338 qsbq); // Concatenated style sheets
339
340#endif
341 itemBoxSizer1->Add(itemDialog1, 1, wxEXPAND | wxALL, 0);
342
343 wxBoxSizer* itemBoxSizer2 = new wxBoxSizer(wxVERTICAL);
344 itemDialog1->SetSizer(itemBoxSizer2);
345
346 wxStaticText* itemStaticText4 = new wxStaticText(
347 itemDialog1, wxID_STATIC, _("Name"), wxDefaultPosition, wxDefaultSize, 0);
348 itemBoxSizer2->Add(itemStaticText4, 0,
349 wxALIGN_LEFT | wxLEFT | wxRIGHT | wxTOP, 5);
350
351 m_tName = new wxTextCtrl(itemDialog1, wxID_ANY, "", wxDefaultPosition,
352 wxSize(400, -1), 0);
353 itemBoxSizer2->Add(m_tName, 0, wxALIGN_LEFT | wxLEFT | wxRIGHT | wxBOTTOM, 5);
354
355 wxStaticText* itemStaticText7 =
356 new wxStaticText(itemDialog1, wxID_STATIC, _("Depart From"),
357 wxDefaultPosition, wxDefaultSize, 0);
358 itemBoxSizer2->Add(itemStaticText7, 0,
359 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT,
360 5);
361
362 m_tFrom = new wxTextCtrl(itemDialog1, wxID_ANY, "", wxDefaultPosition,
363 wxSize(-1, -1), 0);
364 itemBoxSizer2->Add(m_tFrom, 0,
365 wxEXPAND | wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL |
366 wxLEFT | wxRIGHT | wxBOTTOM,
367 5);
368
369 wxStaticText* itemStaticText8 =
370 new wxStaticText(itemDialog1, wxID_STATIC, _("Destination"),
371 wxDefaultPosition, wxDefaultSize, 0);
372 itemBoxSizer2->Add(itemStaticText8, 0,
373 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT,
374 5);
375
376 m_tTo = new wxTextCtrl(itemDialog1, wxID_ANY, "", wxDefaultPosition,
377 wxSize(-1, -1), 0);
378 itemBoxSizer2->Add(m_tTo, 0,
379 wxEXPAND | wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL |
380 wxLEFT | wxRIGHT | wxBOTTOM,
381 5);
382
383 m_cbShow = new wxCheckBox(itemDialog1, wxID_ANY, _("Show on chart"),
384 wxDefaultPosition, wxDefaultSize, 0);
385 itemBoxSizer2->Add(m_cbShow, 0, wxALL, 5);
386
387 wxFlexGridSizer* itemFlexGridSizer6a = new wxFlexGridSizer(4, 2, 0, 0);
388 itemFlexGridSizer6a->AddGrowableCol(1, 0);
389
390 itemBoxSizer2->Add(itemFlexGridSizer6a, 0, wxEXPAND | wxALIGN_LEFT | wxALL,
391 5);
392
393 wxStaticText* itemStaticText11 =
394 new wxStaticText(itemDialog1, wxID_STATIC, _("Total distance"),
395 wxDefaultPosition, wxDefaultSize, 0);
396 itemFlexGridSizer6a->Add(
397 itemStaticText11, 0,
398 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT | wxTOP, 5);
399
400 m_tTotDistance = new wxTextCtrl(itemDialog1, wxID_ANY, "", wxDefaultPosition,
401 wxSize(-1, -1), wxTE_READONLY);
402 itemFlexGridSizer6a->Add(m_tTotDistance, 0,
403 wxEXPAND | wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL |
404 wxLEFT | wxRIGHT | wxBOTTOM,
405 5);
406
407 m_stAvgSpeed = new wxStaticText(itemDialog1, wxID_STATIC, _("Avg. speed"),
408 wxDefaultPosition, wxDefaultSize, 0);
409 itemFlexGridSizer6a->Add(
410 m_stAvgSpeed, 0,
411 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT | wxTOP, 5);
412
413 m_tAvgSpeed = new wxTextCtrl(itemDialog1, wxID_ANY, "", wxDefaultPosition,
414 wxSize(150, -1), wxTE_PROCESS_ENTER);
415 itemFlexGridSizer6a->Add(
416 m_tAvgSpeed, 0,
417 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT | wxBOTTOM, 5);
418
419 m_stTimeEnroute =
420 new wxStaticText(itemDialog1, wxID_STATIC, _("Time Enroute"),
421 wxDefaultPosition, wxDefaultSize, 0);
422 itemFlexGridSizer6a->Add(
423 m_stTimeEnroute, 0,
424 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT | wxTOP, 5);
425
426 m_tTimeEnroute = new wxTextCtrl(itemDialog1, wxID_ANY, "", wxDefaultPosition,
427 wxSize(-1, -1), wxTE_READONLY);
428 itemFlexGridSizer6a->Add(m_tTimeEnroute, 0,
429 wxEXPAND | wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL |
430 wxLEFT | wxRIGHT | wxBOTTOM,
431 5);
432
433 /*
434 m_StartTimeLabel = new wxStaticText( itemDialog1, wxID_STATIC,
435 _("Departure Time"), wxDefaultPosition, wxDefaultSize, 0 );
436 itemFlexGridSizer6a->Add( m_StartTimeLabel, 0,
437 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT | wxTOP,
438 5 );
439
440 m_StartTimeCtl = new wxTextCtrl( itemDialog1, ID_STARTTIMECTL, "",
441 wxDefaultPosition, wxSize( -1, -1 ), wxTE_PROCESS_ENTER );
442 itemFlexGridSizer6a->Add( m_StartTimeCtl, 0,
443 wxEXPAND | wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxLEFT |
444 wxRIGHT | wxBOTTOM, 5 );
445 */
446
447 wxString pDispTimeZone[] = {_("UTC"), _("Local Time"), _("LMT@Location"),
448 _("Honor Global Settings")};
449
450 wxStaticText* itemStaticText12b =
451 new wxStaticText(itemDialog1, wxID_STATIC, _("Time shown as"),
452 wxDefaultPosition, wxDefaultSize, 0);
453 itemBoxSizer2->Add(itemStaticText12b, 0, wxEXPAND | wxALL, 5);
454
455 m_rbShowTimeUTC =
456 new wxRadioButton(itemDialog1, wxID_ANY, _("UTC"), wxDefaultPosition,
457 wxDefaultSize, wxRB_GROUP);
458 itemBoxSizer2->Add(
459 m_rbShowTimeUTC, 0,
460 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT | wxBOTTOM, 5);
461
462 m_rbShowTimePC = new wxRadioButton(itemDialog1, wxID_ANY, _("Local Time"));
463 itemBoxSizer2->Add(
465 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT | wxBOTTOM, 5);
466
468 new wxRadioButton(itemDialog1, wxID_ANY, _("LMT@Location"));
469 itemBoxSizer2->Add(
471 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT | wxBOTTOM, 5);
472
474 new wxRadioButton(itemDialog1, wxID_ANY, _("Honor Global Settings"));
475 itemBoxSizer2->Add(
477 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT | wxBOTTOM, 5);
478
479 wxFlexGridSizer* itemFlexGridSizer6b = new wxFlexGridSizer(3, 2, 0, 0);
480 itemBoxSizer2->Add(itemFlexGridSizer6b, 0, wxEXPAND | wxALIGN_LEFT | wxALL,
481 5);
482
483 wxStaticText* m_staticText1 =
484 new wxStaticText(itemDialog1, wxID_ANY, _("Color") + ":",
485 wxDefaultPosition, wxDefaultSize, 0);
486 itemFlexGridSizer6b->Add(m_staticText1, 0, wxALIGN_CENTER_VERTICAL | wxALL,
487 5);
488
489 wxString m_chColorChoices[] = {
490 _("Default color"), _("Black"), _("Dark Red"), _("Dark Green"),
491 _("Dark Yellow"), _("Dark Blue"), _("Dark Magenta"), _("Dark Cyan"),
492 _("Light Gray"), _("Dark Gray"), _("Red"), _("Green"),
493 _("Yellow"), _("Blue"), _("Magenta"), _("Cyan"),
494 _("White")};
495 int m_chColorNChoices = sizeof(m_chColorChoices) / sizeof(wxString);
496 m_cColor =
497 new wxChoice(itemDialog1, wxID_ANY, wxDefaultPosition, wxSize(250, -1),
498 m_chColorNChoices, m_chColorChoices, 0);
499 m_cColor->SetSelection(0);
500 itemFlexGridSizer6b->Add(m_cColor, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
501
502 wxStaticText* staticTextStyle =
503 new wxStaticText(itemDialog1, wxID_ANY, _("Style") + ":",
504 wxDefaultPosition, wxDefaultSize, 0);
505 itemFlexGridSizer6b->Add(staticTextStyle, 0, wxALIGN_CENTER_VERTICAL | wxALL,
506 5);
507
508 wxString m_chStyleChoices[] = {_("Default"), _("Solid"), _("Dot"),
509 _("Long dash"), _("Short dash")};
510 int m_chStyleNChoices = sizeof(m_chStyleChoices) / sizeof(wxString);
511 m_cStyle =
512 new wxChoice(itemDialog1, wxID_ANY, wxDefaultPosition, wxDefaultSize,
513 m_chStyleNChoices, m_chStyleChoices, 0);
514 m_cStyle->SetSelection(0);
515 itemFlexGridSizer6b->Add(m_cStyle, 0,
516 wxEXPAND | wxALIGN_CENTER_VERTICAL | wxALL, 5);
517
518#ifdef ocpnUSE_GLES // linestipple is emulated poorly
519 staticTextStyle->Hide();
520 m_cStyle->Hide();
521#endif
522
523 m_stWidth = new wxStaticText(itemDialog1, wxID_ANY, _("Width") + ":",
524 wxDefaultPosition, wxDefaultSize, 0);
525 itemFlexGridSizer6b->Add(m_stWidth, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
526
527 wxString m_chWidthChoices[] = {_("Default"), _("1 pixel"), _("2 pixels"),
528 _("3 pixels"), _("4 pixels"), _("5 pixels"),
529 _("6 pixels"), _("7 pixels"), _("8 pixels"),
530 _("9 pixels"), _("10 pixels")};
531 int m_chWidthNChoices = sizeof(m_chWidthChoices) / sizeof(wxString);
532 m_cWidth =
533 new wxChoice(itemDialog1, wxID_ANY, wxDefaultPosition, wxSize(150, -1),
534 m_chWidthNChoices, m_chWidthChoices, 0);
535 m_cWidth->SetSelection(0);
536 itemFlexGridSizer6b->Add(m_cWidth, 0,
537 wxEXPAND | wxALIGN_CENTER_VERTICAL | wxALL, 5);
538
539 wxStaticBox* itemStaticBoxSizer14Static =
540 new wxStaticBox(itemDialog1, wxID_ANY, _("Waypoints"));
541 wxStaticBoxSizer* m_pListSizer =
542 new wxStaticBoxSizer(itemStaticBoxSizer14Static, wxVERTICAL);
543 itemBoxSizer2->Add(m_pListSizer, 1, wxEXPAND | wxALL, 1);
544
545 wxScrolledWindow* itemlistWin =
546 new wxScrolledWindow(itemDialog1, wxID_ANY, wxDefaultPosition,
547 wxDefaultSize, wxHSCROLL | wxVSCROLL);
548 itemlistWin->SetScrollRate(2, 2);
549
550 m_pListSizer->Add(itemlistWin, 0, wxEXPAND | wxALL, 6);
551
552 long flags = wxLC_REPORT | wxLC_HRULES | wxLC_VRULES | wxLC_EDIT_LABELS;
553#ifndef __WXQT__ // Does not support Virtual list boxes....
554 flags |= wxLC_VIRTUAL;
555#endif
556
557 m_lcPoints = new OCPNTrackListCtrl(itemlistWin, wxID_ANY, wxDefaultPosition,
558 wxSize(100, 500), flags);
559 addColumns(m_lcPoints, GetCharWidth());
560
561 // sbSizerPoints->Add( m_lcPoints, 1, wxALL|wxEXPAND, 5 );
562
563#ifdef __ANDROID__
564 m_lcPoints->GetHandle()->setStyleSheet(getQtStyleSheet());
565#endif
566
567 // Buttons, etc...
568
569 wxBoxSizer* itemBoxSizerBottom = new wxBoxSizer(wxVERTICAL);
570 itemBoxSizer1->Add(itemBoxSizerBottom, 0, wxALIGN_LEFT | wxALL | wxEXPAND, 5);
571
572 int n_col = 3;
573
574 wxFlexGridSizer* itemBoxSizerAux = new wxFlexGridSizer(0, n_col, 0, 0);
575 itemBoxSizerAux->SetFlexibleDirection(wxBOTH);
576 itemBoxSizerAux->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_SPECIFIED);
577
578 itemBoxSizerBottom->Add(itemBoxSizerAux, 1, wxALIGN_LEFT | wxALL, 5);
579
580#ifndef __ANDROID__
581
582 m_sdbBtmBtnsSizerPrint = new wxButton(this, wxID_ANY, _("Print"),
583 wxDefaultPosition, wxDefaultSize, 0);
584 itemBoxSizerAux->Add(m_sdbBtmBtnsSizerPrint, 0,
585 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 5);
586 m_sdbBtmBtnsSizerPrint->Enable(true);
587#else
588 m_sdbBtmBtnsSizerPrint = NULL;
589#endif
590
591 m_sdbBtmBtnsSizerSplit = new wxButton(this, wxID_ANY, _("Split"),
592 wxDefaultPosition, wxDefaultSize, 0);
593 itemBoxSizerAux->Add(m_sdbBtmBtnsSizerSplit, 0,
594 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 5);
595 m_sdbBtmBtnsSizerSplit->Enable(false);
596
597 m_sdbBtmBtnsSizerExtend = new wxButton(this, wxID_ANY, _("Extend"),
598 wxDefaultPosition, wxDefaultSize, 0);
599 m_sdbBtmBtnsSizerExtend->SetToolTip(
600 _("Extends this track by connecting it to another track.\n"
601 "Disabled when the track is active, the track is in a layer, or no "
602 "suitable track to connect to exists.\n"
603 "A suitable track is one that is visible, is different from this "
604 "track, and has its last point's timestamp earlier than or equal to "
605 "this track's first point's timestamp."));
606 itemBoxSizerAux->Add(m_sdbBtmBtnsSizerExtend, 0,
607 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 5);
608
609 m_sdbBtmBtnsSizerToRoute = new wxButton(this, wxID_ANY, _("To route"),
610 wxDefaultPosition, wxDefaultSize, 0);
611 itemBoxSizerAux->Add(m_sdbBtmBtnsSizerToRoute, 0,
612 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 5);
613
614 m_sdbBtmBtnsSizerExport = NULL;
615 // m_sdbBtmBtnsSizerExport = new wxButton( this, wxID_ANY, _("Export"),
616 // wxDefaultPosition, wxDefaultSize, 0 ); itemBoxSizerAux->Add(
617 // m_sdbBtmBtnsSizerExport, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL |
618 // wxALL, 5 );
619
620 wxBoxSizer* itemBoxSizer16 = new wxBoxSizer(wxHORIZONTAL);
621 itemBoxSizerBottom->Add(itemBoxSizer16, 0, wxALIGN_RIGHT | wxALL, 5);
622
623 m_sdbBtmBtnsSizerCancel = new wxButton(this, wxID_CANCEL, _("Cancel"),
624 wxDefaultPosition, wxDefaultSize, 0);
625 itemBoxSizer16->Add(m_sdbBtmBtnsSizerCancel, 0,
626 wxALIGN_RIGHT | wxALIGN_BOTTOM | wxALL, 5);
627
628 m_sdbBtmBtnsSizerOK =
629 new wxButton(this, wxID_OK, _("OK"), wxDefaultPosition, wxDefaultSize, 0);
630 itemBoxSizer16->Add(m_sdbBtmBtnsSizerOK, 0,
631 wxALIGN_RIGHT | wxALIGN_BOTTOM | wxALL, 5);
632 m_sdbBtmBtnsSizerOK->SetDefault();
633
634 int char_size = GetCharWidth();
635 // Set the maximum size of the entire dialog
636 int width, height;
637 width = g_monitor_info[g_current_monitor].width;
638 height = g_monitor_info[g_current_monitor].height;
639 SetSizeHints(-1, -1, width - 100, height - 100);
640}
641
642void TrackPropDlg::CreateControls() {
643 wxBoxSizer* bSizerMain;
644 bSizerMain = new wxBoxSizer(wxVERTICAL);
645 SetSizer(bSizerMain);
646
647 m_notebook1 =
648 new wxNotebook(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0);
649
650 bSizerMain->Add(m_notebook1, 1, wxEXPAND | wxALL, 5);
651
652 wxPanel* m_panel0 =
653 new wxPanel(m_notebook1, wxID_ANY, wxDefaultPosition, wxDefaultSize);
654 m_notebook1->AddPage(m_panel0, _("Basic"), true);
655
656 wxBoxSizer* bSizer0 = new wxBoxSizer(wxVERTICAL);
657 m_panel0->SetSizer(bSizer0);
658
659 wxBoxSizer* bSizer1 = new wxBoxSizer(wxVERTICAL);
660 bSizer0->Add(bSizer1, 1, wxEXPAND | wxALL, 5);
661
662 m_panelBasic = new wxScrolledWindow(m_panel0, wxID_ANY, wxDefaultPosition,
663 wxSize(-1, -1),
664 wxHSCROLL | wxVSCROLL | wxTAB_TRAVERSAL);
665
666#ifdef __ANDROID__
667 // Set Dialog Font by custom crafted Qt Stylesheet.
668 wxFont* qFont = GetOCPNScaledFont(_("Dialog"));
669
670 wxString wqs = getFontQtStylesheet(qFont);
671 wxCharBuffer sbuf = wqs.ToUTF8();
672 QString qsb = QString(sbuf.data());
673
674 QString qsbq = getQtStyleSheet(); // basic scrollbars, etc
675
676 m_panelBasic->GetHandle()->setStyleSheet(qsb +
677 qsbq); // Concatenated style sheets
678
679#endif
680
681 // #ifdef __ANDROID__
682 // m_panelBasic->GetHandle()->setStyleSheet( getQtStyleSheet());
683 // #endif
684
685 wxBoxSizer* bSizerBasic = new wxBoxSizer(wxVERTICAL);
686 m_panelBasic->SetSizer(bSizerBasic);
687
688 bSizer1->Add(m_panelBasic, 1, wxEXPAND | wxALL, 5);
689
690 wxBoxSizer* bSizerName;
691 bSizerName = new wxBoxSizer(wxHORIZONTAL);
692 bSizerBasic->Add(bSizerName, 0, wxALL | wxEXPAND, 5);
693
694 m_stName = new wxStaticText(m_panelBasic, wxID_ANY, _("Name"),
695 wxDefaultPosition, wxDefaultSize, 0);
696 // m_stName->Wrap( -1 );
697 bSizerName->Add(m_stName, 0, wxALL, 5);
698
699 m_tName = new wxTextCtrl(m_panelBasic, wxID_ANY, "", wxDefaultPosition,
700 wxDefaultSize, 0);
701 bSizerName->Add(m_tName, 1, 0, 5);
702
703 wxBoxSizer* bSizerFromTo;
704 bSizerFromTo = new wxBoxSizer(wxHORIZONTAL);
705 bSizerBasic->Add(bSizerFromTo, 0, wxALL | wxEXPAND, 5);
706
707 m_stFrom = new wxStaticText(m_panelBasic, wxID_ANY, _("From"),
708 wxDefaultPosition, wxDefaultSize, 0);
709 // m_stFrom->Wrap( -1 );
710 bSizerFromTo->Add(m_stFrom, 0, wxALL, 5);
711
712 m_tFrom = new wxTextCtrl(m_panelBasic, wxID_ANY, "", wxDefaultPosition,
713 wxDefaultSize, 0);
714 bSizerFromTo->Add(m_tFrom, 1, 0, 5);
715
716 m_stTo = new wxStaticText(m_panelBasic, wxID_ANY, _("To"), wxDefaultPosition,
717 wxDefaultSize, 0);
718 // m_stTo->Wrap( -1 );
719 bSizerFromTo->Add(m_stTo, 0, wxALL, 5);
720
721 m_tTo = new wxTextCtrl(m_panelBasic, wxID_ANY, "", wxDefaultPosition,
722 wxDefaultSize, 0);
723 bSizerFromTo->Add(m_tTo, 1, 0, 5);
724
725 wxStaticBoxSizer* sbSizerParams;
726 sbSizerParams = new wxStaticBoxSizer(
727 new wxStaticBox(m_panelBasic, wxID_ANY, _("Display parameters")),
728 wxHORIZONTAL);
729 bSizerBasic->Add(sbSizerParams, 0, wxALL | wxEXPAND, 5);
730
731 m_cbShow = new wxCheckBox(m_panelBasic, wxID_ANY, _("Show on chart"),
732 wxDefaultPosition, wxDefaultSize, 0);
733 sbSizerParams->Add(m_cbShow, 0, wxALL, 5);
734
735 m_stColor = new wxStaticText(m_panelBasic, wxID_ANY, _("Color"),
736 wxDefaultPosition, wxDefaultSize, 0);
737 // m_stColor->Wrap( -1 );
738 sbSizerParams->Add(m_stColor, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
739
740 wxString m_cColorChoices[] = {
741 _("Default color"), _("Black"), _("Dark Red"), _("Dark Green"),
742 _("Dark Yellow"), _("Dark Blue"), _("Dark Magenta"), _("Dark Cyan"),
743 _("Light Gray"), _("Dark Gray"), _("Red"), _("Green"),
744 _("Yellow"), _("Blue"), _("Magenta"), _("Cyan"),
745 _("White")};
746 int m_cColorNChoices = sizeof(m_cColorChoices) / sizeof(wxString);
747 m_cColor = new wxChoice(m_panelBasic, wxID_ANY, wxDefaultPosition,
748 wxDefaultSize, m_cColorNChoices, m_cColorChoices, 0);
749 m_cColor->SetSelection(0);
750 sbSizerParams->Add(m_cColor, 1, 0, 5);
751
752 m_stStyle = new wxStaticText(m_panelBasic, wxID_ANY, _("Style"),
753 wxDefaultPosition, wxDefaultSize, 0);
754 // m_stStyle->Wrap( -1 );
755 sbSizerParams->Add(m_stStyle, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
756
757 wxString m_cStyleChoices[] = {_("Default"), _("Solid"), _("Dot"),
758 _("Long dash"), _("Short dash")};
759 int m_cStyleNChoices = sizeof(m_cStyleChoices) / sizeof(wxString);
760 m_cStyle = new wxChoice(m_panelBasic, wxID_ANY, wxDefaultPosition,
761 wxDefaultSize, m_cStyleNChoices, m_cStyleChoices, 0);
762 m_cStyle->SetSelection(0);
763 sbSizerParams->Add(m_cStyle, 1, 0, 5);
764
765 m_stWidth = new wxStaticText(m_panelBasic, wxID_ANY, _("Width"),
766 wxDefaultPosition, wxDefaultSize, 0);
767 // m_stWidth->Wrap( -1 );
768 sbSizerParams->Add(m_stWidth, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
769
770 wxString m_cWidthChoices[] = {_("Default"), _("1 pixel"), _("2 pixels"),
771 _("3 pixels"), _("4 pixels"), _("5 pixels"),
772 _("6 pixels"), _("7 pixels"), _("8 pixels"),
773 _("9 pixels"), _("10 pixels")};
774 int m_cWidthNChoices = sizeof(m_cWidthChoices) / sizeof(wxString);
775 m_cWidth = new wxChoice(m_panelBasic, wxID_ANY, wxDefaultPosition,
776 wxDefaultSize, m_cWidthNChoices, m_cWidthChoices, 0);
777 m_cWidth->SetSelection(0);
778 sbSizerParams->Add(m_cWidth, 1, 0, 5);
779
780 wxStaticBoxSizer* sbSizerStats;
781 sbSizerStats = new wxStaticBoxSizer(
782 new wxStaticBox(m_panelBasic, wxID_ANY, _("Statistics")), wxVERTICAL);
783 bSizerBasic->Add(sbSizerStats, 0, wxALL | wxEXPAND, 5);
784
785 wxBoxSizer* bSizerStats;
786 bSizerStats = new wxBoxSizer(wxHORIZONTAL);
787
788 m_stTotDistance =
789 new wxStaticText(m_panelBasic, wxID_ANY, _("Total distance"),
790 wxDefaultPosition, wxDefaultSize, 0);
791 // m_stTotDistance->Wrap( -1 );
792 bSizerStats->Add(m_stTotDistance, 0, wxALL, 5);
793
794 m_tTotDistance = new wxTextCtrl(m_panelBasic, wxID_ANY, "", wxDefaultPosition,
795 wxDefaultSize, wxTE_READONLY);
796 bSizerStats->Add(m_tTotDistance, 1, 0, 5);
797
798 m_stAvgSpeed = new wxStaticText(m_panelBasic, wxID_ANY, _("Avg. speed"),
799 wxDefaultPosition, wxDefaultSize, 0);
800 // m_stAvgSpeed->Wrap( -1 );
801 bSizerStats->Add(m_stAvgSpeed, 0, wxALL, 5);
802
803 m_tAvgSpeed = new wxTextCtrl(m_panelBasic, wxID_ANY, "", wxDefaultPosition,
804 wxDefaultSize, wxTE_READONLY);
805 bSizerStats->Add(m_tAvgSpeed, 1, 0, 5);
806
807 m_stTimeEnroute = new wxStaticText(m_panelBasic, wxID_ANY, _("Time enroute"),
808 wxDefaultPosition, wxDefaultSize, 0);
809 // m_stTimeEnroute->Wrap( -1 );
810 bSizerStats->Add(m_stTimeEnroute, 0, wxALL, 5);
811
812 m_tTimeEnroute = new wxTextCtrl(m_panelBasic, wxID_ANY, "", wxDefaultPosition,
813 wxDefaultSize, wxTE_READONLY);
814 bSizerStats->Add(m_tTimeEnroute, 2, 0, 5);
815
816 sbSizerStats->Add(bSizerStats, 0, wxEXPAND, 5);
817
818 wxStaticBoxSizer* sbSizerPoints;
819 sbSizerPoints = new wxStaticBoxSizer(
820 new wxStaticBox(m_panel0, wxID_ANY, _("Recorded points")), wxVERTICAL);
821 bSizer1->Add(sbSizerPoints, 1, wxALL | wxEXPAND, 5);
822
823 wxBoxSizer* bSizerShowTime;
824 bSizerShowTime = new wxBoxSizer(wxHORIZONTAL);
825
826 m_stShowTime = new wxStaticText(m_panel0, wxID_ANY, _("Time shown as"),
827 wxDefaultPosition, wxDefaultSize, 0);
828 // m_stShowTime->Wrap( -1 );
829 bSizerShowTime->Add(m_stShowTime, 0, wxALL, 5);
830
831 m_rbShowTimeUTC = new wxRadioButton(m_panel0, wxID_ANY, _("UTC"),
832 wxDefaultPosition, wxDefaultSize, 0);
833 bSizerShowTime->Add(m_rbShowTimeUTC, 0,
834 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT,
835 5);
836
837 m_rbShowTimePC = new wxRadioButton(m_panel0, wxID_ANY, _("Local Time"),
838 wxDefaultPosition, wxDefaultSize, 0);
839 bSizerShowTime->Add(m_rbShowTimePC, 0,
840 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT,
841 5);
842
844 new wxRadioButton(m_panel0, wxID_ANY, _("LMT@Track Start"),
845 wxDefaultPosition, wxDefaultSize, 0);
846 bSizerShowTime->Add(m_rbShowTimeLocal, 0,
847 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT,
848 5);
849
851 new wxRadioButton(m_panel0, wxID_ANY, _("Honor Global Settings"),
852 wxDefaultPosition, wxDefaultSize, 0);
853 bSizerShowTime->Add(m_rbShowTimeGlobalSettings, 0,
854 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT,
855 5);
856
857 m_rbShowTimeGlobalSettings->SetValue(true);
858
859 sbSizerPoints->Add(bSizerShowTime, 0, wxEXPAND, 5);
860
861 long flags = wxLC_REPORT | wxLC_HRULES | wxLC_VRULES | wxLC_EDIT_LABELS;
862#ifndef __WXQT__ // Does not support Virtual list boxes....
863 flags |= wxLC_VIRTUAL;
864#endif
865
866 m_lcPoints = new OCPNTrackListCtrl(m_panel0, wxID_ANY, wxDefaultPosition,
867 wxDefaultSize, flags);
868 addColumns(m_lcPoints, GetCharWidth());
869
870 sbSizerPoints->Add(m_lcPoints, 1, wxALL | wxEXPAND, 5);
871
872#ifdef __ANDROID__
873 m_lcPoints->GetHandle()->setStyleSheet(getQtStyleSheet());
874#endif
875
876 // m_lcPoints = new OCPNTrackListCtrl( m_panel0, wxID_ANY,
877 // wxDefaultPosition, wxDefaultSize,
878 // wxLC_REPORT | wxLC_HRULES |
879 // wxLC_VRULES | wxLC_EDIT_LABELS |
880 // wxLC_VIRTUAL );
881 //
882 // m_lcPoints->Hide();
883 // m_rbShowTimeUTC = NULL;
884 // m_rbShowTimePC = NULL;
885 // m_rbShowTimeLocal = NULL;
886
887 m_panelAdvanced = new wxScrolledWindow(
888 m_notebook1, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL);
889
890 wxBoxSizer* bSizerAdvanced;
891 bSizerAdvanced = new wxBoxSizer(wxVERTICAL);
892
893 m_stDescription =
894 new wxStaticText(m_panelAdvanced, wxID_ANY, _("Description"),
895 wxDefaultPosition, wxDefaultSize, 0);
896 // m_stDescription->Wrap( -1 );
897 bSizerAdvanced->Add(m_stDescription, 0, wxALL, 5);
898
899 m_tDescription =
900 new wxTextCtrl(m_panelAdvanced, wxID_ANY, "", wxDefaultPosition,
901 wxDefaultSize, wxTE_MULTILINE);
902 bSizerAdvanced->Add(m_tDescription, 1, wxALL | wxEXPAND, 5);
903
904 sbSizerLinks = new wxStaticBoxSizer(
905 new wxStaticBox(m_panelAdvanced, wxID_ANY, _("Links")), wxVERTICAL);
906
907 m_scrolledWindowLinks =
908 new wxScrolledWindow(m_panelAdvanced, wxID_ANY, wxDefaultPosition,
909 wxDefaultSize, wxHSCROLL | wxVSCROLL);
910 m_scrolledWindowLinks->SetScrollRate(5, 5);
911 bSizerLinks = new wxBoxSizer(wxVERTICAL);
912
913 m_hyperlink1 =
914 new wxHyperlinkCtrl(m_scrolledWindowLinks, wxID_ANY, _("wxFB Website"),
915 "http://www.wxformbuilder.org", wxDefaultPosition,
916 wxDefaultSize, wxHL_DEFAULT_STYLE);
917 m_menuLink = new wxMenu();
918 m_menuItemEdit = new wxMenuItem(m_menuLink, ID_TRK_MENU_EDIT,
919 wxString(_("Edit")), "", wxITEM_NORMAL);
920 m_menuLink->Append(m_menuItemEdit);
921
922 m_menuItemAdd = new wxMenuItem(m_menuLink, ID_TRK_MENU_ADD,
923 wxString(_("Add new")), "", wxITEM_NORMAL);
924 m_menuLink->Append(m_menuItemAdd);
925
926 m_menuItemDelete = new wxMenuItem(m_menuLink, ID_TRK_MENU_DELETE,
927 wxString(_("Delete")), "", wxITEM_NORMAL);
928 m_menuLink->Append(m_menuItemDelete);
929
930 m_hyperlink1->Connect(
931 wxEVT_RIGHT_DOWN,
932 wxMouseEventHandler(TrackPropDlg::m_hyperlink1OnContextMenu), NULL, this);
933
934 bSizerLinks->Add(m_hyperlink1, 0, wxALL, 5);
935
936 m_scrolledWindowLinks->SetSizer(bSizerLinks);
937 m_scrolledWindowLinks->Layout();
938 bSizerLinks->Fit(m_scrolledWindowLinks);
939 sbSizerLinks->Add(m_scrolledWindowLinks, 1, wxEXPAND | wxALL, 5);
940
941 wxBoxSizer* bSizerLinkBtns;
942 bSizerLinkBtns = new wxBoxSizer(wxHORIZONTAL);
943
944 m_buttonAddLink =
945 new wxButton(m_panelAdvanced, wxID_ANY, _("Add"), wxDefaultPosition,
946 wxDefaultSize, wxBU_EXACTFIT);
947 bSizerLinkBtns->Add(m_buttonAddLink, 0, wxALL, 5);
948
949 m_toggleBtnEdit = new wxToggleButton(m_panelAdvanced, wxID_ANY, _("Edit"),
950 wxDefaultPosition, wxDefaultSize, 0);
951 bSizerLinkBtns->Add(m_toggleBtnEdit, 0, wxALL, 5);
952
953 m_staticTextEditEnabled = new wxStaticText(
954 m_panelAdvanced, wxID_ANY, _("Links are opened in the default browser."),
955 wxDefaultPosition, wxDefaultSize, 0);
956 // m_staticTextEditEnabled->Wrap( -1 );
957 bSizerLinkBtns->Add(m_staticTextEditEnabled, 0,
958 wxALIGN_CENTER_VERTICAL | wxALL, 5);
959
960 sbSizerLinks->Add(bSizerLinkBtns, 0, wxEXPAND, 5);
961
962 bSizerAdvanced->Add(sbSizerLinks, 1, wxEXPAND, 5);
963
964 m_panelAdvanced->SetSizer(bSizerAdvanced);
965 m_notebook1->AddPage(m_panelAdvanced, _("Advanced"), false);
966
967 // Buttons, etc...
968
969 wxBoxSizer* itemBoxSizerBottom = new wxBoxSizer(wxVERTICAL);
970 bSizerMain->Add(itemBoxSizerBottom, 0, wxALIGN_LEFT | wxALL | wxEXPAND, 5);
971
972 // wxBoxSizer* itemBoxSizerAux = new wxBoxSizer( wxHORIZONTAL );
973
974 int n_col = 5;
975
976 wxFlexGridSizer* itemBoxSizerAux = new wxFlexGridSizer(0, n_col, 0, 0);
977 itemBoxSizerAux->SetFlexibleDirection(wxBOTH);
978 itemBoxSizerAux->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_SPECIFIED);
979
980 itemBoxSizerBottom->Add(itemBoxSizerAux, 1, wxALIGN_LEFT | wxALL, 5);
981
982#ifndef __ANDROID__
983
984 m_sdbBtmBtnsSizerPrint = new wxButton(this, wxID_ANY, _("Print"),
985 wxDefaultPosition, wxDefaultSize, 0);
986 itemBoxSizerAux->Add(m_sdbBtmBtnsSizerPrint, 0,
987 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 5);
988 m_sdbBtmBtnsSizerPrint->Enable(true);
989#else
990 m_sdbBtmBtnsSizerPrint = NULL;
991#endif
992
993 m_sdbBtmBtnsSizerSplit = new wxButton(this, wxID_ANY, _("Split"),
994 wxDefaultPosition, wxDefaultSize, 0);
995 itemBoxSizerAux->Add(m_sdbBtmBtnsSizerSplit, 0,
996 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 5);
997 m_sdbBtmBtnsSizerSplit->Enable(false);
998
999 m_sdbBtmBtnsSizerExtend = new wxButton(this, wxID_ANY, _("Extend track"),
1000 wxDefaultPosition, wxDefaultSize, 0);
1001 itemBoxSizerAux->Add(m_sdbBtmBtnsSizerExtend, 0,
1002 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 5);
1003
1004 m_sdbBtmBtnsSizerToRoute = new wxButton(this, wxID_ANY, _("To route"),
1005 wxDefaultPosition, wxDefaultSize, 0);
1006 itemBoxSizerAux->Add(m_sdbBtmBtnsSizerToRoute, 0,
1007 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 5);
1008
1009 m_sdbBtmBtnsSizerExport = new wxButton(this, wxID_ANY, _("Export"),
1010 wxDefaultPosition, wxDefaultSize, 0);
1011 itemBoxSizerAux->Add(m_sdbBtmBtnsSizerExport, 0,
1012 wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 5);
1013
1014 wxBoxSizer* itemBoxSizer16 = new wxBoxSizer(wxHORIZONTAL);
1015 itemBoxSizerBottom->Add(itemBoxSizer16, 0, wxALIGN_RIGHT | wxALL, 5);
1016
1017 m_sdbBtmBtnsSizerCancel = new wxButton(this, wxID_CANCEL, _("Cancel"),
1018 wxDefaultPosition, wxDefaultSize, 0);
1019 itemBoxSizer16->Add(m_sdbBtmBtnsSizerCancel, 0, wxALIGN_BOTTOM | wxALL, 5);
1020
1021 m_sdbBtmBtnsSizerOK =
1022 new wxButton(this, wxID_OK, _("OK"), wxDefaultPosition, wxDefaultSize, 0);
1023 itemBoxSizer16->Add(m_sdbBtmBtnsSizerOK, 0, wxALIGN_BOTTOM | wxALL, 5);
1024 m_sdbBtmBtnsSizerOK->SetDefault();
1025
1026 // Make it look nice and add the needed non-standard buttons
1027 int w1, w2, h;
1028 ((wxWindowBase*)m_stName)->GetSize(&w1, &h);
1029 ((wxWindowBase*)m_stFrom)->GetSize(&w2, &h);
1030 ((wxWindowBase*)m_stName)->SetMinSize(wxSize(wxMax(w1, w2), h));
1031 ((wxWindowBase*)m_stFrom)->SetMinSize(wxSize(wxMax(w1, w2), h));
1032
1033 m_panelBasic->SetScrollRate(5, 5);
1034 m_panelAdvanced->SetScrollRate(5, 5);
1035}
1036
1037void TrackPropDlg::SetTrackAndUpdate(Track* pt) {
1038 m_pTrack = pt;
1039
1040 m_lcPoints->DeleteAllItems();
1041
1042 if (m_pMyLinkList) delete m_pMyLinkList;
1043 m_pMyLinkList = new HyperlinkList();
1044
1045 for (Hyperlink* link : *m_pTrack->m_TrackHyperlinkList) {
1046 Hyperlink* h = new Hyperlink();
1047 h->DescrText = link->DescrText;
1048 h->Link = link->Link;
1049 h->LType = link->LType;
1050
1051 m_pMyLinkList->push_back(h);
1052 }
1053
1054 InitializeList();
1056
1057 RecalculateSize();
1058}
1059void TrackPropDlg::InitializeList() {
1060 if (NULL == m_pTrack) return;
1061
1062 m_lcPoints->m_pTrack = m_pTrack;
1063
1064 if (m_pTrack->GetnPoints()) {
1065 TrackPoint* prp = m_pTrack->GetPoint(0);
1066 if (prp)
1067 m_lcPoints->m_LMT_Offset = long((prp->m_lon) * 3600. / 15.); // estimated
1068 else
1069 m_lcPoints->m_LMT_Offset = 0;
1070 }
1071
1072 if (m_lcPoints->IsVirtual())
1073 m_lcPoints->SetItemCount(m_pTrack->GetnPoints());
1074
1075 else {
1076 for (int in = 0; in < m_pTrack->GetnPoints(); in++) {
1077 wxListItem item;
1078 item.SetId(in);
1079
1080 m_lcPoints->InsertItem(item);
1081 for (int j = 0; j < 7; j++) {
1082 item.SetColumn(j);
1083 item.SetText(m_lcPoints->OnGetItemText(in, j));
1084 m_lcPoints->SetItem(item);
1085 }
1086 }
1087 }
1088}
1089
1091 if (NULL == m_pTrack) return false;
1092
1093 ::wxBeginBusyCursor();
1094
1095 if (m_scrolledWindowLinks) {
1096 wxWindowList kids = m_scrolledWindowLinks->GetChildren();
1097 for (unsigned int i = 0; i < kids.GetCount(); i++) {
1098 wxWindowListNode* node = kids.Item(i);
1099 wxWindow* win = node->GetData();
1100
1101 auto link_win = dynamic_cast<wxHyperlinkCtrl*>(win);
1102 if (link_win) {
1103 link_win->Disconnect(
1104 wxEVT_COMMAND_HYPERLINK,
1105 wxHyperlinkEventHandler(TrackPropDlg::OnHyperLinkClick));
1106 link_win->Disconnect(
1107 wxEVT_RIGHT_DOWN,
1108 wxMouseEventHandler(TrackPropDlg::m_hyperlinkContextMenu));
1109 win->Destroy();
1110 }
1111 }
1113 int NbrOfLinks = m_pTrack->m_TrackHyperlinkList->size();
1114 HyperlinkList* list = m_pTrack->m_TrackHyperlinkList;
1115 // int len = 0;
1116 if (NbrOfLinks > 0) {
1117 for (auto it = list->begin(); it != list->end(); ++it) {
1118 Hyperlink* link = *it;
1119 wxString Link = link->Link;
1120 wxString Descr = link->DescrText;
1121
1122 wxHyperlinkCtrl* ctrl = new wxHyperlinkCtrl(
1123 m_scrolledWindowLinks, wxID_ANY, Descr, Link, wxDefaultPosition,
1124 wxDefaultSize, wxHL_DEFAULT_STYLE);
1125 ctrl->Connect(wxEVT_COMMAND_HYPERLINK,
1126 wxHyperlinkEventHandler(TrackPropDlg::OnHyperLinkClick),
1127 NULL, this);
1128 if (!m_pTrack->m_bIsInLayer)
1129 ctrl->Connect(
1130 wxEVT_RIGHT_DOWN,
1131 wxMouseEventHandler(TrackPropDlg::m_hyperlinkContextMenu), NULL,
1132 this);
1133
1134 bSizerLinks->Add(ctrl, 0, wxALL, 5);
1135 }
1136 }
1137 bSizerLinks->Fit(m_scrolledWindowLinks);
1138 }
1139
1140 m_tName->SetValue(m_pTrack->GetName());
1141 m_tFrom->SetValue(m_pTrack->m_TrackStartString);
1142 m_tTo->SetValue(m_pTrack->m_TrackEndString);
1143 if (m_tDescription) m_tDescription->SetValue(m_pTrack->m_TrackDescription);
1144
1145 m_tTotDistance->SetValue("");
1146 m_tTimeEnroute->SetValue("");
1147
1148 m_sdbBtmBtnsSizerSplit->Enable(false);
1149 m_sdbBtmBtnsSizerExtend->Enable(false);
1150
1151 // Calculate AVG speed if we are showing a track and total time
1152 TrackPoint* last_point = m_pTrack->GetLastPoint();
1153 TrackPoint* first_point = m_pTrack->GetPoint(0);
1154 double trackLength = m_pTrack->Length();
1155 double total_seconds = 0.;
1156
1157 wxString speed("--");
1158
1159 if (last_point && first_point) {
1160 if (last_point->GetCreateTime().IsValid() &&
1161 first_point->GetCreateTime().IsValid()) {
1162 total_seconds = last_point->GetCreateTime()
1163 .Subtract(first_point->GetCreateTime())
1164 .GetSeconds()
1165 .ToDouble();
1166 if (total_seconds != 0.) {
1167 m_avgspeed = trackLength / total_seconds * 3600;
1168 } else {
1169 m_avgspeed = 0;
1170 }
1171 speed.Printf("%5.2f", toUsrSpeed(m_avgspeed));
1172 }
1173 }
1174
1175 m_tAvgSpeed->SetValue(speed);
1176
1177 // Total length
1178 wxString slen;
1179 slen.Printf("%5.2f " + getUsrDistanceUnit(), toUsrDistance(trackLength));
1180
1181 m_tTotDistance->SetValue(slen);
1182
1183 // Time
1184 wxString time_form;
1185 wxTimeSpan time(0, 0, (int)total_seconds, 0);
1186 // TODO Construct a readable time string, e.g. "xx Days, 15:34"
1187 if (total_seconds > 3600. * 24.)
1188 time_form = time.Format("%H:%M");
1189 else if (total_seconds > 0.)
1190 time_form = time.Format("%H:%M");
1191 else
1192 time_form = "--";
1193 m_tTimeEnroute->SetValue(time_form);
1194
1195 m_cbShow->SetValue(m_pTrack->IsVisible());
1196
1197 if (m_pTrack->m_Colour == "")
1198 m_cColor->Select(0);
1199 else {
1200 for (unsigned int i = 0; i < sizeof(::GpxxColorNames) / sizeof(wxString);
1201 i++) {
1202 if (m_pTrack->m_Colour == ::GpxxColorNames[i]) {
1203 m_cColor->Select(i + 1);
1204 break;
1205 }
1206 }
1207 }
1208
1209 for (unsigned int i = 0; i < sizeof(::StyleValues) / sizeof(int); i++) {
1210 if (m_pTrack->m_style == ::StyleValues[i]) {
1211 m_cStyle->Select(i);
1212 break;
1213 }
1214 }
1215
1216 for (unsigned int i = 0; i < sizeof(::WidthValues) / sizeof(int); i++) {
1217 if (m_pTrack->m_width == ::WidthValues[i]) {
1218 m_cWidth->Select(i);
1219 break;
1220 }
1221 }
1222
1223 if (m_pTrack->m_bIsInLayer) {
1224 m_tName->SetEditable(false);
1225 m_tFrom->SetEditable(false);
1226 m_tTo->SetEditable(false);
1227 if (m_tDescription) m_tDescription->SetEditable(false);
1228 m_cbShow->Enable(false);
1229 m_cColor->Enable(false);
1230 m_cStyle->Enable(false);
1231 m_cWidth->Enable(false);
1232 m_sdbBtmBtnsSizerExtend->Enable(false);
1233 m_sdbBtmBtnsSizerSplit->Enable(false);
1234 SetTitle(wxString::Format("%s, %s: %d", _("Track properties"), "Layer",
1235 m_pTrack->m_LayerID));
1236 } else {
1237 m_tName->SetEditable(true);
1238 m_tFrom->SetEditable(true);
1239 m_tTo->SetEditable(true);
1240 if (m_tDescription) m_tDescription->SetEditable(true);
1241 m_cbShow->Enable(true);
1242 m_cColor->Enable(true);
1243 m_cStyle->Enable(true);
1244 m_cWidth->Enable(true);
1245
1246 m_sdbBtmBtnsSizerExtend->Enable(IsThisTrackExtendable());
1247 // m_sdbBtmBtnsSizerSplit->Enable( false );
1248 SetTitle(_("Track properties"));
1249 }
1250
1251 ::wxEndBusyCursor();
1252
1253 return true;
1254}
1255
1256bool TrackPropDlg::IsThisTrackExtendable() {
1257 m_pExtendTrack = NULL;
1258 m_pExtendPoint = NULL;
1259 if (m_pTrack == g_pActiveTrack || m_pTrack->m_bIsInLayer) {
1260 return false;
1261 }
1262
1263 TrackPoint* pLastPoint = m_pTrack->GetPoint(0);
1264 if (!pLastPoint->GetCreateTime().IsValid()) {
1265 return false;
1266 }
1267
1268 for (Track* ptrack : g_TrackList) {
1269 if (ptrack->IsVisible() && (ptrack->m_GUID != m_pTrack->m_GUID)) {
1270 TrackPoint* track_node = ptrack->GetLastPoint();
1271 if (track_node) {
1272 if (track_node->GetCreateTime().IsValid()) {
1273 if (track_node->GetCreateTime() <= pLastPoint->GetCreateTime()) {
1274 if (!m_pExtendPoint ||
1275 track_node->GetCreateTime() > m_pExtendPoint->GetCreateTime()) {
1276 m_pExtendPoint = track_node;
1277 m_pExtendTrack = ptrack;
1278 }
1279 }
1280 }
1281 }
1282 }
1283 }
1284 if (m_pExtendTrack) {
1285 return (!m_pExtendTrack->m_bIsInLayer);
1286 } else {
1287 return false;
1288 }
1289}
1290
1291void TrackPropDlg::OnExtendBtnClick(wxCommandEvent& event) {
1292 TrackPoint* pFirstPoint = m_pTrack->GetPoint(0);
1293
1294 if (IsThisTrackExtendable()) {
1295 int begin = 0;
1296 if (pFirstPoint->GetCreateTime() == m_pExtendPoint->GetCreateTime()) {
1297 begin = 1;
1298 }
1299 pSelect->DeleteAllSelectableTrackSegments(m_pExtendTrack);
1300 m_pExtendTrack->Clone(m_pTrack, begin, m_pTrack->GetnPoints(), _("_plus"));
1301 pSelect->AddAllSelectableTrackSegments(m_pExtendTrack);
1302 pSelect->DeleteAllSelectableTrackSegments(m_pTrack);
1303 NavObj_dB::GetInstance().DeleteTrack(m_pTrack);
1304 RoutemanGui(*g_pRouteMan).DeleteTrack(m_pTrack);
1305
1306 SetTrackAndUpdate(m_pExtendTrack);
1307 NavObj_dB::GetInstance().UpdateTrack(m_pTrack);
1309
1310 if (pRouteManagerDialog && pRouteManagerDialog->IsShown()) {
1311 pRouteManagerDialog->UpdateTrkListCtrl();
1312 }
1313 }
1314}
1315
1316void TrackPropDlg::OnSplitBtnClick(wxCommandEvent& event) {
1317 m_sdbBtmBtnsSizerSplit->Enable(false);
1318
1319 if (m_pTrack->m_bIsInLayer) {
1320 return;
1321 }
1322
1323 if ((m_nSelected > 1) && (m_nSelected < m_pTrack->GetnPoints())) {
1324 Track* pHead = new Track();
1325 Track* pTail = new Track();
1326 pHead->Clone(m_pTrack, 0, m_nSelected - 1, _("_A"));
1327 pTail->Clone(m_pTrack, m_nSelected - 1, m_pTrack->GetnPoints(), _("_B"));
1328
1329 g_TrackList.push_back(pHead);
1330 NavObj_dB::GetInstance().InsertTrack(pHead);
1331
1332 g_TrackList.push_back(pTail);
1333 NavObj_dB::GetInstance().InsertTrack(pTail);
1334
1335 NavObj_dB::GetInstance().DeleteTrack(m_pTrack);
1336
1337 pSelect->DeleteAllSelectableTrackSegments(m_pTrack);
1338 RoutemanGui(*g_pRouteMan).DeleteTrack(m_pTrack);
1339 pSelect->AddAllSelectableTrackSegments(pTail);
1340 pSelect->AddAllSelectableTrackSegments(pHead);
1341
1342 SetTrackAndUpdate(pTail);
1344
1345 if (pRouteManagerDialog && pRouteManagerDialog->IsShown()) {
1346 pRouteManagerDialog->UpdateTrkListCtrl();
1347 }
1348 }
1349}
1350
1351void TrackPropDlg::OnTrackPropCopyTxtClick(wxCommandEvent& event) {
1352 wxString tab("\t", wxConvUTF8);
1353 wxString eol("\n", wxConvUTF8);
1354 wxString csvString;
1355
1356 csvString << this->GetTitle() << eol << _("Name") << tab
1357 << m_pTrack->GetName() << eol << _("Depart From") << tab
1358 << m_pTrack->m_TrackStartString << eol << _("Destination") << tab
1359 << m_pTrack->m_TrackEndString << eol << _("Total distance") << tab
1360 << m_tTotDistance->GetValue() << eol << _("Speed") << tab
1361 << m_tAvgSpeed->GetValue() << eol
1362 << _("Departure Time") + " " + _("(m/d/y h:m)") << tab
1363 << m_pTrack->GetPoint(1)->GetCreateTime().Format() << eol
1364 << _("Time enroute") << tab << m_tTimeEnroute->GetValue() << eol
1365 << eol;
1366
1367 int noCols;
1368 int noRows;
1369 noCols = m_lcPoints->GetColumnCount();
1370 noRows = m_lcPoints->GetItemCount();
1371 wxListItem item;
1372 item.SetMask(wxLIST_MASK_TEXT);
1373
1374 for (int i = 0; i < noCols; i++) {
1375 m_lcPoints->GetColumn(i, item);
1376 csvString << item.GetText() << tab;
1377 }
1378 csvString << eol;
1379
1380 for (int j = 0; j < noRows; j++) {
1381 item.SetId(j);
1382 for (int i = 0; i < noCols; i++) {
1383 item.SetColumn(i);
1384 m_lcPoints->GetItem(item);
1385 csvString << item.GetText() << tab;
1386 }
1387 csvString << eol;
1388 }
1389
1390 if (wxTheClipboard->Open()) {
1391 wxTextDataObject* data = new wxTextDataObject;
1392 data->SetText(csvString);
1393 wxTheClipboard->SetData(data);
1394 wxTheClipboard->Close();
1395 }
1396}
1397
1398void TrackPropDlg::OnPrintBtnClick(wxCommandEvent& event) {
1399 static std::set<int> s_options; // keep selected options
1400 TrackPrintDialog dlg(this, s_options);
1401 int result = dlg.ShowModal();
1402
1403 if (result == wxID_OK) {
1404 dlg.GetSelected(s_options);
1405 TrackPrintout printout(m_pTrack, m_lcPoints, s_options);
1406 auto& printer = PrintDialog::GetInstance();
1407 printer.Initialize(wxPORTRAIT);
1408 printer.EnablePageNumbers(true);
1409 printer.Print(this, &printout);
1410 }
1411}
1412
1413void TrackPropDlg::OnTrackPropRightClick(wxListEvent& event) {
1414 wxMenu menu;
1415
1416 wxMenuItem* copyItem =
1417 menu.Append(ID_RCLK_MENU_COPY_TEXT, _("&Copy all as text"));
1418
1419 PopupMenu(&menu);
1420}
1421
1422void TrackPropDlg::OnTrackPropListClick(wxListEvent& event) {
1423 long itemno = -1;
1424 m_nSelected = 0;
1425
1426 int selected_no;
1427 itemno =
1428 m_lcPoints->GetNextItem(itemno, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
1429 if (itemno == -1)
1430 selected_no = 0;
1431 else
1432 selected_no = itemno;
1433
1434 m_pTrack->m_HighlightedTrackPoint = -1;
1435
1436 if (itemno >= 0) {
1437 TrackPoint* prp = m_pTrack->GetPoint(itemno);
1438 if (prp) {
1439 m_pTrack->m_HighlightedTrackPoint = itemno; // highlight the trackpoint
1440
1441 if (!(m_pTrack->m_bIsInLayer) && !(m_pTrack == g_pActiveTrack)) {
1442 m_nSelected = selected_no + 1;
1443 m_sdbBtmBtnsSizerSplit->Enable(true);
1444 }
1445 top_frame::Get()->JumpToPosition(prp->m_lat, prp->m_lon);
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 top_frame::Get()->InvalidateAllGL();
1762 top_frame::Get()->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 top_frame::Get()->InvalidateAllGL();
1775 top_frame::Get()->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.
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
Display utilities.
OpenCPN Georef utility.
Platform independent GL includes.
wxFont * GetOCPNScaledFont(wxString item, int default_size)
Retrieves a font from FontMgr, optionally scaled for physical readability.
Definition gui_lib.cpp:61
General purpose GUI support.
size_t g_current_monitor
Current monitor displaying main application frame.
Definition gui_vars.cpp:75
Miscellaneous globals primarely used by gui layer, not persisted in configuration file.
MySQL based storage for routes, tracks, etc.
MyConfig * pConfig
Global instance.
Definition navutil.cpp:118
Utility functions.
double toUsrDistance(double nm_distance, int unit)
Convert a distance from nautical miles (NMi) to user display units.
Navigation Utility Functions without GUI dependencies.
OpenCPN Platform specific support utilities.
double gLat
Vessel's current latitude in decimal degrees.
Definition own_ship.cpp:26
double gLon
Vessel's current longitude in decimal degrees.
Definition own_ship.cpp:27
Position, course, speed, etc.
Tools to send data to plugins.
PlugInManager and helper classes – Mostly gui parts (dialogs) and plugin API stuff.
Generic, styled prit dialog.
Route abstraction.
#define LMTINPUT
Format date/time using the remote location LMT time.
#define GLOBAL_SETTINGS_INPUT
Format date/time according to global OpenCPN settings.
#define UTCINPUT
Format date/time in UTC.
#define LTINPUT
Format date/time using timezone configured in the operating system./*#end#*‍/.
Route Manager.
Routeman drawing stuff.
RouteManagerDialog * pRouteManagerDialog
Global instance.
Manage routes dialog.
Select * pSelect
Global instance.
Definition select.cpp:36
Selected route, segment, waypoint, etc.
Configuration options for date and time formatting.
DateTimeFormatOptions & SetTimezone(const wxString &tz)
Sets the timezone mode for date/time display.
DateTimeFormatOptions & SetLongitude(double lon)
Sets the reference longitude for Local Mean Time (LMT) calculations.
Abstract gFrame/MyFrame interface.
ActiveTrack * g_pActiveTrack
global instance
Definition track.cpp: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.