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