2 Copyright (C) 2019-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 "content_version_dialog.h"
22 #include "editable_list.h"
23 #include "language_tag_dialog.h"
24 #include "smpte_metadata_dialog.h"
25 #include "rating_dialog.h"
27 #include <dcp/types.h>
28 #include <wx/gbsizer.h>
29 #include <wx/spinctrl.h>
33 using boost::optional;
34 using boost::shared_ptr;
35 using boost::weak_ptr;
36 #if BOOST_VERSION >= 106100
37 using namespace boost::placeholders;
42 ratings_column (dcp::Rating r, int c)
53 content_versions_column (string v, int)
59 SMPTEMetadataDialog::SMPTEMetadataDialog (wxWindow* parent, weak_ptr<Film> weak_film)
60 : wxDialog (parent, wxID_ANY, _("Metadata"))
63 wxBoxSizer* overall_sizer = new wxBoxSizer (wxVERTICAL);
64 SetSizer (overall_sizer);
66 wxFlexGridSizer* sizer = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
67 sizer->AddGrowableCol (1, 1);
69 wxButton* edit_name_language = 0;
70 add_label_to_sizer(sizer, this, _("Title language"), true, 0, wxLEFT | wxRIGHT | wxALIGN_CENTER_VERTICAL);
72 wxSizer* s = new wxBoxSizer (wxHORIZONTAL);
73 _name_language = new wxStaticText (this, wxID_ANY, wxT(""));
74 _name_language->SetToolTip (wxString::Format(_("The language that the film's title (\"%s\") is in"), std_to_wx(film()->name())));
75 s->Add (_name_language, 1, wxLEFT | wxALIGN_CENTER_VERTICAL, DCPOMATIC_SIZER_X_GAP);
76 edit_name_language = new Button (this, _("Edit..."));
77 s->Add (edit_name_language, 0, wxLEFT, DCPOMATIC_SIZER_GAP);
78 sizer->Add (s, 0, wxEXPAND);
81 wxButton* edit_audio_language = 0;
82 add_label_to_sizer(sizer, this, _("Audio language"), true, 0, wxLEFT | wxRIGHT | wxALIGN_CENTER_VERTICAL);
84 wxSizer* s = new wxBoxSizer (wxHORIZONTAL);
85 _audio_language = new wxStaticText (this, wxID_ANY, wxT(""));
86 _audio_language->SetToolTip (_("The main language that is spoken in the film's soundtrack"));
87 s->Add (_audio_language, 1, wxLEFT | wxALIGN_CENTER_VERTICAL, DCPOMATIC_SIZER_X_GAP);
88 edit_audio_language = new Button (this, _("Edit..."));
89 s->Add (edit_audio_language, 0, wxLEFT, DCPOMATIC_SIZER_GAP);
90 sizer->Add (s, 0, wxEXPAND);
93 Button* edit_release_territory = 0;
94 add_label_to_sizer (sizer, this, _("Release territory"), true, 0, wxLEFT | wxRIGHT | wxALIGN_CENTER_VERTICAL);
96 wxSizer* s = new wxBoxSizer (wxHORIZONTAL);
97 _release_territory = new wxStaticText (this, wxID_ANY, wxT(""));
98 s->Add (_release_territory, 1, wxLEFT | wxALIGN_CENTER_VERTICAL, DCPOMATIC_SIZER_X_GAP);
99 edit_release_territory = new Button (this, _("Edit..."));
100 s->Add (edit_release_territory, 0, wxLEFT, DCPOMATIC_SIZER_GAP);
101 sizer->Add (s, 0, wxEXPAND);
104 add_label_to_sizer (sizer, this, _("Version number"), true, 0, wxLEFT | wxRIGHT | wxALIGN_CENTER_VERTICAL);
105 _version_number = new wxSpinCtrl (this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 1, 1000);
106 sizer->Add (_version_number, 0);
108 add_label_to_sizer (sizer, this, _("Status"), true, 0, wxLEFT | wxRIGHT | wxALIGN_CENTER_VERTICAL);
109 _status = new wxChoice (this, wxID_ANY);
110 sizer->Add (_status, 0);
112 add_label_to_sizer (sizer, this, _("Chain"), true, 0, wxLEFT | wxRIGHT | wxALIGN_CENTER_VERTICAL);
113 _chain = new wxTextCtrl (this, wxID_ANY);
114 sizer->Add (_chain, 1, wxEXPAND);
116 add_label_to_sizer (sizer, this, _("Distributor"), true, 0, wxLEFT | wxRIGHT | wxALIGN_CENTER_VERTICAL);
117 _distributor = new wxTextCtrl (this, wxID_ANY);
118 sizer->Add (_distributor, 1, wxEXPAND);
120 add_label_to_sizer (sizer, this, _("Facility"), true, 0, wxLEFT | wxRIGHT | wxALIGN_CENTER_VERTICAL);
121 _facility = new wxTextCtrl (this, wxID_ANY);
122 sizer->Add (_facility, 1, wxEXPAND);
124 add_label_to_sizer (sizer, this, _("Luminance"), true, 0, wxLEFT | wxRIGHT | wxALIGN_CENTER_VERTICAL);
126 wxSizer* s = new wxBoxSizer (wxHORIZONTAL);
127 _luminance_value = new wxSpinCtrlDouble (this, wxID_ANY);
128 _luminance_value->SetDigits (1);
129 _luminance_value->SetIncrement (0.1);
130 s->Add (_luminance_value, 0);
131 _luminance_unit = new wxChoice (this, wxID_ANY);
132 s->Add (_luminance_unit, 0, wxLEFT, DCPOMATIC_SIZER_X_GAP);
133 sizer->Add (s, 1, wxEXPAND);
137 int flags = wxALIGN_TOP | wxLEFT | wxRIGHT | wxTOP;
139 flags |= wxALIGN_RIGHT;
141 wxStaticText* m = create_label (this, _("Ratings"), true);
142 sizer->Add (m, 0, flags, DCPOMATIC_SIZER_GAP);
145 vector<EditableListColumn> columns;
146 columns.push_back (EditableListColumn("Agency", 200, true));
147 columns.push_back (EditableListColumn("Label", 50, true));
148 _ratings = new EditableList<dcp::Rating, RatingDialog> (
151 boost::bind(&SMPTEMetadataDialog::ratings, this),
152 boost::bind(&SMPTEMetadataDialog::set_ratings, this, _1),
153 boost::bind(&ratings_column, _1, _2),
157 sizer->Add (_ratings, 1, wxEXPAND);
160 int flags = wxALIGN_TOP | wxLEFT | wxRIGHT | wxTOP;
162 flags |= wxALIGN_RIGHT;
164 wxStaticText* m = create_label (this, _("Content versions"), true);
165 sizer->Add (m, 0, flags, DCPOMATIC_SIZER_GAP);
169 columns.push_back (EditableListColumn("Version", 350, true));
170 _content_versions = new EditableList<string, ContentVersionDialog> (
173 boost::bind(&SMPTEMetadataDialog::content_versions, this),
174 boost::bind(&SMPTEMetadataDialog::set_content_versions, this, _1),
175 boost::bind(&content_versions_column, _1, _2),
179 sizer->Add (_content_versions, 1, wxEXPAND);
181 overall_sizer->Add (sizer, 1, wxEXPAND | wxALL, DCPOMATIC_DIALOG_BORDER);
183 wxSizer* buttons = CreateSeparatedButtonSizer (wxCLOSE);
185 overall_sizer->Add (buttons, wxSizerFlags().Expand().DoubleBorder());
188 overall_sizer->Layout ();
189 overall_sizer->SetSizeHints (this);
191 _status->Append (_("Temporary"));
192 _status->Append (_("Pre-release"));
193 _status->Append (_("Final"));
195 _luminance_unit->Append (_("candela per m²"));
196 _luminance_unit->Append (_("foot lambert"));
198 edit_name_language->Bind (wxEVT_BUTTON, boost::bind(&SMPTEMetadataDialog::edit_name_language, this));
199 edit_audio_language->Bind (wxEVT_BUTTON, boost::bind(&SMPTEMetadataDialog::edit_audio_language, this));
200 edit_release_territory->Bind (wxEVT_BUTTON, boost::bind(&SMPTEMetadataDialog::edit_release_territory, this));
201 _version_number->Bind (wxEVT_SPINCTRL, boost::bind(&SMPTEMetadataDialog::version_number_changed, this));
202 _status->Bind (wxEVT_CHOICE, boost::bind(&SMPTEMetadataDialog::status_changed, this));
203 _chain->Bind (wxEVT_TEXT, boost::bind(&SMPTEMetadataDialog::chain_changed, this));
204 _distributor->Bind (wxEVT_TEXT, boost::bind(&SMPTEMetadataDialog::distributor_changed, this));
205 _facility->Bind (wxEVT_TEXT, boost::bind(&SMPTEMetadataDialog::facility_changed, this));
206 _luminance_value->Bind (wxEVT_SPINCTRLDOUBLE, boost::bind(&SMPTEMetadataDialog::luminance_changed, this));
207 _luminance_unit->Bind (wxEVT_CHOICE, boost::bind(&SMPTEMetadataDialog::luminance_changed, this));
209 _version_number->SetFocus ();
211 _film_changed_connection = film()->Change.connect(boost::bind(&SMPTEMetadataDialog::film_changed, this, _1, _2));
213 film_changed (CHANGE_TYPE_DONE, Film::NAME_LANGUAGE);
214 film_changed (CHANGE_TYPE_DONE, Film::RELEASE_TERRITORY);
215 film_changed (CHANGE_TYPE_DONE, Film::VERSION_NUMBER);
216 film_changed (CHANGE_TYPE_DONE, Film::STATUS);
217 film_changed (CHANGE_TYPE_DONE, Film::CHAIN);
218 film_changed (CHANGE_TYPE_DONE, Film::DISTRIBUTOR);
219 film_changed (CHANGE_TYPE_DONE, Film::FACILITY);
220 film_changed (CHANGE_TYPE_DONE, Film::CONTENT_VERSIONS);
221 film_changed (CHANGE_TYPE_DONE, Film::LUMINANCE);
226 SMPTEMetadataDialog::film_changed (ChangeType type, Film::Property property)
228 if (type != CHANGE_TYPE_DONE || film()->interop()) {
232 if (property == Film::NAME_LANGUAGE) {
233 checked_set (_name_language, std_to_wx(film()->name_language().to_string()));
234 } else if (property == Film::RELEASE_TERRITORY) {
235 checked_set (_release_territory, std_to_wx(*dcp::LanguageTag::get_subtag_description(dcp::LanguageTag::REGION, film()->release_territory().subtag())));
236 } else if (property == Film::VERSION_NUMBER) {
237 checked_set (_version_number, film()->version_number());
238 } else if (property == Film::STATUS) {
239 switch (film()->status()) {
241 checked_set (_status, 0);
244 checked_set (_status, 1);
247 checked_set (_status, 2);
250 } else if (property == Film::CHAIN) {
251 checked_set (_chain, film()->chain());
252 } else if (property == Film::DISTRIBUTOR) {
253 checked_set (_distributor, film()->distributor());
254 } else if (property == Film::FACILITY) {
255 checked_set (_facility, film()->facility());
256 } else if (property == Film::LUMINANCE) {
257 checked_set (_luminance_value, film()->luminance().value());
258 switch (film()->luminance().unit()) {
259 case dcp::Luminance::CANDELA_PER_SQUARE_METRE:
260 checked_set (_luminance_unit, 0);
262 case dcp::Luminance::FOOT_LAMBERT:
263 checked_set (_luminance_unit, 1);
271 SMPTEMetadataDialog::ratings () const
273 return film()->ratings ();
278 SMPTEMetadataDialog::set_ratings (vector<dcp::Rating> r)
280 film()->set_ratings (r);
285 SMPTEMetadataDialog::content_versions () const
287 return film()->content_versions ();
292 SMPTEMetadataDialog::set_content_versions (vector<string> cv)
294 film()->set_content_versions (cv);
299 SMPTEMetadataDialog::edit_name_language ()
301 LanguageTagDialog* d = new LanguageTagDialog(this, film()->name_language());
303 film()->set_name_language (d->get());
309 SMPTEMetadataDialog::edit_audio_language ()
311 LanguageTagDialog* d = new LanguageTagDialog(this, film()->audio_language());
313 film()->set_audio_language (d->get());
319 SMPTEMetadataDialog::edit_release_territory ()
321 RegionSubtagDialog* d = new RegionSubtagDialog(this, film()->release_territory());
323 optional<dcp::LanguageTag::RegionSubtag> tag = d->get();
325 film()->set_release_territory (*tag);
332 SMPTEMetadataDialog::film () const
334 shared_ptr<Film> film = _film.lock ();
335 DCPOMATIC_ASSERT (film);
341 SMPTEMetadataDialog::version_number_changed ()
343 film()->set_version_number (_version_number->GetValue());
348 SMPTEMetadataDialog::status_changed ()
350 switch (_status->GetSelection()) {
352 film()->set_status (dcp::TEMP);
355 film()->set_status (dcp::PRE);
358 film()->set_status (dcp::FINAL);
365 SMPTEMetadataDialog::chain_changed ()
367 film()->set_chain (wx_to_std(_chain->GetValue()));
372 SMPTEMetadataDialog::distributor_changed ()
374 film()->set_distributor (wx_to_std(_distributor->GetValue()));
379 SMPTEMetadataDialog::facility_changed ()
381 film()->set_facility (wx_to_std(_facility->GetValue()));
386 SMPTEMetadataDialog::luminance_changed ()
388 dcp::Luminance::Unit unit;
389 switch (_luminance_unit->GetSelection()) {
391 unit = dcp::Luminance::CANDELA_PER_SQUARE_METRE;
394 unit = dcp::Luminance::FOOT_LAMBERT;
398 film()->set_luminance (dcp::Luminance(_luminance_value->GetValue(), unit));