diff options
| author | Carl Hetherington <cth@carlh.net> | 2022-03-18 22:50:12 +0100 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2022-03-18 22:50:23 +0100 |
| commit | 896a5eca680cf6b0605d10523cfc88bfeb4c9810 (patch) | |
| tree | 0e3957c75d5edda27329579717ded36490cc26d2 | |
| parent | 8937b4096aef372dbde07c78d1af9d44b0b0d642 (diff) | |
Preserve checked status during search (#2212).
| -rw-r--r-- | src/wx/screens_panel.cc | 77 | ||||
| -rw-r--r-- | src/wx/screens_panel.h | 11 |
2 files changed, 69 insertions, 19 deletions
diff --git a/src/wx/screens_panel.cc b/src/wx/screens_panel.cc index fc63d618d..34bdadd8e 100644 --- a/src/wx/screens_panel.cc +++ b/src/wx/screens_panel.cc @@ -465,38 +465,77 @@ ScreensPanel::search_changed () } _ignore_selection_change = false; + + _ignore_check_change = true; + + for (auto const& checked: _checked_screens) { + if (auto item = screen_to_item(checked.second)) { + _targets->CheckItem(*item, wxCHK_CHECKED); + setup_cinema_checked_state(*item); + } + } + + _ignore_check_change = false; +} + + +void +ScreensPanel::set_screen_checked (wxTreeListItem item, bool checked) +{ + auto current = std::find_if( + _checked_screens.begin(), _checked_screens.end(), + [item](pair<wxTreeListItem, shared_ptr<Screen>> const& screen) { return screen.first == item; } + ); + + if (current == _checked_screens.end() && checked) { + _checked_screens.push_back({item, item_to_screen(item)}); + } else if (current != _checked_screens.end() && !checked) { + _checked_screens.erase(current); + } +} + + +void +ScreensPanel::setup_cinema_checked_state (wxTreeListItem screen) +{ + auto cinema = _targets->GetItemParent(screen); + DCPOMATIC_ASSERT (cinema.IsOk()); + int checked = 0; + int unchecked = 0; + for (auto child = _targets->GetFirstChild(cinema); child.IsOk(); child = _targets->GetNextSibling(child)) { + if (_targets->GetCheckedState(child) == wxCHK_CHECKED) { + ++checked; + } else { + ++unchecked; + } + } + if (checked == 0) { + _targets->CheckItem(cinema, wxCHK_UNCHECKED); + } else if (unchecked == 0) { + _targets->CheckItem(cinema, wxCHK_CHECKED); + } else { + _targets->CheckItem(cinema, wxCHK_UNDETERMINED); + } } void ScreensPanel::checkbox_changed (wxTreeListEvent& ev) { + if (_ignore_check_change) { + return; + } + if (item_to_cinema(ev.GetItem())) { /* Cinema: check/uncheck all children */ auto const checked = _targets->GetCheckedState(ev.GetItem()); for (auto child = _targets->GetFirstChild(ev.GetItem()); child.IsOk(); child = _targets->GetNextSibling(child)) { _targets->CheckItem(child, checked); + set_screen_checked(child, checked); } } else { - /* Screen: set cinema to checked/unchecked/3state */ - auto parent = _targets->GetItemParent(ev.GetItem()); - DCPOMATIC_ASSERT (parent.IsOk()); - int checked = 0; - int unchecked = 0; - for (auto child = _targets->GetFirstChild(parent); child.IsOk(); child = _targets->GetNextSibling(child)) { - if (_targets->GetCheckedState(child) == wxCHK_CHECKED) { - ++checked; - } else { - ++unchecked; - } - } - if (checked == 0) { - _targets->CheckItem(parent, wxCHK_UNCHECKED); - } else if (unchecked == 0) { - _targets->CheckItem(parent, wxCHK_CHECKED); - } else { - _targets->CheckItem(parent, wxCHK_UNDETERMINED); - } + set_screen_checked(ev.GetItem(), _targets->GetCheckedState(ev.GetItem())); + setup_cinema_checked_state(ev.GetItem()); } ScreensChanged (); diff --git a/src/wx/screens_panel.h b/src/wx/screens_panel.h index 2567725b8..8c818f441 100644 --- a/src/wx/screens_panel.h +++ b/src/wx/screens_panel.h @@ -65,6 +65,8 @@ private: void search_changed (); void checkbox_changed (wxTreeListEvent& ev); boost::optional<std::pair<wxTreeListItem, std::shared_ptr<Cinema>>> cinema_for_operation () const; + void set_screen_checked (wxTreeListItem item, bool checked); + void setup_cinema_checked_state (wxTreeListItem screen); typedef std::vector<std::pair<wxTreeListItem, std::shared_ptr<Cinema>>> Cinemas; typedef std::vector<std::pair<wxTreeListItem, std::shared_ptr<dcpomatic::Screen>>> Screens; @@ -85,8 +87,16 @@ private: Cinemas _cinemas; Screens _screens; + /* We want to be able to search (and so remove selected things from the view) + * but not deselect them, so we maintain lists of selected cinemas and screens. + */ Cinemas _selected_cinemas; Screens _selected_screens; + /* Likewise with checked screens, except that we can work out which cinemas + * are checked from which screens are checked, so we don't need to store the + * cinemas. + */ + Screens _checked_screens; std::map<wxTreeListItem, std::shared_ptr<Cinema>> _item_to_cinema; std::map<wxTreeListItem, std::shared_ptr<dcpomatic::Screen>> _item_to_screen; @@ -94,6 +104,7 @@ private: std::map<std::shared_ptr<dcpomatic::Screen>, wxTreeListItem> _screen_to_item; bool _ignore_selection_change = false; + bool _ignore_check_change = false; class Comparator : public wxTreeListItemComparator { |
