27#include <wx/textctrl.h>
29#include <wx/tokenzr.h>
30#include <wx/clipbrd.h>
33#include "androidUTIL.h"
56extern wxString g_default_wp_icon;
61static int g_AisTargetList_count;
63static bool g_bAisTargetList_autosort;
68EVT_CLOSE(AISTargetListDialog::OnClose)
71static
bool g_bsort_once;
77 bool b_cmptype_num =
false;
80 if (!g_bAisTargetList_autosort && !g_bsort_once)
return 0;
85 if (t1->Class == AIS_SART) {
86 if (t2->Class == AIS_DSC)
92 if (t2->Class == AIS_SART) {
93 if (t1->Class == AIS_DSC)
99 switch (g_AisTargetList_sortColumn) {
101 n1 = t1->b_show_track;
102 n2 = t2->b_show_track;
103 b_cmptype_num =
true;
107 s1 = trimAISField(t1->ShipName);
108 if ((!t1->b_nameValid && (t1->Class == AIS_BASE)) ||
109 (t1->Class == AIS_SART))
112 s2 = trimAISField(t2->ShipName);
113 if ((!t2->b_nameValid && (t2->Class == AIS_BASE)) ||
114 (t2->Class == AIS_SART))
119 s1 = trimAISField(t1->CallSign);
120 s2 = trimAISField(t2->CallSign);
126 b_cmptype_num =
true;
130 s1 = t1->Get_class_string(
true);
131 s2 = t2->Get_class_string(
true);
135 s1 = t1->Get_vessel_type_string(
false);
136 if ((t1->Class == AIS_BASE) ||
137 (t1->Class == AIS_SART || (t1->Class == AIS_METEO)))
140 s2 = t2->Get_vessel_type_string(
false);
141 if ((t1->Class == AIS_BASE) || (t1->Class == AIS_SART) ||
142 (t1->Class == AIS_METEO))
147 s1 = t1->GetCountryCode(
true);
148 s2 = t2->GetCountryCode(
true);
151 if ((t1->NavStatus <= 15) && (t1->NavStatus >= 0)) {
152 if (t1->Class == AIS_SART) {
153 if (t1->NavStatus == RESERVED_14)
155 else if (t1->NavStatus == UNDEFINED)
158 s1 = ais_get_status(t1->NavStatus);
162 if ((t1->Class == AIS_ATON) || (t1->Class == AIS_BASE) ||
163 (t1->Class == AIS_CLASS_B) || (t1->Class == AIS_METEO))
166 if ((t2->NavStatus <= 15) && (t2->NavStatus >= 0)) {
167 if (t2->Class == AIS_SART) {
168 if (t2->NavStatus == RESERVED_14)
170 else if (t2->NavStatus == UNDEFINED)
173 s2 = ais_get_status(t2->NavStatus);
177 if ((t2->Class == AIS_ATON) || (t2->Class == AIS_BASE) ||
178 (t2->Class == AIS_CLASS_B) || (t2->Class == AIS_METEO))
185 int brg1 = wxRound(t1->Brg);
191 int brg2 = wxRound(t2->Brg);
197 b_cmptype_num =
true;
202 if ((t1->COG >= 360.0) || (t1->Class == AIS_ATON) ||
203 (t1->Class == AIS_BASE) || (t1->Class == AIS_METEO))
206 int crs = wxRound(t1->COG);
213 if ((t2->COG >= 360.0) || (t2->Class == AIS_ATON) ||
214 (t2->Class == AIS_BASE) || (t2->Class == AIS_METEO))
217 int crs = wxRound(t2->COG);
224 b_cmptype_num =
true;
229 if ((t1->SOG > 100.) || (t1->Class == AIS_ATON) ||
230 (t1->Class == AIS_BASE) || (t1->Class == AIS_METEO))
235 if ((t2->SOG > 100.) || (t2->Class == AIS_ATON) ||
236 (t2->Class == AIS_BASE) || (t2->Class == AIS_METEO))
241 b_cmptype_num =
true;
245 if ((!t1->bCPA_Valid) || (t1->Class == AIS_ATON) ||
246 (t1->Class == AIS_BASE) || (t1->Class == AIS_METEO))
251 if ((!t2->bCPA_Valid) || (t2->Class == AIS_ATON) ||
252 (t2->Class == AIS_BASE))
257 b_cmptype_num =
true;
261 if ((!t1->bCPA_Valid) || (t1->Class == AIS_ATON) ||
262 (t1->Class == AIS_BASE) || (t1->Class == AIS_METEO))
267 if ((!t2->bCPA_Valid) || (t2->Class == AIS_ATON) ||
268 (t2->Class == AIS_BASE) || (t2->Class == AIS_METEO))
273 b_cmptype_num =
true;
279 b_cmptype_num =
true;
287 if (!b_cmptype_num) {
288 if (g_bAisTargetList_sortReverse)
return s2.Cmp(s1);
292 if (g_bAisTargetList_sortReverse) {
298 return (t1->Range_NM > t2->Range_NM);
305 return (t1->Range_NM > t2->Range_NM);
310static int ArrayItemCompareMMSI(
int MMSI1,
int MMSI2) {
311 if (s_p_sort_decoder) {
312 std::shared_ptr<AisTargetData> pAISTarget1 =
313 s_p_sort_decoder->Get_Target_Data_From_MMSI(MMSI1);
314 std::shared_ptr<AisTargetData> pAISTarget2 =
315 s_p_sort_decoder->Get_Target_Data_From_MMSI(MMSI2);
317 if (pAISTarget1 && pAISTarget2)
318 return ItemCompare(pAISTarget1.get(), pAISTarget2.get());
325AISTargetListDialog::AISTargetListDialog(wxWindow *parent, wxAuiManager *auimgr,
327 : wxPanel(parent, wxID_ANY, wxDefaultPosition, wxSize(-1, -1 ),
330 m_pAuiManager = auimgr;
331 m_pdecoder = pdecoder;
332 g_bsort_once =
false;
333 m_bautosort_force =
false;
338 s_p_sort_decoder = pdecoder;
339 m_pMMSI_array =
new ArrayOfMMSI(ArrayItemCompareMMSI);
344 SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
350 wxAuiPaneInfo paneproto = wxAuiPaneInfo()
351 .Name(
"AISTargetList")
352 .CaptionVisible(
true)
354 .FloatingPosition(50, 50)
355 .FloatingSize(400, 200)
356 .BestSize(700, GetCharHeight() * 10);
360 paneproto.Caption(wxGetTranslation(_(
"AIS target list")));
361 paneproto.Name(
"AISTargetList");
362 paneproto.DestroyOnClose(
true);
363 paneproto.TopDockable(
false)
364 .BottomDockable(
true)
366 .RightDockable(
false);
367 paneproto.Show(
true);
369 m_pAuiManager->AddPane(
this, paneproto);
371 wxAuiPaneInfo &pane = m_pAuiManager->GetPane(
"AISTargetList");
373 if (g_AisTargetList_perspective.IsEmpty()) {
374 if (!g_btouch) RecalculateSize();
376 m_pAuiManager->LoadPaneInfo(g_AisTargetList_perspective, pane);
377 m_pAuiManager->Update();
380 pane = m_pAuiManager->GetPane(
"AISTargetList");
385 pane.Dockable(
false);
387 wxSize screen_size = gFrame->GetClientSize();
388 pane.FloatingSize(screen_size.x * 8 / 10, screen_size.y * 8 / 10);
389 pane.FloatingPosition(screen_size.x * 1 / 10, screen_size.y * 1 / 10);
390 m_pAuiManager->Update();
393 bool b_reset_pos =
false;
394 if ((pane.floating_size.x != -1) && (pane.floating_size.y != -1)) {
399 RECT frame_title_rect;
400 frame_title_rect.left = pane.floating_pos.x;
401 frame_title_rect.top = pane.floating_pos.y;
402 frame_title_rect.right = pane.floating_pos.x + pane.floating_size.x;
403 frame_title_rect.bottom = pane.floating_pos.y + 30;
405 if (NULL == MonitorFromRect(&frame_title_rect, MONITOR_DEFAULTTONULL))
411 wxRect window_title_rect;
412 window_title_rect.x = pane.floating_pos.x;
413 window_title_rect.y = pane.floating_pos.y;
414 window_title_rect.width = pane.floating_size.x;
415 window_title_rect.height = 30;
417 wxRect ClientRect = wxGetClientDisplayRect();
420 if (!ClientRect.Intersects(window_title_rect)) b_reset_pos =
true;
425 pane.FloatingPosition(50, 50);
426 m_pAuiManager->Update();
432 if (pane.IsDocked() && (pane.dock_row == 0)) {
436 m_pAuiManager->Update();
440 m_pAuiManager->Update();
442 g_AisTargetList_perspective = m_pAuiManager->SavePaneInfo(pane);
443 pConfig->UpdateSettings();
445 m_pAuiManager->Connect(
446 wxEVT_AUI_PANE_CLOSE,
447 wxAuiManagerEventHandler(AISTargetListDialog::OnPaneClose), NULL,
this);
454 esize.y = GetCharHeight() * 10;
459 Connect(wxEVT_CONTEXT_MENU,
460 wxCommandEventHandler(AISTargetListDialog::OnRightClickContext), NULL,
464AISTargetListDialog::~AISTargetListDialog() {
465 Disconnect_decoder();
469void AISTargetListDialog::RecalculateSize() {
473 esize.x = GetCharWidth() * 110;
474 esize.y = GetCharHeight() * 40;
476 wxSize dsize = gFrame->GetClientSize();
477 esize.y = wxMin(esize.y, dsize.y - (4 * GetCharHeight()));
478 esize.x = wxMin(esize.x, dsize.x - (2 * GetCharHeight()));
479 SetClientSize(esize);
481 wxSize fsize = GetSize();
482 fsize.y = wxMin(fsize.y, dsize.y - (2 * GetCharHeight()));
483 fsize.x = wxMin(fsize.x, dsize.x - (2 * GetCharHeight()));
487 wxAuiPaneInfo &pane = m_pAuiManager->GetPane(
"AISTargetList");
490 pane.FloatingSize(fsize.x, fsize.y);
491 wxPoint pos = gFrame->GetScreenPosition();
492 pane.FloatingPosition(pos.x + (dsize.x - fsize.x) / 2,
493 pos.y + (dsize.y - fsize.y) / 2);
496 m_pAuiManager->Update();
500void AISTargetListDialog::CreateControls() {
501 wxBoxSizer *topSizer =
new wxBoxSizer(wxHORIZONTAL);
504 this->GetHandle()->setStyleSheet(getQtStyleSheet());
508 wxStringTokenizer tkz(g_AisTargetList_column_spec,
";");
509 wxString s_width = tkz.GetNextToken();
513 long flags = wxLC_REPORT | wxLC_SINGLE_SEL | wxLC_HRULES | wxLC_VRULES |
516 flags |= wxLC_VIRTUAL;
520 this, ID_AIS_TARGET_LIST, wxDefaultPosition, wxDefaultSize, flags);
522 wxImageList *imglist =
new wxImageList(16, 16,
true, 2);
525 imglist->Add(style->GetIcon(
"sort_asc"));
526 imglist->Add(style->GetIcon(
"sort_desc"));
528 m_pListCtrlAISTargets->AssignImageList(imglist, wxIMAGE_LIST_SMALL);
529 m_pListCtrlAISTargets->Connect(
530 wxEVT_COMMAND_LIST_ITEM_SELECTED,
531 wxListEventHandler(AISTargetListDialog::OnTargetSelected), NULL,
this);
532 m_pListCtrlAISTargets->Connect(
533 wxEVT_COMMAND_LIST_ITEM_DESELECTED,
534 wxListEventHandler(AISTargetListDialog::OnTargetSelected), NULL,
this);
535 m_pListCtrlAISTargets->Connect(
536 wxEVT_COMMAND_LIST_ITEM_ACTIVATED,
537 wxListEventHandler(AISTargetListDialog::OnTargetDefaultAction), NULL,
539 m_pListCtrlAISTargets->Connect(
540 wxEVT_COMMAND_LIST_COL_CLICK,
541 wxListEventHandler(AISTargetListDialog::OnTargetListColumnClicked), NULL,
544 int dx = GetCharWidth();
547 if (s_width.ToLong(&lwidth)) {
548 width = wxMax(dx * 2, lwidth);
549 width = wxMin(width, dx * 30);
551 m_pListCtrlAISTargets->InsertColumn(tlTRK, _(
"Trk"), wxLIST_FORMAT_LEFT,
553 s_width = tkz.GetNextToken();
556 if (s_width.ToLong(&lwidth)) {
557 width = wxMax(dx * 2, lwidth);
558 width = wxMin(width, dx * 30);
560 m_pListCtrlAISTargets->InsertColumn(tlNAME, _(
"Name"), wxLIST_FORMAT_LEFT,
562 s_width = tkz.GetNextToken();
565 if (s_width.ToLong(&lwidth)) {
566 width = wxMax(dx * 2, lwidth);
567 width = wxMin(width, dx * 30);
569 m_pListCtrlAISTargets->InsertColumn(tlCALL, _(
"Call"), wxLIST_FORMAT_LEFT,
571 s_width = tkz.GetNextToken();
574 if (s_width.ToLong(&lwidth)) {
575 width = wxMax(dx * 2, lwidth);
576 width = wxMin(width, dx * 30);
578 m_pListCtrlAISTargets->InsertColumn(tlMMSI, _(
"MMSI"), wxLIST_FORMAT_LEFT,
580 s_width = tkz.GetNextToken();
583 if (s_width.ToLong(&lwidth)) {
584 width = wxMax(dx * 2, lwidth);
585 width = wxMin(width, dx * 30);
587 m_pListCtrlAISTargets->InsertColumn(tlCLASS, _(
"Class"), wxLIST_FORMAT_CENTER,
589 s_width = tkz.GetNextToken();
592 if (s_width.ToLong(&lwidth)) {
593 width = wxMax(dx * 2, lwidth);
594 width = wxMin(width, dx * 30);
596 m_pListCtrlAISTargets->InsertColumn(tlTYPE, _(
"Type"), wxLIST_FORMAT_LEFT,
598 s_width = tkz.GetNextToken();
601 if (s_width.ToLong(&lwidth)) {
602 width = wxMax(dx * 2, lwidth);
603 width = wxMin(width, dx * 30);
605 m_pListCtrlAISTargets->InsertColumn(tlNAVSTATUS, _(
"Flag"),
606 wxLIST_FORMAT_LEFT, width);
607 s_width = tkz.GetNextToken();
610 if (s_width.ToLong(&lwidth)) {
611 width = wxMax(dx * 2, lwidth);
612 width = wxMin(width, dx * 30);
614 m_pListCtrlAISTargets->InsertColumn(tlNAVSTATUS, _(
"Nav Status"),
615 wxLIST_FORMAT_LEFT, width);
616 s_width = tkz.GetNextToken();
619 if (s_width.ToLong(&lwidth)) {
620 width = wxMax(dx * 2, lwidth);
621 width = wxMin(width, dx * 30);
623 m_pListCtrlAISTargets->InsertColumn(tlBRG, _(
"Brg"), wxLIST_FORMAT_RIGHT,
625 s_width = tkz.GetNextToken();
628 if (s_width.ToLong(&lwidth)) {
629 width = wxMax(dx * 2, lwidth);
630 width = wxMin(width, dx * 30);
632 m_pListCtrlAISTargets->InsertColumn(tlRNG, _(
"Range"), wxLIST_FORMAT_RIGHT,
634 s_width = tkz.GetNextToken();
637 if (s_width.ToLong(&lwidth)) {
638 width = wxMax(dx * 2, lwidth);
639 width = wxMin(width, dx * 30);
641 m_pListCtrlAISTargets->InsertColumn(tlCOG, _(
"CoG"), wxLIST_FORMAT_RIGHT,
643 s_width = tkz.GetNextToken();
646 if (s_width.ToLong(&lwidth)) {
647 width = wxMax(dx * 2, lwidth);
648 width = wxMin(width, dx * 30);
650 m_pListCtrlAISTargets->InsertColumn(tlSOG, _(
"SoG"), wxLIST_FORMAT_RIGHT,
654 if (s_width.ToLong(&lwidth)) {
655 width = wxMax(dx * 2, lwidth);
656 width = wxMin(width, dx * 30);
658 m_pListCtrlAISTargets->InsertColumn(tlCPA, _(
"CPA"), wxLIST_FORMAT_RIGHT,
662 if (s_width.ToLong(&lwidth)) {
663 width = wxMax(dx * 2, lwidth);
664 width = wxMin(width, dx * 30);
666 m_pListCtrlAISTargets->InsertColumn(tlTCPA, _(
"TCPA"), wxLIST_FORMAT_RIGHT,
669 item.SetMask(wxLIST_MASK_IMAGE);
670 item.SetImage(g_bAisTargetList_sortReverse ? 1 : 0);
671 g_AisTargetList_sortColumn = wxMax(g_AisTargetList_sortColumn, 0);
672 m_pListCtrlAISTargets->SetColumn(g_AisTargetList_sortColumn, item);
674#ifdef wxHAS_LISTCTRL_COLUMN_ORDER
675 wxStringTokenizer tkz_order(g_AisTargetList_column_order,
";");
676 wxString s_order = tkz_order.GetNextToken();
677 int i_columns = m_pListCtrlAISTargets->GetColumnCount();
678 wxArrayInt a_order(i_columns);
679 for (
int i = 0; i < i_columns; i++) {
680 long l_order = (long)i;
681 s_order.ToLong(&l_order);
682 if (l_order < 0 || l_order > i_columns) {
685 a_order[i] = l_order;
686 s_order = tkz_order.GetNextToken();
689 m_pListCtrlAISTargets->SetColumnsOrder(a_order);
692 topSizer->Add(m_pListCtrlAISTargets, 1, wxEXPAND | wxALL, 0);
694 wxBoxSizer *boxSizer02 =
new wxBoxSizer(wxVERTICAL);
695 boxSizer02->AddSpacer(22);
696 topSizer->Add(boxSizer02, 0, wxEXPAND | wxALL, 2);
698 wxScrolledWindow *winr =
699 new wxScrolledWindow(
this, wxID_ANY, wxDefaultPosition, wxDefaultSize,
700 wxNO_BORDER | wxTAB_TRAVERSAL | wxVSCROLL);
701 winr->SetScrollRate(0, 5);
703 boxSizer02->Add(winr, 1, wxALL | wxEXPAND, 3);
705 wxBoxSizer *bsRouteButtonsInner =
new wxBoxSizer(wxVERTICAL);
706 winr->SetSizer(bsRouteButtonsInner);
708 m_pButtonInfo =
new wxButton(winr, wxID_ANY, _(
"Target info"),
709 wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW);
710 m_pButtonInfo->Connect(
711 wxEVT_COMMAND_BUTTON_CLICKED,
712 wxCommandEventHandler(AISTargetListDialog::OnTargetQuery), NULL,
this);
713 bsRouteButtonsInner->Add(m_pButtonInfo, 0, wxEXPAND | wxALL, 2);
714 bsRouteButtonsInner->AddSpacer(5);
717 new wxButton(winr, wxID_ANY, _(
"Center view"), wxDefaultPosition,
718 wxDefaultSize, wxBU_AUTODRAW);
719 m_pButtonJumpTo->Connect(
720 wxEVT_COMMAND_BUTTON_CLICKED,
721 wxCommandEventHandler(AISTargetListDialog::OnTargetScrollTo), NULL,
this);
722 bsRouteButtonsInner->Add(m_pButtonJumpTo, 0, wxEXPAND | wxALL, 2);
724 m_pButtonJumpTo_Close =
725 new wxButton(winr, wxID_ANY, _(
"Center-Info-Close"), wxDefaultPosition,
726 wxDefaultSize, wxBU_AUTODRAW);
727 m_pButtonJumpTo_Close->Connect(
728 wxEVT_COMMAND_BUTTON_CLICKED,
729 wxCommandEventHandler(AISTargetListDialog::OnTargetScrollToClose), NULL,
731 bsRouteButtonsInner->Add(m_pButtonJumpTo_Close, 0, wxEXPAND | wxALL, 2);
734 new wxButton(winr, wxID_ANY, _(
"Create WPT"), wxDefaultPosition,
735 wxDefaultSize, wxBU_AUTODRAW);
736 m_pButtonCreateWpt->Connect(
737 wxEVT_COMMAND_BUTTON_CLICKED,
738 wxCommandEventHandler(AISTargetListDialog::OnTargetCreateWpt), NULL,
740 bsRouteButtonsInner->Add(m_pButtonCreateWpt, 0, wxEXPAND | wxALL, 0);
742 m_pButtonHideAllTracks =
743 new wxButton(winr, wxID_ANY, _(
"Hide All Tracks"), wxDefaultPosition,
744 wxDefaultSize, wxBU_AUTODRAW);
745 m_pButtonHideAllTracks->Connect(
746 wxEVT_COMMAND_BUTTON_CLICKED,
747 wxCommandEventHandler(AISTargetListDialog::OnHideAllTracks), NULL,
this);
748 bsRouteButtonsInner->Add(m_pButtonHideAllTracks, 0, wxEXPAND | wxALL, 2);
750 m_pButtonShowAllTracks =
751 new wxButton(winr, wxID_ANY, _(
"Show All Tracks"), wxDefaultPosition,
752 wxDefaultSize, wxBU_AUTODRAW);
753 m_pButtonShowAllTracks->Connect(
754 wxEVT_COMMAND_BUTTON_CLICKED,
755 wxCommandEventHandler(AISTargetListDialog::OnShowAllTracks), NULL,
this);
756 bsRouteButtonsInner->Add(m_pButtonShowAllTracks, 0, wxEXPAND | wxALL, 2);
758 m_pButtonToggleTrack =
759 new wxButton(winr, wxID_ANY, _(
"Toggle track"), wxDefaultPosition,
760 wxDefaultSize, wxBU_AUTODRAW);
761 m_pButtonToggleTrack->Connect(
762 wxEVT_COMMAND_BUTTON_CLICKED,
763 wxCommandEventHandler(AISTargetListDialog::OnToggleTrack), NULL,
this);
764 bsRouteButtonsInner->Add(m_pButtonToggleTrack, 0, wxEXPAND | wxALL, 2);
767 new wxButton(winr, wxID_ANY, _(
"Copy MMSI"), wxDefaultPosition,
768 wxDefaultSize, wxBU_AUTODRAW);
769 m_pButtonCopyMMSI->Connect(
770 wxEVT_COMMAND_BUTTON_CLICKED,
771 wxCommandEventHandler(AISTargetListDialog::OnCopyMMSI), NULL,
this);
772 bsRouteButtonsInner->Add(m_pButtonCopyMMSI, 0, wxEXPAND | wxALL, 2);
774 m_pStaticTextFind =
new wxStaticText(winr, wxID_ANY, _(
"Find target name"),
775 wxDefaultPosition, wxDefaultSize, 0);
776 bsRouteButtonsInner->Add(m_pStaticTextFind, 0, wxALL, 2);
779 new wxTextCtrl(winr, wxID_ANY,
"", wxDefaultPosition, wxDefaultSize, 0);
780 m_pFindTargetName->SetMinSize(wxSize(15 * GetCharWidth(), -1));
781 m_pFindTargetName->Connect(
782 wxEVT_COMMAND_TEXT_UPDATED,
783 wxCommandEventHandler(AISTargetListDialog::OnEditFindTarget), NULL,
this);
784 bsRouteButtonsInner->Add(m_pFindTargetName, 0, wxALL, 2);
787 new wxCheckBox(winr, wxID_ANY, _(
"AutoSort"), wxDefaultPosition,
788 wxDefaultSize, wxBU_AUTODRAW);
789 m_pCBAutosort->Connect(
790 wxEVT_COMMAND_CHECKBOX_CLICKED,
791 wxCommandEventHandler(AISTargetListDialog::OnAutosortCB), NULL,
this);
792 bsRouteButtonsInner->Add(m_pCBAutosort, 0, wxEXPAND | wxALL, 2);
793 g_bAisTargetList_autosort =
true;
794 m_pCBAutosort->SetValue(g_bAisTargetList_autosort);
796 bsRouteButtonsInner->AddSpacer(10);
798 m_pStaticTextRange =
new wxStaticText(winr, wxID_ANY, _(
"Limit range: NM"),
799 wxDefaultPosition, wxDefaultSize, 0);
800 bsRouteButtonsInner->Add(m_pStaticTextRange, 0, wxALL, 2);
801 bsRouteButtonsInner->AddSpacer(2);
802 m_pSpinCtrlRange =
new wxSpinCtrl(
803 winr, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(50, -1),
804 wxSP_ARROW_KEYS, 1, 20000, g_AisTargetList_range);
805 m_pSpinCtrlRange->Connect(
806 wxEVT_COMMAND_SPINCTRL_UPDATED,
807 wxCommandEventHandler(AISTargetListDialog::OnLimitRange), NULL,
this);
808 m_pSpinCtrlRange->Connect(
809 wxEVT_COMMAND_TEXT_UPDATED,
810 wxCommandEventHandler(AISTargetListDialog::OnLimitRange), NULL,
this);
811 bsRouteButtonsInner->Add(m_pSpinCtrlRange, 0, wxEXPAND | wxALL, 0);
813 bsRouteButtonsInner->AddSpacer(10);
814 m_pStaticTextCount =
new wxStaticText(winr, wxID_ANY, _(
"Target Count"),
815 wxDefaultPosition, wxDefaultSize, 0);
816 bsRouteButtonsInner->Add(m_pStaticTextCount, 0, wxALL, 2);
818 bsRouteButtonsInner->AddSpacer(2);
819 m_pTextTargetCount =
new wxTextCtrl(winr, wxID_ANY,
"", wxDefaultPosition,
820 wxDefaultSize, wxTE_READONLY);
821 m_pTextTargetCount->SetMinSize(wxSize(6 * GetCharWidth(), -1));
822 bsRouteButtonsInner->Add(m_pTextTargetCount, 0, wxALL, 2);
824 bsRouteButtonsInner->AddSpacer(10);
825 m_pButtonOK =
new wxButton(winr, wxID_ANY, _(
"Close"), wxDefaultPosition,
826 wxDefaultSize, wxBU_AUTODRAW);
827 m_pButtonOK->Connect(
828 wxEVT_COMMAND_BUTTON_CLICKED,
829 wxCommandEventHandler(AISTargetListDialog::OnCloseButton), NULL,
this);
830 bsRouteButtonsInner->Add(m_pButtonOK, 0, wxEXPAND | wxALL, 0);
837 SetSize(GetSize().x, GetSize().y - 1);
840void AISTargetListDialog::OnClose(wxCloseEvent &event) {
841 Disconnect_decoder();
846void AISTargetListDialog::Disconnect_decoder() { m_pdecoder = NULL; }
848void AISTargetListDialog::SetColorScheme() { DimeControl(
this); }
850void AISTargetListDialog::OnPaneClose(wxAuiManagerEvent &event) {
851 if (event.pane->name ==
"AISTargetList") {
852 g_AisTargetList_perspective = m_pAuiManager->SavePaneInfo(*event.pane);
857void AISTargetListDialog::OnCloseButton(wxCommandEvent &event) { Shutdown(); }
859void AISTargetListDialog::Shutdown() {
861 wxAuiPaneInfo pane = m_pAuiManager->GetPane(
this);
862 g_AisTargetList_perspective = m_pAuiManager->SavePaneInfo(pane);
863 m_pAuiManager->DetachPane(
this);
864 Disconnect_decoder();
866 m_pAuiManager->Update();
868 GetParent()->Refresh(
true);
874void AISTargetListDialog::UpdateButtons() {
876 item = m_pListCtrlAISTargets->GetNextItem(item, wxLIST_NEXT_ALL,
877 wxLIST_STATE_SELECTED);
878 bool enable = (item != -1);
880 m_pButtonInfo->Enable(enable);
882 if (m_pdecoder && item != -1) {
884 m_pdecoder->Get_Target_Data_From_MMSI(m_pMMSI_array->Item(item));
885 if (pAISTargetSel && (!pAISTargetSel->b_positionOnceValid)) enable =
false;
887 m_pButtonJumpTo->Enable(enable);
888 m_pButtonJumpTo_Close->Enable(enable);
889 m_pButtonCreateWpt->Enable(enable);
890 m_pButtonToggleTrack->Enable(enable);
891 m_pButtonCopyMMSI->Enable(enable);
894void AISTargetListDialog::OnTargetSelected(wxListEvent &event) {
898void AISTargetListDialog::DoTargetQuery(
int mmsi) {
899 ShowAISTargetQueryDialog(m_pparent, mmsi);
906void AISTargetListDialog::OnTargetDefaultAction(wxListEvent &event) {
908 if ((mmsi_no = event.GetData())) DoTargetQuery(mmsi_no);
911void AISTargetListDialog::OnTargetQuery(wxCommandEvent &event) {
913 selItemID = m_pListCtrlAISTargets->GetNextItem(selItemID, wxLIST_NEXT_ALL,
914 wxLIST_STATE_SELECTED);
915 if (selItemID == -1)
return;
919 m_pdecoder->Get_Target_Data_From_MMSI(m_pMMSI_array->Item(selItemID));
920 if (pAISTarget) DoTargetQuery(pAISTarget->MMSI);
924void AISTargetListDialog::OnAutosortCB(wxCommandEvent &event) {
925 g_bAisTargetList_autosort = m_pCBAutosort->GetValue();
927 m_bautosort_force = g_bAisTargetList_autosort;
929 if (!g_bAisTargetList_autosort) {
931 item.SetMask(wxLIST_MASK_IMAGE);
933 g_AisTargetList_sortColumn = wxMax(g_AisTargetList_sortColumn, 0);
934 m_pListCtrlAISTargets->SetColumn(g_AisTargetList_sortColumn, item);
937 item.SetMask(wxLIST_MASK_IMAGE);
938 item.SetImage(g_bAisTargetList_sortReverse ? 1 : 0);
940 if (g_AisTargetList_sortColumn >= 0) {
941 m_pListCtrlAISTargets->SetColumn(g_AisTargetList_sortColumn, item);
942 UpdateAISTargetList();
947void AISTargetListDialog::OnTargetListColumnClicked(wxListEvent &event) {
948 int key =
event.GetColumn();
950 item.SetMask(wxLIST_MASK_IMAGE);
951 if (key == g_AisTargetList_sortColumn)
952 g_bAisTargetList_sortReverse = !g_bAisTargetList_sortReverse;
955 m_pListCtrlAISTargets->SetColumn(g_AisTargetList_sortColumn, item);
956 g_bAisTargetList_sortReverse =
false;
957 g_AisTargetList_sortColumn = key;
959 item.SetImage(g_bAisTargetList_sortReverse ? 1 : 0);
961 if (!g_bAisTargetList_autosort) g_bsort_once =
true;
963 if (g_AisTargetList_sortColumn >= 0) {
964 m_pListCtrlAISTargets->SetColumn(g_AisTargetList_sortColumn, item);
965 UpdateAISTargetList();
969void AISTargetListDialog::OnTargetScrollTo(wxCommandEvent &event) {
970 CenterToTarget(
false);
973void AISTargetListDialog::OnTargetScrollToClose(wxCommandEvent &event) {
974 CenterToTarget(
true);
977void AISTargetListDialog::OnTargetCreateWpt(wxCommandEvent &event) {
979 selItemID = m_pListCtrlAISTargets->GetNextItem(selItemID, wxLIST_NEXT_ALL,
980 wxLIST_STATE_SELECTED);
981 if (selItemID == -1)
return;
983 std::shared_ptr<AisTargetData> pAISTarget = NULL;
986 m_pdecoder->Get_Target_Data_From_MMSI(m_pMMSI_array->Item(selItemID));
990 new RoutePoint(pAISTarget->Lat, pAISTarget->Lon, g_default_wp_icon,
991 wxEmptyString, wxEmptyString);
993 pSelect->AddSelectableRoutePoint(pAISTarget->Lat, pAISTarget->Lon, pWP);
995 NavObj_dB::GetInstance().InsertRoutePoint(pWP);
997 if (pRouteManagerDialog && pRouteManagerDialog->IsShown())
998 pRouteManagerDialog->UpdateWptListCtrl();
999 gFrame->GetPrimaryCanvas()->undo->BeforeUndoableAction(
1000 Undo_CreateWaypoint, pWP, Undo_HasParent, NULL);
1001 gFrame->GetPrimaryCanvas()->undo->AfterUndoableAction(NULL);
1006void AISTargetListDialog::OnShowAllTracks(wxCommandEvent &event) {
1008 for (
const auto &it : m_pdecoder->GetTargetList()) {
1009 auto pAISTarget = it.second;
1010 if (NULL != pAISTarget) {
1011 pAISTarget->b_show_track =
true;
1014 std::map<int, Track *>::iterator it;
1015 it =
g_pAIS->m_persistent_tracks.find(pAISTarget->MMSI);
1016 if (it !=
g_pAIS->m_persistent_tracks.end()) {
1017 pAISTarget->b_show_track_old =
true;
1021 UpdateAISTargetList();
1025void AISTargetListDialog::OnHideAllTracks(wxCommandEvent &event) {
1027 for (
const auto &it : m_pdecoder->GetTargetList()) {
1028 auto pAISTarget = it.second;
1029 if (NULL != pAISTarget) {
1030 pAISTarget->b_show_track =
false;
1033 std::map<int, Track *>::iterator it;
1034 it =
g_pAIS->m_persistent_tracks.find(pAISTarget->MMSI);
1035 if (it !=
g_pAIS->m_persistent_tracks.end()) {
1036 pAISTarget->b_show_track =
true;
1037 pAISTarget->b_show_track_old =
false;
1041 UpdateAISTargetList();
1045void AISTargetListDialog::OnToggleTrack(wxCommandEvent &event) {
1046 long selItemID = -1;
1047 selItemID = m_pListCtrlAISTargets->GetNextItem(selItemID, wxLIST_NEXT_ALL,
1048 wxLIST_STATE_SELECTED);
1049 if (selItemID == -1)
return;
1051 std::shared_ptr<AisTargetData> pAISTarget = NULL;
1054 m_pdecoder->Get_Target_Data_From_MMSI(m_pMMSI_array->Item(selItemID));
1057 pAISTarget->b_show_track_old =
1058 pAISTarget->b_show_track;
1059 pAISTarget->b_show_track = !pAISTarget->b_show_track;
1060 UpdateAISTargetList();
1064void AISTargetListDialog::OnCopyMMSI(wxCommandEvent &event) {
1065 long selItemID = -1;
1066 selItemID = m_pListCtrlAISTargets->GetNextItem(selItemID, wxLIST_NEXT_ALL,
1067 wxLIST_STATE_SELECTED);
1068 if (selItemID == -1)
return;
1069 CopyMMSItoClipBoard((
int)m_pMMSI_array->Item(selItemID));
1072void AISTargetListDialog::OnEditFindTarget(wxCommandEvent &event) {
1073 wxString name = m_pFindTargetName->GetValue().MakeUpper();
1074 if (name.size() < 2 || name ==
" ")
return;
1080 for (
const auto &it : m_pdecoder->GetTargetList()) {
1081 auto pAISTarget = it.second;
1082 if (NULL != pAISTarget) {
1083 wxString s = pAISTarget->GetFullName();
1086 int selMMSI = pAISTarget->MMSI;
1087 if (selMMSI != -1) {
1089 for (
unsigned int i = 0; i < m_pMMSI_array->GetCount(); i++) {
1090 if (m_pMMSI_array->Item(i) == selMMSI) {
1102 for (
const auto &it : m_pdecoder->GetTargetList()) {
1103 auto pAISTarget = it.second;
1104 if (NULL != pAISTarget) {
1105 wxString s = pAISTarget->GetFullName();
1106 if (s.Find(name) != wxNOT_FOUND) {
1108 int selMMSI = pAISTarget->MMSI;
1109 if (selMMSI != -1) {
1111 for (
unsigned int i = 0; i < m_pMMSI_array->GetCount(); i++) {
1112 if (m_pMMSI_array->Item(i) == selMMSI) {
1124 if (m_pMMSI_array->GetCount())
1125 m_pListCtrlAISTargets->SetItemState(
1126 item_sel, wxLIST_STATE_SELECTED | wxLIST_STATE_FOCUSED,
1127 wxLIST_STATE_SELECTED | wxLIST_STATE_FOCUSED);
1129 m_pListCtrlAISTargets->EnsureVisible(item_sel);
1130 UpdateAISTargetList();
1135void AISTargetListDialog::CenterToTarget(
bool close) {
1136 long selItemID = -1;
1137 selItemID = m_pListCtrlAISTargets->GetNextItem(selItemID, wxLIST_NEXT_ALL,
1138 wxLIST_STATE_SELECTED);
1139 if (selItemID == -1)
return;
1141 std::shared_ptr<AisTargetData> pAISTarget = NULL;
1144 m_pdecoder->Get_Target_Data_From_MMSI(m_pMMSI_array->Item(selItemID));
1149 gFrame->JumpToPosition(gFrame->GetFocusCanvas(), pAISTarget->Lat,
1150 pAISTarget->Lon,
scale);
1156 factor = cc->GetScaleValue() / 5000.0;
1158 gFrame->JumpToPosition(gFrame->GetFocusCanvas(), pAISTarget->Lat,
1159 pAISTarget->Lon,
scale * factor);
1160 DoTargetQuery(pAISTarget->MMSI);
1167void AISTargetListDialog::CopyMMSItoClipBoard(
int mmsi) {
1169 if (wxTheClipboard->Open()) {
1170 wxTheClipboard->SetData(
1171 new wxTextDataObject(wxString::Format(
"%09d", mmsi)));
1172 wxTheClipboard->Close();
1175void AISTargetListDialog::OnLimitRange(wxCommandEvent &event) {
1176 g_AisTargetList_range = m_pSpinCtrlRange->GetValue();
1177 UpdateAISTargetList();
1180std::shared_ptr<AisTargetData> AISTargetListDialog::GetpTarget(
1181 unsigned int list_item) {
1183 return m_pdecoder->Get_Target_Data_From_MMSI(
1184 m_pMMSI_array->Item(list_item));
1189void AISTargetListDialog::UpdateAISTargetList() {
1190 if (m_pListCtrlAISTargets && !m_pListCtrlAISTargets->IsVirtual())
1191 return UpdateNVAISTargetList();
1193 if (m_pdecoder && m_pListCtrlAISTargets) {
1195 long selItemID = -1;
1196 selItemID = m_pListCtrlAISTargets->GetNextItem(selItemID, wxLIST_NEXT_ALL,
1197 wxLIST_STATE_SELECTED);
1200 if (selItemID != -1) selMMSI = m_pMMSI_array->Item(selItemID);
1202 const auto ¤t_targets = m_pdecoder->GetTargetList();
1206 m_pMMSI_array->Clear();
1208 for (
auto it = current_targets.begin(); it != current_targets.end();
1210 auto pAISTarget = it->second;
1213 if (NULL != pAISTarget) {
1215 if ((pAISTarget->b_positionOnceValid) &&
1216 (pAISTarget->Range_NM <= g_AisTargetList_range))
1218 else if (!pAISTarget->b_positionOnceValid)
1222 if (pAISTarget->b_lost) b_add =
false;
1225 m_pMMSI_array->Add(pAISTarget->MMSI);
1230 g_bsort_once =
false;
1232 m_pListCtrlAISTargets->SetItemCount(m_pMMSI_array->GetCount());
1234 g_AisTargetList_count = m_pMMSI_array->GetCount();
1236 if ((g_AisTargetList_count > 1000) && !m_bautosort_force)
1237 g_bAisTargetList_autosort =
false;
1239 m_pCBAutosort->SetValue(g_bAisTargetList_autosort);
1243 if ((selItemID != -1) && (selMMSI != -1)) {
1244 for (
unsigned int i = 0; i < m_pMMSI_array->GetCount(); i++) {
1245 if (m_pMMSI_array->Item(i) == selMMSI) {
1252 if (m_pMMSI_array->GetCount())
1253 m_pListCtrlAISTargets->SetItemState(
1254 item_sel, wxLIST_STATE_SELECTED | wxLIST_STATE_FOCUSED,
1255 wxLIST_STATE_SELECTED | wxLIST_STATE_FOCUSED);
1257 m_pListCtrlAISTargets->DeleteAllItems();
1260 count.Printf(
"%lu", (
unsigned long)m_pMMSI_array->GetCount());
1261 m_pTextTargetCount->ChangeValue(count);
1264 m_pListCtrlAISTargets->Refresh(
false);
1269void AISTargetListDialog::UpdateNVAISTargetList() {
1272 long selItemID = -1;
1273 selItemID = m_pListCtrlAISTargets->GetNextItem(selItemID, wxLIST_NEXT_ALL,
1274 wxLIST_STATE_SELECTED);
1277 if (selItemID != -1) selMMSI = m_pMMSI_array->Item(selItemID);
1279 const auto ¤t_targets = m_pdecoder->GetTargetList();
1283 m_pMMSI_array->Clear();
1285 for (
auto it = current_targets.begin(); it != current_targets.end();
1287 auto pAISTarget = it->second;
1290 if (NULL != pAISTarget) {
1292 if ((pAISTarget->b_positionOnceValid) &&
1293 (pAISTarget->Range_NM <= g_AisTargetList_range))
1295 else if (!pAISTarget->b_positionOnceValid)
1299 m_pMMSI_array->Add(pAISTarget->MMSI);
1304 g_bsort_once =
false;
1306 g_AisTargetList_count = m_pMMSI_array->GetCount();
1308 m_pListCtrlAISTargets->DeleteAllItems();
1310 for (
int i = 0; i < g_AisTargetList_count; i++) {
1313 m_pListCtrlAISTargets->InsertItem(item);
1314 for (
int j = 0; j < tlTCPA + 1; j++) {
1316 item.SetText(m_pListCtrlAISTargets->OnGetItemText(i, j));
1317 m_pListCtrlAISTargets->SetItem(item);
1321 if ((g_AisTargetList_count > 1000) && !m_bautosort_force)
1322 g_bAisTargetList_autosort =
false;
1324 m_pCBAutosort->SetValue(g_bAisTargetList_autosort);
1328 if ((selItemID != -1) && (selMMSI != -1)) {
1329 for (
unsigned int i = 0; i < m_pMMSI_array->GetCount(); i++) {
1330 if (m_pMMSI_array->Item(i) == selMMSI) {
1337 if (m_pMMSI_array->GetCount())
1338 m_pListCtrlAISTargets->SetItemState(
1339 item_sel, wxLIST_STATE_SELECTED | wxLIST_STATE_FOCUSED,
1340 wxLIST_STATE_SELECTED | wxLIST_STATE_FOCUSED);
1342 m_pListCtrlAISTargets->DeleteAllItems();
1345 count.Printf(
"%lu", (
unsigned long)m_pMMSI_array->GetCount());
1346 m_pTextTargetCount->ChangeValue(count);
1349 m_pListCtrlAISTargets->Refresh(
false);
1354void AISTargetListDialog::OnRightClickContext(wxCommandEvent &event) {
1355 wxAuiPaneInfo &pane = m_pAuiManager->GetPane(
"AISTargetList");
1356 if (pane.IsDocked()) {
1357 wxMenu *popup =
new wxMenu();
1358 popup->Append(ID_RCLK_UNDOCK, _(
"Undock Target List"));
1359 popup->Connect(wxEVT_COMMAND_MENU_SELECTED,
1360 wxCommandEventHandler(AISTargetListDialog::OnContextUndock),
1368void AISTargetListDialog::OnContextUndock(wxCommandEvent &event) {
1369 wxAuiPaneInfo &pane = m_pAuiManager->GetPane(
"AISTargetList");
1371 m_pAuiManager->Update();
AisDecoder * g_pAIS
Global instance.
Class AisDecoder and helpers.
Global state for AIS decoder.
Class AISTargetListDialog.
AISTargetListDialog * g_pAISTargetList
Global instance.
Generic Chart canvas base.
Dialog for displaying a list of AIS targets.
ChartCanvas - Main chart display and interaction component.
float GetVPScale()
Return the ViewPort scale factor, in physical pixels per meter.
A custom list control for displaying AIS target information.
Represents a waypoint or mark within the navigation system.
bool m_bIsolatedMark
Flag indicating if the waypoint is a standalone mark.
wxFont * GetOCPNScaledFont(wxString item, int default_size)
Retrieves a font from FontMgr, optionally scaled for physical readability.
MySQL based storage for routes, tracks, etc.
AIS info display component.
Waypoint or mark abstraction.
Select * pSelect
Global instance.
Selected route, segment, waypoint, etc.