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