155 std::function<
void()> on_update)
156 : wxPanel(parent, wxID_ANY),
158 m_on_update(std::move(on_update)),
159 kIncludeBtnId(wxWindow::NewControlId()),
160 kExcludeBtnId(wxWindow::NewControlId()),
161 kEditBtnId(wxWindow::NewControlId()),
162 kListboxId(wxWindow::NewControlId()),
163 kSummaryId(wxWindow::NewControlId()),
164 kSetBtnId(wxWindow::NewControlId()),
165 kClearBtnId(wxWindow::NewControlId()) {
166 auto flags = wxSizerFlags(0).Border();
167 auto vbox =
new wxStaticBoxSizer(wxVERTICAL,
this, _(
"Message Types"));
168 auto hbox =
new wxBoxSizer(wxHORIZONTAL);
170 auto radiobox =
new wxBoxSizer(wxVERTICAL);
171 radiobox->Add(
new wxRadioButton(
this, kIncludeBtnId, _(
"Include messages"),
172 wxDefaultPosition, wxDefaultSize,
175 new wxRadioButton(
this, kExcludeBtnId, _(
"Exclude messages")));
176 radiobox->Add(1, 1, 1);
177 radiobox->Add(
new wxButton(
this, kSetBtnId, _(
"Check all")), flags);
178 radiobox->Add(
new wxButton(
this, kClearBtnId, _(
"Clear all")), flags);
179 hbox->Add(radiobox, flags.Expand());
182 wxArrayString choices;
183 auto msg_types = GetActiveMessages();
184 for (
const auto& msg_type : msg_types) choices.Add(msg_type);
185 auto listbox =
new wxCheckListBox(
this, kListboxId, wxDefaultPosition,
186 wxDefaultSize, choices, 1);
187 hbox->Add(
new wxStaticText(
this, kSummaryId,
""), flags);
188 hbox->Add(listbox, flags);
190 auto edit_box =
new wxBoxSizer(wxVERTICAL);
191 auto edit_btn =
new EditButton(
this, kEditBtnId, [&] { OnEditClick(); });
192 edit_box->Add(edit_btn, wxSizerFlags());
193 hbox->Add(edit_box, flags.Expand());
195 wxWindow* btn = GetWindowById<wxWindow>(kSetBtnId);
197 btn->Bind(wxEVT_BUTTON, [&](wxCommandEvent&) { SetAllItems(
true); });
198 btn = GetWindowById<wxWindow>(kClearBtnId);
200 btn->Bind(wxEVT_BUTTON, [&](wxCommandEvent&) { SetAllItems(
false); });
202 vbox->Add(hbox, flags.Expand());
206 GetWindowById<wxStaticText>(kSummaryId)->SetLabel(GetSummary());
209 listbox->Bind(wxEVT_CHECKLISTBOX,
210 [&](wxCommandEvent& ev) { OnItemCheck(ev.GetInt()); });
214 std::string GetListboxItem(wxCheckListBox* listbox,
unsigned i)
const {
215 return listbox->GetString(i).ToStdString();
218 void SetAllItems(
bool value) {
219 auto listbox = GetWindowById<wxCheckListBox>(kListboxId);
220 for (
unsigned i = 0; i < listbox->GetCount(); i += 1) {
221 listbox->Check(i, value);
226 std::string GetSummary() {
227 auto listbox = GetWindowById<wxCheckListBox>(kListboxId);
229 if (m_filter.exclude_msg.empty() && m_filter.include_msg.empty())
231 bool excluded = !m_filter.exclude_msg.empty();
233 excluded ? m_filter.exclude_msg.size() : m_filter.include_msg.size();
234 size_t all = listbox->GetCount();
235 if (all == checked)
return _(
"All");
237 std::stringstream ss;
238 ss <<
"[" << checked << _(
" of ") << all <<
"]";
247 auto listbox = GetWindowById<wxCheckListBox>(kListboxId);
248 auto summary = GetWindowById<wxStaticText>(kSummaryId);
249 auto edit_button = GetWindowById<EditButton>(kEditBtnId);
250 bool is_editing = listbox->IsShown();
251 listbox->Show(!is_editing);
252 summary->Show(is_editing);
253 summary->SetLabel(GetSummary());
254 edit_button->SetIcon(!is_editing);
255 GetWindowById<wxWindow>(kSetBtnId)->Show(!is_editing);
256 GetWindowById<wxWindow>(kClearBtnId)->Show(!is_editing);
265 void OnItemCheck(
int ix) {
266 auto listbox = GetWindowById<wxCheckListBox>(kListboxId);
268 for (
unsigned i = 0; i < listbox->GetCount(); i += 1)
269 if (listbox->IsChecked(i)) checked += 1;
279 void ImportFromFilter() {
280 auto listbox = GetWindowById<wxCheckListBox>(kListboxId);
281 auto exclude_btn = GetWindowById<wxRadioButton>(kExcludeBtnId);
282 auto include_btn = GetWindowById<wxRadioButton>(kIncludeBtnId);
284 exclude_btn->SetValue(m_filter.exclude_msg.size() > 0);
285 if (include_btn->GetValue()) {
286 if (m_filter.include_msg.empty()) {
287 for (
unsigned i = 0; i < listbox->GetCount(); i++) listbox->Check(i);
289 for (
unsigned i = 0; i < listbox->GetCount(); i += 1) {
290 std::string item = GetListboxItem(listbox, i);
291 if (m_filter.include_msg.count(item)) listbox->Check(i);
295 if (m_filter.exclude_msg.empty()) {
296 for (
unsigned i = 0; i < listbox->GetCount(); i++) listbox->Check(i);
298 for (
unsigned i = 0; i < listbox->GetCount(); i += 1) {
299 std::string item = GetListboxItem(listbox, i);
300 if (m_filter.exclude_msg.count(item)) listbox->Check(i);
307 void ExportToFilter() {
308 auto listbox = GetWindowById<wxCheckListBox>(kListboxId);
309 auto include_btn = GetWindowById<wxRadioButton>(kIncludeBtnId);
310 m_filter.include_msg.clear();
311 m_filter.exclude_msg.clear();
313 include_btn->GetValue() ? m_filter.include_msg : m_filter.exclude_msg;
314 for (
unsigned i = 0; i < listbox->GetCount(); i += 1) {
315 if (!listbox->IsChecked(i))
continue;
316 std::string item = GetListboxItem(listbox, i);
317 the_set.insert(item);
319 if (the_set.size() == listbox->GetCount()) {
320 m_filter.include_msg.clear();
321 m_filter.exclude_msg.clear();
327 std::function<void()> m_on_update;
328 const int kIncludeBtnId;
329 const int kExcludeBtnId;
330 const int kEditBtnId;
331 const int kListboxId;
332 const int kSummaryId;
334 const int kClearBtnId;
348 SetPanel(wxWindow* parent, std::set<T>& set, std::function<
void()> on_update,
349 const std::string& label, std::function<wxArrayString()> get_choices)
352 m_on_update(std::move(on_update)),
353 kEditBtnId(wxWindow::NewControlId()),
354 kListboxId(wxWindow::NewControlId()),
355 kListLabelId(wxWindow::NewControlId()) {
356 wxPanel::Create(parent, wxID_ANY);
357 auto flags = wxSizerFlags(0).Border();
358 auto vbox =
new wxBoxSizer(wxVERTICAL);
359 auto hbox =
new wxBoxSizer(wxHORIZONTAL);
360 hbox->Add(
new wxStaticText(
this, wxID_ANY, label), flags);
364 wxArrayString array = get_choices();
366 for (
auto string : array) max_char = wxMax(max_char,
string.Length());
367 int hsize = (max_char + 8) * wxWindow::GetCharWidth();
370 auto listbox =
new wxCheckListBox(
this, kListboxId, wxDefaultPosition,
371 wxSize(hsize, -1), get_choices());
372 hbox->Add(listbox, flags);
373 auto list_label =
new wxStaticText(
this, kListLabelId,
"");
374 hbox->Add(list_label, flags);
375 auto edit_btn =
new EditButton(
this, kEditBtnId, [&] { OnEditClick(); });
376 hbox->Add(edit_btn, flags);
377 vbox->Add(hbox, flags.Expand());
381 list_label->SetLabel(GetListLabel());
392 listbox->Bind(wxEVT_CHECKLISTBOX,
393 [&](wxCommandEvent& ev) { OnItemCheck(ev.GetInt()); });
398 T GetListboxItem(wxCheckListBox* listbox,
unsigned i)
const {
399 if constexpr (std::is_same<T, std::string>::value)
400 return listbox->GetString(i).ToStdString();
401 else if constexpr (std::is_same<T, NavAddr::Bus>::value)
402 return NavAddr::StringToBus(listbox->GetString(i).ToStdString());
403 else if constexpr (std::is_same<T, NavmsgStatus::Direction>::value)
404 return StringToDirection(listbox->GetString(i).ToStdString());
405 else if constexpr (std::is_same<T, NavmsgStatus::Accepted>::value)
407 listbox->GetString(i).ToStdString());
409 assert(
false &&
"bad type...");
413 std::string GetListLabel() {
414 auto listbox = GetWindowById<wxCheckListBox>(kListboxId);
415 if (m_set.empty() || m_set.size() == listbox->GetCount())
return _(
"All");
416 std::stringstream ss;
417 ss <<
"[" << m_set.size() << _(
" of ") << listbox->GetCount() <<
"]";
426 auto listbox = GetWindowById<wxCheckListBox>(kListboxId);
428 auto list_label = GetWindowById<wxStaticText>(kListLabelId);
429 auto edit_button = GetWindowById<EditButton>(kEditBtnId);
430 bool is_editing = listbox->IsShown();
431 listbox->Show(!is_editing);
432 list_label->Show(is_editing);
433 list_label->SetLabel(GetListLabel());
434 edit_button->SetIcon(!is_editing);
442 void OnItemCheck(
int ix) {
443 auto listbox = GetWindowById<wxCheckListBox>(kListboxId);
444 auto list_label = GetWindowById<wxStaticText>(kListLabelId);
446 for (
unsigned i = 0; i < listbox->GetCount(); i += 1)
447 if (listbox->IsChecked(i)) checked += 1;
452 list_label->SetLabel(GetListLabel());
457 void ImportFromFilter() {
458 auto listbox = GetWindowById<wxCheckListBox>(kListboxId);
460 for (
unsigned i = 0; i < listbox->GetCount(); i++) listbox->Check(i);
462 for (
unsigned i = 0; i < listbox->GetCount(); i += 1) {
463 T item = GetListboxItem(listbox, i);
464 if (m_set.count(item) > 0) listbox->Check(i);
470 void ExportToFilter() {
471 auto listbox = GetWindowById<wxCheckListBox>(kListboxId);
473 for (
unsigned i = 0; i < listbox->GetCount(); i += 1) {
474 if (!listbox->IsChecked(i))
continue;
475 T item = GetListboxItem(listbox, i);
478 if (m_set.size() == listbox->GetCount()) m_set.clear();
483 std::function<void()> m_on_update;
484 const int kEditBtnId;
485 const int kListboxId;
486 const int kListLabelId;
566 class Buttons :
public wxPanel {
568 Buttons(wxWindow* parent) : wxPanel(parent, wxID_ANY) {
569 auto vbox =
new wxBoxSizer(wxVERTICAL);
570 auto buttons =
new wxStdDialogButtonSizer();
571 buttons->AddButton(
new wxButton(
this, wxID_CLOSE));
572 buttons->AddButton(
new wxButton(
this, wxID_APPLY));
573 vbox->Add(buttons, wxSizerFlags().Expand());
582 std::function<
void(
const std::string&)> on_update,
583 std::function<
void(
const std::string&)> on_apply)
584 : wxFrame(parent, wxID_ANY,
585 [name] {
return _(
"Edit filter: ") + name; }()),
586 m_on_update(std::move(on_update)),
587 m_on_apply(std::move(on_apply)),
589 SetName(kEditFilterFrameName + name);
590 m_filter = filters_on_disk::Read(m_name);
592 auto flags = wxSizerFlags().Border().Expand();
593 auto vbox =
new wxBoxSizer(wxVERTICAL);
595 vbox->Add(
new IfacePanel(
this, m_filter, [&] { Update(); }), flags);
596 vbox->Add(
new wxStaticLine(
this), flags.Expand());
597 auto buspanel =
new BusPanel(
this, m_filter, [&] { Update(); });
598 vbox->Add(buspanel, flags);
599 vbox->Add(
new wxStaticLine(
this), flags.Expand());
600 vbox->Add(
new DirectionPanel(
this, m_filter, [&] { Update(); }), flags);
601 vbox->Add(
new wxStaticLine(
this), flags.Expand());
602 vbox->Add(
new AcceptedPanel(
this, m_filter, [&] { Update(); }), flags);
603 vbox->Add(
new MsgTypePanel(
this, m_filter, [&] { Update(); }), flags);
604 vbox->Add(
new Buttons(
this), flags);
608 Bind(wxEVT_CLOSE_WINDOW, [&](wxCloseEvent&) { Destroy(); });
609 Bind(wxEVT_BUTTON, [&](wxCommandEvent& evt) { OnButtonEvent(evt); });
614 filters_on_disk::Write(m_filter, m_name);
618 void OnButtonEvent(wxCommandEvent& evt) {
619 if (evt.GetId() == wxID_CLOSE) {
622 }
else if (evt.GetId() == wxID_APPLY) {
628 std::function<void(
const std::string&)> m_on_update;
629 std::function<void(
const std::string&)> m_on_apply;