2 Copyright (C) 2015-2020 Carl Hetherington <cth@carlh.net>
4 This file is part of DCP-o-matic.
6 DCP-o-matic is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 DCP-o-matic is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with DCP-o-matic. If not, see <http://www.gnu.org/licenses/>.
21 #include "recipients_panel.h"
22 #include "recipient_dialog.h"
24 #include "dcpomatic_button.h"
25 #include "lib/config.h"
26 #include "lib/dkdm_recipient.h"
27 #include <boost/foreach.hpp>
35 using boost::shared_ptr;
36 using boost::optional;
37 using namespace dcpomatic;
39 RecipientsPanel::RecipientsPanel (wxWindow* parent)
40 : wxPanel (parent, wxID_ANY)
41 , _ignore_selection_change (false)
43 wxBoxSizer* sizer = new wxBoxSizer (wxVERTICAL);
45 _search = new wxSearchCtrl (this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize (200, -1));
46 _search->ShowCancelButton (true);
47 sizer->Add (_search, 0, wxBOTTOM, DCPOMATIC_SIZER_GAP);
49 wxBoxSizer* targets = new wxBoxSizer (wxHORIZONTAL);
50 _targets = new wxTreeCtrl (this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTR_HIDE_ROOT | wxTR_MULTIPLE | wxTR_HAS_BUTTONS | wxTR_LINES_AT_ROOT);
51 targets->Add (_targets, 1, wxEXPAND | wxRIGHT, DCPOMATIC_SIZER_GAP);
53 add_recipients_from_config ();
55 wxBoxSizer* target_buttons = new wxBoxSizer (wxVERTICAL);
57 _add_recipient = new Button (this, _("Add Recipient..."));
58 target_buttons->Add (_add_recipient, 1, wxEXPAND | wxBOTTOM, DCPOMATIC_BUTTON_STACK_GAP);
59 _edit_recipient = new Button (this, _("Edit Recipient..."));
60 target_buttons->Add (_edit_recipient, 1, wxEXPAND | wxBOTTOM, DCPOMATIC_BUTTON_STACK_GAP);
61 _remove_recipient = new Button (this, _("Remove Recipient"));
62 target_buttons->Add (_remove_recipient, 1, wxEXPAND | wxBOTTOM, DCPOMATIC_BUTTON_STACK_GAP);
64 targets->Add (target_buttons, 0, 0);
66 sizer->Add (targets, 1, wxEXPAND);
68 _search->Bind (wxEVT_TEXT, boost::bind (&RecipientsPanel::search_changed, this));
69 _targets->Bind (wxEVT_TREE_SEL_CHANGED, &RecipientsPanel::selection_changed_shim, this);
71 _add_recipient->Bind (wxEVT_BUTTON, boost::bind (&RecipientsPanel::add_recipient_clicked, this));
72 _edit_recipient->Bind (wxEVT_BUTTON, boost::bind (&RecipientsPanel::edit_recipient_clicked, this));
73 _remove_recipient->Bind (wxEVT_BUTTON, boost::bind (&RecipientsPanel::remove_recipient_clicked, this));
79 RecipientsPanel::~RecipientsPanel ()
81 _targets->Unbind (wxEVT_TREE_SEL_CHANGED, &RecipientsPanel::selection_changed_shim, this);
86 RecipientsPanel::setup_sensitivity ()
88 bool const s = _selected.size() == 1;
90 _edit_recipient->Enable (s);
91 _remove_recipient->Enable (_selected.size() >= 1);
96 RecipientsPanel::add_recipient (shared_ptr<DKDMRecipient> r)
98 string search = wx_to_std (_search->GetValue());
99 transform (search.begin(), search.end(), search.begin(), ::tolower);
101 if (!search.empty()) {
102 string name = r->name;
103 transform (name.begin(), name.end(), name.begin(), ::tolower);
104 if (name.find(search) == string::npos) {
109 _recipients[_targets->AppendItem(_root, std_to_wx(r->name))] = r;
111 _targets->SortChildren (_root);
116 RecipientsPanel::add_recipient_clicked ()
118 RecipientDialog* d = new RecipientDialog (GetParent(), _("Add Recipient"));
119 if (d->ShowModal() == wxID_OK) {
120 shared_ptr<DKDMRecipient> r (new DKDMRecipient(d->name(), d->notes(), d->recipient(), d->emails(), d->utc_offset_hour(), d->utc_offset_minute()));
121 Config::instance()->add_dkdm_recipient (r);
130 RecipientsPanel::edit_recipient_clicked ()
132 if (_selected.size() != 1) {
136 pair<wxTreeItemId, shared_ptr<DKDMRecipient> > r = *_selected.begin();
138 RecipientDialog* d = new RecipientDialog (
139 GetParent(), _("Edit recipient"), r.second->name, r.second->emails, r.second->notes, r.second->utc_offset_hour(), r.second->utc_offset_minute(), r.second->recipient
142 if (d->ShowModal() == wxID_OK) {
143 r.second->name = d->name ();
144 r.second->emails = d->emails ();
145 r.second->notes = d->notes ();
146 r.second->set_utc_offset_hour (d->utc_offset_hour());
147 r.second->set_utc_offset_minute (d->utc_offset_minute());
148 r.second->recipient = d->recipient ();
149 _targets->SetItemText (r.first, std_to_wx(d->name()));
150 Config::instance()->changed (Config::DKDM_RECIPIENTS);
158 RecipientsPanel::remove_recipient_clicked ()
160 for (RecipientMap::iterator i = _selected.begin(); i != _selected.end(); ++i) {
161 Config::instance()->remove_dkdm_recipient (i->second);
162 _targets->Delete (i->first);
165 selection_changed ();
169 list<shared_ptr<DKDMRecipient> >
170 RecipientsPanel::recipients () const
172 list<shared_ptr<DKDMRecipient> > s;
174 for (RecipientMap::const_iterator i = _selected.begin(); i != _selected.end(); ++i) {
175 s.push_back (i->second);
186 RecipientsPanel::selection_changed_shim (wxTreeEvent &)
188 selection_changed ();
193 RecipientsPanel::selection_changed ()
195 if (_ignore_selection_change) {
199 wxArrayTreeItemIds s;
200 _targets->GetSelections (s);
204 for (size_t i = 0; i < s.GetCount(); ++i) {
205 RecipientMap::const_iterator j = _recipients.find (s[i]);
206 if (j != _recipients.end()) {
207 _selected[j->first] = j->second;
211 setup_sensitivity ();
212 RecipientsChanged ();
217 RecipientsPanel::add_recipients_from_config ()
219 _root = _targets->AddRoot ("Foo");
221 BOOST_FOREACH (shared_ptr<DKDMRecipient> i, Config::instance()->dkdm_recipients()) {
228 RecipientsPanel::search_changed ()
230 _targets->DeleteAllItems ();
231 _recipients.clear ();
233 add_recipients_from_config ();
235 _ignore_selection_change = true;
237 for (RecipientMap::const_iterator i = _selected.begin(); i != _selected.end(); ++i) {
238 RecipientMap::const_iterator j = _recipients.begin ();
239 while (j != _recipients.end() && j->second != i->second) {
243 if (j != _recipients.end()) {
244 _targets->SelectItem (j->first);
248 _ignore_selection_change = false;