146 std::function<
void()> on_update)
147 : wxPanel(parent, wxID_ANY),
149 m_on_update(std::move(on_update)),
150 kIncludeBtnId(wxWindow::NewControlId()),
151 kExcludeBtnId(wxWindow::NewControlId()),
152 kEditBtnId(wxWindow::NewControlId()),
153 kListboxId(wxWindow::NewControlId()),
154 kSummaryId(wxWindow::NewControlId()),
155 kSetBtnId(wxWindow::NewControlId()),
156 kClearBtnId(wxWindow::NewControlId()) {
157 auto flags = wxSizerFlags(0).Border();
158 auto vbox =
new wxStaticBoxSizer(wxVERTICAL,
this, _(
"Message Types"));
159 auto hbox =
new wxBoxSizer(wxHORIZONTAL);
161 auto radiobox =
new wxBoxSizer(wxVERTICAL);
162 radiobox->Add(
new wxRadioButton(
this, kIncludeBtnId, _(
"Include messages"),
163 wxDefaultPosition, wxDefaultSize,
166 new wxRadioButton(
this, kExcludeBtnId, _(
"Exclude messages")));
167 radiobox->Add(1, 1, 1);
168 radiobox->Add(
new wxButton(
this, kSetBtnId, _(
"Check all")), flags);
169 radiobox->Add(
new wxButton(
this, kClearBtnId, _(
"Clear all")), flags);
170 hbox->Add(radiobox, flags.Expand());
173 wxArrayString choices;
174 auto msg_types = GetActiveMessages();
175 for (
const auto& msg_type : msg_types) choices.Add(msg_type);
176 auto listbox =
new wxCheckListBox(
this, kListboxId, wxDefaultPosition,
177 wxDefaultSize, choices, 1);
178 hbox->Add(
new wxStaticText(
this, kSummaryId,
""), flags);
179 hbox->Add(listbox, flags);
181 auto edit_box =
new wxBoxSizer(wxVERTICAL);
182 auto edit_btn =
new EditButton(
this, kEditBtnId, [&] { OnEditClick(); });
183 edit_box->Add(edit_btn, wxSizerFlags());
184 hbox->Add(edit_box, flags.Expand());
186 wxWindow* btn = GetWindowById<wxWindow>(kSetBtnId);
188 btn->Bind(wxEVT_BUTTON, [&](wxCommandEvent&) { SetAllItems(
true); });
189 btn = GetWindowById<wxWindow>(kClearBtnId);
191 btn->Bind(wxEVT_BUTTON, [&](wxCommandEvent&) { SetAllItems(
false); });
193 vbox->Add(hbox, flags.Expand());
197 GetWindowById<wxStaticText>(kSummaryId)->SetLabel(GetSummary());
200 listbox->Bind(wxEVT_CHECKLISTBOX,
201 [&](wxCommandEvent& ev) { OnItemCheck(ev.GetInt()); });
205 std::string GetListboxItem(wxCheckListBox* listbox,
unsigned i)
const {
206 return listbox->GetString(i).ToStdString();
209 void SetAllItems(
bool value) {
210 auto listbox = GetWindowById<wxCheckListBox>(kListboxId);
211 for (
unsigned i = 0; i < listbox->GetCount(); i += 1) {
212 listbox->Check(i, value);
217 std::string GetSummary() {
218 auto listbox = GetWindowById<wxCheckListBox>(kListboxId);
220 if (m_filter.exclude_msg.empty() && m_filter.include_msg.empty())
222 bool excluded = !m_filter.exclude_msg.empty();
224 excluded ? m_filter.exclude_msg.size() : m_filter.include_msg.size();
225 size_t all = listbox->GetCount();
226 if (all == checked)
return _(
"All");
228 std::stringstream ss;
229 ss <<
"[" << checked << _(
" of ") << all <<
"]";
238 auto listbox = GetWindowById<wxCheckListBox>(kListboxId);
239 auto summary = GetWindowById<wxStaticText>(kSummaryId);
240 auto edit_button = GetWindowById<EditButton>(kEditBtnId);
241 bool is_editing = listbox->IsShown();
242 listbox->Show(!is_editing);
243 summary->Show(is_editing);
244 summary->SetLabel(GetSummary());
245 edit_button->SetIcon(!is_editing);
246 GetWindowById<wxWindow>(kSetBtnId)->Show(!is_editing);
247 GetWindowById<wxWindow>(kClearBtnId)->Show(!is_editing);
256 void OnItemCheck(
int ix) {
257 auto listbox = GetWindowById<wxCheckListBox>(kListboxId);
259 for (
unsigned i = 0; i < listbox->GetCount(); i += 1)
260 if (listbox->IsChecked(i)) checked += 1;
270 void ImportFromFilter() {
271 auto listbox = GetWindowById<wxCheckListBox>(kListboxId);
272 auto exclude_btn = GetWindowById<wxRadioButton>(kExcludeBtnId);
273 auto include_btn = GetWindowById<wxRadioButton>(kIncludeBtnId);
275 exclude_btn->SetValue(m_filter.exclude_msg.size() > 0);
276 if (include_btn->GetValue()) {
277 if (m_filter.include_msg.empty()) {
278 for (
unsigned i = 0; i < listbox->GetCount(); i++) listbox->Check(i);
280 for (
unsigned i = 0; i < listbox->GetCount(); i += 1) {
281 std::string item = GetListboxItem(listbox, i);
282 if (m_filter.include_msg.count(item)) listbox->Check(i);
286 if (m_filter.exclude_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.exclude_msg.count(item)) listbox->Check(i);
298 void ExportToFilter() {
299 auto listbox = GetWindowById<wxCheckListBox>(kListboxId);
300 auto include_btn = GetWindowById<wxRadioButton>(kIncludeBtnId);
301 m_filter.include_msg.clear();
302 m_filter.exclude_msg.clear();
304 include_btn->GetValue() ? m_filter.include_msg : m_filter.exclude_msg;
305 for (
unsigned i = 0; i < listbox->GetCount(); i += 1) {
306 if (!listbox->IsChecked(i))
continue;
307 std::string item = GetListboxItem(listbox, i);
308 the_set.insert(item);
310 if (the_set.size() == listbox->GetCount()) {
311 m_filter.include_msg.clear();
312 m_filter.exclude_msg.clear();
318 std::function<void()> m_on_update;
319 const int kIncludeBtnId;
320 const int kExcludeBtnId;
321 const int kEditBtnId;
322 const int kListboxId;
323 const int kSummaryId;
325 const int kClearBtnId;
339 SetPanel(wxWindow* parent, std::set<T>& set, std::function<
void()> on_update,
340 const std::string& label, std::function<wxArrayString()> get_choices)
343 m_on_update(std::move(on_update)),
344 kEditBtnId(wxWindow::NewControlId()),
345 kListboxId(wxWindow::NewControlId()),
346 kListLabelId(wxWindow::NewControlId()) {
347 wxPanel::Create(parent, wxID_ANY);
348 auto flags = wxSizerFlags(0).Border();
349 auto vbox =
new wxBoxSizer(wxVERTICAL);
350 auto hbox =
new wxBoxSizer(wxHORIZONTAL);
351 hbox->Add(
new wxStaticText(
this, wxID_ANY, label), flags);
355 wxArrayString array = get_choices();
357 for (
auto string : array) max_char = wxMax(max_char,
string.Length());
358 int hsize = (max_char + 8) * wxWindow::GetCharWidth();
361 auto listbox =
new wxCheckListBox(
this, kListboxId, wxDefaultPosition,
362 wxSize(hsize, -1), get_choices());
363 hbox->Add(listbox, flags);
364 auto list_label =
new wxStaticText(
this, kListLabelId,
"");
365 hbox->Add(list_label, flags);
366 auto edit_btn =
new EditButton(
this, kEditBtnId, [&] { OnEditClick(); });
367 hbox->Add(edit_btn, flags);
368 vbox->Add(hbox, flags.Expand());
372 list_label->SetLabel(GetListLabel());
383 listbox->Bind(wxEVT_CHECKLISTBOX,
384 [&](wxCommandEvent& ev) { OnItemCheck(ev.GetInt()); });
389 T GetListboxItem(wxCheckListBox* listbox,
unsigned i)
const {
390 if constexpr (std::is_same<T, std::string>::value)
391 return listbox->GetString(i).ToStdString();
392 else if constexpr (std::is_same<T, NavAddr::Bus>::value)
393 return NavAddr::StringToBus(listbox->GetString(i).ToStdString());
394 else if constexpr (std::is_same<T, NavmsgStatus::Direction>::value)
395 return StringToDirection(listbox->GetString(i).ToStdString());
396 else if constexpr (std::is_same<T, NavmsgStatus::Accepted>::value)
398 listbox->GetString(i).ToStdString());
400 assert(
false &&
"bad type...");
404 std::string GetListLabel() {
405 auto listbox = GetWindowById<wxCheckListBox>(kListboxId);
406 if (m_set.empty() || m_set.size() == listbox->GetCount())
return _(
"All");
407 std::stringstream ss;
408 ss <<
"[" << m_set.size() << _(
" of ") << listbox->GetCount() <<
"]";
417 auto listbox = GetWindowById<wxCheckListBox>(kListboxId);
419 auto list_label = GetWindowById<wxStaticText>(kListLabelId);
420 auto edit_button = GetWindowById<EditButton>(kEditBtnId);
421 bool is_editing = listbox->IsShown();
422 listbox->Show(!is_editing);
423 list_label->Show(is_editing);
424 list_label->SetLabel(GetListLabel());
425 edit_button->SetIcon(!is_editing);
433 void OnItemCheck(
int ix) {
434 auto listbox = GetWindowById<wxCheckListBox>(kListboxId);
435 auto list_label = GetWindowById<wxStaticText>(kListLabelId);
437 for (
unsigned i = 0; i < listbox->GetCount(); i += 1)
438 if (listbox->IsChecked(i)) checked += 1;
443 list_label->SetLabel(GetListLabel());
448 void ImportFromFilter() {
449 auto listbox = GetWindowById<wxCheckListBox>(kListboxId);
451 for (
unsigned i = 0; i < listbox->GetCount(); i++) listbox->Check(i);
453 for (
unsigned i = 0; i < listbox->GetCount(); i += 1) {
454 T item = GetListboxItem(listbox, i);
455 if (m_set.count(item) > 0) listbox->Check(i);
461 void ExportToFilter() {
462 auto listbox = GetWindowById<wxCheckListBox>(kListboxId);
464 for (
unsigned i = 0; i < listbox->GetCount(); i += 1) {
465 if (!listbox->IsChecked(i))
continue;
466 T item = GetListboxItem(listbox, i);
469 if (m_set.size() == listbox->GetCount()) m_set.clear();
474 std::function<void()> m_on_update;
475 const int kEditBtnId;
476 const int kListboxId;
477 const int kListLabelId;
557 class Buttons :
public wxPanel {
559 Buttons(wxWindow* parent) : wxPanel(parent, wxID_ANY) {
560 auto vbox =
new wxBoxSizer(wxVERTICAL);
561 auto buttons =
new wxStdDialogButtonSizer();
562 buttons->AddButton(
new wxButton(
this, wxID_CLOSE));
563 buttons->AddButton(
new wxButton(
this, wxID_APPLY));
564 vbox->Add(buttons, wxSizerFlags().Expand());
573 std::function<
void(
const std::string&)> on_update,
574 std::function<
void(
const std::string&)> on_apply)
575 : wxFrame(parent, wxID_ANY,
576 [name] {
return _(
"Edit filter: ") + name; }()),
577 m_on_update(std::move(on_update)),
578 m_on_apply(std::move(on_apply)),
580 SetName(kEditFilterFrameName + name);
581 m_filter = filters_on_disk::Read(m_name);
583 auto flags = wxSizerFlags().Border().Expand();
584 auto vbox =
new wxBoxSizer(wxVERTICAL);
586 vbox->Add(
new IfacePanel(
this, m_filter, [&] { Update(); }), flags);
587 vbox->Add(
new wxStaticLine(
this), flags.Expand());
588 auto buspanel =
new BusPanel(
this, m_filter, [&] { Update(); });
589 vbox->Add(buspanel, flags);
590 vbox->Add(
new wxStaticLine(
this), flags.Expand());
591 vbox->Add(
new DirectionPanel(
this, m_filter, [&] { Update(); }), flags);
592 vbox->Add(
new wxStaticLine(
this), flags.Expand());
593 vbox->Add(
new AcceptedPanel(
this, m_filter, [&] { Update(); }), flags);
594 vbox->Add(
new MsgTypePanel(
this, m_filter, [&] { Update(); }), flags);
595 vbox->Add(
new Buttons(
this), flags);
599 Bind(wxEVT_CLOSE_WINDOW, [&](wxCloseEvent&) { Destroy(); });
600 Bind(wxEVT_BUTTON, [&](wxCommandEvent& evt) { OnButtonEvent(evt); });
605 filters_on_disk::Write(m_filter, m_name);
609 void OnButtonEvent(wxCommandEvent& evt) {
610 if (evt.GetId() == wxID_CLOSE) {
613 }
else if (evt.GetId() == wxID_APPLY) {
619 std::function<void(
const std::string&)> m_on_update;
620 std::function<void(
const std::string&)> m_on_apply;