25 #include <wx/textctrl.h>
27 #include <wx/tokenzr.h>
28 #include <wx/clipbrd.h>
31 #include "androidUTIL.h"
34 #include "model/ais_decoder.h"
36 #include "model/ais_target_data.h"
37 #include "model/route_point.h"
38 #include "model/select.h"
41 #include "AISTargetListDialog.h"
43 #include "ocpn_frame.h"
44 #include "OCPNListCtrl.h"
45 #include "OCPNPlatform.h"
46 #include "routemanagerdialog.h"
51 extern int g_AisTargetList_count;
52 extern bool g_bAisTargetList_autosort;
57 extern wxString g_default_wp_icon;
63 EVT_CLOSE(AISTargetListDialog::OnClose)
66 static
bool g_bsort_once;
73 bool b_cmptype_num =
false;
76 if (!g_bAisTargetList_autosort && !g_bsort_once)
return 0;
81 if (t1->Class == AIS_SART) {
82 if (t2->Class == AIS_DSC)
88 if (t2->Class == AIS_SART) {
89 if (t1->Class == AIS_DSC)
95 switch (g_AisTargetList_sortColumn) {
97 n1 = t1->b_show_track;
98 n2 = t2->b_show_track;
103 s1 = trimAISField(t1->ShipName);
104 if ((!t1->b_nameValid && (t1->Class == AIS_BASE)) ||
105 (t1->Class == AIS_SART))
108 s2 = trimAISField(t2->ShipName);
109 if ((!t2->b_nameValid && (t2->Class == AIS_BASE)) ||
110 (t2->Class == AIS_SART))
115 s1 = trimAISField(t1->CallSign);
116 s2 = trimAISField(t2->CallSign);
122 b_cmptype_num =
true;
126 s1 = t1->Get_class_string(
true);
127 s2 = t2->Get_class_string(
true);
131 s1 = t1->Get_vessel_type_string(
false);
132 if ((t1->Class == AIS_BASE) ||
133 (t1->Class == AIS_SART || (t1->Class == AIS_METEO)))
136 s2 = t2->Get_vessel_type_string(
false);
137 if ((t1->Class == AIS_BASE) || (t1->Class == AIS_SART) ||
138 (t1->Class == AIS_METEO))
143 if ((t1->NavStatus <= 15) && (t1->NavStatus >= 0)) {
144 if (t1->Class == AIS_SART) {
145 if (t1->NavStatus == RESERVED_14)
147 else if (t1->NavStatus == UNDEFINED)
150 s1 = ais_get_status(t1->NavStatus);
154 if ((t1->Class == AIS_ATON) || (t1->Class == AIS_BASE) ||
155 (t1->Class == AIS_CLASS_B) || (t1->Class == AIS_METEO)) s1 = _T(
"-");
157 if ((t2->NavStatus <= 15) && (t2->NavStatus >= 0)) {
158 if (t2->Class == AIS_SART) {
159 if (t2->NavStatus == RESERVED_14)
161 else if (t2->NavStatus == UNDEFINED)
164 s2 = ais_get_status(t2->NavStatus);
168 if ((t2->Class == AIS_ATON) || (t2->Class == AIS_BASE) ||
169 (t2->Class == AIS_CLASS_B) || (t2->Class == AIS_METEO)) s2 = _T(
"-");
175 int brg1 = wxRound(t1->Brg);
181 int brg2 = wxRound(t2->Brg);
187 b_cmptype_num =
true;
192 if ((t1->COG >= 360.0) || (t1->Class == AIS_ATON) ||
193 (t1->Class == AIS_BASE) || (t1->Class == AIS_METEO))
196 int crs = wxRound(t1->COG);
203 if ((t2->COG >= 360.0) || (t2->Class == AIS_ATON) ||
204 (t2->Class == AIS_BASE) || (t2->Class == AIS_METEO))
207 int crs = wxRound(t2->COG);
214 b_cmptype_num =
true;
219 if ((t1->SOG > 100.) || (t1->Class == AIS_ATON) ||
220 (t1->Class == AIS_BASE) || (t1->Class == AIS_METEO))
225 if ((t2->SOG > 100.) || (t2->Class == AIS_ATON) ||
226 (t2->Class == AIS_BASE) || (t2->Class == AIS_METEO))
231 b_cmptype_num =
true;
235 if ((!t1->bCPA_Valid) || (t1->Class == AIS_ATON) ||
236 (t1->Class == AIS_BASE) || (t1->Class == AIS_METEO))
241 if ((!t2->bCPA_Valid) || (t2->Class == AIS_ATON) ||
242 (t2->Class == AIS_BASE))
247 b_cmptype_num =
true;
251 if ((!t1->bCPA_Valid) || (t1->Class == AIS_ATON) ||
252 (t1->Class == AIS_BASE) || (t1->Class == AIS_METEO))
257 if ((!t2->bCPA_Valid) || (t2->Class == AIS_ATON) ||
258 (t2->Class == AIS_BASE) || (t2->Class == AIS_METEO))
263 b_cmptype_num =
true;
269 b_cmptype_num =
true;
277 if (!b_cmptype_num) {
278 if (g_bAisTargetList_sortReverse)
return s2.Cmp(s1);
282 if (g_bAisTargetList_sortReverse) {
288 return (t1->Range_NM > t2->Range_NM);
295 return (t1->Range_NM > t2->Range_NM);
300 static int ArrayItemCompareMMSI(
int MMSI1,
int MMSI2) {
301 if (s_p_sort_decoder) {
302 std::shared_ptr<AisTargetData> pAISTarget1 =
303 s_p_sort_decoder->Get_Target_Data_From_MMSI(MMSI1);
304 std::shared_ptr<AisTargetData> pAISTarget2 =
305 s_p_sort_decoder->Get_Target_Data_From_MMSI(MMSI2);
307 if (pAISTarget1 && pAISTarget2)
308 return ItemCompare(pAISTarget1.get(), pAISTarget2.get());
315 AISTargetListDialog::AISTargetListDialog(wxWindow *parent, wxAuiManager *auimgr,
317 : wxPanel(parent, wxID_ANY, wxDefaultPosition, wxSize(-1, -1 ),
320 m_pAuiManager = auimgr;
321 m_pdecoder = pdecoder;
322 g_bsort_once =
false;
323 m_bautosort_force =
false;
325 wxFont *qFont = GetOCPNScaledFont(_(
"Dialog"));
328 s_p_sort_decoder = pdecoder;
329 m_pMMSI_array =
new ArrayOfMMSI(ArrayItemCompareMMSI);
334 SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
340 wxAuiPaneInfo paneproto = wxAuiPaneInfo()
341 .Name(_T(
"AISTargetList"))
342 .CaptionVisible(
true)
344 .FloatingPosition(50, 50)
345 .FloatingSize(400, 200)
346 .BestSize(700, GetCharHeight() * 10);
350 paneproto.Caption(wxGetTranslation(_(
"AIS target list")));
351 paneproto.Name(_T(
"AISTargetList"));
352 paneproto.DestroyOnClose(
true);
353 paneproto.TopDockable(
false)
354 .BottomDockable(
true)
356 .RightDockable(
false);
357 paneproto.Show(
true);
359 m_pAuiManager->AddPane(
this, paneproto);
361 wxAuiPaneInfo &pane = m_pAuiManager->GetPane(_T(
"AISTargetList"));
363 if (g_AisTargetList_perspective.IsEmpty()) {
364 if (!g_btouch) RecalculateSize();
366 m_pAuiManager->LoadPaneInfo(g_AisTargetList_perspective, pane);
367 m_pAuiManager->Update();
371 m_pAuiManager->GetPane(_T(
"AISTargetList"));
376 pane.Dockable(
false);
378 wxSize screen_size = gFrame->GetClientSize();
379 pane.FloatingSize(screen_size.x * 8 / 10, screen_size.y * 8 / 10);
380 pane.FloatingPosition(screen_size.x * 1 / 10, screen_size.y * 1 / 10);
381 m_pAuiManager->Update();
384 bool b_reset_pos =
false;
385 if ((pane.floating_size.x != -1) && (pane.floating_size.y != -1)) {
390 RECT frame_title_rect;
391 frame_title_rect.left = pane.floating_pos.x;
392 frame_title_rect.top = pane.floating_pos.y;
393 frame_title_rect.right = pane.floating_pos.x + pane.floating_size.x;
394 frame_title_rect.bottom = pane.floating_pos.y + 30;
396 if (NULL == MonitorFromRect(&frame_title_rect, MONITOR_DEFAULTTONULL))
402 wxRect window_title_rect;
403 window_title_rect.x = pane.floating_pos.x;
404 window_title_rect.y = pane.floating_pos.y;
405 window_title_rect.width = pane.floating_size.x;
406 window_title_rect.height = 30;
408 wxRect ClientRect = wxGetClientDisplayRect();
411 if (!ClientRect.Intersects(window_title_rect)) b_reset_pos =
true;
416 pane.FloatingPosition(50, 50);
417 m_pAuiManager->Update();
423 if (pane.IsDocked() && (pane.dock_row == 0)) {
427 m_pAuiManager->Update();
431 m_pAuiManager->Update();
433 g_AisTargetList_perspective = m_pAuiManager->SavePaneInfo(pane);
434 pConfig->UpdateSettings();
436 m_pAuiManager->Connect(
437 wxEVT_AUI_PANE_CLOSE,
438 wxAuiManagerEventHandler(AISTargetListDialog::OnPaneClose), NULL,
this);
445 esize.y = GetCharHeight() * 10;
450 Connect(wxEVT_CONTEXT_MENU,
451 wxCommandEventHandler(AISTargetListDialog::OnRightClickContext), NULL,
455 AISTargetListDialog::~AISTargetListDialog() {
456 Disconnect_decoder();
457 g_pAISTargetList = NULL;
460 void AISTargetListDialog::RecalculateSize() {
464 esize.x = GetCharWidth() * 110;
465 esize.y = GetCharHeight() * 40;
467 wxSize dsize = gFrame->GetClientSize();
468 esize.y = wxMin(esize.y, dsize.y - (4 * GetCharHeight()));
469 esize.x = wxMin(esize.x, dsize.x - (2 * GetCharHeight()));
470 SetClientSize(esize);
472 wxSize fsize = GetSize();
473 fsize.y = wxMin(fsize.y, dsize.y - (2 * GetCharHeight()));
474 fsize.x = wxMin(fsize.x, dsize.x - (2 * GetCharHeight()));
478 wxAuiPaneInfo &pane = m_pAuiManager->GetPane(_T(
"AISTargetList"));
481 pane.FloatingSize(fsize.x, fsize.y);
482 wxPoint pos = gFrame->GetScreenPosition();
483 pane.FloatingPosition(pos.x + (dsize.x - fsize.x) / 2,
484 pos.y + (dsize.y - fsize.y) / 2);
487 m_pAuiManager->Update();
491 void AISTargetListDialog::CreateControls() {
492 wxBoxSizer *topSizer =
new wxBoxSizer(wxHORIZONTAL);
495 this->GetHandle()->setStyleSheet(getQtStyleSheet());
499 wxStringTokenizer tkz(g_AisTargetList_column_spec, _T(
";"));
500 wxString s_width = tkz.GetNextToken();
504 long flags = wxLC_REPORT | wxLC_SINGLE_SEL | wxLC_HRULES | wxLC_VRULES |
507 flags |= wxLC_VIRTUAL;
511 this, ID_AIS_TARGET_LIST, wxDefaultPosition, wxDefaultSize, flags);
513 wxImageList *imglist =
new wxImageList(16, 16,
true, 2);
516 imglist->Add(style->GetIcon(_T(
"sort_asc")));
517 imglist->Add(style->GetIcon(_T(
"sort_desc")));
519 m_pListCtrlAISTargets->AssignImageList(imglist, wxIMAGE_LIST_SMALL);
520 m_pListCtrlAISTargets->Connect(
521 wxEVT_COMMAND_LIST_ITEM_SELECTED,
522 wxListEventHandler(AISTargetListDialog::OnTargetSelected), NULL,
this);
523 m_pListCtrlAISTargets->Connect(
524 wxEVT_COMMAND_LIST_ITEM_DESELECTED,
525 wxListEventHandler(AISTargetListDialog::OnTargetSelected), NULL,
this);
526 m_pListCtrlAISTargets->Connect(
527 wxEVT_COMMAND_LIST_ITEM_ACTIVATED,
528 wxListEventHandler(AISTargetListDialog::OnTargetDefaultAction), NULL,
530 m_pListCtrlAISTargets->Connect(
531 wxEVT_COMMAND_LIST_COL_CLICK,
532 wxListEventHandler(AISTargetListDialog::OnTargetListColumnClicked), NULL,
535 int dx = GetCharWidth();
538 if (s_width.ToLong(&lwidth)) {
539 width = wxMax(dx * 2, lwidth);
540 width = wxMin(width, dx * 30);
542 m_pListCtrlAISTargets->InsertColumn(tlTRK, _(
"Trk"), wxLIST_FORMAT_LEFT,
544 s_width = tkz.GetNextToken();
547 if (s_width.ToLong(&lwidth)) {
548 width = wxMax(dx * 2, lwidth);
549 width = wxMin(width, dx * 30);
551 m_pListCtrlAISTargets->InsertColumn(tlNAME, _(
"Name"), 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(tlCALL, _(
"Call"), 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(tlMMSI, _(
"MMSI"), 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(tlCLASS, _(
"Class"), wxLIST_FORMAT_CENTER,
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(tlTYPE, _(
"Type"), wxLIST_FORMAT_LEFT,
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(tlNAVSTATUS, _(
"Nav Status"),
597 wxLIST_FORMAT_LEFT, width);
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(tlBRG, _(
"Brg"), wxLIST_FORMAT_RIGHT,
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(tlRNG, _(
"Range"), wxLIST_FORMAT_RIGHT,
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(tlCOG, _(
"CoG"), 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(tlSOG, _(
"SoG"), wxLIST_FORMAT_RIGHT,
636 if (s_width.ToLong(&lwidth)) {
637 width = wxMax(dx * 2, lwidth);
638 width = wxMin(width, dx * 30);
640 m_pListCtrlAISTargets->InsertColumn(tlCPA, _(
"CPA"), wxLIST_FORMAT_RIGHT,
644 if (s_width.ToLong(&lwidth)) {
645 width = wxMax(dx * 2, lwidth);
646 width = wxMin(width, dx * 30);
648 m_pListCtrlAISTargets->InsertColumn(tlTCPA, _(
"TCPA"), wxLIST_FORMAT_RIGHT,
651 item.SetMask(wxLIST_MASK_IMAGE);
652 item.SetImage(g_bAisTargetList_sortReverse ? 1 : 0);
653 g_AisTargetList_sortColumn = wxMax(g_AisTargetList_sortColumn, 0);
654 m_pListCtrlAISTargets->SetColumn(g_AisTargetList_sortColumn, item);
656 #ifdef wxHAS_LISTCTRL_COLUMN_ORDER
657 wxStringTokenizer tkz_order(g_AisTargetList_column_order, _T(
";"));
658 wxString s_order = tkz_order.GetNextToken();
659 int i_columns = m_pListCtrlAISTargets->GetColumnCount();
660 wxArrayInt a_order(i_columns);
661 for (
int i = 0; i < i_columns; i++) {
662 long l_order = (long)i;
663 s_order.ToLong(&l_order);
664 if (l_order < 0 || l_order > i_columns) {
667 a_order[i] = l_order;
668 s_order = tkz_order.GetNextToken();
671 m_pListCtrlAISTargets->SetColumnsOrder(a_order);
674 topSizer->Add(m_pListCtrlAISTargets, 1, wxEXPAND | wxALL, 0);
676 wxBoxSizer *boxSizer02 =
new wxBoxSizer(wxVERTICAL);
677 boxSizer02->AddSpacer(22);
678 topSizer->Add(boxSizer02, 0, wxEXPAND | wxALL, 2);
680 wxScrolledWindow *winr =
681 new wxScrolledWindow(
this, wxID_ANY, wxDefaultPosition, wxDefaultSize,
682 wxNO_BORDER | wxTAB_TRAVERSAL | wxVSCROLL);
683 winr->SetScrollRate(0, 5);
685 boxSizer02->Add(winr, 1, wxALL | wxEXPAND, 3);
687 wxBoxSizer *bsRouteButtonsInner =
new wxBoxSizer(wxVERTICAL);
688 winr->SetSizer(bsRouteButtonsInner);
690 m_pButtonInfo =
new wxButton(winr, wxID_ANY, _(
"Target info"),
691 wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW);
692 m_pButtonInfo->Connect(
693 wxEVT_COMMAND_BUTTON_CLICKED,
694 wxCommandEventHandler(AISTargetListDialog::OnTargetQuery), NULL,
this);
695 bsRouteButtonsInner->Add(m_pButtonInfo, 0, wxEXPAND | wxALL, 2);
696 bsRouteButtonsInner->AddSpacer(5);
699 new wxButton(winr, wxID_ANY, _(
"Center view"), wxDefaultPosition,
700 wxDefaultSize, wxBU_AUTODRAW);
701 m_pButtonJumpTo->Connect(
702 wxEVT_COMMAND_BUTTON_CLICKED,
703 wxCommandEventHandler(AISTargetListDialog::OnTargetScrollTo), NULL,
this);
704 bsRouteButtonsInner->Add(m_pButtonJumpTo, 0, wxEXPAND | wxALL, 2);
706 m_pButtonJumpTo_Close =
707 new wxButton(winr, wxID_ANY, _(
"Center-Info-Close"), wxDefaultPosition,
708 wxDefaultSize, wxBU_AUTODRAW);
709 m_pButtonJumpTo_Close->Connect(
710 wxEVT_COMMAND_BUTTON_CLICKED,
711 wxCommandEventHandler(AISTargetListDialog::OnTargetScrollToClose), NULL,
this);
712 bsRouteButtonsInner->Add(m_pButtonJumpTo_Close, 0, wxEXPAND | wxALL, 2);
715 new wxButton(winr, wxID_ANY, _(
"Create WPT"), wxDefaultPosition,
716 wxDefaultSize, wxBU_AUTODRAW);
717 m_pButtonCreateWpt->Connect(
718 wxEVT_COMMAND_BUTTON_CLICKED,
719 wxCommandEventHandler(AISTargetListDialog::OnTargetCreateWpt), NULL,
721 bsRouteButtonsInner->Add(m_pButtonCreateWpt, 0, wxEXPAND | wxALL, 0);
723 m_pButtonHideAllTracks =
724 new wxButton(winr, wxID_ANY, _(
"Hide All Tracks"), wxDefaultPosition,
725 wxDefaultSize, wxBU_AUTODRAW);
726 m_pButtonHideAllTracks->Connect(
727 wxEVT_COMMAND_BUTTON_CLICKED,
728 wxCommandEventHandler(AISTargetListDialog::OnHideAllTracks), NULL,
this);
729 bsRouteButtonsInner->Add(m_pButtonHideAllTracks, 0, wxEXPAND | wxALL, 2);
731 m_pButtonShowAllTracks =
732 new wxButton(winr, wxID_ANY, _(
"Show All Tracks"), wxDefaultPosition,
733 wxDefaultSize, wxBU_AUTODRAW);
734 m_pButtonShowAllTracks->Connect(
735 wxEVT_COMMAND_BUTTON_CLICKED,
736 wxCommandEventHandler(AISTargetListDialog::OnShowAllTracks), NULL,
this);
737 bsRouteButtonsInner->Add(m_pButtonShowAllTracks, 0, wxEXPAND | wxALL, 2);
739 m_pButtonToggleTrack =
740 new wxButton(winr, wxID_ANY, _(
"Toggle track"), wxDefaultPosition,
741 wxDefaultSize, wxBU_AUTODRAW);
742 m_pButtonToggleTrack->Connect(
743 wxEVT_COMMAND_BUTTON_CLICKED,
744 wxCommandEventHandler(AISTargetListDialog::OnToggleTrack), NULL,
this);
745 bsRouteButtonsInner->Add(m_pButtonToggleTrack, 0, wxEXPAND | wxALL, 2);
748 new wxButton(winr, wxID_ANY, _(
"Copy MMSI"), wxDefaultPosition,
749 wxDefaultSize, wxBU_AUTODRAW);
750 m_pButtonCopyMMSI->Connect(
751 wxEVT_COMMAND_BUTTON_CLICKED,
752 wxCommandEventHandler(AISTargetListDialog::OnCopyMMSI), NULL,
this);
753 bsRouteButtonsInner->Add(m_pButtonCopyMMSI, 0, wxEXPAND | wxALL, 2);
756 new wxCheckBox(winr, wxID_ANY, _(
"AutoSort"), wxDefaultPosition,
757 wxDefaultSize, wxBU_AUTODRAW);
758 m_pCBAutosort->Connect(
759 wxEVT_COMMAND_CHECKBOX_CLICKED,
760 wxCommandEventHandler(AISTargetListDialog::OnAutosortCB), NULL,
this);
761 bsRouteButtonsInner->Add(m_pCBAutosort, 0, wxEXPAND | wxALL, 2);
762 g_bAisTargetList_autosort =
true;
763 m_pCBAutosort->SetValue(g_bAisTargetList_autosort);
765 bsRouteButtonsInner->AddSpacer(10);
767 m_pStaticTextRange =
new wxStaticText(winr, wxID_ANY, _(
"Limit range: NM"),
768 wxDefaultPosition, wxDefaultSize, 0);
769 bsRouteButtonsInner->Add(m_pStaticTextRange, 0, wxALL, 2);
770 bsRouteButtonsInner->AddSpacer(2);
771 m_pSpinCtrlRange =
new wxSpinCtrl(
772 winr, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(50, -1),
773 wxSP_ARROW_KEYS, 1, 20000, g_AisTargetList_range);
774 m_pSpinCtrlRange->Connect(
775 wxEVT_COMMAND_SPINCTRL_UPDATED,
776 wxCommandEventHandler(AISTargetListDialog::OnLimitRange), NULL,
this);
777 m_pSpinCtrlRange->Connect(
778 wxEVT_COMMAND_TEXT_UPDATED,
779 wxCommandEventHandler(AISTargetListDialog::OnLimitRange), NULL,
this);
780 bsRouteButtonsInner->Add(m_pSpinCtrlRange, 0, wxEXPAND | wxALL, 0);
782 bsRouteButtonsInner->AddSpacer(10);
783 m_pStaticTextCount =
new wxStaticText(winr, wxID_ANY, _(
"Target Count"),
784 wxDefaultPosition, wxDefaultSize, 0);
785 bsRouteButtonsInner->Add(m_pStaticTextCount, 0, wxALL, 2);
787 bsRouteButtonsInner->AddSpacer(2);
788 m_pTextTargetCount =
new wxTextCtrl(winr, wxID_ANY, _T(
""), wxDefaultPosition,
789 wxDefaultSize, wxTE_READONLY);
790 m_pTextTargetCount->SetMinSize(wxSize(6 * GetCharWidth(), -1));
791 bsRouteButtonsInner->Add(m_pTextTargetCount, 0, wxALL, 2);
793 bsRouteButtonsInner->AddSpacer(10);
794 m_pButtonOK =
new wxButton(winr, wxID_ANY, _(
"Close"), wxDefaultPosition,
795 wxDefaultSize, wxBU_AUTODRAW);
796 m_pButtonOK->Connect(
797 wxEVT_COMMAND_BUTTON_CLICKED,
798 wxCommandEventHandler(AISTargetListDialog::OnCloseButton), NULL,
this);
799 bsRouteButtonsInner->Add(m_pButtonOK, 0, wxEXPAND | wxALL, 0);
806 SetSize(GetSize().x, GetSize().y - 1);
809 void AISTargetListDialog::OnClose(wxCloseEvent &event) {
810 Disconnect_decoder();
812 g_pAISTargetList = NULL;
815 void AISTargetListDialog::Disconnect_decoder() { m_pdecoder = NULL; }
817 void AISTargetListDialog::SetColorScheme() { DimeControl(
this); }
819 void AISTargetListDialog::OnPaneClose(wxAuiManagerEvent &event) {
820 if (event.pane->name == _T(
"AISTargetList")) {
821 g_AisTargetList_perspective = m_pAuiManager->SavePaneInfo(*event.pane);
826 void AISTargetListDialog::OnCloseButton(wxCommandEvent &event) { Shutdown(); }
828 void AISTargetListDialog::Shutdown(
void) {
830 wxAuiPaneInfo pane = m_pAuiManager->GetPane(
this);
831 g_AisTargetList_perspective = m_pAuiManager->SavePaneInfo(pane);
832 m_pAuiManager->DetachPane(
this);
833 Disconnect_decoder();
835 m_pAuiManager->Update();
837 GetParent()->Refresh(
true);
843 void AISTargetListDialog::UpdateButtons() {
845 item = m_pListCtrlAISTargets->GetNextItem(item, wxLIST_NEXT_ALL,
846 wxLIST_STATE_SELECTED);
847 bool enable = (item != -1);
849 m_pButtonInfo->Enable(enable);
851 if (m_pdecoder && item != -1) {
852 auto pAISTargetSel = m_pdecoder->Get_Target_Data_From_MMSI(m_pMMSI_array->Item(item));
853 if (pAISTargetSel && (!pAISTargetSel->b_positionOnceValid)) enable =
false;
855 m_pButtonJumpTo->Enable(enable);
856 m_pButtonJumpTo_Close->Enable(enable);
857 m_pButtonCreateWpt->Enable(enable);
858 m_pButtonToggleTrack->Enable(enable);
859 m_pButtonCopyMMSI->Enable(enable);
862 void AISTargetListDialog::OnTargetSelected(wxListEvent &event) {
866 void AISTargetListDialog::DoTargetQuery(
int mmsi) {
867 ShowAISTargetQueryDialog(m_pparent, mmsi);
874 void AISTargetListDialog::OnTargetDefaultAction(wxListEvent &event) {
876 if ((mmsi_no = event.GetData())) DoTargetQuery(mmsi_no);
879 void AISTargetListDialog::OnTargetQuery(wxCommandEvent &event) {
881 selItemID = m_pListCtrlAISTargets->GetNextItem(selItemID, wxLIST_NEXT_ALL,
882 wxLIST_STATE_SELECTED);
883 if (selItemID == -1)
return;
886 auto pAISTarget = m_pdecoder->Get_Target_Data_From_MMSI(m_pMMSI_array->Item(selItemID));
887 if (pAISTarget) DoTargetQuery(pAISTarget->MMSI);
891 void AISTargetListDialog::OnAutosortCB(wxCommandEvent &event) {
892 g_bAisTargetList_autosort = m_pCBAutosort->GetValue();
894 m_bautosort_force = g_bAisTargetList_autosort;
896 if (!g_bAisTargetList_autosort) {
898 item.SetMask(wxLIST_MASK_IMAGE);
900 g_AisTargetList_sortColumn = wxMax(g_AisTargetList_sortColumn, 0);
901 m_pListCtrlAISTargets->SetColumn(g_AisTargetList_sortColumn, item);
904 item.SetMask(wxLIST_MASK_IMAGE);
905 item.SetImage(g_bAisTargetList_sortReverse ? 1 : 0);
907 if (g_AisTargetList_sortColumn >= 0) {
908 m_pListCtrlAISTargets->SetColumn(g_AisTargetList_sortColumn, item);
909 UpdateAISTargetList();
914 void AISTargetListDialog::OnTargetListColumnClicked(wxListEvent &event) {
915 int key =
event.GetColumn();
917 item.SetMask(wxLIST_MASK_IMAGE);
918 if (key == g_AisTargetList_sortColumn)
919 g_bAisTargetList_sortReverse = !g_bAisTargetList_sortReverse;
922 m_pListCtrlAISTargets->SetColumn(g_AisTargetList_sortColumn, item);
923 g_bAisTargetList_sortReverse =
false;
924 g_AisTargetList_sortColumn = key;
926 item.SetImage(g_bAisTargetList_sortReverse ? 1 : 0);
928 if (!g_bAisTargetList_autosort) g_bsort_once =
true;
930 if (g_AisTargetList_sortColumn >= 0) {
931 m_pListCtrlAISTargets->SetColumn(g_AisTargetList_sortColumn, item);
932 UpdateAISTargetList();
936 void AISTargetListDialog::OnTargetScrollTo(wxCommandEvent &event) {
937 CenterToTarget(
false);
940 void AISTargetListDialog::OnTargetScrollToClose(wxCommandEvent &event) {
941 CenterToTarget(
true);
944 void AISTargetListDialog::OnTargetCreateWpt(wxCommandEvent &event) {
946 selItemID = m_pListCtrlAISTargets->GetNextItem(selItemID, wxLIST_NEXT_ALL,
947 wxLIST_STATE_SELECTED);
948 if (selItemID == -1)
return;
950 std::shared_ptr<AisTargetData> pAISTarget = NULL;
953 m_pdecoder->Get_Target_Data_From_MMSI(m_pMMSI_array->Item(selItemID));
957 new RoutePoint(pAISTarget->Lat, pAISTarget->Lon, g_default_wp_icon,
958 wxEmptyString, wxEmptyString);
959 pWP->m_bIsolatedMark =
true;
960 pSelect->AddSelectableRoutePoint(pAISTarget->Lat, pAISTarget->Lon, pWP);
961 pConfig->AddNewWayPoint(pWP, -1);
963 if (pRouteManagerDialog && pRouteManagerDialog->IsShown())
964 pRouteManagerDialog->UpdateWptListCtrl();
965 gFrame->GetPrimaryCanvas()->undo->BeforeUndoableAction(
966 Undo_CreateWaypoint, pWP, Undo_HasParent, NULL);
967 gFrame->GetPrimaryCanvas()->undo->AfterUndoableAction(NULL);
972 void AISTargetListDialog::OnShowAllTracks(wxCommandEvent &event) {
974 for (
const auto &it : m_pdecoder->GetTargetList()) {
975 auto pAISTarget = it.second;
976 if (NULL != pAISTarget) {
977 pAISTarget->b_show_track =
true;
980 UpdateAISTargetList();
984 void AISTargetListDialog::OnHideAllTracks(wxCommandEvent &event) {
986 for (
const auto &it : m_pdecoder->GetTargetList()) {
987 auto pAISTarget = it.second;
988 if (NULL != pAISTarget) {
989 pAISTarget->b_show_track =
false;
992 std::map<int, Track *>::iterator it;
993 it = g_pAIS->m_persistent_tracks.find(pAISTarget->MMSI);
994 if (it != g_pAIS->m_persistent_tracks.end())
995 pAISTarget->b_show_track =
true;
998 UpdateAISTargetList();
1002 void AISTargetListDialog::OnToggleTrack(wxCommandEvent &event) {
1003 long selItemID = -1;
1004 selItemID = m_pListCtrlAISTargets->GetNextItem(selItemID, wxLIST_NEXT_ALL,
1005 wxLIST_STATE_SELECTED);
1006 if (selItemID == -1)
return;
1008 std::shared_ptr<AisTargetData> pAISTarget = NULL;
1011 m_pdecoder->Get_Target_Data_From_MMSI(m_pMMSI_array->Item(selItemID));
1014 pAISTarget->b_show_track = !pAISTarget->b_show_track;
1015 UpdateAISTargetList();
1019 void AISTargetListDialog::OnCopyMMSI(wxCommandEvent &event) {
1020 long selItemID = -1;
1021 selItemID = m_pListCtrlAISTargets->GetNextItem(selItemID, wxLIST_NEXT_ALL,
1022 wxLIST_STATE_SELECTED);
1023 if (selItemID == -1)
return;
1024 CopyMMSItoClipBoard((
int)m_pMMSI_array->Item(selItemID));
1027 void AISTargetListDialog::CenterToTarget(
bool close) {
1028 long selItemID = -1;
1029 selItemID = m_pListCtrlAISTargets->GetNextItem(selItemID, wxLIST_NEXT_ALL,
1030 wxLIST_STATE_SELECTED);
1031 if (selItemID == -1)
return;
1033 std::shared_ptr<AisTargetData> pAISTarget = NULL;
1036 m_pdecoder->Get_Target_Data_From_MMSI(m_pMMSI_array->Item(selItemID));
1039 double scale = gFrame->GetFocusCanvas()->GetVPScale();
1040 gFrame->JumpToPosition(gFrame->GetFocusCanvas(), pAISTarget->Lat,
1041 pAISTarget->Lon,
scale);
1046 double factor = cc->GetScaleValue() / 5000.0;
1047 cc->DoZoomCanvas(factor,
false);
1049 DoTargetQuery(pAISTarget->MMSI);
1056 void AISTargetListDialog::CopyMMSItoClipBoard(
int mmsi) {
1058 if (wxTheClipboard->Open()) {
1059 wxTheClipboard->SetData(
1060 new wxTextDataObject(wxString::Format(wxT(
"%09d"), mmsi)));
1061 wxTheClipboard->Close();
1064 void AISTargetListDialog::OnLimitRange(wxCommandEvent &event) {
1065 g_AisTargetList_range = m_pSpinCtrlRange->GetValue();
1066 UpdateAISTargetList();
1069 std::shared_ptr<AisTargetData> AISTargetListDialog::GetpTarget(
unsigned int list_item) {
1071 return m_pdecoder->Get_Target_Data_From_MMSI(
1072 m_pMMSI_array->Item(list_item));
1077 void AISTargetListDialog::UpdateAISTargetList(
void) {
1078 if (m_pListCtrlAISTargets && !m_pListCtrlAISTargets->IsVirtual())
1079 return UpdateNVAISTargetList();
1081 if (m_pdecoder && m_pListCtrlAISTargets) {
1083 long selItemID = -1;
1084 selItemID = m_pListCtrlAISTargets->GetNextItem(selItemID, wxLIST_NEXT_ALL,
1085 wxLIST_STATE_SELECTED);
1088 if (selItemID != -1) selMMSI = m_pMMSI_array->Item(selItemID);
1090 const auto ¤t_targets = m_pdecoder->GetTargetList();
1094 m_pMMSI_array->Clear();
1096 for (
auto it = current_targets.begin(); it != current_targets.end();
1098 auto pAISTarget = it->second;
1101 if (NULL != pAISTarget) {
1103 if ((pAISTarget->b_positionOnceValid) &&
1104 (pAISTarget->Range_NM <= g_AisTargetList_range))
1106 else if (!pAISTarget->b_positionOnceValid)
1110 if (pAISTarget->b_lost)
1114 m_pMMSI_array->Add(pAISTarget->MMSI);
1119 g_bsort_once =
false;
1121 m_pListCtrlAISTargets->SetItemCount(m_pMMSI_array->GetCount());
1123 g_AisTargetList_count = m_pMMSI_array->GetCount();
1125 if ((g_AisTargetList_count > 1000) && !m_bautosort_force)
1126 g_bAisTargetList_autosort =
false;
1128 m_pCBAutosort->SetValue(g_bAisTargetList_autosort);
1132 if ((selItemID != -1) && (selMMSI != -1)) {
1133 for (
unsigned int i = 0; i < m_pMMSI_array->GetCount(); i++) {
1134 if (m_pMMSI_array->Item(i) == selMMSI) {
1141 if (m_pMMSI_array->GetCount())
1142 m_pListCtrlAISTargets->SetItemState(
1143 item_sel, wxLIST_STATE_SELECTED | wxLIST_STATE_FOCUSED,
1144 wxLIST_STATE_SELECTED | wxLIST_STATE_FOCUSED);
1146 m_pListCtrlAISTargets->DeleteAllItems();
1149 count.Printf(_T(
"%lu"), (
unsigned long)m_pMMSI_array->GetCount());
1150 m_pTextTargetCount->ChangeValue(count);
1153 m_pListCtrlAISTargets->Refresh(
false);
1158 void AISTargetListDialog::UpdateNVAISTargetList(
void) {
1161 long selItemID = -1;
1162 selItemID = m_pListCtrlAISTargets->GetNextItem(selItemID, wxLIST_NEXT_ALL,
1163 wxLIST_STATE_SELECTED);
1166 if (selItemID != -1) selMMSI = m_pMMSI_array->Item(selItemID);
1168 const auto ¤t_targets = m_pdecoder->GetTargetList();
1172 m_pMMSI_array->Clear();
1174 for (
auto it = current_targets.begin(); it != current_targets.end();
1176 auto pAISTarget = it->second;
1179 if (NULL != pAISTarget) {
1181 if ((pAISTarget->b_positionOnceValid) &&
1182 (pAISTarget->Range_NM <= g_AisTargetList_range))
1184 else if (!pAISTarget->b_positionOnceValid)
1188 m_pMMSI_array->Add(pAISTarget->MMSI);
1193 g_bsort_once =
false;
1195 g_AisTargetList_count = m_pMMSI_array->GetCount();
1197 m_pListCtrlAISTargets->DeleteAllItems();
1199 for (
int i = 0; i < g_AisTargetList_count; i++) {
1202 m_pListCtrlAISTargets->InsertItem(item);
1203 for (
int j = 0; j < tlTCPA + 1; j++) {
1205 item.SetText(m_pListCtrlAISTargets->OnGetItemText(i, j));
1206 m_pListCtrlAISTargets->SetItem(item);
1210 if ((g_AisTargetList_count > 1000) && !m_bautosort_force)
1211 g_bAisTargetList_autosort =
false;
1213 m_pCBAutosort->SetValue(g_bAisTargetList_autosort);
1217 if ((selItemID != -1) && (selMMSI != -1)) {
1218 for (
unsigned int i = 0; i < m_pMMSI_array->GetCount(); i++) {
1219 if (m_pMMSI_array->Item(i) == selMMSI) {
1226 if (m_pMMSI_array->GetCount())
1227 m_pListCtrlAISTargets->SetItemState(
1228 item_sel, wxLIST_STATE_SELECTED | wxLIST_STATE_FOCUSED,
1229 wxLIST_STATE_SELECTED | wxLIST_STATE_FOCUSED);
1231 m_pListCtrlAISTargets->DeleteAllItems();
1234 count.Printf(_T(
"%lu"), (
unsigned long)m_pMMSI_array->GetCount());
1235 m_pTextTargetCount->ChangeValue(count);
1238 m_pListCtrlAISTargets->Refresh(
false);
1243 void AISTargetListDialog::OnRightClickContext(wxCommandEvent &event) {
1244 wxAuiPaneInfo &pane = m_pAuiManager->GetPane(_T(
"AISTargetList"));
1245 if (pane.IsDocked()) {
1246 wxMenu *popup =
new wxMenu();
1247 popup->Append(ID_RCLK_UNDOCK, _(
"Undock Target List"));
1248 popup->Connect(wxEVT_COMMAND_MENU_SELECTED,
1249 wxCommandEventHandler(AISTargetListDialog::OnContextUndock),
1257 void AISTargetListDialog::OnContextUndock(wxCommandEvent &event) {
1258 wxAuiPaneInfo &pane = m_pAuiManager->GetPane(_T(
"AISTargetList"));
1260 m_pAuiManager->Update();
Global state for AIS decoder.