Use studio and facility from Interop/SMPTE metadata rather than ISDCF.
[dcpomatic.git] / src / wx / smpte_metadata_dialog.cc
1 /*
2     Copyright (C) 2019-2021 Carl Hetherington <cth@carlh.net>
3
4     This file is part of DCP-o-matic.
5
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.
10
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.
15
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/>.
18
19 */
20
21
22 #include "content_version_dialog.h"
23 #include "editable_list.h"
24 #include "language_tag_dialog.h"
25 #include "language_tag_widget.h"
26 #include "smpte_metadata_dialog.h"
27 #include "rating_dialog.h"
28 #include "lib/film.h"
29 #include <dcp/types.h>
30 #include <wx/gbsizer.h>
31 #include <wx/spinctrl.h>
32
33
34 using std::string;
35 using std::vector;
36 using boost::optional;
37 using std::shared_ptr;
38 using std::weak_ptr;
39 #if BOOST_VERSION >= 106100
40 using namespace boost::placeholders;
41 #endif
42
43
44 static string
45 ratings_column (dcp::Rating r, int c)
46 {
47         if (c == 0) {
48                 return r.agency;
49         }
50
51         return r.label;
52 }
53
54
55 static string
56 content_versions_column (string v, int)
57 {
58         return v;
59 }
60
61
62 void
63 SMPTEMetadataDialog::setup_standard (wxPanel* panel, wxSizer* sizer)
64 {
65         MetadataDialog::setup_standard (panel, sizer);
66
67         add_label_to_sizer (sizer, panel, _("Title language"), true, 0, wxRIGHT | wxALIGN_CENTER_VERTICAL);
68         _name_language = new LanguageTagWidget(
69                 panel,
70                 wxString::Format(_("The language that the film's title (\"%s\") is in"), std_to_wx(film()->name())),
71                 film()->name_language()
72                 );
73         sizer->Add (_name_language->sizer(), 0, wxEXPAND);
74
75         {
76                 int flags = wxALIGN_TOP | wxRIGHT | wxTOP;
77 #ifdef __WXOSX__
78                 flags |= wxALIGN_RIGHT;
79 #endif
80                 auto m = create_label (panel, _("Ratings"), true);
81                 sizer->Add (m, 0, flags, DCPOMATIC_SIZER_GAP);
82         }
83
84         vector<EditableListColumn> columns;
85         columns.push_back (EditableListColumn("Agency", 200, true));
86         columns.push_back (EditableListColumn("Label", 50, true));
87         _ratings = new EditableList<dcp::Rating, RatingDialog> (
88                 panel,
89                 columns,
90                 boost::bind(&SMPTEMetadataDialog::ratings, this),
91                 boost::bind(&SMPTEMetadataDialog::set_ratings, this, _1),
92                 boost::bind(&ratings_column, _1, _2),
93                 true,
94                 false
95                 );
96         sizer->Add (_ratings, 1, wxEXPAND);
97 }
98
99
100 void
101 SMPTEMetadataDialog::setup_advanced (wxPanel* panel, wxSizer* sizer)
102 {
103         MetadataDialog::setup_advanced (panel, sizer);
104
105         add_label_to_sizer (sizer, panel, _("Version number"), true, 0, wxRIGHT | wxALIGN_CENTER_VERTICAL);
106         _version_number = new wxSpinCtrl (panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 1, 1000);
107         sizer->Add (_version_number, 0);
108
109         add_label_to_sizer (sizer, panel, _("Status"), true, 0, wxRIGHT | wxALIGN_CENTER_VERTICAL);
110         _status = new wxChoice (panel, wxID_ANY);
111         sizer->Add (_status, 0);
112
113         _enable_chain = new wxCheckBox (panel, wxID_ANY, _("Chain"));
114         sizer->Add (_enable_chain, 0, wxRIGHT | wxALIGN_CENTER_VERTICAL);
115         _chain = new wxTextCtrl (panel, wxID_ANY);
116         sizer->Add (_chain, 1, wxEXPAND);
117
118         _enable_distributor = new wxCheckBox (panel, wxID_ANY, _("Distributor"));
119         sizer->Add (_enable_distributor, 0, wxRIGHT | wxALIGN_CENTER_VERTICAL);
120         _distributor = new wxTextCtrl (panel, wxID_ANY);
121         sizer->Add (_distributor, 1, wxEXPAND);
122
123         add_label_to_sizer (sizer, panel, _("Luminance"), true, 0, wxRIGHT | wxALIGN_CENTER_VERTICAL);
124         {
125                 auto s = new wxBoxSizer (wxHORIZONTAL);
126                 _luminance_value = new wxSpinCtrlDouble (panel, wxID_ANY);
127                 _luminance_value->SetDigits (1);
128                 _luminance_value->SetIncrement (0.1);
129                 s->Add (_luminance_value, 0);
130                 _luminance_unit = new wxChoice (panel, wxID_ANY);
131                 s->Add (_luminance_unit, 0, wxLEFT, DCPOMATIC_SIZER_X_GAP);
132                 sizer->Add (s, 1, wxEXPAND);
133         }
134
135         {
136                 int flags = wxALIGN_TOP | wxRIGHT | wxTOP;
137 #ifdef __WXOSX__
138                 flags |= wxALIGN_RIGHT;
139 #endif
140                 auto m = create_label (panel, _("Content versions"), true);
141                 sizer->Add (m, 0, flags, DCPOMATIC_SIZER_GAP);
142         }
143
144         vector<EditableListColumn> columns;
145         columns.push_back (EditableListColumn("Version", 350, true));
146         _content_versions = new EditableList<string, ContentVersionDialog> (
147                 panel,
148                 columns,
149                 boost::bind(&SMPTEMetadataDialog::content_versions, this),
150                 boost::bind(&SMPTEMetadataDialog::set_content_versions, this, _1),
151                 boost::bind(&content_versions_column, _1, _2),
152                 true,
153                 false
154                 );
155         sizer->Add (_content_versions, 1, wxEXPAND);
156 }
157
158
159 SMPTEMetadataDialog::SMPTEMetadataDialog (wxWindow* parent, weak_ptr<Film> weak_film)
160         : MetadataDialog (parent, weak_film)
161 {
162
163 }
164
165
166 void
167 SMPTEMetadataDialog::setup ()
168 {
169         MetadataDialog::setup ();
170
171         _status->Append (_("Temporary"));
172         _status->Append (_("Pre-release"));
173         _status->Append (_("Final"));
174
175         _luminance_unit->Append (wxString::FromUTF8(_("candela per m²")));
176         _luminance_unit->Append (_("foot lambert"));
177
178         _name_language->Changed.connect (boost::bind(&SMPTEMetadataDialog::name_language_changed, this, _1));
179         _version_number->Bind (wxEVT_SPINCTRL, boost::bind(&SMPTEMetadataDialog::version_number_changed, this));
180         _status->Bind (wxEVT_CHOICE, boost::bind(&SMPTEMetadataDialog::status_changed, this));
181         _enable_chain->Bind (wxEVT_CHECKBOX, boost::bind(&SMPTEMetadataDialog::enable_chain_changed, this));
182         _chain->Bind (wxEVT_TEXT, boost::bind(&SMPTEMetadataDialog::chain_changed, this));
183         _enable_distributor->Bind (wxEVT_CHECKBOX, boost::bind(&SMPTEMetadataDialog::enable_distributor_changed, this));
184         _distributor->Bind (wxEVT_TEXT, boost::bind(&SMPTEMetadataDialog::distributor_changed, this));
185         _luminance_value->Bind (wxEVT_SPINCTRLDOUBLE, boost::bind(&SMPTEMetadataDialog::luminance_changed, this));
186         _luminance_unit->Bind (wxEVT_CHOICE, boost::bind(&SMPTEMetadataDialog::luminance_changed, this));
187
188         film_changed (ChangeType::DONE, Film::Property::NAME_LANGUAGE);
189         film_changed (ChangeType::DONE, Film::Property::VERSION_NUMBER);
190         film_changed (ChangeType::DONE, Film::Property::STATUS);
191         film_changed (ChangeType::DONE, Film::Property::CHAIN);
192         film_changed (ChangeType::DONE, Film::Property::DISTRIBUTOR);
193         film_changed (ChangeType::DONE, Film::Property::CONTENT_VERSIONS);
194         film_changed (ChangeType::DONE, Film::Property::LUMINANCE);
195
196         setup_sensitivity ();
197 }
198
199
200 void
201 SMPTEMetadataDialog::film_changed (ChangeType type, Film::Property property)
202 {
203         MetadataDialog::film_changed (type, property);
204
205         if (type != ChangeType::DONE || film()->interop()) {
206                 return;
207         }
208
209         if (property == Film::Property::NAME_LANGUAGE) {
210                 _name_language->set (film()->name_language());
211         } else if (property == Film::Property::VERSION_NUMBER) {
212                 checked_set (_version_number, film()->version_number());
213         } else if (property == Film::Property::STATUS) {
214                 switch (film()->status()) {
215                 case dcp::Status::TEMP:
216                         checked_set (_status, 0);
217                         break;
218                 case dcp::Status::PRE:
219                         checked_set (_status, 1);
220                         break;
221                 case dcp::Status::FINAL:
222                         checked_set (_status, 2);
223                         break;
224                 }
225         } else if (property == Film::Property::CHAIN) {
226                 checked_set (_enable_chain, static_cast<bool>(film()->chain()));
227                 if (film()->chain()) {
228                         checked_set (_chain, *film()->chain());
229                 }
230         } else if (property == Film::Property::DISTRIBUTOR) {
231                 checked_set (_enable_distributor, static_cast<bool>(film()->distributor()));
232                 if (film()->distributor()) {
233                         checked_set (_distributor, *film()->distributor());
234                 }
235         } else if (property == Film::Property::LUMINANCE) {
236                 auto lum = film()->luminance();
237                 if (lum) {
238                         checked_set (_luminance_value, lum->value());
239                         switch (lum->unit()) {
240                         case dcp::Luminance::Unit::CANDELA_PER_SQUARE_METRE:
241                                 checked_set (_luminance_unit, 0);
242                                 break;
243                         case dcp::Luminance::Unit::FOOT_LAMBERT:
244                                 checked_set (_luminance_unit, 1);
245                                 break;
246                         }
247                 } else {
248                         checked_set (_luminance_value, 4.5);
249                         checked_set (_luminance_unit, 1);
250                 }
251         }
252 }
253
254
255 vector<dcp::Rating>
256 SMPTEMetadataDialog::ratings () const
257 {
258         return film()->ratings ();
259 }
260
261
262 void
263 SMPTEMetadataDialog::set_ratings (vector<dcp::Rating> r)
264 {
265         film()->set_ratings (r);
266 }
267
268
269 vector<string>
270 SMPTEMetadataDialog::content_versions () const
271 {
272         return film()->content_versions ();
273 }
274
275
276 void
277 SMPTEMetadataDialog::set_content_versions (vector<string> cv)
278 {
279         film()->set_content_versions (cv);
280 }
281
282
283 void
284 SMPTEMetadataDialog::name_language_changed (dcp::LanguageTag tag)
285 {
286         film()->set_name_language (tag);
287 }
288
289
290 void
291 SMPTEMetadataDialog::version_number_changed ()
292 {
293         film()->set_version_number (_version_number->GetValue());
294 }
295
296
297 void
298 SMPTEMetadataDialog::status_changed ()
299 {
300         switch (_status->GetSelection()) {
301         case 0:
302                 film()->set_status(dcp::Status::TEMP);
303                 break;
304         case 1:
305                 film()->set_status(dcp::Status::PRE);
306                 break;
307         case 2:
308                 film()->set_status(dcp::Status::FINAL);
309                 break;
310         }
311 }
312
313
314 void
315 SMPTEMetadataDialog::chain_changed ()
316 {
317         film()->set_chain (wx_to_std(_chain->GetValue()));
318 }
319
320
321 void
322 SMPTEMetadataDialog::distributor_changed ()
323 {
324         film()->set_distributor (wx_to_std(_distributor->GetValue()));
325 }
326
327
328 void
329 SMPTEMetadataDialog::luminance_changed ()
330 {
331         dcp::Luminance::Unit unit;
332         switch (_luminance_unit->GetSelection()) {
333         case 0:
334                 unit = dcp::Luminance::Unit::CANDELA_PER_SQUARE_METRE;
335                 break;
336         case 1:
337                 unit = dcp::Luminance::Unit::FOOT_LAMBERT;
338                 break;
339         default:
340                 DCPOMATIC_ASSERT (false);
341         }
342
343         film()->set_luminance (dcp::Luminance(_luminance_value->GetValue(), unit));
344 }
345
346
347 void
348 SMPTEMetadataDialog::setup_sensitivity ()
349 {
350         MetadataDialog::setup_sensitivity ();
351
352         _chain->Enable (_enable_chain->GetValue());
353         _distributor->Enable (_enable_distributor->GetValue());
354 }
355
356
357 void
358 SMPTEMetadataDialog::enable_chain_changed ()
359 {
360         setup_sensitivity ();
361         if (_enable_chain->GetValue()) {
362                 film()->set_chain (wx_to_std(_chain->GetValue()));
363         } else {
364                 film()->set_chain ();
365         }
366 }
367
368
369 void
370 SMPTEMetadataDialog::enable_distributor_changed ()
371 {
372         setup_sensitivity ();
373         if (_enable_distributor->GetValue()) {
374                 film()->set_distributor (wx_to_std(_distributor->GetValue()));
375         } else {
376                 film()->set_distributor ();
377         }
378 }
379
380