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