From: Carl Hetherington Date: Sat, 22 Jan 2022 22:21:41 +0000 (+0100) Subject: Use checkboxes to decide which screens KDMs will be made for (#1895). X-Git-Tag: checked-for-v2.16.x~40 X-Git-Url: https://main.carlh.net/gitweb/?p=dcpomatic.git;a=commitdiff_plain;h=0ed0734cc87b642b79ff9f9baaa82639231cd1b3 Use checkboxes to decide which screens KDMs will be made for (#1895). --- diff --git a/src/tools/dcpomatic_kdm.cc b/src/tools/dcpomatic_kdm.cc index 4d84f2f33..4a98619f2 100644 --- a/src/tools/dcpomatic_kdm.cc +++ b/src/tools/dcpomatic_kdm.cc @@ -51,10 +51,11 @@ #include #include "lib/warnings.h" DCPOMATIC_DISABLE_WARNINGS -#include +#include #include #include -#include +#include +#include DCPOMATIC_ENABLE_WARNINGS #ifdef __WXOSX__ #include diff --git a/src/wx/screens_panel.cc b/src/wx/screens_panel.cc index 3c8d51931..534b40604 100644 --- a/src/wx/screens_panel.cc +++ b/src/wx/screens_panel.cc @@ -61,7 +61,8 @@ ScreensPanel::ScreensPanel (wxWindow* parent) sizer->Add (_search, 0, wxBOTTOM, DCPOMATIC_SIZER_GAP); auto targets = new wxBoxSizer (wxHORIZONTAL); - _targets = new TreeCtrl (this); + _targets = new TreeListCtrl (this); + _targets->AppendColumn (wxT("foo")); targets->Add (_targets, 1, wxEXPAND | wxRIGHT, DCPOMATIC_SIZER_GAP); add_cinemas (); @@ -86,7 +87,8 @@ ScreensPanel::ScreensPanel (wxWindow* parent) sizer->Add (targets, 1, wxEXPAND); _search->Bind (wxEVT_TEXT, boost::bind (&ScreensPanel::search_changed, this)); - _targets->Bind (wxEVT_TREE_SEL_CHANGED, &ScreensPanel::selection_changed_shim, this); + _targets->Bind (wxEVT_TREELIST_SELECTION_CHANGED, &ScreensPanel::selection_changed_shim, this); + _targets->Bind (wxEVT_TREELIST_ITEM_CHECKED, &ScreensPanel::checkbox_changed, this); _add_cinema->Bind (wxEVT_BUTTON, boost::bind (&ScreensPanel::add_cinema_clicked, this)); _edit_cinema->Bind (wxEVT_BUTTON, boost::bind (&ScreensPanel::edit_cinema_clicked, this)); @@ -102,7 +104,8 @@ ScreensPanel::ScreensPanel (wxWindow* parent) ScreensPanel::~ScreensPanel () { - _targets->Unbind (wxEVT_TREE_SEL_CHANGED, &ScreensPanel::selection_changed_shim, this); + _targets->Unbind (wxEVT_TREELIST_SELECTION_CHANGED, &ScreensPanel::selection_changed_shim, this); + _targets->Unbind (wxEVT_TREELIST_ITEM_CHECKED, &ScreensPanel::checkbox_changed, this); } @@ -121,7 +124,7 @@ ScreensPanel::setup_sensitivity () } -optional +optional ScreensPanel::add_cinema (shared_ptr c) { auto search = wx_to_std (_search->GetValue ()); @@ -131,11 +134,11 @@ ScreensPanel::add_cinema (shared_ptr c) auto name = c->name; transform (name.begin(), name.end(), name.begin(), ::tolower); if (name.find (search) == string::npos) { - return optional(); + return {}; } } - auto id = _targets->AppendItem(_root, std_to_wx(c->name)); + auto id = _targets->AppendItem(_targets->GetRootItem(), std_to_wx(c->name)); _cinemas[id] = c; @@ -143,13 +146,13 @@ ScreensPanel::add_cinema (shared_ptr c) add_screen (c, i); } - _targets->SortChildren (_root); + _targets->SetSortColumn (0); return id; } -optional +optional ScreensPanel::add_screen (shared_ptr c, shared_ptr s) { auto i = _cinemas.begin(); @@ -175,8 +178,8 @@ ScreensPanel::add_cinema_clicked () Config::instance()->add_cinema (c); auto id = add_cinema (c); if (id) { - _targets->Unselect (); - _targets->SelectItem (*id); + _targets->UnselectAll (); + _targets->Select (*id); } } @@ -226,7 +229,7 @@ ScreensPanel::remove_cinema_clicked () for (auto const& i: _selected_cinemas) { Config::instance()->remove_cinema (i.second); - _targets->Delete (i.first); + _targets->DeleteItem (i.first); } selection_changed (); @@ -344,7 +347,7 @@ ScreensPanel::remove_screen_clicked () } j->second->remove_screen (i.second); - _targets->Delete (i.first); + _targets->DeleteItem (i.first); } Config::instance()->changed (Config::CINEMAS); @@ -354,27 +357,23 @@ ScreensPanel::remove_screen_clicked () list> ScreensPanel::screens () const { - list> s; + list> output; - for (auto const& i: _selected_cinemas) { - for (auto j: i.second->screens()) { - s.push_back (j); + for (auto item = _targets->GetFirstItem(); item.IsOk(); item = _targets->GetNextItem(item)) { + if (_targets->GetCheckedState(item) == wxCHK_CHECKED) { + auto screen_iter = _screens.find(item); + if (screen_iter != _screens.end()) { + output.push_back (screen_iter->second); + } } } - for (auto const& i: _selected_screens) { - s.push_back (i.second); - } - - s.sort (); - s.unique (); - - return s; + return output; } void -ScreensPanel::selection_changed_shim (wxTreeEvent &) +ScreensPanel::selection_changed_shim (wxTreeListEvent &) { selection_changed (); } @@ -387,13 +386,13 @@ ScreensPanel::selection_changed () return; } - wxArrayTreeItemIds s; + wxTreeListItems s; _targets->GetSelections (s); _selected_cinemas.clear (); _selected_screens.clear (); - for (size_t i = 0; i < s.GetCount(); ++i) { + for (size_t i = 0; i < s.size(); ++i) { auto j = _cinemas.find (s[i]); if (j != _cinemas.end ()) { _selected_cinemas[j->first] = j->second; @@ -405,15 +404,12 @@ ScreensPanel::selection_changed () } setup_sensitivity (); - ScreensChanged (); } void ScreensPanel::add_cinemas () { - _root = _targets->AddRoot ("Foo"); - for (auto i: Config::instance()->cinemas()) { add_cinema (i); } @@ -432,14 +428,14 @@ ScreensPanel::search_changed () _ignore_selection_change = true; for (auto const& i: _selected_cinemas) { - /* The wxTreeItemIds will now be different, so we must search by cinema */ + /* The wxTreeListItems will now be different, so we must search by cinema */ auto j = _cinemas.begin (); while (j != _cinemas.end() && j->second != i.second) { ++j; } if (j != _cinemas.end()) { - _targets->SelectItem (j->first); + _targets->Select (j->first); } } @@ -450,7 +446,7 @@ ScreensPanel::search_changed () } if (j != _screens.end()) { - _targets->SelectItem (j->first); + _targets->Select (j->first); } } @@ -458,12 +454,49 @@ ScreensPanel::search_changed () } -wxIMPLEMENT_DYNAMIC_CLASS (TreeCtrl, wxTreeCtrl); +void +ScreensPanel::checkbox_changed (wxTreeListEvent& ev) +{ + if (_cinemas.find(ev.GetItem()) != _cinemas.end()) { + /* 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); + } + } 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); + } + } + + ScreensChanged (); +} + + + +wxIMPLEMENT_DYNAMIC_CLASS (TreeListCtrl, wxTreeListCtrl); int -TreeCtrl::OnCompareItems (wxTreeItemId const& a, wxTreeItemId const& b) +TreeListCtrl::OnCompareItems (wxTreeListItem const& a, wxTreeListItem const& b) { return strcoll (wx_to_std(GetItemText(a)).c_str(), wx_to_std(GetItemText(b)).c_str()); } + diff --git a/src/wx/screens_panel.h b/src/wx/screens_panel.h index 7703d69aa..d5c5144bd 100644 --- a/src/wx/screens_panel.h +++ b/src/wx/screens_panel.h @@ -23,7 +23,7 @@ DCPOMATIC_DISABLE_WARNINGS #include DCPOMATIC_ENABLE_WARNINGS #include -#include +#include #include #include #include @@ -36,22 +36,22 @@ namespace dcpomatic { class Cinema; -/** Shim around wxTreeCtrl so we can use strcoll() to compare things */ -class TreeCtrl : public wxTreeCtrl +/** Shim around wxTreeListCtrl so we can use strcoll() to compare things */ +class TreeListCtrl : public wxTreeListCtrl { public: - wxDECLARE_DYNAMIC_CLASS (TreeCtrl); + wxDECLARE_DYNAMIC_CLASS (TreeListCtrl); - TreeCtrl () {} + TreeListCtrl () {} - TreeCtrl (wxWindow* parent) - : wxTreeCtrl (parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTR_HIDE_ROOT | wxTR_MULTIPLE | wxTR_HAS_BUTTONS | wxTR_LINES_AT_ROOT) + TreeListCtrl (wxWindow* parent) + : wxTreeListCtrl (parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTL_MULTIPLE | wxTL_3STATE | wxTL_NO_HEADER) {} - virtual ~TreeCtrl () {} + virtual ~TreeListCtrl () {} private: - int OnCompareItems (wxTreeItemId const& a, wxTreeItemId const& b); + int OnCompareItems (wxTreeListItem const& a, wxTreeListItem const& b); }; @@ -68,30 +68,30 @@ public: private: void add_cinemas (); - boost::optional add_cinema (std::shared_ptr); - boost::optional add_screen (std::shared_ptr, std::shared_ptr); + boost::optional add_cinema (std::shared_ptr); + boost::optional add_screen (std::shared_ptr, std::shared_ptr); void add_cinema_clicked (); void edit_cinema_clicked (); void remove_cinema_clicked (); void add_screen_clicked (); void edit_screen_clicked (); void remove_screen_clicked (); - void selection_changed_shim (wxTreeEvent &); + void selection_changed_shim (wxTreeListEvent &); void selection_changed (); void search_changed (); + void checkbox_changed (wxTreeListEvent& ev); wxSearchCtrl* _search; - TreeCtrl* _targets; + TreeListCtrl* _targets; wxButton* _add_cinema; wxButton* _edit_cinema; wxButton* _remove_cinema; wxButton* _add_screen; wxButton* _edit_screen; wxButton* _remove_screen; - wxTreeItemId _root; - typedef std::map> CinemaMap; - typedef std::map> ScreenMap; + typedef std::map> CinemaMap; + typedef std::map> ScreenMap; CinemaMap _cinemas; ScreenMap _screens;