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