34#include <wx/datetime.h>
35#include <wx/clipbrd.h>
37#include <wx/printdlg.h>
38#include <wx/stattext.h>
39#include <wx/clrpicker.h>
40#include <wx/bmpbuttn.h>
45#include "model/georef.h"
46#include "model/navutil_base.h"
47#include "model/own_ship.h"
48#include "model/position_parser.h"
49#include "model/route.h"
50#include "model/routeman.h"
51#include "model/select.h"
53#include "ocpn_frame.h"
54#include "OCPNPlatform.h"
56#include "routemanagerdialog.h"
57#include "RoutePropDlgImpl.h"
65#include "androidUTIL.h"
66#include <QtWidgets/QScroller>
80extern wxString g_default_wp_icon;
86extern float g_MarkScaleFactorExp;
90#include <wx/arrimpl.cpp>
91WX_DEFINE_OBJARRAY(ArrayOfBitmaps);
93#define EXTENDED_PROP_PAGE 2
95OCPNIconCombo::OCPNIconCombo(wxWindow* parent, wxWindowID
id,
96 const wxString& value,
const wxPoint& pos,
97 const wxSize& size,
int n,
98 const wxString choices[],
long style,
99 const wxValidator& validator,
const wxString& name)
100 : wxOwnerDrawnComboBox(parent, id, value, pos, size, n, choices, style,
103 GetFont().GetPointSize() / g_Platform->getFontPointsperPixel();
104 itemHeight = (int)wxRound(fontHeight);
107OCPNIconCombo::~OCPNIconCombo() {}
109void OCPNIconCombo::OnDrawItem(wxDC& dc,
const wxRect& rect,
int item,
111 int offset_x = bmpArray[item].GetWidth();
112 int bmpHeight = bmpArray[item].GetHeight();
113 dc.DrawBitmap(bmpArray[item], rect.x, rect.y + (rect.height - bmpHeight) / 2,
116 if (flags & wxODCB_PAINTING_CONTROL) {
117 wxString text = GetValue();
120#if wxCHECK_VERSION(2, 9, 0)
121 if (ShouldUseHintText()) {
123 wxColour col = wxSystemSettings::GetColour(wxSYS_COLOUR_GRAYTEXT);
124 dc.SetTextForeground(col);
127 margin_x = GetMargins().x;
130 dc.DrawText(text, rect.x + margin_x + offset_x,
131 (rect.height - dc.GetCharHeight()) / 2 + rect.y);
133 dc.DrawText(GetVListBoxComboPopup()->GetString(item), rect.x + 2 + offset_x,
134 (rect.height - dc.GetCharHeight()) / 2 + rect.y);
138wxCoord OCPNIconCombo::OnMeasureItem(
size_t item)
const {
139 int bmpHeight = bmpArray[item].GetHeight();
141 return wxMax(itemHeight, bmpHeight);
144wxCoord OCPNIconCombo::OnMeasureItemWidth(
size_t item)
const {
return -1; }
146int OCPNIconCombo::Append(
const wxString& item, wxBitmap bmp) {
148 int idx = wxOwnerDrawnComboBox::Append(item);
153void OCPNIconCombo::Clear(
void) {
154 wxOwnerDrawnComboBox::Clear();
168const wxEventType EVT_LLCHANGE = wxNewEventType();
177 const wxString& value, const wxPoint& pos,
178 const wxSize& size,
long style,
179 const wxValidator& validator,
180 const wxString& name)
181 : wxTextCtrl(parent,
id, value, pos, size, style, validator, name) {
182 m_pParentEventHandler = parent->GetEventHandler();
185void LatLonTextCtrl::OnKillFocus(wxFocusEvent& event) {
187 wxCommandEvent up_event(EVT_LLCHANGE, GetId());
188 up_event.SetEventObject((wxObject*)
this);
189 m_pParentEventHandler->AddPendingEvent(up_event);
198EVT_BUTTON(wxID_OK, MarkInfoDlg::OnMarkInfoOKClick)
199EVT_BUTTON(wxID_CANCEL, MarkInfoDlg::OnMarkInfoCancelClick)
200EVT_BUTTON(ID_BTN_DESC_BASIC, MarkInfoDlg::OnExtDescriptionClick)
201EVT_BUTTON(ID_DEFAULT, MarkInfoDlg::DefautlBtnClicked)
202EVT_BUTTON(ID_BTN_SHOW_TIDES, MarkInfoDlg::ShowTidesBtnClicked)
203EVT_COMBOBOX(ID_BITMAPCOMBOCTRL, MarkInfoDlg::OnBitmapCombClick)
204EVT_CHECKBOX(ID_CHECKBOX_SCAMIN_VIS, MarkInfoDlg::OnSelectScaMinExt)
205EVT_TEXT(ID_DESCR_CTR_DESC, MarkInfoDlg::OnDescChangedExt)
206EVT_TEXT(ID_DESCR_CTR_BASIC, MarkInfoDlg::OnDescChangedBasic)
207EVT_TEXT(ID_LATCTRL, MarkInfoDlg::OnPositionCtlUpdated)
208EVT_TEXT(ID_LONCTRL, MarkInfoDlg::OnPositionCtlUpdated)
209EVT_CHOICE(ID_WPT_RANGERINGS_NO, MarkInfoDlg::OnWptRangeRingsNoChange)
211EVT_HTML_LINK_CLICKED(wxID_ANY, MarkInfoDlg::OnHtmlLinkClicked)
212EVT_COMMAND(wxID_ANY, EVT_LAYOUT_RESIZE, MarkInfoDlg::OnLayoutResize)
213EVT_CLOSE(MarkInfoDlg::OnClose)
219 const wxPoint& pos, const wxSize& size,
long style) {
220 DIALOG_PARENT::Create(parent,
id, title, pos, size, style);
224 int metric = GetCharHeight();
228 wxString wqs = getFontQtStylesheet(qFont);
229 wxCharBuffer sbuf = wqs.ToUTF8();
230 QString qsb = QString(sbuf.data());
231 QString qsbq = getQtStyleSheet();
232 this->GetHandle()->setStyleSheet(qsb + qsbq);
234 if (sdc.IsOk()) sdc.GetTextExtent(
"W", NULL, &metric, NULL, NULL, qFont);
237 m_pMyLinkList = NULL;
238 SetColorScheme((ColorScheme)0);
239 m_pRoutePoint = NULL;
240 m_SaveDefaultDlg = NULL;
244 Connect(wxEVT_ACTIVATE, wxActivateEventHandler(MarkInfoDlg::OnActivate), NULL,
249void MarkInfoDlg::OnActivate(wxActivateEvent& event) {
250 auto pWin =
dynamic_cast<DIALOG_PARENT*
>(
event.GetEventObject());
251 long int style = pWin->GetWindowStyle();
252 if (event.GetActive())
253 pWin->SetWindowStyle(style | wxSTAY_ON_TOP);
255 pWin->SetWindowStyle(style ^ wxSTAY_ON_TOP);
258void MarkInfoDlg::initialize_images(
void) {
259 wxString iconDir = g_Platform->GetSharedDataDir() +
"uidata/MUI_flat/";
260 _img_MUI_settings_svg = LoadSVG(iconDir +
"MUI_settings.svg",
261 2 * GetCharHeight(), 2 * GetCharHeight());
264 wxBitmap tide = style->GetIcon(
"tidesml");
265 wxImage tide1 = tide.ConvertToImage();
266 wxImage tide1s = tide1.Scale(m_sizeMetric * 3 / 2, m_sizeMetric * 3 / 2,
267 wxIMAGE_QUALITY_HIGH);
268 m_bmTide = wxBitmap(tide1s);
273void MarkInfoDlg::Create() {
276 m_sizeMetric = GetCharHeight();
281 wxString wqs = getFontQtStylesheet(qFont);
282 wxCharBuffer sbuf = wqs.ToUTF8();
283 QString qsb = QString(sbuf.data());
285 QString qsbq = getAdjustedDialogStyleSheet();
287 this->GetHandle()->setStyleSheet(qsb + qsbq);
291 sdc.GetTextExtent(
"W", NULL, &m_sizeMetric, NULL, NULL, qFont);
298 bSizer1 =
new wxBoxSizer(wxVERTICAL);
300 bSizer1->SetSizeHints(
this);
303 m_notebookProperties =
new wxNotebook(
this, wxID_ANY, wxDefaultPosition,
304 wxDefaultSize, wxNB_FIXEDWIDTH);
306 m_panelBasicProperties =
new wxScrolledWindow(
307 m_notebookProperties, wxID_ANY, wxDefaultPosition, wxDefaultSize,
308 wxHSCROLL | wxVSCROLL | wxTAB_TRAVERSAL);
310 m_panelBasicProperties->GetHandle()->setStyleSheet(
311 getAdjustedDialogStyleSheet());
315 m_panelBasicProperties->SetScrollRate(0, 2);
316 m_notebookProperties->AddPage(m_panelBasicProperties, _(
"Basic"),
true);
317 bSizerBasicProperties =
new wxBoxSizer(wxVERTICAL);
318 m_panelBasicProperties->SetSizer(bSizerBasicProperties);
321 m_staticTextLayer =
new wxStaticText(
322 m_panelBasicProperties, wxID_ANY,
323 _(
"This waypoint is part of a layer and can't be edited"),
324 wxDefaultPosition, wxDefaultSize, 0);
325 m_staticTextLayer->Enable(
false);
326 bSizerBasicProperties->Add(m_staticTextLayer, 0, wxALL, 5);
329 wxPanel* props_panel =
new wxPanel(m_panelBasicProperties);
331 props_panel->SetSizer(props_sizer);
332 bSizerBasicProperties->Add(props_panel, 0, wxALL | wxEXPAND, 16);
333 int label_size = m_sizeMetric * 4;
336 m_textName =
new TextField(props_panel, _(
"Name"));
339 wxStaticText* name_cb_label =
340 new wxStaticText(props_panel, wxID_ANY, _(
"Show waypoint name"));
342 new wxCheckBox(props_panel, wxID_ANY, wxEmptyString, wxDefaultPosition,
343 wxDefaultSize, wxALIGN_CENTER_VERTICAL);
344 m_checkBoxShowName->Bind(wxEVT_CHECKBOX,
345 &MarkInfoDlg::OnShowWaypointNameSelectBasic,
this);
346 props_sizer->Add(name_cb_label, 0, wxALIGN_TOP);
347 props_sizer->Add(m_checkBoxShowName, 0, wxEXPAND);
350 int icon_size = m_sizeMetric * 2;
351 icon_size = wxMax(icon_size, (32 * g_MarkScaleFactorExp) + 4);
353 new OCPNIconCombo(props_panel, wxID_ANY, _(
"Combo!"), wxDefaultPosition,
354 wxDefaultSize, 0, NULL, wxCB_READONLY);
355 m_bcomboBoxIcon->SetPopupMaxHeight(::wxGetDisplaySize().y / 2);
356 m_bcomboBoxIcon->SetMinSize(wxSize(-1, icon_size));
358 wxStaticText* icon_label =
new wxStaticText(props_panel, wxID_ANY, _(
"Icon"));
359 icon_label->SetMinSize(wxSize(label_size, -1));
360 props_sizer->Add(icon_label, 0, wxALIGN_CENTER_VERTICAL);
361 props_sizer->Add(m_bcomboBoxIcon, 0, wxEXPAND);
364 m_textLatitude =
new TextField(props_panel, _(
"Latitude"));
365 m_textLongitude =
new TextField(props_panel, _(
"Longitude"));
366 props_sizer->Fit(props_panel);
369 wxStaticBox* desc_box =
370 new wxStaticBox(m_panelBasicProperties, wxID_ANY, _(
"Description"));
371 wxStaticBoxSizer* desc_sizer =
new wxStaticBoxSizer(desc_box, wxHORIZONTAL);
372 bSizerBasicProperties->Add(desc_sizer, 1, wxALL | wxEXPAND, 8);
373 m_textDescription =
new wxTextCtrl(
374 m_panelBasicProperties, ID_DESCR_CTR_BASIC, wxEmptyString,
375 wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE | wxTE_READONLY);
376 m_textDescription->SetMinSize(wxSize(-1, 80));
377 desc_sizer->Add(m_textDescription, 1, wxEXPAND);
380 m_buttonExtDescription =
381 new wxButton(m_panelBasicProperties, ID_BTN_DESC_BASIC,
"...",
382 wxDefaultPosition, wxSize(GetCharHeight() * 15 / 10, -1), 0);
383 desc_sizer->Add(m_buttonExtDescription, 0, wxEXPAND);
386 wxStaticBox* links_box =
387 new wxStaticBox(m_panelBasicProperties, wxID_ANY, _(
"Links"));
388 wxStaticBoxSizer* links_sizer =
new wxStaticBoxSizer(links_box, wxHORIZONTAL);
389 bSizerBasicProperties->Add(links_sizer, 1, wxALL | wxEXPAND, 8);
392 m_htmlList =
new wxSimpleHtmlListBox(m_panelBasicProperties, wxID_ANY,
393 wxDefaultPosition, wxDefaultSize, 0);
394 links_sizer->Add(m_htmlList, 1, wxEXPAND);
397 m_scrolledWindowLinks =
398 new wxScrolledWindow(m_panelBasicProperties, wxID_ANY, wxDefaultPosition,
399 wxSize(-1, 100), wxHSCROLL | wxVSCROLL);
400 m_scrolledWindowLinks->SetMinSize(wxSize(-1, 80));
401 m_scrolledWindowLinks->SetScrollRate(2, 2);
402 links_sizer->Add(m_scrolledWindowLinks, 1, wxEXPAND);
404 bSizerLinks =
new wxBoxSizer(wxVERTICAL);
405 m_scrolledWindowLinks->SetSizer(bSizerLinks);
407 m_menuLink =
new wxMenu();
408 wxMenuItem* m_menuItemDelete;
409 m_menuItemDelete =
new wxMenuItem(m_menuLink, wxID_ANY, wxString(_(
"Delete")),
410 wxEmptyString, wxITEM_NORMAL);
411 m_menuLink->Append(m_menuItemDelete);
413 wxMenuItem* m_menuItemEdit;
414 m_menuItemEdit =
new wxMenuItem(m_menuLink, wxID_ANY, wxString(_(
"Edit")),
415 wxEmptyString, wxITEM_NORMAL);
416 m_menuLink->Append(m_menuItemEdit);
418 wxMenuItem* m_menuItemAdd;
419 m_menuItemAdd =
new wxMenuItem(m_menuLink, wxID_ANY, wxString(_(
"Add new")),
420 wxEmptyString, wxITEM_NORMAL);
421 m_menuLink->Append(m_menuItemAdd);
423 wxBoxSizer* bSizer9 =
new wxBoxSizer(wxHORIZONTAL);
426 new wxButton(m_panelBasicProperties, wxID_ANY, _(
"Add new"),
427 wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT);
428 bSizer9->Add(m_buttonAddLink, 0, wxALL, 5);
430 m_buttonAddLink->Connect(wxEVT_COMMAND_BUTTON_CLICKED,
431 wxCommandEventHandler(MarkInfoDlg::OnAddLink), NULL,
434 links_sizer->Add(bSizer9, 0, wxEXPAND, 5);
439 new wxPanel(m_notebookProperties, wxID_ANY, wxDefaultPosition,
440 wxDefaultSize, wxTAB_TRAVERSAL);
441 wxBoxSizer* bSizer15;
442 bSizer15 =
new wxBoxSizer(wxVERTICAL);
444 m_textCtrlExtDescription =
445 new wxTextCtrl(m_panelDescription, ID_DESCR_CTR_DESC, wxEmptyString,
446 wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE);
447 bSizer15->Add(m_textCtrlExtDescription, 1, wxALL | wxEXPAND, 5);
449 m_panelDescription->SetSizer(bSizer15);
450 m_notebookProperties->AddPage(m_panelDescription, _(
"Description"),
false);
455 m_panelExtendedProperties =
new wxScrolledWindow(
456 m_notebookProperties, wxID_ANY, wxDefaultPosition, wxDefaultSize,
457 wxHSCROLL | wxVSCROLL | wxTAB_TRAVERSAL);
459 m_panelExtendedProperties->GetHandle()->setStyleSheet(
460 getAdjustedDialogStyleSheet());
463 m_panelExtendedProperties->SetScrollRate(0, 2);
465 wxBoxSizer* fSizerExtProperties =
new wxBoxSizer(wxVERTICAL);
466 m_panelExtendedProperties->SetSizer(fSizerExtProperties);
467 m_notebookProperties->AddPage(m_panelExtendedProperties, _(
"Extended"),
470 sbSizerExtProperties =
new wxStaticBoxSizer(
471 wxVERTICAL, m_panelExtendedProperties, _(
"Extended Properties"));
472 wxFlexGridSizer* gbSizerInnerExtProperties =
new wxFlexGridSizer(3, 0, 0);
473 gbSizerInnerExtProperties->AddGrowableCol(2);
474 gbSizerInnerExtProperties->SetFlexibleDirection(wxBOTH);
475 gbSizerInnerExtProperties->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_SPECIFIED);
477 m_checkBoxVisible =
new wxCheckBox(sbSizerExtProperties->GetStaticBox(),
478 ID_CHECKBOX_VIS_EXT, wxEmptyString);
479 gbSizerInnerExtProperties->Add(m_checkBoxVisible);
480 wxStaticText* m_staticTextVisible =
new wxStaticText(
481 sbSizerExtProperties->GetStaticBox(), wxID_ANY, _(
"Show on chart"));
482 gbSizerInnerExtProperties->Add(m_staticTextVisible);
483 gbSizerInnerExtProperties->Add(0, 0, 1, wxEXPAND, 0);
485 m_checkBoxScaMin =
new wxCheckBox(sbSizerExtProperties->GetStaticBox(),
486 ID_CHECKBOX_SCAMIN_VIS, wxEmptyString);
487 gbSizerInnerExtProperties->Add(m_checkBoxScaMin, 0, wxALIGN_CENTRE_VERTICAL,
489 m_staticTextScaMin =
new wxStaticText(sbSizerExtProperties->GetStaticBox(),
490 wxID_ANY, _(
"Show at scale > 1 :"));
491 gbSizerInnerExtProperties->Add(m_staticTextScaMin, 0, wxALIGN_CENTRE_VERTICAL,
493 m_textScaMin =
new wxTextCtrl(sbSizerExtProperties->GetStaticBox(), wxID_ANY);
494 gbSizerInnerExtProperties->Add(m_textScaMin, 0, wxALL | wxEXPAND, 5);
496 m_checkBoxShowNameExt =
new wxCheckBox(sbSizerExtProperties->GetStaticBox(),
497 wxID_ANY, wxEmptyString);
498 m_checkBoxShowNameExt->Bind(wxEVT_CHECKBOX,
499 &MarkInfoDlg::OnShowWaypointNameSelectExt,
this);
500 gbSizerInnerExtProperties->Add(m_checkBoxShowNameExt);
501 m_staticTextShowNameExt =
new wxStaticText(
502 sbSizerExtProperties->GetStaticBox(), wxID_ANY, _(
"Show waypoint name"));
504 gbSizerInnerExtProperties->Add(m_staticTextShowNameExt);
505 gbSizerInnerExtProperties->Add(0, 0, 1, wxEXPAND, 0);
507 sbRangeRingsExtProperties =
new wxStaticBoxSizer(
508 wxVERTICAL, sbSizerExtProperties->GetStaticBox(), _(
"Range rings"));
509 wxFlexGridSizer* gbRRExtProperties =
new wxFlexGridSizer(4, 0, 0);
510 gbRRExtProperties->AddGrowableCol(0);
511 gbRRExtProperties->AddGrowableCol(1);
512 gbRRExtProperties->AddGrowableCol(3);
513 m_staticTextRR1 =
new wxStaticText(sbSizerExtProperties->GetStaticBox(),
514 wxID_ANY, _(
"Number"));
515 gbRRExtProperties->Add(m_staticTextRR1, 0, wxLEFT, 5);
516 m_staticTextRR2 =
new wxStaticText(sbSizerExtProperties->GetStaticBox(),
517 wxID_ANY, _(
"Distance"));
518 gbRRExtProperties->Add(m_staticTextRR2, 0, wxLEFT, 5);
519 gbRRExtProperties->Add(0, 0, 1, wxEXPAND, 5);
520 m_staticTextRR4 =
new wxStaticText(sbSizerExtProperties->GetStaticBox(),
521 wxID_ANY, _(
"Color"));
522 gbRRExtProperties->Add(m_staticTextRR4, 0, wxLEFT, 5);
524 wxString rrAlt[] = {_(
"None"), _T(
"1" ), _T(
"2" ), _T(
"3" ),
525 _T(
"4" ), _T(
"5" ), _T(
"6" ), _T(
"7" ),
526 _T(
"8" ), _T(
"9" ), _T(
"10" )};
527 m_ChoiceWaypointRangeRingsNumber =
528 new wxChoice(sbSizerExtProperties->GetStaticBox(), ID_WPT_RANGERINGS_NO,
529 wxDefaultPosition, wxDefaultSize, 11, rrAlt);
531 gbRRExtProperties->Add(m_ChoiceWaypointRangeRingsNumber, 0, wxALL | wxEXPAND,
533 m_textWaypointRangeRingsStep =
534 new wxTextCtrl(sbSizerExtProperties->GetStaticBox(), wxID_ANY, _(
"0.05"),
535 wxDefaultPosition, wxDefaultSize, 0);
536 gbRRExtProperties->Add(m_textWaypointRangeRingsStep, 0, wxALL | wxEXPAND, 5);
538 wxString pDistUnitsStrings[] = {_(
"NMi"), _(
"km")};
540 new wxChoice(sbSizerExtProperties->GetStaticBox(), wxID_ANY,
541 wxDefaultPosition, wxDefaultSize, 2, pDistUnitsStrings);
542 gbRRExtProperties->Add(m_RangeRingUnits, 0, wxALIGN_CENTRE_VERTICAL, 0);
544 m_PickColor =
new wxColourPickerCtrl(sbSizerExtProperties->GetStaticBox(),
545 wxID_ANY, wxColour(0, 0, 0),
546 wxDefaultPosition, wxDefaultSize, 0);
547 gbRRExtProperties->Add(m_PickColor, 0, wxALL | wxEXPAND, 5);
548 sbRangeRingsExtProperties->Add(
549 gbRRExtProperties, 1,
550 wxLEFT | wxTOP | wxEXPAND | wxALIGN_LEFT | wxALIGN_TOP, 5);
552 sbSizerExtProperties->GetStaticBox()->Layout();
554 wxFlexGridSizer* gbSizerInnerExtProperties2 =
new wxFlexGridSizer(2, 0, 0);
555 gbSizerInnerExtProperties2->AddGrowableCol(1);
558 new wxStaticText(sbSizerExtProperties->GetStaticBox(), wxID_ANY,
559 _(
"GUID"), wxDefaultPosition, wxDefaultSize, 0);
560 gbSizerInnerExtProperties2->Add(m_staticTextGuid, 0, wxALIGN_CENTRE_VERTICAL,
562 m_textCtrlGuid =
new wxTextCtrl(sbSizerExtProperties->GetStaticBox(),
563 wxID_ANY, wxEmptyString, wxDefaultPosition,
564 wxDefaultSize, wxTE_READONLY);
565 m_textCtrlGuid->SetEditable(
false);
566 gbSizerInnerExtProperties2->Add(m_textCtrlGuid, 0, wxALL | wxEXPAND, 5);
568 wxFlexGridSizer* gbSizerInnerExtProperties1 =
new wxFlexGridSizer(3, 0, 0);
569 gbSizerInnerExtProperties1->AddGrowableCol(1);
571 m_staticTextTideStation =
572 new wxStaticText(sbSizerExtProperties->GetStaticBox(), wxID_ANY,
573 _(
"Tide Station"), wxDefaultPosition, wxDefaultSize, 0);
574 gbSizerInnerExtProperties1->Add(m_staticTextTideStation, 0,
575 wxALIGN_CENTRE_VERTICAL, 5);
578 m_choiceTideChoices.Add(
" ");
579 m_comboBoxTideStation =
580 new wxChoice(sbSizerExtProperties->GetStaticBox(), wxID_ANY,
581 wxDefaultPosition, wxDefaultSize, m_choiceTideChoices);
583 gbSizerInnerExtProperties1->Add(
584 m_comboBoxTideStation, 0, wxALL | wxEXPAND | wxALIGN_CENTRE_VERTICAL, 5);
587 m_comboBoxTideStation =
new wxComboBox(
588 sbSizerExtProperties->GetStaticBox(), wxID_ANY, wxEmptyString,
589 wxDefaultPosition, wxDefaultSize, 0, NULL, wxCB_READONLY);
590 gbSizerInnerExtProperties1->Add(
591 m_comboBoxTideStation, 0, wxALL | wxEXPAND | wxALIGN_CENTRE_VERTICAL, 5);
593 m_comboBoxTideStation->SetToolTip(
594 _(
"Associate this waypoint with a tide station to quickly access tide "
595 "predictions. Select from nearby stations or leave empty for no "
598 m_buttonShowTides =
new wxBitmapButton(
599 sbSizerExtProperties->GetStaticBox(), ID_BTN_SHOW_TIDES, m_bmTide,
600 wxDefaultPosition, m_bmTide.GetSize(), 0);
601 gbSizerInnerExtProperties1->Add(m_buttonShowTides, 0,
602 wxALL | wxALIGN_CENTRE_VERTICAL, 5);
604 m_staticTextArrivalRadius =
new wxStaticText(
605 sbSizerExtProperties->GetStaticBox(), wxID_ANY, _(
"Arrival Radius"));
606 gbSizerInnerExtProperties1->Add(m_staticTextArrivalRadius, 0,
607 wxALIGN_CENTRE_VERTICAL, 0);
608 m_textArrivalRadius =
609 new wxTextCtrl(sbSizerExtProperties->GetStaticBox(), wxID_ANY,
610 wxEmptyString, wxDefaultPosition, wxDefaultSize, 0);
611 m_textArrivalRadius->SetToolTip(
612 _(
"Distance from the waypoint at which OpenCPN will consider the "
613 "waypoint reached. Used for automatic waypoint advancement during "
614 "active navigation."));
615 gbSizerInnerExtProperties1->Add(m_textArrivalRadius, 0, wxALL | wxEXPAND, 5);
616 m_staticTextArrivalUnits =
617 new wxStaticText(sbSizerExtProperties->GetStaticBox(), wxID_ANY,
618 wxEmptyString, wxDefaultPosition, wxDefaultSize, 0);
619 gbSizerInnerExtProperties1->Add(m_staticTextArrivalUnits, 0,
620 wxALIGN_CENTRE_VERTICAL, 0);
622 m_staticTextPlSpeed =
623 new wxStaticText(sbSizerExtProperties->GetStaticBox(), wxID_ANY,
624 _(
"Planned Speed"), wxDefaultPosition, wxDefaultSize, 0);
625 gbSizerInnerExtProperties1->Add(m_staticTextPlSpeed, 0,
626 wxALIGN_CENTRE_VERTICAL, 0);
628 new wxTextCtrl(sbSizerExtProperties->GetStaticBox(), wxID_ANY,
629 wxEmptyString, wxDefaultPosition, wxDefaultSize, 0);
631 "Enter the planned vessel speed for the leg FOLLOWING this waypoint. "
632 "This speed is used when traveling FROM this waypoint TO the next "
633 "waypoint in the route. The value is used to calculate estimated time "
634 "of arrival at the next waypoint based on the ETD from this waypoint.\n\n"
635 "If left blank, the route's default speed will be used for this leg. "
636 "Individual waypoint speeds override the route-level speed setting."));
638 m_staticTextPlSpeedUnits =
639 new wxStaticText(sbSizerExtProperties->GetStaticBox(), wxID_ANY,
640 getUsrSpeedUnit(), wxDefaultPosition, wxDefaultSize, 0);
641 gbSizerInnerExtProperties1->Add(m_staticTextPlSpeedUnits, 0,
642 wxALIGN_CENTRE_VERTICAL, 0);
646 m_staticTextEtd =
new wxStaticText(sbSizerExtProperties->GetStaticBox(),
648 gbSizerInnerExtProperties1->Add(
m_staticTextEtd, 0, wxALIGN_CENTRE_VERTICAL,
650 wxBoxSizer* bsTimestamp =
new wxBoxSizer(wxHORIZONTAL);
651 m_cbEtdPresent =
new wxCheckBox(sbSizerExtProperties->GetStaticBox(),
652 wxID_ANY, wxEmptyString);
654 _(
"Enable to manually set a planned departure time (ETD) for this "
656 "When checked, the specified date and time will be used instead of the "
657 "automatically calculated ETD. This affects ETA calculations for "
658 "subsequent waypoints in the route."));
661 sbSizerExtProperties->GetStaticBox(), ID_ETA_DATEPICKERCTRL,
662 wxDefaultDateTime, wxDefaultPosition, wxDefaultSize, wxDP_DEFAULT,
665 "Select the planned departure date (ETD) for this waypoint.\nUsed "
666 "together with the time control to calculate arrival times at subsequent "
667 "waypoints.\nETD information is only used for route planning "
668 "and does not affect navigation."));
673 new TimeCtrl(sbSizerExtProperties->GetStaticBox(), ID_ETA_TIMEPICKERCTRL,
674 wxDefaultDateTime, wxDefaultPosition, wxDefaultSize);
677 sbSizerExtProperties->GetStaticBox(), ID_ETA_TIMEPICKERCTRL,
678 wxDefaultDateTime, wxDefaultPosition, wxDefaultSize, wxDP_DEFAULT,
683 gbSizerInnerExtProperties1->Add(bsTimestamp, 0, wxEXPAND, 0);
684 sbSizerExtProperties->Add(gbSizerInnerExtProperties, 0, wxALL | wxEXPAND, 5);
685 sbSizerExtProperties->Add(sbRangeRingsExtProperties, 0, wxALL | wxEXPAND, 5);
686 sbSizerExtProperties->Add(gbSizerInnerExtProperties2, 0, wxALL | wxEXPAND, 5);
687 sbSizerExtProperties->Add(gbSizerInnerExtProperties1, 0, wxALL | wxEXPAND, 5);
689 fSizerExtProperties->Add(sbSizerExtProperties, 1, wxALL | wxEXPAND);
692 bSizer1->Add(m_notebookProperties, 1, wxEXPAND);
694 wxBoxSizer* btnSizer =
new wxBoxSizer(wxHORIZONTAL);
695 bSizer1->Add(btnSizer, 0, wxEXPAND, 0);
698 new wxBitmapButton(
this, ID_DEFAULT, _img_MUI_settings_svg,
699 wxDefaultPosition, _img_MUI_settings_svg.GetSize(), 0);
700 btnSizer->Add(DefaultsBtn, 0, wxALL | wxALIGN_LEFT | wxALIGN_BOTTOM, 5);
701 btnSizer->Add(0, 0, 1, wxEXPAND);
703 m_sdbSizerButtons =
new wxStdDialogButtonSizer();
704 m_buttonOkay =
new wxButton(
this, wxID_OK);
705 m_sdbSizerButtons->AddButton(m_buttonOkay);
706 m_sdbSizerButtons->AddButton(
new wxButton(
this, wxID_CANCEL, _(
"Cancel")));
707 m_sdbSizerButtons->Realize();
708 btnSizer->Add(m_sdbSizerButtons, 0, wxALL, 5);
713 m_textLatitude->Connect(
715 wxCommandEventHandler(MarkInfoDlg::OnRightClickLatLon), NULL,
this);
716 m_textLongitude->Connect(
718 wxCommandEventHandler(MarkInfoDlg::OnRightClickLatLon), NULL,
this);
720 m_htmlList->Connect(wxEVT_RIGHT_DOWN,
721 wxMouseEventHandler(MarkInfoDlg::m_htmlListContextMenu),
725 m_notebookProperties->Connect(
726 wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED,
727 wxNotebookEventHandler(MarkInfoDlg::OnNotebookPageChanged), NULL,
this);
732 m_comboBoxTideStation->Connect(
733 wxEVT_COMMAND_COMBOBOX_SELECTED,
734 wxCommandEventHandler(MarkInfoDlg::OnTideStationCombobox), NULL,
this);
737void MarkInfoDlg::OnClose(wxCloseEvent& event) {
743#define TIDESTATION_BATCH_SIZE 10
745void MarkInfoDlg::OnTideStationCombobox(wxCommandEvent& event) {
746 int count = m_comboBoxTideStation->GetCount();
747 int sel = m_comboBoxTideStation->GetSelection();
748 if (sel == count - 1) {
751 for (
auto ts : m_tss) {
752 if (i == count + TIDESTATION_BATCH_SIZE) {
756 n = wxString::FromUTF8(ts.second->IDX_station_name);
757 m_comboBoxTideStation->Append(n);
764void MarkInfoDlg::OnNotebookPageChanged(wxNotebookEvent& event) {
765 if (event.GetSelection() == EXTENDED_PROP_PAGE) {
766 if (m_lasttspos.IsSameAs(m_textLatitude->GetValue() +
767 m_textLongitude->GetValue())) {
770 m_lasttspos = m_textLatitude->GetValue() + m_textLongitude->GetValue();
771 double lat = fromDMM(m_textLatitude->GetValue());
772 double lon = fromDMM(m_textLongitude->GetValue());
773 m_tss = ptcmgr->GetStationsForLL(lat, lon);
774 wxString s = m_comboBoxTideStation->GetStringSelection();
777 m_comboBoxTideStation->Clear();
778 m_comboBoxTideStation->Append(wxEmptyString);
779 for (
auto ts : m_tss) {
780 if (i == TIDESTATION_BATCH_SIZE) {
784 n = wxString::FromUTF8(ts.second->IDX_station_name);
785 m_comboBoxTideStation->Append(n);
787 m_comboBoxTideStation->SetSelection(i);
790 if (m_comboBoxTideStation->GetStringSelection() != s) {
791 m_comboBoxTideStation->Insert(s, 1);
792 m_comboBoxTideStation->SetSelection(1);
797void MarkInfoDlg::RecalculateSize(
void) {
802 wxSize dsize = GetParent()->GetClientSize();
806 esize.x = GetCharHeight() * 20;
807 esize.y = GetCharHeight() * 40;
810 esize.y = wxMin(esize.y, dsize.y - (2 * GetCharHeight()));
811 esize.x = wxMin(esize.x, dsize.x - (1 * GetCharHeight()));
812 SetSize(wxSize(esize.x, esize.y));
815 wxSize fsize = GetSize();
816 fsize.y = wxMin(fsize.y, dsize.y - (2 * GetCharHeight()));
817 fsize.x = wxMin(fsize.x, dsize.x - (1 * GetCharHeight()));
821 fsize.y = wxMin(fsize.y, (25 * GetCharHeight()));
823 SetSize(wxSize(-1, fsize.y));
825 m_defaultClientSize = GetClientSize();
828 wxSize dsize = GetParent()->GetClientSize();
829 SetSize(-1, wxMax(GetSize().y, dsize.y / 1.5));
833MarkInfoDlg::~MarkInfoDlg() {
835 m_textLatitude->Disconnect(
837 wxCommandEventHandler(MarkInfoDlg::OnRightClickLatLon), NULL,
this);
838 m_textLongitude->Disconnect(
840 wxCommandEventHandler(MarkInfoDlg::OnRightClickLatLon), NULL,
this);
842 m_htmlList->Disconnect(
843 wxEVT_RIGHT_DOWN, wxMouseEventHandler(MarkInfoDlg::m_htmlListContextMenu),
848 m_notebookProperties->Disconnect(
849 wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED,
850 wxNotebookEventHandler(MarkInfoDlg::OnNotebookPageChanged), NULL,
this);
852 wxEVT_TIME_CHANGED, wxDateEventHandler(MarkInfoDlg::OnTimeChanged), NULL,
855 wxEVT_DATE_CHANGED, wxDateEventHandler(MarkInfoDlg::OnTimeChanged), NULL,
859 androidEnableBackButton(
true);
863void MarkInfoDlg::InitialFocus(
void) {
864 m_textName->SetFocus();
865 m_textName->SetInsertionPointEnd();
868void MarkInfoDlg::SetColorScheme(ColorScheme cs) { DimeControl(
this); }
870void MarkInfoDlg::ClearData() {
871 m_pRoutePoint = NULL;
875void MarkInfoDlg::SetRoutePoint(
RoutePoint* pRP) {
878 m_lat_save = m_pRoutePoint->m_lat;
879 m_lon_save = m_pRoutePoint->m_lon;
880 m_IconName_save = m_pRoutePoint->GetIconName();
883 m_Name_save = m_pRoutePoint->GetName();
885 m_bUseScaMin_save = m_pRoutePoint->GetUseSca();
886 m_iScaminVal_save = m_pRoutePoint->GetScaMin();
888 if (m_pMyLinkList)
delete m_pMyLinkList;
889 m_pMyLinkList =
new HyperlinkList();
890 for (
Hyperlink* link : *m_pRoutePoint->m_HyperlinkList) {
892 h->DescrText = link->DescrText;
893 h->Link = link->Link;
894 h->LType = link->LType;
896 m_pMyLinkList->push_back(h);
901void MarkInfoDlg::UpdateHtmlList() {
903 GetSimpleBox()->Clear();
906 if (NbrOfLinks > 0) {
908 for (
auto it = list->begin(); it != list->end(); ++it) {
911 wxString::Format(
"<a href='%s'>%s</a>", link->Link, link->DescrText);
912 GetSimpleBox()->AppendString(s);
917 wxWindowList kids = m_scrolledWindowLinks->GetChildren();
918 for (
unsigned int i = 0; i < kids.GetCount(); i++) {
919 wxWindowListNode* node = kids.Item(i);
920 wxWindow* win = node->GetData();
922 auto link_win =
dynamic_cast<wxHyperlinkCtrl*
>(win);
924 link_win->Disconnect(
925 wxEVT_COMMAND_HYPERLINK,
926 wxHyperlinkEventHandler(MarkInfoDlg::OnHyperLinkClick));
927 link_win->Disconnect(
929 wxMouseEventHandler(MarkInfoDlg::m_htmlListContextMenu));
934 for (
Hyperlink* link : *m_pRoutePoint->m_HyperlinkList) {
935 wxString Link = link->Link;
936 wxString Descr = link->DescrText;
938 wxHyperlinkCtrl* ctrl =
new wxHyperlinkCtrl(
939 m_scrolledWindowLinks, wxID_ANY, Descr, Link, wxDefaultPosition,
940 wxDefaultSize, wxNO_BORDER | wxHL_CONTEXTMENU | wxHL_ALIGN_LEFT);
941 ctrl->Connect(wxEVT_COMMAND_HYPERLINK,
942 wxHyperlinkEventHandler(MarkInfoDlg::OnHyperLinkClick), NULL,
945 ctrl->Connect(wxEVT_RIGHT_DOWN,
946 wxMouseEventHandler(MarkInfoDlg::m_htmlListContextMenu),
949 bSizerLinks->Add(ctrl, 1, wxALL | wxEXPAND, 5);
953 m_scrolledWindowLinks->Layout();
957void MarkInfoDlg::OnHyperLinkClick(wxHyperlinkEvent& event) {
958 wxString url =
event.GetURL();
959 url.Replace(
" ",
"%20");
960 if (g_Platform) g_Platform->platformLaunchDefaultBrowser(url);
963void MarkInfoDlg::OnHtmlLinkClicked(wxHtmlLinkEvent& event) {
973 wxString cc =
event.GetLinkInfo().GetHref().c_str();
974 if (cc.Find(
"#") != wxNOT_FOUND) {
975 wxRegKey RegKey(wxString(
"HKEY_CLASSES_ROOT\\HTTP\\shell\\open\\command"));
976 if (RegKey.Exists()) {
977 wxString command_line;
978 RegKey.QueryValue(wxString(
""), command_line);
981 command_line.Replace(wxString(
"\""), wxString(
""));
984 int l = command_line.Find(
".exe");
985 if (wxNOT_FOUND == l) l = command_line.Find(
".EXE");
987 if (wxNOT_FOUND != l) {
988 wxString cl = command_line.Mid(0, l + 4);
997 wxString url =
event.GetLinkInfo().GetHref().c_str();
998 url.Replace(
" ",
"%20");
999 ::wxLaunchDefaultBrowser(url);
1003 wxString url =
event.GetLinkInfo().GetHref().c_str();
1004 url.Replace(
" ",
"%20");
1005 if (g_Platform) g_Platform->platformLaunchDefaultBrowser(url);
1011void MarkInfoDlg::OnLayoutResize(wxCommandEvent& event) {
1012 m_panelBasicProperties->Layout();
1016void MarkInfoDlg::OnDescChangedExt(wxCommandEvent& event) {
1017 if (m_panelDescription->IsShownOnScreen()) {
1018 m_textDescription->ChangeValue(m_textCtrlExtDescription->GetValue());
1022void MarkInfoDlg::OnDescChangedBasic(wxCommandEvent& event) {
1023 if (m_panelBasicProperties->IsShownOnScreen()) {
1024 m_textCtrlExtDescription->ChangeValue(m_textDescription->GetValue());
1029void MarkInfoDlg::OnExtDescriptionClick(wxCommandEvent& event) {
1030 long pos = m_textDescription->GetInsertionPoint();
1031 m_notebookProperties->SetSelection(1);
1032 m_textCtrlExtDescription->SetInsertionPoint(pos);
1036void MarkInfoDlg::OnShowWaypointNameSelectBasic(wxCommandEvent& event) {
1037 m_checkBoxShowNameExt->SetValue(m_checkBoxShowName->GetValue());
1040void MarkInfoDlg::OnShowWaypointNameSelectExt(wxCommandEvent& event) {
1041 m_checkBoxShowName->SetValue(m_checkBoxShowNameExt->GetValue());
1045void MarkInfoDlg::OnWptRangeRingsNoChange(wxCommandEvent& event) {
1047 m_textWaypointRangeRingsStep->Enable(
1048 (
bool)(m_ChoiceWaypointRangeRingsNumber->GetSelection() != 0));
1049 m_PickColor->Enable(
1050 (
bool)(m_ChoiceWaypointRangeRingsNumber->GetSelection() != 0));
1054void MarkInfoDlg::OnSelectScaMinExt(wxCommandEvent& event) {
1056 m_textScaMin->Enable(m_checkBoxScaMin->GetValue());
1060void MarkInfoDlg::OnPositionCtlUpdated(wxCommandEvent& event) {
1062 double lat = fromDMM(m_textLatitude->GetValue());
1063 double lon = fromDMM(m_textLongitude->GetValue());
1065 m_pRoutePoint->SetPosition(lat, lon);
1066 pSelect->ModifySelectablePoint(lat, lon, (
void*)m_pRoutePoint,
1067 SELTYPE_ROUTEPOINT);
1070 gFrame->RefreshAllCanvas();
1073void MarkInfoDlg::m_htmlListContextMenu(wxMouseEvent& event) {
1077 wxPoint pos =
event.GetPosition();
1078 i_htmlList_item = -1;
1079 for (
int i = 0; i < (int)GetSimpleBox()->GetCount(); i++) {
1080 wxRect rect = GetSimpleBox()->GetItemRect(i);
1081 if (rect.Contains(pos)) {
1082 i_htmlList_item = i;
1087 wxMenu* popup =
new wxMenu();
1088 if ((GetSimpleBox()->GetCount()) > 0 && (i_htmlList_item > -1) &&
1089 (i_htmlList_item < (
int)GetSimpleBox()->GetCount())) {
1090 popup->Append(ID_RCLK_MENU_DELETE_LINK, _(
"Delete"));
1091 popup->Append(ID_RCLK_MENU_EDIT_LINK, _(
"Edit"));
1093 popup->Append(ID_RCLK_MENU_ADD_LINK, _(
"Add New"));
1095 m_contextObject =
event.GetEventObject();
1097 wxEVT_COMMAND_MENU_SELECTED,
1098 wxCommandEventHandler(MarkInfoDlg::On_html_link_popupmenu_Click), NULL,
1104 m_pEditedLink =
dynamic_cast<wxHyperlinkCtrl*
>(
event.GetEventObject());
1106 if (m_pEditedLink) {
1107 wxString url = m_pEditedLink->GetURL();
1108 wxString label = m_pEditedLink->GetLabel();
1109 i_htmlList_item = -1;
1112 for (
Hyperlink* link : *hyperlinklist) {
1113 if (link->DescrText == label) {
1114 i_htmlList_item = i;
1122 wxMenu* popup =
new wxMenu();
1124 wxMenuItem* menuItemDelete =
1125 new wxMenuItem(popup, ID_RCLK_MENU_DELETE_LINK, wxString(_(
"Delete")),
1126 wxEmptyString, wxITEM_NORMAL);
1128 menuItemDelete->SetFont(sFont);
1130 popup->Append(menuItemDelete);
1132 wxMenuItem* menuItemEdit =
1133 new wxMenuItem(popup, ID_RCLK_MENU_EDIT_LINK, wxString(_(
"Edit")),
1134 wxEmptyString, wxITEM_NORMAL);
1136 menuItemEdit->SetFont(sFont);
1138 popup->Append(menuItemEdit);
1141 wxMenuItem* menuItemAdd =
1142 new wxMenuItem(popup, ID_RCLK_MENU_ADD_LINK, wxString(_(
"Add New")),
1143 wxEmptyString, wxITEM_NORMAL);
1145 menuItemAdd->SetFont(sFont);
1147 popup->Append(menuItemAdd);
1149 m_contextObject =
event.GetEventObject();
1151 wxEVT_COMMAND_MENU_SELECTED,
1152 wxCommandEventHandler(MarkInfoDlg::On_html_link_popupmenu_Click), NULL,
1154 wxPoint p = m_scrolledWindowLinks->GetPosition();
1155 p.x += m_scrolledWindowLinks->GetSize().x / 2;
1156 PopupMenu(popup, p);
1179void MarkInfoDlg::OnAddLink(wxCommandEvent& event) {
1180 wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED);
1181 evt.SetId(ID_RCLK_MENU_ADD_LINK);
1183 On_html_link_popupmenu_Click(evt);
1186void MarkInfoDlg::On_html_link_popupmenu_Click(wxCommandEvent& event) {
1187 switch (event.GetId()) {
1188 case ID_RCLK_MENU_DELETE_LINK: {
1194 case ID_RCLK_MENU_EDIT_LINK: {
1198 LinkPropDlg->m_textCtrlLinkDescription->SetValue(link->DescrText);
1199 LinkPropDlg->m_textCtrlLinkUrl->SetValue(link->Link);
1200 DimeControl(LinkPropDlg);
1201 LinkPropDlg->ShowWindowModalThenDo([
this, LinkPropDlg,
1202 link](
int retcode) {
1203 if (retcode == wxID_OK) {
1204 link->DescrText = LinkPropDlg->m_textCtrlLinkDescription->GetValue();
1206 link->Link = LinkPropDlg->m_textCtrlLinkUrl->GetValue();
1213 case ID_RCLK_MENU_ADD_LINK: {
1215 LinkPropDlg->m_textCtrlLinkDescription->SetValue(wxEmptyString);
1216 LinkPropDlg->m_textCtrlLinkUrl->SetValue(wxEmptyString);
1217 DimeControl(LinkPropDlg);
1218 LinkPropDlg->ShowWindowModalThenDo([
this, LinkPropDlg](
int retcode) {
1219 if (retcode == wxID_OK) {
1221 link->DescrText = LinkPropDlg->m_textCtrlLinkDescription->GetValue();
1222 link->Link = LinkPropDlg->m_textCtrlLinkUrl->GetValue();
1224 if (link->DescrText == wxEmptyString) {
1225 link->DescrText = link->Link;
1227 if (link->Link == wxEmptyString) {
1230 m_pRoutePoint->m_HyperlinkList->push_back(link);
1241void MarkInfoDlg::OnRightClickLatLon(wxCommandEvent& event) {
1242 wxMenu* popup =
new wxMenu();
1243 popup->Append(ID_RCLK_MENU_COPY, _(
"Copy"));
1244 popup->Append(ID_RCLK_MENU_COPY_LL, _(
"Copy lat/long"));
1245 popup->Append(ID_RCLK_MENU_PASTE, _(
"Paste"));
1246 popup->Append(ID_RCLK_MENU_PASTE_LL, _(
"Paste lat/long"));
1247 m_contextObject =
event.GetEventObject();
1248 popup->Connect(wxEVT_COMMAND_MENU_SELECTED,
1249 wxCommandEventHandler(MarkInfoDlg::OnCopyPasteLatLon), NULL,
1256void MarkInfoDlg::OnCopyPasteLatLon(wxCommandEvent& event) {
1258 double lat = fromDMM(m_textLatitude->GetValue());
1259 double lon = fromDMM(m_textLongitude->GetValue());
1263 switch (event.GetId()) {
1264 case ID_RCLK_MENU_PASTE: {
1265 if (wxTheClipboard->Open()) {
1266 wxTextDataObject data;
1267 wxTheClipboard->GetData(data);
1268 result = data.GetText();
1269 ((wxTextCtrl*)m_contextObject)->SetValue(result);
1270 wxTheClipboard->Close();
1274 case ID_RCLK_MENU_PASTE_LL: {
1275 if (wxTheClipboard->Open()) {
1276 wxTextDataObject data;
1277 wxTheClipboard->GetData(data);
1278 result = data.GetText();
1282 if (pparse.IsOk()) {
1283 m_textLatitude->SetValue(pparse.GetLatitudeString());
1284 m_textLongitude->SetValue(pparse.GetLongitudeString());
1286 wxTheClipboard->Close();
1290 case ID_RCLK_MENU_COPY: {
1291 result = ((wxTextCtrl*)m_contextObject)->GetValue();
1294 case ID_RCLK_MENU_COPY_LL: {
1295 result << toSDMM(1, lat,
true) << _T(
'\t');
1296 result << toSDMM(2, lon,
true);
1301 if (wxTheClipboard->Open()) {
1302 wxTextDataObject* data =
new wxTextDataObject;
1303 data->SetText(result);
1304 wxTheClipboard->SetData(data);
1305 wxTheClipboard->Close();
1309void MarkInfoDlg::DefautlBtnClicked(wxCommandEvent& event) {
1311 m_SaveDefaultDlg->Center();
1312 DimeControl(m_SaveDefaultDlg);
1313 int retcode = m_SaveDefaultDlg->ShowModal();
1316 if (retcode == wxID_OK) {
1318 if (m_SaveDefaultDlg->IconCB->GetValue()) {
1320 *pWayPointMan->GetIconKey(m_bcomboBoxIcon->GetSelection());
1322 if (m_SaveDefaultDlg->RangRingsCB->GetValue()) {
1323 g_iWaypointRangeRingsNumber =
1324 m_ChoiceWaypointRangeRingsNumber->GetSelection();
1325 if (m_textWaypointRangeRingsStep->GetValue().ToDouble(&value))
1326 g_fWaypointRangeRingsStep = fromUsrDistance(value, -1);
1327 g_colourWaypointRangeRingsColour = m_PickColor->GetColour();
1329 if (m_SaveDefaultDlg->ArrivalRCB->GetValue())
1330 if (m_textArrivalRadius->GetValue().ToDouble(&value))
1331 g_n_arrival_circle_radius = fromUsrDistance(value, -1);
1332 if (m_SaveDefaultDlg->ScaleCB->GetValue()) {
1333 g_iWpt_ScaMin = wxAtoi(m_textScaMin->GetValue());
1334 g_bUseWptScaMin = m_checkBoxScaMin->GetValue();
1336 if (m_SaveDefaultDlg->NameCB->GetValue()) {
1337 g_bShowWptName = m_checkBoxShowName->GetValue();
1340 m_SaveDefaultDlg = NULL;
1344void MarkInfoDlg::OnMarkInfoCancelClick(wxCommandEvent& event) {
1345 if (m_pRoutePoint) {
1346 m_pRoutePoint->SetVisible(m_bIsVisible_save);
1347 m_pRoutePoint->SetNameShown(m_bShowName_save);
1348 m_pRoutePoint->SetPosition(m_lat_save, m_lon_save);
1349 m_pRoutePoint->SetIconName(m_IconName_save);
1350 m_pRoutePoint->ReLoadIcon();
1351 m_pRoutePoint->SetName(m_Name_save);
1353 m_pRoutePoint->SetUseSca(m_bUseScaMin_save);
1354 m_pRoutePoint->SetScaMin(m_iScaminVal_save);
1358 int NbrOfLinks = m_pMyLinkList->size();
1359 if (NbrOfLinks > 0) {
1360 for (
Hyperlink* link : *m_pMyLinkList) {
1362 h->DescrText = link->DescrText;
1363 h->Link = link->Link;
1364 h->LType = link->LType;
1371 m_lasttspos.Clear();
1378 delete m_pMyLinkList;
1379 m_pMyLinkList = NULL;
1380 SetClientSize(m_defaultClientSize);
1383 androidEnableBackButton(
true);
1389void MarkInfoDlg::OnMarkInfoOKClick(wxCommandEvent& event) {
1390 if (m_pRoutePoint) {
1393 OnPositionCtlUpdated(event);
1403 if (pRouteManagerDialog && pRouteManagerDialog->IsShown())
1404 pRouteManagerDialog->UpdateWptListCtrl();
1406 if (pRoutePropDialog && pRoutePropDialog->IsShown())
1407 pRoutePropDialog->UpdatePoints();
1409 SetClientSize(m_defaultClientSize);
1412 androidEnableBackButton(
true);
1418bool MarkInfoDlg::UpdateProperties(
bool positionOnly) {
1419 if (m_pRoutePoint) {
1420 m_textLatitude->SetValue(::toSDMM(1, m_pRoutePoint->m_lat));
1421 m_textLongitude->SetValue(::toSDMM(2, m_pRoutePoint->m_lon));
1422 m_lat_save = m_pRoutePoint->m_lat;
1423 m_lon_save = m_pRoutePoint->m_lon;
1424 m_textName->SetValue(m_pRoutePoint->GetName());
1427 m_checkBoxShowName->SetValue(m_pRoutePoint->
m_bShowName);
1428 m_checkBoxShowNameExt->SetValue(m_pRoutePoint->
m_bShowName);
1429 m_checkBoxVisible->SetValue(m_pRoutePoint->
m_bIsVisible);
1430 m_checkBoxScaMin->SetValue(m_pRoutePoint->GetUseSca());
1431 m_textScaMin->SetValue(
1432 wxString::Format(
"%i", (
int)m_pRoutePoint->GetScaMin()));
1433 m_textCtrlGuid->SetValue(m_pRoutePoint->
m_GUID);
1434 m_ChoiceWaypointRangeRingsNumber->SetSelection(
1435 m_pRoutePoint->GetWaypointRangeRingsNumber());
1438 toUsrDistance(m_pRoutePoint->GetWaypointRangeRingsStep(), -1));
1439 m_textWaypointRangeRingsStep->SetValue(buf);
1440 m_staticTextArrivalUnits->SetLabel(getUsrDistanceUnit());
1442 toUsrDistance(m_pRoutePoint->GetWaypointArrivalRadius(), -1));
1443 m_textArrivalRadius->SetValue(buf);
1445 int nUnits = m_pRoutePoint->GetWaypointRangeRingsStepUnits();
1446 m_RangeRingUnits->SetSelection(nUnits);
1449 m_PickColor->SetColour(col);
1452 if (m_name_validator) m_name_validator.reset();
1454 std::make_unique<RoutePointNameValidator>(m_pRoutePoint);
1455 m_textName->SetValidator(*m_name_validator);
1457 m_textName->Bind(wxEVT_KILL_FOCUS, &MarkInfoDlg::OnFocusEvent,
this);
1459 m_textName->SetValidator();
1461 m_textName->Unbind(wxEVT_KILL_FOCUS, &MarkInfoDlg::OnFocusEvent,
this);
1464 if (m_comboBoxTideStation->GetStringSelection() !=
1466 m_comboBoxTideStation->Clear();
1467 m_comboBoxTideStation->Append(wxEmptyString);
1469 m_comboBoxTideStation->Append(m_pRoutePoint->
m_TideStation);
1470 m_comboBoxTideStation->SetSelection(1);
1474 m_staticTextPlSpeedUnits->SetLabel(getUsrSpeedUnit());
1482 bool isLastWaypoint =
false;
1485 wxArrayPtrVoid* pRouteArray =
1488 isLastWaypoint =
true;
1490 for (
unsigned int i = 0; i < pRouteArray->GetCount(); i++) {
1492 if (route->GetLastPoint()->
m_GUID != m_pRoutePoint->
m_GUID) {
1493 isLastWaypoint =
false;
1502 if (isLastWaypoint) {
1507 if (etd.IsValid()) {
1510 if (dtFormat ==
"Local Time") {
1514 }
else if (dtFormat ==
"UTC") {
1521 "MarkInfoDlg::UpdateProperties. Unexpected date/time format: %s",
1523 etd = wxInvalidDateTime;
1534 m_staticTextPlSpeed->Show(m_pRoutePoint->
m_bIsInRoute);
1540 m_staticTextPlSpeedUnits->Show(m_pRoutePoint->
m_bIsInRoute);
1541 m_staticTextArrivalRadius->Show(m_pRoutePoint->
m_bIsInRoute);
1542 m_staticTextArrivalUnits->Show(m_pRoutePoint->
m_bIsInRoute);
1543 m_textArrivalRadius->Show(m_pRoutePoint->
m_bIsInRoute);
1545 if (positionOnly)
return true;
1549 m_staticTextLayer->Enable();
1550 m_staticTextLayer->Show(
true);
1551 m_textName->SetEditable(
false);
1552 m_textDescription->SetEditable(
false);
1553 m_textCtrlExtDescription->SetEditable(
false);
1554 m_textLatitude->SetEditable(
false);
1555 m_textLongitude->SetEditable(
false);
1556 m_bcomboBoxIcon->Enable(
false);
1557 m_checkBoxShowName->Enable(
false);
1558 m_checkBoxVisible->Enable(
false);
1559 m_textArrivalRadius->SetEditable(
false);
1560 m_checkBoxScaMin->Enable(
false);
1561 m_textScaMin->SetEditable(
false);
1562 m_checkBoxShowNameExt->Enable(
false);
1563 m_ChoiceWaypointRangeRingsNumber->Enable(
false);
1564 m_textWaypointRangeRingsStep->SetEditable(
false);
1565 m_PickColor->Enable(
false);
1566 DefaultsBtn->Enable(
false);
1570 m_notebookProperties->SetSelection(0);
1571 m_comboBoxTideStation->Enable(
false);
1573 m_staticTextLayer->Enable(
false);
1574 m_staticTextLayer->Show(
false);
1575 m_textName->SetEditable(
true);
1576 m_textDescription->SetEditable(
true);
1577 m_textCtrlExtDescription->SetEditable(
true);
1578 m_textLatitude->SetEditable(
true);
1579 m_textLongitude->SetEditable(
true);
1580 m_bcomboBoxIcon->Enable(
true);
1581 m_checkBoxShowName->Enable(
true);
1582 m_checkBoxVisible->Enable(
true);
1583 m_textArrivalRadius->SetEditable(
true);
1584 m_checkBoxScaMin->Enable(
true);
1585 m_textScaMin->SetEditable(
true);
1586 m_checkBoxShowNameExt->Enable(
true);
1587 m_ChoiceWaypointRangeRingsNumber->Enable(
true);
1588 m_textWaypointRangeRingsStep->SetEditable(
true);
1589 m_PickColor->Enable(
true);
1590 DefaultsBtn->Enable(
true);
1591 m_notebookProperties->SetSelection(0);
1592 m_comboBoxTideStation->Enable(
true);
1602 m_bcomboBoxIcon->Clear();
1604 bool fillCombo = m_bcomboBoxIcon->GetCount() == 0;
1607 for (
int i = 0; i < pWayPointMan->GetNumIcons(); i++) {
1608 wxString* ps = pWayPointMan->GetIconDescription(i);
1610 pWayPointMan->GetIconBitmapForList(i, 2 * GetCharHeight());
1612 m_bcomboBoxIcon->Append(*ps, bmp);
1616 int iconToSelect = -1;
1617 for (
int i = 0; i < pWayPointMan->GetNumIcons(); i++) {
1618 if (*pWayPointMan->GetIconKey(i) == m_pRoutePoint->GetIconName()) {
1620 m_bcomboBoxIcon->Select(iconToSelect);
1625 OnShowWaypointNameSelectBasic(ev);
1626 OnWptRangeRingsNoChange(ev);
1627 OnSelectScaMinExt(ev);
1632 androidEnableBackButton(
false);
1643void MarkInfoDlg::OnFocusEvent(wxFocusEvent& event) {
1644 bool is_valid = Validate();
1645 m_buttonOkay->Enable(is_valid);
1649void MarkInfoDlg::OnBitmapCombClick(wxCommandEvent& event) {
1650 wxString* icon_name =
1651 pWayPointMan->GetIconKey(m_bcomboBoxIcon->GetSelection());
1652 if (icon_name && icon_name->Length()) m_pRoutePoint->SetIconName(*icon_name);
1653 m_pRoutePoint->ReLoadIcon();
1658void MarkInfoDlg::ValidateMark(
void) {
1661 wxRoutePointListNode* node = pWayPointMan->GetWaypointList()->GetFirst();
1663 bool b_found =
false;
1666 if (m_pRoutePoint == rp) {
1670 node = node->GetNext();
1672 if (!b_found) m_pRoutePoint = NULL;
1675bool MarkInfoDlg::SaveChanges() {
1676 if (m_pRoutePoint) {
1678 if (!this->Validate())
return false;
1681 m_pRoutePoint->SetName(m_textName->GetValue());
1682 m_pRoutePoint->SetWaypointArrivalRadius(m_textArrivalRadius->GetValue());
1683 m_pRoutePoint->SetScaMin(m_textScaMin->GetValue());
1684 m_pRoutePoint->SetUseSca(m_checkBoxScaMin->GetValue());
1686 m_pRoutePoint->SetVisible(m_checkBoxVisible->GetValue());
1687 m_pRoutePoint->
m_bShowName = m_checkBoxShowName->GetValue();
1688 m_pRoutePoint->SetPosition(fromDMM(m_textLatitude->GetValue()),
1689 fromDMM(m_textLongitude->GetValue()));
1690 wxString* icon_name =
1691 pWayPointMan->GetIconKey(m_bcomboBoxIcon->GetSelection());
1692 if (icon_name && icon_name->Length())
1693 m_pRoutePoint->SetIconName(*icon_name);
1694 m_pRoutePoint->ReLoadIcon();
1695 m_pRoutePoint->SetShowWaypointRangeRings(
1696 (
bool)(m_ChoiceWaypointRangeRingsNumber->GetSelection() != 0));
1697 m_pRoutePoint->SetWaypointRangeRingsNumber(
1698 m_ChoiceWaypointRangeRingsNumber->GetSelection());
1700 if (m_textWaypointRangeRingsStep->GetValue().ToDouble(&value))
1701 m_pRoutePoint->SetWaypointRangeRingsStep(fromUsrDistance(value, -1));
1702 if (m_textArrivalRadius->GetValue().ToDouble(&value))
1703 m_pRoutePoint->SetWaypointArrivalRadius(fromUsrDistance(value, -1));
1705 if (m_RangeRingUnits->GetSelection() != wxNOT_FOUND)
1706 m_pRoutePoint->SetWaypointRangeRingsStepUnits(
1707 m_RangeRingUnits->GetSelection());
1709 m_pRoutePoint->
m_TideStation = m_comboBoxTideStation->GetStringSelection();
1711 m_pRoutePoint->SetPlannedSpeed(0.0);
1715 m_pRoutePoint->SetPlannedSpeed(fromUsrSpeed(spd));
1722 int hour = t.GetHour();
1732 if (dtFormat ==
"Local Time") {
1733 m_pRoutePoint->
SetETD(dt.MakeUTC());
1734 }
else if (dtFormat ==
"UTC") {
1735 m_pRoutePoint->
SetETD(dt);
1744 "Failed to configured ETD. Unsupported date/time format: %s",
1746 m_pRoutePoint->
SetETD(wxInvalidDateTime);
1750 m_pRoutePoint->
SetETD(wxInvalidDateTime);
1755 pSelect->UpdateSelectableRouteSegments(m_pRoutePoint);
1758 wxArrayPtrVoid* pEditRouteArray =
1761 if (pEditRouteArray) {
1762 for (
unsigned int ir = 0; ir < pEditRouteArray->GetCount(); ir++) {
1763 Route* pr = (
Route*)pEditRouteArray->Item(ir);
1764 pr->FinalizeForRendering();
1765 pr->UpdateSegmentDistances();
1768 NavObj_dB::GetInstance().UpdateRoute(pr);
1770 delete pEditRouteArray;
1774 NavObj_dB::GetInstance().UpdateRoutePoint(m_pRoutePoint);
1780SaveDefaultsDialog::SaveDefaultsDialog(
MarkInfoDlg* parent)
1781 : wxDialog(parent, wxID_ANY, _(
"Save some defaults")) {
1783 this->SetSizeHints(wxDefaultSize, wxDefaultSize);
1785 wxBoxSizer* bSizer1 =
new wxBoxSizer(wxVERTICAL);
1786 wxStdDialogButtonSizer* StdDialogButtonSizer1;
1789 new wxStaticText(
this, wxID_ANY,
1790 _(
"Check which properties of current waypoint\n should "
1791 "be set as default for NEW waypoints."));
1792 bSizer1->Add(StaticText1, 0, wxALL | wxALIGN_CENTER_HORIZONTAL, 5);
1794 wxFlexGridSizer* fgSizer1 =
new wxFlexGridSizer(2);
1797 (g_pMarkInfoDialog->m_checkBoxShowName->GetValue() ? _(
"Do use")
1800 new wxCheckBox(
this, wxID_ANY, _(
"Show Waypoint Name"), wxDefaultPosition,
1801 wxDefaultSize, 0, wxDefaultValidator);
1802 fgSizer1->Add(NameCB, 0, wxALL, 5);
1803 stName =
new wxStaticText(
this, wxID_ANY,
"[" + s +
"]", wxDefaultPosition,
1806 fgSizer1->Add(stName, 0, wxALL | wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL, 5);
1808 s = g_pMarkInfoDialog->m_pRoutePoint->GetIconName();
1809 IconCB =
new wxCheckBox(
this, wxID_ANY, _(
"Icon"));
1810 fgSizer1->Add(IconCB, 0, wxALL, 5);
1811 stIcon =
new wxStaticText(
this, wxID_ANY,
"[" + s +
"]", wxDefaultPosition,
1814 fgSizer1->Add(stIcon, 0, wxALL | wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL, 5);
1816 s = (g_pMarkInfoDialog->m_ChoiceWaypointRangeRingsNumber->GetSelection()
1820 g_pMarkInfoDialog->m_ChoiceWaypointRangeRingsNumber
1823 RangRingsCB =
new wxCheckBox(
this, wxID_ANY, _(
"Range rings"));
1824 fgSizer1->Add(RangRingsCB, 0, wxALL, 5);
1825 stRR =
new wxStaticText(
this, wxID_ANY,
"[" + s +
"]", wxDefaultPosition,
1828 fgSizer1->Add(stRR, 0, wxALL | wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL, 5);
1830 s = (g_pMarkInfoDialog->m_textArrivalRadius->GetValue());
1831 ArrivalRCB =
new wxCheckBox(
this, wxID_ANY, _(
"Arrival radius"));
1832 fgSizer1->Add(ArrivalRCB, 0, wxALL, 5);
1833 stArrivalR =
new wxStaticText(
1835 wxString::Format(
"[%s %s]", s.c_str(), getUsrDistanceUnit().c_str()),
1836 wxDefaultPosition, wxDefaultSize, 0);
1837 stArrivalR->Wrap(-1);
1838 fgSizer1->Add(stArrivalR, 0, wxALL | wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL,
1841 s = (g_pMarkInfoDialog->m_checkBoxScaMin->GetValue()
1842 ? _(
"Show only if") +
" < " +
1843 g_pMarkInfoDialog->m_textScaMin->GetValue()
1844 : _(
"Show always"));
1845 ScaleCB =
new wxCheckBox(
this, wxID_ANY, _(
"Show only at scale"));
1846 fgSizer1->Add(ScaleCB, 0, wxALL, 5);
1847 stScale =
new wxStaticText(
this, wxID_ANY,
"[" + s +
"]", wxDefaultPosition,
1850 fgSizer1->Add(stScale, 0, wxALL | wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL, 5);
1852 bSizer1->Add(fgSizer1, 0, wxALL | wxEXPAND, 5);
1854 StdDialogButtonSizer1 =
new wxStdDialogButtonSizer();
1855 StdDialogButtonSizer1->AddButton(
new wxButton(
this, wxID_OK));
1856 StdDialogButtonSizer1->AddButton(
1857 new wxButton(
this, wxID_CANCEL, _(
"Cancel")));
1858 StdDialogButtonSizer1->Realize();
1859 bSizer1->Add(StdDialogButtonSizer1, 0, wxALL | wxEXPAND, 5);
1866 SetSize(parent->GetSize());
1872void MarkInfoDlg::ShowTidesBtnClicked(wxCommandEvent& event) {
1873 if (m_comboBoxTideStation->GetSelection() < 1) {
1877 ptcmgr->GetStationIDXbyName(m_comboBoxTideStation->GetStringSelection(),
1878 fromDMM(m_textLatitude->GetValue()),
1879 fromDMM(m_textLongitude->GetValue())));
1881 TCWin* pCwin =
new TCWin(gFrame->GetPrimaryCanvas(), 0, 0, pIDX);
1884 wxString msg(_(
"Tide Station not found"));
1886 msg += m_comboBoxTideStation->GetStringSelection();
1887 OCPNMessageBox(NULL, msg, _(
"OpenCPN Info"), wxOK | wxCENTER, 10);
Generic Chart canvas base.
Represents an index entry for tidal and current data.
Dialog for displaying and editing waypoint properties.
wxDatePickerCtrl * m_EtdDatePickerCtrl
Date picker control for setting the Estimated Time of Departure (ETD).
wxStaticText * m_staticTextEtd
Label for the Estimated Time of Departure field.
wxCheckBox * m_cbEtdPresent
Checkbox control that enables/disables manual ETD setting for a waypoint.
wxTextCtrl * m_textCtrlPlSpeed
Text control for waypoint planned speed.
wxTimePickerCtrl * m_EtdTimePickerCtrl
Time picker control for setting the Estimated Time of Departure (ETD).
Custom combobox for selecting waypoint icons.
Represents a waypoint or mark within the navigation system.
HyperlinkList * m_HyperlinkList
List of hyperlinks associated with this waypoint.
wxColour m_wxcWaypointRangeRingsColour
Color for the range rings display.
wxString m_MarkDescription
Description text for the waypoint.
bool m_bRPIsBeingEdited
Flag indicating if this waypoint is currently being edited.
wxString m_GUID
Globally Unique Identifier for the waypoint.
wxDateTime GetManualETD()
Retrieves the manually set Estimated Time of Departure for this waypoint, in UTC.
bool m_bIsInRoute
Flag indicating if this waypoint is part of a route.
bool m_bShowName
Flag indicating if the waypoint name should be shown.
double GetPlannedSpeed()
Return the planned speed associated with this waypoint.
bool m_bIsVisible
Flag indicating if the waypoint should be drawn on the chart.
bool m_bIsInLayer
Flag indicating if the waypoint belongs to a layer.
wxString m_TideStation
Associated tide station identifier.
void SetETD(const wxDateTime &etd)
Sets the Estimated Time of Departure for this waypoint, in UTC.
Represents a navigational route in the navigation system.
wxArrayPtrVoid * GetRouteArrayContaining(RoutePoint *pWP)
Find all routes that contain the given waypoint.
Dialog for saving default waypoint properties.
Text field with validator and error handler.
void OnTextChanged(wxCommandEvent &event)
Text changed event handler.
wxFont * GetOCPNScaledFont(wxString item, int default_size)
Retrieves a font from FontMgr, optionally scaled for physical readability.
wxFont GetOCPNGUIScaledFont(wxString item)
Retrieves a font optimized for touch and high-resolution interfaces.
General purpose GUI support.
wxString getUsrDateTimeFormat()
Return the date/time format to use when formatting date/time strings.
PlugInManager and helper classes – Mostly gui parts (dialogs) and plugin API stuff.
GUI library utils and events.