2 Copyright (C) 2012-2019 Carl Hetherington <cth@carlh.net>
4 This file is part of DCP-o-matic.
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.
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.
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/>.
21 /** @file src/full_config_dialog.cc
22 * @brief A dialogue to edit all DCP-o-matic configuration.
25 #include "full_config_dialog.h"
27 #include "editable_list.h"
28 #include "filter_dialog.h"
29 #include "dir_picker_ctrl.h"
30 #include "file_picker_ctrl.h"
31 #include "isdcf_metadata_dialog.h"
32 #include "server_dialog.h"
33 #include "make_chain_dialog.h"
34 #include "email_dialog.h"
35 #include "name_format_editor.h"
36 #include "nag_dialog.h"
37 #include "config_move_dialog.h"
38 #include "config_dialog.h"
39 #include "static_text.h"
40 #include "check_box.h"
41 #include "dcpomatic_button.h"
42 #include "password_entry.h"
43 #include "lib/config.h"
44 #include "lib/ratio.h"
45 #include "lib/filter.h"
46 #include "lib/dcp_content_type.h"
49 #include "lib/cross.h"
50 #include "lib/exceptions.h"
51 #include <dcp/locale_convert.h>
52 #include <dcp/exceptions.h>
53 #include <dcp/certificate_chain.h>
54 #include <wx/stdpaths.h>
55 #include <wx/preferences.h>
56 #include <wx/spinctrl.h>
57 #include <wx/filepicker.h>
59 #include <boost/filesystem.hpp>
60 #include <boost/foreach.hpp>
71 using boost::shared_ptr;
72 using boost::function;
73 using boost::optional;
74 using dcp::locale_convert;
76 class FullGeneralPage : public GeneralPage
79 FullGeneralPage (wxSize panel_size, int border)
80 : GeneralPage (panel_size, border)
86 wxGridBagSizer* table = new wxGridBagSizer (DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
87 _panel->GetSizer()->Add (table, 1, wxALL | wxEXPAND, _border);
90 add_language_controls (table, r);
92 add_label_to_sizer (table, _panel, _("Interface complexity"), true, wxGBPosition(r, 0));
93 _interface_complexity = new wxChoice (_panel, wxID_ANY);
94 table->Add (_interface_complexity, wxGBPosition (r, 1));
97 add_label_to_sizer (table, _panel, _("Number of threads DCP-o-matic should use"), true, wxGBPosition (r, 0));
98 _master_encoding_threads = new wxSpinCtrl (_panel);
99 table->Add (_master_encoding_threads, wxGBPosition (r, 1));
102 add_label_to_sizer (table, _panel, _("Number of threads DCP-o-matic encode server should use"), true, wxGBPosition (r, 0));
103 _server_encoding_threads = new wxSpinCtrl (_panel);
104 table->Add (_server_encoding_threads, wxGBPosition (r, 1));
107 add_label_to_sizer (table, _panel, _("Configuration file"), true, wxGBPosition (r, 0));
108 _config_file = new FilePickerCtrl (_panel, _("Select configuration file"), "*.xml", true, true);
109 table->Add (_config_file, wxGBPosition (r, 1));
112 add_label_to_sizer (table, _panel, _("Cinema and screen database file"), true, wxGBPosition (r, 0));
113 _cinemas_file = new FilePickerCtrl (_panel, _("Select cinema and screen database file"), "*.xml", true, true);
114 table->Add (_cinemas_file, wxGBPosition (r, 1));
115 Button* export_cinemas = new Button (_panel, _("Export..."));
116 table->Add (export_cinemas, wxGBPosition (r, 2));
119 #ifdef DCPOMATIC_HAVE_EBUR128_PATCHED_FFMPEG
120 _analyse_ebur128 = new CheckBox (_panel, _("Find integrated loudness, true peak and loudness range when analysing audio"));
121 table->Add (_analyse_ebur128, wxGBPosition (r, 0), wxGBSpan (1, 2));
125 _automatic_audio_analysis = new CheckBox (_panel, _("Automatically analyse content audio"));
126 table->Add (_automatic_audio_analysis, wxGBPosition (r, 0), wxGBSpan (1, 2));
129 add_update_controls (table, r);
131 wxFlexGridSizer* bottom_table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
132 bottom_table->AddGrowableCol (1, 1);
134 add_label_to_sizer (bottom_table, _panel, _("Issuer"), true);
135 _issuer = new wxTextCtrl (_panel, wxID_ANY);
136 _issuer->SetToolTip (_("This will be written to the DCP's XML files as the <Issuer>. If it is blank, a default value mentioning DCP-o-matic will be used."));
137 bottom_table->Add (_issuer, 1, wxALL | wxEXPAND);
139 add_label_to_sizer (bottom_table, _panel, _("Creator"), true);
140 _creator = new wxTextCtrl (_panel, wxID_ANY);
141 _creator->SetToolTip (_("This will be written to the DCP's XML files as the <Creator>. If it is blank, a default value mentioning DCP-o-matic will be used."));
142 bottom_table->Add (_creator, 1, wxALL | wxEXPAND);
144 add_label_to_sizer (bottom_table, _panel, _("Company name"), true);
145 _company_name = new wxTextCtrl (_panel, wxID_ANY);
146 _company_name->SetToolTip (_("This will be written to the DCP's MXF files as the 'company name'. If it is blank, a default value mentioning libdcp (an internal DCP-o-matic library) will be used."));
147 bottom_table->Add (_company_name, 1, wxALL | wxEXPAND);
149 add_label_to_sizer (bottom_table, _panel, _("Product name"), true);
150 _product_name = new wxTextCtrl (_panel, wxID_ANY);
151 _product_name->SetToolTip (_("This will be written to the DCP's MXF files as the 'product name'. If it is blank, a default value mentioning libdcp (an internal DCP-o-matic library) will be used."));
152 bottom_table->Add (_product_name, 1, wxALL | wxEXPAND);
154 add_label_to_sizer (bottom_table, _panel, _("Product version"), true);
155 _product_version = new wxTextCtrl (_panel, wxID_ANY);
156 _product_version->SetToolTip (_("This will be written to the DCP's MXF files as the 'product version'. If it is blank, a default value mentioning libdcp (an internal DCP-o-matic library) will be used."));
157 bottom_table->Add (_product_version, 1, wxALL | wxEXPAND);
159 add_label_to_sizer (bottom_table, _panel, _("JPEG2000 comment"), true);
160 _j2k_comment = new wxTextCtrl (_panel, wxID_ANY);
161 _j2k_comment->SetToolTip (_("This will be written to the DCP's JPEG2000 data as a comment. If it is blank, a default value mentioning libdcp (an internal DCP-o-matic library) will be used."));
162 bottom_table->Add (_j2k_comment, 1, wxALL | wxEXPAND);
164 table->Add (bottom_table, wxGBPosition (r, 0), wxGBSpan (2, 2), wxEXPAND);
167 _config_file->Bind (wxEVT_FILEPICKER_CHANGED, boost::bind (&FullGeneralPage::config_file_changed, this));
168 _cinemas_file->Bind (wxEVT_FILEPICKER_CHANGED, boost::bind (&FullGeneralPage::cinemas_file_changed, this));
170 _interface_complexity->Append (_("Simple"));
171 _interface_complexity->Append (_("Full"));
172 _interface_complexity->Bind (wxEVT_CHOICE, boost::bind(&FullGeneralPage::interface_complexity_changed, this));
174 _master_encoding_threads->SetRange (1, 128);
175 _master_encoding_threads->Bind (wxEVT_SPINCTRL, boost::bind (&FullGeneralPage::master_encoding_threads_changed, this));
176 _server_encoding_threads->SetRange (1, 128);
177 _server_encoding_threads->Bind (wxEVT_SPINCTRL, boost::bind (&FullGeneralPage::server_encoding_threads_changed, this));
178 export_cinemas->Bind (wxEVT_BUTTON, boost::bind (&FullGeneralPage::export_cinemas_file, this));
180 #ifdef DCPOMATIC_HAVE_EBUR128_PATCHED_FFMPEG
181 _analyse_ebur128->Bind (wxEVT_CHECKBOX, boost::bind (&FullGeneralPage::analyse_ebur128_changed, this));
183 _automatic_audio_analysis->Bind (wxEVT_CHECKBOX, boost::bind (&FullGeneralPage::automatic_audio_analysis_changed, this));
185 _issuer->Bind (wxEVT_TEXT, boost::bind (&FullGeneralPage::issuer_changed, this));
186 _creator->Bind (wxEVT_TEXT, boost::bind (&FullGeneralPage::creator_changed, this));
187 _company_name->Bind (wxEVT_TEXT, boost::bind (&FullGeneralPage::company_name_changed, this));
188 _product_name->Bind (wxEVT_TEXT, boost::bind (&FullGeneralPage::product_name_changed, this));
189 _product_version->Bind (wxEVT_TEXT, boost::bind (&FullGeneralPage::product_version_changed, this));
190 _j2k_comment->Bind (wxEVT_TEXT, boost::bind (&FullGeneralPage::j2k_comment_changed, this));
193 void config_changed ()
195 Config* config = Config::instance ();
197 switch (config->interface_complexity()) {
198 case Config::INTERFACE_SIMPLE:
199 checked_set (_interface_complexity, 0);
201 case Config::INTERFACE_FULL:
202 checked_set (_interface_complexity, 1);
205 checked_set (_master_encoding_threads, config->master_encoding_threads ());
206 checked_set (_server_encoding_threads, config->server_encoding_threads ());
207 #ifdef DCPOMATIC_HAVE_EBUR128_PATCHED_FFMPEG
208 checked_set (_analyse_ebur128, config->analyse_ebur128 ());
210 checked_set (_automatic_audio_analysis, config->automatic_audio_analysis ());
211 checked_set (_issuer, config->dcp_issuer ());
212 checked_set (_creator, config->dcp_creator ());
213 checked_set (_company_name, config->dcp_company_name ());
214 checked_set (_product_name, config->dcp_product_name ());
215 checked_set (_product_version, config->dcp_product_version ());
216 checked_set (_j2k_comment, config->dcp_j2k_comment ());
217 checked_set (_config_file, config->config_file());
218 checked_set (_cinemas_file, config->cinemas_file());
220 GeneralPage::config_changed ();
223 void export_cinemas_file ()
225 wxFileDialog* d = new wxFileDialog (
226 _panel, _("Select Cinemas File"), wxEmptyString, wxEmptyString, wxT ("XML files (*.xml)|*.xml"),
227 wxFD_SAVE | wxFD_OVERWRITE_PROMPT
230 if (d->ShowModal () == wxID_OK) {
231 boost::filesystem::copy_file (Config::instance()->cinemas_file(), wx_to_std(d->GetPath()));
236 void interface_complexity_changed ()
238 if (_interface_complexity->GetSelection() == 0) {
239 Config::instance()->set_interface_complexity (Config::INTERFACE_SIMPLE);
241 Config::instance()->set_interface_complexity (Config::INTERFACE_FULL);
246 #ifdef DCPOMATIC_HAVE_EBUR128_PATCHED_FFMPEG
247 void analyse_ebur128_changed ()
249 Config::instance()->set_analyse_ebur128 (_analyse_ebur128->GetValue ());
253 void automatic_audio_analysis_changed ()
255 Config::instance()->set_automatic_audio_analysis (_automatic_audio_analysis->GetValue ());
258 void master_encoding_threads_changed ()
260 Config::instance()->set_master_encoding_threads (_master_encoding_threads->GetValue ());
263 void server_encoding_threads_changed ()
265 Config::instance()->set_server_encoding_threads (_server_encoding_threads->GetValue ());
268 void issuer_changed ()
270 Config::instance()->set_dcp_issuer (wx_to_std (_issuer->GetValue ()));
273 void creator_changed ()
275 Config::instance()->set_dcp_creator (wx_to_std (_creator->GetValue ()));
278 void company_name_changed ()
280 Config::instance()->set_dcp_company_name (wx_to_std(_company_name->GetValue()));
283 void product_name_changed ()
285 Config::instance()->set_dcp_product_name (wx_to_std(_product_name->GetValue()));
288 void product_version_changed ()
290 Config::instance()->set_dcp_product_version (wx_to_std(_product_version->GetValue()));
293 void j2k_comment_changed ()
295 Config::instance()->set_dcp_j2k_comment (wx_to_std(_j2k_comment->GetValue()));
298 void config_file_changed ()
300 Config* config = Config::instance();
301 boost::filesystem::path new_file = wx_to_std(_config_file->GetPath());
302 if (new_file == config->config_file()) {
305 bool copy_and_link = true;
306 if (boost::filesystem::exists(new_file)) {
307 ConfigMoveDialog* d = new ConfigMoveDialog (_panel, new_file);
308 if (d->ShowModal() == wxID_OK) {
309 copy_and_link = false;
316 if (new_file != config->config_file()) {
317 config->copy_and_link (new_file);
320 config->link (new_file);
324 void cinemas_file_changed ()
326 Config::instance()->set_cinemas_file (wx_to_std (_cinemas_file->GetPath ()));
329 wxChoice* _interface_complexity;
330 wxSpinCtrl* _master_encoding_threads;
331 wxSpinCtrl* _server_encoding_threads;
332 FilePickerCtrl* _config_file;
333 FilePickerCtrl* _cinemas_file;
334 #ifdef DCPOMATIC_HAVE_EBUR128_PATCHED_FFMPEG
335 wxCheckBox* _analyse_ebur128;
337 wxCheckBox* _automatic_audio_analysis;
339 wxTextCtrl* _creator;
340 wxTextCtrl* _company_name;
341 wxTextCtrl* _product_name;
342 wxTextCtrl* _product_version;
343 wxTextCtrl* _j2k_comment;
346 class DefaultsPage : public StandardPage
349 DefaultsPage (wxSize panel_size, int border)
350 : StandardPage (panel_size, border)
353 wxString GetName () const
355 return _("Defaults");
359 wxBitmap GetLargeIcon () const
361 return wxBitmap ("defaults", wxBITMAP_TYPE_PNG_RESOURCE);
368 wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
369 table->AddGrowableCol (1, 1);
370 _panel->GetSizer()->Add (table, 1, wxALL | wxEXPAND, _border);
373 add_label_to_sizer (table, _panel, _("Default duration of still images"), true);
374 wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL);
375 _still_length = new wxSpinCtrl (_panel);
376 s->Add (_still_length);
377 add_label_to_sizer (s, _panel, _("s"), false);
381 add_label_to_sizer (table, _panel, _("Default directory for new films"), true);
382 #ifdef DCPOMATIC_USE_OWN_PICKER
383 _directory = new DirPickerCtrl (_panel);
385 _directory = new wxDirPickerCtrl (_panel, wxDD_DIR_MUST_EXIST);
387 table->Add (_directory, 1, wxEXPAND);
389 add_label_to_sizer (table, _panel, _("Default ISDCF name details"), true);
390 _isdcf_metadata_button = new Button (_panel, _("Edit..."));
391 table->Add (_isdcf_metadata_button);
393 add_label_to_sizer (table, _panel, _("Default container"), true);
394 _container = new wxChoice (_panel, wxID_ANY);
395 table->Add (_container);
397 add_label_to_sizer (table, _panel, _("Default content type"), true);
398 _dcp_content_type = new wxChoice (_panel, wxID_ANY);
399 table->Add (_dcp_content_type);
401 add_label_to_sizer (table, _panel, _("Default DCP audio channels"), true);
402 _dcp_audio_channels = new wxChoice (_panel, wxID_ANY);
403 table->Add (_dcp_audio_channels);
406 add_label_to_sizer (table, _panel, _("Default JPEG2000 bandwidth"), true);
407 wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL);
408 _j2k_bandwidth = new wxSpinCtrl (_panel);
409 s->Add (_j2k_bandwidth);
410 add_label_to_sizer (s, _panel, _("Mbit/s"), false);
415 add_label_to_sizer (table, _panel, _("Default audio delay"), true);
416 wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL);
417 _audio_delay = new wxSpinCtrl (_panel);
418 s->Add (_audio_delay);
419 add_label_to_sizer (s, _panel, _("ms"), false);
423 add_label_to_sizer (table, _panel, _("Default standard"), true);
424 _standard = new wxChoice (_panel, wxID_ANY);
425 table->Add (_standard);
427 add_label_to_sizer (table, _panel, _("Default KDM directory"), true);
428 #ifdef DCPOMATIC_USE_OWN_PICKER
429 _kdm_directory = new DirPickerCtrl (_panel);
431 _kdm_directory = new wxDirPickerCtrl (_panel, wxDD_DIR_MUST_EXIST);
434 table->Add (_kdm_directory, 1, wxEXPAND);
436 _still_length->SetRange (1, 3600);
437 _still_length->Bind (wxEVT_SPINCTRL, boost::bind (&DefaultsPage::still_length_changed, this));
439 _directory->Bind (wxEVT_DIRPICKER_CHANGED, boost::bind (&DefaultsPage::directory_changed, this));
440 _kdm_directory->Bind (wxEVT_DIRPICKER_CHANGED, boost::bind (&DefaultsPage::kdm_directory_changed, this));
442 _isdcf_metadata_button->Bind (wxEVT_BUTTON, boost::bind (&DefaultsPage::edit_isdcf_metadata_clicked, this));
444 BOOST_FOREACH (Ratio const * i, Ratio::containers()) {
445 _container->Append (std_to_wx(i->container_nickname()));
448 _container->Bind (wxEVT_CHOICE, boost::bind (&DefaultsPage::container_changed, this));
450 BOOST_FOREACH (DCPContentType const * i, DCPContentType::all()) {
451 _dcp_content_type->Append (std_to_wx (i->pretty_name ()));
454 setup_audio_channels_choice (_dcp_audio_channels, 2);
456 _dcp_content_type->Bind (wxEVT_CHOICE, boost::bind (&DefaultsPage::dcp_content_type_changed, this));
457 _dcp_audio_channels->Bind (wxEVT_CHOICE, boost::bind (&DefaultsPage::dcp_audio_channels_changed, this));
459 _j2k_bandwidth->SetRange (50, 250);
460 _j2k_bandwidth->Bind (wxEVT_SPINCTRL, boost::bind (&DefaultsPage::j2k_bandwidth_changed, this));
462 _audio_delay->SetRange (-1000, 1000);
463 _audio_delay->Bind (wxEVT_SPINCTRL, boost::bind (&DefaultsPage::audio_delay_changed, this));
465 _standard->Append (_("SMPTE"));
466 _standard->Append (_("Interop"));
467 _standard->Bind (wxEVT_CHOICE, boost::bind (&DefaultsPage::standard_changed, this));
470 void config_changed ()
472 Config* config = Config::instance ();
474 vector<Ratio const *> containers = Ratio::containers ();
475 for (size_t i = 0; i < containers.size(); ++i) {
476 if (containers[i] == config->default_container ()) {
477 _container->SetSelection (i);
481 vector<DCPContentType const *> const ct = DCPContentType::all ();
482 for (size_t i = 0; i < ct.size(); ++i) {
483 if (ct[i] == config->default_dcp_content_type ()) {
484 _dcp_content_type->SetSelection (i);
488 checked_set (_still_length, config->default_still_length ());
489 _directory->SetPath (std_to_wx (config->default_directory_or (wx_to_std (wxStandardPaths::Get().GetDocumentsDir())).string ()));
490 _kdm_directory->SetPath (std_to_wx (config->default_kdm_directory_or (wx_to_std (wxStandardPaths::Get().GetDocumentsDir())).string ()));
491 checked_set (_j2k_bandwidth, config->default_j2k_bandwidth() / 1000000);
492 _j2k_bandwidth->SetRange (50, config->maximum_j2k_bandwidth() / 1000000);
493 checked_set (_dcp_audio_channels, locale_convert<string> (config->default_dcp_audio_channels()));
494 checked_set (_audio_delay, config->default_audio_delay ());
495 checked_set (_standard, config->default_interop() ? 1 : 0);
498 void j2k_bandwidth_changed ()
500 Config::instance()->set_default_j2k_bandwidth (_j2k_bandwidth->GetValue() * 1000000);
503 void audio_delay_changed ()
505 Config::instance()->set_default_audio_delay (_audio_delay->GetValue());
508 void dcp_audio_channels_changed ()
510 int const s = _dcp_audio_channels->GetSelection ();
511 if (s != wxNOT_FOUND) {
512 Config::instance()->set_default_dcp_audio_channels (
513 locale_convert<int> (string_client_data (_dcp_audio_channels->GetClientObject (s)))
518 void directory_changed ()
520 Config::instance()->set_default_directory (wx_to_std (_directory->GetPath ()));
523 void kdm_directory_changed ()
525 Config::instance()->set_default_kdm_directory (wx_to_std (_kdm_directory->GetPath ()));
528 void edit_isdcf_metadata_clicked ()
530 ISDCFMetadataDialog* d = new ISDCFMetadataDialog (_panel, Config::instance()->default_isdcf_metadata (), false);
532 Config::instance()->set_default_isdcf_metadata (d->isdcf_metadata ());
536 void still_length_changed ()
538 Config::instance()->set_default_still_length (_still_length->GetValue ());
541 void container_changed ()
543 vector<Ratio const *> ratio = Ratio::containers ();
544 Config::instance()->set_default_container (ratio[_container->GetSelection()]);
547 void dcp_content_type_changed ()
549 vector<DCPContentType const *> ct = DCPContentType::all ();
550 Config::instance()->set_default_dcp_content_type (ct[_dcp_content_type->GetSelection()]);
553 void standard_changed ()
555 Config::instance()->set_default_interop (_standard->GetSelection() == 1);
558 wxSpinCtrl* _j2k_bandwidth;
559 wxSpinCtrl* _audio_delay;
560 wxButton* _isdcf_metadata_button;
561 wxSpinCtrl* _still_length;
562 #ifdef DCPOMATIC_USE_OWN_PICKER
563 DirPickerCtrl* _directory;
564 DirPickerCtrl* _kdm_directory;
566 wxDirPickerCtrl* _directory;
567 wxDirPickerCtrl* _kdm_directory;
569 wxChoice* _container;
570 wxChoice* _dcp_content_type;
571 wxChoice* _dcp_audio_channels;
575 class EncodingServersPage : public StandardPage
578 EncodingServersPage (wxSize panel_size, int border)
579 : StandardPage (panel_size, border)
582 wxString GetName () const
588 wxBitmap GetLargeIcon () const
590 return wxBitmap ("servers", wxBITMAP_TYPE_PNG_RESOURCE);
597 _use_any_servers = new CheckBox (_panel, _("Search network for servers"));
598 _panel->GetSizer()->Add (_use_any_servers, 0, wxALL, _border);
600 vector<EditableListColumn> columns;
601 columns.push_back (EditableListColumn(wx_to_std(_("IP address / host name"))));
602 _servers_list = new EditableList<string, ServerDialog> (
605 boost::bind (&Config::servers, Config::instance()),
606 boost::bind (&Config::set_servers, Config::instance(), _1),
607 boost::bind (&EncodingServersPage::server_column, this, _1)
610 _panel->GetSizer()->Add (_servers_list, 1, wxEXPAND | wxALL, _border);
612 _use_any_servers->Bind (wxEVT_CHECKBOX, boost::bind (&EncodingServersPage::use_any_servers_changed, this));
615 void config_changed ()
617 checked_set (_use_any_servers, Config::instance()->use_any_servers ());
618 _servers_list->refresh ();
621 void use_any_servers_changed ()
623 Config::instance()->set_use_any_servers (_use_any_servers->GetValue ());
626 string server_column (string s)
631 wxCheckBox* _use_any_servers;
632 EditableList<string, ServerDialog>* _servers_list;
635 class TMSPage : public StandardPage
638 TMSPage (wxSize panel_size, int border)
639 : StandardPage (panel_size, border)
642 wxString GetName () const
648 wxBitmap GetLargeIcon () const
650 return wxBitmap ("tms", wxBITMAP_TYPE_PNG_RESOURCE);
657 _upload = new CheckBox (_panel, _("Upload DCP to TMS after creation"));
658 _panel->GetSizer()->Add (_upload, 0, wxALL | wxEXPAND, _border);
660 wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
661 table->AddGrowableCol (1, 1);
662 _panel->GetSizer()->Add (table, 1, wxALL | wxEXPAND, _border);
664 add_label_to_sizer (table, _panel, _("Protocol"), true);
665 _tms_protocol = new wxChoice (_panel, wxID_ANY);
666 table->Add (_tms_protocol, 1, wxEXPAND);
668 add_label_to_sizer (table, _panel, _("IP address"), true);
669 _tms_ip = new wxTextCtrl (_panel, wxID_ANY);
670 table->Add (_tms_ip, 1, wxEXPAND);
672 add_label_to_sizer (table, _panel, _("Target path"), true);
673 _tms_path = new wxTextCtrl (_panel, wxID_ANY);
674 table->Add (_tms_path, 1, wxEXPAND);
676 add_label_to_sizer (table, _panel, _("User name"), true);
677 _tms_user = new wxTextCtrl (_panel, wxID_ANY);
678 table->Add (_tms_user, 1, wxEXPAND);
680 add_label_to_sizer (table, _panel, _("Password"), true);
681 _tms_password = new PasswordEntry (_panel);
682 table->Add (_tms_password->get_panel(), 1, wxEXPAND);
684 _tms_protocol->Append (_("SCP (for AAM and Doremi)"));
685 _tms_protocol->Append (_("FTP (for Dolby)"));
687 _upload->Bind (wxEVT_CHECKBOX, boost::bind(&TMSPage::upload_changed, this));
688 _tms_protocol->Bind (wxEVT_CHOICE, boost::bind (&TMSPage::tms_protocol_changed, this));
689 _tms_ip->Bind (wxEVT_TEXT, boost::bind (&TMSPage::tms_ip_changed, this));
690 _tms_path->Bind (wxEVT_TEXT, boost::bind (&TMSPage::tms_path_changed, this));
691 _tms_user->Bind (wxEVT_TEXT, boost::bind (&TMSPage::tms_user_changed, this));
692 _tms_password->Changed.connect (boost::bind (&TMSPage::tms_password_changed, this));
695 void config_changed ()
697 Config* config = Config::instance ();
699 checked_set (_upload, config->upload_after_make_dcp());
700 checked_set (_tms_protocol, config->tms_protocol ());
701 checked_set (_tms_ip, config->tms_ip ());
702 checked_set (_tms_path, config->tms_path ());
703 checked_set (_tms_user, config->tms_user ());
704 checked_set (_tms_password, config->tms_password ());
707 void upload_changed ()
709 Config::instance()->set_upload_after_make_dcp (_upload->GetValue());
712 void tms_protocol_changed ()
714 Config::instance()->set_tms_protocol(static_cast<FileTransferProtocol>(_tms_protocol->GetSelection()));
717 void tms_ip_changed ()
719 Config::instance()->set_tms_ip (wx_to_std (_tms_ip->GetValue ()));
722 void tms_path_changed ()
724 Config::instance()->set_tms_path (wx_to_std (_tms_path->GetValue ()));
727 void tms_user_changed ()
729 Config::instance()->set_tms_user (wx_to_std (_tms_user->GetValue ()));
732 void tms_password_changed ()
734 Config::instance()->set_tms_password (_tms_password->get());
738 wxChoice* _tms_protocol;
740 wxTextCtrl* _tms_path;
741 wxTextCtrl* _tms_user;
742 PasswordEntry* _tms_password;
751 class EmailPage : public StandardPage
754 EmailPage (wxSize panel_size, int border)
755 : StandardPage (panel_size, border)
758 wxString GetName () const
764 wxBitmap GetLargeIcon () const
766 return wxBitmap ("email", wxBITMAP_TYPE_PNG_RESOURCE);
773 wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
774 table->AddGrowableCol (1, 1);
775 _panel->GetSizer()->Add (table, 1, wxEXPAND | wxALL, _border);
777 add_label_to_sizer (table, _panel, _("Outgoing mail server"), true);
779 wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL);
780 _server = new wxTextCtrl (_panel, wxID_ANY);
781 s->Add (_server, 1, wxEXPAND | wxALL);
782 add_label_to_sizer (s, _panel, _("port"), false);
783 _port = new wxSpinCtrl (_panel, wxID_ANY);
784 _port->SetRange (0, 65535);
786 add_label_to_sizer (s, _panel, _("protocol"), false);
787 _protocol = new wxChoice (_panel, wxID_ANY);
788 /* Make sure this matches the switches in config_changed and port_changed below */
789 _protocol->Append (_("Auto"));
790 _protocol->Append (_("Plain"));
791 _protocol->Append (_("STARTTLS"));
792 _protocol->Append (_("SSL"));
794 table->Add (s, 1, wxEXPAND | wxALL);
797 add_label_to_sizer (table, _panel, _("User name"), true);
798 _user = new wxTextCtrl (_panel, wxID_ANY);
799 table->Add (_user, 1, wxEXPAND | wxALL);
801 add_label_to_sizer (table, _panel, _("Password"), true);
802 _password = new PasswordEntry (_panel);
803 table->Add (_password->get_panel(), 1, wxEXPAND | wxALL);
805 _server->Bind (wxEVT_TEXT, boost::bind (&EmailPage::server_changed, this));
806 _port->Bind (wxEVT_SPINCTRL, boost::bind (&EmailPage::port_changed, this));
807 _protocol->Bind (wxEVT_CHOICE, boost::bind (&EmailPage::protocol_changed, this));
808 _user->Bind (wxEVT_TEXT, boost::bind (&EmailPage::user_changed, this));
809 _password->Changed.connect (boost::bind (&EmailPage::password_changed, this));
812 void config_changed ()
814 Config* config = Config::instance ();
816 checked_set (_server, config->mail_server ());
817 checked_set (_port, config->mail_port ());
818 switch (config->mail_protocol()) {
819 case EMAIL_PROTOCOL_AUTO:
820 checked_set (_protocol, 0);
822 case EMAIL_PROTOCOL_PLAIN:
823 checked_set (_protocol, 1);
825 case EMAIL_PROTOCOL_STARTTLS:
826 checked_set (_protocol, 2);
828 case EMAIL_PROTOCOL_SSL:
829 checked_set (_protocol, 3);
832 checked_set (_user, config->mail_user ());
833 checked_set (_password, config->mail_password());
836 void server_changed ()
838 Config::instance()->set_mail_server (wx_to_std (_server->GetValue ()));
843 Config::instance()->set_mail_port (_port->GetValue ());
846 void protocol_changed ()
848 switch (_protocol->GetSelection()) {
850 Config::instance()->set_mail_protocol(EMAIL_PROTOCOL_AUTO);
853 Config::instance()->set_mail_protocol(EMAIL_PROTOCOL_PLAIN);
856 Config::instance()->set_mail_protocol(EMAIL_PROTOCOL_STARTTLS);
859 Config::instance()->set_mail_protocol(EMAIL_PROTOCOL_SSL);
866 Config::instance()->set_mail_user (wx_to_std (_user->GetValue ()));
869 void password_changed ()
871 Config::instance()->set_mail_password(_password->get());
878 PasswordEntry* _password;
881 class KDMEmailPage : public StandardPage
885 KDMEmailPage (wxSize panel_size, int border)
887 /* We have to force both width and height of this one */
888 : StandardPage (wxSize (panel_size.GetWidth(), 128), border)
890 : StandardPage (panel_size, border)
894 wxString GetName () const
896 return _("KDM Email");
900 wxBitmap GetLargeIcon () const
902 return wxBitmap ("kdm_email", wxBITMAP_TYPE_PNG_RESOURCE);
909 wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
910 table->AddGrowableCol (1, 1);
911 _panel->GetSizer()->Add (table, 1, wxEXPAND | wxALL, _border);
913 add_label_to_sizer (table, _panel, _("Subject"), true);
914 _subject = new wxTextCtrl (_panel, wxID_ANY);
915 table->Add (_subject, 1, wxEXPAND | wxALL);
917 add_label_to_sizer (table, _panel, _("From address"), true);
918 _from = new wxTextCtrl (_panel, wxID_ANY);
919 table->Add (_from, 1, wxEXPAND | wxALL);
921 vector<EditableListColumn> columns;
922 columns.push_back (EditableListColumn(wx_to_std(_("Address"))));
923 add_label_to_sizer (table, _panel, _("CC addresses"), true);
924 _cc = new EditableList<string, EmailDialog> (
927 bind (&Config::kdm_cc, Config::instance()),
928 bind (&Config::set_kdm_cc, Config::instance(), _1),
931 table->Add (_cc, 1, wxEXPAND | wxALL);
933 add_label_to_sizer (table, _panel, _("BCC address"), true);
934 _bcc = new wxTextCtrl (_panel, wxID_ANY);
935 table->Add (_bcc, 1, wxEXPAND | wxALL);
937 _email = new wxTextCtrl (_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize (-1, 200), wxTE_MULTILINE);
938 _panel->GetSizer()->Add (_email, 0, wxEXPAND | wxALL, _border);
940 _reset_email = new Button (_panel, _("Reset to default subject and text"));
941 _panel->GetSizer()->Add (_reset_email, 0, wxEXPAND | wxALL, _border);
945 _subject->Bind (wxEVT_TEXT, boost::bind (&KDMEmailPage::kdm_subject_changed, this));
946 _from->Bind (wxEVT_TEXT, boost::bind (&KDMEmailPage::kdm_from_changed, this));
947 _bcc->Bind (wxEVT_TEXT, boost::bind (&KDMEmailPage::kdm_bcc_changed, this));
948 _email->Bind (wxEVT_TEXT, boost::bind (&KDMEmailPage::kdm_email_changed, this));
949 _reset_email->Bind (wxEVT_BUTTON, boost::bind (&KDMEmailPage::reset_email, this));
952 void config_changed ()
954 Config* config = Config::instance ();
956 checked_set (_subject, config->kdm_subject ());
957 checked_set (_from, config->kdm_from ());
958 checked_set (_bcc, config->kdm_bcc ());
959 checked_set (_email, Config::instance()->kdm_email ());
962 void kdm_subject_changed ()
964 Config::instance()->set_kdm_subject (wx_to_std (_subject->GetValue ()));
967 void kdm_from_changed ()
969 Config::instance()->set_kdm_from (wx_to_std (_from->GetValue ()));
972 void kdm_bcc_changed ()
974 Config::instance()->set_kdm_bcc (wx_to_std (_bcc->GetValue ()));
977 void kdm_email_changed ()
979 if (_email->GetValue().IsEmpty ()) {
980 /* Sometimes we get sent an erroneous notification that the email
981 is empty; I don't know why.
985 Config::instance()->set_kdm_email (wx_to_std (_email->GetValue ()));
990 Config::instance()->reset_kdm_email ();
991 checked_set (_email, Config::instance()->kdm_email ());
994 wxTextCtrl* _subject;
996 EditableList<string, EmailDialog>* _cc;
999 wxButton* _reset_email;
1002 class NotificationsPage : public StandardPage
1005 NotificationsPage (wxSize panel_size, int border)
1006 #ifdef DCPOMATIC_OSX
1007 /* We have to force both width and height of this one */
1008 : StandardPage (wxSize (panel_size.GetWidth(), 128), border)
1010 : StandardPage (panel_size, border)
1014 wxString GetName () const
1016 return _("Notifications");
1019 #ifdef DCPOMATIC_OSX
1020 wxBitmap GetLargeIcon () const
1022 return wxBitmap ("notifications", wxBITMAP_TYPE_PNG_RESOURCE);
1029 wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
1030 table->AddGrowableCol (1, 1);
1031 _panel->GetSizer()->Add (table, 1, wxEXPAND | wxALL, _border);
1033 _enable_message_box = new CheckBox (_panel, _("Message box"));
1034 table->Add (_enable_message_box, 1, wxEXPAND | wxALL);
1035 table->AddSpacer (0);
1037 _enable_email = new CheckBox (_panel, _("Email"));
1038 table->Add (_enable_email, 1, wxEXPAND | wxALL);
1039 table->AddSpacer (0);
1041 add_label_to_sizer (table, _panel, _("Subject"), true);
1042 _subject = new wxTextCtrl (_panel, wxID_ANY);
1043 table->Add (_subject, 1, wxEXPAND | wxALL);
1045 add_label_to_sizer (table, _panel, _("From address"), true);
1046 _from = new wxTextCtrl (_panel, wxID_ANY);
1047 table->Add (_from, 1, wxEXPAND | wxALL);
1049 add_label_to_sizer (table, _panel, _("To address"), true);
1050 _to = new wxTextCtrl (_panel, wxID_ANY);
1051 table->Add (_to, 1, wxEXPAND | wxALL);
1053 vector<EditableListColumn> columns;
1054 columns.push_back (EditableListColumn(wx_to_std(_("Address"))));
1055 add_label_to_sizer (table, _panel, _("CC addresses"), true);
1056 _cc = new EditableList<string, EmailDialog> (
1059 bind (&Config::notification_cc, Config::instance()),
1060 bind (&Config::set_notification_cc, Config::instance(), _1),
1063 table->Add (_cc, 1, wxEXPAND | wxALL);
1065 add_label_to_sizer (table, _panel, _("BCC address"), true);
1066 _bcc = new wxTextCtrl (_panel, wxID_ANY);
1067 table->Add (_bcc, 1, wxEXPAND | wxALL);
1069 _email = new wxTextCtrl (_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize (-1, 200), wxTE_MULTILINE);
1070 _panel->GetSizer()->Add (_email, 0, wxEXPAND | wxALL, _border);
1072 _reset_email = new Button (_panel, _("Reset to default subject and text"));
1073 _panel->GetSizer()->Add (_reset_email, 0, wxEXPAND | wxALL, _border);
1077 _enable_message_box->Bind (wxEVT_CHECKBOX, boost::bind (&NotificationsPage::type_changed, this, _enable_message_box, Config::MESSAGE_BOX));
1078 _enable_email->Bind (wxEVT_CHECKBOX, boost::bind (&NotificationsPage::type_changed, this, _enable_email, Config::EMAIL));
1080 _subject->Bind (wxEVT_TEXT, boost::bind (&NotificationsPage::notification_subject_changed, this));
1081 _from->Bind (wxEVT_TEXT, boost::bind (&NotificationsPage::notification_from_changed, this));
1082 _to->Bind (wxEVT_TEXT, boost::bind (&NotificationsPage::notification_to_changed, this));
1083 _bcc->Bind (wxEVT_TEXT, boost::bind (&NotificationsPage::notification_bcc_changed, this));
1084 _email->Bind (wxEVT_TEXT, boost::bind (&NotificationsPage::notification_email_changed, this));
1085 _reset_email->Bind (wxEVT_BUTTON, boost::bind (&NotificationsPage::reset_email, this));
1087 update_sensitivity ();
1090 void update_sensitivity ()
1092 bool const s = _enable_email->GetValue();
1093 _subject->Enable(s);
1099 _reset_email->Enable(s);
1102 void config_changed ()
1104 Config* config = Config::instance ();
1106 checked_set (_enable_message_box, config->notification(Config::MESSAGE_BOX));
1107 checked_set (_enable_email, config->notification(Config::EMAIL));
1108 checked_set (_subject, config->notification_subject ());
1109 checked_set (_from, config->notification_from ());
1110 checked_set (_to, config->notification_to ());
1111 checked_set (_bcc, config->notification_bcc ());
1112 checked_set (_email, Config::instance()->notification_email ());
1114 update_sensitivity ();
1117 void notification_subject_changed ()
1119 Config::instance()->set_notification_subject (wx_to_std (_subject->GetValue ()));
1122 void notification_from_changed ()
1124 Config::instance()->set_notification_from (wx_to_std (_from->GetValue ()));
1127 void notification_to_changed ()
1129 Config::instance()->set_notification_to (wx_to_std (_to->GetValue ()));
1132 void notification_bcc_changed ()
1134 Config::instance()->set_notification_bcc (wx_to_std (_bcc->GetValue ()));
1137 void notification_email_changed ()
1139 if (_email->GetValue().IsEmpty ()) {
1140 /* Sometimes we get sent an erroneous notification that the email
1141 is empty; I don't know why.
1145 Config::instance()->set_notification_email (wx_to_std (_email->GetValue ()));
1150 Config::instance()->reset_notification_email ();
1151 checked_set (_email, Config::instance()->notification_email ());
1154 void type_changed (wxCheckBox* b, Config::Notification n)
1156 Config::instance()->set_notification(n, b->GetValue());
1157 update_sensitivity ();
1160 wxCheckBox* _enable_message_box;
1161 wxCheckBox* _enable_email;
1163 wxTextCtrl* _subject;
1166 EditableList<string, EmailDialog>* _cc;
1169 wxButton* _reset_email;
1172 class CoverSheetPage : public StandardPage
1176 CoverSheetPage (wxSize panel_size, int border)
1177 #ifdef DCPOMATIC_OSX
1178 /* We have to force both width and height of this one */
1179 : StandardPage (wxSize (panel_size.GetWidth(), 128), border)
1181 : StandardPage (panel_size, border)
1185 wxString GetName () const
1187 return _("Cover Sheet");
1190 #ifdef DCPOMATIC_OSX
1191 wxBitmap GetLargeIcon () const
1193 return wxBitmap ("cover_sheet", wxBITMAP_TYPE_PNG_RESOURCE);
1200 _cover_sheet = new wxTextCtrl (_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize (-1, 200), wxTE_MULTILINE);
1201 _panel->GetSizer()->Add (_cover_sheet, 0, wxEXPAND | wxALL, _border);
1203 _reset_cover_sheet = new Button (_panel, _("Reset to default text"));
1204 _panel->GetSizer()->Add (_reset_cover_sheet, 0, wxEXPAND | wxALL, _border);
1206 _cover_sheet->Bind (wxEVT_TEXT, boost::bind (&CoverSheetPage::cover_sheet_changed, this));
1207 _reset_cover_sheet->Bind (wxEVT_BUTTON, boost::bind (&CoverSheetPage::reset_cover_sheet, this));
1210 void config_changed ()
1212 checked_set (_cover_sheet, Config::instance()->cover_sheet ());
1215 void cover_sheet_changed ()
1217 if (_cover_sheet->GetValue().IsEmpty ()) {
1218 /* Sometimes we get sent an erroneous notification that the cover sheet
1219 is empty; I don't know why.
1223 Config::instance()->set_cover_sheet (wx_to_std (_cover_sheet->GetValue ()));
1226 void reset_cover_sheet ()
1228 Config::instance()->reset_cover_sheet ();
1229 checked_set (_cover_sheet, Config::instance()->cover_sheet ());
1232 wxTextCtrl* _cover_sheet;
1233 wxButton* _reset_cover_sheet;
1237 /** @class AdvancedPage
1238 * @brief Advanced page of the preferences dialog.
1240 class AdvancedPage : public StockPage
1243 AdvancedPage (wxSize panel_size, int border)
1244 : StockPage (Kind_Advanced, panel_size, border)
1245 , _maximum_j2k_bandwidth (0)
1246 , _allow_any_dcp_frame_rate (0)
1247 , _allow_any_container (0)
1248 , _show_experimental_audio_processors (0)
1249 , _only_servers_encode (0)
1254 , _log_debug_threed (0)
1255 , _log_debug_encode (0)
1256 , _log_debug_email (0)
1260 void add_top_aligned_label_to_sizer (wxSizer* table, wxWindow* parent, wxString text)
1262 int flags = wxALIGN_TOP | wxTOP | wxLEFT;
1264 flags |= wxALIGN_RIGHT;
1267 wxStaticText* m = new StaticText (parent, text);
1268 table->Add (m, 0, flags, DCPOMATIC_SIZER_Y_GAP);
1273 wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
1274 table->AddGrowableCol (1, 1);
1275 _panel->GetSizer()->Add (table, 1, wxALL | wxEXPAND, _border);
1278 add_label_to_sizer (table, _panel, _("Maximum JPEG2000 bandwidth"), true);
1279 wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL);
1280 _maximum_j2k_bandwidth = new wxSpinCtrl (_panel);
1281 s->Add (_maximum_j2k_bandwidth, 1);
1282 add_label_to_sizer (s, _panel, _("Mbit/s"), false);
1286 add_label_to_sizer (table, _panel, _("Video display mode"), true);
1287 _video_display_mode = new wxChoice (_panel, wxID_ANY);
1288 table->Add (_video_display_mode);
1290 wxStaticText* restart = add_label_to_sizer (table, _panel, _("(restart DCP-o-matic to change display mode)"), false);
1291 wxFont font = restart->GetFont();
1292 font.SetStyle (wxFONTSTYLE_ITALIC);
1293 font.SetPointSize (font.GetPointSize() - 1);
1294 restart->SetFont (font);
1295 table->AddSpacer (0);
1297 _allow_any_dcp_frame_rate = new CheckBox (_panel, _("Allow any DCP frame rate"));
1298 table->Add (_allow_any_dcp_frame_rate, 1, wxEXPAND | wxALL);
1299 table->AddSpacer (0);
1301 _allow_any_container = new CheckBox (_panel, _("Allow full-frame and non-standard container ratios"));
1302 table->Add (_allow_any_container, 1, wxEXPAND | wxALL);
1303 table->AddSpacer (0);
1305 restart = add_label_to_sizer (table, _panel, _("(restart DCP-o-matic to see all ratios)"), false);
1306 restart->SetFont (font);
1307 table->AddSpacer (0);
1309 _show_experimental_audio_processors = new CheckBox (_panel, _("Show experimental audio processors"));
1310 table->Add (_show_experimental_audio_processors, 1, wxEXPAND | wxALL);
1311 table->AddSpacer (0);
1313 _only_servers_encode = new CheckBox (_panel, _("Only servers encode"));
1314 table->Add (_only_servers_encode, 1, wxEXPAND | wxALL);
1315 table->AddSpacer (0);
1318 add_label_to_sizer (table, _panel, _("Maximum number of frames to store per thread"), true);
1319 wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL);
1320 _frames_in_memory_multiplier = new wxSpinCtrl (_panel);
1321 s->Add (_frames_in_memory_multiplier, 1);
1326 add_top_aligned_label_to_sizer (table, _panel, _("DCP metadata filename format"));
1327 dcp::NameFormat::Map titles;
1328 titles['t'] = wx_to_std (_("type (cpl/pkl)"));
1329 dcp::NameFormat::Map examples;
1330 examples['t'] = "cpl";
1331 _dcp_metadata_filename_format = new NameFormatEditor (
1332 _panel, Config::instance()->dcp_metadata_filename_format(), titles, examples, "_eb1c112c-ca3c-4ae6-9263-c6714ff05d64.xml"
1334 table->Add (_dcp_metadata_filename_format->panel(), 1, wxEXPAND | wxALL);
1338 add_top_aligned_label_to_sizer (table, _panel, _("DCP asset filename format"));
1339 dcp::NameFormat::Map titles;
1340 titles['t'] = wx_to_std (_("type (j2c/pcm/sub)"));
1341 titles['r'] = wx_to_std (_("reel number"));
1342 titles['n'] = wx_to_std (_("number of reels"));
1343 titles['c'] = wx_to_std (_("content filename"));
1344 dcp::NameFormat::Map examples;
1345 examples['t'] = "j2c";
1346 examples['r'] = "1";
1347 examples['n'] = "4";
1348 examples['c'] = "myfile.mp4";
1349 _dcp_asset_filename_format = new NameFormatEditor (
1350 _panel, Config::instance()->dcp_asset_filename_format(), titles, examples, "_eb1c112c-ca3c-4ae6-9263-c6714ff05d64.mxf"
1352 table->Add (_dcp_asset_filename_format->panel(), 1, wxEXPAND | wxALL);
1356 add_top_aligned_label_to_sizer (table, _panel, _("Log"));
1357 wxBoxSizer* t = new wxBoxSizer (wxVERTICAL);
1358 _log_general = new CheckBox (_panel, _("General"));
1359 t->Add (_log_general, 1, wxEXPAND | wxALL);
1360 _log_warning = new CheckBox (_panel, _("Warnings"));
1361 t->Add (_log_warning, 1, wxEXPAND | wxALL);
1362 _log_error = new CheckBox (_panel, _("Errors"));
1363 t->Add (_log_error, 1, wxEXPAND | wxALL);
1364 /// TRANSLATORS: translate the word "Timing" here; do not include the "Config|" prefix
1365 _log_timing = new CheckBox (_panel, S_("Config|Timing"));
1366 t->Add (_log_timing, 1, wxEXPAND | wxALL);
1367 _log_debug_threed = new CheckBox (_panel, _("Debug: 3D"));
1368 t->Add (_log_debug_threed, 1, wxEXPAND | wxALL);
1369 _log_debug_encode = new CheckBox (_panel, _("Debug: encode"));
1370 t->Add (_log_debug_encode, 1, wxEXPAND | wxALL);
1371 _log_debug_email = new CheckBox (_panel, _("Debug: email sending"));
1372 t->Add (_log_debug_email, 1, wxEXPAND | wxALL);
1373 table->Add (t, 0, wxALL, 6);
1376 #ifdef DCPOMATIC_WINDOWS
1377 _win32_console = new CheckBox (_panel, _("Open console window"));
1378 table->Add (_win32_console, 1, wxEXPAND | wxALL);
1379 table->AddSpacer (0);
1382 _maximum_j2k_bandwidth->SetRange (1, 1000);
1383 _maximum_j2k_bandwidth->Bind (wxEVT_SPINCTRL, boost::bind (&AdvancedPage::maximum_j2k_bandwidth_changed, this));
1384 _video_display_mode->Append (_("Simple (safer)"));
1385 _video_display_mode->Append (_("OpenGL (faster)"));
1386 _video_display_mode->Bind (wxEVT_CHOICE, boost::bind(&AdvancedPage::video_display_mode_changed, this));
1387 _allow_any_dcp_frame_rate->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::allow_any_dcp_frame_rate_changed, this));
1388 _allow_any_container->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::allow_any_container_changed, this));
1389 _show_experimental_audio_processors->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::show_experimental_audio_processors_changed, this));
1390 _only_servers_encode->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::only_servers_encode_changed, this));
1391 _frames_in_memory_multiplier->Bind (wxEVT_SPINCTRL, boost::bind(&AdvancedPage::frames_in_memory_multiplier_changed, this));
1392 _dcp_metadata_filename_format->Changed.connect (boost::bind (&AdvancedPage::dcp_metadata_filename_format_changed, this));
1393 _dcp_asset_filename_format->Changed.connect (boost::bind (&AdvancedPage::dcp_asset_filename_format_changed, this));
1394 _log_general->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::log_changed, this));
1395 _log_warning->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::log_changed, this));
1396 _log_error->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::log_changed, this));
1397 _log_timing->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::log_changed, this));
1398 _log_debug_threed->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::log_changed, this));
1399 _log_debug_encode->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::log_changed, this));
1400 _log_debug_email->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::log_changed, this));
1401 #ifdef DCPOMATIC_WINDOWS
1402 _win32_console->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::win32_console_changed, this));
1406 void config_changed ()
1408 Config* config = Config::instance ();
1410 checked_set (_maximum_j2k_bandwidth, config->maximum_j2k_bandwidth() / 1000000);
1411 switch (config->video_view_type()) {
1412 case Config::VIDEO_VIEW_SIMPLE:
1413 checked_set (_video_display_mode, 0);
1415 case Config::VIDEO_VIEW_OPENGL:
1416 checked_set (_video_display_mode, 1);
1419 checked_set (_allow_any_dcp_frame_rate, config->allow_any_dcp_frame_rate ());
1420 checked_set (_allow_any_container, config->allow_any_container ());
1421 checked_set (_show_experimental_audio_processors, config->show_experimental_audio_processors ());
1422 checked_set (_only_servers_encode, config->only_servers_encode ());
1423 checked_set (_log_general, config->log_types() & LogEntry::TYPE_GENERAL);
1424 checked_set (_log_warning, config->log_types() & LogEntry::TYPE_WARNING);
1425 checked_set (_log_error, config->log_types() & LogEntry::TYPE_ERROR);
1426 checked_set (_log_timing, config->log_types() & LogEntry::TYPE_TIMING);
1427 checked_set (_log_debug_threed, config->log_types() & LogEntry::TYPE_DEBUG_THREED);
1428 checked_set (_log_debug_encode, config->log_types() & LogEntry::TYPE_DEBUG_ENCODE);
1429 checked_set (_log_debug_email, config->log_types() & LogEntry::TYPE_DEBUG_EMAIL);
1430 checked_set (_frames_in_memory_multiplier, config->frames_in_memory_multiplier());
1431 #ifdef DCPOMATIC_WINDOWS
1432 checked_set (_win32_console, config->win32_console());
1436 void maximum_j2k_bandwidth_changed ()
1438 Config::instance()->set_maximum_j2k_bandwidth (_maximum_j2k_bandwidth->GetValue() * 1000000);
1441 void video_display_mode_changed ()
1443 if (_video_display_mode->GetSelection() == 0) {
1444 Config::instance()->set_video_view_type (Config::VIDEO_VIEW_SIMPLE);
1446 Config::instance()->set_video_view_type (Config::VIDEO_VIEW_OPENGL);
1450 void frames_in_memory_multiplier_changed ()
1452 Config::instance()->set_frames_in_memory_multiplier (_frames_in_memory_multiplier->GetValue());
1455 void allow_any_dcp_frame_rate_changed ()
1457 Config::instance()->set_allow_any_dcp_frame_rate (_allow_any_dcp_frame_rate->GetValue ());
1460 void allow_any_container_changed ()
1462 Config::instance()->set_allow_any_container (_allow_any_container->GetValue ());
1465 void show_experimental_audio_processors_changed ()
1467 Config::instance()->set_show_experimental_audio_processors (_show_experimental_audio_processors->GetValue ());
1470 void only_servers_encode_changed ()
1472 Config::instance()->set_only_servers_encode (_only_servers_encode->GetValue ());
1475 void dcp_metadata_filename_format_changed ()
1477 Config::instance()->set_dcp_metadata_filename_format (_dcp_metadata_filename_format->get ());
1480 void dcp_asset_filename_format_changed ()
1482 Config::instance()->set_dcp_asset_filename_format (_dcp_asset_filename_format->get ());
1488 if (_log_general->GetValue ()) {
1489 types |= LogEntry::TYPE_GENERAL;
1491 if (_log_warning->GetValue ()) {
1492 types |= LogEntry::TYPE_WARNING;
1494 if (_log_error->GetValue ()) {
1495 types |= LogEntry::TYPE_ERROR;
1497 if (_log_timing->GetValue ()) {
1498 types |= LogEntry::TYPE_TIMING;
1500 if (_log_debug_threed->GetValue ()) {
1501 types |= LogEntry::TYPE_DEBUG_THREED;
1503 if (_log_debug_encode->GetValue ()) {
1504 types |= LogEntry::TYPE_DEBUG_ENCODE;
1506 if (_log_debug_email->GetValue ()) {
1507 types |= LogEntry::TYPE_DEBUG_EMAIL;
1509 Config::instance()->set_log_types (types);
1512 #ifdef DCPOMATIC_WINDOWS
1513 void win32_console_changed ()
1515 Config::instance()->set_win32_console (_win32_console->GetValue ());
1519 wxSpinCtrl* _maximum_j2k_bandwidth;
1520 wxChoice* _video_display_mode;
1521 wxSpinCtrl* _frames_in_memory_multiplier;
1522 wxCheckBox* _allow_any_dcp_frame_rate;
1523 wxCheckBox* _allow_any_container;
1524 wxCheckBox* _show_experimental_audio_processors;
1525 wxCheckBox* _only_servers_encode;
1526 NameFormatEditor* _dcp_metadata_filename_format;
1527 NameFormatEditor* _dcp_asset_filename_format;
1528 wxCheckBox* _log_general;
1529 wxCheckBox* _log_warning;
1530 wxCheckBox* _log_error;
1531 wxCheckBox* _log_timing;
1532 wxCheckBox* _log_debug_threed;
1533 wxCheckBox* _log_debug_encode;
1534 wxCheckBox* _log_debug_email;
1535 #ifdef DCPOMATIC_WINDOWS
1536 wxCheckBox* _win32_console;
1540 wxPreferencesEditor*
1541 create_full_config_dialog ()
1543 wxPreferencesEditor* e = new wxPreferencesEditor ();
1545 #ifdef DCPOMATIC_OSX
1546 /* Width that we force some of the config panels to be on OSX so that
1547 the containing window doesn't shrink too much when we select those panels.
1548 This is obviously an unpleasant hack.
1550 wxSize ps = wxSize (700, -1);
1551 int const border = 16;
1553 wxSize ps = wxSize (-1, -1);
1554 int const border = 8;
1557 e->AddPage (new FullGeneralPage (ps, border));
1558 e->AddPage (new SoundPage (ps, border));
1559 e->AddPage (new DefaultsPage (ps, border));
1560 e->AddPage (new EncodingServersPage (ps, border));
1561 e->AddPage (new KeysPage (ps, border));
1562 e->AddPage (new TMSPage (ps, border));
1563 e->AddPage (new EmailPage (ps, border));
1564 e->AddPage (new KDMEmailPage (ps, border));
1565 e->AddPage (new NotificationsPage (ps, border));
1566 e->AddPage (new CoverSheetPage (ps, border));
1567 e->AddPage (new AdvancedPage (ps, border));