2 Copyright (C) 2015-2021 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/>.
22 #include "recipients_panel.h"
24 #include "recipient_dialog.h"
25 #include "dcpomatic_button.h"
26 #include "lib/dkdm_recipient_list.h"
36 using std::shared_ptr;
38 using boost::optional;
39 using namespace dcpomatic;
42 RecipientsPanel::RecipientsPanel (wxWindow* parent)
43 : wxPanel (parent, wxID_ANY)
44 , _ignore_selection_change (false)
46 auto sizer = new wxBoxSizer (wxVERTICAL);
49 int const height = 30;
51 int const height = -1;
54 _search = new wxSearchCtrl (this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize (200, height));
56 /* The cancel button seems to be strangely broken in GTK3; clicking on it twice sometimes works */
57 _search->ShowCancelButton (true);
59 sizer->Add (_search, 0, wxBOTTOM, DCPOMATIC_SIZER_GAP);
61 auto targets = new wxBoxSizer (wxHORIZONTAL);
62 _targets = new wxTreeCtrl (this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTR_HIDE_ROOT | wxTR_MULTIPLE | wxTR_HAS_BUTTONS | wxTR_LINES_AT_ROOT);
63 targets->Add (_targets, 1, wxEXPAND | wxRIGHT, DCPOMATIC_SIZER_GAP);
67 auto target_buttons = new wxBoxSizer (wxVERTICAL);
69 _add_recipient = new Button (this, _("Add..."));
70 target_buttons->Add (_add_recipient, 1, wxEXPAND | wxBOTTOM, DCPOMATIC_BUTTON_STACK_GAP);
71 _edit_recipient = new Button (this, _("Edit..."));
72 target_buttons->Add (_edit_recipient, 1, wxEXPAND | wxBOTTOM, DCPOMATIC_BUTTON_STACK_GAP);
73 _remove_recipient = new Button (this, _("Remove"));
74 target_buttons->Add (_remove_recipient, 1, wxEXPAND | wxBOTTOM, DCPOMATIC_BUTTON_STACK_GAP);
76 targets->Add (target_buttons, 0, 0);
78 sizer->Add (targets, 1, wxEXPAND);
80 _search->Bind (wxEVT_TEXT, boost::bind (&RecipientsPanel::search_changed, this));
81 _targets->Bind (wxEVT_TREE_SEL_CHANGED, &RecipientsPanel::selection_changed_shim, this);
83 _add_recipient->Bind (wxEVT_BUTTON, boost::bind (&RecipientsPanel::add_recipient_clicked, this));
84 _edit_recipient->Bind (wxEVT_BUTTON, boost::bind (&RecipientsPanel::edit_recipient_clicked, this));
85 _remove_recipient->Bind (wxEVT_BUTTON, boost::bind (&RecipientsPanel::remove_recipient_clicked, this));
91 RecipientsPanel::~RecipientsPanel ()
93 _targets->Unbind (wxEVT_TREE_SEL_CHANGED, &RecipientsPanel::selection_changed_shim, this);
98 RecipientsPanel::setup_sensitivity ()
100 _edit_recipient->Enable (_selected.size() == 1);
101 _remove_recipient->Enable (_selected.size() >= 1);
106 RecipientsPanel::add_recipient(DKDMRecipientID id, DKDMRecipient const& recipient)
108 string const search = wx_to_std(_search->GetValue());
110 if (!search.empty() && !_collator.find(search, recipient.name)) {
114 _recipients.emplace(make_pair(_targets->AppendItem(_root, std_to_wx(recipient.name)), id));
116 _targets->SortChildren (_root);
121 RecipientsPanel::add_recipient_clicked ()
123 RecipientDialog dialog(GetParent(), _("Add recipient"));
124 if (dialog.ShowModal() == wxID_OK) {
125 auto recipient = DKDMRecipient(dialog.name(), dialog.notes(), dialog.recipient(), dialog.emails());
126 DKDMRecipientList recipient_list;
127 auto const id = recipient_list.add_dkdm_recipient(recipient);
128 add_recipient(id, recipient);
134 RecipientsPanel::edit_recipient_clicked ()
136 if (_selected.size() != 1) {
140 DKDMRecipientList recipients;
141 auto selection = *_selected.begin();
142 auto const recipient_id = selection.second;
143 auto recipient = recipients.dkdm_recipient(recipient_id);
144 DCPOMATIC_ASSERT(recipient);
146 RecipientDialog dialog(
155 if (dialog.ShowModal() == wxID_OK) {
156 recipient->name = dialog.name();
157 recipient->emails = dialog.emails();
158 recipient->notes = dialog.notes();
159 recipient->recipient = dialog.recipient();
160 recipients.update_dkdm_recipient(recipient_id, *recipient);
161 _targets->SetItemText(selection.first, std_to_wx(dialog.name()));
167 RecipientsPanel::remove_recipient_clicked ()
169 for (auto const& i: _selected) {
170 DKDMRecipientList recipient_list;
171 recipient_list.remove_dkdm_recipient(i.second);
172 _targets->Delete (i.first);
175 selection_changed ();
180 RecipientsPanel::recipients () const
182 list<DKDMRecipient> all;
183 DKDMRecipientList recipients;
184 for (auto const& recipient: recipients.dkdm_recipients()) {
185 all.push_back(recipient.second);
192 RecipientsPanel::selection_changed_shim (wxTreeEvent &)
194 selection_changed ();
199 RecipientsPanel::selection_changed ()
201 if (_ignore_selection_change) {
205 wxArrayTreeItemIds s;
206 _targets->GetSelections (s);
210 for (size_t i = 0; i < s.GetCount(); ++i) {
211 RecipientMap::const_iterator j = _recipients.find (s[i]);
212 if (j != _recipients.end ()) {
213 _selected.emplace(*j);
217 setup_sensitivity ();
218 RecipientsChanged ();
223 RecipientsPanel::add_recipients ()
225 _root = _targets->AddRoot ("Foo");
227 DKDMRecipientList recipients;
228 for (auto const& recipient: recipients.dkdm_recipients()) {
229 add_recipient(recipient.first, recipient.second);
235 RecipientsPanel::search_changed ()
237 _targets->DeleteAllItems ();
238 _recipients.clear ();
242 _ignore_selection_change = true;
244 for (auto const& i: _selected) {
245 /* The wxTreeItemIds will now be different, so we must search by recipient */
246 auto j = _recipients.begin ();
247 while (j != _recipients.end() && j->second != i.second) {
251 if (j != _recipients.end ()) {
252 _targets->SelectItem (j->first);
256 _ignore_selection_change = false;