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 _upload_after_make_dcp = new CheckBox (_panel, _("Default to enabling upload of DCP to TMS"));
383 table->Add (_upload_after_make_dcp, 1, wxEXPAND);
385 _still_length->SetRange (1, 3600);
386 _still_length->Bind (wxEVT_SPINCTRL, boost::bind (&DefaultsPage::still_length_changed, this));
388 _directory->Bind (wxEVT_DIRPICKER_CHANGED, boost::bind (&DefaultsPage::directory_changed, this));
389 _kdm_directory->Bind (wxEVT_DIRPICKER_CHANGED, boost::bind (&DefaultsPage::kdm_directory_changed, this));
391 _isdcf_metadata_button->Bind (wxEVT_BUTTON, boost::bind (&DefaultsPage::edit_isdcf_metadata_clicked, this));
393 BOOST_FOREACH (Ratio const * i, Ratio::containers()) {
394 _container->Append (std_to_wx(i->container_nickname()));
397 _container->Bind (wxEVT_CHOICE, boost::bind (&DefaultsPage::container_changed, this));
399 BOOST_FOREACH (DCPContentType const * i, DCPContentType::all()) {
400 _dcp_content_type->Append (std_to_wx (i->pretty_name ()));
403 setup_audio_channels_choice (_dcp_audio_channels, 2);
405 _dcp_content_type->Bind (wxEVT_CHOICE, boost::bind (&DefaultsPage::dcp_content_type_changed, this));
406 _dcp_audio_channels->Bind (wxEVT_CHOICE, boost::bind (&DefaultsPage::dcp_audio_channels_changed, this));
408 _j2k_bandwidth->SetRange (50, 250);
409 _j2k_bandwidth->Bind (wxEVT_SPINCTRL, boost::bind (&DefaultsPage::j2k_bandwidth_changed, this));
411 _audio_delay->SetRange (-1000, 1000);
412 _audio_delay->Bind (wxEVT_SPINCTRL, boost::bind (&DefaultsPage::audio_delay_changed, this));
414 _standard->Append (_("SMPTE"));
415 _standard->Append (_("Interop"));
416 _standard->Bind (wxEVT_CHOICE, boost::bind (&DefaultsPage::standard_changed, this));
418 _upload_after_make_dcp->Bind (wxEVT_CHECKBOX, boost::bind (&DefaultsPage::upload_after_make_dcp_changed, this));
421 void config_changed ()
423 Config* config = Config::instance ();
425 vector<Ratio const *> containers = Ratio::containers ();
426 for (size_t i = 0; i < containers.size(); ++i) {
427 if (containers[i] == config->default_container ()) {
428 _container->SetSelection (i);
432 vector<DCPContentType const *> const ct = DCPContentType::all ();
433 for (size_t i = 0; i < ct.size(); ++i) {
434 if (ct[i] == config->default_dcp_content_type ()) {
435 _dcp_content_type->SetSelection (i);
439 checked_set (_still_length, config->default_still_length ());
440 _directory->SetPath (std_to_wx (config->default_directory_or (wx_to_std (wxStandardPaths::Get().GetDocumentsDir())).string ()));
441 _kdm_directory->SetPath (std_to_wx (config->default_kdm_directory_or (wx_to_std (wxStandardPaths::Get().GetDocumentsDir())).string ()));
442 checked_set (_j2k_bandwidth, config->default_j2k_bandwidth() / 1000000);
443 _j2k_bandwidth->SetRange (50, config->maximum_j2k_bandwidth() / 1000000);
444 checked_set (_dcp_audio_channels, locale_convert<string> (config->default_dcp_audio_channels()));
445 checked_set (_audio_delay, config->default_audio_delay ());
446 checked_set (_standard, config->default_interop() ? 1 : 0);
447 checked_set (_upload_after_make_dcp, config->default_upload_after_make_dcp());
450 void j2k_bandwidth_changed ()
452 Config::instance()->set_default_j2k_bandwidth (_j2k_bandwidth->GetValue() * 1000000);
455 void audio_delay_changed ()
457 Config::instance()->set_default_audio_delay (_audio_delay->GetValue());
460 void dcp_audio_channels_changed ()
462 int const s = _dcp_audio_channels->GetSelection ();
463 if (s != wxNOT_FOUND) {
464 Config::instance()->set_default_dcp_audio_channels (
465 locale_convert<int> (string_client_data (_dcp_audio_channels->GetClientObject (s)))
470 void directory_changed ()
472 Config::instance()->set_default_directory (wx_to_std (_directory->GetPath ()));
475 void kdm_directory_changed ()
477 Config::instance()->set_default_kdm_directory (wx_to_std (_kdm_directory->GetPath ()));
480 void edit_isdcf_metadata_clicked ()
482 ISDCFMetadataDialog* d = new ISDCFMetadataDialog (_panel, Config::instance()->default_isdcf_metadata (), false);
484 Config::instance()->set_default_isdcf_metadata (d->isdcf_metadata ());
488 void still_length_changed ()
490 Config::instance()->set_default_still_length (_still_length->GetValue ());
493 void container_changed ()
495 vector<Ratio const *> ratio = Ratio::containers ();
496 Config::instance()->set_default_container (ratio[_container->GetSelection()]);
499 void dcp_content_type_changed ()
501 vector<DCPContentType const *> ct = DCPContentType::all ();
502 Config::instance()->set_default_dcp_content_type (ct[_dcp_content_type->GetSelection()]);
505 void standard_changed ()
507 Config::instance()->set_default_interop (_standard->GetSelection() == 1);
510 void upload_after_make_dcp_changed ()
512 Config::instance()->set_default_upload_after_make_dcp (_upload_after_make_dcp->GetValue ());
515 wxSpinCtrl* _j2k_bandwidth;
516 wxSpinCtrl* _audio_delay;
517 wxButton* _isdcf_metadata_button;
518 wxSpinCtrl* _still_length;
519 #ifdef DCPOMATIC_USE_OWN_PICKER
520 DirPickerCtrl* _directory;
521 DirPickerCtrl* _kdm_directory;
523 wxDirPickerCtrl* _directory;
524 wxDirPickerCtrl* _kdm_directory;
526 wxChoice* _container;
527 wxChoice* _dcp_content_type;
528 wxChoice* _dcp_audio_channels;
530 wxCheckBox* _upload_after_make_dcp;
533 class EncodingServersPage : public StandardPage
536 EncodingServersPage (wxSize panel_size, int border)
537 : StandardPage (panel_size, border)
540 wxString GetName () const
546 wxBitmap GetLargeIcon () const
548 return wxBitmap ("servers", wxBITMAP_TYPE_PNG_RESOURCE);
555 _use_any_servers = new CheckBox (_panel, _("Search network for servers"));
556 _panel->GetSizer()->Add (_use_any_servers, 0, wxALL, _border);
558 vector<EditableListColumn> columns;
559 columns.push_back (EditableListColumn(wx_to_std(_("IP address / host name"))));
560 _servers_list = new EditableList<string, ServerDialog> (
563 boost::bind (&Config::servers, Config::instance()),
564 boost::bind (&Config::set_servers, Config::instance(), _1),
565 boost::bind (&EncodingServersPage::server_column, this, _1)
568 _panel->GetSizer()->Add (_servers_list, 1, wxEXPAND | wxALL, _border);
570 _use_any_servers->Bind (wxEVT_CHECKBOX, boost::bind (&EncodingServersPage::use_any_servers_changed, this));
573 void config_changed ()
575 checked_set (_use_any_servers, Config::instance()->use_any_servers ());
576 _servers_list->refresh ();
579 void use_any_servers_changed ()
581 Config::instance()->set_use_any_servers (_use_any_servers->GetValue ());
584 string server_column (string s)
589 wxCheckBox* _use_any_servers;
590 EditableList<string, ServerDialog>* _servers_list;
593 class TMSPage : public StandardPage
596 TMSPage (wxSize panel_size, int border)
597 : StandardPage (panel_size, border)
600 wxString GetName () const
606 wxBitmap GetLargeIcon () const
608 return wxBitmap ("tms", wxBITMAP_TYPE_PNG_RESOURCE);
615 wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
616 table->AddGrowableCol (1, 1);
617 _panel->GetSizer()->Add (table, 1, wxALL | wxEXPAND, _border);
619 add_label_to_sizer (table, _panel, _("Protocol"), true);
620 _tms_protocol = new wxChoice (_panel, wxID_ANY);
621 table->Add (_tms_protocol, 1, wxEXPAND);
623 add_label_to_sizer (table, _panel, _("IP address"), true);
624 _tms_ip = new wxTextCtrl (_panel, wxID_ANY);
625 table->Add (_tms_ip, 1, wxEXPAND);
627 add_label_to_sizer (table, _panel, _("Target path"), true);
628 _tms_path = new wxTextCtrl (_panel, wxID_ANY);
629 table->Add (_tms_path, 1, wxEXPAND);
631 add_label_to_sizer (table, _panel, _("User name"), true);
632 _tms_user = new wxTextCtrl (_panel, wxID_ANY);
633 table->Add (_tms_user, 1, wxEXPAND);
635 add_label_to_sizer (table, _panel, _("Password"), true);
636 _tms_password = new PasswordEntry (_panel);
637 table->Add (_tms_password->get_panel(), 1, wxEXPAND);
639 _tms_protocol->Append (_("SCP (for AAM and Doremi)"));
640 _tms_protocol->Append (_("FTP (for Dolby)"));
642 _tms_protocol->Bind (wxEVT_CHOICE, boost::bind (&TMSPage::tms_protocol_changed, this));
643 _tms_ip->Bind (wxEVT_TEXT, boost::bind (&TMSPage::tms_ip_changed, this));
644 _tms_path->Bind (wxEVT_TEXT, boost::bind (&TMSPage::tms_path_changed, this));
645 _tms_user->Bind (wxEVT_TEXT, boost::bind (&TMSPage::tms_user_changed, this));
646 _tms_password->Changed.connect (boost::bind (&TMSPage::tms_password_changed, this));
649 void config_changed ()
651 Config* config = Config::instance ();
653 checked_set (_tms_protocol, config->tms_protocol ());
654 checked_set (_tms_ip, config->tms_ip ());
655 checked_set (_tms_path, config->tms_path ());
656 checked_set (_tms_user, config->tms_user ());
657 checked_set (_tms_password, config->tms_password ());
660 void tms_protocol_changed ()
662 Config::instance()->set_tms_protocol(static_cast<FileTransferProtocol>(_tms_protocol->GetSelection()));
665 void tms_ip_changed ()
667 Config::instance()->set_tms_ip (wx_to_std (_tms_ip->GetValue ()));
670 void tms_path_changed ()
672 Config::instance()->set_tms_path (wx_to_std (_tms_path->GetValue ()));
675 void tms_user_changed ()
677 Config::instance()->set_tms_user (wx_to_std (_tms_user->GetValue ()));
680 void tms_password_changed ()
682 Config::instance()->set_tms_password (_tms_password->get());
685 wxChoice* _tms_protocol;
687 wxTextCtrl* _tms_path;
688 wxTextCtrl* _tms_user;
689 PasswordEntry* _tms_password;
698 class EmailPage : public StandardPage
701 EmailPage (wxSize panel_size, int border)
702 : StandardPage (panel_size, border)
705 wxString GetName () const
711 wxBitmap GetLargeIcon () const
713 return wxBitmap ("email", wxBITMAP_TYPE_PNG_RESOURCE);
720 wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
721 table->AddGrowableCol (1, 1);
722 _panel->GetSizer()->Add (table, 1, wxEXPAND | wxALL, _border);
724 add_label_to_sizer (table, _panel, _("Outgoing mail server"), true);
726 wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL);
727 _server = new wxTextCtrl (_panel, wxID_ANY);
728 s->Add (_server, 1, wxEXPAND | wxALL);
729 add_label_to_sizer (s, _panel, _("port"), false);
730 _port = new wxSpinCtrl (_panel, wxID_ANY);
731 _port->SetRange (0, 65535);
733 add_label_to_sizer (s, _panel, _("protocol"), false);
734 _protocol = new wxChoice (_panel, wxID_ANY);
735 /* Make sure this matches the switches in config_changed and port_changed below */
736 _protocol->Append (_("Auto"));
737 _protocol->Append (_("Plain"));
738 _protocol->Append (_("STARTTLS"));
739 _protocol->Append (_("SSL"));
741 table->Add (s, 1, wxEXPAND | wxALL);
744 add_label_to_sizer (table, _panel, _("User name"), true);
745 _user = new wxTextCtrl (_panel, wxID_ANY);
746 table->Add (_user, 1, wxEXPAND | wxALL);
748 add_label_to_sizer (table, _panel, _("Password"), true);
749 _password = new PasswordEntry (_panel);
750 table->Add (_password->get_panel(), 1, wxEXPAND | wxALL);
752 _server->Bind (wxEVT_TEXT, boost::bind (&EmailPage::server_changed, this));
753 _port->Bind (wxEVT_SPINCTRL, boost::bind (&EmailPage::port_changed, this));
754 _protocol->Bind (wxEVT_CHOICE, boost::bind (&EmailPage::protocol_changed, this));
755 _user->Bind (wxEVT_TEXT, boost::bind (&EmailPage::user_changed, this));
756 _password->Changed.connect (boost::bind (&EmailPage::password_changed, this));
759 void config_changed ()
761 Config* config = Config::instance ();
763 checked_set (_server, config->mail_server ());
764 checked_set (_port, config->mail_port ());
765 switch (config->mail_protocol()) {
766 case EMAIL_PROTOCOL_AUTO:
767 checked_set (_protocol, 0);
769 case EMAIL_PROTOCOL_PLAIN:
770 checked_set (_protocol, 1);
772 case EMAIL_PROTOCOL_STARTTLS:
773 checked_set (_protocol, 2);
775 case EMAIL_PROTOCOL_SSL:
776 checked_set (_protocol, 3);
779 checked_set (_user, config->mail_user ());
780 checked_set (_password, config->mail_password());
783 void server_changed ()
785 Config::instance()->set_mail_server (wx_to_std (_server->GetValue ()));
790 Config::instance()->set_mail_port (_port->GetValue ());
793 void protocol_changed ()
795 switch (_protocol->GetSelection()) {
797 Config::instance()->set_mail_protocol(EMAIL_PROTOCOL_AUTO);
800 Config::instance()->set_mail_protocol(EMAIL_PROTOCOL_PLAIN);
803 Config::instance()->set_mail_protocol(EMAIL_PROTOCOL_STARTTLS);
806 Config::instance()->set_mail_protocol(EMAIL_PROTOCOL_SSL);
813 Config::instance()->set_mail_user (wx_to_std (_user->GetValue ()));
816 void password_changed ()
818 Config::instance()->set_mail_password(_password->get());
825 PasswordEntry* _password;
828 class KDMEmailPage : public StandardPage
832 KDMEmailPage (wxSize panel_size, int border)
834 /* We have to force both width and height of this one */
835 : StandardPage (wxSize (panel_size.GetWidth(), 128), border)
837 : StandardPage (panel_size, border)
841 wxString GetName () const
843 return _("KDM Email");
847 wxBitmap GetLargeIcon () const
849 return wxBitmap ("kdm_email", wxBITMAP_TYPE_PNG_RESOURCE);
856 wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
857 table->AddGrowableCol (1, 1);
858 _panel->GetSizer()->Add (table, 1, wxEXPAND | wxALL, _border);
860 add_label_to_sizer (table, _panel, _("Subject"), true);
861 _subject = new wxTextCtrl (_panel, wxID_ANY);
862 table->Add (_subject, 1, wxEXPAND | wxALL);
864 add_label_to_sizer (table, _panel, _("From address"), true);
865 _from = new wxTextCtrl (_panel, wxID_ANY);
866 table->Add (_from, 1, wxEXPAND | wxALL);
868 vector<EditableListColumn> columns;
869 columns.push_back (EditableListColumn(wx_to_std(_("Address"))));
870 add_label_to_sizer (table, _panel, _("CC addresses"), true);
871 _cc = new EditableList<string, EmailDialog> (
874 bind (&Config::kdm_cc, Config::instance()),
875 bind (&Config::set_kdm_cc, Config::instance(), _1),
878 table->Add (_cc, 1, wxEXPAND | wxALL);
880 add_label_to_sizer (table, _panel, _("BCC address"), true);
881 _bcc = new wxTextCtrl (_panel, wxID_ANY);
882 table->Add (_bcc, 1, wxEXPAND | wxALL);
884 _email = new wxTextCtrl (_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize (-1, 200), wxTE_MULTILINE);
885 _panel->GetSizer()->Add (_email, 0, wxEXPAND | wxALL, _border);
887 _reset_email = new Button (_panel, _("Reset to default subject and text"));
888 _panel->GetSizer()->Add (_reset_email, 0, wxEXPAND | wxALL, _border);
892 _subject->Bind (wxEVT_TEXT, boost::bind (&KDMEmailPage::kdm_subject_changed, this));
893 _from->Bind (wxEVT_TEXT, boost::bind (&KDMEmailPage::kdm_from_changed, this));
894 _bcc->Bind (wxEVT_TEXT, boost::bind (&KDMEmailPage::kdm_bcc_changed, this));
895 _email->Bind (wxEVT_TEXT, boost::bind (&KDMEmailPage::kdm_email_changed, this));
896 _reset_email->Bind (wxEVT_BUTTON, boost::bind (&KDMEmailPage::reset_email, this));
899 void config_changed ()
901 Config* config = Config::instance ();
903 checked_set (_subject, config->kdm_subject ());
904 checked_set (_from, config->kdm_from ());
905 checked_set (_bcc, config->kdm_bcc ());
906 checked_set (_email, Config::instance()->kdm_email ());
909 void kdm_subject_changed ()
911 Config::instance()->set_kdm_subject (wx_to_std (_subject->GetValue ()));
914 void kdm_from_changed ()
916 Config::instance()->set_kdm_from (wx_to_std (_from->GetValue ()));
919 void kdm_bcc_changed ()
921 Config::instance()->set_kdm_bcc (wx_to_std (_bcc->GetValue ()));
924 void kdm_email_changed ()
926 if (_email->GetValue().IsEmpty ()) {
927 /* Sometimes we get sent an erroneous notification that the email
928 is empty; I don't know why.
932 Config::instance()->set_kdm_email (wx_to_std (_email->GetValue ()));
937 Config::instance()->reset_kdm_email ();
938 checked_set (_email, Config::instance()->kdm_email ());
941 wxTextCtrl* _subject;
943 EditableList<string, EmailDialog>* _cc;
946 wxButton* _reset_email;
949 class NotificationsPage : public StandardPage
952 NotificationsPage (wxSize panel_size, int border)
954 /* We have to force both width and height of this one */
955 : StandardPage (wxSize (panel_size.GetWidth(), 128), border)
957 : StandardPage (panel_size, border)
961 wxString GetName () const
963 return _("Notifications");
967 wxBitmap GetLargeIcon () const
969 return wxBitmap ("notifications", wxBITMAP_TYPE_PNG_RESOURCE);
976 wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
977 table->AddGrowableCol (1, 1);
978 _panel->GetSizer()->Add (table, 1, wxEXPAND | wxALL, _border);
980 _enable_message_box = new CheckBox (_panel, _("Message box"));
981 table->Add (_enable_message_box, 1, wxEXPAND | wxALL);
982 table->AddSpacer (0);
984 _enable_email = new CheckBox (_panel, _("Email"));
985 table->Add (_enable_email, 1, wxEXPAND | wxALL);
986 table->AddSpacer (0);
988 add_label_to_sizer (table, _panel, _("Subject"), true);
989 _subject = new wxTextCtrl (_panel, wxID_ANY);
990 table->Add (_subject, 1, wxEXPAND | wxALL);
992 add_label_to_sizer (table, _panel, _("From address"), true);
993 _from = new wxTextCtrl (_panel, wxID_ANY);
994 table->Add (_from, 1, wxEXPAND | wxALL);
996 add_label_to_sizer (table, _panel, _("To address"), true);
997 _to = new wxTextCtrl (_panel, wxID_ANY);
998 table->Add (_to, 1, wxEXPAND | wxALL);
1000 vector<EditableListColumn> columns;
1001 columns.push_back (EditableListColumn(wx_to_std(_("Address"))));
1002 add_label_to_sizer (table, _panel, _("CC addresses"), true);
1003 _cc = new EditableList<string, EmailDialog> (
1006 bind (&Config::notification_cc, Config::instance()),
1007 bind (&Config::set_notification_cc, Config::instance(), _1),
1010 table->Add (_cc, 1, wxEXPAND | wxALL);
1012 add_label_to_sizer (table, _panel, _("BCC address"), true);
1013 _bcc = new wxTextCtrl (_panel, wxID_ANY);
1014 table->Add (_bcc, 1, wxEXPAND | wxALL);
1016 _email = new wxTextCtrl (_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize (-1, 200), wxTE_MULTILINE);
1017 _panel->GetSizer()->Add (_email, 0, wxEXPAND | wxALL, _border);
1019 _reset_email = new Button (_panel, _("Reset to default subject and text"));
1020 _panel->GetSizer()->Add (_reset_email, 0, wxEXPAND | wxALL, _border);
1024 _enable_message_box->Bind (wxEVT_CHECKBOX, boost::bind (&NotificationsPage::type_changed, this, _enable_message_box, Config::MESSAGE_BOX));
1025 _enable_email->Bind (wxEVT_CHECKBOX, boost::bind (&NotificationsPage::type_changed, this, _enable_email, Config::EMAIL));
1027 _subject->Bind (wxEVT_TEXT, boost::bind (&NotificationsPage::notification_subject_changed, this));
1028 _from->Bind (wxEVT_TEXT, boost::bind (&NotificationsPage::notification_from_changed, this));
1029 _to->Bind (wxEVT_TEXT, boost::bind (&NotificationsPage::notification_to_changed, this));
1030 _bcc->Bind (wxEVT_TEXT, boost::bind (&NotificationsPage::notification_bcc_changed, this));
1031 _email->Bind (wxEVT_TEXT, boost::bind (&NotificationsPage::notification_email_changed, this));
1032 _reset_email->Bind (wxEVT_BUTTON, boost::bind (&NotificationsPage::reset_email, this));
1034 update_sensitivity ();
1037 void update_sensitivity ()
1039 bool const s = _enable_email->GetValue();
1040 _subject->Enable(s);
1046 _reset_email->Enable(s);
1049 void config_changed ()
1051 Config* config = Config::instance ();
1053 checked_set (_enable_message_box, config->notification(Config::MESSAGE_BOX));
1054 checked_set (_enable_email, config->notification(Config::EMAIL));
1055 checked_set (_subject, config->notification_subject ());
1056 checked_set (_from, config->notification_from ());
1057 checked_set (_to, config->notification_to ());
1058 checked_set (_bcc, config->notification_bcc ());
1059 checked_set (_email, Config::instance()->notification_email ());
1061 update_sensitivity ();
1064 void notification_subject_changed ()
1066 Config::instance()->set_notification_subject (wx_to_std (_subject->GetValue ()));
1069 void notification_from_changed ()
1071 Config::instance()->set_notification_from (wx_to_std (_from->GetValue ()));
1074 void notification_to_changed ()
1076 Config::instance()->set_notification_to (wx_to_std (_to->GetValue ()));
1079 void notification_bcc_changed ()
1081 Config::instance()->set_notification_bcc (wx_to_std (_bcc->GetValue ()));
1084 void notification_email_changed ()
1086 if (_email->GetValue().IsEmpty ()) {
1087 /* Sometimes we get sent an erroneous notification that the email
1088 is empty; I don't know why.
1092 Config::instance()->set_notification_email (wx_to_std (_email->GetValue ()));
1097 Config::instance()->reset_notification_email ();
1098 checked_set (_email, Config::instance()->notification_email ());
1101 void type_changed (wxCheckBox* b, Config::Notification n)
1103 Config::instance()->set_notification(n, b->GetValue());
1104 update_sensitivity ();
1107 wxCheckBox* _enable_message_box;
1108 wxCheckBox* _enable_email;
1110 wxTextCtrl* _subject;
1113 EditableList<string, EmailDialog>* _cc;
1116 wxButton* _reset_email;
1119 class CoverSheetPage : public StandardPage
1123 CoverSheetPage (wxSize panel_size, int border)
1124 #ifdef DCPOMATIC_OSX
1125 /* We have to force both width and height of this one */
1126 : StandardPage (wxSize (panel_size.GetWidth(), 128), border)
1128 : StandardPage (panel_size, border)
1132 wxString GetName () const
1134 return _("Cover Sheet");
1137 #ifdef DCPOMATIC_OSX
1138 wxBitmap GetLargeIcon () const
1140 return wxBitmap ("cover_sheet", wxBITMAP_TYPE_PNG_RESOURCE);
1147 _cover_sheet = new wxTextCtrl (_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize (-1, 200), wxTE_MULTILINE);
1148 _panel->GetSizer()->Add (_cover_sheet, 0, wxEXPAND | wxALL, _border);
1150 _reset_cover_sheet = new Button (_panel, _("Reset to default text"));
1151 _panel->GetSizer()->Add (_reset_cover_sheet, 0, wxEXPAND | wxALL, _border);
1153 _cover_sheet->Bind (wxEVT_TEXT, boost::bind (&CoverSheetPage::cover_sheet_changed, this));
1154 _reset_cover_sheet->Bind (wxEVT_BUTTON, boost::bind (&CoverSheetPage::reset_cover_sheet, this));
1157 void config_changed ()
1159 checked_set (_cover_sheet, Config::instance()->cover_sheet ());
1162 void cover_sheet_changed ()
1164 if (_cover_sheet->GetValue().IsEmpty ()) {
1165 /* Sometimes we get sent an erroneous notification that the cover sheet
1166 is empty; I don't know why.
1170 Config::instance()->set_cover_sheet (wx_to_std (_cover_sheet->GetValue ()));
1173 void reset_cover_sheet ()
1175 Config::instance()->reset_cover_sheet ();
1176 checked_set (_cover_sheet, Config::instance()->cover_sheet ());
1179 wxTextCtrl* _cover_sheet;
1180 wxButton* _reset_cover_sheet;
1184 /** @class AdvancedPage
1185 * @brief Advanced page of the preferences dialog.
1187 class AdvancedPage : public StockPage
1190 AdvancedPage (wxSize panel_size, int border)
1191 : StockPage (Kind_Advanced, panel_size, border)
1192 , _maximum_j2k_bandwidth (0)
1193 , _allow_any_dcp_frame_rate (0)
1194 , _allow_any_container (0)
1195 , _show_experimental_audio_processors (0)
1196 , _only_servers_encode (0)
1201 , _log_debug_threed (0)
1202 , _log_debug_encode (0)
1203 , _log_debug_email (0)
1207 void add_top_aligned_label_to_sizer (wxSizer* table, wxWindow* parent, wxString text)
1209 int flags = wxALIGN_TOP | wxTOP | wxLEFT;
1211 flags |= wxALIGN_RIGHT;
1214 wxStaticText* m = new StaticText (parent, text);
1215 table->Add (m, 0, flags, DCPOMATIC_SIZER_Y_GAP);
1220 wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
1221 table->AddGrowableCol (1, 1);
1222 _panel->GetSizer()->Add (table, 1, wxALL | wxEXPAND, _border);
1225 add_label_to_sizer (table, _panel, _("Maximum JPEG2000 bandwidth"), true);
1226 wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL);
1227 _maximum_j2k_bandwidth = new wxSpinCtrl (_panel);
1228 s->Add (_maximum_j2k_bandwidth, 1);
1229 add_label_to_sizer (s, _panel, _("Mbit/s"), false);
1233 add_label_to_sizer (table, _panel, _("Video display mode"), true);
1234 _video_display_mode = new wxChoice (_panel, wxID_ANY);
1235 table->Add (_video_display_mode);
1237 wxStaticText* restart = add_label_to_sizer (table, _panel, _("(restart DCP-o-matic to change display mode)"), false);
1238 wxFont font = restart->GetFont();
1239 font.SetStyle (wxFONTSTYLE_ITALIC);
1240 font.SetPointSize (font.GetPointSize() - 1);
1241 restart->SetFont (font);
1242 table->AddSpacer (0);
1244 _allow_any_dcp_frame_rate = new CheckBox (_panel, _("Allow any DCP frame rate"));
1245 table->Add (_allow_any_dcp_frame_rate, 1, wxEXPAND | wxALL);
1246 table->AddSpacer (0);
1248 _allow_any_container = new CheckBox (_panel, _("Allow full-frame and non-standard container ratios"));
1249 table->Add (_allow_any_container, 1, wxEXPAND | wxALL);
1250 table->AddSpacer (0);
1252 restart = add_label_to_sizer (table, _panel, _("(restart DCP-o-matic to see all ratios)"), false);
1253 restart->SetFont (font);
1254 table->AddSpacer (0);
1256 _show_experimental_audio_processors = new CheckBox (_panel, _("Show experimental audio processors"));
1257 table->Add (_show_experimental_audio_processors, 1, wxEXPAND | wxALL);
1258 table->AddSpacer (0);
1260 _only_servers_encode = new CheckBox (_panel, _("Only servers encode"));
1261 table->Add (_only_servers_encode, 1, wxEXPAND | wxALL);
1262 table->AddSpacer (0);
1265 add_label_to_sizer (table, _panel, _("Maximum number of frames to store per thread"), true);
1266 wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL);
1267 _frames_in_memory_multiplier = new wxSpinCtrl (_panel);
1268 s->Add (_frames_in_memory_multiplier, 1);
1273 add_top_aligned_label_to_sizer (table, _panel, _("DCP metadata filename format"));
1274 dcp::NameFormat::Map titles;
1275 titles['t'] = wx_to_std (_("type (cpl/pkl)"));
1276 dcp::NameFormat::Map examples;
1277 examples['t'] = "cpl";
1278 _dcp_metadata_filename_format = new NameFormatEditor (
1279 _panel, Config::instance()->dcp_metadata_filename_format(), titles, examples, "_eb1c112c-ca3c-4ae6-9263-c6714ff05d64.xml"
1281 table->Add (_dcp_metadata_filename_format->panel(), 1, wxEXPAND | wxALL);
1285 add_top_aligned_label_to_sizer (table, _panel, _("DCP asset filename format"));
1286 dcp::NameFormat::Map titles;
1287 titles['t'] = wx_to_std (_("type (j2c/pcm/sub)"));
1288 titles['r'] = wx_to_std (_("reel number"));
1289 titles['n'] = wx_to_std (_("number of reels"));
1290 titles['c'] = wx_to_std (_("content filename"));
1291 dcp::NameFormat::Map examples;
1292 examples['t'] = "j2c";
1293 examples['r'] = "1";
1294 examples['n'] = "4";
1295 examples['c'] = "myfile.mp4";
1296 _dcp_asset_filename_format = new NameFormatEditor (
1297 _panel, Config::instance()->dcp_asset_filename_format(), titles, examples, "_eb1c112c-ca3c-4ae6-9263-c6714ff05d64.mxf"
1299 table->Add (_dcp_asset_filename_format->panel(), 1, wxEXPAND | wxALL);
1303 add_top_aligned_label_to_sizer (table, _panel, _("Log"));
1304 wxBoxSizer* t = new wxBoxSizer (wxVERTICAL);
1305 _log_general = new CheckBox (_panel, _("General"));
1306 t->Add (_log_general, 1, wxEXPAND | wxALL);
1307 _log_warning = new CheckBox (_panel, _("Warnings"));
1308 t->Add (_log_warning, 1, wxEXPAND | wxALL);
1309 _log_error = new CheckBox (_panel, _("Errors"));
1310 t->Add (_log_error, 1, wxEXPAND | wxALL);
1311 /// TRANSLATORS: translate the word "Timing" here; do not include the "Config|" prefix
1312 _log_timing = new CheckBox (_panel, S_("Config|Timing"));
1313 t->Add (_log_timing, 1, wxEXPAND | wxALL);
1314 _log_debug_threed = new CheckBox (_panel, _("Debug: 3D"));
1315 t->Add (_log_debug_threed, 1, wxEXPAND | wxALL);
1316 _log_debug_encode = new CheckBox (_panel, _("Debug: encode"));
1317 t->Add (_log_debug_encode, 1, wxEXPAND | wxALL);
1318 _log_debug_email = new CheckBox (_panel, _("Debug: email sending"));
1319 t->Add (_log_debug_email, 1, wxEXPAND | wxALL);
1320 table->Add (t, 0, wxALL, 6);
1323 #ifdef DCPOMATIC_WINDOWS
1324 _win32_console = new CheckBox (_panel, _("Open console window"));
1325 table->Add (_win32_console, 1, wxEXPAND | wxALL);
1326 table->AddSpacer (0);
1329 _maximum_j2k_bandwidth->SetRange (1, 1000);
1330 _maximum_j2k_bandwidth->Bind (wxEVT_SPINCTRL, boost::bind (&AdvancedPage::maximum_j2k_bandwidth_changed, this));
1331 _video_display_mode->Append (_("Simple (safer)"));
1332 _video_display_mode->Append (_("OpenGL (faster)"));
1333 _video_display_mode->Bind (wxEVT_CHOICE, boost::bind(&AdvancedPage::video_display_mode_changed, this));
1334 _allow_any_dcp_frame_rate->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::allow_any_dcp_frame_rate_changed, this));
1335 _allow_any_container->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::allow_any_container_changed, this));
1336 _show_experimental_audio_processors->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::show_experimental_audio_processors_changed, this));
1337 _only_servers_encode->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::only_servers_encode_changed, this));
1338 _frames_in_memory_multiplier->Bind (wxEVT_SPINCTRL, boost::bind(&AdvancedPage::frames_in_memory_multiplier_changed, this));
1339 _dcp_metadata_filename_format->Changed.connect (boost::bind (&AdvancedPage::dcp_metadata_filename_format_changed, this));
1340 _dcp_asset_filename_format->Changed.connect (boost::bind (&AdvancedPage::dcp_asset_filename_format_changed, this));
1341 _log_general->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::log_changed, this));
1342 _log_warning->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::log_changed, this));
1343 _log_error->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::log_changed, this));
1344 _log_timing->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::log_changed, this));
1345 _log_debug_threed->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::log_changed, this));
1346 _log_debug_encode->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::log_changed, this));
1347 _log_debug_email->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::log_changed, this));
1348 #ifdef DCPOMATIC_WINDOWS
1349 _win32_console->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::win32_console_changed, this));
1353 void config_changed ()
1355 Config* config = Config::instance ();
1357 checked_set (_maximum_j2k_bandwidth, config->maximum_j2k_bandwidth() / 1000000);
1358 switch (config->video_view_type()) {
1359 case Config::VIDEO_VIEW_SIMPLE:
1360 checked_set (_video_display_mode, 0);
1362 case Config::VIDEO_VIEW_OPENGL:
1363 checked_set (_video_display_mode, 1);
1366 checked_set (_allow_any_dcp_frame_rate, config->allow_any_dcp_frame_rate ());
1367 checked_set (_allow_any_container, config->allow_any_container ());
1368 checked_set (_show_experimental_audio_processors, config->show_experimental_audio_processors ());
1369 checked_set (_only_servers_encode, config->only_servers_encode ());
1370 checked_set (_log_general, config->log_types() & LogEntry::TYPE_GENERAL);
1371 checked_set (_log_warning, config->log_types() & LogEntry::TYPE_WARNING);
1372 checked_set (_log_error, config->log_types() & LogEntry::TYPE_ERROR);
1373 checked_set (_log_timing, config->log_types() & LogEntry::TYPE_TIMING);
1374 checked_set (_log_debug_threed, config->log_types() & LogEntry::TYPE_DEBUG_THREED);
1375 checked_set (_log_debug_encode, config->log_types() & LogEntry::TYPE_DEBUG_ENCODE);
1376 checked_set (_log_debug_email, config->log_types() & LogEntry::TYPE_DEBUG_EMAIL);
1377 checked_set (_frames_in_memory_multiplier, config->frames_in_memory_multiplier());
1378 #ifdef DCPOMATIC_WINDOWS
1379 checked_set (_win32_console, config->win32_console());
1383 void maximum_j2k_bandwidth_changed ()
1385 Config::instance()->set_maximum_j2k_bandwidth (_maximum_j2k_bandwidth->GetValue() * 1000000);
1388 void video_display_mode_changed ()
1390 if (_video_display_mode->GetSelection() == 0) {
1391 Config::instance()->set_video_view_type (Config::VIDEO_VIEW_SIMPLE);
1393 Config::instance()->set_video_view_type (Config::VIDEO_VIEW_OPENGL);
1397 void frames_in_memory_multiplier_changed ()
1399 Config::instance()->set_frames_in_memory_multiplier (_frames_in_memory_multiplier->GetValue());
1402 void allow_any_dcp_frame_rate_changed ()
1404 Config::instance()->set_allow_any_dcp_frame_rate (_allow_any_dcp_frame_rate->GetValue ());
1407 void allow_any_container_changed ()
1409 Config::instance()->set_allow_any_container (_allow_any_container->GetValue ());
1412 void show_experimental_audio_processors_changed ()
1414 Config::instance()->set_show_experimental_audio_processors (_show_experimental_audio_processors->GetValue ());
1417 void only_servers_encode_changed ()
1419 Config::instance()->set_only_servers_encode (_only_servers_encode->GetValue ());
1422 void dcp_metadata_filename_format_changed ()
1424 Config::instance()->set_dcp_metadata_filename_format (_dcp_metadata_filename_format->get ());
1427 void dcp_asset_filename_format_changed ()
1429 Config::instance()->set_dcp_asset_filename_format (_dcp_asset_filename_format->get ());
1435 if (_log_general->GetValue ()) {
1436 types |= LogEntry::TYPE_GENERAL;
1438 if (_log_warning->GetValue ()) {
1439 types |= LogEntry::TYPE_WARNING;
1441 if (_log_error->GetValue ()) {
1442 types |= LogEntry::TYPE_ERROR;
1444 if (_log_timing->GetValue ()) {
1445 types |= LogEntry::TYPE_TIMING;
1447 if (_log_debug_threed->GetValue ()) {
1448 types |= LogEntry::TYPE_DEBUG_THREED;
1450 if (_log_debug_encode->GetValue ()) {
1451 types |= LogEntry::TYPE_DEBUG_ENCODE;
1453 if (_log_debug_email->GetValue ()) {
1454 types |= LogEntry::TYPE_DEBUG_EMAIL;
1456 Config::instance()->set_log_types (types);
1459 #ifdef DCPOMATIC_WINDOWS
1460 void win32_console_changed ()
1462 Config::instance()->set_win32_console (_win32_console->GetValue ());
1466 wxSpinCtrl* _maximum_j2k_bandwidth;
1467 wxChoice* _video_display_mode;
1468 wxSpinCtrl* _frames_in_memory_multiplier;
1469 wxCheckBox* _allow_any_dcp_frame_rate;
1470 wxCheckBox* _allow_any_container;
1471 wxCheckBox* _show_experimental_audio_processors;
1472 wxCheckBox* _only_servers_encode;
1473 NameFormatEditor* _dcp_metadata_filename_format;
1474 NameFormatEditor* _dcp_asset_filename_format;
1475 wxCheckBox* _log_general;
1476 wxCheckBox* _log_warning;
1477 wxCheckBox* _log_error;
1478 wxCheckBox* _log_timing;
1479 wxCheckBox* _log_debug_threed;
1480 wxCheckBox* _log_debug_encode;
1481 wxCheckBox* _log_debug_email;
1482 #ifdef DCPOMATIC_WINDOWS
1483 wxCheckBox* _win32_console;
1487 wxPreferencesEditor*
1488 create_full_config_dialog ()
1490 wxPreferencesEditor* e = new wxPreferencesEditor ();
1492 #ifdef DCPOMATIC_OSX
1493 /* Width that we force some of the config panels to be on OSX so that
1494 the containing window doesn't shrink too much when we select those panels.
1495 This is obviously an unpleasant hack.
1497 wxSize ps = wxSize (700, -1);
1498 int const border = 16;
1500 wxSize ps = wxSize (-1, -1);
1501 int const border = 8;
1504 e->AddPage (new FullGeneralPage (ps, border));
1505 e->AddPage (new SoundPage (ps, border));
1506 e->AddPage (new DefaultsPage (ps, border));
1507 e->AddPage (new EncodingServersPage (ps, border));
1508 e->AddPage (new KeysPage (ps, border));
1509 e->AddPage (new TMSPage (ps, border));
1510 e->AddPage (new EmailPage (ps, border));
1511 e->AddPage (new KDMEmailPage (ps, border));
1512 e->AddPage (new NotificationsPage (ps, border));
1513 e->AddPage (new CoverSheetPage (ps, border));
1514 e->AddPage (new AdvancedPage (ps, border));