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 bottom_table->Add (_issuer, 1, wxALL | wxEXPAND);
138 add_label_to_sizer (bottom_table, _panel, _("Creator"), true);
139 _creator = new wxTextCtrl (_panel, wxID_ANY);
140 bottom_table->Add (_creator, 1, wxALL | wxEXPAND);
142 table->Add (bottom_table, wxGBPosition (r, 0), wxGBSpan (2, 2), wxEXPAND);
145 _config_file->Bind (wxEVT_FILEPICKER_CHANGED, boost::bind (&FullGeneralPage::config_file_changed, this));
146 _cinemas_file->Bind (wxEVT_FILEPICKER_CHANGED, boost::bind (&FullGeneralPage::cinemas_file_changed, this));
148 _interface_complexity->Append (_("Simple"));
149 _interface_complexity->Append (_("Full"));
150 _interface_complexity->Bind (wxEVT_CHOICE, boost::bind(&FullGeneralPage::interface_complexity_changed, this));
152 _master_encoding_threads->SetRange (1, 128);
153 _master_encoding_threads->Bind (wxEVT_SPINCTRL, boost::bind (&FullGeneralPage::master_encoding_threads_changed, this));
154 _server_encoding_threads->SetRange (1, 128);
155 _server_encoding_threads->Bind (wxEVT_SPINCTRL, boost::bind (&FullGeneralPage::server_encoding_threads_changed, this));
156 export_cinemas->Bind (wxEVT_BUTTON, boost::bind (&FullGeneralPage::export_cinemas_file, this));
158 #ifdef DCPOMATIC_HAVE_EBUR128_PATCHED_FFMPEG
159 _analyse_ebur128->Bind (wxEVT_CHECKBOX, boost::bind (&FullGeneralPage::analyse_ebur128_changed, this));
161 _automatic_audio_analysis->Bind (wxEVT_CHECKBOX, boost::bind (&FullGeneralPage::automatic_audio_analysis_changed, this));
163 _issuer->Bind (wxEVT_TEXT, boost::bind (&FullGeneralPage::issuer_changed, this));
164 _creator->Bind (wxEVT_TEXT, boost::bind (&FullGeneralPage::creator_changed, this));
167 void config_changed ()
169 Config* config = Config::instance ();
171 switch (config->interface_complexity()) {
172 case Config::INTERFACE_SIMPLE:
173 checked_set (_interface_complexity, 0);
175 case Config::INTERFACE_FULL:
176 checked_set (_interface_complexity, 1);
179 checked_set (_master_encoding_threads, config->master_encoding_threads ());
180 checked_set (_server_encoding_threads, config->server_encoding_threads ());
181 #ifdef DCPOMATIC_HAVE_EBUR128_PATCHED_FFMPEG
182 checked_set (_analyse_ebur128, config->analyse_ebur128 ());
184 checked_set (_automatic_audio_analysis, config->automatic_audio_analysis ());
185 checked_set (_issuer, config->dcp_issuer ());
186 checked_set (_creator, config->dcp_creator ());
187 checked_set (_config_file, config->config_file());
188 checked_set (_cinemas_file, config->cinemas_file());
190 GeneralPage::config_changed ();
193 void export_cinemas_file ()
195 wxFileDialog* d = new wxFileDialog (
196 _panel, _("Select Cinemas File"), wxEmptyString, wxEmptyString, wxT ("XML files (*.xml)|*.xml"),
197 wxFD_SAVE | wxFD_OVERWRITE_PROMPT
200 if (d->ShowModal () == wxID_OK) {
201 boost::filesystem::copy_file (Config::instance()->cinemas_file(), wx_to_std(d->GetPath()));
206 void interface_complexity_changed ()
208 if (_interface_complexity->GetSelection() == 0) {
209 Config::instance()->set_interface_complexity (Config::INTERFACE_SIMPLE);
211 Config::instance()->set_interface_complexity (Config::INTERFACE_FULL);
216 #ifdef DCPOMATIC_HAVE_EBUR128_PATCHED_FFMPEG
217 void analyse_ebur128_changed ()
219 Config::instance()->set_analyse_ebur128 (_analyse_ebur128->GetValue ());
223 void automatic_audio_analysis_changed ()
225 Config::instance()->set_automatic_audio_analysis (_automatic_audio_analysis->GetValue ());
228 void master_encoding_threads_changed ()
230 Config::instance()->set_master_encoding_threads (_master_encoding_threads->GetValue ());
233 void server_encoding_threads_changed ()
235 Config::instance()->set_server_encoding_threads (_server_encoding_threads->GetValue ());
238 void issuer_changed ()
240 Config::instance()->set_dcp_issuer (wx_to_std (_issuer->GetValue ()));
243 void creator_changed ()
245 Config::instance()->set_dcp_creator (wx_to_std (_creator->GetValue ()));
248 void config_file_changed ()
250 Config* config = Config::instance();
251 boost::filesystem::path new_file = wx_to_std(_config_file->GetPath());
252 if (new_file == config->config_file()) {
255 bool copy_and_link = true;
256 if (boost::filesystem::exists(new_file)) {
257 ConfigMoveDialog* d = new ConfigMoveDialog (_panel, new_file);
258 if (d->ShowModal() == wxID_OK) {
259 copy_and_link = false;
266 if (new_file != config->config_file()) {
267 config->copy_and_link (new_file);
270 config->link (new_file);
274 void cinemas_file_changed ()
276 Config::instance()->set_cinemas_file (wx_to_std (_cinemas_file->GetPath ()));
279 wxChoice* _interface_complexity;
280 wxSpinCtrl* _master_encoding_threads;
281 wxSpinCtrl* _server_encoding_threads;
282 FilePickerCtrl* _config_file;
283 FilePickerCtrl* _cinemas_file;
284 #ifdef DCPOMATIC_HAVE_EBUR128_PATCHED_FFMPEG
285 wxCheckBox* _analyse_ebur128;
287 wxCheckBox* _automatic_audio_analysis;
289 wxTextCtrl* _creator;
292 class DefaultsPage : public StandardPage
295 DefaultsPage (wxSize panel_size, int border)
296 : StandardPage (panel_size, border)
299 wxString GetName () const
301 return _("Defaults");
305 wxBitmap GetLargeIcon () const
307 return wxBitmap ("defaults", wxBITMAP_TYPE_PNG_RESOURCE);
314 wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
315 table->AddGrowableCol (1, 1);
316 _panel->GetSizer()->Add (table, 1, wxALL | wxEXPAND, _border);
319 add_label_to_sizer (table, _panel, _("Default duration of still images"), true);
320 wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL);
321 _still_length = new wxSpinCtrl (_panel);
322 s->Add (_still_length);
323 add_label_to_sizer (s, _panel, _("s"), false);
327 add_label_to_sizer (table, _panel, _("Default directory for new films"), true);
328 #ifdef DCPOMATIC_USE_OWN_PICKER
329 _directory = new DirPickerCtrl (_panel);
331 _directory = new wxDirPickerCtrl (_panel, wxDD_DIR_MUST_EXIST);
333 table->Add (_directory, 1, wxEXPAND);
335 add_label_to_sizer (table, _panel, _("Default ISDCF name details"), true);
336 _isdcf_metadata_button = new Button (_panel, _("Edit..."));
337 table->Add (_isdcf_metadata_button);
339 add_label_to_sizer (table, _panel, _("Default container"), true);
340 _container = new wxChoice (_panel, wxID_ANY);
341 table->Add (_container);
343 add_label_to_sizer (table, _panel, _("Default content type"), true);
344 _dcp_content_type = new wxChoice (_panel, wxID_ANY);
345 table->Add (_dcp_content_type);
347 add_label_to_sizer (table, _panel, _("Default DCP audio channels"), true);
348 _dcp_audio_channels = new wxChoice (_panel, wxID_ANY);
349 table->Add (_dcp_audio_channels);
352 add_label_to_sizer (table, _panel, _("Default JPEG2000 bandwidth"), true);
353 wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL);
354 _j2k_bandwidth = new wxSpinCtrl (_panel);
355 s->Add (_j2k_bandwidth);
356 add_label_to_sizer (s, _panel, _("Mbit/s"), false);
361 add_label_to_sizer (table, _panel, _("Default audio delay"), true);
362 wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL);
363 _audio_delay = new wxSpinCtrl (_panel);
364 s->Add (_audio_delay);
365 add_label_to_sizer (s, _panel, _("ms"), false);
369 add_label_to_sizer (table, _panel, _("Default standard"), true);
370 _standard = new wxChoice (_panel, wxID_ANY);
371 table->Add (_standard);
373 add_label_to_sizer (table, _panel, _("Default KDM directory"), true);
374 #ifdef DCPOMATIC_USE_OWN_PICKER
375 _kdm_directory = new DirPickerCtrl (_panel);
377 _kdm_directory = new wxDirPickerCtrl (_panel, wxDD_DIR_MUST_EXIST);
380 table->Add (_kdm_directory, 1, wxEXPAND);
382 _still_length->SetRange (1, 3600);
383 _still_length->Bind (wxEVT_SPINCTRL, boost::bind (&DefaultsPage::still_length_changed, this));
385 _directory->Bind (wxEVT_DIRPICKER_CHANGED, boost::bind (&DefaultsPage::directory_changed, this));
386 _kdm_directory->Bind (wxEVT_DIRPICKER_CHANGED, boost::bind (&DefaultsPage::kdm_directory_changed, this));
388 _isdcf_metadata_button->Bind (wxEVT_BUTTON, boost::bind (&DefaultsPage::edit_isdcf_metadata_clicked, this));
390 BOOST_FOREACH (Ratio const * i, Ratio::containers()) {
391 _container->Append (std_to_wx(i->container_nickname()));
394 _container->Bind (wxEVT_CHOICE, boost::bind (&DefaultsPage::container_changed, this));
396 BOOST_FOREACH (DCPContentType const * i, DCPContentType::all()) {
397 _dcp_content_type->Append (std_to_wx (i->pretty_name ()));
400 setup_audio_channels_choice (_dcp_audio_channels, 2);
402 _dcp_content_type->Bind (wxEVT_CHOICE, boost::bind (&DefaultsPage::dcp_content_type_changed, this));
403 _dcp_audio_channels->Bind (wxEVT_CHOICE, boost::bind (&DefaultsPage::dcp_audio_channels_changed, this));
405 _j2k_bandwidth->SetRange (50, 250);
406 _j2k_bandwidth->Bind (wxEVT_SPINCTRL, boost::bind (&DefaultsPage::j2k_bandwidth_changed, this));
408 _audio_delay->SetRange (-1000, 1000);
409 _audio_delay->Bind (wxEVT_SPINCTRL, boost::bind (&DefaultsPage::audio_delay_changed, this));
411 _standard->Append (_("SMPTE"));
412 _standard->Append (_("Interop"));
413 _standard->Bind (wxEVT_CHOICE, boost::bind (&DefaultsPage::standard_changed, this));
416 void config_changed ()
418 Config* config = Config::instance ();
420 vector<Ratio const *> containers = Ratio::containers ();
421 for (size_t i = 0; i < containers.size(); ++i) {
422 if (containers[i] == config->default_container ()) {
423 _container->SetSelection (i);
427 vector<DCPContentType const *> const ct = DCPContentType::all ();
428 for (size_t i = 0; i < ct.size(); ++i) {
429 if (ct[i] == config->default_dcp_content_type ()) {
430 _dcp_content_type->SetSelection (i);
434 checked_set (_still_length, config->default_still_length ());
435 _directory->SetPath (std_to_wx (config->default_directory_or (wx_to_std (wxStandardPaths::Get().GetDocumentsDir())).string ()));
436 _kdm_directory->SetPath (std_to_wx (config->default_kdm_directory_or (wx_to_std (wxStandardPaths::Get().GetDocumentsDir())).string ()));
437 checked_set (_j2k_bandwidth, config->default_j2k_bandwidth() / 1000000);
438 _j2k_bandwidth->SetRange (50, config->maximum_j2k_bandwidth() / 1000000);
439 checked_set (_dcp_audio_channels, locale_convert<string> (config->default_dcp_audio_channels()));
440 checked_set (_audio_delay, config->default_audio_delay ());
441 checked_set (_standard, config->default_interop() ? 1 : 0);
444 void j2k_bandwidth_changed ()
446 Config::instance()->set_default_j2k_bandwidth (_j2k_bandwidth->GetValue() * 1000000);
449 void audio_delay_changed ()
451 Config::instance()->set_default_audio_delay (_audio_delay->GetValue());
454 void dcp_audio_channels_changed ()
456 int const s = _dcp_audio_channels->GetSelection ();
457 if (s != wxNOT_FOUND) {
458 Config::instance()->set_default_dcp_audio_channels (
459 locale_convert<int> (string_client_data (_dcp_audio_channels->GetClientObject (s)))
464 void directory_changed ()
466 Config::instance()->set_default_directory (wx_to_std (_directory->GetPath ()));
469 void kdm_directory_changed ()
471 Config::instance()->set_default_kdm_directory (wx_to_std (_kdm_directory->GetPath ()));
474 void edit_isdcf_metadata_clicked ()
476 ISDCFMetadataDialog* d = new ISDCFMetadataDialog (_panel, Config::instance()->default_isdcf_metadata (), false);
478 Config::instance()->set_default_isdcf_metadata (d->isdcf_metadata ());
482 void still_length_changed ()
484 Config::instance()->set_default_still_length (_still_length->GetValue ());
487 void container_changed ()
489 vector<Ratio const *> ratio = Ratio::containers ();
490 Config::instance()->set_default_container (ratio[_container->GetSelection()]);
493 void dcp_content_type_changed ()
495 vector<DCPContentType const *> ct = DCPContentType::all ();
496 Config::instance()->set_default_dcp_content_type (ct[_dcp_content_type->GetSelection()]);
499 void standard_changed ()
501 Config::instance()->set_default_interop (_standard->GetSelection() == 1);
504 wxSpinCtrl* _j2k_bandwidth;
505 wxSpinCtrl* _audio_delay;
506 wxButton* _isdcf_metadata_button;
507 wxSpinCtrl* _still_length;
508 #ifdef DCPOMATIC_USE_OWN_PICKER
509 DirPickerCtrl* _directory;
510 DirPickerCtrl* _kdm_directory;
512 wxDirPickerCtrl* _directory;
513 wxDirPickerCtrl* _kdm_directory;
515 wxChoice* _container;
516 wxChoice* _dcp_content_type;
517 wxChoice* _dcp_audio_channels;
521 class EncodingServersPage : public StandardPage
524 EncodingServersPage (wxSize panel_size, int border)
525 : StandardPage (panel_size, border)
528 wxString GetName () const
534 wxBitmap GetLargeIcon () const
536 return wxBitmap ("servers", wxBITMAP_TYPE_PNG_RESOURCE);
543 _use_any_servers = new CheckBox (_panel, _("Search network for servers"));
544 _panel->GetSizer()->Add (_use_any_servers, 0, wxALL, _border);
546 vector<EditableListColumn> columns;
547 columns.push_back (EditableListColumn(wx_to_std(_("IP address / host name"))));
548 _servers_list = new EditableList<string, ServerDialog> (
551 boost::bind (&Config::servers, Config::instance()),
552 boost::bind (&Config::set_servers, Config::instance(), _1),
553 boost::bind (&EncodingServersPage::server_column, this, _1)
556 _panel->GetSizer()->Add (_servers_list, 1, wxEXPAND | wxALL, _border);
558 _use_any_servers->Bind (wxEVT_CHECKBOX, boost::bind (&EncodingServersPage::use_any_servers_changed, this));
561 void config_changed ()
563 checked_set (_use_any_servers, Config::instance()->use_any_servers ());
564 _servers_list->refresh ();
567 void use_any_servers_changed ()
569 Config::instance()->set_use_any_servers (_use_any_servers->GetValue ());
572 string server_column (string s)
577 wxCheckBox* _use_any_servers;
578 EditableList<string, ServerDialog>* _servers_list;
581 class TMSPage : public StandardPage
584 TMSPage (wxSize panel_size, int border)
585 : StandardPage (panel_size, border)
588 wxString GetName () const
594 wxBitmap GetLargeIcon () const
596 return wxBitmap ("tms", wxBITMAP_TYPE_PNG_RESOURCE);
603 _upload = new CheckBox (_panel, _("Upload DCP to TMS after creation"));
604 _panel->GetSizer()->Add (_upload, 0, wxALL | wxEXPAND, _border);
606 wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
607 table->AddGrowableCol (1, 1);
608 _panel->GetSizer()->Add (table, 1, wxALL | wxEXPAND, _border);
610 add_label_to_sizer (table, _panel, _("Protocol"), true);
611 _tms_protocol = new wxChoice (_panel, wxID_ANY);
612 table->Add (_tms_protocol, 1, wxEXPAND);
614 add_label_to_sizer (table, _panel, _("IP address"), true);
615 _tms_ip = new wxTextCtrl (_panel, wxID_ANY);
616 table->Add (_tms_ip, 1, wxEXPAND);
618 add_label_to_sizer (table, _panel, _("Target path"), true);
619 _tms_path = new wxTextCtrl (_panel, wxID_ANY);
620 table->Add (_tms_path, 1, wxEXPAND);
622 add_label_to_sizer (table, _panel, _("User name"), true);
623 _tms_user = new wxTextCtrl (_panel, wxID_ANY);
624 table->Add (_tms_user, 1, wxEXPAND);
626 add_label_to_sizer (table, _panel, _("Password"), true);
627 _tms_password = new PasswordEntry (_panel);
628 table->Add (_tms_password->get_panel(), 1, wxEXPAND);
630 _tms_protocol->Append (_("SCP (for AAM and Doremi)"));
631 _tms_protocol->Append (_("FTP (for Dolby)"));
633 _upload->Bind (wxEVT_CHECKBOX, boost::bind(&TMSPage::upload_changed, this));
634 _tms_protocol->Bind (wxEVT_CHOICE, boost::bind (&TMSPage::tms_protocol_changed, this));
635 _tms_ip->Bind (wxEVT_TEXT, boost::bind (&TMSPage::tms_ip_changed, this));
636 _tms_path->Bind (wxEVT_TEXT, boost::bind (&TMSPage::tms_path_changed, this));
637 _tms_user->Bind (wxEVT_TEXT, boost::bind (&TMSPage::tms_user_changed, this));
638 _tms_password->Changed.connect (boost::bind (&TMSPage::tms_password_changed, this));
641 void config_changed ()
643 Config* config = Config::instance ();
645 checked_set (_upload, config->upload_after_make_dcp());
646 checked_set (_tms_protocol, config->tms_protocol ());
647 checked_set (_tms_ip, config->tms_ip ());
648 checked_set (_tms_path, config->tms_path ());
649 checked_set (_tms_user, config->tms_user ());
650 checked_set (_tms_password, config->tms_password ());
653 void upload_changed ()
655 Config::instance()->set_upload_after_make_dcp (_upload->GetValue());
658 void tms_protocol_changed ()
660 Config::instance()->set_tms_protocol(static_cast<FileTransferProtocol>(_tms_protocol->GetSelection()));
663 void tms_ip_changed ()
665 Config::instance()->set_tms_ip (wx_to_std (_tms_ip->GetValue ()));
668 void tms_path_changed ()
670 Config::instance()->set_tms_path (wx_to_std (_tms_path->GetValue ()));
673 void tms_user_changed ()
675 Config::instance()->set_tms_user (wx_to_std (_tms_user->GetValue ()));
678 void tms_password_changed ()
680 Config::instance()->set_tms_password (_tms_password->get());
684 wxChoice* _tms_protocol;
686 wxTextCtrl* _tms_path;
687 wxTextCtrl* _tms_user;
688 PasswordEntry* _tms_password;
697 class EmailPage : public StandardPage
700 EmailPage (wxSize panel_size, int border)
701 : StandardPage (panel_size, border)
704 wxString GetName () const
710 wxBitmap GetLargeIcon () const
712 return wxBitmap ("email", wxBITMAP_TYPE_PNG_RESOURCE);
719 wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
720 table->AddGrowableCol (1, 1);
721 _panel->GetSizer()->Add (table, 1, wxEXPAND | wxALL, _border);
723 add_label_to_sizer (table, _panel, _("Outgoing mail server"), true);
725 wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL);
726 _server = new wxTextCtrl (_panel, wxID_ANY);
727 s->Add (_server, 1, wxEXPAND | wxALL);
728 add_label_to_sizer (s, _panel, _("port"), false);
729 _port = new wxSpinCtrl (_panel, wxID_ANY);
730 _port->SetRange (0, 65535);
732 add_label_to_sizer (s, _panel, _("protocol"), false);
733 _protocol = new wxChoice (_panel, wxID_ANY);
734 /* Make sure this matches the switches in config_changed and port_changed below */
735 _protocol->Append (_("Auto"));
736 _protocol->Append (_("Plain"));
737 _protocol->Append (_("STARTTLS"));
738 _protocol->Append (_("SSL"));
740 table->Add (s, 1, wxEXPAND | wxALL);
743 add_label_to_sizer (table, _panel, _("User name"), true);
744 _user = new wxTextCtrl (_panel, wxID_ANY);
745 table->Add (_user, 1, wxEXPAND | wxALL);
747 add_label_to_sizer (table, _panel, _("Password"), true);
748 _password = new PasswordEntry (_panel);
749 table->Add (_password->get_panel(), 1, wxEXPAND | wxALL);
751 _server->Bind (wxEVT_TEXT, boost::bind (&EmailPage::server_changed, this));
752 _port->Bind (wxEVT_SPINCTRL, boost::bind (&EmailPage::port_changed, this));
753 _protocol->Bind (wxEVT_CHOICE, boost::bind (&EmailPage::protocol_changed, this));
754 _user->Bind (wxEVT_TEXT, boost::bind (&EmailPage::user_changed, this));
755 _password->Changed.connect (boost::bind (&EmailPage::password_changed, this));
758 void config_changed ()
760 Config* config = Config::instance ();
762 checked_set (_server, config->mail_server ());
763 checked_set (_port, config->mail_port ());
764 switch (config->mail_protocol()) {
765 case EMAIL_PROTOCOL_AUTO:
766 checked_set (_protocol, 0);
768 case EMAIL_PROTOCOL_PLAIN:
769 checked_set (_protocol, 1);
771 case EMAIL_PROTOCOL_STARTTLS:
772 checked_set (_protocol, 2);
774 case EMAIL_PROTOCOL_SSL:
775 checked_set (_protocol, 3);
778 checked_set (_user, config->mail_user ());
779 checked_set (_password, config->mail_password());
782 void server_changed ()
784 Config::instance()->set_mail_server (wx_to_std (_server->GetValue ()));
789 Config::instance()->set_mail_port (_port->GetValue ());
792 void protocol_changed ()
794 switch (_protocol->GetSelection()) {
796 Config::instance()->set_mail_protocol(EMAIL_PROTOCOL_AUTO);
799 Config::instance()->set_mail_protocol(EMAIL_PROTOCOL_PLAIN);
802 Config::instance()->set_mail_protocol(EMAIL_PROTOCOL_STARTTLS);
805 Config::instance()->set_mail_protocol(EMAIL_PROTOCOL_SSL);
812 Config::instance()->set_mail_user (wx_to_std (_user->GetValue ()));
815 void password_changed ()
817 Config::instance()->set_mail_password(_password->get());
824 PasswordEntry* _password;
827 class KDMEmailPage : public StandardPage
831 KDMEmailPage (wxSize panel_size, int border)
833 /* We have to force both width and height of this one */
834 : StandardPage (wxSize (panel_size.GetWidth(), 128), border)
836 : StandardPage (panel_size, border)
840 wxString GetName () const
842 return _("KDM Email");
846 wxBitmap GetLargeIcon () const
848 return wxBitmap ("kdm_email", wxBITMAP_TYPE_PNG_RESOURCE);
855 wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
856 table->AddGrowableCol (1, 1);
857 _panel->GetSizer()->Add (table, 1, wxEXPAND | wxALL, _border);
859 add_label_to_sizer (table, _panel, _("Subject"), true);
860 _subject = new wxTextCtrl (_panel, wxID_ANY);
861 table->Add (_subject, 1, wxEXPAND | wxALL);
863 add_label_to_sizer (table, _panel, _("From address"), true);
864 _from = new wxTextCtrl (_panel, wxID_ANY);
865 table->Add (_from, 1, wxEXPAND | wxALL);
867 vector<EditableListColumn> columns;
868 columns.push_back (EditableListColumn(wx_to_std(_("Address"))));
869 add_label_to_sizer (table, _panel, _("CC addresses"), true);
870 _cc = new EditableList<string, EmailDialog> (
873 bind (&Config::kdm_cc, Config::instance()),
874 bind (&Config::set_kdm_cc, Config::instance(), _1),
877 table->Add (_cc, 1, wxEXPAND | wxALL);
879 add_label_to_sizer (table, _panel, _("BCC address"), true);
880 _bcc = new wxTextCtrl (_panel, wxID_ANY);
881 table->Add (_bcc, 1, wxEXPAND | wxALL);
883 _email = new wxTextCtrl (_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize (-1, 200), wxTE_MULTILINE);
884 _panel->GetSizer()->Add (_email, 0, wxEXPAND | wxALL, _border);
886 _reset_email = new Button (_panel, _("Reset to default subject and text"));
887 _panel->GetSizer()->Add (_reset_email, 0, wxEXPAND | wxALL, _border);
891 _subject->Bind (wxEVT_TEXT, boost::bind (&KDMEmailPage::kdm_subject_changed, this));
892 _from->Bind (wxEVT_TEXT, boost::bind (&KDMEmailPage::kdm_from_changed, this));
893 _bcc->Bind (wxEVT_TEXT, boost::bind (&KDMEmailPage::kdm_bcc_changed, this));
894 _email->Bind (wxEVT_TEXT, boost::bind (&KDMEmailPage::kdm_email_changed, this));
895 _reset_email->Bind (wxEVT_BUTTON, boost::bind (&KDMEmailPage::reset_email, this));
898 void config_changed ()
900 Config* config = Config::instance ();
902 checked_set (_subject, config->kdm_subject ());
903 checked_set (_from, config->kdm_from ());
904 checked_set (_bcc, config->kdm_bcc ());
905 checked_set (_email, Config::instance()->kdm_email ());
908 void kdm_subject_changed ()
910 Config::instance()->set_kdm_subject (wx_to_std (_subject->GetValue ()));
913 void kdm_from_changed ()
915 Config::instance()->set_kdm_from (wx_to_std (_from->GetValue ()));
918 void kdm_bcc_changed ()
920 Config::instance()->set_kdm_bcc (wx_to_std (_bcc->GetValue ()));
923 void kdm_email_changed ()
925 if (_email->GetValue().IsEmpty ()) {
926 /* Sometimes we get sent an erroneous notification that the email
927 is empty; I don't know why.
931 Config::instance()->set_kdm_email (wx_to_std (_email->GetValue ()));
936 Config::instance()->reset_kdm_email ();
937 checked_set (_email, Config::instance()->kdm_email ());
940 wxTextCtrl* _subject;
942 EditableList<string, EmailDialog>* _cc;
945 wxButton* _reset_email;
948 class NotificationsPage : public StandardPage
951 NotificationsPage (wxSize panel_size, int border)
953 /* We have to force both width and height of this one */
954 : StandardPage (wxSize (panel_size.GetWidth(), 128), border)
956 : StandardPage (panel_size, border)
960 wxString GetName () const
962 return _("Notifications");
966 wxBitmap GetLargeIcon () const
968 return wxBitmap ("notifications", wxBITMAP_TYPE_PNG_RESOURCE);
975 wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
976 table->AddGrowableCol (1, 1);
977 _panel->GetSizer()->Add (table, 1, wxEXPAND | wxALL, _border);
979 _enable_message_box = new CheckBox (_panel, _("Message box"));
980 table->Add (_enable_message_box, 1, wxEXPAND | wxALL);
981 table->AddSpacer (0);
983 _enable_email = new CheckBox (_panel, _("Email"));
984 table->Add (_enable_email, 1, wxEXPAND | wxALL);
985 table->AddSpacer (0);
987 add_label_to_sizer (table, _panel, _("Subject"), true);
988 _subject = new wxTextCtrl (_panel, wxID_ANY);
989 table->Add (_subject, 1, wxEXPAND | wxALL);
991 add_label_to_sizer (table, _panel, _("From address"), true);
992 _from = new wxTextCtrl (_panel, wxID_ANY);
993 table->Add (_from, 1, wxEXPAND | wxALL);
995 add_label_to_sizer (table, _panel, _("To address"), true);
996 _to = new wxTextCtrl (_panel, wxID_ANY);
997 table->Add (_to, 1, wxEXPAND | wxALL);
999 vector<EditableListColumn> columns;
1000 columns.push_back (EditableListColumn(wx_to_std(_("Address"))));
1001 add_label_to_sizer (table, _panel, _("CC addresses"), true);
1002 _cc = new EditableList<string, EmailDialog> (
1005 bind (&Config::notification_cc, Config::instance()),
1006 bind (&Config::set_notification_cc, Config::instance(), _1),
1009 table->Add (_cc, 1, wxEXPAND | wxALL);
1011 add_label_to_sizer (table, _panel, _("BCC address"), true);
1012 _bcc = new wxTextCtrl (_panel, wxID_ANY);
1013 table->Add (_bcc, 1, wxEXPAND | wxALL);
1015 _email = new wxTextCtrl (_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize (-1, 200), wxTE_MULTILINE);
1016 _panel->GetSizer()->Add (_email, 0, wxEXPAND | wxALL, _border);
1018 _reset_email = new Button (_panel, _("Reset to default subject and text"));
1019 _panel->GetSizer()->Add (_reset_email, 0, wxEXPAND | wxALL, _border);
1023 _enable_message_box->Bind (wxEVT_CHECKBOX, boost::bind (&NotificationsPage::type_changed, this, _enable_message_box, Config::MESSAGE_BOX));
1024 _enable_email->Bind (wxEVT_CHECKBOX, boost::bind (&NotificationsPage::type_changed, this, _enable_email, Config::EMAIL));
1026 _subject->Bind (wxEVT_TEXT, boost::bind (&NotificationsPage::notification_subject_changed, this));
1027 _from->Bind (wxEVT_TEXT, boost::bind (&NotificationsPage::notification_from_changed, this));
1028 _to->Bind (wxEVT_TEXT, boost::bind (&NotificationsPage::notification_to_changed, this));
1029 _bcc->Bind (wxEVT_TEXT, boost::bind (&NotificationsPage::notification_bcc_changed, this));
1030 _email->Bind (wxEVT_TEXT, boost::bind (&NotificationsPage::notification_email_changed, this));
1031 _reset_email->Bind (wxEVT_BUTTON, boost::bind (&NotificationsPage::reset_email, this));
1033 update_sensitivity ();
1036 void update_sensitivity ()
1038 bool const s = _enable_email->GetValue();
1039 _subject->Enable(s);
1045 _reset_email->Enable(s);
1048 void config_changed ()
1050 Config* config = Config::instance ();
1052 checked_set (_enable_message_box, config->notification(Config::MESSAGE_BOX));
1053 checked_set (_enable_email, config->notification(Config::EMAIL));
1054 checked_set (_subject, config->notification_subject ());
1055 checked_set (_from, config->notification_from ());
1056 checked_set (_to, config->notification_to ());
1057 checked_set (_bcc, config->notification_bcc ());
1058 checked_set (_email, Config::instance()->notification_email ());
1060 update_sensitivity ();
1063 void notification_subject_changed ()
1065 Config::instance()->set_notification_subject (wx_to_std (_subject->GetValue ()));
1068 void notification_from_changed ()
1070 Config::instance()->set_notification_from (wx_to_std (_from->GetValue ()));
1073 void notification_to_changed ()
1075 Config::instance()->set_notification_to (wx_to_std (_to->GetValue ()));
1078 void notification_bcc_changed ()
1080 Config::instance()->set_notification_bcc (wx_to_std (_bcc->GetValue ()));
1083 void notification_email_changed ()
1085 if (_email->GetValue().IsEmpty ()) {
1086 /* Sometimes we get sent an erroneous notification that the email
1087 is empty; I don't know why.
1091 Config::instance()->set_notification_email (wx_to_std (_email->GetValue ()));
1096 Config::instance()->reset_notification_email ();
1097 checked_set (_email, Config::instance()->notification_email ());
1100 void type_changed (wxCheckBox* b, Config::Notification n)
1102 Config::instance()->set_notification(n, b->GetValue());
1103 update_sensitivity ();
1106 wxCheckBox* _enable_message_box;
1107 wxCheckBox* _enable_email;
1109 wxTextCtrl* _subject;
1112 EditableList<string, EmailDialog>* _cc;
1115 wxButton* _reset_email;
1118 class CoverSheetPage : public StandardPage
1122 CoverSheetPage (wxSize panel_size, int border)
1123 #ifdef DCPOMATIC_OSX
1124 /* We have to force both width and height of this one */
1125 : StandardPage (wxSize (panel_size.GetWidth(), 128), border)
1127 : StandardPage (panel_size, border)
1131 wxString GetName () const
1133 return _("Cover Sheet");
1136 #ifdef DCPOMATIC_OSX
1137 wxBitmap GetLargeIcon () const
1139 return wxBitmap ("cover_sheet", wxBITMAP_TYPE_PNG_RESOURCE);
1146 _cover_sheet = new wxTextCtrl (_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize (-1, 200), wxTE_MULTILINE);
1147 _panel->GetSizer()->Add (_cover_sheet, 0, wxEXPAND | wxALL, _border);
1149 _reset_cover_sheet = new Button (_panel, _("Reset to default text"));
1150 _panel->GetSizer()->Add (_reset_cover_sheet, 0, wxEXPAND | wxALL, _border);
1152 _cover_sheet->Bind (wxEVT_TEXT, boost::bind (&CoverSheetPage::cover_sheet_changed, this));
1153 _reset_cover_sheet->Bind (wxEVT_BUTTON, boost::bind (&CoverSheetPage::reset_cover_sheet, this));
1156 void config_changed ()
1158 checked_set (_cover_sheet, Config::instance()->cover_sheet ());
1161 void cover_sheet_changed ()
1163 if (_cover_sheet->GetValue().IsEmpty ()) {
1164 /* Sometimes we get sent an erroneous notification that the cover sheet
1165 is empty; I don't know why.
1169 Config::instance()->set_cover_sheet (wx_to_std (_cover_sheet->GetValue ()));
1172 void reset_cover_sheet ()
1174 Config::instance()->reset_cover_sheet ();
1175 checked_set (_cover_sheet, Config::instance()->cover_sheet ());
1178 wxTextCtrl* _cover_sheet;
1179 wxButton* _reset_cover_sheet;
1183 /** @class AdvancedPage
1184 * @brief Advanced page of the preferences dialog.
1186 class AdvancedPage : public StockPage
1189 AdvancedPage (wxSize panel_size, int border)
1190 : StockPage (Kind_Advanced, panel_size, border)
1191 , _maximum_j2k_bandwidth (0)
1192 , _allow_any_dcp_frame_rate (0)
1193 , _allow_any_container (0)
1194 , _show_experimental_audio_processors (0)
1195 , _only_servers_encode (0)
1200 , _log_debug_threed (0)
1201 , _log_debug_encode (0)
1202 , _log_debug_email (0)
1206 void add_top_aligned_label_to_sizer (wxSizer* table, wxWindow* parent, wxString text)
1208 int flags = wxALIGN_TOP | wxTOP | wxLEFT;
1210 flags |= wxALIGN_RIGHT;
1213 wxStaticText* m = new StaticText (parent, text);
1214 table->Add (m, 0, flags, DCPOMATIC_SIZER_Y_GAP);
1219 wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
1220 table->AddGrowableCol (1, 1);
1221 _panel->GetSizer()->Add (table, 1, wxALL | wxEXPAND, _border);
1224 add_label_to_sizer (table, _panel, _("Maximum JPEG2000 bandwidth"), true);
1225 wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL);
1226 _maximum_j2k_bandwidth = new wxSpinCtrl (_panel);
1227 s->Add (_maximum_j2k_bandwidth, 1);
1228 add_label_to_sizer (s, _panel, _("Mbit/s"), false);
1232 add_label_to_sizer (table, _panel, _("Video display mode"), true);
1233 _video_display_mode = new wxChoice (_panel, wxID_ANY);
1234 table->Add (_video_display_mode);
1236 wxStaticText* restart = add_label_to_sizer (table, _panel, _("(restart DCP-o-matic to change display mode)"), false);
1237 wxFont font = restart->GetFont();
1238 font.SetStyle (wxFONTSTYLE_ITALIC);
1239 font.SetPointSize (font.GetPointSize() - 1);
1240 restart->SetFont (font);
1241 table->AddSpacer (0);
1243 _allow_any_dcp_frame_rate = new CheckBox (_panel, _("Allow any DCP frame rate"));
1244 table->Add (_allow_any_dcp_frame_rate, 1, wxEXPAND | wxALL);
1245 table->AddSpacer (0);
1247 _allow_any_container = new CheckBox (_panel, _("Allow full-frame and non-standard container ratios"));
1248 table->Add (_allow_any_container, 1, wxEXPAND | wxALL);
1249 table->AddSpacer (0);
1251 restart = add_label_to_sizer (table, _panel, _("(restart DCP-o-matic to see all ratios)"), false);
1252 restart->SetFont (font);
1253 table->AddSpacer (0);
1255 _show_experimental_audio_processors = new CheckBox (_panel, _("Show experimental audio processors"));
1256 table->Add (_show_experimental_audio_processors, 1, wxEXPAND | wxALL);
1257 table->AddSpacer (0);
1259 _only_servers_encode = new CheckBox (_panel, _("Only servers encode"));
1260 table->Add (_only_servers_encode, 1, wxEXPAND | wxALL);
1261 table->AddSpacer (0);
1264 add_label_to_sizer (table, _panel, _("Maximum number of frames to store per thread"), true);
1265 wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL);
1266 _frames_in_memory_multiplier = new wxSpinCtrl (_panel);
1267 s->Add (_frames_in_memory_multiplier, 1);
1272 add_top_aligned_label_to_sizer (table, _panel, _("DCP metadata filename format"));
1273 dcp::NameFormat::Map titles;
1274 titles['t'] = wx_to_std (_("type (cpl/pkl)"));
1275 dcp::NameFormat::Map examples;
1276 examples['t'] = "cpl";
1277 _dcp_metadata_filename_format = new NameFormatEditor (
1278 _panel, Config::instance()->dcp_metadata_filename_format(), titles, examples, "_eb1c112c-ca3c-4ae6-9263-c6714ff05d64.xml"
1280 table->Add (_dcp_metadata_filename_format->panel(), 1, wxEXPAND | wxALL);
1284 add_top_aligned_label_to_sizer (table, _panel, _("DCP asset filename format"));
1285 dcp::NameFormat::Map titles;
1286 titles['t'] = wx_to_std (_("type (j2c/pcm/sub)"));
1287 titles['r'] = wx_to_std (_("reel number"));
1288 titles['n'] = wx_to_std (_("number of reels"));
1289 titles['c'] = wx_to_std (_("content filename"));
1290 dcp::NameFormat::Map examples;
1291 examples['t'] = "j2c";
1292 examples['r'] = "1";
1293 examples['n'] = "4";
1294 examples['c'] = "myfile.mp4";
1295 _dcp_asset_filename_format = new NameFormatEditor (
1296 _panel, Config::instance()->dcp_asset_filename_format(), titles, examples, "_eb1c112c-ca3c-4ae6-9263-c6714ff05d64.mxf"
1298 table->Add (_dcp_asset_filename_format->panel(), 1, wxEXPAND | wxALL);
1302 add_top_aligned_label_to_sizer (table, _panel, _("Log"));
1303 wxBoxSizer* t = new wxBoxSizer (wxVERTICAL);
1304 _log_general = new CheckBox (_panel, _("General"));
1305 t->Add (_log_general, 1, wxEXPAND | wxALL);
1306 _log_warning = new CheckBox (_panel, _("Warnings"));
1307 t->Add (_log_warning, 1, wxEXPAND | wxALL);
1308 _log_error = new CheckBox (_panel, _("Errors"));
1309 t->Add (_log_error, 1, wxEXPAND | wxALL);
1310 /// TRANSLATORS: translate the word "Timing" here; do not include the "Config|" prefix
1311 _log_timing = new CheckBox (_panel, S_("Config|Timing"));
1312 t->Add (_log_timing, 1, wxEXPAND | wxALL);
1313 _log_debug_threed = new CheckBox (_panel, _("Debug: 3D"));
1314 t->Add (_log_debug_threed, 1, wxEXPAND | wxALL);
1315 _log_debug_encode = new CheckBox (_panel, _("Debug: encode"));
1316 t->Add (_log_debug_encode, 1, wxEXPAND | wxALL);
1317 _log_debug_email = new CheckBox (_panel, _("Debug: email sending"));
1318 t->Add (_log_debug_email, 1, wxEXPAND | wxALL);
1319 table->Add (t, 0, wxALL, 6);
1322 #ifdef DCPOMATIC_WINDOWS
1323 _win32_console = new CheckBox (_panel, _("Open console window"));
1324 table->Add (_win32_console, 1, wxEXPAND | wxALL);
1325 table->AddSpacer (0);
1328 _maximum_j2k_bandwidth->SetRange (1, 1000);
1329 _maximum_j2k_bandwidth->Bind (wxEVT_SPINCTRL, boost::bind (&AdvancedPage::maximum_j2k_bandwidth_changed, this));
1330 _video_display_mode->Append (_("Simple (safer)"));
1331 _video_display_mode->Append (_("OpenGL (faster)"));
1332 _video_display_mode->Bind (wxEVT_CHOICE, boost::bind(&AdvancedPage::video_display_mode_changed, this));
1333 _allow_any_dcp_frame_rate->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::allow_any_dcp_frame_rate_changed, this));
1334 _allow_any_container->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::allow_any_container_changed, this));
1335 _show_experimental_audio_processors->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::show_experimental_audio_processors_changed, this));
1336 _only_servers_encode->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::only_servers_encode_changed, this));
1337 _frames_in_memory_multiplier->Bind (wxEVT_SPINCTRL, boost::bind(&AdvancedPage::frames_in_memory_multiplier_changed, this));
1338 _dcp_metadata_filename_format->Changed.connect (boost::bind (&AdvancedPage::dcp_metadata_filename_format_changed, this));
1339 _dcp_asset_filename_format->Changed.connect (boost::bind (&AdvancedPage::dcp_asset_filename_format_changed, this));
1340 _log_general->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::log_changed, this));
1341 _log_warning->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::log_changed, this));
1342 _log_error->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::log_changed, this));
1343 _log_timing->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::log_changed, this));
1344 _log_debug_threed->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::log_changed, this));
1345 _log_debug_encode->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::log_changed, this));
1346 _log_debug_email->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::log_changed, this));
1347 #ifdef DCPOMATIC_WINDOWS
1348 _win32_console->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::win32_console_changed, this));
1352 void config_changed ()
1354 Config* config = Config::instance ();
1356 checked_set (_maximum_j2k_bandwidth, config->maximum_j2k_bandwidth() / 1000000);
1357 switch (config->video_view_type()) {
1358 case Config::VIDEO_VIEW_SIMPLE:
1359 checked_set (_video_display_mode, 0);
1361 case Config::VIDEO_VIEW_OPENGL:
1362 checked_set (_video_display_mode, 1);
1365 checked_set (_allow_any_dcp_frame_rate, config->allow_any_dcp_frame_rate ());
1366 checked_set (_allow_any_container, config->allow_any_container ());
1367 checked_set (_show_experimental_audio_processors, config->show_experimental_audio_processors ());
1368 checked_set (_only_servers_encode, config->only_servers_encode ());
1369 checked_set (_log_general, config->log_types() & LogEntry::TYPE_GENERAL);
1370 checked_set (_log_warning, config->log_types() & LogEntry::TYPE_WARNING);
1371 checked_set (_log_error, config->log_types() & LogEntry::TYPE_ERROR);
1372 checked_set (_log_timing, config->log_types() & LogEntry::TYPE_TIMING);
1373 checked_set (_log_debug_threed, config->log_types() & LogEntry::TYPE_DEBUG_THREED);
1374 checked_set (_log_debug_encode, config->log_types() & LogEntry::TYPE_DEBUG_ENCODE);
1375 checked_set (_log_debug_email, config->log_types() & LogEntry::TYPE_DEBUG_EMAIL);
1376 checked_set (_frames_in_memory_multiplier, config->frames_in_memory_multiplier());
1377 #ifdef DCPOMATIC_WINDOWS
1378 checked_set (_win32_console, config->win32_console());
1382 void maximum_j2k_bandwidth_changed ()
1384 Config::instance()->set_maximum_j2k_bandwidth (_maximum_j2k_bandwidth->GetValue() * 1000000);
1387 void video_display_mode_changed ()
1389 if (_video_display_mode->GetSelection() == 0) {
1390 Config::instance()->set_video_view_type (Config::VIDEO_VIEW_SIMPLE);
1392 Config::instance()->set_video_view_type (Config::VIDEO_VIEW_OPENGL);
1396 void frames_in_memory_multiplier_changed ()
1398 Config::instance()->set_frames_in_memory_multiplier (_frames_in_memory_multiplier->GetValue());
1401 void allow_any_dcp_frame_rate_changed ()
1403 Config::instance()->set_allow_any_dcp_frame_rate (_allow_any_dcp_frame_rate->GetValue ());
1406 void allow_any_container_changed ()
1408 Config::instance()->set_allow_any_container (_allow_any_container->GetValue ());
1411 void show_experimental_audio_processors_changed ()
1413 Config::instance()->set_show_experimental_audio_processors (_show_experimental_audio_processors->GetValue ());
1416 void only_servers_encode_changed ()
1418 Config::instance()->set_only_servers_encode (_only_servers_encode->GetValue ());
1421 void dcp_metadata_filename_format_changed ()
1423 Config::instance()->set_dcp_metadata_filename_format (_dcp_metadata_filename_format->get ());
1426 void dcp_asset_filename_format_changed ()
1428 Config::instance()->set_dcp_asset_filename_format (_dcp_asset_filename_format->get ());
1434 if (_log_general->GetValue ()) {
1435 types |= LogEntry::TYPE_GENERAL;
1437 if (_log_warning->GetValue ()) {
1438 types |= LogEntry::TYPE_WARNING;
1440 if (_log_error->GetValue ()) {
1441 types |= LogEntry::TYPE_ERROR;
1443 if (_log_timing->GetValue ()) {
1444 types |= LogEntry::TYPE_TIMING;
1446 if (_log_debug_threed->GetValue ()) {
1447 types |= LogEntry::TYPE_DEBUG_THREED;
1449 if (_log_debug_encode->GetValue ()) {
1450 types |= LogEntry::TYPE_DEBUG_ENCODE;
1452 if (_log_debug_email->GetValue ()) {
1453 types |= LogEntry::TYPE_DEBUG_EMAIL;
1455 Config::instance()->set_log_types (types);
1458 #ifdef DCPOMATIC_WINDOWS
1459 void win32_console_changed ()
1461 Config::instance()->set_win32_console (_win32_console->GetValue ());
1465 wxSpinCtrl* _maximum_j2k_bandwidth;
1466 wxChoice* _video_display_mode;
1467 wxSpinCtrl* _frames_in_memory_multiplier;
1468 wxCheckBox* _allow_any_dcp_frame_rate;
1469 wxCheckBox* _allow_any_container;
1470 wxCheckBox* _show_experimental_audio_processors;
1471 wxCheckBox* _only_servers_encode;
1472 NameFormatEditor* _dcp_metadata_filename_format;
1473 NameFormatEditor* _dcp_asset_filename_format;
1474 wxCheckBox* _log_general;
1475 wxCheckBox* _log_warning;
1476 wxCheckBox* _log_error;
1477 wxCheckBox* _log_timing;
1478 wxCheckBox* _log_debug_threed;
1479 wxCheckBox* _log_debug_encode;
1480 wxCheckBox* _log_debug_email;
1481 #ifdef DCPOMATIC_WINDOWS
1482 wxCheckBox* _win32_console;
1486 wxPreferencesEditor*
1487 create_full_config_dialog ()
1489 wxPreferencesEditor* e = new wxPreferencesEditor ();
1491 #ifdef DCPOMATIC_OSX
1492 /* Width that we force some of the config panels to be on OSX so that
1493 the containing window doesn't shrink too much when we select those panels.
1494 This is obviously an unpleasant hack.
1496 wxSize ps = wxSize (700, -1);
1497 int const border = 16;
1499 wxSize ps = wxSize (-1, -1);
1500 int const border = 8;
1503 e->AddPage (new FullGeneralPage (ps, border));
1504 e->AddPage (new SoundPage (ps, border));
1505 e->AddPage (new DefaultsPage (ps, border));
1506 e->AddPage (new EncodingServersPage (ps, border));
1507 e->AddPage (new KeysPage (ps, border));
1508 e->AddPage (new TMSPage (ps, border));
1509 e->AddPage (new EmailPage (ps, border));
1510 e->AddPage (new KDMEmailPage (ps, border));
1511 e->AddPage (new NotificationsPage (ps, border));
1512 e->AddPage (new CoverSheetPage (ps, border));
1513 e->AddPage (new AdvancedPage (ps, border));