Merge branch 'main' into v2.17.x
[dcpomatic.git] / src / lib / config.h
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 /** @file src/config.h
22  *  @brief Class holding configuration.
23  */
24
25
26 #ifndef DCPOMATIC_CONFIG_H
27 #define DCPOMATIC_CONFIG_H
28
29
30 #include "audio_mapping.h"
31 #include "export_config.h"
32 #include "rough_duration.h"
33 #include "state.h"
34 #include <dcp/name_format.h>
35 #include <dcp/certificate_chain.h>
36 #include <dcp/encrypted_kdm.h>
37 #include <dcp/language_tag.h>
38 #include <boost/signals2.hpp>
39 #include <boost/filesystem.hpp>
40 #include <vector>
41
42
43 class Cinema;
44 class CinemaSoundProcessor;
45 class DCPContentType;
46 class DKDMGroup;
47 class DKDMRecipient;
48 class Film;
49 class Ratio;
50
51
52 extern void save_all_config_as_zip (boost::filesystem::path zip_file);
53
54
55 /** @class Config
56  *  @brief A singleton class holding configuration.
57  */
58 class Config : public State
59 {
60 public:
61         /** @return number of threads which a master DoM should use for J2K encoding on the local machine */
62         int master_encoding_threads () const {
63                 return _master_encoding_threads;
64         }
65
66         /** @return number of threads which a server should use for J2K encoding on the local machine */
67         int server_encoding_threads () const {
68                 return _server_encoding_threads;
69         }
70
71         boost::optional<boost::filesystem::path> default_directory () const {
72                 return _default_directory;
73         }
74
75         boost::optional<boost::filesystem::path> default_kdm_directory () const {
76                 return _default_kdm_directory;
77         }
78
79         boost::filesystem::path default_directory_or (boost::filesystem::path a) const;
80         boost::filesystem::path default_kdm_directory_or (boost::filesystem::path a) const;
81
82         enum Property {
83                 USE_ANY_SERVERS,
84                 SERVERS,
85                 CINEMAS,
86                 DKDM_RECIPIENTS,
87                 SOUND,
88                 SOUND_OUTPUT,
89                 PLAYER_CONTENT_DIRECTORY,
90                 PLAYER_PLAYLIST_DIRECTORY,
91                 PLAYER_DEBUG_LOG,
92                 HISTORY,
93                 SHOW_EXPERIMENTAL_AUDIO_PROCESSORS,
94                 AUDIO_MAPPING,
95                 AUTO_CROP_THRESHOLD,
96                 ALLOW_SMPTE_BV20,
97                 ISDCF_NAME_PART_LENGTH,
98 #ifdef DCPOMATIC_GROK
99                 GROK,
100 #endif
101                 OTHER
102         };
103
104         /** @return base port number to use for J2K encoding servers */
105         int server_port_base () const {
106                 return _server_port_base;
107         }
108
109         void set_use_any_servers (bool u) {
110                 _use_any_servers = u;
111                 changed (USE_ANY_SERVERS);
112         }
113
114         bool use_any_servers () const {
115                 return _use_any_servers;
116         }
117
118         /** @param s New list of servers */
119         void set_servers (std::vector<std::string> s) {
120                 _servers = s;
121                 changed (SERVERS);
122         }
123
124         /** @return Host names / IP addresses of J2K encoding servers that should definitely be used */
125         std::vector<std::string> servers () const {
126                 return _servers;
127         }
128
129         bool only_servers_encode () const {
130                 return _only_servers_encode;
131         }
132
133         FileTransferProtocol tms_protocol () const {
134                 return _tms_protocol;
135         }
136
137         bool tms_passive() const {
138                 return _tms_passive;
139         }
140
141         /** @return The IP address of a TMS that we can copy DCPs to */
142         std::string tms_ip () const {
143                 return _tms_ip;
144         }
145
146         /** @return The path on a TMS that we should changed DCPs to */
147         std::string tms_path () const {
148                 return _tms_path;
149         }
150
151         /** @return User name to log into the TMS with */
152         std::string tms_user () const {
153                 return _tms_user;
154         }
155
156         /** @return Password to log into the TMS with */
157         std::string tms_password () const {
158                 return _tms_password;
159         }
160
161         std::list<std::shared_ptr<Cinema>> cinemas () const {
162                 return _cinemas;
163         }
164
165         std::list<std::shared_ptr<DKDMRecipient>> dkdm_recipients () const {
166                 return _dkdm_recipients;
167         }
168
169         std::list<int> allowed_dcp_frame_rates () const {
170                 return _allowed_dcp_frame_rates;
171         }
172
173         bool allow_any_dcp_frame_rate () const {
174                 return _allow_any_dcp_frame_rate;
175         }
176
177         bool allow_any_container () const {
178                 return _allow_any_container;
179         }
180
181         bool allow_96khz_audio () const {
182                 return _allow_96khz_audio;
183         }
184
185         bool use_all_audio_channels () const {
186                 return _use_all_audio_channels;
187         }
188
189         bool show_experimental_audio_processors () const {
190                 return _show_experimental_audio_processors;
191         }
192
193         boost::optional<std::string> language () const {
194                 return _language;
195         }
196
197         int default_still_length () const {
198                 return _default_still_length;
199         }
200
201         DCPContentType const * default_dcp_content_type () const {
202                 return _default_dcp_content_type;
203         }
204
205         int default_dcp_audio_channels () const {
206                 return _default_dcp_audio_channels;
207         }
208
209         std::string dcp_issuer () const {
210                 return _dcp_issuer;
211         }
212
213         std::string dcp_creator () const {
214                 return _dcp_creator;
215         }
216
217         std::string dcp_company_name () const {
218                 return _dcp_company_name;
219         }
220
221         std::string dcp_product_name () const {
222                 return _dcp_product_name;
223         }
224
225         std::string dcp_product_version () const {
226                 return _dcp_product_version;
227         }
228
229         std::string dcp_j2k_comment () const {
230                 return _dcp_j2k_comment;
231         }
232
233         int default_j2k_bandwidth () const {
234                 return _default_j2k_bandwidth;
235         }
236
237         int default_audio_delay () const {
238                 return _default_audio_delay;
239         }
240
241         bool default_interop () const {
242                 return _default_interop;
243         }
244
245         boost::optional<dcp::LanguageTag> default_audio_language() const {
246                 return _default_audio_language;
247         }
248
249         boost::optional<dcp::LanguageTag::RegionSubtag> default_territory() const {
250                 return _default_territory;
251         }
252
253         std::map<std::string, std::string> default_metadata () const {
254                 return _default_metadata;
255         }
256
257         bool upload_after_make_dcp () {
258                 return _upload_after_make_dcp;
259         }
260
261         void set_default_kdm_directory (boost::filesystem::path d) {
262                 if (_default_kdm_directory && _default_kdm_directory.get() == d) {
263                         return;
264                 }
265                 _default_kdm_directory = d;
266                 changed ();
267         }
268
269         std::string mail_server () const {
270                 return _mail_server;
271         }
272
273         int mail_port () const {
274                 return _mail_port;
275         }
276
277         EmailProtocol mail_protocol () const {
278                 return _mail_protocol;
279         }
280
281         std::string mail_user () const {
282                 return _mail_user;
283         }
284
285         std::string mail_password () const {
286                 return _mail_password;
287         }
288
289         std::string kdm_subject () const {
290                 return _kdm_subject;
291         }
292
293         std::string kdm_from () const {
294                 return _kdm_from;
295         }
296
297         std::vector<std::string> kdm_cc () const {
298                 return _kdm_cc;
299         }
300
301         std::string kdm_bcc () const {
302                 return _kdm_bcc;
303         }
304
305         std::string kdm_email () const {
306                 return _kdm_email;
307         }
308
309         std::string notification_subject () const {
310                 return _notification_subject;
311         }
312
313         std::string notification_from () const {
314                 return _notification_from;
315         }
316
317         std::string notification_to () const {
318                 return _notification_to;
319         }
320
321         std::vector<std::string> notification_cc () const {
322                 return _notification_cc;
323         }
324
325         std::string notification_bcc () const {
326                 return _notification_bcc;
327         }
328
329         std::string notification_email () const {
330                 return _notification_email;
331         }
332
333         std::shared_ptr<const dcp::CertificateChain> signer_chain () const {
334                 return _signer_chain;
335         }
336
337         std::shared_ptr<const dcp::CertificateChain> decryption_chain () const {
338                 return _decryption_chain;
339         }
340
341         bool check_for_updates () const {
342                 return _check_for_updates;
343         }
344
345         bool check_for_test_updates () const {
346                 return _check_for_test_updates;
347         }
348
349         int maximum_j2k_bandwidth () const {
350                 return _maximum_j2k_bandwidth;
351         }
352
353         int log_types () const {
354                 return _log_types;
355         }
356
357         bool analyse_ebur128 () const {
358                 return _analyse_ebur128;
359         }
360
361         bool automatic_audio_analysis () const {
362                 return _automatic_audio_analysis;
363         }
364
365 #ifdef DCPOMATIC_WINDOWS
366         bool win32_console () const {
367                 return _win32_console;
368         }
369 #endif
370
371         std::vector<boost::filesystem::path> history () const {
372                 return _history;
373         }
374
375         std::vector<boost::filesystem::path> player_history () const {
376                 return _player_history;
377         }
378
379         std::shared_ptr<DKDMGroup> dkdms () const {
380                 return _dkdms;
381         }
382
383         boost::filesystem::path cinemas_file () const {
384                 return _cinemas_file;
385         }
386
387         boost::filesystem::path dkdm_recipients_file () const {
388                 return _dkdm_recipients_file;
389         }
390
391         bool show_hints_before_make_dcp () const {
392                 return _show_hints_before_make_dcp;
393         }
394
395         bool confirm_kdm_email () const {
396                 return _confirm_kdm_email;
397         }
398
399         dcp::NameFormat kdm_container_name_format () const {
400                 return _kdm_container_name_format;
401         }
402
403         dcp::NameFormat kdm_filename_format () const {
404                 return _kdm_filename_format;
405         }
406
407         dcp::NameFormat dkdm_filename_format () const {
408                 return _dkdm_filename_format;
409         }
410
411         dcp::NameFormat dcp_metadata_filename_format () const {
412                 return _dcp_metadata_filename_format;
413         }
414
415         dcp::NameFormat dcp_asset_filename_format () const {
416                 return _dcp_asset_filename_format;
417         }
418
419         bool jump_to_selected () const {
420                 return _jump_to_selected;
421         }
422
423         /* This could be an enum class but we use the enum a lot to index _nagged
424          * so it means a lot of casts.
425          */
426         enum Nag {
427                 NAG_DKDM_CONFIG,
428                 NAG_ENCRYPTED_METADATA,
429                 NAG_ALTER_DECRYPTION_CHAIN,
430                 NAG_BAD_SIGNER_CHAIN_UTF8,
431                 NAG_IMPORT_DECRYPTION_CHAIN,
432                 NAG_DELETE_DKDM,
433                 NAG_32_ON_64,
434                 NAG_TOO_MANY_DROPPED_FRAMES,
435                 NAG_BAD_SIGNER_CHAIN_VALIDITY,
436                 NAG_BAD_SIGNER_DN_QUALIFIER,
437                 NAG_COUNT
438         };
439
440         bool nagged (Nag nag) const {
441                 return _nagged[nag];
442         }
443
444         bool sound () const {
445                 return _sound;
446         }
447
448         std::string cover_sheet () const {
449                 return _cover_sheet;
450         }
451
452         boost::optional<std::string> sound_output () const {
453                 return _sound_output;
454         }
455
456         boost::optional<boost::filesystem::path> last_player_load_directory () const {
457                 return _last_player_load_directory;
458         }
459
460         enum KDMWriteType {
461                 KDM_WRITE_FLAT,
462                 KDM_WRITE_FOLDER,
463                 KDM_WRITE_ZIP
464         };
465
466         boost::optional<KDMWriteType> last_kdm_write_type () const {
467                 return _last_kdm_write_type;
468         }
469
470         enum DKDMWriteType {
471                 DKDM_WRITE_INTERNAL,
472                 DKDM_WRITE_FILE
473         };
474
475         boost::optional<DKDMWriteType> last_dkdm_write_type () const {
476                 return _last_dkdm_write_type;
477         }
478
479         int frames_in_memory_multiplier () const {
480                 return _frames_in_memory_multiplier;
481         }
482
483         boost::optional<int> decode_reduction () const {
484                 return _decode_reduction;
485         }
486
487         bool default_notify () const {
488                 return _default_notify;
489         }
490
491         enum Notification {
492                 MESSAGE_BOX,
493                 EMAIL,
494                 NOTIFICATION_COUNT
495         };
496
497         bool notification (Notification n) const {
498                 return _notification[n];
499         }
500
501         boost::optional<std::string> barco_username () const {
502                 return _barco_username;
503         }
504
505         boost::optional<std::string> barco_password () const {
506                 return _barco_password;
507         }
508
509         boost::optional<std::string> christie_username () const {
510                 return _christie_username;
511         }
512
513         boost::optional<std::string> christie_password () const {
514                 return _christie_password;
515         }
516
517         boost::optional<std::string> gdc_username () const {
518                 return _gdc_username;
519         }
520
521         boost::optional<std::string> gdc_password () const {
522                 return _gdc_password;
523         }
524
525         enum PlayerMode {
526                 PLAYER_MODE_WINDOW, ///< one window containing image and controls
527                 PLAYER_MODE_FULL,   ///< just the image filling the screen
528                 PLAYER_MODE_DUAL    ///< image on one monitor and extended controls on the other
529         };
530
531         PlayerMode player_mode () const {
532                 return _player_mode;
533         }
534
535         int image_display () const {
536                 return _image_display;
537         }
538
539         enum VideoViewType {
540                 VIDEO_VIEW_SIMPLE,
541                 VIDEO_VIEW_OPENGL
542         };
543
544         VideoViewType video_view_type () const {
545                 return _video_view_type;
546         }
547
548         bool respect_kdm_validity_periods () const {
549                 return _respect_kdm_validity_periods;
550         }
551
552         boost::optional<boost::filesystem::path> player_debug_log_file () const {
553                 return _player_debug_log_file;
554         }
555
556         boost::optional<boost::filesystem::path> player_content_directory () const {
557                 return _player_content_directory;
558         }
559
560         boost::optional<boost::filesystem::path> player_playlist_directory () const {
561                 return _player_playlist_directory;
562         }
563
564         boost::optional<boost::filesystem::path> player_kdm_directory () const {
565                 return _player_kdm_directory;
566         }
567
568         AudioMapping audio_mapping (int output_channels);
569
570         std::vector<dcp::LanguageTag> custom_languages () const {
571                 return _custom_languages;
572         }
573
574         boost::optional<boost::filesystem::path> initial_path(std::string id) const;
575
576         bool use_isdcf_name_by_default () const {
577                 return _use_isdcf_name_by_default;
578         }
579
580         bool write_kdms_to_disk () const {
581                 return _write_kdms_to_disk;
582         }
583
584         bool email_kdms () const {
585                 return _email_kdms;
586         }
587
588         dcp::Formulation default_kdm_type () const {
589                 return _default_kdm_type;
590         }
591
592         RoughDuration default_kdm_duration () const {
593                 return _default_kdm_duration;
594         }
595
596         double auto_crop_threshold () const {
597                 return _auto_crop_threshold;
598         }
599
600         boost::optional<std::string> last_release_notes_version () const {
601                 return _last_release_notes_version;
602         }
603
604         boost::optional<int> main_divider_sash_position() const {
605                 return _main_divider_sash_position;
606         }
607
608         boost::optional<int> main_content_divider_sash_position() const {
609                 return _main_content_divider_sash_position;
610         }
611
612         enum class DefaultAddFileLocation {
613                 SAME_AS_LAST_TIME,
614                 SAME_AS_PROJECT
615         };
616
617         DefaultAddFileLocation default_add_file_location() const {
618                 return _default_add_file_location;
619         }
620
621         bool allow_smpte_bv20() const {
622                 return _allow_smpte_bv20;
623         }
624
625 #ifdef DCPOMATIC_GROK
626         class Grok
627         {
628         public:
629                 Grok() = default;
630                 Grok(cxml::ConstNodePtr node);
631
632                 void as_xml(xmlpp::Element* node) const;
633
634                 bool enable = false;
635                 boost::filesystem::path binary_location;
636                 int selected = 0;
637                 std::string licence_server;
638                 int licence_port = 5000;
639                 std::string licence;
640         };
641
642         boost::optional<Grok> grok() const {
643                 return _grok;
644         }
645 #endif
646
647         int isdcf_name_part_length() const {
648                 return _isdcf_name_part_length;
649         }
650
651         /* SET (mostly) */
652
653         void set_master_encoding_threads (int n) {
654                 maybe_set (_master_encoding_threads, n);
655         }
656
657         void set_server_encoding_threads (int n) {
658                 maybe_set (_server_encoding_threads, n);
659         }
660
661         void set_default_directory (boost::filesystem::path d) {
662                 if (_default_directory && *_default_directory == d) {
663                         return;
664                 }
665                 _default_directory = d;
666                 changed ();
667         }
668
669         /** @param p New server port */
670         void set_server_port_base (int p) {
671                 maybe_set (_server_port_base, p);
672         }
673
674         void set_only_servers_encode (bool o) {
675                 maybe_set (_only_servers_encode, o);
676         }
677
678         void set_tms_protocol (FileTransferProtocol p) {
679                 maybe_set (_tms_protocol, p);
680         }
681
682         void set_tms_passive(bool passive) {
683                 maybe_set(_tms_passive, passive);
684         }
685
686         /** @param i IP address of a TMS that we can copy DCPs to */
687         void set_tms_ip (std::string i) {
688                 maybe_set (_tms_ip, i);
689         }
690
691         /** @param p Path on a TMS that we should changed DCPs to */
692         void set_tms_path (std::string p) {
693                 maybe_set (_tms_path, p);
694         }
695
696         /** @param u User name to log into the TMS with */
697         void set_tms_user (std::string u) {
698                 maybe_set (_tms_user, u);
699         }
700
701         /** @param p Password to log into the TMS with */
702         void set_tms_password (std::string p) {
703                 maybe_set (_tms_password, p);
704         }
705
706         void add_cinema (std::shared_ptr<Cinema> c) {
707                 _cinemas.push_back (c);
708                 changed (CINEMAS);
709         }
710
711         void remove_cinema (std::shared_ptr<Cinema> c) {
712                 _cinemas.remove (c);
713                 changed (CINEMAS);
714         }
715
716         void add_dkdm_recipient (std::shared_ptr<DKDMRecipient> c) {
717                 _dkdm_recipients.push_back (c);
718                 changed (DKDM_RECIPIENTS);
719         }
720
721         void remove_dkdm_recipient (std::shared_ptr<DKDMRecipient> c) {
722                 _dkdm_recipients.remove (c);
723                 changed (DKDM_RECIPIENTS);
724         }
725
726         void set_allowed_dcp_frame_rates (std::list<int> const & r) {
727                 maybe_set (_allowed_dcp_frame_rates, r);
728         }
729
730         void set_allow_any_dcp_frame_rate (bool a) {
731                 maybe_set (_allow_any_dcp_frame_rate, a);
732         }
733
734         void set_allow_any_container (bool a) {
735                 maybe_set (_allow_any_container, a);
736         }
737
738         void set_allow_96hhz_audio (bool a) {
739                 maybe_set (_allow_96khz_audio, a);
740         }
741
742         void set_use_all_audio_channels (bool a) {
743                 maybe_set (_use_all_audio_channels, a);
744         }
745
746         void set_show_experimental_audio_processors (bool e) {
747                 maybe_set (_show_experimental_audio_processors, e, SHOW_EXPERIMENTAL_AUDIO_PROCESSORS);
748         }
749
750         void set_language (std::string l) {
751                 if (_language && _language.get() == l) {
752                         return;
753                 }
754                 _language = l;
755                 changed ();
756         }
757
758         void unset_language () {
759                 if (!_language) {
760                         return;
761                 }
762
763                 _language = boost::none;
764                 changed ();
765         }
766
767         void set_default_still_length (int s) {
768                 maybe_set (_default_still_length, s);
769         }
770
771         void set_default_dcp_content_type (DCPContentType const * t) {
772                 maybe_set (_default_dcp_content_type, t);
773         }
774
775         void set_default_dcp_audio_channels (int c) {
776                 maybe_set (_default_dcp_audio_channels, c);
777         }
778
779         void set_dcp_issuer (std::string i) {
780                 maybe_set (_dcp_issuer, i);
781         }
782
783         void set_dcp_creator (std::string c) {
784                 maybe_set (_dcp_creator, c);
785         }
786
787         void set_dcp_company_name (std::string c) {
788                 maybe_set (_dcp_company_name, c);
789         }
790
791         void set_dcp_product_name (std::string c) {
792                 maybe_set (_dcp_product_name, c);
793         }
794
795         void set_dcp_product_version (std::string c) {
796                 maybe_set (_dcp_product_version, c);
797         }
798
799         void set_dcp_j2k_comment (std::string c) {
800                 maybe_set (_dcp_j2k_comment, c);
801         }
802
803         void set_default_j2k_bandwidth (int b) {
804                 maybe_set (_default_j2k_bandwidth, b);
805         }
806
807         void set_default_audio_delay (int d) {
808                 maybe_set (_default_audio_delay, d);
809         }
810
811         void set_default_interop (bool i) {
812                 maybe_set (_default_interop, i);
813         }
814
815         void set_default_audio_language(dcp::LanguageTag tag) {
816                 maybe_set(_default_audio_language, tag);
817         }
818
819         void unset_default_audio_language() {
820                 maybe_set(_default_audio_language, boost::optional<dcp::LanguageTag>());
821         }
822
823         void set_default_territory(dcp::LanguageTag::RegionSubtag tag) {
824                 maybe_set(_default_territory, tag);
825         }
826
827         void unset_default_territory() {
828                 maybe_set(_default_territory, boost::optional<dcp::LanguageTag::RegionSubtag>());
829         }
830
831         void set_default_metadata (std::map<std::string, std::string> const& metadata) {
832                 maybe_set (_default_metadata, metadata);
833         }
834
835         void set_upload_after_make_dcp (bool u) {
836                 maybe_set (_upload_after_make_dcp, u);
837         }
838
839         void set_mail_server (std::string s) {
840                 maybe_set (_mail_server, s);
841         }
842
843         void set_mail_port (int p) {
844                 maybe_set (_mail_port, p);
845         }
846
847         void set_mail_protocol (EmailProtocol p) {
848                 maybe_set (_mail_protocol, p);
849         }
850
851         void set_mail_user (std::string u) {
852                 maybe_set (_mail_user, u);
853         }
854
855         void set_mail_password (std::string p) {
856                 maybe_set (_mail_password, p);
857         }
858
859         void set_kdm_subject (std::string s) {
860                 maybe_set (_kdm_subject, s);
861         }
862
863         void set_kdm_from (std::string f) {
864                 maybe_set (_kdm_from, f);
865         }
866
867         void set_kdm_cc (std::vector<std::string> f) {
868                 maybe_set (_kdm_cc, f);
869         }
870
871         void set_kdm_bcc (std::string f) {
872                 maybe_set (_kdm_bcc, f);
873         }
874
875         void set_kdm_email (std::string e) {
876                 maybe_set (_kdm_email, e);
877         }
878
879         void reset_kdm_email ();
880
881         void set_notification_subject (std::string s) {
882                 maybe_set (_notification_subject, s);
883         }
884
885         void set_notification_from (std::string f) {
886                 maybe_set (_notification_from, f);
887         }
888
889         void set_notification_to (std::string t) {
890                 maybe_set (_notification_to, t);
891         }
892
893         void set_notification_cc (std::vector<std::string> f) {
894                 maybe_set (_notification_cc, f);
895         }
896
897         void set_notification_bcc (std::string f) {
898                 maybe_set (_notification_bcc, f);
899         }
900
901         void set_notification_email (std::string e) {
902                 maybe_set (_notification_email, e);
903         }
904
905         void reset_notification_email ();
906
907         void set_signer_chain (std::shared_ptr<const dcp::CertificateChain> s) {
908                 maybe_set (_signer_chain, s);
909         }
910
911         void set_decryption_chain (std::shared_ptr<const dcp::CertificateChain> c) {
912                 maybe_set (_decryption_chain, c);
913         }
914
915         void set_check_for_updates (bool c) {
916                 maybe_set (_check_for_updates, c);
917                 if (!c) {
918                         set_check_for_test_updates (false);
919                 }
920         }
921
922         void set_check_for_test_updates (bool c) {
923                 maybe_set (_check_for_test_updates, c);
924         }
925
926         void set_maximum_j2k_bandwidth (int b) {
927                 maybe_set (_maximum_j2k_bandwidth, b);
928         }
929
930         void set_log_types (int t) {
931                 maybe_set (_log_types, t);
932         }
933
934         void set_analyse_ebur128 (bool a) {
935                 maybe_set (_analyse_ebur128, a);
936         }
937
938         void set_automatic_audio_analysis (bool a) {
939                 maybe_set (_automatic_audio_analysis, a);
940         }
941
942 #ifdef DCPOMATIC_WINDOWS
943         void set_win32_console (bool c) {
944                 maybe_set (_win32_console, c);
945         }
946 #endif
947
948         void set_dkdms (std::shared_ptr<DKDMGroup> dkdms) {
949                 _dkdms = dkdms;
950                 changed ();
951         }
952
953         void set_cinemas_file (boost::filesystem::path file);
954
955         void set_show_hints_before_make_dcp (bool s) {
956                 maybe_set (_show_hints_before_make_dcp, s);
957         }
958
959         void set_confirm_kdm_email (bool s) {
960                 maybe_set (_confirm_kdm_email, s);
961         }
962
963         void set_sound (bool s) {
964                 maybe_set (_sound, s, SOUND);
965         }
966
967         void set_sound_output (std::string o) {
968                 maybe_set (_sound_output, o, SOUND_OUTPUT);
969         }
970
971         void set_last_player_load_directory (boost::filesystem::path d) {
972                 maybe_set (_last_player_load_directory, d);
973         }
974
975         void set_last_kdm_write_type (KDMWriteType t) {
976                 maybe_set (_last_kdm_write_type, t);
977         }
978
979         void set_last_dkdm_write_type (DKDMWriteType t) {
980                 maybe_set (_last_dkdm_write_type, t);
981         }
982
983         void unset_sound_output () {
984                 if (!_sound_output) {
985                         return;
986                 }
987
988                 _sound_output = boost::none;
989                 changed ();
990         }
991
992         void set_kdm_container_name_format (dcp::NameFormat n) {
993                 maybe_set (_kdm_container_name_format, n);
994         }
995
996         void set_kdm_filename_format (dcp::NameFormat n) {
997                 maybe_set (_kdm_filename_format, n);
998         }
999
1000         void set_dkdm_filename_format (dcp::NameFormat n) {
1001                 maybe_set (_dkdm_filename_format, n);
1002         }
1003
1004         void set_dcp_metadata_filename_format (dcp::NameFormat n) {
1005                 maybe_set (_dcp_metadata_filename_format, n);
1006         }
1007
1008         void set_dcp_asset_filename_format (dcp::NameFormat n) {
1009                 maybe_set (_dcp_asset_filename_format, n);
1010         }
1011
1012         void set_frames_in_memory_multiplier (int m) {
1013                 maybe_set (_frames_in_memory_multiplier, m);
1014         }
1015
1016         void set_decode_reduction (boost::optional<int> r) {
1017                 maybe_set (_decode_reduction, r);
1018         }
1019
1020         void set_default_notify (bool n) {
1021                 maybe_set (_default_notify, n);
1022         }
1023
1024         void clear_history () {
1025                 _history.clear ();
1026                 changed ();
1027         }
1028
1029         void clear_player_history () {
1030                 _player_history.clear ();
1031                 changed ();
1032         }
1033
1034         void add_to_history (boost::filesystem::path p);
1035         void clean_history ();
1036         void add_to_player_history (boost::filesystem::path p);
1037         void clean_player_history ();
1038
1039         void set_jump_to_selected (bool j) {
1040                 maybe_set (_jump_to_selected, j);
1041         }
1042
1043         void set_nagged (Nag nag, bool nagged) {
1044                 maybe_set (_nagged[nag], nagged);
1045         }
1046
1047         void set_cover_sheet (std::string s) {
1048                 maybe_set (_cover_sheet, s);
1049         }
1050
1051         void reset_cover_sheet ();
1052
1053         void set_notification (Notification n, bool v) {
1054                 maybe_set (_notification[n], v);
1055         }
1056
1057         void set_barco_username (std::string u) {
1058                 maybe_set (_barco_username, u);
1059         }
1060
1061         void unset_barco_username () {
1062                 maybe_set (_barco_username, boost::optional<std::string>());
1063         }
1064
1065         void set_barco_password (std::string p) {
1066                 maybe_set (_barco_password, p);
1067         }
1068
1069         void unset_barco_password () {
1070                 maybe_set (_barco_password, boost::optional<std::string>());
1071         }
1072
1073         void set_christie_username (std::string u) {
1074                 maybe_set (_christie_username, u);
1075         }
1076
1077         void unset_christie_username () {
1078                 maybe_set (_christie_username, boost::optional<std::string>());
1079         }
1080
1081         void set_christie_password (std::string p) {
1082                 maybe_set (_christie_password, p);
1083         }
1084
1085         void unset_christie_password () {
1086                 maybe_set (_christie_password, boost::optional<std::string>());
1087         }
1088
1089         void set_gdc_username (std::string u) {
1090                 maybe_set (_gdc_username, u);
1091         }
1092
1093         void unset_gdc_username () {
1094                 maybe_set (_gdc_username, boost::optional<std::string>());
1095         }
1096
1097         void set_gdc_password (std::string p) {
1098                 maybe_set (_gdc_password, p);
1099         }
1100
1101         void unset_gdc_password () {
1102                 maybe_set (_gdc_password, boost::optional<std::string>());
1103         }
1104
1105         void set_player_mode (PlayerMode m) {
1106                 maybe_set (_player_mode, m);
1107         }
1108
1109         void set_image_display (int n) {
1110                 maybe_set (_image_display, n);
1111         }
1112
1113         void set_video_view_type (VideoViewType v) {
1114                 maybe_set (_video_view_type, v);
1115         }
1116
1117         void set_respect_kdm_validity_periods (bool r) {
1118                 maybe_set (_respect_kdm_validity_periods, r);
1119         }
1120
1121         void set_player_debug_log_file (boost::filesystem::path p) {
1122                 maybe_set (_player_debug_log_file, p, PLAYER_DEBUG_LOG);
1123         }
1124
1125         void unset_player_debug_log_file () {
1126                 if (!_player_debug_log_file) {
1127                         return;
1128                 }
1129                 _player_debug_log_file = boost::none;
1130                 changed (PLAYER_DEBUG_LOG);
1131         }
1132
1133         void set_player_content_directory (boost::filesystem::path p) {
1134                 maybe_set (_player_content_directory, p, PLAYER_CONTENT_DIRECTORY);
1135         }
1136
1137         void unset_player_content_directory () {
1138                 if (!_player_content_directory) {
1139                         return;
1140                 }
1141                 _player_content_directory = boost::none;
1142                 changed (PLAYER_CONTENT_DIRECTORY);
1143         }
1144
1145         void set_player_playlist_directory (boost::filesystem::path p) {
1146                 maybe_set (_player_playlist_directory, p, PLAYER_PLAYLIST_DIRECTORY);
1147         }
1148
1149         void unset_player_playlist_directory () {
1150                 if (!_player_playlist_directory) {
1151                         return;
1152                 }
1153                 _player_playlist_directory = boost::none;
1154                 changed (PLAYER_PLAYLIST_DIRECTORY);
1155         }
1156
1157         void set_player_kdm_directory (boost::filesystem::path p) {
1158                 maybe_set (_player_kdm_directory, p);
1159         }
1160
1161         void unset_player_kdm_directory () {
1162                 if (!_player_kdm_directory) {
1163                         return;
1164                 }
1165                 _player_kdm_directory = boost::none;
1166                 changed ();
1167         }
1168
1169         void set_audio_mapping (AudioMapping m);
1170         void set_audio_mapping_to_default ();
1171
1172         void add_custom_language (dcp::LanguageTag tag);
1173
1174         void set_initial_path(std::string id, boost::filesystem::path path);
1175
1176         void set_use_isdcf_name_by_default (bool use) {
1177                 maybe_set (_use_isdcf_name_by_default, use);
1178         }
1179
1180         void set_write_kdms_to_disk (bool write) {
1181                 maybe_set (_write_kdms_to_disk, write);
1182         }
1183
1184         void set_email_kdms (bool email) {
1185                 maybe_set (_email_kdms, email);
1186         }
1187
1188         void set_default_kdm_type (dcp::Formulation type) {
1189                 maybe_set (_default_kdm_type, type);
1190         }
1191
1192         void set_default_kdm_duration (RoughDuration duration) {
1193                 maybe_set (_default_kdm_duration, duration);
1194         }
1195
1196         void set_auto_crop_threshold (double threshold) {
1197                 maybe_set (_auto_crop_threshold, threshold, AUTO_CROP_THRESHOLD);
1198         }
1199
1200         void set_last_release_notes_version (std::string version) {
1201                 maybe_set (_last_release_notes_version, version);
1202         }
1203
1204         void unset_last_release_notes_version() {
1205                 maybe_set(_last_release_notes_version, boost::optional<std::string>());
1206         }
1207
1208         ExportConfig& export_config() {
1209                 return _export;
1210         }
1211
1212         void set_main_divider_sash_position(int position) {
1213                 maybe_set(_main_divider_sash_position, position);
1214         }
1215
1216         void set_main_content_divider_sash_position(int position) {
1217                 maybe_set(_main_content_divider_sash_position, position);
1218         }
1219
1220         void set_default_add_file_location(DefaultAddFileLocation location) {
1221                 maybe_set(_default_add_file_location, location);
1222         }
1223
1224         void set_allow_smpte_bv20(bool allow) {
1225                 maybe_set(_allow_smpte_bv20, allow, ALLOW_SMPTE_BV20);
1226         }
1227
1228 #ifdef DCPOMATIC_GROK
1229         void set_grok(Grok const& grok);
1230 #endif
1231
1232         void set_isdcf_name_part_length(int length) {
1233                 maybe_set(_isdcf_name_part_length, length, ISDCF_NAME_PART_LENGTH);
1234         }
1235
1236
1237         void changed (Property p = OTHER);
1238         boost::signals2::signal<void (Property)> Changed;
1239         /** Emitted if read() failed on an existing Config file.  There is nothing
1240             a listener can do about it: this is just for information.
1241         */
1242         enum class LoadFailure {
1243                 CONFIG,
1244                 CINEMAS,
1245                 DKDM_RECIPIENTS
1246         };
1247         static boost::signals2::signal<void (LoadFailure)> FailedToLoad;
1248         /** Emitted if read() issued a warning which the user might want to know about */
1249         static boost::signals2::signal<void (std::string)> Warning;
1250         /** Emitted if there is a something wrong the contents of our config.  Handler can call
1251          *  true to ask Config to solve the problem (by discarding and recreating the bad thing)
1252          */
1253         enum BadReason {
1254                 BAD_SIGNER_UTF8_STRINGS,      ///< signer chain contains UTF-8 strings (not PRINTABLESTRING)
1255                 BAD_SIGNER_INCONSISTENT,      ///< signer chain is somehow inconsistent
1256                 BAD_DECRYPTION_INCONSISTENT,  ///< KDM decryption chain is somehow inconsistent
1257                 BAD_SIGNER_VALIDITY_TOO_LONG, ///< signer certificate validity periods are >10 years
1258                 BAD_SIGNER_DN_QUALIFIER,      ///< some signer certificate has a bad dnQualifier (DoM #2716).
1259         };
1260
1261         static boost::signals2::signal<bool (BadReason)> Bad;
1262
1263         void write () const override;
1264         void write_config () const;
1265         void write_cinemas () const;
1266         void write_dkdm_recipients () const;
1267         void link (boost::filesystem::path new_file) const;
1268         void copy_and_link (boost::filesystem::path new_file) const;
1269         bool have_write_permission () const;
1270
1271         void save_template (std::shared_ptr<const Film> film, std::string name) const;
1272         bool existing_template (std::string name) const;
1273         std::list<std::string> templates () const;
1274         boost::filesystem::path template_read_path (std::string name) const;
1275         boost::filesystem::path template_write_path (std::string name) const;
1276         void rename_template (std::string old_name, std::string new_name) const;
1277         void delete_template (std::string name) const;
1278
1279         boost::optional<BadReason> check_certificates () const;
1280
1281         static Config* instance ();
1282         static void drop ();
1283         static void restore_defaults ();
1284         static bool have_existing (std::string);
1285         static boost::filesystem::path config_read_file ();
1286         static boost::filesystem::path config_write_file ();
1287
1288         template <class T>
1289         void maybe_set (T& member, T new_value, Property prop = OTHER) {
1290                 if (member == new_value) {
1291                         return;
1292                 }
1293                 member = new_value;
1294                 changed (prop);
1295         }
1296
1297         template <class T>
1298         void maybe_set (boost::optional<T>& member, T new_value, Property prop = OTHER) {
1299                 if (member && member.get() == new_value) {
1300                         return;
1301                 }
1302                 member = new_value;
1303                 changed (prop);
1304         }
1305
1306 private:
1307         Config ();
1308         void read () override;
1309         void read_config();
1310         void read_cinemas();
1311         void read_dkdm_recipients();
1312         void set_defaults ();
1313         void set_kdm_email_to_default ();
1314         void set_notification_email_to_default ();
1315         void set_cover_sheet_to_default ();
1316         void read_cinemas (cxml::Document const & f);
1317         void read_dkdm_recipients (cxml::Document const & f);
1318         std::shared_ptr<dcp::CertificateChain> create_certificate_chain ();
1319         boost::filesystem::path directory_or (boost::optional<boost::filesystem::path> dir, boost::filesystem::path a) const;
1320         void add_to_history_internal (std::vector<boost::filesystem::path>& h, boost::filesystem::path p);
1321         void clean_history_internal (std::vector<boost::filesystem::path>& h);
1322         void backup ();
1323
1324         /** number of threads which a master DoM should use for J2K encoding on the local machine */
1325         int _master_encoding_threads;
1326         /** number of threads which a server should use for J2K encoding on the local machine */
1327         int _server_encoding_threads;
1328         /** default directory to put new films in */
1329         boost::optional<boost::filesystem::path> _default_directory;
1330         /** base port number to use for J2K encoding servers;
1331          *  this port and the two above it will be used.
1332          */
1333         int _server_port_base;
1334         /** true to broadcast on the `any' address to look for servers */
1335         bool _use_any_servers;
1336         /** J2K encoding servers that should definitely be used */
1337         std::vector<std::string> _servers;
1338         bool _only_servers_encode;
1339         FileTransferProtocol _tms_protocol;
1340         bool _tms_passive;
1341         /** The IP address of a TMS that we can copy DCPs to */
1342         std::string _tms_ip;
1343         /** The path on a TMS that we should write DCPs to */
1344         std::string _tms_path;
1345         /** User name to log into the TMS with */
1346         std::string _tms_user;
1347         /** Password to log into the TMS with */
1348         std::string _tms_password;
1349         /** The list of possible DCP frame rates that DCP-o-matic will use */
1350         std::list<int> _allowed_dcp_frame_rates;
1351         /** Allow any video frame rate for the DCP; if true, overrides _allowed_dcp_frame_rates */
1352         bool _allow_any_dcp_frame_rate;
1353         /** Allow any container ratio, not just the standard ones.  GDC SX-2001 will not play Flat
1354             DCPs at 25fps but will play 16:9, so this is very useful for some users.
1355             https://www.dcpomatic.com/forum/viewtopic.php?f=2&t=1119&p=4468
1356         */
1357         bool _allow_any_container;
1358         bool _allow_96khz_audio;
1359         bool _use_all_audio_channels;
1360         /** Offer the upmixers in the audio processor settings */
1361         bool _show_experimental_audio_processors;
1362         boost::optional<std::string> _language;
1363         /** Default length of still image content (seconds) */
1364         int _default_still_length;
1365         DCPContentType const * _default_dcp_content_type;
1366         int _default_dcp_audio_channels;
1367         std::string _dcp_issuer;
1368         std::string _dcp_creator;
1369         std::string _dcp_company_name;
1370         std::string _dcp_product_name;
1371         std::string _dcp_product_version;
1372         std::string _dcp_j2k_comment;
1373         int _default_j2k_bandwidth;
1374         int _default_audio_delay;
1375         bool _default_interop;
1376         boost::optional<dcp::LanguageTag> _default_audio_language;
1377         boost::optional<dcp::LanguageTag::RegionSubtag> _default_territory;
1378         std::map<std::string, std::string> _default_metadata;
1379         /** Default directory to offer to write KDMs to; if it's not set,
1380             the home directory will be offered.
1381         */
1382         boost::optional<boost::filesystem::path> _default_kdm_directory;
1383         bool _upload_after_make_dcp;
1384         std::list<std::shared_ptr<Cinema>> _cinemas;
1385         std::list<std::shared_ptr<DKDMRecipient>> _dkdm_recipients;
1386         std::string _mail_server;
1387         int _mail_port;
1388         EmailProtocol _mail_protocol;
1389         std::string _mail_user;
1390         std::string _mail_password;
1391         std::string _kdm_subject;
1392         std::string _kdm_from;
1393         std::vector<std::string> _kdm_cc;
1394         std::string _kdm_bcc;
1395         std::string _kdm_email;
1396         std::string _notification_subject;
1397         std::string _notification_from;
1398         std::string _notification_to;
1399         std::vector<std::string> _notification_cc;
1400         std::string _notification_bcc;
1401         std::string _notification_email;
1402         std::shared_ptr<const dcp::CertificateChain> _signer_chain;
1403         /** Chain used to decrypt KDMs; the leaf of this chain is the target
1404          *  certificate for making KDMs given to DCP-o-matic.
1405          */
1406         std::shared_ptr<const dcp::CertificateChain> _decryption_chain;
1407         /** true to check for updates on startup */
1408         bool _check_for_updates;
1409         bool _check_for_test_updates;
1410         /** maximum allowed J2K bandwidth in bits per second */
1411         int _maximum_j2k_bandwidth;
1412         int _log_types;
1413         bool _analyse_ebur128;
1414         bool _automatic_audio_analysis;
1415 #ifdef DCPOMATIC_WINDOWS
1416         bool _win32_console;
1417 #endif
1418         std::vector<boost::filesystem::path> _history;
1419         std::vector<boost::filesystem::path> _player_history;
1420         std::shared_ptr<DKDMGroup> _dkdms;
1421         boost::filesystem::path _cinemas_file;
1422         boost::filesystem::path _dkdm_recipients_file;
1423         bool _show_hints_before_make_dcp;
1424         bool _confirm_kdm_email;
1425         dcp::NameFormat _kdm_filename_format;
1426         dcp::NameFormat _dkdm_filename_format;
1427         dcp::NameFormat _kdm_container_name_format;
1428         dcp::NameFormat _dcp_metadata_filename_format;
1429         dcp::NameFormat _dcp_asset_filename_format;
1430         bool _jump_to_selected;
1431         bool _nagged[NAG_COUNT];
1432         bool _sound;
1433         /** name of a specific sound output stream to use, or empty to use the default */
1434         boost::optional<std::string> _sound_output;
1435         std::string _cover_sheet;
1436         boost::optional<boost::filesystem::path> _last_player_load_directory;
1437         boost::optional<KDMWriteType> _last_kdm_write_type;
1438         boost::optional<DKDMWriteType> _last_dkdm_write_type;
1439         int _frames_in_memory_multiplier;
1440         boost::optional<int> _decode_reduction;
1441         bool _default_notify;
1442         bool _notification[NOTIFICATION_COUNT];
1443         boost::optional<std::string> _barco_username;
1444         boost::optional<std::string> _barco_password;
1445         boost::optional<std::string> _christie_username;
1446         boost::optional<std::string> _christie_password;
1447         boost::optional<std::string> _gdc_username;
1448         boost::optional<std::string> _gdc_password;
1449         PlayerMode _player_mode;
1450         int _image_display;
1451         VideoViewType _video_view_type;
1452         bool _respect_kdm_validity_periods;
1453         /** Log file containing debug information for the player */
1454         boost::optional<boost::filesystem::path> _player_debug_log_file;
1455         /** A directory containing DCPs whose contents are presented to the user
1456             in the dual-screen player mode.  DCPs on the list can be loaded
1457             for playback.
1458         */
1459         boost::optional<boost::filesystem::path> _player_content_directory;
1460         boost::optional<boost::filesystem::path> _player_playlist_directory;
1461         boost::optional<boost::filesystem::path> _player_kdm_directory;
1462         boost::optional<AudioMapping> _audio_mapping;
1463         std::vector<dcp::LanguageTag> _custom_languages;
1464         std::map<std::string, boost::optional<boost::filesystem::path>> _initial_paths;
1465         bool _use_isdcf_name_by_default;
1466         bool _write_kdms_to_disk;
1467         bool _email_kdms;
1468         dcp::Formulation _default_kdm_type;
1469         RoughDuration _default_kdm_duration;
1470         double _auto_crop_threshold;
1471         boost::optional<std::string> _last_release_notes_version;
1472         boost::optional<int> _main_divider_sash_position;
1473         boost::optional<int> _main_content_divider_sash_position;
1474         DefaultAddFileLocation _default_add_file_location;
1475         bool _allow_smpte_bv20;
1476         int _isdcf_name_part_length;
1477
1478 #ifdef DCPOMATIC_GROK
1479         boost::optional<Grok> _grok;
1480 #endif
1481
1482         ExportConfig _export;
1483
1484         static int const _current_version;
1485
1486         /** Singleton instance, or 0 */
1487         static Config* _instance;
1488 };
1489
1490
1491 #endif