OpenCPN Partial API docs
Loading...
Searching...
No Matches
MarkInfo.cpp
1/**************************************************************************
2 *
3 * Project: OpenCPN
4 * Purpose: MarkProperties Support
5 * Author: David Register
6 *
7 ***************************************************************************
8 * Copyright (C) 2010 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// For compilers that support precompilation, includes "wx/wx.h".
28#include <wx/wxprec.h>
29
30#ifndef WX_PRECOMP
31#include <wx/wx.h>
32#endif
33
34#include <wx/datetime.h>
35#include <wx/clipbrd.h>
36#include <wx/print.h>
37#include <wx/printdlg.h>
38#include <wx/stattext.h>
39#include <wx/clrpicker.h>
40#include <wx/bmpbuttn.h>
41
42#include "styles.h"
43#include "MarkInfo.h"
44#include "navutil.h" // for Route
45#include "navutil_base.h"
46#include "georef.h"
47#include "gui_lib.h"
48#include "own_ship.h"
49#include "routeman.h"
50#include "routemanagerdialog.h"
51#include "routeprintout.h"
52#include "RoutePropDlgImpl.h"
53#include "chcanv.h"
54#include "position_parser.h"
55#include "pluginmanager.h"
56#include "OCPNPlatform.h"
57#include "route.h"
58#include "TCWin.h"
59#include "svg_utils.h"
60#include "ocpn_frame.h"
61
62#ifdef __OCPN__ANDROID__
63#include "androidUTIL.h"
64#include <QtWidgets/QScroller>
65#endif
66
67extern TCMgr* ptcmgr;
68extern MyConfig* pConfig;
69extern WayPointman* pWayPointMan;
70extern Select* pSelect;
71extern Routeman* g_pRouteMan;
72extern RouteManagerDialog* pRouteManagerDialog;
73extern RoutePropDlgImpl* pRoutePropDialog;
74extern bool g_bShowTrue, g_bShowMag;
75extern ocpnStyle::StyleManager* g_StyleManager;
76
77extern MyFrame* gFrame;
78extern OCPNPlatform* g_Platform;
79extern wxString g_default_wp_icon;
80
81// Global print data, to remember settings during the session
82
83// Global page setup data
84
85extern float g_ChartScaleFactorExp;
86extern float g_MarkScaleFactorExp;
87
88extern MarkInfoDlg* g_pMarkInfoDialog;
89extern double g_n_arrival_circle_radius;
90extern int g_iWaypointRangeRingsNumber;
91extern float g_fWaypointRangeRingsStep;
92extern wxColour g_colourWaypointRangeRingsColour;
93
94extern int g_iWpt_ScaMin;
95extern bool g_bUseWptScaMin;
96
97WX_DECLARE_LIST(wxBitmap, BitmapList);
98#include <wx/listimpl.cpp>
99WX_DEFINE_LIST(BitmapList);
100
101#include <wx/arrimpl.cpp>
102WX_DEFINE_OBJARRAY(ArrayOfBitmaps);
103
104#define EXTENDED_PROP_PAGE 2 // Index of the extended properties page
105
106OCPNIconCombo::OCPNIconCombo(wxWindow* parent, wxWindowID id,
107 const wxString& value, const wxPoint& pos,
108 const wxSize& size, int n,
109 const wxString choices[], long style,
110 const wxValidator& validator, const wxString& name)
111 : wxOwnerDrawnComboBox(parent, id, value, pos, size, n, choices, style,
112 validator, name) {
113 double fontHeight =
114 GetFont().GetPointSize() / g_Platform->getFontPointsperPixel();
115 itemHeight = (int)wxRound(fontHeight);
116}
117
118OCPNIconCombo::~OCPNIconCombo() {}
119
120void OCPNIconCombo::OnDrawItem(wxDC& dc, const wxRect& rect, int item,
121 int flags) const {
122 int offset_x = bmpArray[item].GetWidth();
123 int bmpHeight = bmpArray[item].GetHeight();
124 dc.DrawBitmap(bmpArray[item], rect.x, rect.y + (rect.height - bmpHeight) / 2,
125 true);
126
127 if (flags & wxODCB_PAINTING_CONTROL) {
128 wxString text = GetValue();
129 int margin_x = 2;
130
131#if wxCHECK_VERSION(2, 9, 0)
132 if (ShouldUseHintText()) {
133 text = GetHint();
134 wxColour col = wxSystemSettings::GetColour(wxSYS_COLOUR_GRAYTEXT);
135 dc.SetTextForeground(col);
136 }
137
138 margin_x = GetMargins().x;
139#endif
140
141 dc.DrawText(text, rect.x + margin_x + offset_x,
142 (rect.height - dc.GetCharHeight()) / 2 + rect.y);
143 } else {
144 dc.DrawText(GetVListBoxComboPopup()->GetString(item), rect.x + 2 + offset_x,
145 (rect.height - dc.GetCharHeight()) / 2 + rect.y);
146 }
147}
148
149wxCoord OCPNIconCombo::OnMeasureItem(size_t item) const {
150 int bmpHeight = bmpArray[item].GetHeight();
151
152 return wxMax(itemHeight, bmpHeight);
153}
154
155wxCoord OCPNIconCombo::OnMeasureItemWidth(size_t item) const { return -1; }
156
157int OCPNIconCombo::Append(const wxString& item, wxBitmap bmp) {
158 bmpArray.Add(bmp);
159 int idx = wxOwnerDrawnComboBox::Append(item);
160
161 return idx;
162}
163
164void OCPNIconCombo::Clear(void) {
165 wxOwnerDrawnComboBox::Clear();
166 bmpArray.Clear();
167}
168
169//-------------------------------------------------------------------------------
170//
171// Mark Properties Dialog Implementation
172//
173//-------------------------------------------------------------------------------
178// DEFINE_EVENT_TYPE(EVT_LLCHANGE) // events from LatLonTextCtrl
179const wxEventType EVT_LLCHANGE = wxNewEventType();
180//------------------------------------------------------------------------------
181// LatLonTextCtrl Window Implementation
182//------------------------------------------------------------------------------
183BEGIN_EVENT_TABLE(LatLonTextCtrl, wxWindow)
184END_EVENT_TABLE()
185
186// constructor
187LatLonTextCtrl::LatLonTextCtrl(wxWindow* parent, wxWindowID id,
188 const wxString& value, const wxPoint& pos,
189 const wxSize& size, long style,
190 const wxValidator& validator,
191 const wxString& name)
192 : wxTextCtrl(parent, id, value, pos, size, style, validator, name) {
193 m_pParentEventHandler = parent->GetEventHandler();
194}
195
196void LatLonTextCtrl::OnKillFocus(wxFocusEvent& event) {
197 // Send an event to the Parent Dialog
198 wxCommandEvent up_event(EVT_LLCHANGE, GetId());
199 up_event.SetEventObject((wxObject*)this);
200 m_pParentEventHandler->AddPendingEvent(up_event);
201}
202
203//-------------------------------------------------------------------------------
204//
205// Mark Information Dialog Implementation
206//
207//-------------------------------------------------------------------------------
208BEGIN_EVENT_TABLE(MarkInfoDlg, wxFrame)
209EVT_BUTTON(wxID_OK, MarkInfoDlg::OnMarkInfoOKClick)
210EVT_BUTTON(wxID_CANCEL, MarkInfoDlg::OnMarkInfoCancelClick)
211EVT_BUTTON(ID_BTN_DESC_BASIC, MarkInfoDlg::OnExtDescriptionClick)
212EVT_BUTTON(ID_DEFAULT, MarkInfoDlg::DefautlBtnClicked)
213EVT_BUTTON(ID_BTN_SHOW_TIDES, MarkInfoDlg::ShowTidesBtnClicked)
214EVT_COMBOBOX(ID_BITMAPCOMBOCTRL, MarkInfoDlg::OnBitmapCombClick)
215EVT_CHECKBOX(ID_SHOWNAMECHECKBOXBASIC,
216 MarkInfoDlg::OnShowWaypointNameSelectBasic)
217EVT_CHECKBOX(ID_SHOWNAMECHECKBOX_EXT, MarkInfoDlg::OnShowWaypointNameSelectExt)
218EVT_CHECKBOX(ID_CHECKBOX_SCAMIN_VIS, MarkInfoDlg::OnSelectScaMinExt)
219EVT_TEXT(ID_DESCR_CTR_DESC, MarkInfoDlg::OnDescChangedExt)
220EVT_TEXT(ID_DESCR_CTR_BASIC, MarkInfoDlg::OnDescChangedBasic)
221EVT_TEXT(ID_LATCTRL, MarkInfoDlg::OnPositionCtlUpdated)
222EVT_TEXT(ID_LONCTRL, MarkInfoDlg::OnPositionCtlUpdated)
223EVT_CHOICE(ID_WPT_RANGERINGS_NO, MarkInfoDlg::OnWptRangeRingsNoChange)
224// the HTML listbox's events
225EVT_HTML_LINK_CLICKED(wxID_ANY, MarkInfoDlg::OnHtmlLinkClicked)
226EVT_CLOSE(MarkInfoDlg::OnClose)
227
228// EVT_CHOICE( ID_WAYPOINTRANGERINGS, MarkInfoDef::OnWaypointRangeRingSelect )
229END_EVENT_TABLE()
230
231MarkInfoDlg::MarkInfoDlg(wxWindow* parent, wxWindowID id, const wxString& title,
232 const wxPoint& pos, const wxSize& size, long style) {
233 wxFrame::Create(parent, id, title, pos, size, style);
234
235 wxFont* qFont = GetOCPNScaledFont(_("Dialog"));
236 SetFont(*qFont);
237 int metric = GetCharHeight();
238
239#ifdef __OCPN__ANDROID__
240 // Set Dialog Font by custom crafted Qt Stylesheet.
241 wxString wqs = getFontQtStylesheet(qFont);
242 wxCharBuffer sbuf = wqs.ToUTF8();
243 QString qsb = QString(sbuf.data());
244 QString qsbq = getQtStyleSheet(); // basic scrollbars, etc
245 this->GetHandle()->setStyleSheet(qsb + qsbq); // Concatenated style sheets
246 wxScreenDC sdc;
247 if (sdc.IsOk()) sdc.GetTextExtent(_T("W"), NULL, &metric, NULL, NULL, qFont);
248#endif
249 Create();
250 m_pMyLinkList = NULL;
251 SetColorScheme((ColorScheme)0);
252 m_pRoutePoint = NULL;
253 m_SaveDefaultDlg = NULL;
254 CenterOnScreen();
255
256#ifdef __WXOSX__
257 Connect(wxEVT_ACTIVATE, wxActivateEventHandler(MarkInfoDlg::OnActivate), NULL,
258 this);
259#endif
260}
261
262void MarkInfoDlg::OnActivate(wxActivateEvent& event) {
263 wxFrame* pWin = wxDynamicCast(event.GetEventObject(), wxFrame);
264 long int style = pWin->GetWindowStyle();
265 if (event.GetActive())
266 pWin->SetWindowStyle(style | wxSTAY_ON_TOP);
267 else
268 pWin->SetWindowStyle(style ^ wxSTAY_ON_TOP);
269}
270
271void MarkInfoDlg::initialize_images(void) {
272 wxString iconDir = g_Platform->GetSharedDataDir() + _T("uidata/MUI_flat/");
273 _img_MUI_settings_svg = LoadSVG(iconDir + _T("MUI_settings.svg"),
274 2 * GetCharHeight(), 2 * GetCharHeight());
275
276 ocpnStyle::Style* style = g_StyleManager->GetCurrentStyle();
277 wxBitmap tide = style->GetIcon(_T("tidesml"));
278 wxImage tide1 = tide.ConvertToImage();
279 wxImage tide1s = tide1.Scale(m_sizeMetric * 3 / 2, m_sizeMetric * 3 / 2,
280 wxIMAGE_QUALITY_HIGH);
281 m_bmTide = wxBitmap(tide1s);
282
283 return;
284}
285
286void MarkInfoDlg::Create() {
287 wxFont* qFont = GetOCPNScaledFont(_("Dialog"));
288 SetFont(*qFont);
289 m_sizeMetric = GetCharHeight();
290
291#ifdef __OCPN__ANDROID__
292 // Set Dialog Font by custom crafted Qt Stylesheet.
293
294 wxString wqs = getFontQtStylesheet(qFont);
295 wxCharBuffer sbuf = wqs.ToUTF8();
296 QString qsb = QString(sbuf.data());
297
298 QString qsbq = getAdjustedDialogStyleSheet(); // basic scrollbars, etc
299
300 this->GetHandle()->setStyleSheet(qsb + qsbq); // Concatenated style sheets
301
302 wxScreenDC sdc;
303 if (sdc.IsOk())
304 sdc.GetTextExtent(_T("W"), NULL, &m_sizeMetric, NULL, NULL, qFont);
305
306#endif
307
308 initialize_images();
309
310 wxBoxSizer* bSizer1;
311 bSizer1 = new wxBoxSizer(wxVERTICAL);
312 SetSizer(bSizer1);
313 bSizer1->SetSizeHints(this); // set size hints to honour minimum size
314
315 m_notebookProperties =
316 new wxNotebook(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0);
317
318 m_panelBasicProperties = new wxScrolledWindow(
319 m_notebookProperties, wxID_ANY, wxDefaultPosition, wxDefaultSize,
320 wxHSCROLL | wxVSCROLL | wxTAB_TRAVERSAL);
321#ifdef __OCPN__ANDROID__
322 m_panelBasicProperties->GetHandle()->setStyleSheet(
323 getAdjustedDialogStyleSheet());
324#endif
325
326 m_panelBasicProperties->SetScrollRate(0, 2);
327
328 m_notebookProperties->AddPage(m_panelBasicProperties, _("Basic"), true);
329
330 bSizerBasicProperties = new wxBoxSizer(wxVERTICAL);
331 m_panelBasicProperties->SetSizer(bSizerBasicProperties);
332
333 wxStaticBoxSizer* sbSizerProperties;
334 sbSizerProperties = new wxStaticBoxSizer(
335 new wxStaticBox(m_panelBasicProperties, wxID_ANY, _("Properties")),
336 wxVERTICAL);
337
338 wxBoxSizer* bSizerInnerProperties = new wxBoxSizer(wxHORIZONTAL);
339
340 // m_bitmapIcon = new wxStaticBitmap( m_panelBasicProperties, wxID_ANY,
341 // wxNullBitmap,
342 // wxDefaultPosition, wxDefaultSize, 0 );
343 // bSizerInnerProperties->Add( m_bitmapIcon, 0, wxALL, 5 );
344 // m_bitmapIcon->Show( false );
345
346 wxBoxSizer* bSizerTextProperties;
347 bSizerTextProperties = new wxBoxSizer(wxVERTICAL);
348
349 m_staticTextLayer = new wxStaticText(
350 m_panelBasicProperties, wxID_ANY,
351 _("This waypoint is part of a layer and can't be edited"),
352 wxDefaultPosition, wxDefaultSize, 0);
353 m_staticTextLayer->Enable(false);
354
355 bSizerTextProperties->Add(m_staticTextLayer, 0, wxALL, 5);
356
357 wxBoxSizer* bSizerName;
358 bSizerName = new wxBoxSizer(wxHORIZONTAL);
359
360 m_staticTextName =
361 new wxStaticText(m_panelBasicProperties, wxID_ANY, _("Name"),
362 wxDefaultPosition, wxDefaultSize, 0);
363 // m_staticTextName->Wrap( -1 );
364 bSizerName->Add(m_staticTextName, 0, wxALL | wxALIGN_CENTER_VERTICAL, 5);
365
366 wxBoxSizer* bSizerNameValue = new wxBoxSizer(wxVERTICAL);
367
368 m_textName = new wxTextCtrl(m_panelBasicProperties, wxID_ANY, wxEmptyString,
369 wxDefaultPosition, wxDefaultSize, 0);
370 bSizerNameValue->Add(m_textName, 0, wxALL | wxEXPAND, 5);
371 bSizerName->Add(bSizerNameValue, 1, wxEXPAND, 5);
372 bSizerTextProperties->Add(bSizerName, 0, wxEXPAND, 5);
373
374 m_checkBoxShowName =
375 new wxCheckBox(m_panelBasicProperties, wxID_ANY, _("Show name"),
376 wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT);
377 bSizerTextProperties->Add(m_checkBoxShowName, 0, wxALL, 5);
378
380 wxBoxSizer* bSizer8 = new wxBoxSizer(wxHORIZONTAL);
381 bSizerTextProperties->Add(bSizer8, 0, wxEXPAND, 5);
382
383 m_staticTextIcon =
384 new wxStaticText(m_panelBasicProperties, wxID_ANY, _("Icon"),
385 wxDefaultPosition, wxDefaultSize, 0);
386 bSizer8->Add(m_staticTextIcon, 0, wxALL, 5);
387
388 m_bcomboBoxIcon = new OCPNIconCombo(m_panelBasicProperties, wxID_ANY,
389 _("Combo!"), wxDefaultPosition,
390 wxDefaultSize, 0, NULL, wxCB_READONLY);
391
392 m_bcomboBoxIcon->SetPopupMaxHeight(::wxGetDisplaySize().y / 2);
393
394 // Accomodate scaling of icon
395 int min_size = m_sizeMetric * 2;
396 min_size = wxMax(min_size, (32 * g_MarkScaleFactorExp) + 4);
397 m_bcomboBoxIcon->SetMinSize(wxSize(-1, min_size));
398
399 bSizer8->Add(m_bcomboBoxIcon, 1, wxALL, 5);
400
401 bSizerTextProperties->AddSpacer(5);
402
403 wxFlexGridSizer* LLGrid = new wxFlexGridSizer(0, 2, 1, 1);
404 LLGrid->AddGrowableCol(1);
405 bSizerTextProperties->Add(LLGrid, 0, wxEXPAND, 0);
406
407 int w, h;
408 GetTextExtent(_T("179 59.9999 W"), &w, &h);
409
410 m_staticTextLatitude =
411 new wxStaticText(m_panelBasicProperties, wxID_ANY, _("Latitude"));
412 LLGrid->Add(m_staticTextLatitude, 0, wxALL | wxALIGN_LEFT, 0);
413
414 m_textLatitude =
415 new wxTextCtrl(m_panelBasicProperties, wxID_ANY, wxEmptyString,
416 wxDefaultPosition, wxSize(w + 20, -1), 0);
417 LLGrid->Add(m_textLatitude, 1, wxALL, 5);
418
419 m_staticTextLongitude =
420 new wxStaticText(m_panelBasicProperties, wxID_ANY, _("Longitude"));
421 LLGrid->Add(m_staticTextLongitude, 0, wxALL | wxALIGN_LEFT, 0);
422
423 m_textLongitude =
424 new wxTextCtrl(m_panelBasicProperties, wxID_ANY, wxEmptyString,
425 wxDefaultPosition, wxSize(w + 20, -1), 0);
426 LLGrid->Add(m_textLongitude, 1, wxALL, 5);
427
428 bSizerTextProperties->AddSpacer(15);
429
430 m_staticTextDescription =
431 new wxStaticText(m_panelBasicProperties, wxID_ANY, _("Description"),
432 wxDefaultPosition, wxDefaultSize, 0);
433 bSizerTextProperties->Add(m_staticTextDescription, 0, wxALL, 5);
434
435 wxBoxSizer* bSizer14;
436 bSizer14 = new wxBoxSizer(wxHORIZONTAL);
437
438 m_textDescription = new wxTextCtrl(
439 m_panelBasicProperties, ID_DESCR_CTR_BASIC, wxEmptyString,
440 wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE | wxTE_READONLY);
441 m_textDescription->SetMinSize(wxSize(-1, 80));
442 bSizer14->Add(m_textDescription, 1, wxALL | wxEXPAND, 5);
443
444 m_buttonExtDescription =
445 new wxButton(m_panelBasicProperties, ID_BTN_DESC_BASIC, _T("..."),
446 wxDefaultPosition, wxSize(GetCharHeight() * 15 / 10, -1), 0);
447 bSizer14->Add(m_buttonExtDescription, 0, wxALL | wxEXPAND, 5);
448
449 bSizerTextProperties->Add(bSizer14, 1, wxEXPAND, 5);
450
451 bSizerInnerProperties->Add(bSizerTextProperties, 1, wxEXPAND, 5);
452
453 sbSizerProperties->Add(bSizerInnerProperties, 1, wxEXPAND, 5);
454
455 bSizerBasicProperties->Add(sbSizerProperties, 2, wxALL | wxEXPAND, 5);
456
457#ifndef __OCPN__ANDROID__ // wxSimpleHtmlListBox is broken on Android....
458 wxStaticText* staticTextLinks =
459 new wxStaticText(m_panelBasicProperties, wxID_ANY, _("Links"),
460 wxDefaultPosition, wxDefaultSize, 0);
461 bSizerTextProperties->Add(staticTextLinks, 0, wxALL, 5);
462
463 wxBoxSizer* bSizer19 = new wxBoxSizer(wxHORIZONTAL);
464 bSizerTextProperties->Add(bSizer19, 1, wxEXPAND, 5);
465
466 m_htmlList = new wxSimpleHtmlListBox(m_panelBasicProperties, wxID_ANY,
467 wxDefaultPosition, wxDefaultSize, 0);
468 bSizer19->Add(m_htmlList, 1, wxALL | wxEXPAND, 5);
469#else
470
471 sbSizerLinks = new wxStaticBoxSizer(
472 new wxStaticBox(m_panelBasicProperties, wxID_ANY, _("Links")),
473 wxVERTICAL);
474 bSizerBasicProperties->Add(sbSizerLinks, 1, wxALL | wxEXPAND, 5);
475
476 m_scrolledWindowLinks =
477 new wxScrolledWindow(m_panelBasicProperties, wxID_ANY, wxDefaultPosition,
478 wxSize(-1, 100), wxHSCROLL | wxVSCROLL);
479 m_scrolledWindowLinks->SetMinSize(wxSize(-1, 80));
480 m_scrolledWindowLinks->SetScrollRate(2, 2);
481 sbSizerLinks->Add(m_scrolledWindowLinks, 1, wxEXPAND | wxALL, 5);
482
483 bSizerLinks = new wxBoxSizer(wxVERTICAL);
484 m_scrolledWindowLinks->SetSizer(bSizerLinks);
485
486 m_menuLink = new wxMenu();
487 wxMenuItem* m_menuItemDelete;
488 m_menuItemDelete = new wxMenuItem(m_menuLink, wxID_ANY, wxString(_("Delete")),
489 wxEmptyString, wxITEM_NORMAL);
490 m_menuLink->Append(m_menuItemDelete);
491
492 wxMenuItem* m_menuItemEdit;
493 m_menuItemEdit = new wxMenuItem(m_menuLink, wxID_ANY, wxString(_("Edit")),
494 wxEmptyString, wxITEM_NORMAL);
495 m_menuLink->Append(m_menuItemEdit);
496
497 wxMenuItem* m_menuItemAdd;
498 m_menuItemAdd = new wxMenuItem(m_menuLink, wxID_ANY, wxString(_("Add new")),
499 wxEmptyString, wxITEM_NORMAL);
500 m_menuLink->Append(m_menuItemAdd);
501
502 wxBoxSizer* bSizer9 = new wxBoxSizer(wxHORIZONTAL);
503
504 m_buttonAddLink =
505 new wxButton(m_panelBasicProperties, wxID_ANY, _("Add new"),
506 wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT);
507 bSizer9->Add(m_buttonAddLink, 0, wxALL, 5);
508
509 m_buttonAddLink->Connect(wxEVT_COMMAND_BUTTON_CLICKED,
510 wxCommandEventHandler(MarkInfoDlg::OnAddLink), NULL,
511 this);
512
513 sbSizerLinks->Add(bSizer9, 0, wxEXPAND, 5);
514
515#endif
516
517 m_panelDescription =
518 new wxPanel(m_notebookProperties, wxID_ANY, wxDefaultPosition,
519 wxDefaultSize, wxTAB_TRAVERSAL);
520 wxBoxSizer* bSizer15;
521 bSizer15 = new wxBoxSizer(wxVERTICAL);
522
523 m_textCtrlExtDescription =
524 new wxTextCtrl(m_panelDescription, ID_DESCR_CTR_DESC, wxEmptyString,
525 wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE);
526 bSizer15->Add(m_textCtrlExtDescription, 1, wxALL | wxEXPAND, 5);
527
528 m_panelDescription->SetSizer(bSizer15);
529 m_notebookProperties->AddPage(m_panelDescription, _("Description"), false);
530
533
534 m_panelExtendedProperties = new wxScrolledWindow(
535 m_notebookProperties, wxID_ANY, wxDefaultPosition, wxDefaultSize,
536 wxHSCROLL | wxVSCROLL | wxTAB_TRAVERSAL);
537#ifdef __OCPN__ANDROID__
538 m_panelExtendedProperties->GetHandle()->setStyleSheet(
539 getAdjustedDialogStyleSheet());
540#endif
541
542 m_panelExtendedProperties->SetScrollRate(0, 2);
543
544 wxBoxSizer* fSizerExtProperties = new wxBoxSizer(wxVERTICAL);
545 m_panelExtendedProperties->SetSizer(fSizerExtProperties);
546 m_notebookProperties->AddPage(m_panelExtendedProperties, _("Extended"),
547 false);
548
549 sbSizerExtProperties = new wxStaticBoxSizer(
550 wxVERTICAL, m_panelExtendedProperties, _("Extended Properties"));
551 wxFlexGridSizer* gbSizerInnerExtProperties = new wxFlexGridSizer(3, 0, 0);
552 gbSizerInnerExtProperties->AddGrowableCol(2);
553 gbSizerInnerExtProperties->SetFlexibleDirection(wxBOTH);
554 gbSizerInnerExtProperties->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_SPECIFIED);
555
556 m_checkBoxVisible = new wxCheckBox(sbSizerExtProperties->GetStaticBox(),
557 ID_CHECKBOX_VIS_EXT, wxEmptyString);
558 gbSizerInnerExtProperties->Add(m_checkBoxVisible);
559 wxStaticText* m_staticTextVisible = new wxStaticText(
560 sbSizerExtProperties->GetStaticBox(), wxID_ANY, _("Show on chart"));
561 gbSizerInnerExtProperties->Add(m_staticTextVisible);
562 gbSizerInnerExtProperties->Add(0, 0, 1, wxEXPAND, 0);
563
564 m_checkBoxScaMin = new wxCheckBox(sbSizerExtProperties->GetStaticBox(),
565 ID_CHECKBOX_SCAMIN_VIS, wxEmptyString);
566 gbSizerInnerExtProperties->Add(m_checkBoxScaMin, 0, wxALIGN_CENTRE_VERTICAL,
567 0);
568 m_staticTextScaMin = new wxStaticText(sbSizerExtProperties->GetStaticBox(),
569 wxID_ANY, _("Show at scale > 1 :"));
570 gbSizerInnerExtProperties->Add(m_staticTextScaMin, 0, wxALIGN_CENTRE_VERTICAL,
571 0);
572 m_textScaMin = new wxTextCtrl(sbSizerExtProperties->GetStaticBox(), wxID_ANY);
573 gbSizerInnerExtProperties->Add(m_textScaMin, 0, wxALL | wxEXPAND, 5);
574
575 m_checkBoxShowNameExt =
576 new wxCheckBox(sbSizerExtProperties->GetStaticBox(),
577 ID_SHOWNAMECHECKBOX_EXT, wxEmptyString);
578 gbSizerInnerExtProperties->Add(m_checkBoxShowNameExt);
579 m_staticTextShowNameExt = new wxStaticText(
580 sbSizerExtProperties->GetStaticBox(), wxID_ANY, _("Show waypoint name"));
581 gbSizerInnerExtProperties->Add(m_staticTextShowNameExt);
582 gbSizerInnerExtProperties->Add(0, 0, 1, wxEXPAND, 0);
583
584 sbRangeRingsExtProperties = new wxStaticBoxSizer(
585 wxVERTICAL, sbSizerExtProperties->GetStaticBox(), _("Range rings"));
586 wxFlexGridSizer* gbRRExtProperties = new wxFlexGridSizer(4, 0, 0);
587 gbRRExtProperties->AddGrowableCol(0);
588 gbRRExtProperties->AddGrowableCol(1);
589 gbRRExtProperties->AddGrowableCol(3);
590 m_staticTextRR1 = new wxStaticText(sbSizerExtProperties->GetStaticBox(),
591 wxID_ANY, _("Number"));
592 gbRRExtProperties->Add(m_staticTextRR1, 0, wxLEFT, 5);
593 m_staticTextRR2 = new wxStaticText(sbSizerExtProperties->GetStaticBox(),
594 wxID_ANY, _("Distance"));
595 gbRRExtProperties->Add(m_staticTextRR2, 0, wxLEFT, 5);
596 gbRRExtProperties->Add(0, 0, 1, wxEXPAND, 5); // a spacer
597 m_staticTextRR4 = new wxStaticText(sbSizerExtProperties->GetStaticBox(),
598 wxID_ANY, _("Color"));
599 gbRRExtProperties->Add(m_staticTextRR4, 0, wxLEFT, 5);
600
601 wxString rrAlt[] = {_("None"), _T( "1" ), _T( "2" ), _T( "3" ),
602 _T( "4" ), _T( "5" ), _T( "6" ), _T( "7" ),
603 _T( "8" ), _T( "9" ), _T( "10" )};
604 m_ChoiceWaypointRangeRingsNumber =
605 new wxChoice(sbSizerExtProperties->GetStaticBox(), ID_WPT_RANGERINGS_NO,
606 wxDefaultPosition, wxDefaultSize, 11, rrAlt);
607
608 gbRRExtProperties->Add(m_ChoiceWaypointRangeRingsNumber, 0, wxALL | wxEXPAND,
609 5);
610 m_textWaypointRangeRingsStep =
611 new wxTextCtrl(sbSizerExtProperties->GetStaticBox(), wxID_ANY, _("0.05"),
612 wxDefaultPosition, wxDefaultSize, 0);
613 gbRRExtProperties->Add(m_textWaypointRangeRingsStep, 0, wxALL | wxEXPAND, 5);
614
615 wxString pDistUnitsStrings[] = {_("NMi"), _("km")};
616 m_RangeRingUnits =
617 new wxChoice(sbSizerExtProperties->GetStaticBox(), wxID_ANY,
618 wxDefaultPosition, wxDefaultSize, 2, pDistUnitsStrings);
619 gbRRExtProperties->Add(m_RangeRingUnits, 0, wxALIGN_CENTRE_VERTICAL, 0);
620
621 m_PickColor = new wxColourPickerCtrl(sbSizerExtProperties->GetStaticBox(),
622 wxID_ANY, wxColour(0, 0, 0),
623 wxDefaultPosition, wxDefaultSize, 0);
624 gbRRExtProperties->Add(m_PickColor, 0, wxALL | wxEXPAND, 5);
625 sbRangeRingsExtProperties->Add(
626 gbRRExtProperties, 1,
627 wxLEFT | wxTOP | wxEXPAND | wxALIGN_LEFT | wxALIGN_TOP, 5);
628
629 sbSizerExtProperties->GetStaticBox()->Layout();
630
631 wxFlexGridSizer* gbSizerInnerExtProperties2 = new wxFlexGridSizer(2, 0, 0);
632 gbSizerInnerExtProperties2->AddGrowableCol(1);
633
634 m_staticTextGuid =
635 new wxStaticText(sbSizerExtProperties->GetStaticBox(), wxID_ANY,
636 _("GUID"), wxDefaultPosition, wxDefaultSize, 0);
637 gbSizerInnerExtProperties2->Add(m_staticTextGuid, 0, wxALIGN_CENTRE_VERTICAL,
638 0);
639 m_textCtrlGuid = new wxTextCtrl(sbSizerExtProperties->GetStaticBox(),
640 wxID_ANY, wxEmptyString, wxDefaultPosition,
641 wxDefaultSize, wxTE_READONLY);
642 m_textCtrlGuid->SetEditable(false);
643 gbSizerInnerExtProperties2->Add(m_textCtrlGuid, 0, wxALL | wxEXPAND, 5);
644
645 wxFlexGridSizer* gbSizerInnerExtProperties1 = new wxFlexGridSizer(3, 0, 0);
646 gbSizerInnerExtProperties1->AddGrowableCol(1);
647
648 m_staticTextTideStation =
649 new wxStaticText(sbSizerExtProperties->GetStaticBox(), wxID_ANY,
650 _("Tide Station"), wxDefaultPosition, wxDefaultSize, 0);
651 gbSizerInnerExtProperties1->Add(m_staticTextTideStation, 0,
652 wxALIGN_CENTRE_VERTICAL, 5);
653
654#ifdef __OCPN__ANDROID__
655 m_choiceTideChoices.Add(_T(" "));
656 m_comboBoxTideStation =
657 new wxChoice(sbSizerExtProperties->GetStaticBox(), wxID_ANY,
658 wxDefaultPosition, wxDefaultSize, m_choiceTideChoices);
659
660 gbSizerInnerExtProperties1->Add(
661 m_comboBoxTideStation, 0, wxALL | wxEXPAND | wxALIGN_CENTRE_VERTICAL, 5);
662
663#else
664 m_comboBoxTideStation = new wxComboBox(
665 sbSizerExtProperties->GetStaticBox(), wxID_ANY, wxEmptyString,
666 wxDefaultPosition, wxDefaultSize, 0, NULL, wxCB_READONLY);
667 gbSizerInnerExtProperties1->Add(
668 m_comboBoxTideStation, 0, wxALL | wxEXPAND | wxALIGN_CENTRE_VERTICAL, 5);
669#endif
670
671 m_buttonShowTides = new wxBitmapButton(
672 sbSizerExtProperties->GetStaticBox(), ID_BTN_SHOW_TIDES, m_bmTide,
673 wxDefaultPosition, m_bmTide.GetSize(), 0);
674 gbSizerInnerExtProperties1->Add(m_buttonShowTides, 0,
675 wxALL | wxALIGN_CENTRE_VERTICAL, 5);
676
677 m_staticTextArrivalRadius = new wxStaticText(
678 sbSizerExtProperties->GetStaticBox(), wxID_ANY, _("Arrival Radius"));
679 gbSizerInnerExtProperties1->Add(m_staticTextArrivalRadius, 0,
680 wxALIGN_CENTRE_VERTICAL, 0);
681 m_textArrivalRadius =
682 new wxTextCtrl(sbSizerExtProperties->GetStaticBox(), wxID_ANY,
683 wxEmptyString, wxDefaultPosition, wxDefaultSize, 0);
684 gbSizerInnerExtProperties1->Add(m_textArrivalRadius, 0, wxALL | wxEXPAND, 5);
685 m_staticTextArrivalUnits =
686 new wxStaticText(sbSizerExtProperties->GetStaticBox(), wxID_ANY,
687 wxEmptyString, wxDefaultPosition, wxDefaultSize, 0);
688 gbSizerInnerExtProperties1->Add(m_staticTextArrivalUnits, 0,
689 wxALIGN_CENTRE_VERTICAL, 0);
690
691 m_staticTextPlSpeed =
692 new wxStaticText(sbSizerExtProperties->GetStaticBox(), wxID_ANY,
693 _("Planned Speed"), wxDefaultPosition, wxDefaultSize, 0);
694 gbSizerInnerExtProperties1->Add(m_staticTextPlSpeed, 0,
695 wxALIGN_CENTRE_VERTICAL, 0);
696 m_textCtrlPlSpeed =
697 new wxTextCtrl(sbSizerExtProperties->GetStaticBox(), wxID_ANY,
698 wxEmptyString, wxDefaultPosition, wxDefaultSize, 0);
699 gbSizerInnerExtProperties1->Add(m_textCtrlPlSpeed, 0, wxALL | wxEXPAND, 5);
700 m_staticTextPlSpeedUnits =
701 new wxStaticText(sbSizerExtProperties->GetStaticBox(), wxID_ANY,
702 getUsrSpeedUnit(), wxDefaultPosition, wxDefaultSize, 0);
703 gbSizerInnerExtProperties1->Add(m_staticTextPlSpeedUnits, 0,
704 wxALIGN_CENTRE_VERTICAL, 0);
705
706 m_staticTextEta = new wxStaticText(sbSizerExtProperties->GetStaticBox(),
707 wxID_ANY, _("ETD (UTC)"));
708 gbSizerInnerExtProperties1->Add(m_staticTextEta, 0, wxALIGN_CENTRE_VERTICAL,
709 0);
710 wxBoxSizer* bsTimestamp = new wxBoxSizer(wxHORIZONTAL);
711 m_cbEtaPresent = new wxCheckBox(sbSizerExtProperties->GetStaticBox(),
712 wxID_ANY, wxEmptyString);
713 bsTimestamp->Add(m_cbEtaPresent, 0, wxALL | wxEXPAND, 5);
714 m_EtaDatePickerCtrl = new wxDatePickerCtrl(
715 sbSizerExtProperties->GetStaticBox(), ID_ETA_DATEPICKERCTRL,
716 wxDefaultDateTime, wxDefaultPosition, wxDefaultSize, wxDP_DEFAULT,
717 wxDefaultValidator);
718 bsTimestamp->Add(m_EtaDatePickerCtrl, 0, wxALL | wxEXPAND, 5);
719
720#ifdef __WXGTK__
721 m_EtaTimePickerCtrl =
722 new TimeCtrl(sbSizerExtProperties->GetStaticBox(), ID_ETA_TIMEPICKERCTRL,
723 wxDefaultDateTime, wxDefaultPosition, wxDefaultSize);
724#else
725 m_EtaTimePickerCtrl = new wxTimePickerCtrl(
726 sbSizerExtProperties->GetStaticBox(), ID_ETA_TIMEPICKERCTRL,
727 wxDefaultDateTime, wxDefaultPosition, wxDefaultSize, wxDP_DEFAULT,
728 wxDefaultValidator);
729#endif
730
731 bsTimestamp->Add(m_EtaTimePickerCtrl, 0, wxALL | wxEXPAND, 5);
732 gbSizerInnerExtProperties1->Add(bsTimestamp, 0, wxEXPAND, 0);
733 sbSizerExtProperties->Add(gbSizerInnerExtProperties, 0, wxALL | wxEXPAND, 5);
734 sbSizerExtProperties->Add(sbRangeRingsExtProperties, 0, wxALL | wxEXPAND, 5);
735 sbSizerExtProperties->Add(gbSizerInnerExtProperties2, 0, wxALL | wxEXPAND, 5);
736 sbSizerExtProperties->Add(gbSizerInnerExtProperties1, 0, wxALL | wxEXPAND, 5);
737
738 fSizerExtProperties->Add(sbSizerExtProperties, 1, wxALL | wxEXPAND);
739
740 //-----------------
741 bSizer1->Add(m_notebookProperties, 1, wxEXPAND | wxALL, 5);
742
743 wxBoxSizer* btnSizer = new wxBoxSizer(wxHORIZONTAL);
744 bSizer1->Add(btnSizer, 0, wxEXPAND, 0);
745
746 DefaultsBtn =
747 new wxBitmapButton(this, ID_DEFAULT, _img_MUI_settings_svg,
748 wxDefaultPosition, _img_MUI_settings_svg.GetSize(), 0);
749 btnSizer->Add(DefaultsBtn, 0, wxALL | wxALIGN_LEFT | wxALIGN_BOTTOM, 5);
750 btnSizer->Add(0, 0, 1, wxEXPAND); // spacer
751
752 m_sdbSizerButtons = new wxStdDialogButtonSizer();
753 m_sdbSizerButtons->AddButton(new wxButton(this, wxID_OK));
754 m_sdbSizerButtons->AddButton(new wxButton(this, wxID_CANCEL, _("Cancel")));
755 m_sdbSizerButtons->Realize();
756 btnSizer->Add(m_sdbSizerButtons, 0, wxALL, 5);
757
758 // SetMinSize(wxSize(-1, 600));
759
760 // Connect Events
761 m_textLatitude->Connect(
762 wxEVT_CONTEXT_MENU,
763 wxCommandEventHandler(MarkInfoDlg::OnRightClickLatLon), NULL, this);
764 m_textLongitude->Connect(
765 wxEVT_CONTEXT_MENU,
766 wxCommandEventHandler(MarkInfoDlg::OnRightClickLatLon), NULL, this);
767#ifndef __OCPN__ANDROID__ // wxSimpleHtmlListBox is broken on Android....
768 m_htmlList->Connect(wxEVT_RIGHT_DOWN,
769 wxMouseEventHandler(MarkInfoDlg::m_htmlListContextMenu),
770 NULL, this);
771#else
772#endif
773 m_notebookProperties->Connect(
774 wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED,
775 wxNotebookEventHandler(MarkInfoDlg::OnNotebookPageChanged), NULL, this);
776 // m_EtaTimePickerCtrl->Connect( wxEVT_TIME_CHANGED, wxDateEventHandler(
777 // MarkInfoDlg::OnTimeChanged ), NULL, this ); m_EtaDatePickerCtrl->Connect(
778 // wxEVT_DATE_CHANGED, wxDateEventHandler( MarkInfoDlg::OnTimeChanged ), NULL,
779 // this );
780 m_comboBoxTideStation->Connect(
781 wxEVT_COMMAND_COMBOBOX_SELECTED,
782 wxCommandEventHandler(MarkInfoDlg::OnTideStationCombobox), NULL, this);
783}
784
785void MarkInfoDlg::OnClose(wxCloseEvent& event) {
786 Hide();
787 event.Veto();
788 if (m_pRoutePoint) m_pRoutePoint->m_bRPIsBeingEdited = false;
789}
790
791#define TIDESTATION_BATCH_SIZE 10
792
793void MarkInfoDlg::OnTideStationCombobox(wxCommandEvent& event) {
794 int count = m_comboBoxTideStation->GetCount();
795 int sel = m_comboBoxTideStation->GetSelection();
796 if (sel == count - 1) {
797 wxString n;
798 int i = 0;
799 for (auto ts : m_tss) {
800 if (i == count + TIDESTATION_BATCH_SIZE) {
801 break;
802 }
803 if (i > count) {
804 n = wxString::FromUTF8(ts.second->IDX_station_name);
805 m_comboBoxTideStation->Append(n);
806 }
807 i++;
808 }
809 }
810}
811
812void MarkInfoDlg::OnNotebookPageChanged(wxNotebookEvent& event) {
813 if (event.GetSelection() == EXTENDED_PROP_PAGE) {
814 if (m_lasttspos.IsSameAs(m_textLatitude->GetValue() +
815 m_textLongitude->GetValue())) {
816 return;
817 }
818 m_lasttspos = m_textLatitude->GetValue() + m_textLongitude->GetValue();
819 double lat = fromDMM(m_textLatitude->GetValue());
820 double lon = fromDMM(m_textLongitude->GetValue());
821 m_tss = ptcmgr->GetStationsForLL(lat, lon);
822 wxString s = m_comboBoxTideStation->GetStringSelection();
823 wxString n;
824 int i = 0;
825 m_comboBoxTideStation->Clear();
826 m_comboBoxTideStation->Append(wxEmptyString);
827 for (auto ts : m_tss) {
828 if (i == TIDESTATION_BATCH_SIZE) {
829 break;
830 }
831 i++;
832 n = wxString::FromUTF8(ts.second->IDX_station_name);
833 m_comboBoxTideStation->Append(n);
834 if (s == n) {
835 m_comboBoxTideStation->SetSelection(i);
836 }
837 }
838 if (m_comboBoxTideStation->GetStringSelection() != s) {
839 m_comboBoxTideStation->Insert(s, 1);
840 m_comboBoxTideStation->SetSelection(1);
841 }
842 }
843}
844
845void MarkInfoDlg::RecalculateSize(void) {
846#ifdef __OCPN__ANDROID__
847
848 Layout();
849
850 wxSize dsize = GetParent()->GetClientSize();
851
852 wxSize esize;
853
854 esize.x = GetCharHeight() * 20;
855 esize.y = GetCharHeight() * 40;
856 // qDebug() << "esizeA" << esize.x << esize.y;
857
858 esize.y = wxMin(esize.y, dsize.y - (2 * GetCharHeight()));
859 esize.x = wxMin(esize.x, dsize.x - (1 * GetCharHeight()));
860 SetSize(wxSize(esize.x, esize.y));
861 // qDebug() << "esize" << esize.x << esize.y;
862
863 wxSize fsize = GetSize();
864 fsize.y = wxMin(fsize.y, dsize.y - (2 * GetCharHeight()));
865 fsize.x = wxMin(fsize.x, dsize.x - (1 * GetCharHeight()));
866 // qDebug() << "fsize" << fsize.x << fsize.y;
867
868 // And finally, not too tall...
869 fsize.y = wxMin(fsize.y, (25 * GetCharHeight()));
870
871 SetSize(wxSize(-1, fsize.y));
872
873 m_defaultClientSize = GetClientSize();
874 Center();
875#endif
876}
877
878MarkInfoDlg::~MarkInfoDlg() {
879 // Disconnect Events
880 m_textLatitude->Disconnect(
881 wxEVT_CONTEXT_MENU,
882 wxCommandEventHandler(MarkInfoDlg::OnRightClickLatLon), NULL, this);
883 m_textLongitude->Disconnect(
884 wxEVT_CONTEXT_MENU,
885 wxCommandEventHandler(MarkInfoDlg::OnRightClickLatLon), NULL, this);
886#ifndef __OCPN__ANDROID__ // wxSimpleHtmlListBox is broken on Android....
887 m_htmlList->Disconnect(
888 wxEVT_RIGHT_DOWN, wxMouseEventHandler(MarkInfoDlg::m_htmlListContextMenu),
889 NULL, this);
890#else
891#endif
892
893 m_notebookProperties->Disconnect(
894 wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED,
895 wxNotebookEventHandler(MarkInfoDlg::OnNotebookPageChanged), NULL, this);
896 m_EtaTimePickerCtrl->Disconnect(
897 wxEVT_TIME_CHANGED, wxDateEventHandler(MarkInfoDlg::OnTimeChanged), NULL,
898 this);
899 m_EtaDatePickerCtrl->Disconnect(
900 wxEVT_DATE_CHANGED, wxDateEventHandler(MarkInfoDlg::OnTimeChanged), NULL,
901 this);
902
903#ifdef __OCPN__ANDROID__
904 androidEnableBackButton(true);
905#endif
906}
907
908void MarkInfoDlg::InitialFocus(void) {
909 m_textName->SetFocus();
910 m_textName->SetInsertionPointEnd();
911}
912
913void MarkInfoDlg::SetColorScheme(ColorScheme cs) { DimeControl(this); }
914
915void MarkInfoDlg::SetRoutePoint(RoutePoint* pRP) {
916 m_pRoutePoint = pRP;
917 if (m_pRoutePoint) {
918 m_lat_save = m_pRoutePoint->m_lat;
919 m_lon_save = m_pRoutePoint->m_lon;
920 m_IconName_save = m_pRoutePoint->GetIconName();
921 m_bShowName_save = m_pRoutePoint->m_bShowName;
922 m_bIsVisible_save = m_pRoutePoint->m_bIsVisible;
923 m_Name_save = m_pRoutePoint->GetName();
924 m_Description_save = m_pRoutePoint->m_MarkDescription;
925 m_bUseScaMin_save = m_pRoutePoint->GetUseSca();
926 m_iScaminVal_save = m_pRoutePoint->GetScaMin();
927
928 if (m_pMyLinkList) delete m_pMyLinkList;
929 m_pMyLinkList = new HyperlinkList();
930 int NbrOfLinks = m_pRoutePoint->m_HyperlinkList->GetCount();
931 if (NbrOfLinks > 0) {
932 wxHyperlinkListNode* linknode =
933 m_pRoutePoint->m_HyperlinkList->GetFirst();
934 while (linknode) {
935 Hyperlink* link = linknode->GetData();
936
937 Hyperlink* h = new Hyperlink();
938 h->DescrText = link->DescrText;
939 h->Link = link->Link;
940 h->LType = link->LType;
941
942 m_pMyLinkList->Append(h);
943
944 linknode = linknode->GetNext();
945 }
946 }
947 }
948}
949
950void MarkInfoDlg::UpdateHtmlList() {
951#ifndef __OCPN__ANDROID__ // wxSimpleHtmlListBox is broken on Android....
952 GetSimpleBox()->Clear();
953 int NbrOfLinks = m_pRoutePoint->m_HyperlinkList->GetCount();
954
955 if (NbrOfLinks > 0) {
956 wxHyperlinkListNode* linknode = m_pRoutePoint->m_HyperlinkList->GetFirst();
957 while (linknode) {
958 Hyperlink* link = linknode->GetData();
959 wxString s = wxString::Format(wxT("<a href='%s'>%s</a>"), link->Link,
960 link->DescrText);
961 GetSimpleBox()->AppendString(s);
962 linknode = linknode->GetNext();
963 }
964 }
965#else
966 // Clear the list
967 wxWindowList kids = m_scrolledWindowLinks->GetChildren();
968 for (unsigned int i = 0; i < kids.GetCount(); i++) {
969 wxWindowListNode* node = kids.Item(i);
970 wxWindow* win = node->GetData();
971
972 if (win->IsKindOf(CLASSINFO(wxHyperlinkCtrl))) {
973 ((wxHyperlinkCtrl*)win)
974 ->Disconnect(wxEVT_COMMAND_HYPERLINK,
975 wxHyperlinkEventHandler(MarkInfoDlg::OnHyperLinkClick));
976 ((wxHyperlinkCtrl*)win)
977 ->Disconnect(wxEVT_RIGHT_DOWN,
978 wxMouseEventHandler(MarkInfoDlg::m_htmlListContextMenu));
979 win->Destroy();
980 }
981 }
982
983 int NbrOfLinks = m_pRoutePoint->m_HyperlinkList->GetCount();
984 HyperlinkList* hyperlinklist = m_pRoutePoint->m_HyperlinkList;
985 if (NbrOfLinks > 0) {
986 wxHyperlinkListNode* linknode = hyperlinklist->GetFirst();
987 while (linknode) {
988 Hyperlink* link = linknode->GetData();
989 wxString Link = link->Link;
990 wxString Descr = link->DescrText;
991
992 wxHyperlinkCtrl* ctrl = new wxHyperlinkCtrl(
993 m_scrolledWindowLinks, wxID_ANY, Descr, Link, wxDefaultPosition,
994 wxDefaultSize, wxNO_BORDER | wxHL_CONTEXTMENU | wxHL_ALIGN_LEFT);
995 ctrl->Connect(wxEVT_COMMAND_HYPERLINK,
996 wxHyperlinkEventHandler(MarkInfoDlg::OnHyperLinkClick),
997 NULL, this);
998 if (!m_pRoutePoint->m_bIsInLayer)
999 ctrl->Connect(wxEVT_RIGHT_DOWN,
1000 wxMouseEventHandler(MarkInfoDlg::m_htmlListContextMenu),
1001 NULL, this);
1002
1003 bSizerLinks->Add(ctrl, 1, wxALL | wxEXPAND, 5);
1004
1005 linknode = linknode->GetNext();
1006 }
1007 }
1008
1009 // Integrate all of the rebuilt hyperlink controls
1010 m_scrolledWindowLinks->Layout();
1011#endif
1012}
1013
1014void MarkInfoDlg::OnHyperLinkClick(wxHyperlinkEvent& event) {
1015 wxString url = event.GetURL();
1016 url.Replace(_T(" "), _T("%20"));
1017 if (g_Platform) g_Platform->platformLaunchDefaultBrowser(url);
1018}
1019
1020void MarkInfoDlg::OnHtmlLinkClicked(wxHtmlLinkEvent& event) {
1021 // Windows has trouble handling local file URLs with embedded anchor
1022 // points, e.g file://testfile.html#point1 The trouble is with the
1023 // wxLaunchDefaultBrowser with verb "open" Workaround is to probe the
1024 // registry to get the default browser, and open directly
1025 //
1026 // But, we will do this only if the URL contains the anchor point
1027 // character '#' What a hack......
1028
1029#ifdef __WXMSW__
1030 wxString cc = event.GetLinkInfo().GetHref().c_str();
1031 if (cc.Find(_T("#")) != wxNOT_FOUND) {
1032 wxRegKey RegKey(
1033 wxString(_T("HKEY_CLASSES_ROOT\\HTTP\\shell\\open\\command")));
1034 if (RegKey.Exists()) {
1035 wxString command_line;
1036 RegKey.QueryValue(wxString(_T("")), command_line);
1037
1038 // Remove "
1039 command_line.Replace(wxString(_T("\"")), wxString(_T("")));
1040
1041 // Strip arguments
1042 int l = command_line.Find(_T(".exe"));
1043 if (wxNOT_FOUND == l) l = command_line.Find(_T(".EXE"));
1044
1045 if (wxNOT_FOUND != l) {
1046 wxString cl = command_line.Mid(0, l + 4);
1047 cl += _T(" ");
1048 cc.Prepend(_T("\""));
1049 cc.Append(_T("\""));
1050 cl += cc;
1051 wxExecute(cl); // Async, so Fire and Forget...
1052 }
1053 }
1054 } else {
1055 wxString url = event.GetLinkInfo().GetHref().c_str();
1056 url.Replace(_T(" "), _T("%20"));
1057 ::wxLaunchDefaultBrowser(url);
1058 event.Skip();
1059 }
1060#else
1061 wxString url = event.GetLinkInfo().GetHref().c_str();
1062 url.Replace(_T(" "), _T("%20"));
1063 if (g_Platform) g_Platform->platformLaunchDefaultBrowser(url);
1064
1065 event.Skip();
1066#endif
1067}
1068
1069void MarkInfoDlg::OnDescChangedExt(wxCommandEvent& event) {
1070 if (m_panelDescription->IsShownOnScreen()) {
1071 m_textDescription->ChangeValue(m_textCtrlExtDescription->GetValue());
1072 }
1073 event.Skip();
1074}
1075void MarkInfoDlg::OnDescChangedBasic(wxCommandEvent& event) {
1076 if (m_panelBasicProperties->IsShownOnScreen()) {
1077 m_textCtrlExtDescription->ChangeValue(m_textDescription->GetValue());
1078 }
1079 event.Skip();
1080}
1081
1082void MarkInfoDlg::OnExtDescriptionClick(wxCommandEvent& event) {
1083 long pos = m_textDescription->GetInsertionPoint();
1084 m_notebookProperties->SetSelection(1);
1085 m_textCtrlExtDescription->SetInsertionPoint(pos);
1086 event.Skip();
1087}
1088
1089void MarkInfoDlg::OnShowWaypointNameSelectBasic(wxCommandEvent& event) {
1090 if (m_panelBasicProperties->IsShownOnScreen())
1091 m_checkBoxShowNameExt->SetValue(m_checkBoxShowName->GetValue());
1092 event.Skip();
1093}
1094void MarkInfoDlg::OnShowWaypointNameSelectExt(wxCommandEvent& event) {
1095 if (m_panelExtendedProperties->IsShownOnScreen())
1096 m_checkBoxShowName->SetValue(m_checkBoxShowNameExt->GetValue());
1097 event.Skip();
1098}
1099
1100void MarkInfoDlg::OnWptRangeRingsNoChange(wxCommandEvent& event) {
1101 if (!m_pRoutePoint->m_bIsInLayer) {
1102 m_textWaypointRangeRingsStep->Enable(
1103 (bool)(m_ChoiceWaypointRangeRingsNumber->GetSelection() != 0));
1104 m_PickColor->Enable(
1105 (bool)(m_ChoiceWaypointRangeRingsNumber->GetSelection() != 0));
1106 }
1107}
1108
1109void MarkInfoDlg::OnSelectScaMinExt(wxCommandEvent& event) {
1110 if (!m_pRoutePoint->m_bIsInLayer) {
1111 m_textScaMin->Enable(m_checkBoxScaMin->GetValue());
1112 }
1113}
1114
1115void MarkInfoDlg::OnPositionCtlUpdated(wxCommandEvent& event) {
1116 // Fetch the control values, convert to degrees
1117 double lat = fromDMM(m_textLatitude->GetValue());
1118 double lon = fromDMM(m_textLongitude->GetValue());
1119 if (!m_pRoutePoint->m_bIsInLayer) {
1120 m_pRoutePoint->SetPosition(lat, lon);
1121 pSelect->ModifySelectablePoint(lat, lon, (void*)m_pRoutePoint,
1122 SELTYPE_ROUTEPOINT);
1123 }
1124 // Update the mark position dynamically
1125 gFrame->RefreshAllCanvas();
1126}
1127
1128void MarkInfoDlg::m_htmlListContextMenu(wxMouseEvent& event) {
1129#ifndef __OCPN__ANDROID__
1130 // SimpleHtmlList->HitTest doesn't seem to work under msWin, so we use a
1131 // custom made version
1132 wxPoint pos = event.GetPosition();
1133 i_htmlList_item = -1;
1134 for (int i = 0; i < (int)GetSimpleBox()->GetCount(); i++) {
1135 wxRect rect = GetSimpleBox()->GetItemRect(i);
1136 if (rect.Contains(pos)) {
1137 i_htmlList_item = i;
1138 break;
1139 }
1140 }
1141
1142 wxMenu* popup = new wxMenu();
1143 if ((GetSimpleBox()->GetCount()) > 0 && (i_htmlList_item > -1) &&
1144 (i_htmlList_item < (int)GetSimpleBox()->GetCount())) {
1145 popup->Append(ID_RCLK_MENU_DELETE_LINK, _("Delete"));
1146 popup->Append(ID_RCLK_MENU_EDIT_LINK, _("Edit"));
1147 }
1148 popup->Append(ID_RCLK_MENU_ADD_LINK, _("Add New"));
1149
1150 m_contextObject = event.GetEventObject();
1151 popup->Connect(
1152 wxEVT_COMMAND_MENU_SELECTED,
1153 wxCommandEventHandler(MarkInfoDlg::On_html_link_popupmenu_Click), NULL,
1154 this);
1155 PopupMenu(popup);
1156 delete popup;
1157#else
1158
1159 m_pEditedLink = wxDynamicCast(event.GetEventObject(), wxHyperlinkCtrl);
1160
1161 if (m_pEditedLink) {
1162 wxString url = m_pEditedLink->GetURL();
1163 wxString label = m_pEditedLink->GetLabel();
1164 i_htmlList_item = -1;
1165 HyperlinkList* hyperlinklist = m_pRoutePoint->m_HyperlinkList;
1166 if (hyperlinklist->GetCount() > 0) {
1167 int i = 0;
1168 wxHyperlinkListNode* linknode = hyperlinklist->GetFirst();
1169 while (linknode) {
1170 Hyperlink* link = linknode->GetData();
1171 if (link->DescrText == label) {
1172 i_htmlList_item = i;
1173 break;
1174 }
1175
1176 linknode = linknode->GetNext();
1177 i++;
1178 }
1179 }
1180
1181 wxFont sFont = GetOCPNGUIScaledFont(_T("Menu"));
1182
1183 wxMenu* popup = new wxMenu();
1184 {
1185 wxMenuItem* menuItemDelete =
1186 new wxMenuItem(popup, ID_RCLK_MENU_DELETE_LINK, wxString(_("Delete")),
1187 wxEmptyString, wxITEM_NORMAL);
1188#ifdef __WXQT__
1189 menuItemDelete->SetFont(sFont);
1190#endif
1191 popup->Append(menuItemDelete);
1192
1193 wxMenuItem* menuItemEdit =
1194 new wxMenuItem(popup, ID_RCLK_MENU_EDIT_LINK, wxString(_("Edit")),
1195 wxEmptyString, wxITEM_NORMAL);
1196#ifdef __WXQT__
1197 menuItemEdit->SetFont(sFont);
1198#endif
1199 popup->Append(menuItemEdit);
1200 }
1201
1202 wxMenuItem* menuItemAdd =
1203 new wxMenuItem(popup, ID_RCLK_MENU_ADD_LINK, wxString(_("Add New")),
1204 wxEmptyString, wxITEM_NORMAL);
1205#ifdef __WXQT__
1206 menuItemAdd->SetFont(sFont);
1207#endif
1208 popup->Append(menuItemAdd);
1209
1210 m_contextObject = event.GetEventObject();
1211 popup->Connect(
1212 wxEVT_COMMAND_MENU_SELECTED,
1213 wxCommandEventHandler(MarkInfoDlg::On_html_link_popupmenu_Click), NULL,
1214 this);
1215 wxPoint p = m_scrolledWindowLinks->GetPosition();
1216 p.x += m_scrolledWindowLinks->GetSize().x / 2;
1217 PopupMenu(popup, p);
1218 delete popup;
1219
1220 // m_scrolledWindowLinks->PopupMenu( m_menuLink,
1221 // m_pEditedLink->GetPosition().x /*+ event.GetPosition().x*/,
1222 // m_pEditedLink->GetPosition().y /*+ event.GetPosition().y*/ );
1223 }
1224/*
1225 wxPoint pos = event.GetPosition();
1226 i_htmlList_item = -1;
1227 for( int i=0; i < (int)GetSimpleBox()->GetCount(); i++ )
1228 {
1229 wxRect rect = GetSimpleBox()->GetItemRect( i );
1230 if( rect.Contains( pos) ){
1231 i_htmlList_item = i;
1232 break;
1233 }
1234 }
1235
1236 */
1237#endif
1238}
1239
1240void MarkInfoDlg::OnAddLink(wxCommandEvent& event) {
1241 wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED);
1242 evt.SetId(ID_RCLK_MENU_ADD_LINK);
1243
1244 On_html_link_popupmenu_Click(evt);
1245}
1246
1247void MarkInfoDlg::On_html_link_popupmenu_Click(wxCommandEvent& event) {
1248 switch (event.GetId()) {
1249 case ID_RCLK_MENU_DELETE_LINK: {
1250 wxHyperlinkListNode* node =
1251 m_pRoutePoint->m_HyperlinkList->Item(i_htmlList_item);
1252 m_pRoutePoint->m_HyperlinkList->DeleteNode(node);
1253 UpdateHtmlList();
1254 break;
1255 }
1256 case ID_RCLK_MENU_EDIT_LINK: {
1257 Hyperlink* link =
1258 m_pRoutePoint->m_HyperlinkList->Item(i_htmlList_item)->GetData();
1259 LinkPropImpl* LinkPropDlg = new LinkPropImpl(this);
1260 LinkPropDlg->m_textCtrlLinkDescription->SetValue(link->DescrText);
1261 LinkPropDlg->m_textCtrlLinkUrl->SetValue(link->Link);
1262 DimeControl(LinkPropDlg);
1263 LinkPropDlg->ShowWindowModalThenDo([this, LinkPropDlg,
1264 link](int retcode) {
1265 if (retcode == wxID_OK) {
1266 link->DescrText = LinkPropDlg->m_textCtrlLinkDescription->GetValue();
1267 link->Link = LinkPropDlg->m_textCtrlLinkUrl->GetValue();
1268 m_pRoutePoint->m_HyperlinkList->Item(i_htmlList_item)->SetData(link);
1269 UpdateHtmlList();
1270 }
1271 });
1272 break;
1273 }
1274 case ID_RCLK_MENU_ADD_LINK: {
1275 LinkPropImpl* LinkPropDlg = new LinkPropImpl(this);
1276 LinkPropDlg->m_textCtrlLinkDescription->SetValue(wxEmptyString);
1277 LinkPropDlg->m_textCtrlLinkUrl->SetValue(wxEmptyString);
1278 DimeControl(LinkPropDlg);
1279 LinkPropDlg->ShowWindowModalThenDo([this, LinkPropDlg](int retcode) {
1280 if (retcode == wxID_OK) {
1281 Hyperlink* link = new Hyperlink;
1282 link->DescrText = LinkPropDlg->m_textCtrlLinkDescription->GetValue();
1283 link->Link = LinkPropDlg->m_textCtrlLinkUrl->GetValue();
1284 // Check if decent
1285 if (link->DescrText == wxEmptyString) {
1286 link->DescrText = link->Link;
1287 }
1288 if (link->Link == wxEmptyString) {
1289 delete link;
1290 } else {
1291 m_pRoutePoint->m_HyperlinkList->Append(link);
1292 }
1293 UpdateHtmlList();
1294 }
1295 });
1296 break;
1297 }
1298 }
1299 event.Skip();
1300}
1301
1302void MarkInfoDlg::OnRightClickLatLon(wxCommandEvent& event) {
1303 wxMenu* popup = new wxMenu();
1304 popup->Append(ID_RCLK_MENU_COPY, _("Copy"));
1305 popup->Append(ID_RCLK_MENU_COPY_LL, _("Copy lat/long"));
1306 popup->Append(ID_RCLK_MENU_PASTE, _("Paste"));
1307 popup->Append(ID_RCLK_MENU_PASTE_LL, _("Paste lat/long"));
1308 m_contextObject = event.GetEventObject();
1309 popup->Connect(wxEVT_COMMAND_MENU_SELECTED,
1310 wxCommandEventHandler(MarkInfoDlg::OnCopyPasteLatLon), NULL,
1311 this);
1312
1313 PopupMenu(popup);
1314 delete popup;
1315}
1316
1317void MarkInfoDlg::OnCopyPasteLatLon(wxCommandEvent& event) {
1318 // Fetch the control values, convert to degrees
1319 double lat = fromDMM(m_textLatitude->GetValue());
1320 double lon = fromDMM(m_textLongitude->GetValue());
1321
1322 wxString result;
1323
1324 switch (event.GetId()) {
1325 case ID_RCLK_MENU_PASTE: {
1326 if (wxTheClipboard->Open()) {
1327 wxTextDataObject data;
1328 wxTheClipboard->GetData(data);
1329 result = data.GetText();
1330 ((wxTextCtrl*)m_contextObject)->SetValue(result);
1331 wxTheClipboard->Close();
1332 }
1333 return;
1334 }
1335 case ID_RCLK_MENU_PASTE_LL: {
1336 if (wxTheClipboard->Open()) {
1337 wxTextDataObject data;
1338 wxTheClipboard->GetData(data);
1339 result = data.GetText();
1340
1341 PositionParser pparse(result);
1342
1343 if (pparse.IsOk()) {
1344 m_textLatitude->SetValue(pparse.GetLatitudeString());
1345 m_textLongitude->SetValue(pparse.GetLongitudeString());
1346 }
1347 wxTheClipboard->Close();
1348 }
1349 return;
1350 }
1351 case ID_RCLK_MENU_COPY: {
1352 result = ((wxTextCtrl*)m_contextObject)->GetValue();
1353 break;
1354 }
1355 case ID_RCLK_MENU_COPY_LL: {
1356 result << toSDMM(1, lat, true) << _T('\t');
1357 result << toSDMM(2, lon, true);
1358 break;
1359 }
1360 }
1361
1362 if (wxTheClipboard->Open()) {
1363 wxTextDataObject* data = new wxTextDataObject;
1364 data->SetText(result);
1365 wxTheClipboard->SetData(data);
1366 wxTheClipboard->Close();
1367 }
1368}
1369
1370void MarkInfoDlg::DefautlBtnClicked(wxCommandEvent& event) {
1371 m_SaveDefaultDlg = new SaveDefaultsDialog(this);
1372 m_SaveDefaultDlg->Center();
1373 DimeControl(m_SaveDefaultDlg);
1374 int retcode = m_SaveDefaultDlg->ShowModal();
1375
1376 {
1377 if (retcode == wxID_OK) {
1378 double value;
1379 if (m_SaveDefaultDlg->IconCB->GetValue()) {
1380 g_default_wp_icon =
1381 *pWayPointMan->GetIconKey(m_bcomboBoxIcon->GetSelection());
1382 }
1383 if (m_SaveDefaultDlg->RangRingsCB->GetValue()) {
1384 g_iWaypointRangeRingsNumber =
1385 m_ChoiceWaypointRangeRingsNumber->GetSelection();
1386 if (m_textWaypointRangeRingsStep->GetValue().ToDouble(&value))
1387 g_fWaypointRangeRingsStep = fromUsrDistance(value, -1);
1388 g_colourWaypointRangeRingsColour = m_PickColor->GetColour();
1389 }
1390 if (m_SaveDefaultDlg->ArrivalRCB->GetValue())
1391 if (m_textArrivalRadius->GetValue().ToDouble(&value))
1392 g_n_arrival_circle_radius = fromUsrDistance(value, -1);
1393 if (m_SaveDefaultDlg->ScaleCB->GetValue()) {
1394 g_iWpt_ScaMin = wxAtoi(m_textScaMin->GetValue());
1395 g_bUseWptScaMin = m_checkBoxScaMin->GetValue();
1396 }
1397 if (m_SaveDefaultDlg->NameCB->GetValue()) {
1398 g_iWpt_ScaMin = m_checkBoxShowName->GetValue();
1399 }
1400 }
1401 m_SaveDefaultDlg = NULL;
1402 }
1403}
1404
1405void MarkInfoDlg::OnMarkInfoCancelClick(wxCommandEvent& event) {
1406 if (m_pRoutePoint) {
1407 m_pRoutePoint->SetVisible(m_bIsVisible_save);
1408 m_pRoutePoint->SetNameShown(m_bShowName_save);
1409 m_pRoutePoint->SetPosition(m_lat_save, m_lon_save);
1410 m_pRoutePoint->SetIconName(m_IconName_save);
1411 m_pRoutePoint->ReLoadIcon();
1412 m_pRoutePoint->SetName(m_Name_save);
1413 m_pRoutePoint->m_MarkDescription = m_Description_save;
1414 m_pRoutePoint->SetUseSca(m_bUseScaMin_save);
1415 m_pRoutePoint->SetScaMin(m_iScaminVal_save);
1416
1417 m_pRoutePoint->m_HyperlinkList->Clear();
1418
1419 int NbrOfLinks = m_pMyLinkList->GetCount();
1420 if (NbrOfLinks > 0) {
1421 wxHyperlinkListNode* linknode = m_pMyLinkList->GetFirst();
1422 while (linknode) {
1423 Hyperlink* link = linknode->GetData();
1424 Hyperlink* h = new Hyperlink();
1425 h->DescrText = link->DescrText;
1426 h->Link = link->Link;
1427 h->LType = link->LType;
1428
1429 m_pRoutePoint->m_HyperlinkList->Append(h);
1430
1431 linknode = linknode->GetNext();
1432 }
1433 }
1434 }
1435
1436 m_lasttspos.Clear();
1437
1438#ifdef __WXGTK__
1439 gFrame->Raise();
1440#endif
1441
1442 Show(false);
1443 delete m_pMyLinkList;
1444 m_pMyLinkList = NULL;
1445 SetClientSize(m_defaultClientSize);
1446
1447#ifdef __OCPN__ANDROID__
1448 androidEnableBackButton(true);
1449#endif
1450
1451 event.Skip();
1452}
1453
1454void MarkInfoDlg::OnMarkInfoOKClick(wxCommandEvent& event) {
1455 if (m_pRoutePoint) {
1456 m_pRoutePoint->m_wxcWaypointRangeRingsColour = m_PickColor->GetColour();
1457
1458 OnPositionCtlUpdated(event);
1459 SaveChanges(); // write changes to globals and update config
1460 }
1461
1462#ifdef __WXGTK__
1463 gFrame->Raise();
1464#endif
1465
1466 Show(false);
1467
1468 if (pRouteManagerDialog && pRouteManagerDialog->IsShown())
1469 pRouteManagerDialog->UpdateWptListCtrl();
1470
1471 if (pRoutePropDialog && pRoutePropDialog->IsShown())
1472 pRoutePropDialog->UpdatePoints();
1473
1474 SetClientSize(m_defaultClientSize);
1475
1476#ifdef __OCPN__ANDROID__
1477 androidEnableBackButton(true);
1478#endif
1479
1480 event.Skip();
1481}
1482
1483bool MarkInfoDlg::UpdateProperties(bool positionOnly) {
1484 if (m_pRoutePoint) {
1485 m_textLatitude->SetValue(::toSDMM(1, m_pRoutePoint->m_lat));
1486 m_textLongitude->SetValue(::toSDMM(2, m_pRoutePoint->m_lon));
1487 m_lat_save = m_pRoutePoint->m_lat;
1488 m_lon_save = m_pRoutePoint->m_lon;
1489 m_textName->SetValue(m_pRoutePoint->GetName());
1490 m_textDescription->ChangeValue(m_pRoutePoint->m_MarkDescription);
1491 m_textCtrlExtDescription->ChangeValue(m_pRoutePoint->m_MarkDescription);
1492 m_checkBoxShowName->SetValue(m_pRoutePoint->m_bShowName);
1493 m_checkBoxShowNameExt->SetValue(m_pRoutePoint->m_bShowName);
1494 m_checkBoxVisible->SetValue(m_pRoutePoint->m_bIsVisible);
1495 m_checkBoxScaMin->SetValue(m_pRoutePoint->GetUseSca());
1496 m_textScaMin->SetValue(
1497 wxString::Format(wxT("%i"), (int)m_pRoutePoint->GetScaMin()));
1498 m_textCtrlGuid->SetValue(m_pRoutePoint->m_GUID);
1499 m_ChoiceWaypointRangeRingsNumber->SetSelection(
1500 m_pRoutePoint->GetWaypointRangeRingsNumber());
1501 wxString buf;
1502 buf.Printf(_T("%.3f"),
1503 toUsrDistance(m_pRoutePoint->GetWaypointRangeRingsStep(), -1));
1504 m_textWaypointRangeRingsStep->SetValue(buf);
1505 m_staticTextArrivalUnits->SetLabel(getUsrDistanceUnit());
1506 buf.Printf(_T("%.3f"),
1507 toUsrDistance(m_pRoutePoint->GetWaypointArrivalRadius(), -1));
1508 m_textArrivalRadius->SetValue(buf);
1509
1510 int nUnits = m_pRoutePoint->GetWaypointRangeRingsStepUnits();
1511 m_RangeRingUnits->SetSelection(nUnits);
1512
1513 wxColour col = m_pRoutePoint->m_wxcWaypointRangeRingsColour;
1514 m_PickColor->SetColour(col);
1515
1516 if (m_comboBoxTideStation->GetStringSelection() !=
1517 m_pRoutePoint->m_TideStation) {
1518 m_comboBoxTideStation->Clear();
1519 m_comboBoxTideStation->Append(wxEmptyString);
1520 if (!m_pRoutePoint->m_TideStation.IsEmpty()) {
1521 m_comboBoxTideStation->Append(m_pRoutePoint->m_TideStation);
1522 m_comboBoxTideStation->SetSelection(1);
1523 }
1524 }
1525
1526 if (m_pRoutePoint->GetPlannedSpeed() > .01) {
1527 m_textCtrlPlSpeed->SetValue(wxString::Format(
1528 "%.1f", toUsrSpeed(m_pRoutePoint->GetPlannedSpeed())));
1529 } else {
1530 m_textCtrlPlSpeed->SetValue(wxEmptyString);
1531 }
1532
1533 wxDateTime etd;
1534 etd = m_pRoutePoint->GetManualETD();
1535 if (etd.IsValid()) {
1536 m_cbEtaPresent->SetValue(true);
1537 m_EtaDatePickerCtrl->SetValue(etd.GetDateOnly());
1538 m_EtaTimePickerCtrl->SetValue(etd);
1539 } else {
1540 m_cbEtaPresent->SetValue(false);
1541 }
1542
1543 m_staticTextPlSpeed->Show(m_pRoutePoint->m_bIsInRoute);
1544 m_textCtrlPlSpeed->Show(m_pRoutePoint->m_bIsInRoute);
1545 m_staticTextEta->Show(m_pRoutePoint->m_bIsInRoute);
1546 m_EtaDatePickerCtrl->Show(m_pRoutePoint->m_bIsInRoute);
1547 m_EtaTimePickerCtrl->Show(m_pRoutePoint->m_bIsInRoute);
1548 m_cbEtaPresent->Show(m_pRoutePoint->m_bIsInRoute);
1549 m_staticTextPlSpeedUnits->Show(m_pRoutePoint->m_bIsInRoute);
1550 m_staticTextArrivalRadius->Show(m_pRoutePoint->m_bIsInRoute);
1551 m_staticTextArrivalUnits->Show(m_pRoutePoint->m_bIsInRoute);
1552 m_textArrivalRadius->Show(m_pRoutePoint->m_bIsInRoute);
1553
1554 if (positionOnly) return true;
1555
1556 // Layer or not?
1557 if (m_pRoutePoint->m_bIsInLayer) {
1558 m_staticTextLayer->Enable();
1559 m_staticTextLayer->Show(true);
1560 m_textName->SetEditable(false);
1561 m_textDescription->SetEditable(false);
1562 m_textCtrlExtDescription->SetEditable(false);
1563 m_textLatitude->SetEditable(false);
1564 m_textLongitude->SetEditable(false);
1565 m_bcomboBoxIcon->Enable(false);
1566 m_checkBoxShowName->Enable(false);
1567 m_checkBoxVisible->Enable(false);
1568 m_textArrivalRadius->SetEditable(false);
1569 m_checkBoxScaMin->Enable(false);
1570 m_textScaMin->SetEditable(false);
1571 m_checkBoxShowNameExt->Enable(false);
1572 m_ChoiceWaypointRangeRingsNumber->Enable(false);
1573 m_textWaypointRangeRingsStep->SetEditable(false);
1574 m_PickColor->Enable(false);
1575 DefaultsBtn->Enable(false);
1576 m_EtaDatePickerCtrl->Enable(false);
1577 m_EtaTimePickerCtrl->Enable(false);
1578 m_cbEtaPresent->Enable(false);
1579 if (!m_textDescription->IsEmpty()) {
1580 m_notebookProperties->SetSelection(1); // Show Description page
1581 }
1582 m_comboBoxTideStation->Enable(false);
1583 } else {
1584 m_staticTextLayer->Enable(false);
1585 m_staticTextLayer->Show(false);
1586 m_textName->SetEditable(true);
1587 m_textDescription->SetEditable(true);
1588 m_textCtrlExtDescription->SetEditable(true);
1589 m_textLatitude->SetEditable(true);
1590 m_textLongitude->SetEditable(true);
1591 m_bcomboBoxIcon->Enable(true);
1592 m_checkBoxShowName->Enable(true);
1593 m_checkBoxVisible->Enable(true);
1594 m_textArrivalRadius->SetEditable(true);
1595 m_checkBoxScaMin->Enable(true);
1596 m_textScaMin->SetEditable(true);
1597 m_checkBoxShowNameExt->Enable(true);
1598 m_ChoiceWaypointRangeRingsNumber->Enable(true);
1599 m_textWaypointRangeRingsStep->SetEditable(true);
1600 m_PickColor->Enable(true);
1601 DefaultsBtn->Enable(true);
1602 m_EtaDatePickerCtrl->Enable(true);
1603 m_EtaTimePickerCtrl->Enable(true);
1604 m_cbEtaPresent->Enable(true);
1605 m_notebookProperties->SetSelection(0);
1606 m_comboBoxTideStation->Enable(true);
1607 }
1608
1609 // Fill the icon selector combo box
1610 m_bcomboBoxIcon->Clear();
1611 // Iterate on the Icon Descriptions, filling in the combo control
1612 bool fillCombo = m_bcomboBoxIcon->GetCount() == 0;
1613
1614 if (fillCombo) {
1615 for (int i = 0; i < pWayPointMan->GetNumIcons(); i++) {
1616 wxString* ps = pWayPointMan->GetIconDescription(i);
1617 wxBitmap bmp =
1618 pWayPointMan->GetIconBitmapForList(i, 2 * GetCharHeight());
1619
1620 m_bcomboBoxIcon->Append(*ps, bmp);
1621 }
1622 }
1623 // find the correct item in the combo box
1624 int iconToSelect = -1;
1625 for (int i = 0; i < pWayPointMan->GetNumIcons(); i++) {
1626 if (*pWayPointMan->GetIconKey(i) == m_pRoutePoint->GetIconName()) {
1627 iconToSelect = i;
1628 m_bcomboBoxIcon->Select(iconToSelect);
1629 break;
1630 }
1631 }
1632 wxCommandEvent ev;
1633 OnShowWaypointNameSelectBasic(ev);
1634 OnWptRangeRingsNoChange(ev);
1635 OnSelectScaMinExt(ev);
1636 UpdateHtmlList();
1637 }
1638
1639#ifdef __OCPN__ANDROID__
1640 androidEnableBackButton(false);
1641#endif
1642
1643 Fit();
1644 // SetMinSize(wxSize(-1, 600));
1645 RecalculateSize();
1646
1647 return true;
1648}
1649
1650void MarkInfoDlg::OnBitmapCombClick(wxCommandEvent& event) {
1651 wxString* icon_name =
1652 pWayPointMan->GetIconKey(m_bcomboBoxIcon->GetSelection());
1653 if (icon_name && icon_name->Length()) m_pRoutePoint->SetIconName(*icon_name);
1654 m_pRoutePoint->ReLoadIcon();
1655 SaveChanges();
1656 // pConfig->UpdateWayPoint( m_pRoutePoint );
1657}
1658
1659void MarkInfoDlg::ValidateMark(void) {
1660 // Look in the master list of Waypoints to see if the currently selected
1661 // waypoint is still valid It may have been deleted as part of a route
1662 wxRoutePointListNode* node = pWayPointMan->GetWaypointList()->GetFirst();
1663
1664 bool b_found = false;
1665 while (node) {
1666 RoutePoint* rp = node->GetData();
1667 if (m_pRoutePoint == rp) {
1668 b_found = true;
1669 break;
1670 }
1671 node = node->GetNext();
1672 }
1673 if (!b_found) m_pRoutePoint = NULL;
1674}
1675
1676bool MarkInfoDlg::SaveChanges() {
1677 if (m_pRoutePoint) {
1678 if (m_pRoutePoint->m_bIsInLayer) return true;
1679
1680 // Get User input Text Fields
1681 m_pRoutePoint->SetName(m_textName->GetValue());
1682 m_pRoutePoint->SetWaypointArrivalRadius(m_textArrivalRadius->GetValue());
1683 m_pRoutePoint->SetScaMin(m_textScaMin->GetValue());
1684 m_pRoutePoint->SetUseSca(m_checkBoxScaMin->GetValue());
1685 m_pRoutePoint->m_MarkDescription = m_textDescription->GetValue();
1686 m_pRoutePoint->SetVisible(m_checkBoxVisible->GetValue());
1687 m_pRoutePoint->m_bShowName = m_checkBoxShowName->GetValue();
1688 m_pRoutePoint->SetPosition(fromDMM(m_textLatitude->GetValue()),
1689 fromDMM(m_textLongitude->GetValue()));
1690 wxString* icon_name =
1691 pWayPointMan->GetIconKey(m_bcomboBoxIcon->GetSelection());
1692 if (icon_name && icon_name->Length())
1693 m_pRoutePoint->SetIconName(*icon_name);
1694 m_pRoutePoint->ReLoadIcon();
1695 m_pRoutePoint->SetShowWaypointRangeRings(
1696 (bool)(m_ChoiceWaypointRangeRingsNumber->GetSelection() != 0));
1697 m_pRoutePoint->SetWaypointRangeRingsNumber(
1698 m_ChoiceWaypointRangeRingsNumber->GetSelection());
1699 double value;
1700 if (m_textWaypointRangeRingsStep->GetValue().ToDouble(&value))
1701 m_pRoutePoint->SetWaypointRangeRingsStep(fromUsrDistance(value, -1));
1702 if (m_textArrivalRadius->GetValue().ToDouble(&value))
1703 m_pRoutePoint->SetWaypointArrivalRadius(fromUsrDistance(value, -1));
1704
1705 if (m_RangeRingUnits->GetSelection() != wxNOT_FOUND)
1706 m_pRoutePoint->SetWaypointRangeRingsStepUnits(
1707 m_RangeRingUnits->GetSelection());
1708
1709 m_pRoutePoint->m_TideStation = m_comboBoxTideStation->GetStringSelection();
1710 if (m_textCtrlPlSpeed->GetValue() == wxEmptyString) {
1711 m_pRoutePoint->SetPlannedSpeed(0.0);
1712 } else {
1713 double spd;
1714 if (m_textCtrlPlSpeed->GetValue().ToDouble(&spd)) {
1715 m_pRoutePoint->SetPlannedSpeed(fromUsrSpeed(spd));
1716 }
1717 }
1718
1719 if (m_cbEtaPresent->GetValue()) {
1720 wxDateTime dt = m_EtaDatePickerCtrl->GetValue();
1721 dt.SetHour(m_EtaTimePickerCtrl->GetValue().GetHour());
1722 dt.SetMinute(m_EtaTimePickerCtrl->GetValue().GetMinute());
1723 dt.SetSecond(m_EtaTimePickerCtrl->GetValue().GetSecond());
1724 if (dt.IsValid()) {
1725 m_pRoutePoint->SetETD(dt.FormatISOCombined());
1726 }
1727 } else {
1728 m_pRoutePoint->SetETD(wxEmptyString);
1729 }
1730 // Here is some logic....
1731 // If the Markname is completely numeric, and is part of a route,
1732 // Then declare it to be of attribute m_bDynamicName = true
1733 // This is later used for re-numbering points on actions like
1734 // Insert Point, Delete Point, Append Point, etc
1735
1736 if (m_pRoutePoint->m_bIsInRoute) {
1737 bool b_name_is_numeric = true;
1738 for (unsigned int i = 0; i < m_pRoutePoint->GetName().Len(); i++) {
1739 if (i < 2 && wxChar('N') == m_pRoutePoint->GetName()[0] &&
1740 wxChar('M') == m_pRoutePoint->GetName()[1] &&
1741 m_pRoutePoint->GetName().Len() > 2)
1742 continue;
1743 if (wxChar('0') > m_pRoutePoint->GetName()[i])
1744 b_name_is_numeric = false;
1745 if (wxChar('9') < m_pRoutePoint->GetName()[i])
1746 b_name_is_numeric = false;
1747 }
1748
1749 m_pRoutePoint->m_bDynamicName = b_name_is_numeric;
1750 } else
1751 m_pRoutePoint->m_bDynamicName = false;
1752
1753 if (m_pRoutePoint->m_bIsInRoute) {
1754 // Update the route segment selectables
1755 pSelect->UpdateSelectableRouteSegments(m_pRoutePoint);
1756
1757 // Get an array of all routes using this point
1758 wxArrayPtrVoid* pEditRouteArray =
1759 g_pRouteMan->GetRouteArrayContaining(m_pRoutePoint);
1760
1761 if (pEditRouteArray) {
1762 for (unsigned int ir = 0; ir < pEditRouteArray->GetCount(); ir++) {
1763 Route* pr = (Route*)pEditRouteArray->Item(ir);
1764 pr->FinalizeForRendering();
1765 pr->UpdateSegmentDistances();
1766
1767 pConfig->UpdateRoute(pr);
1768 }
1769 delete pEditRouteArray;
1770 }
1771 } else
1772 pConfig->UpdateWayPoint(m_pRoutePoint);
1773 // No general settings need be saved pConfig->UpdateSettings();
1774 }
1775 // gFrame->GetFocusCanvas()->Refresh(false);
1776 return true;
1777}
1778
1779SaveDefaultsDialog::SaveDefaultsDialog(MarkInfoDlg* parent)
1780 : wxDialog(parent, wxID_ANY, _("Save some defaults")) {
1781 //(*Initialize(SaveDefaultsDialog)
1782 this->SetSizeHints(wxDefaultSize, wxDefaultSize);
1783
1784 wxBoxSizer* bSizer1 = new wxBoxSizer(wxVERTICAL);
1785 wxStdDialogButtonSizer* StdDialogButtonSizer1;
1786
1787 StaticText1 =
1788 new wxStaticText(this, wxID_ANY,
1789 _("Check which properties of current waypoint\n should "
1790 "be set as default for NEW waypoints."));
1791 bSizer1->Add(StaticText1, 0, wxALL | wxALIGN_CENTER_HORIZONTAL, 5);
1792
1793 wxFlexGridSizer* fgSizer1 = new wxFlexGridSizer(2);
1794
1795 wxString s =
1796 (g_pMarkInfoDialog->m_checkBoxShowName->GetValue() ? _("Do use")
1797 : _("Don't use"));
1798 NameCB =
1799 new wxCheckBox(this, wxID_ANY, _("Show Waypoint Name"), wxDefaultPosition,
1800 wxDefaultSize, 0, wxDefaultValidator);
1801 fgSizer1->Add(NameCB, 0, wxALL, 5);
1802 stName = new wxStaticText(this, wxID_ANY, _T("[") + s + _T("]"),
1803 wxDefaultPosition, wxDefaultSize, 0);
1804 stName->Wrap(-1);
1805 fgSizer1->Add(stName, 0, wxALL | wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL, 5);
1806
1807 s = g_pMarkInfoDialog->m_pRoutePoint->GetIconName();
1808 IconCB = new wxCheckBox(this, wxID_ANY, _("Icon"));
1809 fgSizer1->Add(IconCB, 0, wxALL, 5);
1810 stIcon = new wxStaticText(this, wxID_ANY, _T("[") + s + _T("]"),
1811 wxDefaultPosition, wxDefaultSize, 0);
1812 stIcon->Wrap(-1);
1813 fgSizer1->Add(stIcon, 0, wxALL | wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL, 5);
1814
1815 s = (g_pMarkInfoDialog->m_ChoiceWaypointRangeRingsNumber->GetSelection()
1816 ? _("Do use") +
1817 wxString::Format(
1818 _T(" (%i) "),
1819 g_pMarkInfoDialog->m_ChoiceWaypointRangeRingsNumber
1820 ->GetSelection())
1821 : _("Don't use"));
1822 RangRingsCB = new wxCheckBox(this, wxID_ANY, _("Range rings"));
1823 fgSizer1->Add(RangRingsCB, 0, wxALL, 5);
1824 stRR = new wxStaticText(this, wxID_ANY, _T("[") + s + _T("]"),
1825 wxDefaultPosition, wxDefaultSize, 0);
1826 stRR->Wrap(-1);
1827 fgSizer1->Add(stRR, 0, wxALL | wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL, 5);
1828
1829 s = (g_pMarkInfoDialog->m_textArrivalRadius->GetValue());
1830 ArrivalRCB = new wxCheckBox(this, wxID_ANY, _("Arrival radius"));
1831 fgSizer1->Add(ArrivalRCB, 0, wxALL, 5);
1832 stArrivalR = new wxStaticText(
1833 this, wxID_ANY,
1834 wxString::Format(_T("[%s %s]"), s.c_str(), getUsrDistanceUnit().c_str()),
1835 wxDefaultPosition, wxDefaultSize, 0);
1836 stArrivalR->Wrap(-1);
1837 fgSizer1->Add(stArrivalR, 0, wxALL | wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL,
1838 5);
1839
1840 s = (g_pMarkInfoDialog->m_checkBoxScaMin->GetValue()
1841 ? _("Show only if") + _T(" < ") +
1842 g_pMarkInfoDialog->m_textScaMin->GetValue()
1843 : _("Show always"));
1844 ScaleCB = new wxCheckBox(this, wxID_ANY, _("Show only at scale"));
1845 fgSizer1->Add(ScaleCB, 0, wxALL, 5);
1846 stScale = new wxStaticText(this, wxID_ANY, _T("[") + s + _T("]"),
1847 wxDefaultPosition, wxDefaultSize, 0);
1848 stScale->Wrap(-1);
1849 fgSizer1->Add(stScale, 0, wxALL | wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL, 5);
1850
1851 bSizer1->Add(fgSizer1, 0, wxALL | wxEXPAND, 5);
1852
1853 StdDialogButtonSizer1 = new wxStdDialogButtonSizer();
1854 StdDialogButtonSizer1->AddButton(new wxButton(this, wxID_OK));
1855 StdDialogButtonSizer1->AddButton(
1856 new wxButton(this, wxID_CANCEL, _("Cancel")));
1857 StdDialogButtonSizer1->Realize();
1858 bSizer1->Add(StdDialogButtonSizer1, 0, wxALL | wxEXPAND, 5);
1859
1860 SetSizer(bSizer1);
1861 Fit();
1862 Layout();
1863
1864#ifdef __OCPN__ANDROID__
1865 SetSize(parent->GetSize());
1866#endif
1867
1868 Center();
1869}
1870
1871void MarkInfoDlg::ShowTidesBtnClicked(wxCommandEvent& event) {
1872 if (m_comboBoxTideStation->GetSelection() < 1) {
1873 return;
1874 }
1875 IDX_entry* pIDX = (IDX_entry*)ptcmgr->GetIDX_entry(
1876 ptcmgr->GetStationIDXbyName(m_comboBoxTideStation->GetStringSelection(),
1877 fromDMM(m_textLatitude->GetValue()),
1878 fromDMM(m_textLongitude->GetValue())));
1879 if (pIDX) {
1880 TCWin* pCwin = new TCWin(gFrame->GetPrimaryCanvas(), 0, 0, pIDX);
1881 pCwin->Show();
1882 } else {
1883 wxString msg(_("Tide Station not found"));
1884 msg += _T(":\n");
1885 msg += m_comboBoxTideStation->GetStringSelection();
1886 OCPNMessageBox(NULL, msg, _("OpenCPN Info"), wxOK | wxCENTER, 10);
1887 }
1888}
Definition: IDX_entry.h:41
Class LinkPropImpl.
Definition: LinkPropDlg.h:89
Class MarkInfoDef.
Definition: MarkInfo.h:197
Definition: route.h:70
Class SaveDefaultsDialog.
Definition: MarkInfo.h:383
Definition: select.h:51
Definition: tcmgr.h:86
Definition: TCWin.h:46