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