25 #include <wx/wxprec.h>
27 #include <wx/html/htmlwin.h>
29 #include "model/ais_decoder.h"
31 #include "model/ais_target_data.h"
32 #include "model/route_point.h"
33 #include "model/select.h"
34 #include "model/track.h"
37 #include "AISTargetQueryDialog.h"
41 #include "ocpn_frame.h"
42 #include "OCPNPlatform.h"
43 #include "routemanagerdialog.h"
46 extern ColorScheme global_color_scheme;
47 extern wxString g_default_wp_icon;
50 extern std::vector<Track*> g_TrackList;
55 #define xID_WPT_CREATE 10010
56 #define xID_TRK_CREATE 10011
60 EVT_BUTTON(xID_OK, AISTargetQueryDialog::OnIdOKClick)
61 EVT_BUTTON(xID_WPT_CREATE, AISTargetQueryDialog::OnIdWptCreateClick)
62 EVT_BUTTON(xID_TRK_CREATE, AISTargetQueryDialog::OnIdTrkCreateClick)
63 EVT_CLOSE(AISTargetQueryDialog::OnClose)
64 EVT_MOVE(AISTargetQueryDialog::OnMove)
65 EVT_SIZE(AISTargetQueryDialog::OnSize)
66 EVT_CHAR_HOOK(AISTargetQueryDialog::OnKey)
72 const wxString &caption,
74 const wxSize &size,
long style) {
76 Create(parent,
id, caption, pos, size, style);
79 AISTargetQueryDialog::~AISTargetQueryDialog() {
delete m_pQueryTextCtl; }
83 m_pQueryTextCtl = NULL;
85 m_colorscheme = (ColorScheme)(-1);
87 m_bautoCentre =
false;
90 void AISTargetQueryDialog::OnClose(wxCloseEvent &event) {
92 g_pais_query_dialog_active = NULL;
95 void AISTargetQueryDialog::OnIdOKClick(wxCommandEvent &event) { Close(); }
97 void AISTargetQueryDialog::OnKey(wxKeyEvent &ke) {
98 if (ke.GetKeyCode() == WXK_ESCAPE)
104 void AISTargetQueryDialog::OnIdWptCreateClick(wxCommandEvent &event) {
106 auto td = g_pAIS->Get_Target_Data_From_MMSI(m_MMSI);
108 wxString n0 = wxString::Format(wxT(
"%s"), td->ShipName);
109 n0.Replace(_T(
"@"), _T(
" "));
111 wxString mmsi = wxString::Format(wxT(
"%i "), td->MMSI);
112 wxString n = _T(
"\"") + n0 + _T(
"\" ") + mmsi;
113 n.append(wxDateTime::Now().Format(wxT(
"%H:%M")));
117 new RoutePoint(td->Lat, td->Lon, g_default_wp_icon, n, wxEmptyString);
118 pWP->m_bIsolatedMark =
true;
119 pSelect->AddSelectableRoutePoint(td->Lat, td->Lon, pWP);
120 pConfig->AddNewWayPoint(pWP, -1);
122 if (pRouteManagerDialog && pRouteManagerDialog->IsShown())
123 pRouteManagerDialog->UpdateWptListCtrl();
124 gFrame->GetPrimaryCanvas()->undo->BeforeUndoableAction(
125 Undo_CreateWaypoint, pWP, Undo_HasParent, NULL);
126 gFrame->GetPrimaryCanvas()->undo->AfterUndoableAction(NULL);
132 void AISTargetQueryDialog::OnIdTrkCreateClick(wxCommandEvent &event) {
134 auto td = g_pAIS->Get_Target_Data_From_MMSI(m_MMSI);
136 if (td->b_PersistTrack)
139 td->b_PersistTrack =
false;
140 g_pAIS->m_persistent_tracks.erase(td->MMSI);
141 m_createTrkBtn->SetLabel(_(
"Record Track"));
142 td->b_show_track =
false;
149 t->SetName(wxString::Format(_T(
"AIS %s (%u) %s %s"),
150 td->GetFullName().c_str(), td->MMSI,
151 wxDateTime::Now().FormatISODate().c_str(),
152 wxDateTime::Now().FormatISOTime().c_str()));
154 vector2D point(ptrack_point.m_lon, ptrack_point.m_lat);
155 tp1 = t->AddNewPoint(point, wxDateTime(ptrack_point.m_time).ToUTC());
157 pSelect->AddSelectableTrackSegment(tp->m_lat, tp->m_lon, tp1->m_lat,
158 tp1->m_lon, tp, tp1, t);
163 g_TrackList.push_back(t);
164 pConfig->AddNewTrack(t);
168 if (pRouteManagerDialog && pRouteManagerDialog->IsShown())
169 pRouteManagerDialog->UpdateTrkListCtrl();
172 if (wxID_YES == OCPNMessageBox(gFrame,
173 _(
"The recently captured track of this target has been "
174 "recorded.\nDo you want to continue recording until the end "
175 "of the current OpenCPN session?"),
176 _(
"OpenCPN Info"), wxYES_NO | wxCENTER, 60)) {
177 td->b_PersistTrack =
true;
178 g_pAIS->m_persistent_tracks[td->MMSI] = t;
179 td->b_show_track =
true;
187 const wxString &caption,
const wxPoint &pos,
188 const wxSize &size,
long style) {
189 long wstyle = AIS_TARGET_QUERY_STYLE;
191 if (!wxFrame::Create(parent,
id, caption, pos, size, wstyle))
return false;
195 wxFont *dFont = FontMgr::Get().GetFont(_(
"AISTargetQuery"));
196 int font_size = wxMax(8, dFont->GetPointSize());
197 wxString face = dFont->GetFaceName();
199 face = _T(
"Monospace");
201 m_basefont = FontMgr::Get().FindOrCreateFont(font_size, wxFONTFAMILY_MODERN,
203 dFont->GetWeight(),
false, face);
205 m_adjustedFontSize = dFont->GetPointSize();
206 m_control_font_size = dFont->GetPointSize();
210 SetColorScheme(global_color_scheme);
213 wxSize sz = g_Platform->getDisplaySize();
214 SetSizeHints(50, 50, sz.x - 20, sz.y - 40);
219 SetSize(-1, m_adjustedFontSize * 30);
225 void AISTargetQueryDialog::SetMMSI(
int mmsi) {
228 auto td = g_pAIS->Get_Target_Data_From_MMSI(m_MMSI);
229 AdjustBestSize(td.get());
232 void AISTargetQueryDialog::RecalculateSize() {
233 auto td = g_pAIS->Get_Target_Data_From_MMSI(m_MMSI);
234 AdjustBestSize(td.get());
238 void AISTargetQueryDialog::SetColorScheme(ColorScheme cs) {
240 wxColor bg = GetBackgroundColour();
241 m_pQueryTextCtl->SetBackgroundColour(bg);
248 wxBitmap tbm(GetSize().x, GetSize().y, -1);
251 tdc.SetBackground(bg);
253 m_pQueryTextCtl->SetBackgroundImage(tbm);
256 if (cs != m_colorscheme) {
262 void AISTargetQueryDialog::CreateControls() {
263 wxBoxSizer *topSizer =
new wxBoxSizer(wxVERTICAL);
267 new wxHtmlWindow(
this, wxID_ANY, wxDefaultPosition, wxDefaultSize,
268 wxHW_SCROLLBAR_AUTO | wxHW_NO_SELECTION);
269 m_pQueryTextCtl->SetBorders(1);
270 m_pQueryTextCtl->SetFont(*m_basefont);
271 topSizer->Add(m_pQueryTextCtl, 1, wxALL | wxEXPAND, 5);
273 wxSizer *opt =
new wxBoxSizer(wxHORIZONTAL);
274 m_createWptBtn =
new wxButton(
this, xID_WPT_CREATE, _(
"Create Waypoint"),
275 wxDefaultPosition, wxDefaultSize, 0);
276 opt->Add(m_createWptBtn, 0, wxALL | wxEXPAND, 5);
278 m_createTrkBtn =
new wxButton(
this, xID_TRK_CREATE, _(
"Record Track"),
279 wxDefaultPosition, wxDefaultSize, 0);
280 opt->Add(m_createTrkBtn, 0, wxALL | wxEXPAND, 5);
281 topSizer->Add(opt, 0, wxALIGN_CENTER_HORIZONTAL | wxBOTTOM, 5);
283 topSizer->Add(
new wxButton(
this, xID_OK, _(
"OK")), 0,
284 wxALIGN_CENTER_HORIZONTAL | wxBOTTOM, 5);
289 void AISTargetQueryDialog::UpdateText() {
292 if (!m_pQueryTextCtl)
return;
294 int scroll_x, scroll_y;
295 m_pQueryTextCtl->GetViewStart(&scroll_x, &scroll_y);
297 auto td = g_pAIS->Get_Target_Data_From_MMSI(m_MMSI);
301 wxColor bg = GetBackgroundColour();
302 m_pQueryTextCtl->SetBackgroundColour(bg);
303 SetBackgroundColour(bg);
306 if (td->b_PersistTrack)
307 m_createTrkBtn->SetLabel(_(
"Stop Tracking"));
309 m_createTrkBtn->SetLabel(_(
"Record Track"));
311 m_createWptBtn->Enable(td->b_positionOnceValid);
313 if (td->Class == AIS_METEO || td->Class == AIS_BASE)
314 m_createTrkBtn->Disable();
316 m_createTrkBtn->Enable();
318 RenderHTMLQuery(td.get());
322 SetColorScheme(m_colorscheme);
325 m_pQueryTextCtl->Scroll(scroll_x, scroll_y);
328 void AISTargetQueryDialog::OnMove(wxMoveEvent &event) {
330 wxPoint p =
event.GetPosition();
331 g_ais_query_dialog_x = p.x;
332 g_ais_query_dialog_y = p.y;
337 void AISTargetQueryDialog::OnSize(wxSizeEvent &event) {
event.Skip(); }
339 void AISTargetQueryDialog::AdjustBestSize(
AisTargetData *td) {
342 wxSize origSize = GetSize();
354 wxSize szv = m_pQueryTextCtl->GetVirtualSize();
355 if (szv.x > m_pQueryTextCtl->GetSize().x) {
356 while ((szv.x > m_pQueryTextCtl->GetSize().x) &&
357 (m_adjustedFontSize > 8)) {
358 m_adjustedFontSize--;
361 m_pQueryTextCtl->Refresh();
362 m_pQueryTextCtl->Update();
364 szv = m_pQueryTextCtl->GetVirtualSize();
367 m_adjustedFontSize--;
369 target_x = szv.x * 12/10;
371 wxSize szv = m_pQueryTextCtl->GetVirtualSize();
372 int csz = g_Platform->getDisplaySize().x * 8 / 10;
374 if (szv.x > m_pQueryTextCtl->GetSize().x) target_x = szv.x;
376 target_x = szv.x * 12/10;
385 if (m_createWptBtn && m_createTrkBtn) {
386 wxSize psz = g_Platform->getDisplaySize();
389 wxFont *tFont = FontMgr::Get().FindOrCreateFont(
390 m_control_font_size, wxFONTFAMILY_MODERN, wxFONTSTYLE_NORMAL,
391 m_basefont->GetWeight(),
false, m_basefont->GetFaceName());
394 wxSize tsz = dc.GetTextExtent(m_createWptBtn->GetLabel() +
395 m_createTrkBtn->GetLabel());
397 float totalButtonWidth = tsz.x;
399 if (totalButtonWidth * 1.5 > psz.x) {
400 float delta = (float)totalButtonWidth * 2. / psz.x;
402 float font_size = m_control_font_size / delta;
404 wxFont *fp_font = FontMgr::Get().FindOrCreateFont(
405 font_size, wxFONTFAMILY_MODERN, wxFONTSTYLE_NORMAL,
406 m_basefont->GetWeight(),
false, m_basefont->GetFaceName());
408 m_createWptBtn->SetFont(*fp_font);
409 m_createTrkBtn->SetFont(*fp_font);
411 m_control_font_size = font_size;
421 if (m_createWptBtn) yb = m_createWptBtn->GetSize().y * 4;
423 wxSize szyv = m_pQueryTextCtl->GetVirtualSize();
424 int csz = g_Platform->getDisplaySize().y * 85 / 100;
425 if ((szyv.y + yb) < csz) {
426 if (szyv.y > m_pQueryTextCtl->GetSize().y)
427 target_y = szyv.y * 12 / 10 + yb;
431 SetSize(target_x, target_y);
433 wxSize nowSize = GetSize();
435 if (nowSize != origSize) {
436 if (m_bautoCentre) Centre();
440 void AISTargetQueryDialog::RenderHTMLQuery(
AisTargetData *td) {
441 int font_size = m_adjustedFontSize;
442 wxFont *fp_font = FontMgr::Get().FindOrCreateFont(
443 font_size, wxFONTFAMILY_MODERN, wxFONTSTYLE_NORMAL,
444 m_basefont->GetWeight(),
false, m_basefont->GetFaceName());
449 for (
int i = -2; i < 5; i++) {
450 sizes[i + 2] = fp_font->GetPointSize() + i + (i > 0 ? i : 0);
454 wxColor bg = GetBackgroundColour();
455 wxColor fg = GetForegroundColour();
458 _T(
"<html><body bgcolor=#%02x%02x%02x><font ")
459 _T(
"color=#%02x%02x%02x><center>"),
460 bg.Red(), bg.Green(), bg.Blue(), fg.Red(), fg.Green(), fg.Blue());
462 html << td->BuildQueryResult();
464 html << _T(
"</center></font></body></html>");
466 m_pQueryTextCtl->SetFonts(fp_font->GetFaceName(), fp_font->GetFaceName(),
469 wxCharBuffer buf = html.ToUTF8();
471 m_pQueryTextCtl->SetPage(html);
Global state for AIS decoder.
AISTargetQueryDialog()
Constructors.
bool Create(wxWindow *parent, wxWindowID id=wxID_ANY, const wxString &caption=_("Object Query"), const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxDefaultSize, long style=AIS_TARGET_QUERY_STYLE)
Creation.
void Init()
Initialise our variables.