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 scale-to"), true);
344 _scale_to = new wxChoice (_panel, wxID_ANY);
345 table->Add (_scale_to);
347 add_label_to_sizer (table, _panel, _("Default content type"), true);
348 _dcp_content_type = new wxChoice (_panel, wxID_ANY);
349 table->Add (_dcp_content_type);
351 add_label_to_sizer (table, _panel, _("Default DCP audio channels"), true);
352 _dcp_audio_channels = new wxChoice (_panel, wxID_ANY);
353 table->Add (_dcp_audio_channels);
356 add_label_to_sizer (table, _panel, _("Default JPEG2000 bandwidth"), true);
357 wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL);
358 _j2k_bandwidth = new wxSpinCtrl (_panel);
359 s->Add (_j2k_bandwidth);
360 add_label_to_sizer (s, _panel, _("Mbit/s"), false);
365 add_label_to_sizer (table, _panel, _("Default audio delay"), true);
366 wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL);
367 _audio_delay = new wxSpinCtrl (_panel);
368 s->Add (_audio_delay);
369 add_label_to_sizer (s, _panel, _("ms"), false);
373 add_label_to_sizer (table, _panel, _("Default standard"), true);
374 _standard = new wxChoice (_panel, wxID_ANY);
375 table->Add (_standard);
377 add_label_to_sizer (table, _panel, _("Default KDM directory"), true);
378 #ifdef DCPOMATIC_USE_OWN_PICKER
379 _kdm_directory = new DirPickerCtrl (_panel);
381 _kdm_directory = new wxDirPickerCtrl (_panel, wxDD_DIR_MUST_EXIST);
384 table->Add (_kdm_directory, 1, wxEXPAND);
386 _upload_after_make_dcp = new CheckBox (_panel, _("Default to enabling upload of DCP to TMS"));
387 table->Add (_upload_after_make_dcp, 1, wxEXPAND);
389 _still_length->SetRange (1, 3600);
390 _still_length->Bind (wxEVT_SPINCTRL, boost::bind (&DefaultsPage::still_length_changed, this));
392 _directory->Bind (wxEVT_DIRPICKER_CHANGED, boost::bind (&DefaultsPage::directory_changed, this));
393 _kdm_directory->Bind (wxEVT_DIRPICKER_CHANGED, boost::bind (&DefaultsPage::kdm_directory_changed, this));
395 _isdcf_metadata_button->Bind (wxEVT_BUTTON, boost::bind (&DefaultsPage::edit_isdcf_metadata_clicked, this));
397 BOOST_FOREACH (Ratio const * i, Ratio::containers()) {
398 _container->Append (std_to_wx(i->container_nickname()));
401 _container->Bind (wxEVT_CHOICE, boost::bind (&DefaultsPage::container_changed, this));
403 _scale_to->Append (_("Guess from content"));
405 BOOST_FOREACH (Ratio const * i, Ratio::all()) {
406 _scale_to->Append (std_to_wx(i->image_nickname()));
409 _scale_to->Bind (wxEVT_CHOICE, boost::bind (&DefaultsPage::scale_to_changed, this));
411 BOOST_FOREACH (DCPContentType const * i, DCPContentType::all()) {
412 _dcp_content_type->Append (std_to_wx (i->pretty_name ()));
415 setup_audio_channels_choice (_dcp_audio_channels, 2);
417 _dcp_content_type->Bind (wxEVT_CHOICE, boost::bind (&DefaultsPage::dcp_content_type_changed, this));
418 _dcp_audio_channels->Bind (wxEVT_CHOICE, boost::bind (&DefaultsPage::dcp_audio_channels_changed, this));
420 _j2k_bandwidth->SetRange (50, 250);
421 _j2k_bandwidth->Bind (wxEVT_SPINCTRL, boost::bind (&DefaultsPage::j2k_bandwidth_changed, this));
423 _audio_delay->SetRange (-1000, 1000);
424 _audio_delay->Bind (wxEVT_SPINCTRL, boost::bind (&DefaultsPage::audio_delay_changed, this));
426 _standard->Append (_("SMPTE"));
427 _standard->Append (_("Interop"));
428 _standard->Bind (wxEVT_CHOICE, boost::bind (&DefaultsPage::standard_changed, this));
430 _upload_after_make_dcp->Bind (wxEVT_CHECKBOX, boost::bind (&DefaultsPage::upload_after_make_dcp_changed, this));
433 void config_changed ()
435 Config* config = Config::instance ();
437 vector<Ratio const *> containers = Ratio::containers ();
438 for (size_t i = 0; i < containers.size(); ++i) {
439 if (containers[i] == config->default_container ()) {
440 _container->SetSelection (i);
444 vector<Ratio const *> ratios = Ratio::all ();
445 for (size_t i = 0; i < ratios.size(); ++i) {
446 if (ratios[i] == config->default_scale_to ()) {
447 _scale_to->SetSelection (i + 1);
451 if (!config->default_scale_to()) {
452 _scale_to->SetSelection (0);
455 vector<DCPContentType const *> const ct = DCPContentType::all ();
456 for (size_t i = 0; i < ct.size(); ++i) {
457 if (ct[i] == config->default_dcp_content_type ()) {
458 _dcp_content_type->SetSelection (i);
462 checked_set (_still_length, config->default_still_length ());
463 _directory->SetPath (std_to_wx (config->default_directory_or (wx_to_std (wxStandardPaths::Get().GetDocumentsDir())).string ()));
464 _kdm_directory->SetPath (std_to_wx (config->default_kdm_directory_or (wx_to_std (wxStandardPaths::Get().GetDocumentsDir())).string ()));
465 checked_set (_j2k_bandwidth, config->default_j2k_bandwidth() / 1000000);
466 _j2k_bandwidth->SetRange (50, config->maximum_j2k_bandwidth() / 1000000);
467 checked_set (_dcp_audio_channels, locale_convert<string> (config->default_dcp_audio_channels()));
468 checked_set (_audio_delay, config->default_audio_delay ());
469 checked_set (_standard, config->default_interop() ? 1 : 0);
470 checked_set (_upload_after_make_dcp, config->default_upload_after_make_dcp());
473 void j2k_bandwidth_changed ()
475 Config::instance()->set_default_j2k_bandwidth (_j2k_bandwidth->GetValue() * 1000000);
478 void audio_delay_changed ()
480 Config::instance()->set_default_audio_delay (_audio_delay->GetValue());
483 void dcp_audio_channels_changed ()
485 int const s = _dcp_audio_channels->GetSelection ();
486 if (s != wxNOT_FOUND) {
487 Config::instance()->set_default_dcp_audio_channels (
488 locale_convert<int> (string_client_data (_dcp_audio_channels->GetClientObject (s)))
493 void directory_changed ()
495 Config::instance()->set_default_directory (wx_to_std (_directory->GetPath ()));
498 void kdm_directory_changed ()
500 Config::instance()->set_default_kdm_directory (wx_to_std (_kdm_directory->GetPath ()));
503 void edit_isdcf_metadata_clicked ()
505 ISDCFMetadataDialog* d = new ISDCFMetadataDialog (_panel, Config::instance()->default_isdcf_metadata (), false);
507 Config::instance()->set_default_isdcf_metadata (d->isdcf_metadata ());
511 void still_length_changed ()
513 Config::instance()->set_default_still_length (_still_length->GetValue ());
516 void container_changed ()
518 vector<Ratio const *> ratio = Ratio::containers ();
519 Config::instance()->set_default_container (ratio[_container->GetSelection()]);
522 void scale_to_changed ()
524 int const s = _scale_to->GetSelection ();
526 Config::instance()->set_default_scale_to (0);
528 vector<Ratio const *> ratio = Ratio::all ();
529 Config::instance()->set_default_scale_to (ratio[s - 1]);
533 void dcp_content_type_changed ()
535 vector<DCPContentType const *> ct = DCPContentType::all ();
536 Config::instance()->set_default_dcp_content_type (ct[_dcp_content_type->GetSelection()]);
539 void standard_changed ()
541 Config::instance()->set_default_interop (_standard->GetSelection() == 1);
544 void upload_after_make_dcp_changed ()
546 Config::instance()->set_default_upload_after_make_dcp (_upload_after_make_dcp->GetValue ());
549 wxSpinCtrl* _j2k_bandwidth;
550 wxSpinCtrl* _audio_delay;
551 wxButton* _isdcf_metadata_button;
552 wxSpinCtrl* _still_length;
553 #ifdef DCPOMATIC_USE_OWN_PICKER
554 DirPickerCtrl* _directory;
555 DirPickerCtrl* _kdm_directory;
557 wxDirPickerCtrl* _directory;
558 wxDirPickerCtrl* _kdm_directory;
560 wxChoice* _container;
562 wxChoice* _dcp_content_type;
563 wxChoice* _dcp_audio_channels;
565 wxCheckBox* _upload_after_make_dcp;
568 class EncodingServersPage : public StandardPage
571 EncodingServersPage (wxSize panel_size, int border)
572 : StandardPage (panel_size, border)
575 wxString GetName () const
581 wxBitmap GetLargeIcon () const
583 return wxBitmap ("servers", wxBITMAP_TYPE_PNG_RESOURCE);
590 _use_any_servers = new CheckBox (_panel, _("Search network for servers"));
591 _panel->GetSizer()->Add (_use_any_servers, 0, wxALL, _border);
593 vector<EditableListColumn> columns;
594 columns.push_back (EditableListColumn(wx_to_std(_("IP address / host name"))));
595 _servers_list = new EditableList<string, ServerDialog> (
598 boost::bind (&Config::servers, Config::instance()),
599 boost::bind (&Config::set_servers, Config::instance(), _1),
600 boost::bind (&EncodingServersPage::server_column, this, _1)
603 _panel->GetSizer()->Add (_servers_list, 1, wxEXPAND | wxALL, _border);
605 _use_any_servers->Bind (wxEVT_CHECKBOX, boost::bind (&EncodingServersPage::use_any_servers_changed, this));
608 void config_changed ()
610 checked_set (_use_any_servers, Config::instance()->use_any_servers ());
611 _servers_list->refresh ();
614 void use_any_servers_changed ()
616 Config::instance()->set_use_any_servers (_use_any_servers->GetValue ());
619 string server_column (string s)
624 wxCheckBox* _use_any_servers;
625 EditableList<string, ServerDialog>* _servers_list;
628 class TMSPage : public StandardPage
631 TMSPage (wxSize panel_size, int border)
632 : StandardPage (panel_size, border)
635 wxString GetName () const
641 wxBitmap GetLargeIcon () const
643 return wxBitmap ("tms", wxBITMAP_TYPE_PNG_RESOURCE);
650 wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
651 table->AddGrowableCol (1, 1);
652 _panel->GetSizer()->Add (table, 1, wxALL | wxEXPAND, _border);
654 add_label_to_sizer (table, _panel, _("Protocol"), true);
655 _tms_protocol = new wxChoice (_panel, wxID_ANY);
656 table->Add (_tms_protocol, 1, wxEXPAND);
658 add_label_to_sizer (table, _panel, _("IP address"), true);
659 _tms_ip = new wxTextCtrl (_panel, wxID_ANY);
660 table->Add (_tms_ip, 1, wxEXPAND);
662 add_label_to_sizer (table, _panel, _("Target path"), true);
663 _tms_path = new wxTextCtrl (_panel, wxID_ANY);
664 table->Add (_tms_path, 1, wxEXPAND);
666 add_label_to_sizer (table, _panel, _("User name"), true);
667 _tms_user = new wxTextCtrl (_panel, wxID_ANY);
668 table->Add (_tms_user, 1, wxEXPAND);
670 add_label_to_sizer (table, _panel, _("Password"), true);
671 _tms_password = new PasswordEntry (_panel);
672 table->Add (_tms_password->get_panel(), 1, wxEXPAND);
674 _tms_protocol->Append (_("SCP (for AAM and Doremi)"));
675 _tms_protocol->Append (_("FTP (for Dolby)"));
677 _tms_protocol->Bind (wxEVT_CHOICE, boost::bind (&TMSPage::tms_protocol_changed, this));
678 _tms_ip->Bind (wxEVT_TEXT, boost::bind (&TMSPage::tms_ip_changed, this));
679 _tms_path->Bind (wxEVT_TEXT, boost::bind (&TMSPage::tms_path_changed, this));
680 _tms_user->Bind (wxEVT_TEXT, boost::bind (&TMSPage::tms_user_changed, this));
681 _tms_password->Changed.connect (boost::bind (&TMSPage::tms_password_changed, this));
684 void config_changed ()
686 Config* config = Config::instance ();
688 checked_set (_tms_protocol, config->tms_protocol ());
689 checked_set (_tms_ip, config->tms_ip ());
690 checked_set (_tms_path, config->tms_path ());
691 checked_set (_tms_user, config->tms_user ());
692 checked_set (_tms_password, config->tms_password ());
695 void tms_protocol_changed ()
697 Config::instance()->set_tms_protocol(static_cast<FileTransferProtocol>(_tms_protocol->GetSelection()));
700 void tms_ip_changed ()
702 Config::instance()->set_tms_ip (wx_to_std (_tms_ip->GetValue ()));
705 void tms_path_changed ()
707 Config::instance()->set_tms_path (wx_to_std (_tms_path->GetValue ()));
710 void tms_user_changed ()
712 Config::instance()->set_tms_user (wx_to_std (_tms_user->GetValue ()));
715 void tms_password_changed ()
717 Config::instance()->set_tms_password (_tms_password->get());
720 wxChoice* _tms_protocol;
722 wxTextCtrl* _tms_path;
723 wxTextCtrl* _tms_user;
724 PasswordEntry* _tms_password;
733 class EmailPage : public StandardPage
736 EmailPage (wxSize panel_size, int border)
737 : StandardPage (panel_size, border)
740 wxString GetName () const
746 wxBitmap GetLargeIcon () const
748 return wxBitmap ("email", wxBITMAP_TYPE_PNG_RESOURCE);
755 wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
756 table->AddGrowableCol (1, 1);
757 _panel->GetSizer()->Add (table, 1, wxEXPAND | wxALL, _border);
759 add_label_to_sizer (table, _panel, _("Outgoing mail server"), true);
761 wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL);
762 _server = new wxTextCtrl (_panel, wxID_ANY);
763 s->Add (_server, 1, wxEXPAND | wxALL);
764 add_label_to_sizer (s, _panel, _("port"), false);
765 _port = new wxSpinCtrl (_panel, wxID_ANY);
766 _port->SetRange (0, 65535);
768 add_label_to_sizer (s, _panel, _("protocol"), false);
769 _protocol = new wxChoice (_panel, wxID_ANY);
770 /* Make sure this matches the switches in config_changed and port_changed below */
771 _protocol->Append (_("Auto"));
772 _protocol->Append (_("Plain"));
773 _protocol->Append (_("STARTTLS"));
774 _protocol->Append (_("SSL"));
776 table->Add (s, 1, wxEXPAND | wxALL);
779 add_label_to_sizer (table, _panel, _("User name"), true);
780 _user = new wxTextCtrl (_panel, wxID_ANY);
781 table->Add (_user, 1, wxEXPAND | wxALL);
783 add_label_to_sizer (table, _panel, _("Password"), true);
784 _password = new PasswordEntry (_panel);
785 table->Add (_password->get_panel(), 1, wxEXPAND | wxALL);
787 _server->Bind (wxEVT_TEXT, boost::bind (&EmailPage::server_changed, this));
788 _port->Bind (wxEVT_SPINCTRL, boost::bind (&EmailPage::port_changed, this));
789 _protocol->Bind (wxEVT_CHOICE, boost::bind (&EmailPage::protocol_changed, this));
790 _user->Bind (wxEVT_TEXT, boost::bind (&EmailPage::user_changed, this));
791 _password->Changed.connect (boost::bind (&EmailPage::password_changed, this));
794 void config_changed ()
796 Config* config = Config::instance ();
798 checked_set (_server, config->mail_server ());
799 checked_set (_port, config->mail_port ());
800 switch (config->mail_protocol()) {
801 case EMAIL_PROTOCOL_AUTO:
802 checked_set (_protocol, 0);
804 case EMAIL_PROTOCOL_PLAIN:
805 checked_set (_protocol, 1);
807 case EMAIL_PROTOCOL_STARTTLS:
808 checked_set (_protocol, 2);
810 case EMAIL_PROTOCOL_SSL:
811 checked_set (_protocol, 3);
814 checked_set (_user, config->mail_user ());
815 checked_set (_password, config->mail_password());
818 void server_changed ()
820 Config::instance()->set_mail_server (wx_to_std (_server->GetValue ()));
825 Config::instance()->set_mail_port (_port->GetValue ());
828 void protocol_changed ()
830 switch (_protocol->GetSelection()) {
832 Config::instance()->set_mail_protocol(EMAIL_PROTOCOL_AUTO);
835 Config::instance()->set_mail_protocol(EMAIL_PROTOCOL_PLAIN);
838 Config::instance()->set_mail_protocol(EMAIL_PROTOCOL_STARTTLS);
841 Config::instance()->set_mail_protocol(EMAIL_PROTOCOL_SSL);
848 Config::instance()->set_mail_user (wx_to_std (_user->GetValue ()));
851 void password_changed ()
853 Config::instance()->set_mail_password(_password->get());
860 PasswordEntry* _password;
863 class KDMEmailPage : public StandardPage
867 KDMEmailPage (wxSize panel_size, int border)
869 /* We have to force both width and height of this one */
870 : StandardPage (wxSize (panel_size.GetWidth(), 128), border)
872 : StandardPage (panel_size, border)
876 wxString GetName () const
878 return _("KDM Email");
882 wxBitmap GetLargeIcon () const
884 return wxBitmap ("kdm_email", wxBITMAP_TYPE_PNG_RESOURCE);
891 wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
892 table->AddGrowableCol (1, 1);
893 _panel->GetSizer()->Add (table, 1, wxEXPAND | wxALL, _border);
895 add_label_to_sizer (table, _panel, _("Subject"), true);
896 _subject = new wxTextCtrl (_panel, wxID_ANY);
897 table->Add (_subject, 1, wxEXPAND | wxALL);
899 add_label_to_sizer (table, _panel, _("From address"), true);
900 _from = new wxTextCtrl (_panel, wxID_ANY);
901 table->Add (_from, 1, wxEXPAND | wxALL);
903 vector<EditableListColumn> columns;
904 columns.push_back (EditableListColumn(wx_to_std(_("Address"))));
905 add_label_to_sizer (table, _panel, _("CC addresses"), true);
906 _cc = new EditableList<string, EmailDialog> (
909 bind (&Config::kdm_cc, Config::instance()),
910 bind (&Config::set_kdm_cc, Config::instance(), _1),
913 table->Add (_cc, 1, wxEXPAND | wxALL);
915 add_label_to_sizer (table, _panel, _("BCC address"), true);
916 _bcc = new wxTextCtrl (_panel, wxID_ANY);
917 table->Add (_bcc, 1, wxEXPAND | wxALL);
919 _email = new wxTextCtrl (_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize (-1, 200), wxTE_MULTILINE);
920 _panel->GetSizer()->Add (_email, 0, wxEXPAND | wxALL, _border);
922 _reset_email = new Button (_panel, _("Reset to default subject and text"));
923 _panel->GetSizer()->Add (_reset_email, 0, wxEXPAND | wxALL, _border);
927 _subject->Bind (wxEVT_TEXT, boost::bind (&KDMEmailPage::kdm_subject_changed, this));
928 _from->Bind (wxEVT_TEXT, boost::bind (&KDMEmailPage::kdm_from_changed, this));
929 _bcc->Bind (wxEVT_TEXT, boost::bind (&KDMEmailPage::kdm_bcc_changed, this));
930 _email->Bind (wxEVT_TEXT, boost::bind (&KDMEmailPage::kdm_email_changed, this));
931 _reset_email->Bind (wxEVT_BUTTON, boost::bind (&KDMEmailPage::reset_email, this));
934 void config_changed ()
936 Config* config = Config::instance ();
938 checked_set (_subject, config->kdm_subject ());
939 checked_set (_from, config->kdm_from ());
940 checked_set (_bcc, config->kdm_bcc ());
941 checked_set (_email, Config::instance()->kdm_email ());
944 void kdm_subject_changed ()
946 Config::instance()->set_kdm_subject (wx_to_std (_subject->GetValue ()));
949 void kdm_from_changed ()
951 Config::instance()->set_kdm_from (wx_to_std (_from->GetValue ()));
954 void kdm_bcc_changed ()
956 Config::instance()->set_kdm_bcc (wx_to_std (_bcc->GetValue ()));
959 void kdm_email_changed ()
961 if (_email->GetValue().IsEmpty ()) {
962 /* Sometimes we get sent an erroneous notification that the email
963 is empty; I don't know why.
967 Config::instance()->set_kdm_email (wx_to_std (_email->GetValue ()));
972 Config::instance()->reset_kdm_email ();
973 checked_set (_email, Config::instance()->kdm_email ());
976 wxTextCtrl* _subject;
978 EditableList<string, EmailDialog>* _cc;
981 wxButton* _reset_email;
984 class NotificationsPage : public StandardPage
987 NotificationsPage (wxSize panel_size, int border)
989 /* We have to force both width and height of this one */
990 : StandardPage (wxSize (panel_size.GetWidth(), 128), border)
992 : StandardPage (panel_size, border)
996 wxString GetName () const
998 return _("Notifications");
1001 #ifdef DCPOMATIC_OSX
1002 wxBitmap GetLargeIcon () const
1004 return wxBitmap ("notifications", wxBITMAP_TYPE_PNG_RESOURCE);
1011 wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
1012 table->AddGrowableCol (1, 1);
1013 _panel->GetSizer()->Add (table, 1, wxEXPAND | wxALL, _border);
1015 _enable_message_box = new CheckBox (_panel, _("Message box"));
1016 table->Add (_enable_message_box, 1, wxEXPAND | wxALL);
1017 table->AddSpacer (0);
1019 _enable_email = new CheckBox (_panel, _("Email"));
1020 table->Add (_enable_email, 1, wxEXPAND | wxALL);
1021 table->AddSpacer (0);
1023 add_label_to_sizer (table, _panel, _("Subject"), true);
1024 _subject = new wxTextCtrl (_panel, wxID_ANY);
1025 table->Add (_subject, 1, wxEXPAND | wxALL);
1027 add_label_to_sizer (table, _panel, _("From address"), true);
1028 _from = new wxTextCtrl (_panel, wxID_ANY);
1029 table->Add (_from, 1, wxEXPAND | wxALL);
1031 add_label_to_sizer (table, _panel, _("To address"), true);
1032 _to = new wxTextCtrl (_panel, wxID_ANY);
1033 table->Add (_to, 1, wxEXPAND | wxALL);
1035 vector<EditableListColumn> columns;
1036 columns.push_back (EditableListColumn(wx_to_std(_("Address"))));
1037 add_label_to_sizer (table, _panel, _("CC addresses"), true);
1038 _cc = new EditableList<string, EmailDialog> (
1041 bind (&Config::notification_cc, Config::instance()),
1042 bind (&Config::set_notification_cc, Config::instance(), _1),
1045 table->Add (_cc, 1, wxEXPAND | wxALL);
1047 add_label_to_sizer (table, _panel, _("BCC address"), true);
1048 _bcc = new wxTextCtrl (_panel, wxID_ANY);
1049 table->Add (_bcc, 1, wxEXPAND | wxALL);
1051 _email = new wxTextCtrl (_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize (-1, 200), wxTE_MULTILINE);
1052 _panel->GetSizer()->Add (_email, 0, wxEXPAND | wxALL, _border);
1054 _reset_email = new Button (_panel, _("Reset to default subject and text"));
1055 _panel->GetSizer()->Add (_reset_email, 0, wxEXPAND | wxALL, _border);
1059 _enable_message_box->Bind (wxEVT_CHECKBOX, boost::bind (&NotificationsPage::type_changed, this, _enable_message_box, Config::MESSAGE_BOX));
1060 _enable_email->Bind (wxEVT_CHECKBOX, boost::bind (&NotificationsPage::type_changed, this, _enable_email, Config::EMAIL));
1062 _subject->Bind (wxEVT_TEXT, boost::bind (&NotificationsPage::notification_subject_changed, this));
1063 _from->Bind (wxEVT_TEXT, boost::bind (&NotificationsPage::notification_from_changed, this));
1064 _to->Bind (wxEVT_TEXT, boost::bind (&NotificationsPage::notification_to_changed, this));
1065 _bcc->Bind (wxEVT_TEXT, boost::bind (&NotificationsPage::notification_bcc_changed, this));
1066 _email->Bind (wxEVT_TEXT, boost::bind (&NotificationsPage::notification_email_changed, this));
1067 _reset_email->Bind (wxEVT_BUTTON, boost::bind (&NotificationsPage::reset_email, this));
1069 update_sensitivity ();
1072 void update_sensitivity ()
1074 bool const s = _enable_email->GetValue();
1075 _subject->Enable(s);
1081 _reset_email->Enable(s);
1084 void config_changed ()
1086 Config* config = Config::instance ();
1088 checked_set (_enable_message_box, config->notification(Config::MESSAGE_BOX));
1089 checked_set (_enable_email, config->notification(Config::EMAIL));
1090 checked_set (_subject, config->notification_subject ());
1091 checked_set (_from, config->notification_from ());
1092 checked_set (_to, config->notification_to ());
1093 checked_set (_bcc, config->notification_bcc ());
1094 checked_set (_email, Config::instance()->notification_email ());
1096 update_sensitivity ();
1099 void notification_subject_changed ()
1101 Config::instance()->set_notification_subject (wx_to_std (_subject->GetValue ()));
1104 void notification_from_changed ()
1106 Config::instance()->set_notification_from (wx_to_std (_from->GetValue ()));
1109 void notification_to_changed ()
1111 Config::instance()->set_notification_to (wx_to_std (_to->GetValue ()));
1114 void notification_bcc_changed ()
1116 Config::instance()->set_notification_bcc (wx_to_std (_bcc->GetValue ()));
1119 void notification_email_changed ()
1121 if (_email->GetValue().IsEmpty ()) {
1122 /* Sometimes we get sent an erroneous notification that the email
1123 is empty; I don't know why.
1127 Config::instance()->set_notification_email (wx_to_std (_email->GetValue ()));
1132 Config::instance()->reset_notification_email ();
1133 checked_set (_email, Config::instance()->notification_email ());
1136 void type_changed (wxCheckBox* b, Config::Notification n)
1138 Config::instance()->set_notification(n, b->GetValue());
1139 update_sensitivity ();
1142 wxCheckBox* _enable_message_box;
1143 wxCheckBox* _enable_email;
1145 wxTextCtrl* _subject;
1148 EditableList<string, EmailDialog>* _cc;
1151 wxButton* _reset_email;
1154 class CoverSheetPage : public StandardPage
1158 CoverSheetPage (wxSize panel_size, int border)
1159 #ifdef DCPOMATIC_OSX
1160 /* We have to force both width and height of this one */
1161 : StandardPage (wxSize (panel_size.GetWidth(), 128), border)
1163 : StandardPage (panel_size, border)
1167 wxString GetName () const
1169 return _("Cover Sheet");
1172 #ifdef DCPOMATIC_OSX
1173 wxBitmap GetLargeIcon () const
1175 return wxBitmap ("cover_sheet", wxBITMAP_TYPE_PNG_RESOURCE);
1182 _cover_sheet = new wxTextCtrl (_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize (-1, 200), wxTE_MULTILINE);
1183 _panel->GetSizer()->Add (_cover_sheet, 0, wxEXPAND | wxALL, _border);
1185 _reset_cover_sheet = new Button (_panel, _("Reset to default text"));
1186 _panel->GetSizer()->Add (_reset_cover_sheet, 0, wxEXPAND | wxALL, _border);
1188 _cover_sheet->Bind (wxEVT_TEXT, boost::bind (&CoverSheetPage::cover_sheet_changed, this));
1189 _reset_cover_sheet->Bind (wxEVT_BUTTON, boost::bind (&CoverSheetPage::reset_cover_sheet, this));
1192 void config_changed ()
1194 checked_set (_cover_sheet, Config::instance()->cover_sheet ());
1197 void cover_sheet_changed ()
1199 if (_cover_sheet->GetValue().IsEmpty ()) {
1200 /* Sometimes we get sent an erroneous notification that the cover sheet
1201 is empty; I don't know why.
1205 Config::instance()->set_cover_sheet (wx_to_std (_cover_sheet->GetValue ()));
1208 void reset_cover_sheet ()
1210 Config::instance()->reset_cover_sheet ();
1211 checked_set (_cover_sheet, Config::instance()->cover_sheet ());
1214 wxTextCtrl* _cover_sheet;
1215 wxButton* _reset_cover_sheet;
1219 /** @class AdvancedPage
1220 * @brief Advanced page of the preferences dialog.
1222 class AdvancedPage : public StockPage
1225 AdvancedPage (wxSize panel_size, int border)
1226 : StockPage (Kind_Advanced, panel_size, border)
1227 , _maximum_j2k_bandwidth (0)
1228 , _allow_any_dcp_frame_rate (0)
1229 , _allow_any_container (0)
1230 , _show_experimental_audio_processors (0)
1231 , _only_servers_encode (0)
1236 , _log_debug_decode (0)
1237 , _log_debug_encode (0)
1238 , _log_debug_email (0)
1242 void add_top_aligned_label_to_sizer (wxSizer* table, wxWindow* parent, wxString text)
1244 int flags = wxALIGN_TOP | wxTOP | wxLEFT;
1246 flags |= wxALIGN_RIGHT;
1249 wxStaticText* m = new StaticText (parent, text);
1250 table->Add (m, 0, flags, DCPOMATIC_SIZER_Y_GAP);
1255 wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
1256 table->AddGrowableCol (1, 1);
1257 _panel->GetSizer()->Add (table, 1, wxALL | wxEXPAND, _border);
1260 add_label_to_sizer (table, _panel, _("Maximum JPEG2000 bandwidth"), true);
1261 wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL);
1262 _maximum_j2k_bandwidth = new wxSpinCtrl (_panel);
1263 s->Add (_maximum_j2k_bandwidth, 1);
1264 add_label_to_sizer (s, _panel, _("Mbit/s"), false);
1268 add_label_to_sizer (table, _panel, _("Video display mode"), true);
1269 _video_display_mode = new wxChoice (_panel, wxID_ANY);
1270 table->Add (_video_display_mode);
1272 wxStaticText* restart = add_label_to_sizer (table, _panel, _("(restart DCP-o-matic to change display mode)"), false);
1273 wxFont font = restart->GetFont();
1274 font.SetStyle (wxFONTSTYLE_ITALIC);
1275 font.SetPointSize (font.GetPointSize() - 1);
1276 restart->SetFont (font);
1277 table->AddSpacer (0);
1279 _allow_any_dcp_frame_rate = new CheckBox (_panel, _("Allow any DCP frame rate"));
1280 table->Add (_allow_any_dcp_frame_rate, 1, wxEXPAND | wxALL);
1281 table->AddSpacer (0);
1283 _allow_any_container = new CheckBox (_panel, _("Allow non-standard container ratios"));
1284 table->Add (_allow_any_container, 1, wxEXPAND | wxALL);
1285 table->AddSpacer (0);
1287 restart = add_label_to_sizer (table, _panel, _("(restart DCP-o-matic to see all ratios)"), false);
1288 restart->SetFont (font);
1289 table->AddSpacer (0);
1291 _show_experimental_audio_processors = new CheckBox (_panel, _("Show experimental audio processors"));
1292 table->Add (_show_experimental_audio_processors, 1, wxEXPAND | wxALL);
1293 table->AddSpacer (0);
1295 _only_servers_encode = new CheckBox (_panel, _("Only servers encode"));
1296 table->Add (_only_servers_encode, 1, wxEXPAND | wxALL);
1297 table->AddSpacer (0);
1300 add_label_to_sizer (table, _panel, _("Maximum number of frames to store per thread"), true);
1301 wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL);
1302 _frames_in_memory_multiplier = new wxSpinCtrl (_panel);
1303 s->Add (_frames_in_memory_multiplier, 1);
1308 add_top_aligned_label_to_sizer (table, _panel, _("DCP metadata filename format"));
1309 dcp::NameFormat::Map titles;
1310 titles['t'] = wx_to_std (_("type (cpl/pkl)"));
1311 dcp::NameFormat::Map examples;
1312 examples['t'] = "cpl";
1313 _dcp_metadata_filename_format = new NameFormatEditor (
1314 _panel, Config::instance()->dcp_metadata_filename_format(), titles, examples, "_eb1c112c-ca3c-4ae6-9263-c6714ff05d64.xml"
1316 table->Add (_dcp_metadata_filename_format->panel(), 1, wxEXPAND | wxALL);
1320 add_top_aligned_label_to_sizer (table, _panel, _("DCP asset filename format"));
1321 dcp::NameFormat::Map titles;
1322 titles['t'] = wx_to_std (_("type (j2c/pcm/sub)"));
1323 titles['r'] = wx_to_std (_("reel number"));
1324 titles['n'] = wx_to_std (_("number of reels"));
1325 titles['c'] = wx_to_std (_("content filename"));
1326 dcp::NameFormat::Map examples;
1327 examples['t'] = "j2c";
1328 examples['r'] = "1";
1329 examples['n'] = "4";
1330 examples['c'] = "myfile.mp4";
1331 _dcp_asset_filename_format = new NameFormatEditor (
1332 _panel, Config::instance()->dcp_asset_filename_format(), titles, examples, "_eb1c112c-ca3c-4ae6-9263-c6714ff05d64.mxf"
1334 table->Add (_dcp_asset_filename_format->panel(), 1, wxEXPAND | wxALL);
1338 add_top_aligned_label_to_sizer (table, _panel, _("Log"));
1339 wxBoxSizer* t = new wxBoxSizer (wxVERTICAL);
1340 _log_general = new CheckBox (_panel, _("General"));
1341 t->Add (_log_general, 1, wxEXPAND | wxALL);
1342 _log_warning = new CheckBox (_panel, _("Warnings"));
1343 t->Add (_log_warning, 1, wxEXPAND | wxALL);
1344 _log_error = new CheckBox (_panel, _("Errors"));
1345 t->Add (_log_error, 1, wxEXPAND | wxALL);
1346 /// TRANSLATORS: translate the word "Timing" here; do not include the "Config|" prefix
1347 _log_timing = new CheckBox (_panel, S_("Config|Timing"));
1348 t->Add (_log_timing, 1, wxEXPAND | wxALL);
1349 _log_debug_decode = new CheckBox (_panel, _("Debug: decode"));
1350 t->Add (_log_debug_decode, 1, wxEXPAND | wxALL);
1351 _log_debug_encode = new CheckBox (_panel, _("Debug: encode"));
1352 t->Add (_log_debug_encode, 1, wxEXPAND | wxALL);
1353 _log_debug_email = new CheckBox (_panel, _("Debug: email sending"));
1354 t->Add (_log_debug_email, 1, wxEXPAND | wxALL);
1355 table->Add (t, 0, wxALL, 6);
1358 #ifdef DCPOMATIC_WINDOWS
1359 _win32_console = new CheckBox (_panel, _("Open console window"));
1360 table->Add (_win32_console, 1, wxEXPAND | wxALL);
1361 table->AddSpacer (0);
1364 _maximum_j2k_bandwidth->SetRange (1, 1000);
1365 _maximum_j2k_bandwidth->Bind (wxEVT_SPINCTRL, boost::bind (&AdvancedPage::maximum_j2k_bandwidth_changed, this));
1366 _video_display_mode->Append (_("Simple (safer)"));
1367 _video_display_mode->Append (_("OpenGL (faster)"));
1368 _video_display_mode->Bind (wxEVT_CHOICE, boost::bind(&AdvancedPage::video_display_mode_changed, this));
1369 _allow_any_dcp_frame_rate->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::allow_any_dcp_frame_rate_changed, this));
1370 _allow_any_container->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::allow_any_container_changed, this));
1371 _show_experimental_audio_processors->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::show_experimental_audio_processors_changed, this));
1372 _only_servers_encode->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::only_servers_encode_changed, this));
1373 _frames_in_memory_multiplier->Bind (wxEVT_SPINCTRL, boost::bind(&AdvancedPage::frames_in_memory_multiplier_changed, this));
1374 _dcp_metadata_filename_format->Changed.connect (boost::bind (&AdvancedPage::dcp_metadata_filename_format_changed, this));
1375 _dcp_asset_filename_format->Changed.connect (boost::bind (&AdvancedPage::dcp_asset_filename_format_changed, this));
1376 _log_general->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::log_changed, this));
1377 _log_warning->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::log_changed, this));
1378 _log_error->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::log_changed, this));
1379 _log_timing->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::log_changed, this));
1380 _log_debug_decode->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::log_changed, this));
1381 _log_debug_encode->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::log_changed, this));
1382 _log_debug_email->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::log_changed, this));
1383 #ifdef DCPOMATIC_WINDOWS
1384 _win32_console->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::win32_console_changed, this));
1388 void config_changed ()
1390 Config* config = Config::instance ();
1392 checked_set (_maximum_j2k_bandwidth, config->maximum_j2k_bandwidth() / 1000000);
1393 switch (config->video_view_type()) {
1394 case Config::VIDEO_VIEW_SIMPLE:
1395 checked_set (_video_display_mode, 0);
1397 case Config::VIDEO_VIEW_OPENGL:
1398 checked_set (_video_display_mode, 1);
1401 checked_set (_allow_any_dcp_frame_rate, config->allow_any_dcp_frame_rate ());
1402 checked_set (_allow_any_container, config->allow_any_container ());
1403 checked_set (_show_experimental_audio_processors, config->show_experimental_audio_processors ());
1404 checked_set (_only_servers_encode, config->only_servers_encode ());
1405 checked_set (_log_general, config->log_types() & LogEntry::TYPE_GENERAL);
1406 checked_set (_log_warning, config->log_types() & LogEntry::TYPE_WARNING);
1407 checked_set (_log_error, config->log_types() & LogEntry::TYPE_ERROR);
1408 checked_set (_log_timing, config->log_types() & LogEntry::TYPE_TIMING);
1409 checked_set (_log_debug_decode, config->log_types() & LogEntry::TYPE_DEBUG_DECODE);
1410 checked_set (_log_debug_encode, config->log_types() & LogEntry::TYPE_DEBUG_ENCODE);
1411 checked_set (_log_debug_email, config->log_types() & LogEntry::TYPE_DEBUG_EMAIL);
1412 checked_set (_frames_in_memory_multiplier, config->frames_in_memory_multiplier());
1413 #ifdef DCPOMATIC_WINDOWS
1414 checked_set (_win32_console, config->win32_console());
1418 void maximum_j2k_bandwidth_changed ()
1420 Config::instance()->set_maximum_j2k_bandwidth (_maximum_j2k_bandwidth->GetValue() * 1000000);
1423 void video_display_mode_changed ()
1425 if (_video_display_mode->GetSelection() == 0) {
1426 Config::instance()->set_video_view_type (Config::VIDEO_VIEW_SIMPLE);
1428 Config::instance()->set_video_view_type (Config::VIDEO_VIEW_OPENGL);
1432 void frames_in_memory_multiplier_changed ()
1434 Config::instance()->set_frames_in_memory_multiplier (_frames_in_memory_multiplier->GetValue());
1437 void allow_any_dcp_frame_rate_changed ()
1439 Config::instance()->set_allow_any_dcp_frame_rate (_allow_any_dcp_frame_rate->GetValue ());
1442 void allow_any_container_changed ()
1444 Config::instance()->set_allow_any_container (_allow_any_container->GetValue ());
1447 void show_experimental_audio_processors_changed ()
1449 Config::instance()->set_show_experimental_audio_processors (_show_experimental_audio_processors->GetValue ());
1452 void only_servers_encode_changed ()
1454 Config::instance()->set_only_servers_encode (_only_servers_encode->GetValue ());
1457 void dcp_metadata_filename_format_changed ()
1459 Config::instance()->set_dcp_metadata_filename_format (_dcp_metadata_filename_format->get ());
1462 void dcp_asset_filename_format_changed ()
1464 Config::instance()->set_dcp_asset_filename_format (_dcp_asset_filename_format->get ());
1470 if (_log_general->GetValue ()) {
1471 types |= LogEntry::TYPE_GENERAL;
1473 if (_log_warning->GetValue ()) {
1474 types |= LogEntry::TYPE_WARNING;
1476 if (_log_error->GetValue ()) {
1477 types |= LogEntry::TYPE_ERROR;
1479 if (_log_timing->GetValue ()) {
1480 types |= LogEntry::TYPE_TIMING;
1482 if (_log_debug_decode->GetValue ()) {
1483 types |= LogEntry::TYPE_DEBUG_DECODE;
1485 if (_log_debug_encode->GetValue ()) {
1486 types |= LogEntry::TYPE_DEBUG_ENCODE;
1488 if (_log_debug_email->GetValue ()) {
1489 types |= LogEntry::TYPE_DEBUG_EMAIL;
1491 Config::instance()->set_log_types (types);
1494 #ifdef DCPOMATIC_WINDOWS
1495 void win32_console_changed ()
1497 Config::instance()->set_win32_console (_win32_console->GetValue ());
1501 wxSpinCtrl* _maximum_j2k_bandwidth;
1502 wxChoice* _video_display_mode;
1503 wxSpinCtrl* _frames_in_memory_multiplier;
1504 wxCheckBox* _allow_any_dcp_frame_rate;
1505 wxCheckBox* _allow_any_container;
1506 wxCheckBox* _show_experimental_audio_processors;
1507 wxCheckBox* _only_servers_encode;
1508 NameFormatEditor* _dcp_metadata_filename_format;
1509 NameFormatEditor* _dcp_asset_filename_format;
1510 wxCheckBox* _log_general;
1511 wxCheckBox* _log_warning;
1512 wxCheckBox* _log_error;
1513 wxCheckBox* _log_timing;
1514 wxCheckBox* _log_debug_decode;
1515 wxCheckBox* _log_debug_encode;
1516 wxCheckBox* _log_debug_email;
1517 #ifdef DCPOMATIC_WINDOWS
1518 wxCheckBox* _win32_console;
1522 wxPreferencesEditor*
1523 create_full_config_dialog ()
1525 wxPreferencesEditor* e = new wxPreferencesEditor ();
1527 #ifdef DCPOMATIC_OSX
1528 /* Width that we force some of the config panels to be on OSX so that
1529 the containing window doesn't shrink too much when we select those panels.
1530 This is obviously an unpleasant hack.
1532 wxSize ps = wxSize (700, -1);
1533 int const border = 16;
1535 wxSize ps = wxSize (-1, -1);
1536 int const border = 8;
1539 e->AddPage (new FullGeneralPage (ps, border));
1540 e->AddPage (new SoundPage (ps, border));
1541 e->AddPage (new DefaultsPage (ps, border));
1542 e->AddPage (new EncodingServersPage (ps, border));
1543 e->AddPage (new KeysPage (ps, border));
1544 e->AddPage (new TMSPage (ps, border));
1545 e->AddPage (new EmailPage (ps, border));
1546 e->AddPage (new KDMEmailPage (ps, border));
1547 e->AddPage (new NotificationsPage (ps, border));
1548 e->AddPage (new CoverSheetPage (ps, border));
1549 e->AddPage (new AdvancedPage (ps, border));