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 AccountsPage : public StandardPage
987 AccountsPage (wxSize panel_size, int border)
988 : StandardPage (panel_size, border)
991 wxString GetName () const
993 return _("Accounts");
997 wxBitmap GetLargeIcon () const
999 return wxBitmap ("accounts", wxBITMAP_TYPE_PNG_RESOURCE);
1005 wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
1006 table->AddGrowableCol (1, 1);
1007 _panel->GetSizer()->Add (table, 1, wxEXPAND | wxALL, _border);
1009 add_label_to_sizer (table, _panel, _("certificates.barco.com user name"), true);
1010 _barco_username = new wxTextCtrl (_panel, wxID_ANY);
1011 table->Add (_barco_username, 1, wxEXPAND | wxALL);
1013 add_label_to_sizer (table, _panel, _("certificates.barco.com password"), true);
1014 _barco_password = new PasswordEntry (_panel);
1015 table->Add (_barco_password->get_panel(), 1, wxEXPAND | wxALL);
1017 add_label_to_sizer (table, _panel, _("certificates.christiedigital.com user name"), true);
1018 _christie_username = new wxTextCtrl (_panel, wxID_ANY);
1019 table->Add (_christie_username, 1, wxEXPAND | wxALL);
1021 add_label_to_sizer (table, _panel, _("certificates.christiedigital.com password"), true);
1022 _christie_password = new PasswordEntry (_panel);
1023 table->Add (_christie_password->get_panel(), 1, wxEXPAND | wxALL);
1025 add_label_to_sizer (table, _panel, _("GDC user name"), true);
1026 _gdc_username = new wxTextCtrl (_panel, wxID_ANY);
1027 table->Add (_gdc_username, 1, wxEXPAND | wxALL);
1029 add_label_to_sizer (table, _panel, _("GDC password"), true);
1030 _gdc_password = new PasswordEntry (_panel);
1031 table->Add (_gdc_password->get_panel(), 1, wxEXPAND | wxALL);
1033 _barco_username->Bind (wxEVT_TEXT, boost::bind(&AccountsPage::barco_username_changed, this));
1034 _barco_password->Changed.connect (boost::bind(&AccountsPage::barco_password_changed, this));
1035 _christie_username->Bind (wxEVT_TEXT, boost::bind(&AccountsPage::christie_username_changed, this));
1036 _christie_password->Changed.connect (boost::bind(&AccountsPage::christie_password_changed, this));
1037 _gdc_username->Bind (wxEVT_TEXT, boost::bind(&AccountsPage::gdc_username_changed, this));
1038 _gdc_password->Changed.connect (boost::bind(&AccountsPage::gdc_password_changed, this));
1041 void config_changed ()
1043 Config* config = Config::instance ();
1045 checked_set (_barco_username, config->barco_username().get_value_or(""));
1046 checked_set (_barco_password, config->barco_password().get_value_or(""));
1047 checked_set (_christie_username, config->christie_username().get_value_or(""));
1048 checked_set (_christie_password, config->christie_password().get_value_or(""));
1049 checked_set (_gdc_username, config->gdc_username().get_value_or(""));
1050 checked_set (_gdc_password, config->gdc_password().get_value_or(""));
1053 void barco_username_changed ()
1055 wxString const s = _barco_username->GetValue();
1057 Config::instance()->set_barco_username (wx_to_std(s));
1059 Config::instance()->unset_barco_username ();
1063 void barco_password_changed ()
1065 string const s = _barco_password->get();
1067 Config::instance()->set_barco_password(s);
1069 Config::instance()->unset_barco_password();
1073 void christie_username_changed ()
1075 wxString const s = _christie_username->GetValue();
1077 Config::instance()->set_christie_username (wx_to_std(s));
1079 Config::instance()->unset_christie_username ();
1083 void christie_password_changed ()
1085 string const s = _christie_password->get();
1087 Config::instance()->set_christie_password(s);
1089 Config::instance()->unset_christie_password();
1093 void gdc_username_changed ()
1095 wxString const s = _gdc_username->GetValue();
1097 Config::instance()->set_gdc_username (wx_to_std(s));
1099 Config::instance()->unset_gdc_username ();
1103 void gdc_password_changed ()
1105 string const s = _gdc_password->get();
1107 Config::instance()->set_gdc_password(s);
1109 Config::instance()->unset_gdc_password();
1114 wxTextCtrl* _barco_username;
1115 PasswordEntry* _barco_password;
1116 wxTextCtrl* _christie_username;
1117 PasswordEntry* _christie_password;
1118 wxTextCtrl* _gdc_username;
1119 PasswordEntry* _gdc_password;
1123 class NotificationsPage : public StandardPage
1126 NotificationsPage (wxSize panel_size, int border)
1127 #ifdef DCPOMATIC_OSX
1128 /* We have to force both width and height of this one */
1129 : StandardPage (wxSize (panel_size.GetWidth(), 128), border)
1131 : StandardPage (panel_size, border)
1135 wxString GetName () const
1137 return _("Notifications");
1140 #ifdef DCPOMATIC_OSX
1141 wxBitmap GetLargeIcon () const
1143 return wxBitmap ("notifications", wxBITMAP_TYPE_PNG_RESOURCE);
1150 wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
1151 table->AddGrowableCol (1, 1);
1152 _panel->GetSizer()->Add (table, 1, wxEXPAND | wxALL, _border);
1154 _enable_message_box = new CheckBox (_panel, _("Message box"));
1155 table->Add (_enable_message_box, 1, wxEXPAND | wxALL);
1156 table->AddSpacer (0);
1158 _enable_email = new CheckBox (_panel, _("Email"));
1159 table->Add (_enable_email, 1, wxEXPAND | wxALL);
1160 table->AddSpacer (0);
1162 add_label_to_sizer (table, _panel, _("Subject"), true);
1163 _subject = new wxTextCtrl (_panel, wxID_ANY);
1164 table->Add (_subject, 1, wxEXPAND | wxALL);
1166 add_label_to_sizer (table, _panel, _("From address"), true);
1167 _from = new wxTextCtrl (_panel, wxID_ANY);
1168 table->Add (_from, 1, wxEXPAND | wxALL);
1170 add_label_to_sizer (table, _panel, _("To address"), true);
1171 _to = new wxTextCtrl (_panel, wxID_ANY);
1172 table->Add (_to, 1, wxEXPAND | wxALL);
1174 vector<EditableListColumn> columns;
1175 columns.push_back (EditableListColumn(wx_to_std(_("Address"))));
1176 add_label_to_sizer (table, _panel, _("CC addresses"), true);
1177 _cc = new EditableList<string, EmailDialog> (
1180 bind (&Config::notification_cc, Config::instance()),
1181 bind (&Config::set_notification_cc, Config::instance(), _1),
1184 table->Add (_cc, 1, wxEXPAND | wxALL);
1186 add_label_to_sizer (table, _panel, _("BCC address"), true);
1187 _bcc = new wxTextCtrl (_panel, wxID_ANY);
1188 table->Add (_bcc, 1, wxEXPAND | wxALL);
1190 _email = new wxTextCtrl (_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize (-1, 200), wxTE_MULTILINE);
1191 _panel->GetSizer()->Add (_email, 0, wxEXPAND | wxALL, _border);
1193 _reset_email = new Button (_panel, _("Reset to default subject and text"));
1194 _panel->GetSizer()->Add (_reset_email, 0, wxEXPAND | wxALL, _border);
1198 _enable_message_box->Bind (wxEVT_CHECKBOX, boost::bind (&NotificationsPage::type_changed, this, _enable_message_box, Config::MESSAGE_BOX));
1199 _enable_email->Bind (wxEVT_CHECKBOX, boost::bind (&NotificationsPage::type_changed, this, _enable_email, Config::EMAIL));
1201 _subject->Bind (wxEVT_TEXT, boost::bind (&NotificationsPage::notification_subject_changed, this));
1202 _from->Bind (wxEVT_TEXT, boost::bind (&NotificationsPage::notification_from_changed, this));
1203 _to->Bind (wxEVT_TEXT, boost::bind (&NotificationsPage::notification_to_changed, this));
1204 _bcc->Bind (wxEVT_TEXT, boost::bind (&NotificationsPage::notification_bcc_changed, this));
1205 _email->Bind (wxEVT_TEXT, boost::bind (&NotificationsPage::notification_email_changed, this));
1206 _reset_email->Bind (wxEVT_BUTTON, boost::bind (&NotificationsPage::reset_email, this));
1208 update_sensitivity ();
1211 void update_sensitivity ()
1213 bool const s = _enable_email->GetValue();
1214 _subject->Enable(s);
1220 _reset_email->Enable(s);
1223 void config_changed ()
1225 Config* config = Config::instance ();
1227 checked_set (_enable_message_box, config->notification(Config::MESSAGE_BOX));
1228 checked_set (_enable_email, config->notification(Config::EMAIL));
1229 checked_set (_subject, config->notification_subject ());
1230 checked_set (_from, config->notification_from ());
1231 checked_set (_to, config->notification_to ());
1232 checked_set (_bcc, config->notification_bcc ());
1233 checked_set (_email, Config::instance()->notification_email ());
1235 update_sensitivity ();
1238 void notification_subject_changed ()
1240 Config::instance()->set_notification_subject (wx_to_std (_subject->GetValue ()));
1243 void notification_from_changed ()
1245 Config::instance()->set_notification_from (wx_to_std (_from->GetValue ()));
1248 void notification_to_changed ()
1250 Config::instance()->set_notification_to (wx_to_std (_to->GetValue ()));
1253 void notification_bcc_changed ()
1255 Config::instance()->set_notification_bcc (wx_to_std (_bcc->GetValue ()));
1258 void notification_email_changed ()
1260 if (_email->GetValue().IsEmpty ()) {
1261 /* Sometimes we get sent an erroneous notification that the email
1262 is empty; I don't know why.
1266 Config::instance()->set_notification_email (wx_to_std (_email->GetValue ()));
1271 Config::instance()->reset_notification_email ();
1272 checked_set (_email, Config::instance()->notification_email ());
1275 void type_changed (wxCheckBox* b, Config::Notification n)
1277 Config::instance()->set_notification(n, b->GetValue());
1278 update_sensitivity ();
1281 wxCheckBox* _enable_message_box;
1282 wxCheckBox* _enable_email;
1284 wxTextCtrl* _subject;
1287 EditableList<string, EmailDialog>* _cc;
1290 wxButton* _reset_email;
1293 class CoverSheetPage : public StandardPage
1297 CoverSheetPage (wxSize panel_size, int border)
1298 #ifdef DCPOMATIC_OSX
1299 /* We have to force both width and height of this one */
1300 : StandardPage (wxSize (panel_size.GetWidth(), 128), border)
1302 : StandardPage (panel_size, border)
1306 wxString GetName () const
1308 return _("Cover Sheet");
1311 #ifdef DCPOMATIC_OSX
1312 wxBitmap GetLargeIcon () const
1314 return wxBitmap ("cover_sheet", wxBITMAP_TYPE_PNG_RESOURCE);
1321 _cover_sheet = new wxTextCtrl (_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize (-1, 200), wxTE_MULTILINE);
1322 _panel->GetSizer()->Add (_cover_sheet, 0, wxEXPAND | wxALL, _border);
1324 _reset_cover_sheet = new Button (_panel, _("Reset to default text"));
1325 _panel->GetSizer()->Add (_reset_cover_sheet, 0, wxEXPAND | wxALL, _border);
1327 _cover_sheet->Bind (wxEVT_TEXT, boost::bind (&CoverSheetPage::cover_sheet_changed, this));
1328 _reset_cover_sheet->Bind (wxEVT_BUTTON, boost::bind (&CoverSheetPage::reset_cover_sheet, this));
1331 void config_changed ()
1333 checked_set (_cover_sheet, Config::instance()->cover_sheet ());
1336 void cover_sheet_changed ()
1338 if (_cover_sheet->GetValue().IsEmpty ()) {
1339 /* Sometimes we get sent an erroneous notification that the cover sheet
1340 is empty; I don't know why.
1344 Config::instance()->set_cover_sheet (wx_to_std (_cover_sheet->GetValue ()));
1347 void reset_cover_sheet ()
1349 Config::instance()->reset_cover_sheet ();
1350 checked_set (_cover_sheet, Config::instance()->cover_sheet ());
1353 wxTextCtrl* _cover_sheet;
1354 wxButton* _reset_cover_sheet;
1358 /** @class AdvancedPage
1359 * @brief Advanced page of the preferences dialog.
1361 class AdvancedPage : public StockPage
1364 AdvancedPage (wxSize panel_size, int border)
1365 : StockPage (Kind_Advanced, panel_size, border)
1366 , _maximum_j2k_bandwidth (0)
1367 , _allow_any_dcp_frame_rate (0)
1368 , _allow_any_container (0)
1369 , _show_experimental_audio_processors (0)
1370 , _only_servers_encode (0)
1375 , _log_debug_decode (0)
1376 , _log_debug_encode (0)
1377 , _log_debug_email (0)
1381 void add_top_aligned_label_to_sizer (wxSizer* table, wxWindow* parent, wxString text)
1383 int flags = wxALIGN_TOP | wxTOP | wxLEFT;
1385 flags |= wxALIGN_RIGHT;
1388 wxStaticText* m = new StaticText (parent, text);
1389 table->Add (m, 0, flags, DCPOMATIC_SIZER_Y_GAP);
1394 wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
1395 table->AddGrowableCol (1, 1);
1396 _panel->GetSizer()->Add (table, 1, wxALL | wxEXPAND, _border);
1399 add_label_to_sizer (table, _panel, _("Maximum JPEG2000 bandwidth"), true);
1400 wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL);
1401 _maximum_j2k_bandwidth = new wxSpinCtrl (_panel);
1402 s->Add (_maximum_j2k_bandwidth, 1);
1403 add_label_to_sizer (s, _panel, _("Mbit/s"), false);
1407 add_label_to_sizer (table, _panel, _("Video display mode"), true);
1408 _video_display_mode = new wxChoice (_panel, wxID_ANY);
1409 table->Add (_video_display_mode);
1411 wxStaticText* restart = add_label_to_sizer (table, _panel, _("(restart DCP-o-matic to change display mode)"), false);
1412 wxFont font = restart->GetFont();
1413 font.SetStyle (wxFONTSTYLE_ITALIC);
1414 font.SetPointSize (font.GetPointSize() - 1);
1415 restart->SetFont (font);
1416 table->AddSpacer (0);
1418 _allow_any_dcp_frame_rate = new CheckBox (_panel, _("Allow any DCP frame rate"));
1419 table->Add (_allow_any_dcp_frame_rate, 1, wxEXPAND | wxALL);
1420 table->AddSpacer (0);
1422 _allow_any_container = new CheckBox (_panel, _("Allow non-standard container ratios"));
1423 table->Add (_allow_any_container, 1, wxEXPAND | wxALL);
1424 table->AddSpacer (0);
1426 restart = add_label_to_sizer (table, _panel, _("(restart DCP-o-matic to see all ratios)"), false);
1427 restart->SetFont (font);
1428 table->AddSpacer (0);
1430 _show_experimental_audio_processors = new CheckBox (_panel, _("Show experimental audio processors"));
1431 table->Add (_show_experimental_audio_processors, 1, wxEXPAND | wxALL);
1432 table->AddSpacer (0);
1434 _only_servers_encode = new CheckBox (_panel, _("Only servers encode"));
1435 table->Add (_only_servers_encode, 1, wxEXPAND | wxALL);
1436 table->AddSpacer (0);
1439 add_label_to_sizer (table, _panel, _("Maximum number of frames to store per thread"), true);
1440 wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL);
1441 _frames_in_memory_multiplier = new wxSpinCtrl (_panel);
1442 s->Add (_frames_in_memory_multiplier, 1);
1447 add_top_aligned_label_to_sizer (table, _panel, _("DCP metadata filename format"));
1448 dcp::NameFormat::Map titles;
1449 titles['t'] = wx_to_std (_("type (cpl/pkl)"));
1450 dcp::NameFormat::Map examples;
1451 examples['t'] = "cpl";
1452 _dcp_metadata_filename_format = new NameFormatEditor (
1453 _panel, Config::instance()->dcp_metadata_filename_format(), titles, examples, "_eb1c112c-ca3c-4ae6-9263-c6714ff05d64.xml"
1455 table->Add (_dcp_metadata_filename_format->panel(), 1, wxEXPAND | wxALL);
1459 add_top_aligned_label_to_sizer (table, _panel, _("DCP asset filename format"));
1460 dcp::NameFormat::Map titles;
1461 titles['t'] = wx_to_std (_("type (j2c/pcm/sub)"));
1462 titles['r'] = wx_to_std (_("reel number"));
1463 titles['n'] = wx_to_std (_("number of reels"));
1464 titles['c'] = wx_to_std (_("content filename"));
1465 dcp::NameFormat::Map examples;
1466 examples['t'] = "j2c";
1467 examples['r'] = "1";
1468 examples['n'] = "4";
1469 examples['c'] = "myfile.mp4";
1470 _dcp_asset_filename_format = new NameFormatEditor (
1471 _panel, Config::instance()->dcp_asset_filename_format(), titles, examples, "_eb1c112c-ca3c-4ae6-9263-c6714ff05d64.mxf"
1473 table->Add (_dcp_asset_filename_format->panel(), 1, wxEXPAND | wxALL);
1477 add_top_aligned_label_to_sizer (table, _panel, _("Log"));
1478 wxBoxSizer* t = new wxBoxSizer (wxVERTICAL);
1479 _log_general = new CheckBox (_panel, _("General"));
1480 t->Add (_log_general, 1, wxEXPAND | wxALL);
1481 _log_warning = new CheckBox (_panel, _("Warnings"));
1482 t->Add (_log_warning, 1, wxEXPAND | wxALL);
1483 _log_error = new CheckBox (_panel, _("Errors"));
1484 t->Add (_log_error, 1, wxEXPAND | wxALL);
1485 /// TRANSLATORS: translate the word "Timing" here; do not include the "Config|" prefix
1486 _log_timing = new CheckBox (_panel, S_("Config|Timing"));
1487 t->Add (_log_timing, 1, wxEXPAND | wxALL);
1488 _log_debug_decode = new CheckBox (_panel, _("Debug: decode"));
1489 t->Add (_log_debug_decode, 1, wxEXPAND | wxALL);
1490 _log_debug_encode = new CheckBox (_panel, _("Debug: encode"));
1491 t->Add (_log_debug_encode, 1, wxEXPAND | wxALL);
1492 _log_debug_email = new CheckBox (_panel, _("Debug: email sending"));
1493 t->Add (_log_debug_email, 1, wxEXPAND | wxALL);
1494 table->Add (t, 0, wxALL, 6);
1497 #ifdef DCPOMATIC_WINDOWS
1498 _win32_console = new CheckBox (_panel, _("Open console window"));
1499 table->Add (_win32_console, 1, wxEXPAND | wxALL);
1500 table->AddSpacer (0);
1503 _maximum_j2k_bandwidth->SetRange (1, 1000);
1504 _maximum_j2k_bandwidth->Bind (wxEVT_SPINCTRL, boost::bind (&AdvancedPage::maximum_j2k_bandwidth_changed, this));
1505 _video_display_mode->Append (_("Simple (safer)"));
1506 _video_display_mode->Append (_("OpenGL (faster)"));
1507 _video_display_mode->Bind (wxEVT_CHOICE, boost::bind(&AdvancedPage::video_display_mode_changed, this));
1508 _allow_any_dcp_frame_rate->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::allow_any_dcp_frame_rate_changed, this));
1509 _allow_any_container->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::allow_any_container_changed, this));
1510 _show_experimental_audio_processors->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::show_experimental_audio_processors_changed, this));
1511 _only_servers_encode->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::only_servers_encode_changed, this));
1512 _frames_in_memory_multiplier->Bind (wxEVT_SPINCTRL, boost::bind(&AdvancedPage::frames_in_memory_multiplier_changed, this));
1513 _dcp_metadata_filename_format->Changed.connect (boost::bind (&AdvancedPage::dcp_metadata_filename_format_changed, this));
1514 _dcp_asset_filename_format->Changed.connect (boost::bind (&AdvancedPage::dcp_asset_filename_format_changed, this));
1515 _log_general->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::log_changed, this));
1516 _log_warning->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::log_changed, this));
1517 _log_error->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::log_changed, this));
1518 _log_timing->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::log_changed, this));
1519 _log_debug_decode->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::log_changed, this));
1520 _log_debug_encode->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::log_changed, this));
1521 _log_debug_email->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::log_changed, this));
1522 #ifdef DCPOMATIC_WINDOWS
1523 _win32_console->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::win32_console_changed, this));
1527 void config_changed ()
1529 Config* config = Config::instance ();
1531 checked_set (_maximum_j2k_bandwidth, config->maximum_j2k_bandwidth() / 1000000);
1532 switch (config->video_view_type()) {
1533 case Config::VIDEO_VIEW_SIMPLE:
1534 checked_set (_video_display_mode, 0);
1536 case Config::VIDEO_VIEW_OPENGL:
1537 checked_set (_video_display_mode, 1);
1540 checked_set (_allow_any_dcp_frame_rate, config->allow_any_dcp_frame_rate ());
1541 checked_set (_allow_any_container, config->allow_any_container ());
1542 checked_set (_show_experimental_audio_processors, config->show_experimental_audio_processors ());
1543 checked_set (_only_servers_encode, config->only_servers_encode ());
1544 checked_set (_log_general, config->log_types() & LogEntry::TYPE_GENERAL);
1545 checked_set (_log_warning, config->log_types() & LogEntry::TYPE_WARNING);
1546 checked_set (_log_error, config->log_types() & LogEntry::TYPE_ERROR);
1547 checked_set (_log_timing, config->log_types() & LogEntry::TYPE_TIMING);
1548 checked_set (_log_debug_decode, config->log_types() & LogEntry::TYPE_DEBUG_DECODE);
1549 checked_set (_log_debug_encode, config->log_types() & LogEntry::TYPE_DEBUG_ENCODE);
1550 checked_set (_log_debug_email, config->log_types() & LogEntry::TYPE_DEBUG_EMAIL);
1551 checked_set (_frames_in_memory_multiplier, config->frames_in_memory_multiplier());
1552 #ifdef DCPOMATIC_WINDOWS
1553 checked_set (_win32_console, config->win32_console());
1557 void maximum_j2k_bandwidth_changed ()
1559 Config::instance()->set_maximum_j2k_bandwidth (_maximum_j2k_bandwidth->GetValue() * 1000000);
1562 void video_display_mode_changed ()
1564 if (_video_display_mode->GetSelection() == 0) {
1565 Config::instance()->set_video_view_type (Config::VIDEO_VIEW_SIMPLE);
1567 Config::instance()->set_video_view_type (Config::VIDEO_VIEW_OPENGL);
1571 void frames_in_memory_multiplier_changed ()
1573 Config::instance()->set_frames_in_memory_multiplier (_frames_in_memory_multiplier->GetValue());
1576 void allow_any_dcp_frame_rate_changed ()
1578 Config::instance()->set_allow_any_dcp_frame_rate (_allow_any_dcp_frame_rate->GetValue ());
1581 void allow_any_container_changed ()
1583 Config::instance()->set_allow_any_container (_allow_any_container->GetValue ());
1586 void show_experimental_audio_processors_changed ()
1588 Config::instance()->set_show_experimental_audio_processors (_show_experimental_audio_processors->GetValue ());
1591 void only_servers_encode_changed ()
1593 Config::instance()->set_only_servers_encode (_only_servers_encode->GetValue ());
1596 void dcp_metadata_filename_format_changed ()
1598 Config::instance()->set_dcp_metadata_filename_format (_dcp_metadata_filename_format->get ());
1601 void dcp_asset_filename_format_changed ()
1603 Config::instance()->set_dcp_asset_filename_format (_dcp_asset_filename_format->get ());
1609 if (_log_general->GetValue ()) {
1610 types |= LogEntry::TYPE_GENERAL;
1612 if (_log_warning->GetValue ()) {
1613 types |= LogEntry::TYPE_WARNING;
1615 if (_log_error->GetValue ()) {
1616 types |= LogEntry::TYPE_ERROR;
1618 if (_log_timing->GetValue ()) {
1619 types |= LogEntry::TYPE_TIMING;
1621 if (_log_debug_decode->GetValue ()) {
1622 types |= LogEntry::TYPE_DEBUG_DECODE;
1624 if (_log_debug_encode->GetValue ()) {
1625 types |= LogEntry::TYPE_DEBUG_ENCODE;
1627 if (_log_debug_email->GetValue ()) {
1628 types |= LogEntry::TYPE_DEBUG_EMAIL;
1630 Config::instance()->set_log_types (types);
1633 #ifdef DCPOMATIC_WINDOWS
1634 void win32_console_changed ()
1636 Config::instance()->set_win32_console (_win32_console->GetValue ());
1640 wxSpinCtrl* _maximum_j2k_bandwidth;
1641 wxChoice* _video_display_mode;
1642 wxSpinCtrl* _frames_in_memory_multiplier;
1643 wxCheckBox* _allow_any_dcp_frame_rate;
1644 wxCheckBox* _allow_any_container;
1645 wxCheckBox* _show_experimental_audio_processors;
1646 wxCheckBox* _only_servers_encode;
1647 NameFormatEditor* _dcp_metadata_filename_format;
1648 NameFormatEditor* _dcp_asset_filename_format;
1649 wxCheckBox* _log_general;
1650 wxCheckBox* _log_warning;
1651 wxCheckBox* _log_error;
1652 wxCheckBox* _log_timing;
1653 wxCheckBox* _log_debug_decode;
1654 wxCheckBox* _log_debug_encode;
1655 wxCheckBox* _log_debug_email;
1656 #ifdef DCPOMATIC_WINDOWS
1657 wxCheckBox* _win32_console;
1661 wxPreferencesEditor*
1662 create_full_config_dialog ()
1664 wxPreferencesEditor* e = new wxPreferencesEditor ();
1666 #ifdef DCPOMATIC_OSX
1667 /* Width that we force some of the config panels to be on OSX so that
1668 the containing window doesn't shrink too much when we select those panels.
1669 This is obviously an unpleasant hack.
1671 wxSize ps = wxSize (700, -1);
1672 int const border = 16;
1674 wxSize ps = wxSize (-1, -1);
1675 int const border = 8;
1678 e->AddPage (new FullGeneralPage (ps, border));
1679 e->AddPage (new SoundPage (ps, border));
1680 e->AddPage (new DefaultsPage (ps, border));
1681 e->AddPage (new EncodingServersPage (ps, border));
1682 e->AddPage (new KeysPage (ps, border));
1683 e->AddPage (new TMSPage (ps, border));
1684 e->AddPage (new EmailPage (ps, border));
1685 e->AddPage (new KDMEmailPage (ps, border));
1686 e->AddPage (new AccountsPage (ps, border));
1687 e->AddPage (new NotificationsPage (ps, border));
1688 e->AddPage (new CoverSheetPage (ps, border));
1689 e->AddPage (new AdvancedPage (ps, border));