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