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