Use FileDialog for Add DKDM in the KDM creator.
[dcpomatic.git] / src / lib / config.cc
1 /*
2     Copyright (C) 2012-2022 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 "cinema.h"
23 #include "colour_conversion.h"
24 #include "compose.hpp"
25 #include "config.h"
26 #include "constants.h"
27 #include "cross.h"
28 #include "crypto.h"
29 #include "dcp_content_type.h"
30 #include "dkdm_recipient.h"
31 #include "dkdm_wrapper.h"
32 #include "film.h"
33 #include "filter.h"
34 #include "log.h"
35 #include "ratio.h"
36 #include "zipper.h"
37 #include <dcp/certificate_chain.h>
38 #include <dcp/name_format.h>
39 #include <dcp/raw_convert.h>
40 #include <libcxml/cxml.h>
41 #include <glib.h>
42 #include <libxml++/libxml++.h>
43 #include <boost/filesystem.hpp>
44 #include <boost/algorithm/string.hpp>
45 #include <boost/thread.hpp>
46 #include <cstdlib>
47 #include <fstream>
48 #include <iostream>
49
50 #include "i18n.h"
51
52
53 using std::cout;
54 using std::dynamic_pointer_cast;
55 using std::ifstream;
56 using std::list;
57 using std::make_shared;
58 using std::max;
59 using std::min;
60 using std::remove;
61 using std::shared_ptr;
62 using std::string;
63 using std::vector;
64 using boost::algorithm::trim;
65 using boost::optional;
66 using dcp::raw_convert;
67
68
69 Config* Config::_instance = 0;
70 int const Config::_current_version = 3;
71 boost::signals2::signal<void (Config::LoadFailure)> Config::FailedToLoad;
72 boost::signals2::signal<void (string)> Config::Warning;
73 boost::signals2::signal<bool (Config::BadReason)> Config::Bad;
74
75
76 /** Construct default configuration */
77 Config::Config ()
78         /* DKDMs are not considered a thing to reset on set_defaults() */
79         : _dkdms (new DKDMGroup ("root"))
80         , _default_kdm_duration (1, RoughDuration::Unit::WEEKS)
81         , _export(this)
82 {
83         set_defaults ();
84 }
85
86 void
87 Config::set_defaults ()
88 {
89         _master_encoding_threads = max (2U, boost::thread::hardware_concurrency ());
90         _server_encoding_threads = max (2U, boost::thread::hardware_concurrency ());
91         _server_port_base = 6192;
92         _use_any_servers = true;
93         _servers.clear ();
94         _only_servers_encode = false;
95         _tms_protocol = FileTransferProtocol::SCP;
96         _tms_passive = true;
97         _tms_ip = "";
98         _tms_path = ".";
99         _tms_user = "";
100         _tms_password = "";
101         _allow_any_dcp_frame_rate = false;
102         _allow_any_container = false;
103         _allow_96khz_audio = false;
104         _use_all_audio_channels = false;
105         _show_experimental_audio_processors = false;
106         _language = optional<string> ();
107         _default_still_length = 10;
108         _default_dcp_content_type = DCPContentType::from_isdcf_name ("FTR");
109         _default_dcp_audio_channels = 6;
110         _default_j2k_bandwidth = 150000000;
111         _default_audio_delay = 0;
112         _default_interop = false;
113         _default_metadata.clear ();
114         _upload_after_make_dcp = false;
115         _mail_server = "";
116         _mail_port = 25;
117         _mail_protocol = EmailProtocol::AUTO;
118         _mail_user = "";
119         _mail_password = "";
120         _kdm_from = "";
121         _kdm_cc.clear ();
122         _kdm_bcc = "";
123         _notification_from = "";
124         _notification_to = "";
125         _notification_cc.clear ();
126         _notification_bcc = "";
127         _check_for_updates = false;
128         _check_for_test_updates = false;
129         _maximum_j2k_bandwidth = 250000000;
130         _log_types = LogEntry::TYPE_GENERAL | LogEntry::TYPE_WARNING | LogEntry::TYPE_ERROR | LogEntry::TYPE_DISK;
131         _analyse_ebur128 = true;
132         _automatic_audio_analysis = false;
133 #ifdef DCPOMATIC_WINDOWS
134         _win32_console = false;
135 #endif
136         /* At the moment we don't write these files anywhere new after a version change, so they will be read from
137          * ~/.config/dcpomatic2 (or equivalent) and written back there.
138          */
139         _cinemas_file = read_path ("cinemas.xml");
140         _dkdm_recipients_file = read_path ("dkdm_recipients.xml");
141         _show_hints_before_make_dcp = true;
142         _confirm_kdm_email = true;
143         _kdm_container_name_format = dcp::NameFormat ("KDM %f %c");
144         _kdm_filename_format = dcp::NameFormat ("KDM %f %c %s");
145         _dkdm_filename_format = dcp::NameFormat ("DKDM %f %c %s");
146         _dcp_metadata_filename_format = dcp::NameFormat ("%t");
147         _dcp_asset_filename_format = dcp::NameFormat ("%t");
148         _jump_to_selected = true;
149         for (int i = 0; i < NAG_COUNT; ++i) {
150                 _nagged[i] = false;
151         }
152         _sound = true;
153         _sound_output = optional<string> ();
154         _last_kdm_write_type = KDM_WRITE_FLAT;
155         _last_dkdm_write_type = DKDM_WRITE_INTERNAL;
156
157         /* I think the scaling factor here should be the ratio of the longest frame
158            encode time to the shortest; if the thread count is T, longest time is L
159            and the shortest time S we could encode L/S frames per thread whilst waiting
160            for the L frame to encode so we might have to store LT/S frames.
161
162            However we don't want to use too much memory, so keep it a bit lower than we'd
163            perhaps like.  A J2K frame is typically about 1Mb so 3 here will mean we could
164            use about 240Mb with 72 encoding threads.
165         */
166         _frames_in_memory_multiplier = 3;
167         _decode_reduction = optional<int>();
168         _default_notify = false;
169         for (int i = 0; i < NOTIFICATION_COUNT; ++i) {
170                 _notification[i] = false;
171         }
172         _barco_username = optional<string>();
173         _barco_password = optional<string>();
174         _christie_username = optional<string>();
175         _christie_password = optional<string>();
176         _gdc_username = optional<string>();
177         _gdc_password = optional<string>();
178         _player_mode = PLAYER_MODE_WINDOW;
179         _image_display = 0;
180         _video_view_type = VIDEO_VIEW_SIMPLE;
181         _respect_kdm_validity_periods = true;
182         _player_debug_log_file = boost::none;
183         _player_content_directory = boost::none;
184         _player_playlist_directory = boost::none;
185         _player_kdm_directory = boost::none;
186         _audio_mapping = boost::none;
187         _custom_languages.clear ();
188         _initial_paths.clear();
189         _initial_paths["AddFilesPath"] = boost::none;
190         _initial_paths["AddDKDMPath"] = boost::none;
191         _use_isdcf_name_by_default = true;
192         _write_kdms_to_disk = true;
193         _email_kdms = false;
194         _default_kdm_type = dcp::Formulation::MODIFIED_TRANSITIONAL_1;
195         _default_kdm_duration = RoughDuration(1, RoughDuration::Unit::WEEKS);
196         _auto_crop_threshold = 0.1;
197         _last_release_notes_version = boost::none;
198
199         _allowed_dcp_frame_rates.clear ();
200         _allowed_dcp_frame_rates.push_back (24);
201         _allowed_dcp_frame_rates.push_back (25);
202         _allowed_dcp_frame_rates.push_back (30);
203         _allowed_dcp_frame_rates.push_back (48);
204         _allowed_dcp_frame_rates.push_back (50);
205         _allowed_dcp_frame_rates.push_back (60);
206
207         set_kdm_email_to_default ();
208         set_notification_email_to_default ();
209         set_cover_sheet_to_default ();
210
211         _main_divider_sash_position = {};
212         _main_content_divider_sash_position = {};
213
214         _export.set_defaults();
215 }
216
217 void
218 Config::restore_defaults ()
219 {
220         Config::instance()->set_defaults ();
221         Config::instance()->changed ();
222 }
223
224 shared_ptr<dcp::CertificateChain>
225 Config::create_certificate_chain ()
226 {
227         return make_shared<dcp::CertificateChain> (
228                 openssl_path(),
229                 CERTIFICATE_VALIDITY_PERIOD,
230                 "dcpomatic.com",
231                 "dcpomatic.com",
232                 ".dcpomatic.smpte-430-2.ROOT",
233                 ".dcpomatic.smpte-430-2.INTERMEDIATE",
234                 "CS.dcpomatic.smpte-430-2.LEAF"
235                 );
236 }
237
238 void
239 Config::backup ()
240 {
241         using namespace boost::filesystem;
242
243         auto copy_adding_number = [](path const& path_to_copy) {
244
245                 auto add_number = [](path const& path, int number) {
246                         return String::compose("%1.%2", path, number);
247                 };
248
249                 int n = 1;
250                 while (n < 100 && exists(add_number(path_to_copy, n))) {
251                         ++n;
252                 }
253                 boost::system::error_code ec;
254                 copy_file(path_to_copy, add_number(path_to_copy, n), ec);
255         };
256
257         /* Make a backup copy of any config.xml, cinemas.xml, dkdm_recipients.xml that we might be about
258          * to write over.  This is more intended for the situation where we have a corrupted config.xml,
259          * and decide to overwrite it with a new one (possibly losing important details in the corrupted
260          * file).  But we might as well back up the other files while we're about it.
261          */
262
263         /* This uses the State::write_path stuff so, e.g. for a current version 2.16 we might copy
264          * ~/.config/dcpomatic2/2.16/config.xml to ~/.config/dcpomatic2/2.16/config.xml.1
265          */
266         copy_adding_number (config_write_file());
267
268         /* These do not use State::write_path, so whatever path is in the Config we will copy
269          * adding a number.
270          */
271         copy_adding_number (_cinemas_file);
272         copy_adding_number (_dkdm_recipients_file);
273 }
274
275 void
276 Config::read ()
277 {
278         read_config();
279         read_cinemas();
280         read_dkdm_recipients();
281 }
282
283
284 void
285 Config::read_config()
286 try
287 {
288         cxml::Document f ("Config");
289         f.read_file (config_read_file());
290
291         auto version = f.optional_number_child<int> ("Version");
292         if (version && *version < _current_version) {
293                 /* Back up the old config before we re-write it in a back-incompatible way */
294                 backup ();
295         }
296
297         if (f.optional_number_child<int>("NumLocalEncodingThreads")) {
298                 _master_encoding_threads = _server_encoding_threads = f.optional_number_child<int>("NumLocalEncodingThreads").get();
299         } else {
300                 _master_encoding_threads = f.number_child<int>("MasterEncodingThreads");
301                 _server_encoding_threads = f.number_child<int>("ServerEncodingThreads");
302         }
303
304         _default_directory = f.optional_string_child ("DefaultDirectory");
305         if (_default_directory && _default_directory->empty ()) {
306                 /* We used to store an empty value for this to mean "none set" */
307                 _default_directory = boost::optional<boost::filesystem::path> ();
308         }
309
310         auto b = f.optional_number_child<int> ("ServerPort");
311         if (!b) {
312                 b = f.optional_number_child<int> ("ServerPortBase");
313         }
314         _server_port_base = b.get ();
315
316         auto u = f.optional_bool_child ("UseAnyServers");
317         _use_any_servers = u.get_value_or (true);
318
319         for (auto i: f.node_children("Server")) {
320                 if (i->node_children("HostName").size() == 1) {
321                         _servers.push_back (i->string_child ("HostName"));
322                 } else {
323                         _servers.push_back (i->content ());
324                 }
325         }
326
327         _only_servers_encode = f.optional_bool_child ("OnlyServersEncode").get_value_or (false);
328         _tms_protocol = static_cast<FileTransferProtocol>(f.optional_number_child<int>("TMSProtocol").get_value_or(static_cast<int>(FileTransferProtocol::SCP)));
329         _tms_passive = f.optional_bool_child("TMSPassive").get_value_or(true);
330         _tms_ip = f.string_child ("TMSIP");
331         _tms_path = f.string_child ("TMSPath");
332         _tms_user = f.string_child ("TMSUser");
333         _tms_password = f.string_child ("TMSPassword");
334
335         _language = f.optional_string_child ("Language");
336
337         _default_dcp_content_type = DCPContentType::from_isdcf_name(f.optional_string_child("DefaultDCPContentType").get_value_or("FTR"));
338         _default_dcp_audio_channels = f.optional_number_child<int>("DefaultDCPAudioChannels").get_value_or (6);
339
340         if (f.optional_string_child ("DCPMetadataIssuer")) {
341                 _dcp_issuer = f.string_child ("DCPMetadataIssuer");
342         } else if (f.optional_string_child ("DCPIssuer")) {
343                 _dcp_issuer = f.string_child ("DCPIssuer");
344         }
345
346         auto up = f.optional_bool_child("UploadAfterMakeDCP");
347         if (!up) {
348                 up = f.optional_bool_child("DefaultUploadAfterMakeDCP");
349         }
350         _upload_after_make_dcp = up.get_value_or (false);
351         _dcp_creator = f.optional_string_child ("DCPCreator").get_value_or ("");
352         _dcp_company_name = f.optional_string_child("DCPCompanyName").get_value_or("");
353         _dcp_product_name = f.optional_string_child("DCPProductName").get_value_or("");
354         _dcp_product_version = f.optional_string_child("DCPProductVersion").get_value_or("");
355         _dcp_j2k_comment = f.optional_string_child("DCPJ2KComment").get_value_or("");
356
357         _default_still_length = f.optional_number_child<int>("DefaultStillLength").get_value_or (10);
358         _default_j2k_bandwidth = f.optional_number_child<int>("DefaultJ2KBandwidth").get_value_or (200000000);
359         _default_audio_delay = f.optional_number_child<int>("DefaultAudioDelay").get_value_or (0);
360         _default_interop = f.optional_bool_child("DefaultInterop").get_value_or (false);
361
362         try {
363                 auto al = f.optional_string_child("DefaultAudioLanguage");
364                 if (al) {
365                         _default_audio_language = dcp::LanguageTag(*al);
366                 }
367         } catch (std::runtime_error&) {}
368
369         try {
370                 auto te = f.optional_string_child("DefaultTerritory");
371                 if (te) {
372                         _default_territory = dcp::LanguageTag::RegionSubtag(*te);
373                 }
374         } catch (std::runtime_error&) {}
375
376         for (auto const& i: f.node_children("DefaultMetadata")) {
377                 _default_metadata[i->string_attribute("key")] = i->content();
378         }
379
380         _default_kdm_directory = f.optional_string_child("DefaultKDMDirectory");
381
382         /* Read any cinemas that are still lying around in the config file
383          * from an old version.
384          */
385         read_cinemas (f);
386
387         _mail_server = f.string_child ("MailServer");
388         _mail_port = f.optional_number_child<int> ("MailPort").get_value_or (25);
389
390         {
391                 /* Make sure this matches the code in write_config */
392                 string const protocol = f.optional_string_child("MailProtocol").get_value_or("Auto");
393                 if (protocol == "Auto") {
394                         _mail_protocol = EmailProtocol::AUTO;
395                 } else if (protocol == "Plain") {
396                         _mail_protocol = EmailProtocol::PLAIN;
397                 } else if (protocol == "STARTTLS") {
398                         _mail_protocol = EmailProtocol::STARTTLS;
399                 } else if (protocol == "SSL") {
400                         _mail_protocol = EmailProtocol::SSL;
401                 }
402         }
403
404         _mail_user = f.optional_string_child("MailUser").get_value_or ("");
405         _mail_password = f.optional_string_child("MailPassword").get_value_or ("");
406
407         _kdm_subject = f.optional_string_child ("KDMSubject").get_value_or (_("KDM delivery: $CPL_NAME"));
408         _kdm_from = f.string_child ("KDMFrom");
409         for (auto i: f.node_children("KDMCC")) {
410                 if (!i->content().empty()) {
411                         _kdm_cc.push_back (i->content ());
412                 }
413         }
414         _kdm_bcc = f.optional_string_child ("KDMBCC").get_value_or ("");
415         _kdm_email = f.string_child ("KDMEmail");
416
417         _notification_subject = f.optional_string_child("NotificationSubject").get_value_or(_("DCP-o-matic notification"));
418         _notification_from = f.optional_string_child("NotificationFrom").get_value_or("");
419         _notification_to = f.optional_string_child("NotificationTo").get_value_or("");
420         for (auto i: f.node_children("NotificationCC")) {
421                 if (!i->content().empty()) {
422                         _notification_cc.push_back (i->content ());
423                 }
424         }
425         _notification_bcc = f.optional_string_child("NotificationBCC").get_value_or("");
426         if (f.optional_string_child("NotificationEmail")) {
427                 _notification_email = f.string_child("NotificationEmail");
428         }
429
430         _check_for_updates = f.optional_bool_child("CheckForUpdates").get_value_or (false);
431         _check_for_test_updates = f.optional_bool_child("CheckForTestUpdates").get_value_or (false);
432
433         _maximum_j2k_bandwidth = f.optional_number_child<int> ("MaximumJ2KBandwidth").get_value_or (250000000);
434         _allow_any_dcp_frame_rate = f.optional_bool_child ("AllowAnyDCPFrameRate").get_value_or (false);
435         _allow_any_container = f.optional_bool_child ("AllowAnyContainer").get_value_or (false);
436         _allow_96khz_audio = f.optional_bool_child("Allow96kHzAudio").get_value_or(false);
437         _use_all_audio_channels = f.optional_bool_child("UseAllAudioChannels").get_value_or(false);
438         _show_experimental_audio_processors = f.optional_bool_child ("ShowExperimentalAudioProcessors").get_value_or (false);
439
440         _log_types = f.optional_number_child<int> ("LogTypes").get_value_or (LogEntry::TYPE_GENERAL | LogEntry::TYPE_WARNING | LogEntry::TYPE_ERROR);
441         _analyse_ebur128 = f.optional_bool_child("AnalyseEBUR128").get_value_or (true);
442         _automatic_audio_analysis = f.optional_bool_child ("AutomaticAudioAnalysis").get_value_or (false);
443 #ifdef DCPOMATIC_WINDOWS
444         _win32_console = f.optional_bool_child ("Win32Console").get_value_or (false);
445 #endif
446
447         for (auto i: f.node_children("History")) {
448                 _history.push_back (i->content ());
449         }
450
451         for (auto i: f.node_children("PlayerHistory")) {
452                 _player_history.push_back (i->content ());
453         }
454
455         auto signer = f.optional_node_child ("Signer");
456         if (signer) {
457                 auto c = make_shared<dcp::CertificateChain>();
458                 /* Read the signing certificates and private key in from the config file */
459                 for (auto i: signer->node_children ("Certificate")) {
460                         c->add (dcp::Certificate (i->content ()));
461                 }
462                 c->set_key (signer->string_child ("PrivateKey"));
463                 _signer_chain = c;
464         } else {
465                 /* Make a new set of signing certificates and key */
466                 _signer_chain = create_certificate_chain ();
467         }
468
469         auto decryption = f.optional_node_child ("Decryption");
470         if (decryption) {
471                 auto c = make_shared<dcp::CertificateChain>();
472                 for (auto i: decryption->node_children ("Certificate")) {
473                         c->add (dcp::Certificate (i->content ()));
474                 }
475                 c->set_key (decryption->string_child ("PrivateKey"));
476                 _decryption_chain = c;
477         } else {
478                 _decryption_chain = create_certificate_chain ();
479         }
480
481         /* These must be done before we call Bad as that might set one
482            of the nags.
483         */
484         for (auto i: f.node_children("Nagged")) {
485                 auto const id = i->number_attribute<int>("Id");
486                 if (id >= 0 && id < NAG_COUNT) {
487                         _nagged[id] = raw_convert<int>(i->content());
488                 }
489         }
490
491         auto bad = check_certificates ();
492         if (bad) {
493                 auto const remake = Bad(*bad);
494                 if (remake && *remake) {
495                         switch (*bad) {
496                         case BAD_SIGNER_UTF8_STRINGS:
497                         case BAD_SIGNER_INCONSISTENT:
498                         case BAD_SIGNER_VALIDITY_TOO_LONG:
499                                 _signer_chain = create_certificate_chain ();
500                                 break;
501                         case BAD_DECRYPTION_INCONSISTENT:
502                                 _decryption_chain = create_certificate_chain ();
503                                 break;
504                         }
505                 }
506         }
507
508         if (f.optional_node_child("DKDMGroup")) {
509                 /* New-style: all DKDMs in a group */
510                 _dkdms = dynamic_pointer_cast<DKDMGroup> (DKDMBase::read (f.node_child("DKDMGroup")));
511         } else {
512                 /* Old-style: one or more DKDM nodes */
513                 _dkdms = make_shared<DKDMGroup>("root");
514                 for (auto i: f.node_children("DKDM")) {
515                         _dkdms->add (DKDMBase::read (i));
516                 }
517         }
518         _cinemas_file = f.optional_string_child("CinemasFile").get_value_or(read_path("cinemas.xml").string());
519         _dkdm_recipients_file = f.optional_string_child("DKDMRecipientsFile").get_value_or(read_path("dkdm_recipients.xml").string());
520         _show_hints_before_make_dcp = f.optional_bool_child("ShowHintsBeforeMakeDCP").get_value_or (true);
521         _confirm_kdm_email = f.optional_bool_child("ConfirmKDMEmail").get_value_or (true);
522         _kdm_container_name_format = dcp::NameFormat (f.optional_string_child("KDMContainerNameFormat").get_value_or ("KDM %f %c"));
523         _kdm_filename_format = dcp::NameFormat (f.optional_string_child("KDMFilenameFormat").get_value_or ("KDM %f %c %s"));
524         _dkdm_filename_format = dcp::NameFormat (f.optional_string_child("DKDMFilenameFormat").get_value_or("DKDM %f %c %s"));
525         _dcp_metadata_filename_format = dcp::NameFormat (f.optional_string_child("DCPMetadataFilenameFormat").get_value_or ("%t"));
526         _dcp_asset_filename_format = dcp::NameFormat (f.optional_string_child("DCPAssetFilenameFormat").get_value_or ("%t"));
527         _jump_to_selected = f.optional_bool_child("JumpToSelected").get_value_or (true);
528         /* The variable was renamed but not the XML tag */
529         _sound = f.optional_bool_child("PreviewSound").get_value_or (true);
530         _sound_output = f.optional_string_child("PreviewSoundOutput");
531         if (f.optional_string_child("CoverSheet")) {
532                 _cover_sheet = f.optional_string_child("CoverSheet").get();
533         }
534         _last_player_load_directory = f.optional_string_child("LastPlayerLoadDirectory");
535         if (f.optional_string_child("LastKDMWriteType")) {
536                 if (f.optional_string_child("LastKDMWriteType").get() == "flat") {
537                         _last_kdm_write_type = KDM_WRITE_FLAT;
538                 } else if (f.optional_string_child("LastKDMWriteType").get() == "folder") {
539                         _last_kdm_write_type = KDM_WRITE_FOLDER;
540                 } else if (f.optional_string_child("LastKDMWriteType").get() == "zip") {
541                         _last_kdm_write_type = KDM_WRITE_ZIP;
542                 }
543         }
544         if (f.optional_string_child("LastDKDMWriteType")) {
545                 if (f.optional_string_child("LastDKDMWriteType").get() == "internal") {
546                         _last_dkdm_write_type = DKDM_WRITE_INTERNAL;
547                 } else if (f.optional_string_child("LastDKDMWriteType").get() == "file") {
548                         _last_dkdm_write_type = DKDM_WRITE_FILE;
549                 }
550         }
551         _frames_in_memory_multiplier = f.optional_number_child<int>("FramesInMemoryMultiplier").get_value_or(3);
552         _decode_reduction = f.optional_number_child<int>("DecodeReduction");
553         _default_notify = f.optional_bool_child("DefaultNotify").get_value_or(false);
554
555         for (auto i: f.node_children("Notification")) {
556                 int const id = i->number_attribute<int>("Id");
557                 if (id >= 0 && id < NOTIFICATION_COUNT) {
558                         _notification[id] = raw_convert<int>(i->content());
559                 }
560         }
561
562         _barco_username = f.optional_string_child("BarcoUsername");
563         _barco_password = f.optional_string_child("BarcoPassword");
564         _christie_username = f.optional_string_child("ChristieUsername");
565         _christie_password = f.optional_string_child("ChristiePassword");
566         _gdc_username = f.optional_string_child("GDCUsername");
567         _gdc_password = f.optional_string_child("GDCPassword");
568
569         auto pm = f.optional_string_child("PlayerMode");
570         if (pm && *pm == "window") {
571                 _player_mode = PLAYER_MODE_WINDOW;
572         } else if (pm && *pm == "full") {
573                 _player_mode = PLAYER_MODE_FULL;
574         } else if (pm && *pm == "dual") {
575                 _player_mode = PLAYER_MODE_DUAL;
576         }
577
578         _image_display = f.optional_number_child<int>("ImageDisplay").get_value_or(0);
579         auto vc = f.optional_string_child("VideoViewType");
580         if (vc && *vc == "opengl") {
581                 _video_view_type = VIDEO_VIEW_OPENGL;
582         } else if (vc && *vc == "simple") {
583                 _video_view_type = VIDEO_VIEW_SIMPLE;
584         }
585         _respect_kdm_validity_periods = f.optional_bool_child("RespectKDMValidityPeriods").get_value_or(true);
586         _player_debug_log_file = f.optional_string_child("PlayerDebugLogFile");
587         _player_content_directory = f.optional_string_child("PlayerContentDirectory");
588         _player_playlist_directory = f.optional_string_child("PlayerPlaylistDirectory");
589         _player_kdm_directory = f.optional_string_child("PlayerKDMDirectory");
590
591         if (f.optional_node_child("AudioMapping")) {
592                 _audio_mapping = AudioMapping (f.node_child("AudioMapping"), Film::current_state_version);
593         }
594
595         for (auto i: f.node_children("CustomLanguage")) {
596                 try {
597                         /* This will fail if it's called before dcp::init() as it won't recognise the
598                          * tag.  That's OK because the Config will be reloaded again later.
599                          */
600                         _custom_languages.push_back (dcp::LanguageTag(i->content()));
601                 } catch (std::runtime_error& e) {}
602         }
603
604         for (auto& initial: _initial_paths) {
605                 initial.second = f.optional_string_child(initial.first);
606         }
607         _use_isdcf_name_by_default = f.optional_bool_child("UseISDCFNameByDefault").get_value_or(true);
608         _write_kdms_to_disk = f.optional_bool_child("WriteKDMsToDisk").get_value_or(true);
609         _email_kdms = f.optional_bool_child("EmailKDMs").get_value_or(false);
610         _default_kdm_type = dcp::string_to_formulation(f.optional_string_child("DefaultKDMType").get_value_or("modified-transitional-1"));
611         if (auto duration = f.optional_node_child("DefaultKDMDuration")) {
612                 _default_kdm_duration = RoughDuration(duration);
613         } else {
614                 _default_kdm_duration = RoughDuration(1, RoughDuration::Unit::WEEKS);
615         }
616         _auto_crop_threshold = f.optional_number_child<double>("AutoCropThreshold").get_value_or(0.1);
617         _last_release_notes_version = f.optional_string_child("LastReleaseNotesVersion");
618         _main_divider_sash_position = f.optional_number_child<int>("MainDividerSashPosition");
619         _main_content_divider_sash_position = f.optional_number_child<int>("MainContentDividerSashPosition");
620
621         _export.read(f.optional_node_child("Export"));
622 }
623 catch (...) {
624         if (have_existing("config.xml")) {
625                 backup ();
626                 /* We have a config file but it didn't load */
627                 FailedToLoad(LoadFailure::CONFIG);
628         }
629         set_defaults ();
630         /* Make a new set of signing certificates and key */
631         _signer_chain = create_certificate_chain ();
632         /* And similar for decryption of KDMs */
633         _decryption_chain = create_certificate_chain ();
634         write_config();
635 }
636
637
638 void
639 Config::read_cinemas()
640 {
641         if (boost::filesystem::exists (_cinemas_file)) {
642                 try {
643                         cxml::Document f("Cinemas");
644                         f.read_file(_cinemas_file);
645                         read_cinemas(f);
646                 } catch (...) {
647                         backup();
648                         FailedToLoad(LoadFailure::CINEMAS);
649                         write_cinemas();
650                 }
651         }
652 }
653
654
655 void
656 Config::read_dkdm_recipients()
657 {
658         if (boost::filesystem::exists (_dkdm_recipients_file)) {
659                 try {
660                         cxml::Document f("DKDMRecipients");
661                         f.read_file(_dkdm_recipients_file);
662                         read_dkdm_recipients(f);
663                 } catch (...) {
664                         backup();
665                         FailedToLoad(LoadFailure::DKDM_RECIPIENTS);
666                         write_dkdm_recipients();
667                 }
668         }
669 }
670
671
672 /** @return Singleton instance */
673 Config *
674 Config::instance ()
675 {
676         if (_instance == nullptr) {
677                 _instance = new Config;
678                 _instance->read ();
679         }
680
681         return _instance;
682 }
683
684 /** Write our configuration to disk */
685 void
686 Config::write () const
687 {
688         write_config ();
689         write_cinemas ();
690         write_dkdm_recipients ();
691 }
692
693 void
694 Config::write_config () const
695 {
696         xmlpp::Document doc;
697         auto root = doc.create_root_node ("Config");
698
699         /* [XML] Version The version number of the configuration file format. */
700         root->add_child("Version")->add_child_text (raw_convert<string>(_current_version));
701         /* [XML] MasterEncodingThreads Number of encoding threads to use when running as master. */
702         root->add_child("MasterEncodingThreads")->add_child_text (raw_convert<string> (_master_encoding_threads));
703         /* [XML] ServerEncodingThreads Number of encoding threads to use when running as server. */
704         root->add_child("ServerEncodingThreads")->add_child_text (raw_convert<string> (_server_encoding_threads));
705         if (_default_directory) {
706                 /* [XML:opt] DefaultDirectory Default directory when creating a new film in the GUI. */
707                 root->add_child("DefaultDirectory")->add_child_text (_default_directory->string ());
708         }
709         /* [XML] ServerPortBase Port number to use for frame encoding requests.  <code>ServerPortBase</code> + 1 and
710            <code>ServerPortBase</code> + 2 are used for querying servers.  <code>ServerPortBase</code> + 3 is used
711            by the batch converter to listen for job requests.
712         */
713         root->add_child("ServerPortBase")->add_child_text (raw_convert<string> (_server_port_base));
714         /* [XML] UseAnyServers 1 to broadcast to look for encoding servers to use, 0 to use only those configured. */
715         root->add_child("UseAnyServers")->add_child_text (_use_any_servers ? "1" : "0");
716
717         for (auto i: _servers) {
718                 /* [XML:opt] Server IP address or hostname of an encoding server to use; you can use as many of these tags
719                    as you like.
720                 */
721                 root->add_child("Server")->add_child_text (i);
722         }
723
724         /* [XML] OnlyServersEncode 1 to set the master to do decoding of source content no JPEG2000 encoding; all encoding
725            is done by the encoding servers.  0 to set the master to do some encoding as well as coordinating the job.
726         */
727         root->add_child("OnlyServersEncode")->add_child_text (_only_servers_encode ? "1" : "0");
728         /* [XML] TMSProtocol Protocol to use to copy files to a TMS; 0 to use SCP, 1 for FTP. */
729         root->add_child("TMSProtocol")->add_child_text (raw_convert<string> (static_cast<int> (_tms_protocol)));
730         /* [XML] TMSPassive True to use PASV mode with TMS FTP connections. */
731         root->add_child("TMSPassive")->add_child_text(_tms_passive ? "1" : "0");
732         /* [XML] TMSIP IP address of TMS. */
733         root->add_child("TMSIP")->add_child_text (_tms_ip);
734         /* [XML] TMSPath Path on the TMS to copy files to. */
735         root->add_child("TMSPath")->add_child_text (_tms_path);
736         /* [XML] TMSUser Username to log into the TMS with. */
737         root->add_child("TMSUser")->add_child_text (_tms_user);
738         /* [XML] TMSPassword Password to log into the TMS with. */
739         root->add_child("TMSPassword")->add_child_text (_tms_password);
740         if (_language) {
741                 /* [XML:opt] Language Language to use in the GUI e.g. <code>fr_FR</code>. */
742                 root->add_child("Language")->add_child_text (_language.get());
743         }
744         if (_default_dcp_content_type) {
745                 /* [XML:opt] DefaultDCPContentType Default content type to use when creating new films (<code>FTR</code>, <code>SHR</code>,
746                    <code>TLR</code>, <code>TST</code>, <code>XSN</code>, <code>RTG</code>, <code>TSR</code>, <code>POL</code>,
747                    <code>PSA</code> or <code>ADV</code>). */
748                 root->add_child("DefaultDCPContentType")->add_child_text (_default_dcp_content_type->isdcf_name ());
749         }
750         /* [XML] DefaultDCPAudioChannels Default number of audio channels to use when creating new films. */
751         root->add_child("DefaultDCPAudioChannels")->add_child_text (raw_convert<string> (_default_dcp_audio_channels));
752         /* [XML] DCPIssuer Issuer text to write into CPL files. */
753         root->add_child("DCPIssuer")->add_child_text (_dcp_issuer);
754         /* [XML] DCPCreator Creator text to write into CPL files. */
755         root->add_child("DCPCreator")->add_child_text (_dcp_creator);
756         /* [XML] Company name to write into MXF files. */
757         root->add_child("DCPCompanyName")->add_child_text (_dcp_company_name);
758         /* [XML] Product name to write into MXF files. */
759         root->add_child("DCPProductName")->add_child_text (_dcp_product_name);
760         /* [XML] Product version to write into MXF files. */
761         root->add_child("DCPProductVersion")->add_child_text (_dcp_product_version);
762         /* [XML] Comment to write into JPEG2000 data. */
763         root->add_child("DCPJ2KComment")->add_child_text (_dcp_j2k_comment);
764         /* [XML] UploadAfterMakeDCP 1 to upload to a TMS after making a DCP, 0 for no upload. */
765         root->add_child("UploadAfterMakeDCP")->add_child_text (_upload_after_make_dcp ? "1" : "0");
766
767         /* [XML] DefaultStillLength Default length (in seconds) for still images in new films. */
768         root->add_child("DefaultStillLength")->add_child_text (raw_convert<string> (_default_still_length));
769         /* [XML] DefaultJ2KBandwidth Default bitrate (in bits per second) for JPEG2000 data in new films. */
770         root->add_child("DefaultJ2KBandwidth")->add_child_text (raw_convert<string> (_default_j2k_bandwidth));
771         /* [XML] DefaultAudioDelay Default delay to apply to audio (positive moves audio later) in milliseconds. */
772         root->add_child("DefaultAudioDelay")->add_child_text (raw_convert<string> (_default_audio_delay));
773         /* [XML] DefaultInterop 1 to default new films to Interop, 0 for SMPTE. */
774         root->add_child("DefaultInterop")->add_child_text (_default_interop ? "1" : "0");
775         if (_default_audio_language) {
776                 /* [XML] DefaultAudioLanguage Default audio language to use for new films */
777                 root->add_child("DefaultAudioLanguage")->add_child_text(_default_audio_language->to_string());
778         }
779         if (_default_territory) {
780                 /* [XML] DefaultTerritory Default territory to use for new films */
781                 root->add_child("DefaultTerritory")->add_child_text(_default_territory->subtag());
782         }
783         for (auto const& i: _default_metadata) {
784                 auto c = root->add_child("DefaultMetadata");
785                 c->set_attribute("key", i.first);
786                 c->add_child_text(i.second);
787         }
788         if (_default_kdm_directory) {
789                 /* [XML:opt] DefaultKDMDirectory Default directory to write KDMs to. */
790                 root->add_child("DefaultKDMDirectory")->add_child_text (_default_kdm_directory->string ());
791         }
792         _default_kdm_duration.as_xml(root->add_child("DefaultKDMDuration"));
793         /* [XML] MailServer Hostname of SMTP server to use. */
794         root->add_child("MailServer")->add_child_text (_mail_server);
795         /* [XML] MailPort Port number to use on SMTP server. */
796         root->add_child("MailPort")->add_child_text (raw_convert<string> (_mail_port));
797         /* [XML] MailProtocol Protocol to use on SMTP server (Auto, Plain, STARTTLS or SSL) */
798         switch (_mail_protocol) {
799         case EmailProtocol::AUTO:
800                 root->add_child("MailProtocol")->add_child_text("Auto");
801                 break;
802         case EmailProtocol::PLAIN:
803                 root->add_child("MailProtocol")->add_child_text("Plain");
804                 break;
805         case EmailProtocol::STARTTLS:
806                 root->add_child("MailProtocol")->add_child_text("STARTTLS");
807                 break;
808         case EmailProtocol::SSL:
809                 root->add_child("MailProtocol")->add_child_text("SSL");
810                 break;
811         }
812         /* [XML] MailUser Username to use on SMTP server. */
813         root->add_child("MailUser")->add_child_text (_mail_user);
814         /* [XML] MailPassword Password to use on SMTP server. */
815         root->add_child("MailPassword")->add_child_text (_mail_password);
816
817         /* [XML] KDMSubject Subject to use for KDM emails. */
818         root->add_child("KDMSubject")->add_child_text (_kdm_subject);
819         /* [XML] KDMFrom From address to use for KDM emails. */
820         root->add_child("KDMFrom")->add_child_text (_kdm_from);
821         for (auto i: _kdm_cc) {
822                 /* [XML] KDMCC CC address to use for KDM emails; you can use as many of these tags as you like. */
823                 root->add_child("KDMCC")->add_child_text (i);
824         }
825         /* [XML] KDMBCC BCC address to use for KDM emails. */
826         root->add_child("KDMBCC")->add_child_text (_kdm_bcc);
827         /* [XML] KDMEmail Text of KDM email. */
828         root->add_child("KDMEmail")->add_child_text (_kdm_email);
829
830         /* [XML] NotificationSubject Subject to use for notification emails. */
831         root->add_child("NotificationSubject")->add_child_text (_notification_subject);
832         /* [XML] NotificationFrom From address to use for notification emails. */
833         root->add_child("NotificationFrom")->add_child_text (_notification_from);
834         /* [XML] NotificationFrom To address to use for notification emails. */
835         root->add_child("NotificationTo")->add_child_text (_notification_to);
836         for (auto i: _notification_cc) {
837                 /* [XML] NotificationCC CC address to use for notification emails; you can use as many of these tags as you like. */
838                 root->add_child("NotificationCC")->add_child_text (i);
839         }
840         /* [XML] NotificationBCC BCC address to use for notification emails. */
841         root->add_child("NotificationBCC")->add_child_text (_notification_bcc);
842         /* [XML] NotificationEmail Text of notification email. */
843         root->add_child("NotificationEmail")->add_child_text (_notification_email);
844
845         /* [XML] CheckForUpdates 1 to check dcpomatic.com for new versions, 0 to check only on request. */
846         root->add_child("CheckForUpdates")->add_child_text (_check_for_updates ? "1" : "0");
847         /* [XML] CheckForUpdates 1 to check dcpomatic.com for new text versions, 0 to check only on request. */
848         root->add_child("CheckForTestUpdates")->add_child_text (_check_for_test_updates ? "1" : "0");
849
850         /* [XML] MaximumJ2KBandwidth Maximum J2K bandwidth (in bits per second) that can be specified in the GUI. */
851         root->add_child("MaximumJ2KBandwidth")->add_child_text (raw_convert<string> (_maximum_j2k_bandwidth));
852         /* [XML] AllowAnyDCPFrameRate 1 to allow users to specify any frame rate when creating DCPs, 0 to limit the GUI to standard rates. */
853         root->add_child("AllowAnyDCPFrameRate")->add_child_text (_allow_any_dcp_frame_rate ? "1" : "0");
854         /* [XML] AllowAnyContainer 1 to allow users to user any container ratio for their DCP, 0 to limit the GUI to DCI Flat/Scope */
855         root->add_child("AllowAnyContainer")->add_child_text (_allow_any_container ? "1" : "0");
856         /* [XML] Allow96kHzAudio 1 to allow users to make DCPs with 96kHz audio, 0 to always make 48kHz DCPs */
857         root->add_child("Allow96kHzAudio")->add_child_text(_allow_96khz_audio ? "1" : "0");
858         /* [XML] UseAllAudioChannels 1 to allow users to map audio to all 16 DCP channels, 0 to limit to the channels used in standard DCPs */
859         root->add_child("UseAllAudioChannels")->add_child_text(_use_all_audio_channels ? "1" : "0");
860         /* [XML] ShowExperimentalAudioProcessors 1 to offer users the (experimental) audio upmixer processors, 0 to hide them */
861         root->add_child("ShowExperimentalAudioProcessors")->add_child_text (_show_experimental_audio_processors ? "1" : "0");
862         /* [XML] LogTypes Types of logging to write; a bitfield where 1 is general notes, 2 warnings, 4 errors, 8 debug information related
863            to 3D, 16 debug information related to encoding, 32 debug information for timing purposes, 64 debug information related
864            to sending email, 128 debug information related to the video view, 256 information about disk writing, 512 debug information
865            related to the player, 1024 debug information related to audio analyses.
866         */
867         root->add_child("LogTypes")->add_child_text (raw_convert<string> (_log_types));
868         /* [XML] AnalyseEBUR128 1 to do EBUR128 analyses when analysing audio, otherwise 0. */
869         root->add_child("AnalyseEBUR128")->add_child_text (_analyse_ebur128 ? "1" : "0");
870         /* [XML] AutomaticAudioAnalysis 1 to run audio analysis automatically when audio content is added to the film, otherwise 0. */
871         root->add_child("AutomaticAudioAnalysis")->add_child_text (_automatic_audio_analysis ? "1" : "0");
872 #ifdef DCPOMATIC_WINDOWS
873         if (_win32_console) {
874                 /* [XML] Win32Console 1 to open a console when running on Windows, otherwise 0.
875                  * We only write this if it's true, which is a bit of a hack to allow unit tests to work
876                  * more easily on Windows (without a platform-specific reference in config_write_utf8_test)
877                  */
878                 root->add_child("Win32Console")->add_child_text ("1");
879         }
880 #endif
881
882         /* [XML] Signer Certificate chain and private key to use when signing DCPs and KDMs.  Should contain <code>&lt;Certificate&gt;</code>
883            tags in order and a <code>&lt;PrivateKey&gt;</code> tag all containing PEM-encoded certificates or private keys as appropriate.
884         */
885         auto signer = root->add_child ("Signer");
886         DCPOMATIC_ASSERT (_signer_chain);
887         for (auto const& i: _signer_chain->unordered()) {
888                 signer->add_child("Certificate")->add_child_text (i.certificate (true));
889         }
890         signer->add_child("PrivateKey")->add_child_text (_signer_chain->key().get ());
891
892         /* [XML] Decryption Certificate chain and private key to use when decrypting KDMs */
893         auto decryption = root->add_child ("Decryption");
894         DCPOMATIC_ASSERT (_decryption_chain);
895         for (auto const& i: _decryption_chain->unordered()) {
896                 decryption->add_child("Certificate")->add_child_text (i.certificate (true));
897         }
898         decryption->add_child("PrivateKey")->add_child_text (_decryption_chain->key().get ());
899
900         /* [XML] History Filename of DCP to present in the <guilabel>File</guilabel> menu of the GUI; there can be more than one
901            of these tags.
902         */
903         for (auto i: _history) {
904                 root->add_child("History")->add_child_text (i.string ());
905         }
906
907         /* [XML] History Filename of DCP to present in the <guilabel>File</guilabel> menu of the player; there can be more than one
908            of these tags.
909         */
910         for (auto i: _player_history) {
911                 root->add_child("PlayerHistory")->add_child_text (i.string ());
912         }
913
914         /* [XML] DKDMGroup A group of DKDMs, each with a <code>Name</code> attribute, containing other <code>&lt;DKDMGroup&gt;</code>
915            or <code>&lt;DKDM&gt;</code> tags.
916         */
917         /* [XML] DKDM A DKDM as XML */
918         _dkdms->as_xml (root);
919
920         /* [XML] CinemasFile Filename of cinemas list file. */
921         root->add_child("CinemasFile")->add_child_text (_cinemas_file.string());
922         /* [XML] DKDMRecipientsFile Filename of DKDM recipients list file. */
923         root->add_child("DKDMRecipientsFile")->add_child_text (_dkdm_recipients_file.string());
924         /* [XML] ShowHintsBeforeMakeDCP 1 to show hints in the GUI before making a DCP, otherwise 0. */
925         root->add_child("ShowHintsBeforeMakeDCP")->add_child_text (_show_hints_before_make_dcp ? "1" : "0");
926         /* [XML] ConfirmKDMEmail 1 to confirm before sending KDM emails in the GUI, otherwise 0. */
927         root->add_child("ConfirmKDMEmail")->add_child_text (_confirm_kdm_email ? "1" : "0");
928         /* [XML] KDMFilenameFormat Format for KDM filenames. */
929         root->add_child("KDMFilenameFormat")->add_child_text (_kdm_filename_format.specification ());
930         /* [XML] KDMFilenameFormat Format for DKDM filenames. */
931         root->add_child("DKDMFilenameFormat")->add_child_text(_dkdm_filename_format.specification());
932         /* [XML] KDMContainerNameFormat Format for KDM containers (directories or ZIP files). */
933         root->add_child("KDMContainerNameFormat")->add_child_text (_kdm_container_name_format.specification ());
934         /* [XML] DCPMetadataFilenameFormat Format for DCP metadata filenames. */
935         root->add_child("DCPMetadataFilenameFormat")->add_child_text (_dcp_metadata_filename_format.specification ());
936         /* [XML] DCPAssetFilenameFormat Format for DCP asset filenames. */
937         root->add_child("DCPAssetFilenameFormat")->add_child_text (_dcp_asset_filename_format.specification ());
938         /* [XML] JumpToSelected 1 to make the GUI jump to the start of content when it is selected, otherwise 0. */
939         root->add_child("JumpToSelected")->add_child_text (_jump_to_selected ? "1" : "0");
940         /* [XML] Nagged 1 if a particular nag screen has been shown and should not be shown again, otherwise 0. */
941         for (int i = 0; i < NAG_COUNT; ++i) {
942                 xmlpp::Element* e = root->add_child ("Nagged");
943                 e->set_attribute ("Id", raw_convert<string>(i));
944                 e->add_child_text (_nagged[i] ? "1" : "0");
945         }
946         /* [XML] PreviewSound 1 to use sound in the GUI preview and player, otherwise 0. */
947         root->add_child("PreviewSound")->add_child_text (_sound ? "1" : "0");
948         if (_sound_output) {
949                 /* [XML:opt] PreviewSoundOutput Name of the audio output to use. */
950                 root->add_child("PreviewSoundOutput")->add_child_text (_sound_output.get());
951         }
952         /* [XML] CoverSheet Text of the cover sheet to write when making DCPs. */
953         root->add_child("CoverSheet")->add_child_text (_cover_sheet);
954         if (_last_player_load_directory) {
955                 root->add_child("LastPlayerLoadDirectory")->add_child_text(_last_player_load_directory->string());
956         }
957         /* [XML] LastKDMWriteType Last type of KDM-write: <code>flat</code> for a flat file, <code>folder</code> for a folder or <code>zip</code> for a ZIP file. */
958         if (_last_kdm_write_type) {
959                 switch (_last_kdm_write_type.get()) {
960                 case KDM_WRITE_FLAT:
961                         root->add_child("LastKDMWriteType")->add_child_text("flat");
962                         break;
963                 case KDM_WRITE_FOLDER:
964                         root->add_child("LastKDMWriteType")->add_child_text("folder");
965                         break;
966                 case KDM_WRITE_ZIP:
967                         root->add_child("LastKDMWriteType")->add_child_text("zip");
968                         break;
969                 }
970         }
971         /* [XML] LastDKDMWriteType Last type of DKDM-write: <code>file</code> for a file, <code>internal</code> to add to DCP-o-matic's list. */
972         if (_last_dkdm_write_type) {
973                 switch (_last_dkdm_write_type.get()) {
974                 case DKDM_WRITE_INTERNAL:
975                         root->add_child("LastDKDMWriteType")->add_child_text("internal");
976                         break;
977                 case DKDM_WRITE_FILE:
978                         root->add_child("LastDKDMWriteType")->add_child_text("file");
979                         break;
980                 }
981         }
982         /* [XML] FramesInMemoryMultiplier value to multiply the encoding threads count by to get the maximum number of
983            frames to be held in memory at once.
984         */
985         root->add_child("FramesInMemoryMultiplier")->add_child_text(raw_convert<string>(_frames_in_memory_multiplier));
986
987         /* [XML] DecodeReduction power of 2 to reduce DCP images by before decoding in the player. */
988         if (_decode_reduction) {
989                 root->add_child("DecodeReduction")->add_child_text(raw_convert<string>(_decode_reduction.get()));
990         }
991
992         /* [XML] DefaultNotify 1 to default jobs to notify when complete, otherwise 0. */
993         root->add_child("DefaultNotify")->add_child_text(_default_notify ? "1" : "0");
994
995         /* [XML] Notification 1 if a notification type is enabled, otherwise 0. */
996         for (int i = 0; i < NOTIFICATION_COUNT; ++i) {
997                 xmlpp::Element* e = root->add_child ("Notification");
998                 e->set_attribute ("Id", raw_convert<string>(i));
999                 e->add_child_text (_notification[i] ? "1" : "0");
1000         }
1001
1002         if (_barco_username) {
1003                 /* [XML] BarcoUsername Username for logging into Barco's servers when downloading server certificates. */
1004                 root->add_child("BarcoUsername")->add_child_text(*_barco_username);
1005         }
1006         if (_barco_password) {
1007                 /* [XML] BarcoPassword Password for logging into Barco's servers when downloading server certificates. */
1008                 root->add_child("BarcoPassword")->add_child_text(*_barco_password);
1009         }
1010
1011         if (_christie_username) {
1012                 /* [XML] ChristieUsername Username for logging into Christie's servers when downloading server certificates. */
1013                 root->add_child("ChristieUsername")->add_child_text(*_christie_username);
1014         }
1015         if (_christie_password) {
1016                 /* [XML] ChristiePassword Password for logging into Christie's servers when downloading server certificates. */
1017                 root->add_child("ChristiePassword")->add_child_text(*_christie_password);
1018         }
1019
1020         if (_gdc_username) {
1021                 /* [XML] GDCUsername Username for logging into GDC's servers when downloading server certificates. */
1022                 root->add_child("GDCUsername")->add_child_text(*_gdc_username);
1023         }
1024         if (_gdc_password) {
1025                 /* [XML] GDCPassword Password for logging into GDC's servers when downloading server certificates. */
1026                 root->add_child("GDCPassword")->add_child_text(*_gdc_password);
1027         }
1028
1029         /* [XML] PlayerMode <code>window</code> for a single window, <code>full</code> for full-screen and <code>dual</code> for full screen playback
1030            with controls on another monitor.
1031         */
1032         switch (_player_mode) {
1033         case PLAYER_MODE_WINDOW:
1034                 root->add_child("PlayerMode")->add_child_text("window");
1035                 break;
1036         case PLAYER_MODE_FULL:
1037                 root->add_child("PlayerMode")->add_child_text("full");
1038                 break;
1039         case PLAYER_MODE_DUAL:
1040                 root->add_child("PlayerMode")->add_child_text("dual");
1041                 break;
1042         }
1043
1044         /* [XML] ImageDisplay Screen number to put image on in dual-screen player mode. */
1045         root->add_child("ImageDisplay")->add_child_text(raw_convert<string>(_image_display));
1046         switch (_video_view_type) {
1047         case VIDEO_VIEW_SIMPLE:
1048                 root->add_child("VideoViewType")->add_child_text("simple");
1049                 break;
1050         case VIDEO_VIEW_OPENGL:
1051                 root->add_child("VideoViewType")->add_child_text("opengl");
1052                 break;
1053         }
1054         /* [XML] RespectKDMValidityPeriods 1 to refuse to use KDMs that are out of date, 0 to ignore KDM dates. */
1055         root->add_child("RespectKDMValidityPeriods")->add_child_text(_respect_kdm_validity_periods ? "1" : "0");
1056         if (_player_debug_log_file) {
1057                 /* [XML] PlayerLogFile Filename to use for player debug logs. */
1058                 root->add_child("PlayerDebugLogFile")->add_child_text(_player_debug_log_file->string());
1059         }
1060         if (_player_content_directory) {
1061                 /* [XML] PlayerContentDirectory Directory to use for player content in the dual-screen mode. */
1062                 root->add_child("PlayerContentDirectory")->add_child_text(_player_content_directory->string());
1063         }
1064         if (_player_playlist_directory) {
1065                 /* [XML] PlayerPlaylistDirectory Directory to use for player playlists in the dual-screen mode. */
1066                 root->add_child("PlayerPlaylistDirectory")->add_child_text(_player_playlist_directory->string());
1067         }
1068         if (_player_kdm_directory) {
1069                 /* [XML] PlayerKDMDirectory Directory to use for player KDMs in the dual-screen mode. */
1070                 root->add_child("PlayerKDMDirectory")->add_child_text(_player_kdm_directory->string());
1071         }
1072         if (_audio_mapping) {
1073                 _audio_mapping->as_xml (root->add_child("AudioMapping"));
1074         }
1075         for (auto const& i: _custom_languages) {
1076                 root->add_child("CustomLanguage")->add_child_text(i.to_string());
1077         }
1078         for (auto const& initial: _initial_paths) {
1079                 if (initial.second) {
1080                         root->add_child(initial.first)->add_child_text(initial.second->string());
1081                 }
1082         }
1083         root->add_child("UseISDCFNameByDefault")->add_child_text(_use_isdcf_name_by_default ? "1" : "0");
1084         root->add_child("WriteKDMsToDisk")->add_child_text(_write_kdms_to_disk ? "1" : "0");
1085         root->add_child("EmailKDMs")->add_child_text(_email_kdms ? "1" : "0");
1086         root->add_child("DefaultKDMType")->add_child_text(dcp::formulation_to_string(_default_kdm_type));
1087         root->add_child("AutoCropThreshold")->add_child_text(raw_convert<string>(_auto_crop_threshold));
1088         if (_last_release_notes_version) {
1089                 root->add_child("LastReleaseNotesVersion")->add_child_text(*_last_release_notes_version);
1090         }
1091         if (_main_divider_sash_position) {
1092                 root->add_child("MainDividerSashPosition")->add_child_text(raw_convert<string>(*_main_divider_sash_position));
1093         }
1094         if (_main_content_divider_sash_position) {
1095                 root->add_child("MainContentDividerSashPosition")->add_child_text(raw_convert<string>(*_main_content_divider_sash_position));
1096         }
1097
1098         _export.write(root->add_child("Export"));
1099
1100         auto target = config_write_file();
1101
1102         try {
1103                 auto const s = doc.write_to_string_formatted ();
1104                 boost::filesystem::path tmp (string(target.string()).append(".tmp"));
1105                 dcp::File f(tmp, "w");
1106                 if (!f) {
1107                         throw FileError (_("Could not open file for writing"), tmp);
1108                 }
1109                 f.checked_write(s.c_str(), s.bytes());
1110                 f.close();
1111                 boost::filesystem::remove (target);
1112                 boost::filesystem::rename (tmp, target);
1113         } catch (xmlpp::exception& e) {
1114                 string s = e.what ();
1115                 trim (s);
1116                 throw FileError (s, target);
1117         }
1118 }
1119
1120
1121 template <class T>
1122 void
1123 write_file (string root_node, string node, string version, list<shared_ptr<T>> things, boost::filesystem::path file)
1124 {
1125         xmlpp::Document doc;
1126         auto root = doc.create_root_node (root_node);
1127         root->add_child("Version")->add_child_text(version);
1128
1129         for (auto i: things) {
1130                 i->as_xml (root->add_child(node));
1131         }
1132
1133         try {
1134                 doc.write_to_file_formatted (file.string() + ".tmp");
1135                 boost::filesystem::remove (file);
1136                 boost::filesystem::rename (file.string() + ".tmp", file);
1137         } catch (xmlpp::exception& e) {
1138                 string s = e.what ();
1139                 trim (s);
1140                 throw FileError (s, file);
1141         }
1142 }
1143
1144
1145 void
1146 Config::write_cinemas () const
1147 {
1148         write_file ("Cinemas", "Cinema", "1", _cinemas, _cinemas_file);
1149 }
1150
1151
1152 void
1153 Config::write_dkdm_recipients () const
1154 {
1155         write_file ("DKDMRecipients", "DKDMRecipient", "1", _dkdm_recipients, _dkdm_recipients_file);
1156 }
1157
1158
1159 boost::filesystem::path
1160 Config::default_directory_or (boost::filesystem::path a) const
1161 {
1162         return directory_or (_default_directory, a);
1163 }
1164
1165 boost::filesystem::path
1166 Config::default_kdm_directory_or (boost::filesystem::path a) const
1167 {
1168         return directory_or (_default_kdm_directory, a);
1169 }
1170
1171 boost::filesystem::path
1172 Config::directory_or (optional<boost::filesystem::path> dir, boost::filesystem::path a) const
1173 {
1174         if (!dir) {
1175                 return a;
1176         }
1177
1178         boost::system::error_code ec;
1179         auto const e = boost::filesystem::exists (*dir, ec);
1180         if (ec || !e) {
1181                 return a;
1182         }
1183
1184         return *dir;
1185 }
1186
1187 void
1188 Config::drop ()
1189 {
1190         delete _instance;
1191         _instance = 0;
1192 }
1193
1194 void
1195 Config::changed (Property what)
1196 {
1197         Changed (what);
1198 }
1199
1200 void
1201 Config::set_kdm_email_to_default ()
1202 {
1203         _kdm_subject = _("KDM delivery: $CPL_NAME");
1204
1205         _kdm_email = _(
1206                 "Dear Projectionist\n\n"
1207                 "Please find attached KDMs for $CPL_NAME.\n\n"
1208                 "Cinema: $CINEMA_NAME\n"
1209                 "Screen(s): $SCREENS\n\n"
1210                 "The KDMs are valid from $START_TIME until $END_TIME.\n\n"
1211                 "Best regards,\nDCP-o-matic"
1212                 );
1213 }
1214
1215 void
1216 Config::set_notification_email_to_default ()
1217 {
1218         _notification_subject = _("DCP-o-matic notification");
1219
1220         _notification_email = _(
1221                 "$JOB_NAME: $JOB_STATUS"
1222                 );
1223 }
1224
1225 void
1226 Config::reset_kdm_email ()
1227 {
1228         set_kdm_email_to_default ();
1229         changed ();
1230 }
1231
1232 void
1233 Config::reset_notification_email ()
1234 {
1235         set_notification_email_to_default ();
1236         changed ();
1237 }
1238
1239 void
1240 Config::set_cover_sheet_to_default ()
1241 {
1242         _cover_sheet = _(
1243                 "$CPL_NAME\n\n"
1244                 "CPL Filename: $CPL_FILENAME\n"
1245                 "Type: $TYPE\n"
1246                 "Format: $CONTAINER\n"
1247                 "Audio: $AUDIO\n"
1248                 "Audio Language: $AUDIO_LANGUAGE\n"
1249                 "Subtitle Language: $SUBTITLE_LANGUAGE\n"
1250                 "Length: $LENGTH\n"
1251                 "Size: $SIZE\n"
1252                 );
1253 }
1254
1255 void
1256 Config::add_to_history (boost::filesystem::path p)
1257 {
1258         add_to_history_internal (_history, p);
1259 }
1260
1261 /** Remove non-existent items from the history */
1262 void
1263 Config::clean_history ()
1264 {
1265         clean_history_internal (_history);
1266 }
1267
1268 void
1269 Config::add_to_player_history (boost::filesystem::path p)
1270 {
1271         add_to_history_internal (_player_history, p);
1272 }
1273
1274 /** Remove non-existant items from the player history */
1275 void
1276 Config::clean_player_history ()
1277 {
1278         clean_history_internal (_player_history);
1279 }
1280
1281 void
1282 Config::add_to_history_internal (vector<boost::filesystem::path>& h, boost::filesystem::path p)
1283 {
1284         /* Remove existing instances of this path in the history */
1285         h.erase (remove (h.begin(), h.end(), p), h.end ());
1286
1287         h.insert (h.begin (), p);
1288         if (h.size() > HISTORY_SIZE) {
1289                 h.pop_back ();
1290         }
1291
1292         changed (HISTORY);
1293 }
1294
1295 void
1296 Config::clean_history_internal (vector<boost::filesystem::path>& h)
1297 {
1298         auto old = h;
1299         h.clear ();
1300         for (auto i: old) {
1301                 try {
1302                         if (boost::filesystem::is_directory(i)) {
1303                                 h.push_back (i);
1304                         }
1305                 } catch (...) {
1306                         /* We couldn't find out if it's a directory for some reason; just ignore it */
1307                 }
1308         }
1309 }
1310
1311
1312 bool
1313 Config::have_existing (string file)
1314 {
1315         return boost::filesystem::exists (read_path(file));
1316 }
1317
1318
1319 void
1320 Config::read_cinemas (cxml::Document const & f)
1321 {
1322         _cinemas.clear ();
1323         for (auto i: f.node_children("Cinema")) {
1324                 /* Slightly grotty two-part construction of Cinema here so that we can use
1325                    shared_from_this.
1326                 */
1327                 auto cinema = make_shared<Cinema>(i);
1328                 cinema->read_screens (i);
1329                 _cinemas.push_back (cinema);
1330         }
1331 }
1332
1333 void
1334 Config::set_cinemas_file (boost::filesystem::path file)
1335 {
1336         if (file == _cinemas_file) {
1337                 return;
1338         }
1339
1340         _cinemas_file = file;
1341
1342         if (boost::filesystem::exists (_cinemas_file)) {
1343                 /* Existing file; read it in */
1344                 cxml::Document f ("Cinemas");
1345                 f.read_file (_cinemas_file);
1346                 read_cinemas (f);
1347         }
1348
1349         changed (CINEMAS);
1350         changed (OTHER);
1351 }
1352
1353
1354 void
1355 Config::read_dkdm_recipients (cxml::Document const & f)
1356 {
1357         _dkdm_recipients.clear ();
1358         for (auto i: f.node_children("DKDMRecipient")) {
1359                 _dkdm_recipients.push_back (make_shared<DKDMRecipient>(i));
1360         }
1361 }
1362
1363
1364 void
1365 Config::save_template (shared_ptr<const Film> film, string name) const
1366 {
1367         film->write_template (template_write_path(name));
1368 }
1369
1370
1371 list<string>
1372 Config::templates () const
1373 {
1374         if (!boost::filesystem::exists(read_path("templates"))) {
1375                 return {};
1376         }
1377
1378         list<string> n;
1379         for (auto const& i: boost::filesystem::directory_iterator(read_path("templates"))) {
1380                 n.push_back (i.path().filename().string());
1381         }
1382         return n;
1383 }
1384
1385 bool
1386 Config::existing_template (string name) const
1387 {
1388         return boost::filesystem::exists (template_read_path(name));
1389 }
1390
1391
1392 boost::filesystem::path
1393 Config::template_read_path (string name) const
1394 {
1395         return read_path("templates") / tidy_for_filename (name);
1396 }
1397
1398
1399 boost::filesystem::path
1400 Config::template_write_path (string name) const
1401 {
1402         return write_path("templates") / tidy_for_filename (name);
1403 }
1404
1405
1406 void
1407 Config::rename_template (string old_name, string new_name) const
1408 {
1409         boost::filesystem::rename (template_read_path(old_name), template_write_path(new_name));
1410 }
1411
1412 void
1413 Config::delete_template (string name) const
1414 {
1415         boost::filesystem::remove (template_write_path(name));
1416 }
1417
1418 /** @return Path to the config.xml containing the actual settings, following a link if required */
1419 boost::filesystem::path
1420 config_file (boost::filesystem::path main)
1421 {
1422         cxml::Document f ("Config");
1423         if (!boost::filesystem::exists (main)) {
1424                 /* It doesn't exist, so there can't be any links; just return it */
1425                 return main;
1426         }
1427
1428         /* See if there's a link */
1429         try {
1430                 f.read_file (main);
1431                 auto link = f.optional_string_child("Link");
1432                 if (link) {
1433                         return *link;
1434                 }
1435         } catch (xmlpp::exception& e) {
1436                 /* There as a problem reading the main configuration file,
1437                    so there can't be a link.
1438                 */
1439         }
1440
1441         return main;
1442 }
1443
1444
1445 boost::filesystem::path
1446 Config::config_read_file ()
1447 {
1448         return config_file (read_path("config.xml"));
1449 }
1450
1451
1452 boost::filesystem::path
1453 Config::config_write_file ()
1454 {
1455         return config_file (write_path("config.xml"));
1456 }
1457
1458
1459 void
1460 Config::reset_cover_sheet ()
1461 {
1462         set_cover_sheet_to_default ();
1463         changed ();
1464 }
1465
1466 void
1467 Config::link (boost::filesystem::path new_file) const
1468 {
1469         xmlpp::Document doc;
1470         doc.create_root_node("Config")->add_child("Link")->add_child_text(new_file.string());
1471         try {
1472                 doc.write_to_file_formatted(write_path("config.xml").string());
1473         } catch (xmlpp::exception& e) {
1474                 string s = e.what ();
1475                 trim (s);
1476                 throw FileError (s, write_path("config.xml"));
1477         }
1478 }
1479
1480 void
1481 Config::copy_and_link (boost::filesystem::path new_file) const
1482 {
1483         write ();
1484         boost::filesystem::copy_file (config_read_file(), new_file, boost::filesystem::copy_option::overwrite_if_exists);
1485         link (new_file);
1486 }
1487
1488 bool
1489 Config::have_write_permission () const
1490 {
1491         dcp::File f(config_write_file(), "r+");
1492         return static_cast<bool>(f);
1493 }
1494
1495 /** @param  output_channels Number of output channels in use.
1496  *  @return Audio mapping for this output channel count (may be a default).
1497  */
1498 AudioMapping
1499 Config::audio_mapping (int output_channels)
1500 {
1501         if (!_audio_mapping || _audio_mapping->output_channels() != output_channels) {
1502                 /* Set up a default */
1503                 _audio_mapping = AudioMapping (MAX_DCP_AUDIO_CHANNELS, output_channels);
1504                 if (output_channels == 2) {
1505                         /* Special case for stereo output.
1506                            Map so that Lt = L(-3dB) + Ls(-3dB) + C(-6dB) + Lfe(-10dB)
1507                            Rt = R(-3dB) + Rs(-3dB) + C(-6dB) + Lfe(-10dB)
1508                         */
1509                         _audio_mapping->set (dcp::Channel::LEFT,   0, 1 / sqrt(2));  // L   -> Lt
1510                         _audio_mapping->set (dcp::Channel::RIGHT,  1, 1 / sqrt(2));  // R   -> Rt
1511                         _audio_mapping->set (dcp::Channel::CENTRE, 0, 1 / 2.0);      // C   -> Lt
1512                         _audio_mapping->set (dcp::Channel::CENTRE, 1, 1 / 2.0);      // C   -> Rt
1513                         _audio_mapping->set (dcp::Channel::LFE,    0, 1 / sqrt(10)); // Lfe -> Lt
1514                         _audio_mapping->set (dcp::Channel::LFE,    1, 1 / sqrt(10)); // Lfe -> Rt
1515                         _audio_mapping->set (dcp::Channel::LS,     0, 1 / sqrt(2));  // Ls  -> Lt
1516                         _audio_mapping->set (dcp::Channel::RS,     1, 1 / sqrt(2));  // Rs  -> Rt
1517                 } else {
1518                         /* 1:1 mapping */
1519                         for (int i = 0; i < min (MAX_DCP_AUDIO_CHANNELS, output_channels); ++i) {
1520                                 _audio_mapping->set (i, i, 1);
1521                         }
1522                 }
1523         }
1524
1525         return *_audio_mapping;
1526 }
1527
1528 void
1529 Config::set_audio_mapping (AudioMapping m)
1530 {
1531         _audio_mapping = m;
1532         changed (AUDIO_MAPPING);
1533 }
1534
1535 void
1536 Config::set_audio_mapping_to_default ()
1537 {
1538         DCPOMATIC_ASSERT (_audio_mapping);
1539         auto const ch = _audio_mapping->output_channels ();
1540         _audio_mapping = boost::none;
1541         _audio_mapping = audio_mapping (ch);
1542         changed (AUDIO_MAPPING);
1543 }
1544
1545
1546 void
1547 Config::add_custom_language (dcp::LanguageTag tag)
1548 {
1549         if (find(_custom_languages.begin(), _custom_languages.end(), tag) == _custom_languages.end()) {
1550                 _custom_languages.push_back (tag);
1551                 changed ();
1552         }
1553 }
1554
1555
1556 optional<Config::BadReason>
1557 Config::check_certificates () const
1558 {
1559         optional<BadReason> bad;
1560
1561         for (auto const& i: _signer_chain->unordered()) {
1562                 if (i.has_utf8_strings()) {
1563                         bad = BAD_SIGNER_UTF8_STRINGS;
1564                 }
1565                 if ((i.not_after().year() - i.not_before().year()) > 15) {
1566                         bad = BAD_SIGNER_VALIDITY_TOO_LONG;
1567                 }
1568         }
1569
1570         if (!_signer_chain->chain_valid() || !_signer_chain->private_key_valid()) {
1571                 bad = BAD_SIGNER_INCONSISTENT;
1572         }
1573
1574         if (!_decryption_chain->chain_valid() || !_decryption_chain->private_key_valid()) {
1575                 bad = BAD_DECRYPTION_INCONSISTENT;
1576         }
1577
1578         return bad;
1579 }
1580
1581
1582 void
1583 save_all_config_as_zip (boost::filesystem::path zip_file)
1584 {
1585         Zipper zipper (zip_file);
1586
1587         auto config = Config::instance();
1588         zipper.add ("config.xml", dcp::file_to_string(config->config_read_file()));
1589         if (boost::filesystem::exists(config->cinemas_file())) {
1590                 zipper.add ("cinemas.xml", dcp::file_to_string(config->cinemas_file()));
1591         }
1592         if (boost::filesystem::exists(config->dkdm_recipients_file())) {
1593                 zipper.add ("dkdm_recipients.xml", dcp::file_to_string(config->dkdm_recipients_file()));
1594         }
1595
1596         zipper.close ();
1597 }
1598
1599
1600 void
1601 Config::set_initial_path(string id, boost::filesystem::path path)
1602 {
1603         auto iter = _initial_paths.find(id);
1604         DCPOMATIC_ASSERT(iter != _initial_paths.end());
1605         iter->second = path;
1606         changed();
1607 }
1608
1609
1610 optional<boost::filesystem::path>
1611 Config::initial_path(string id) const
1612 {
1613         auto iter = _initial_paths.find(id);
1614         DCPOMATIC_ASSERT(iter != _initial_paths.end());
1615         return iter->second;
1616 }
1617