X-Git-Url: https://git.carlh.net/gitweb/?a=blobdiff_plain;f=src%2Fwx%2Fscreens_panel.cc;h=5f903eda4851c22745e1935703225cfed54a7623;hb=6b9450088fc7dc119476f72b2faaee1ed417db53;hp=88ca750f814ba01512106befdcb80e0359d6cc60;hpb=9c17e94cac5e9d48fe170b8e5288cb764d8145ad;p=dcpomatic.git diff --git a/src/wx/screens_panel.cc b/src/wx/screens_panel.cc index 88ca750f8..5f903eda4 100644 --- a/src/wx/screens_panel.cc +++ b/src/wx/screens_panel.cc @@ -26,6 +26,7 @@ #include "wx_util.h" #include "lib/cinema.h" #include "lib/config.h" +#include "lib/scope_guard.h" #include "lib/screen.h" #include "lib/timer.h" #include @@ -67,6 +68,8 @@ ScreensPanel::ScreensPanel (wxWindow* parent) add_cinemas (); + auto side_buttons = new wxBoxSizer (wxVERTICAL); + auto target_buttons = new wxBoxSizer (wxVERTICAL); _add_cinema = new Button (this, _("Add Cinema...")); @@ -82,7 +85,18 @@ ScreensPanel::ScreensPanel (wxWindow* parent) _remove_screen = new Button (this, _("Remove Screen")); target_buttons->Add (_remove_screen, 1, wxEXPAND | wxBOTTOM, DCPOMATIC_BUTTON_STACK_GAP); - targets->Add (target_buttons, 0, 0); + side_buttons->Add (target_buttons, 0, 0); + + auto check_buttons = new wxBoxSizer (wxVERTICAL); + + _check_all = new Button (this, _("Check all")); + check_buttons->Add (_check_all, 1, wxEXPAND | wxBOTTOM, DCPOMATIC_BUTTON_STACK_GAP); + _uncheck_all = new Button (this, _("Uncheck all")); + check_buttons->Add (_uncheck_all, 1, wxEXPAND | wxBOTTOM, DCPOMATIC_BUTTON_STACK_GAP); + + side_buttons->Add (check_buttons, 1, wxEXPAND | wxTOP, DCPOMATIC_BUTTON_STACK_GAP * 8); + + targets->Add (side_buttons, 0, 0); sizer->Add (targets, 1, wxEXPAND); @@ -98,6 +112,9 @@ ScreensPanel::ScreensPanel (wxWindow* parent) _edit_screen->Bind (wxEVT_BUTTON, boost::bind (&ScreensPanel::edit_screen_clicked, this)); _remove_screen->Bind (wxEVT_BUTTON, boost::bind (&ScreensPanel::remove_screen_clicked, this)); + _check_all->Bind (wxEVT_BUTTON, boost::bind(&ScreensPanel::check_all, this)); + _uncheck_all->Bind (wxEVT_BUTTON, boost::bind(&ScreensPanel::uncheck_all, this)); + SetSizer (sizer); UErrorCode status = U_ZERO_ERROR; @@ -121,6 +138,32 @@ ScreensPanel::~ScreensPanel () } +void +ScreensPanel::check_all () +{ + for (auto cinema = _targets->GetFirstChild(_targets->GetRootItem()); cinema.IsOk(); cinema = _targets->GetNextSibling(cinema)) { + _targets->CheckItem(cinema, wxCHK_CHECKED); + for (auto screen = _targets->GetFirstChild(cinema); screen.IsOk(); screen = _targets->GetNextSibling(screen)) { + _targets->CheckItem(screen, wxCHK_CHECKED); + set_screen_checked(screen, true); + } + } +} + + +void +ScreensPanel::uncheck_all () +{ + for (auto cinema = _targets->GetFirstChild(_targets->GetRootItem()); cinema.IsOk(); cinema = _targets->GetNextSibling(cinema)) { + _targets->CheckItem(cinema, wxCHK_UNCHECKED); + for (auto screen = _targets->GetFirstChild(cinema); screen.IsOk(); screen = _targets->GetNextSibling(screen)) { + _targets->CheckItem(screen, wxCHK_UNCHECKED); + set_screen_checked(screen, false); + } + } +} + + void ScreensPanel::setup_sensitivity () { @@ -152,7 +195,6 @@ ScreensPanel::add_cinema (shared_ptr cinema, wxTreeListItem previous) auto id = _targets->InsertItem(_targets->GetRootItem(), previous, std_to_wx(cinema->name)); - _cinemas.push_back(make_pair(id, cinema)); _item_to_cinema[id] = cinema; _cinema_to_item[cinema] = id; @@ -174,7 +216,6 @@ ScreensPanel::add_screen (shared_ptr cinema, shared_ptr screen) auto id = _targets->AppendItem(*item, std_to_wx(screen->name)); - _screens.push_back(make_pair(id, screen)); _item_to_screen[id] = screen; _screen_to_item[screen] = id; @@ -185,18 +226,27 @@ ScreensPanel::add_screen (shared_ptr cinema, shared_ptr screen) void ScreensPanel::add_cinema_clicked () { - auto d = new CinemaDialog (GetParent(), _("Add Cinema")); - if (d->ShowModal () == wxID_OK) { - auto cinema = make_shared(d->name(), d->emails(), d->notes(), d->utc_offset_hour(), d->utc_offset_minute()); + auto dialog = new CinemaDialog (GetParent(), _("Add Cinema")); + ScopeGuard sg = [dialog]() { dialog->Destroy(); }; + + if (dialog->ShowModal() == wxID_OK) { + auto cinema = make_shared(dialog->name(), dialog->emails(), dialog->notes(), dialog->utc_offset_hour(), dialog->utc_offset_minute()); auto cinemas = Config::instance()->cinemas(); cinemas.sort( [this](shared_ptr a, shared_ptr b) { return compare(a->name, b->name) < 0; } ); + try { + Config::instance()->add_cinema(cinema); + } catch (FileError& e) { + error_dialog(GetParent(), _("Could not write cinema details to the cinemas.xml file. Check that the location of cinemas.xml is valid in DCP-o-matic's preferences."), std_to_wx(e.what())); + return; + } + optional item; for (auto existing_cinema: cinemas) { - if (!item && compare(d->name(), existing_cinema->name) < 0) { + if (!item && compare(dialog->name(), existing_cinema->name) < 0) { if (auto existing_item = cinema_to_item(existing_cinema)) { item = add_cinema (cinema, *existing_item); } @@ -211,21 +261,19 @@ ScreensPanel::add_cinema_clicked () _targets->UnselectAll (); _targets->Select (*item); } - - Config::instance()->add_cinema (cinema); } - d->Destroy (); + selection_changed (); } -optional>> +shared_ptr ScreensPanel::cinema_for_operation () const { if (_selected_cinemas.size() == 1) { - return make_pair(_selected_cinemas.begin()->first, _selected_cinemas.begin()->second); + return _selected_cinemas[0]; } else if (_selected_screens.size() == 1) { - return make_pair(_targets->GetItemParent(_selected_screens.begin()->first), _selected_screens.begin()->second->cinema); + return _selected_screens[0]->cinema; } return {}; @@ -240,21 +288,22 @@ ScreensPanel::edit_cinema_clicked () return; } - auto d = new CinemaDialog ( - GetParent(), _("Edit cinema"), cinema->second->name, cinema->second->emails, cinema->second->notes, cinema->second->utc_offset_hour(), cinema->second->utc_offset_minute() + auto dialog = new CinemaDialog( + GetParent(), _("Edit cinema"), cinema->name, cinema->emails, cinema->notes, cinema->utc_offset_hour(), cinema->utc_offset_minute() ); - - if (d->ShowModal() == wxID_OK) { - cinema->second->name = d->name (); - cinema->second->emails = d->emails (); - cinema->second->notes = d->notes (); - cinema->second->set_utc_offset_hour (d->utc_offset_hour ()); - cinema->second->set_utc_offset_minute (d->utc_offset_minute ()); - _targets->SetItemText (cinema->first, std_to_wx(d->name())); - Config::instance()->changed (Config::CINEMAS); + ScopeGuard sg = [dialog]() { dialog->Destroy(); }; + + if (dialog->ShowModal() == wxID_OK) { + cinema->name = dialog->name(); + cinema->emails = dialog->emails(); + cinema->notes = dialog->notes(); + cinema->set_utc_offset_hour(dialog->utc_offset_hour()); + cinema->set_utc_offset_minute(dialog->utc_offset_minute()); + notify_cinemas_changed(); + auto item = cinema_to_item(cinema); + DCPOMATIC_ASSERT(item); + _targets->SetItemText (*item, std_to_wx(dialog->name())); } - - d->Destroy (); } @@ -262,7 +311,7 @@ void ScreensPanel::remove_cinema_clicked () { if (_selected_cinemas.size() == 1) { - if (!confirm_dialog(this, wxString::Format(_("Are you sure you want to remove the cinema '%s'?"), std_to_wx(_selected_cinemas.begin()->second->name)))) { + if (!confirm_dialog(this, wxString::Format(_("Are you sure you want to remove the cinema '%s'?"), std_to_wx(_selected_cinemas[0]->name)))) { return; } } else { @@ -271,9 +320,11 @@ ScreensPanel::remove_cinema_clicked () } } - for (auto const& i: _selected_cinemas) { - Config::instance()->remove_cinema (i.second); - _targets->DeleteItem (i.first); + for (auto const& cinema: _selected_cinemas) { + Config::instance()->remove_cinema(cinema); + auto item = cinema_to_item(cinema); + DCPOMATIC_ASSERT(item); + _targets->DeleteItem(*item); } selection_changed (); @@ -288,35 +339,34 @@ ScreensPanel::add_screen_clicked () return; } - auto d = new ScreenDialog (GetParent(), _("Add Screen")); - if (d->ShowModal () != wxID_OK) { - d->Destroy (); + auto dialog = new ScreenDialog(GetParent(), _("Add Screen")); + ScopeGuard sg = [dialog]() { dialog->Destroy(); }; + + if (dialog->ShowModal () != wxID_OK) { return; } - for (auto screen: cinema->second->screens()) { - if (screen->name == d->name()) { + for (auto screen: cinema->screens()) { + if (screen->name == dialog->name()) { error_dialog ( GetParent(), wxString::Format ( _("You cannot add a screen called '%s' as the cinema already has a screen with this name."), - std_to_wx(d->name()).data() + std_to_wx(dialog->name()).data() ) ); return; } } - auto screen = std::make_shared(d->name(), d->notes(), d->recipient(), d->recipient_file(), d->trusted_devices()); - cinema->second->add_screen (screen); - auto id = add_screen (cinema->second, screen); + auto screen = std::make_shared(dialog->name(), dialog->notes(), dialog->recipient(), dialog->recipient_file(), dialog->trusted_devices()); + cinema->add_screen (screen); + notify_cinemas_changed(); + + auto id = add_screen (cinema, screen); if (id) { _targets->Expand (id.get ()); } - - Config::instance()->changed (Config::CINEMAS); - - d->Destroy (); } @@ -327,45 +377,46 @@ ScreensPanel::edit_screen_clicked () return; } - auto edit_screen = *_selected_screens.begin(); + auto edit_screen = _selected_screens[0]; - auto d = new ScreenDialog ( + auto dialog = new ScreenDialog( GetParent(), _("Edit screen"), - edit_screen.second->name, - edit_screen.second->notes, - edit_screen.second->recipient, - edit_screen.second->recipient_file, - edit_screen.second->trusted_devices + edit_screen->name, + edit_screen->notes, + edit_screen->recipient, + edit_screen->recipient_file, + edit_screen->trusted_devices ); + ScopeGuard sg = [dialog]() { dialog->Destroy(); }; - if (d->ShowModal() != wxID_OK) { - d->Destroy (); + if (dialog->ShowModal() != wxID_OK) { return; } - auto cinema = edit_screen.second->cinema; + auto cinema = edit_screen->cinema; for (auto screen: cinema->screens()) { - if (screen != edit_screen.second && screen->name == d->name()) { + if (screen != edit_screen && screen->name == dialog->name()) { error_dialog ( GetParent(), wxString::Format ( _("You cannot change this screen's name to '%s' as the cinema already has a screen with this name."), - std_to_wx(d->name()).data() + std_to_wx(dialog->name()).data() ) ); return; } } - edit_screen.second->name = d->name (); - edit_screen.second->notes = d->notes (); - edit_screen.second->recipient = d->recipient (); - edit_screen.second->recipient_file = d->recipient_file (); - edit_screen.second->trusted_devices = d->trusted_devices (); - _targets->SetItemText (edit_screen.first, std_to_wx(d->name())); - Config::instance()->changed (Config::CINEMAS); + edit_screen->name = dialog->name(); + edit_screen->notes = dialog->notes(); + edit_screen->recipient = dialog->recipient(); + edit_screen->recipient_file = dialog->recipient_file(); + edit_screen->trusted_devices = dialog->trusted_devices(); + notify_cinemas_changed(); - d->Destroy (); + auto item = screen_to_item(edit_screen); + DCPOMATIC_ASSERT (item); + _targets->SetItemText (*item, std_to_wx(dialog->name())); } @@ -373,7 +424,7 @@ void ScreensPanel::remove_screen_clicked () { if (_selected_screens.size() == 1) { - if (!confirm_dialog(this, wxString::Format(_("Are you sure you want to remove the screen '%s'?"), std_to_wx(_selected_screens.begin()->second->name)))) { + if (!confirm_dialog(this, wxString::Format(_("Are you sure you want to remove the screen '%s'?"), std_to_wx(_selected_screens[0]->name)))) { return; } } else { @@ -382,26 +433,14 @@ ScreensPanel::remove_screen_clicked () } } - for (auto const& i: _selected_screens) { - auto j = _cinemas.begin (); - while (j != _cinemas.end ()) { - auto sc = j->second->screens (); - if (find (sc.begin(), sc.end(), i.second) != sc.end ()) { - break; - } - - ++j; - } - - if (j == _cinemas.end()) { - continue; - } - - j->second->remove_screen (i.second); - _targets->DeleteItem (i.first); + for (auto const& screen: _selected_screens) { + screen->cinema->remove_screen(screen); + auto item = screen_to_item(screen); + DCPOMATIC_ASSERT(item); + _targets->DeleteItem(*item); } - Config::instance()->changed (Config::CINEMAS); + notify_cinemas_changed(); } @@ -409,15 +448,7 @@ vector> ScreensPanel::screens () const { vector> output; - - for (auto item = _targets->GetFirstItem(); item.IsOk(); item = _targets->GetNextItem(item)) { - if (_targets->GetCheckedState(item) == wxCHK_CHECKED) { - if (auto screen = item_to_screen(item)) { - output.push_back (screen); - } - } - } - + std::copy (_checked_screens.begin(), _checked_screens.end(), std::back_inserter(output)); return output; } @@ -444,10 +475,10 @@ ScreensPanel::selection_changed () for (size_t i = 0; i < selection.size(); ++i) { if (auto cinema = item_to_cinema(selection[i])) { - _selected_cinemas.push_back(make_pair(selection[i], cinema)); + _selected_cinemas.push_back(cinema); } if (auto screen = item_to_screen(selection[i])) { - _selected_screens.push_back(make_pair(selection[i], screen)); + _selected_screens.push_back(screen); } } @@ -473,8 +504,6 @@ void ScreensPanel::search_changed () { _targets->DeleteAllItems (); - _cinemas.clear (); - _screens.clear (); _item_to_cinema.clear (); _cinema_to_item.clear (); @@ -486,15 +515,13 @@ ScreensPanel::search_changed () _ignore_selection_change = true; for (auto const& selection: _selected_cinemas) { - /* The wxTreeListItems will now be different, so we must search by cinema */ - if (auto item = cinema_to_item(selection.second)) { + if (auto item = cinema_to_item(selection)) { _targets->Select (*item); } } for (auto const& selection: _selected_screens) { - /* Likewise by screen */ - if (auto item = screen_to_item(selection.second)) { + if (auto item = screen_to_item(selection)) { _targets->Select (*item); } } @@ -504,7 +531,7 @@ ScreensPanel::search_changed () _ignore_check_change = true; for (auto const& checked: _checked_screens) { - if (auto item = screen_to_item(checked.second)) { + if (auto item = screen_to_item(checked)) { _targets->CheckItem(*item, wxCHK_CHECKED); setup_cinema_checked_state(*item); } @@ -517,15 +544,12 @@ ScreensPanel::search_changed () void ScreensPanel::set_screen_checked (wxTreeListItem item, bool checked) { - auto current = std::find_if( - _checked_screens.begin(), _checked_screens.end(), - [item](pair> 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); + auto screen = item_to_screen(item); + DCPOMATIC_ASSERT(screen); + if (checked) { + _checked_screens.insert(screen); + } else { + _checked_screens.erase(screen); } } @@ -639,3 +663,19 @@ ScreensPanel::compare (string const& utf8_a, string const& utf8_b) return strcoll(utf8_a.c_str(), utf8_b.c_str()); } } + + +bool +ScreensPanel::notify_cinemas_changed() +{ + try { + Config::instance()->changed(Config::CINEMAS); + } catch (FileError& e) { + error_dialog(GetParent(), _("Could not write cinema details to the cinemas.xml file. Check that the location of cinemas.xml is valid in DCP-o-matic's preferences."), std_to_wx(e.what())); + return false; + } + + return true; +} + +