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);
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);
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 add_play_sound_controls (table, r);
121 #ifdef DCPOMATIC_HAVE_EBUR128_PATCHED_FFMPEG
122 _analyse_ebur128 = new CheckBox (_panel, _("Find integrated loudness, true peak and loudness range when analysing audio"));
123 table->Add (_analyse_ebur128, wxGBPosition (r, 0), wxGBSpan (1, 2));
127 _automatic_audio_analysis = new CheckBox (_panel, _("Automatically analyse content audio"));
128 table->Add (_automatic_audio_analysis, wxGBPosition (r, 0), wxGBSpan (1, 2));
131 add_update_controls (table, r);
133 wxFlexGridSizer* bottom_table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
134 bottom_table->AddGrowableCol (1, 1);
136 add_label_to_sizer (bottom_table, _panel, _("Issuer"), true);
137 _issuer = new wxTextCtrl (_panel, wxID_ANY);
138 bottom_table->Add (_issuer, 1, wxALL | wxEXPAND);
140 add_label_to_sizer (bottom_table, _panel, _("Creator"), true);
141 _creator = new wxTextCtrl (_panel, wxID_ANY);
142 bottom_table->Add (_creator, 1, wxALL | wxEXPAND);
144 table->Add (bottom_table, wxGBPosition (r, 0), wxGBSpan (2, 2), wxEXPAND);
147 _config_file->Bind (wxEVT_FILEPICKER_CHANGED, boost::bind (&FullGeneralPage::config_file_changed, this));
148 _cinemas_file->Bind (wxEVT_FILEPICKER_CHANGED, boost::bind (&FullGeneralPage::cinemas_file_changed, this));
150 _interface_complexity->Append (_("Simple"));
151 _interface_complexity->Append (_("Full"));
152 _interface_complexity->Bind (wxEVT_CHOICE, boost::bind(&FullGeneralPage::interface_complexity_changed, this));
154 _master_encoding_threads->SetRange (1, 128);
155 _master_encoding_threads->Bind (wxEVT_SPINCTRL, boost::bind (&FullGeneralPage::master_encoding_threads_changed, this));
156 _server_encoding_threads->SetRange (1, 128);
157 _server_encoding_threads->Bind (wxEVT_SPINCTRL, boost::bind (&FullGeneralPage::server_encoding_threads_changed, this));
158 export_cinemas->Bind (wxEVT_BUTTON, boost::bind (&FullGeneralPage::export_cinemas_file, this));
160 #ifdef DCPOMATIC_HAVE_EBUR128_PATCHED_FFMPEG
161 _analyse_ebur128->Bind (wxEVT_CHECKBOX, boost::bind (&FullGeneralPage::analyse_ebur128_changed, this));
163 _automatic_audio_analysis->Bind (wxEVT_CHECKBOX, boost::bind (&FullGeneralPage::automatic_audio_analysis_changed, this));
165 _issuer->Bind (wxEVT_TEXT, boost::bind (&FullGeneralPage::issuer_changed, this));
166 _creator->Bind (wxEVT_TEXT, boost::bind (&FullGeneralPage::creator_changed, this));
169 void config_changed ()
171 Config* config = Config::instance ();
173 switch (config->interface_complexity()) {
174 case Config::INTERFACE_SIMPLE:
175 checked_set (_interface_complexity, 0);
177 case Config::INTERFACE_FULL:
178 checked_set (_interface_complexity, 1);
181 checked_set (_master_encoding_threads, config->master_encoding_threads ());
182 checked_set (_server_encoding_threads, config->server_encoding_threads ());
183 #ifdef DCPOMATIC_HAVE_EBUR128_PATCHED_FFMPEG
184 checked_set (_analyse_ebur128, config->analyse_ebur128 ());
186 checked_set (_automatic_audio_analysis, config->automatic_audio_analysis ());
187 checked_set (_issuer, config->dcp_issuer ());
188 checked_set (_creator, config->dcp_creator ());
189 checked_set (_config_file, config->config_file());
190 checked_set (_cinemas_file, config->cinemas_file());
192 GeneralPage::config_changed ();
195 void export_cinemas_file ()
197 wxFileDialog* d = new wxFileDialog (
198 _panel, _("Select Cinemas File"), wxEmptyString, wxEmptyString, wxT ("XML files (*.xml)|*.xml"),
199 wxFD_SAVE | wxFD_OVERWRITE_PROMPT
202 if (d->ShowModal () == wxID_OK) {
203 boost::filesystem::copy_file (Config::instance()->cinemas_file(), wx_to_std(d->GetPath()));
208 void interface_complexity_changed ()
210 if (_interface_complexity->GetSelection() == 0) {
211 Config::instance()->set_interface_complexity (Config::INTERFACE_SIMPLE);
213 Config::instance()->set_interface_complexity (Config::INTERFACE_FULL);
218 #ifdef DCPOMATIC_HAVE_EBUR128_PATCHED_FFMPEG
219 void analyse_ebur128_changed ()
221 Config::instance()->set_analyse_ebur128 (_analyse_ebur128->GetValue ());
225 void automatic_audio_analysis_changed ()
227 Config::instance()->set_automatic_audio_analysis (_automatic_audio_analysis->GetValue ());
230 void master_encoding_threads_changed ()
232 Config::instance()->set_master_encoding_threads (_master_encoding_threads->GetValue ());
235 void server_encoding_threads_changed ()
237 Config::instance()->set_server_encoding_threads (_server_encoding_threads->GetValue ());
240 void issuer_changed ()
242 Config::instance()->set_dcp_issuer (wx_to_std (_issuer->GetValue ()));
245 void creator_changed ()
247 Config::instance()->set_dcp_creator (wx_to_std (_creator->GetValue ()));
250 void config_file_changed ()
252 Config* config = Config::instance();
253 boost::filesystem::path new_file = wx_to_std(_config_file->GetPath());
254 if (new_file == config->config_file()) {
257 bool copy_and_link = true;
258 if (boost::filesystem::exists(new_file)) {
259 ConfigMoveDialog* d = new ConfigMoveDialog (_panel, new_file);
260 if (d->ShowModal() == wxID_OK) {
261 copy_and_link = false;
268 if (new_file != config->config_file()) {
269 config->copy_and_link (new_file);
272 config->link (new_file);
276 void cinemas_file_changed ()
278 Config::instance()->set_cinemas_file (wx_to_std (_cinemas_file->GetPath ()));
281 wxChoice* _interface_complexity;
282 wxSpinCtrl* _master_encoding_threads;
283 wxSpinCtrl* _server_encoding_threads;
284 FilePickerCtrl* _config_file;
285 FilePickerCtrl* _cinemas_file;
286 #ifdef DCPOMATIC_HAVE_EBUR128_PATCHED_FFMPEG
287 wxCheckBox* _analyse_ebur128;
289 wxCheckBox* _automatic_audio_analysis;
291 wxTextCtrl* _creator;
294 class DefaultsPage : public StandardPage
297 DefaultsPage (wxSize panel_size, int border)
298 : StandardPage (panel_size, border)
301 wxString GetName () const
303 return _("Defaults");
307 wxBitmap GetLargeIcon () const
309 return wxBitmap ("defaults", wxBITMAP_TYPE_PNG_RESOURCE);
316 wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
317 table->AddGrowableCol (1, 1);
318 _panel->GetSizer()->Add (table, 1, wxALL | wxEXPAND, _border);
321 add_label_to_sizer (table, _panel, _("Default duration of still images"), true);
322 wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL);
323 _still_length = new wxSpinCtrl (_panel);
324 s->Add (_still_length);
325 add_label_to_sizer (s, _panel, _("s"), false);
329 add_label_to_sizer (table, _panel, _("Default directory for new films"), true);
330 #ifdef DCPOMATIC_USE_OWN_PICKER
331 _directory = new DirPickerCtrl (_panel);
333 _directory = new wxDirPickerCtrl (_panel, wxDD_DIR_MUST_EXIST);
335 table->Add (_directory, 1, wxEXPAND);
337 add_label_to_sizer (table, _panel, _("Default ISDCF name details"), true);
338 _isdcf_metadata_button = new Button (_panel, _("Edit..."));
339 table->Add (_isdcf_metadata_button);
341 add_label_to_sizer (table, _panel, _("Default container"), true);
342 _container = new wxChoice (_panel, wxID_ANY);
343 table->Add (_container);
345 add_label_to_sizer (table, _panel, _("Default scale-to"), true);
346 _scale_to = new wxChoice (_panel, wxID_ANY);
347 table->Add (_scale_to);
349 add_label_to_sizer (table, _panel, _("Default content type"), true);
350 _dcp_content_type = new wxChoice (_panel, wxID_ANY);
351 table->Add (_dcp_content_type);
353 add_label_to_sizer (table, _panel, _("Default DCP audio channels"), true);
354 _dcp_audio_channels = new wxChoice (_panel, wxID_ANY);
355 table->Add (_dcp_audio_channels);
358 add_label_to_sizer (table, _panel, _("Default JPEG2000 bandwidth"), true);
359 wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL);
360 _j2k_bandwidth = new wxSpinCtrl (_panel);
361 s->Add (_j2k_bandwidth);
362 add_label_to_sizer (s, _panel, _("Mbit/s"), false);
367 add_label_to_sizer (table, _panel, _("Default audio delay"), true);
368 wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL);
369 _audio_delay = new wxSpinCtrl (_panel);
370 s->Add (_audio_delay);
371 add_label_to_sizer (s, _panel, _("ms"), false);
375 add_label_to_sizer (table, _panel, _("Default standard"), true);
376 _standard = new wxChoice (_panel, wxID_ANY);
377 table->Add (_standard);
379 add_label_to_sizer (table, _panel, _("Default KDM directory"), true);
380 #ifdef DCPOMATIC_USE_OWN_PICKER
381 _kdm_directory = new DirPickerCtrl (_panel);
383 _kdm_directory = new wxDirPickerCtrl (_panel, wxDD_DIR_MUST_EXIST);
386 table->Add (_kdm_directory, 1, wxEXPAND);
388 _upload_after_make_dcp = new CheckBox (_panel, _("Default to enabling upload of DCP to TMS"));
389 table->Add (_upload_after_make_dcp, 1, wxEXPAND);
391 _still_length->SetRange (1, 3600);
392 _still_length->Bind (wxEVT_SPINCTRL, boost::bind (&DefaultsPage::still_length_changed, this));
394 _directory->Bind (wxEVT_DIRPICKER_CHANGED, boost::bind (&DefaultsPage::directory_changed, this));
395 _kdm_directory->Bind (wxEVT_DIRPICKER_CHANGED, boost::bind (&DefaultsPage::kdm_directory_changed, this));
397 _isdcf_metadata_button->Bind (wxEVT_BUTTON, boost::bind (&DefaultsPage::edit_isdcf_metadata_clicked, this));
399 BOOST_FOREACH (Ratio const * i, Ratio::containers()) {
400 _container->Append (std_to_wx(i->container_nickname()));
403 _container->Bind (wxEVT_CHOICE, boost::bind (&DefaultsPage::container_changed, this));
405 _scale_to->Append (_("Guess from content"));
407 BOOST_FOREACH (Ratio const * i, Ratio::all()) {
408 _scale_to->Append (std_to_wx(i->image_nickname()));
411 _scale_to->Bind (wxEVT_CHOICE, boost::bind (&DefaultsPage::scale_to_changed, this));
413 BOOST_FOREACH (DCPContentType const * i, DCPContentType::all()) {
414 _dcp_content_type->Append (std_to_wx (i->pretty_name ()));
417 setup_audio_channels_choice (_dcp_audio_channels, 2);
419 _dcp_content_type->Bind (wxEVT_CHOICE, boost::bind (&DefaultsPage::dcp_content_type_changed, this));
420 _dcp_audio_channels->Bind (wxEVT_CHOICE, boost::bind (&DefaultsPage::dcp_audio_channels_changed, this));
422 _j2k_bandwidth->SetRange (50, 250);
423 _j2k_bandwidth->Bind (wxEVT_SPINCTRL, boost::bind (&DefaultsPage::j2k_bandwidth_changed, this));
425 _audio_delay->SetRange (-1000, 1000);
426 _audio_delay->Bind (wxEVT_SPINCTRL, boost::bind (&DefaultsPage::audio_delay_changed, this));
428 _standard->Append (_("SMPTE"));
429 _standard->Append (_("Interop"));
430 _standard->Bind (wxEVT_CHOICE, boost::bind (&DefaultsPage::standard_changed, this));
432 _upload_after_make_dcp->Bind (wxEVT_CHECKBOX, boost::bind (&DefaultsPage::upload_after_make_dcp_changed, this));
435 void config_changed ()
437 Config* config = Config::instance ();
439 vector<Ratio const *> containers = Ratio::containers ();
440 for (size_t i = 0; i < containers.size(); ++i) {
441 if (containers[i] == config->default_container ()) {
442 _container->SetSelection (i);
446 vector<Ratio const *> ratios = Ratio::all ();
447 for (size_t i = 0; i < ratios.size(); ++i) {
448 if (ratios[i] == config->default_scale_to ()) {
449 _scale_to->SetSelection (i + 1);
453 if (!config->default_scale_to()) {
454 _scale_to->SetSelection (0);
457 vector<DCPContentType const *> const ct = DCPContentType::all ();
458 for (size_t i = 0; i < ct.size(); ++i) {
459 if (ct[i] == config->default_dcp_content_type ()) {
460 _dcp_content_type->SetSelection (i);
464 checked_set (_still_length, config->default_still_length ());
465 _directory->SetPath (std_to_wx (config->default_directory_or (wx_to_std (wxStandardPaths::Get().GetDocumentsDir())).string ()));
466 _kdm_directory->SetPath (std_to_wx (config->default_kdm_directory_or (wx_to_std (wxStandardPaths::Get().GetDocumentsDir())).string ()));
467 checked_set (_j2k_bandwidth, config->default_j2k_bandwidth() / 1000000);
468 _j2k_bandwidth->SetRange (50, config->maximum_j2k_bandwidth() / 1000000);
469 checked_set (_dcp_audio_channels, locale_convert<string> (config->default_dcp_audio_channels()));
470 checked_set (_audio_delay, config->default_audio_delay ());
471 checked_set (_standard, config->default_interop() ? 1 : 0);
472 checked_set (_upload_after_make_dcp, config->default_upload_after_make_dcp());
475 void j2k_bandwidth_changed ()
477 Config::instance()->set_default_j2k_bandwidth (_j2k_bandwidth->GetValue() * 1000000);
480 void audio_delay_changed ()
482 Config::instance()->set_default_audio_delay (_audio_delay->GetValue());
485 void dcp_audio_channels_changed ()
487 int const s = _dcp_audio_channels->GetSelection ();
488 if (s != wxNOT_FOUND) {
489 Config::instance()->set_default_dcp_audio_channels (
490 locale_convert<int> (string_client_data (_dcp_audio_channels->GetClientObject (s)))
495 void directory_changed ()
497 Config::instance()->set_default_directory (wx_to_std (_directory->GetPath ()));
500 void kdm_directory_changed ()
502 Config::instance()->set_default_kdm_directory (wx_to_std (_kdm_directory->GetPath ()));
505 void edit_isdcf_metadata_clicked ()
507 ISDCFMetadataDialog* d = new ISDCFMetadataDialog (_panel, Config::instance()->default_isdcf_metadata (), false);
509 Config::instance()->set_default_isdcf_metadata (d->isdcf_metadata ());
513 void still_length_changed ()
515 Config::instance()->set_default_still_length (_still_length->GetValue ());
518 void container_changed ()
520 vector<Ratio const *> ratio = Ratio::containers ();
521 Config::instance()->set_default_container (ratio[_container->GetSelection()]);
524 void scale_to_changed ()
526 int const s = _scale_to->GetSelection ();
528 Config::instance()->set_default_scale_to (0);
530 vector<Ratio const *> ratio = Ratio::all ();
531 Config::instance()->set_default_scale_to (ratio[s - 1]);
535 void dcp_content_type_changed ()
537 vector<DCPContentType const *> ct = DCPContentType::all ();
538 Config::instance()->set_default_dcp_content_type (ct[_dcp_content_type->GetSelection()]);
541 void standard_changed ()
543 Config::instance()->set_default_interop (_standard->GetSelection() == 1);
546 void upload_after_make_dcp_changed ()
548 Config::instance()->set_default_upload_after_make_dcp (_upload_after_make_dcp->GetValue ());
551 wxSpinCtrl* _j2k_bandwidth;
552 wxSpinCtrl* _audio_delay;
553 wxButton* _isdcf_metadata_button;
554 wxSpinCtrl* _still_length;
555 #ifdef DCPOMATIC_USE_OWN_PICKER
556 DirPickerCtrl* _directory;
557 DirPickerCtrl* _kdm_directory;
559 wxDirPickerCtrl* _directory;
560 wxDirPickerCtrl* _kdm_directory;
562 wxChoice* _container;
564 wxChoice* _dcp_content_type;
565 wxChoice* _dcp_audio_channels;
567 wxCheckBox* _upload_after_make_dcp;
570 class EncodingServersPage : public StandardPage
573 EncodingServersPage (wxSize panel_size, int border)
574 : StandardPage (panel_size, border)
577 wxString GetName () const
583 wxBitmap GetLargeIcon () const
585 return wxBitmap ("servers", wxBITMAP_TYPE_PNG_RESOURCE);
592 _use_any_servers = new CheckBox (_panel, _("Search network for servers"));
593 _panel->GetSizer()->Add (_use_any_servers, 0, wxALL, _border);
595 vector<EditableListColumn> columns;
596 columns.push_back (EditableListColumn(wx_to_std(_("IP address / host name"))));
597 _servers_list = new EditableList<string, ServerDialog> (
600 boost::bind (&Config::servers, Config::instance()),
601 boost::bind (&Config::set_servers, Config::instance(), _1),
602 boost::bind (&EncodingServersPage::server_column, this, _1)
605 _panel->GetSizer()->Add (_servers_list, 1, wxEXPAND | wxALL, _border);
607 _use_any_servers->Bind (wxEVT_CHECKBOX, boost::bind (&EncodingServersPage::use_any_servers_changed, this));
610 void config_changed ()
612 checked_set (_use_any_servers, Config::instance()->use_any_servers ());
613 _servers_list->refresh ();
616 void use_any_servers_changed ()
618 Config::instance()->set_use_any_servers (_use_any_servers->GetValue ());
621 string server_column (string s)
626 wxCheckBox* _use_any_servers;
627 EditableList<string, ServerDialog>* _servers_list;
630 class TMSPage : public StandardPage
633 TMSPage (wxSize panel_size, int border)
634 : StandardPage (panel_size, border)
637 wxString GetName () const
643 wxBitmap GetLargeIcon () const
645 return wxBitmap ("tms", wxBITMAP_TYPE_PNG_RESOURCE);
652 wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
653 table->AddGrowableCol (1, 1);
654 _panel->GetSizer()->Add (table, 1, wxALL | wxEXPAND, _border);
656 add_label_to_sizer (table, _panel, _("Protocol"), true);
657 _tms_protocol = new wxChoice (_panel, wxID_ANY);
658 table->Add (_tms_protocol, 1, wxEXPAND);
660 add_label_to_sizer (table, _panel, _("IP address"), true);
661 _tms_ip = new wxTextCtrl (_panel, wxID_ANY);
662 table->Add (_tms_ip, 1, wxEXPAND);
664 add_label_to_sizer (table, _panel, _("Target path"), true);
665 _tms_path = new wxTextCtrl (_panel, wxID_ANY);
666 table->Add (_tms_path, 1, wxEXPAND);
668 add_label_to_sizer (table, _panel, _("User name"), true);
669 _tms_user = new wxTextCtrl (_panel, wxID_ANY);
670 table->Add (_tms_user, 1, wxEXPAND);
672 add_label_to_sizer (table, _panel, _("Password"), true);
673 _tms_password = new PasswordEntry (_panel);
674 table->Add (_tms_password->get_panel(), 1, wxEXPAND);
676 _tms_protocol->Append (_("SCP (for AAM and Doremi)"));
677 _tms_protocol->Append (_("FTP (for Dolby)"));
679 _tms_protocol->Bind (wxEVT_CHOICE, boost::bind (&TMSPage::tms_protocol_changed, this));
680 _tms_ip->Bind (wxEVT_TEXT, boost::bind (&TMSPage::tms_ip_changed, this));
681 _tms_path->Bind (wxEVT_TEXT, boost::bind (&TMSPage::tms_path_changed, this));
682 _tms_user->Bind (wxEVT_TEXT, boost::bind (&TMSPage::tms_user_changed, this));
683 _tms_password->Changed.connect (boost::bind (&TMSPage::tms_password_changed, this));
686 void config_changed ()
688 Config* config = Config::instance ();
690 checked_set (_tms_protocol, config->tms_protocol ());
691 checked_set (_tms_ip, config->tms_ip ());
692 checked_set (_tms_path, config->tms_path ());
693 checked_set (_tms_user, config->tms_user ());
694 checked_set (_tms_password, config->tms_password ());
697 void tms_protocol_changed ()
699 Config::instance()->set_tms_protocol(static_cast<FileTransferProtocol>(_tms_protocol->GetSelection()));
702 void tms_ip_changed ()
704 Config::instance()->set_tms_ip (wx_to_std (_tms_ip->GetValue ()));
707 void tms_path_changed ()
709 Config::instance()->set_tms_path (wx_to_std (_tms_path->GetValue ()));
712 void tms_user_changed ()
714 Config::instance()->set_tms_user (wx_to_std (_tms_user->GetValue ()));
717 void tms_password_changed ()
719 Config::instance()->set_tms_password (_tms_password->get());
722 wxChoice* _tms_protocol;
724 wxTextCtrl* _tms_path;
725 wxTextCtrl* _tms_user;
726 PasswordEntry* _tms_password;
735 class EmailPage : public StandardPage
738 EmailPage (wxSize panel_size, int border)
739 : StandardPage (panel_size, border)
742 wxString GetName () const
748 wxBitmap GetLargeIcon () const
750 return wxBitmap ("email", wxBITMAP_TYPE_PNG_RESOURCE);
757 wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
758 table->AddGrowableCol (1, 1);
759 _panel->GetSizer()->Add (table, 1, wxEXPAND | wxALL, _border);
761 add_label_to_sizer (table, _panel, _("Outgoing mail server"), true);
763 wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL);
764 _server = new wxTextCtrl (_panel, wxID_ANY);
765 s->Add (_server, 1, wxEXPAND | wxALL);
766 add_label_to_sizer (s, _panel, _("port"), false);
767 _port = new wxSpinCtrl (_panel, wxID_ANY);
768 _port->SetRange (0, 65535);
770 add_label_to_sizer (s, _panel, _("protocol"), false);
771 _protocol = new wxChoice (_panel, wxID_ANY);
772 /* Make sure this matches the switches in config_changed and port_changed below */
773 _protocol->Append (_("Auto"));
774 _protocol->Append (_("Plain"));
775 _protocol->Append (_("STARTTLS"));
776 _protocol->Append (_("SSL"));
778 table->Add (s, 1, wxEXPAND | wxALL);
781 add_label_to_sizer (table, _panel, _("User name"), true);
782 _user = new wxTextCtrl (_panel, wxID_ANY);
783 table->Add (_user, 1, wxEXPAND | wxALL);
785 add_label_to_sizer (table, _panel, _("Password"), true);
786 _password = new PasswordEntry (_panel);
787 table->Add (_password->get_panel(), 1, wxEXPAND | wxALL);
789 _server->Bind (wxEVT_TEXT, boost::bind (&EmailPage::server_changed, this));
790 _port->Bind (wxEVT_SPINCTRL, boost::bind (&EmailPage::port_changed, this));
791 _protocol->Bind (wxEVT_CHOICE, boost::bind (&EmailPage::protocol_changed, this));
792 _user->Bind (wxEVT_TEXT, boost::bind (&EmailPage::user_changed, this));
793 _password->Changed.connect (boost::bind (&EmailPage::password_changed, this));
796 void config_changed ()
798 Config* config = Config::instance ();
800 checked_set (_server, config->mail_server ());
801 checked_set (_port, config->mail_port ());
802 switch (config->mail_protocol()) {
803 case EMAIL_PROTOCOL_AUTO:
804 checked_set (_protocol, 0);
806 case EMAIL_PROTOCOL_PLAIN:
807 checked_set (_protocol, 1);
809 case EMAIL_PROTOCOL_STARTTLS:
810 checked_set (_protocol, 2);
812 case EMAIL_PROTOCOL_SSL:
813 checked_set (_protocol, 3);
816 checked_set (_user, config->mail_user ());
817 checked_set (_password, config->mail_password());
820 void server_changed ()
822 Config::instance()->set_mail_server (wx_to_std (_server->GetValue ()));
827 Config::instance()->set_mail_port (_port->GetValue ());
830 void protocol_changed ()
832 switch (_protocol->GetSelection()) {
834 Config::instance()->set_mail_protocol(EMAIL_PROTOCOL_AUTO);
837 Config::instance()->set_mail_protocol(EMAIL_PROTOCOL_PLAIN);
840 Config::instance()->set_mail_protocol(EMAIL_PROTOCOL_STARTTLS);
843 Config::instance()->set_mail_protocol(EMAIL_PROTOCOL_SSL);
850 Config::instance()->set_mail_user (wx_to_std (_user->GetValue ()));
853 void password_changed ()
855 Config::instance()->set_mail_password(_password->get());
862 PasswordEntry* _password;
865 class KDMEmailPage : public StandardPage
869 KDMEmailPage (wxSize panel_size, int border)
871 /* We have to force both width and height of this one */
872 : StandardPage (wxSize (panel_size.GetWidth(), 128), border)
874 : StandardPage (panel_size, border)
878 wxString GetName () const
880 return _("KDM Email");
884 wxBitmap GetLargeIcon () const
886 return wxBitmap ("kdm_email", wxBITMAP_TYPE_PNG_RESOURCE);
893 wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
894 table->AddGrowableCol (1, 1);
895 _panel->GetSizer()->Add (table, 1, wxEXPAND | wxALL, _border);
897 add_label_to_sizer (table, _panel, _("Subject"), true);
898 _subject = new wxTextCtrl (_panel, wxID_ANY);
899 table->Add (_subject, 1, wxEXPAND | wxALL);
901 add_label_to_sizer (table, _panel, _("From address"), true);
902 _from = new wxTextCtrl (_panel, wxID_ANY);
903 table->Add (_from, 1, wxEXPAND | wxALL);
905 vector<EditableListColumn> columns;
906 columns.push_back (EditableListColumn(wx_to_std(_("Address"))));
907 add_label_to_sizer (table, _panel, _("CC addresses"), true);
908 _cc = new EditableList<string, EmailDialog> (
911 bind (&Config::kdm_cc, Config::instance()),
912 bind (&Config::set_kdm_cc, Config::instance(), _1),
915 table->Add (_cc, 1, wxEXPAND | wxALL);
917 add_label_to_sizer (table, _panel, _("BCC address"), true);
918 _bcc = new wxTextCtrl (_panel, wxID_ANY);
919 table->Add (_bcc, 1, wxEXPAND | wxALL);
921 _email = new wxTextCtrl (_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize (-1, 200), wxTE_MULTILINE);
922 _panel->GetSizer()->Add (_email, 0, wxEXPAND | wxALL, _border);
924 _reset_email = new Button (_panel, _("Reset to default subject and text"));
925 _panel->GetSizer()->Add (_reset_email, 0, wxEXPAND | wxALL, _border);
929 _subject->Bind (wxEVT_TEXT, boost::bind (&KDMEmailPage::kdm_subject_changed, this));
930 _from->Bind (wxEVT_TEXT, boost::bind (&KDMEmailPage::kdm_from_changed, this));
931 _bcc->Bind (wxEVT_TEXT, boost::bind (&KDMEmailPage::kdm_bcc_changed, this));
932 _email->Bind (wxEVT_TEXT, boost::bind (&KDMEmailPage::kdm_email_changed, this));
933 _reset_email->Bind (wxEVT_BUTTON, boost::bind (&KDMEmailPage::reset_email, this));
936 void config_changed ()
938 Config* config = Config::instance ();
940 checked_set (_subject, config->kdm_subject ());
941 checked_set (_from, config->kdm_from ());
942 checked_set (_bcc, config->kdm_bcc ());
943 checked_set (_email, Config::instance()->kdm_email ());
946 void kdm_subject_changed ()
948 Config::instance()->set_kdm_subject (wx_to_std (_subject->GetValue ()));
951 void kdm_from_changed ()
953 Config::instance()->set_kdm_from (wx_to_std (_from->GetValue ()));
956 void kdm_bcc_changed ()
958 Config::instance()->set_kdm_bcc (wx_to_std (_bcc->GetValue ()));
961 void kdm_email_changed ()
963 if (_email->GetValue().IsEmpty ()) {
964 /* Sometimes we get sent an erroneous notification that the email
965 is empty; I don't know why.
969 Config::instance()->set_kdm_email (wx_to_std (_email->GetValue ()));
974 Config::instance()->reset_kdm_email ();
975 checked_set (_email, Config::instance()->kdm_email ());
978 wxTextCtrl* _subject;
980 EditableList<string, EmailDialog>* _cc;
983 wxButton* _reset_email;
986 class AccountsPage : public StandardPage
989 AccountsPage (wxSize panel_size, int border)
990 : StandardPage (panel_size, border)
993 wxString GetName () const
995 return _("Accounts");
999 wxBitmap GetLargeIcon () const
1001 return wxBitmap ("accounts", wxBITMAP_TYPE_PNG_RESOURCE);
1007 wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
1008 table->AddGrowableCol (1, 1);
1009 _panel->GetSizer()->Add (table, 1, wxEXPAND | wxALL, _border);
1011 add_label_to_sizer (table, _panel, _("certificates.barco.com user name"), true);
1012 _barco_username = new wxTextCtrl (_panel, wxID_ANY);
1013 table->Add (_barco_username, 1, wxEXPAND | wxALL);
1015 add_label_to_sizer (table, _panel, _("certificates.barco.com password"), true);
1016 _barco_password = new PasswordEntry (_panel);
1017 table->Add (_barco_password->get_panel(), 1, wxEXPAND | wxALL);
1019 add_label_to_sizer (table, _panel, _("certificates.christiedigital.com user name"), true);
1020 _christie_username = new wxTextCtrl (_panel, wxID_ANY);
1021 table->Add (_christie_username, 1, wxEXPAND | wxALL);
1023 add_label_to_sizer (table, _panel, _("certificates.christiedigital.com password"), true);
1024 _christie_password = new PasswordEntry (_panel);
1025 table->Add (_christie_password->get_panel(), 1, wxEXPAND | wxALL);
1027 add_label_to_sizer (table, _panel, _("GDC user name"), true);
1028 _gdc_username = new wxTextCtrl (_panel, wxID_ANY);
1029 table->Add (_gdc_username, 1, wxEXPAND | wxALL);
1031 add_label_to_sizer (table, _panel, _("GDC password"), true);
1032 _gdc_password = new PasswordEntry (_panel);
1033 table->Add (_gdc_password->get_panel(), 1, wxEXPAND | wxALL);
1035 _barco_username->Bind (wxEVT_TEXT, boost::bind(&AccountsPage::barco_username_changed, this));
1036 _barco_password->Changed.connect (boost::bind(&AccountsPage::barco_password_changed, this));
1037 _christie_username->Bind (wxEVT_TEXT, boost::bind(&AccountsPage::christie_username_changed, this));
1038 _christie_password->Changed.connect (boost::bind(&AccountsPage::christie_password_changed, this));
1039 _gdc_username->Bind (wxEVT_TEXT, boost::bind(&AccountsPage::gdc_username_changed, this));
1040 _gdc_password->Changed.connect (boost::bind(&AccountsPage::gdc_password_changed, this));
1043 void config_changed ()
1045 Config* config = Config::instance ();
1047 checked_set (_barco_username, config->barco_username().get_value_or(""));
1048 checked_set (_barco_password, config->barco_password().get_value_or(""));
1049 checked_set (_christie_username, config->christie_username().get_value_or(""));
1050 checked_set (_christie_password, config->christie_password().get_value_or(""));
1051 checked_set (_gdc_username, config->gdc_username().get_value_or(""));
1052 checked_set (_gdc_password, config->gdc_password().get_value_or(""));
1055 void barco_username_changed ()
1057 wxString const s = _barco_username->GetValue();
1059 Config::instance()->set_barco_username (wx_to_std(s));
1061 Config::instance()->unset_barco_username ();
1065 void barco_password_changed ()
1067 string const s = _barco_password->get();
1069 Config::instance()->set_barco_password(s);
1071 Config::instance()->unset_barco_password();
1075 void christie_username_changed ()
1077 wxString const s = _christie_username->GetValue();
1079 Config::instance()->set_christie_username (wx_to_std(s));
1081 Config::instance()->unset_christie_username ();
1085 void christie_password_changed ()
1087 string const s = _christie_password->get();
1089 Config::instance()->set_christie_password(s);
1091 Config::instance()->unset_christie_password();
1095 void gdc_username_changed ()
1097 wxString const s = _gdc_username->GetValue();
1099 Config::instance()->set_gdc_username (wx_to_std(s));
1101 Config::instance()->unset_gdc_username ();
1105 void gdc_password_changed ()
1107 string const s = _gdc_password->get();
1109 Config::instance()->set_gdc_password(s);
1111 Config::instance()->unset_gdc_password();
1116 wxTextCtrl* _barco_username;
1117 PasswordEntry* _barco_password;
1118 wxTextCtrl* _christie_username;
1119 PasswordEntry* _christie_password;
1120 wxTextCtrl* _gdc_username;
1121 PasswordEntry* _gdc_password;
1125 class NotificationsPage : public StandardPage
1128 NotificationsPage (wxSize panel_size, int border)
1129 #ifdef DCPOMATIC_OSX
1130 /* We have to force both width and height of this one */
1131 : StandardPage (wxSize (panel_size.GetWidth(), 128), border)
1133 : StandardPage (panel_size, border)
1137 wxString GetName () const
1139 return _("Notifications");
1142 #ifdef DCPOMATIC_OSX
1143 wxBitmap GetLargeIcon () const
1145 return wxBitmap ("notifications", wxBITMAP_TYPE_PNG_RESOURCE);
1152 wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
1153 table->AddGrowableCol (1, 1);
1154 _panel->GetSizer()->Add (table, 1, wxEXPAND | wxALL, _border);
1156 _enable_message_box = new CheckBox (_panel, _("Message box"));
1157 table->Add (_enable_message_box, 1, wxEXPAND | wxALL);
1158 table->AddSpacer (0);
1160 _enable_email = new CheckBox (_panel, _("Email"));
1161 table->Add (_enable_email, 1, wxEXPAND | wxALL);
1162 table->AddSpacer (0);
1164 add_label_to_sizer (table, _panel, _("Subject"), true);
1165 _subject = new wxTextCtrl (_panel, wxID_ANY);
1166 table->Add (_subject, 1, wxEXPAND | wxALL);
1168 add_label_to_sizer (table, _panel, _("From address"), true);
1169 _from = new wxTextCtrl (_panel, wxID_ANY);
1170 table->Add (_from, 1, wxEXPAND | wxALL);
1172 add_label_to_sizer (table, _panel, _("To address"), true);
1173 _to = new wxTextCtrl (_panel, wxID_ANY);
1174 table->Add (_to, 1, wxEXPAND | wxALL);
1176 vector<EditableListColumn> columns;
1177 columns.push_back (EditableListColumn(wx_to_std(_("Address"))));
1178 add_label_to_sizer (table, _panel, _("CC addresses"), true);
1179 _cc = new EditableList<string, EmailDialog> (
1182 bind (&Config::notification_cc, Config::instance()),
1183 bind (&Config::set_notification_cc, Config::instance(), _1),
1186 table->Add (_cc, 1, wxEXPAND | wxALL);
1188 add_label_to_sizer (table, _panel, _("BCC address"), true);
1189 _bcc = new wxTextCtrl (_panel, wxID_ANY);
1190 table->Add (_bcc, 1, wxEXPAND | wxALL);
1192 _email = new wxTextCtrl (_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize (-1, 200), wxTE_MULTILINE);
1193 _panel->GetSizer()->Add (_email, 0, wxEXPAND | wxALL, _border);
1195 _reset_email = new Button (_panel, _("Reset to default subject and text"));
1196 _panel->GetSizer()->Add (_reset_email, 0, wxEXPAND | wxALL, _border);
1200 _enable_message_box->Bind (wxEVT_CHECKBOX, boost::bind (&NotificationsPage::type_changed, this, _enable_message_box, Config::MESSAGE_BOX));
1201 _enable_email->Bind (wxEVT_CHECKBOX, boost::bind (&NotificationsPage::type_changed, this, _enable_email, Config::EMAIL));
1203 _subject->Bind (wxEVT_TEXT, boost::bind (&NotificationsPage::notification_subject_changed, this));
1204 _from->Bind (wxEVT_TEXT, boost::bind (&NotificationsPage::notification_from_changed, this));
1205 _to->Bind (wxEVT_TEXT, boost::bind (&NotificationsPage::notification_to_changed, this));
1206 _bcc->Bind (wxEVT_TEXT, boost::bind (&NotificationsPage::notification_bcc_changed, this));
1207 _email->Bind (wxEVT_TEXT, boost::bind (&NotificationsPage::notification_email_changed, this));
1208 _reset_email->Bind (wxEVT_BUTTON, boost::bind (&NotificationsPage::reset_email, this));
1210 update_sensitivity ();
1213 void update_sensitivity ()
1215 bool const s = _enable_email->GetValue();
1216 _subject->Enable(s);
1222 _reset_email->Enable(s);
1225 void config_changed ()
1227 Config* config = Config::instance ();
1229 checked_set (_enable_message_box, config->notification(Config::MESSAGE_BOX));
1230 checked_set (_enable_email, config->notification(Config::EMAIL));
1231 checked_set (_subject, config->notification_subject ());
1232 checked_set (_from, config->notification_from ());
1233 checked_set (_to, config->notification_to ());
1234 checked_set (_bcc, config->notification_bcc ());
1235 checked_set (_email, Config::instance()->notification_email ());
1237 update_sensitivity ();
1240 void notification_subject_changed ()
1242 Config::instance()->set_notification_subject (wx_to_std (_subject->GetValue ()));
1245 void notification_from_changed ()
1247 Config::instance()->set_notification_from (wx_to_std (_from->GetValue ()));
1250 void notification_to_changed ()
1252 Config::instance()->set_notification_to (wx_to_std (_to->GetValue ()));
1255 void notification_bcc_changed ()
1257 Config::instance()->set_notification_bcc (wx_to_std (_bcc->GetValue ()));
1260 void notification_email_changed ()
1262 if (_email->GetValue().IsEmpty ()) {
1263 /* Sometimes we get sent an erroneous notification that the email
1264 is empty; I don't know why.
1268 Config::instance()->set_notification_email (wx_to_std (_email->GetValue ()));
1273 Config::instance()->reset_notification_email ();
1274 checked_set (_email, Config::instance()->notification_email ());
1277 void type_changed (wxCheckBox* b, Config::Notification n)
1279 Config::instance()->set_notification(n, b->GetValue());
1280 update_sensitivity ();
1283 wxCheckBox* _enable_message_box;
1284 wxCheckBox* _enable_email;
1286 wxTextCtrl* _subject;
1289 EditableList<string, EmailDialog>* _cc;
1292 wxButton* _reset_email;
1295 class CoverSheetPage : public StandardPage
1299 CoverSheetPage (wxSize panel_size, int border)
1300 #ifdef DCPOMATIC_OSX
1301 /* We have to force both width and height of this one */
1302 : StandardPage (wxSize (panel_size.GetWidth(), 128), border)
1304 : StandardPage (panel_size, border)
1308 wxString GetName () const
1310 return _("Cover Sheet");
1313 #ifdef DCPOMATIC_OSX
1314 wxBitmap GetLargeIcon () const
1316 return wxBitmap ("cover_sheet", wxBITMAP_TYPE_PNG_RESOURCE);
1323 _cover_sheet = new wxTextCtrl (_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize (-1, 200), wxTE_MULTILINE);
1324 _panel->GetSizer()->Add (_cover_sheet, 0, wxEXPAND | wxALL, _border);
1326 _reset_cover_sheet = new Button (_panel, _("Reset to default text"));
1327 _panel->GetSizer()->Add (_reset_cover_sheet, 0, wxEXPAND | wxALL, _border);
1329 _cover_sheet->Bind (wxEVT_TEXT, boost::bind (&CoverSheetPage::cover_sheet_changed, this));
1330 _reset_cover_sheet->Bind (wxEVT_BUTTON, boost::bind (&CoverSheetPage::reset_cover_sheet, this));
1333 void config_changed ()
1335 checked_set (_cover_sheet, Config::instance()->cover_sheet ());
1338 void cover_sheet_changed ()
1340 if (_cover_sheet->GetValue().IsEmpty ()) {
1341 /* Sometimes we get sent an erroneous notification that the cover sheet
1342 is empty; I don't know why.
1346 Config::instance()->set_cover_sheet (wx_to_std (_cover_sheet->GetValue ()));
1349 void reset_cover_sheet ()
1351 Config::instance()->reset_cover_sheet ();
1352 checked_set (_cover_sheet, Config::instance()->cover_sheet ());
1355 wxTextCtrl* _cover_sheet;
1356 wxButton* _reset_cover_sheet;
1360 /** @class AdvancedPage
1361 * @brief Advanced page of the preferences dialog.
1363 class AdvancedPage : public StockPage
1366 AdvancedPage (wxSize panel_size, int border)
1367 : StockPage (Kind_Advanced, panel_size, border)
1368 , _maximum_j2k_bandwidth (0)
1369 , _allow_any_dcp_frame_rate (0)
1370 , _allow_any_container (0)
1371 , _only_servers_encode (0)
1376 , _log_debug_decode (0)
1377 , _log_debug_encode (0)
1378 , _log_debug_email (0)
1382 void add_top_aligned_label_to_sizer (wxSizer* table, wxWindow* parent, wxString text)
1384 int flags = wxALIGN_TOP | wxTOP | wxLEFT;
1386 flags |= wxALIGN_RIGHT;
1389 wxStaticText* m = new StaticText (parent, text);
1390 table->Add (m, 0, flags, DCPOMATIC_SIZER_Y_GAP);
1395 wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
1396 table->AddGrowableCol (1, 1);
1397 _panel->GetSizer()->Add (table, 1, wxALL | wxEXPAND, _border);
1400 add_label_to_sizer (table, _panel, _("Maximum JPEG2000 bandwidth"), true);
1401 wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL);
1402 _maximum_j2k_bandwidth = new wxSpinCtrl (_panel);
1403 s->Add (_maximum_j2k_bandwidth, 1);
1404 add_label_to_sizer (s, _panel, _("Mbit/s"), false);
1408 add_label_to_sizer (table, _panel, _("Video display mode"), true);
1409 _video_display_mode = new wxChoice (_panel, wxID_ANY);
1410 table->Add (_video_display_mode);
1412 wxStaticText* restart = add_label_to_sizer (table, _panel, _("(restart DCP-o-matic to change display mode)"), false);
1413 wxFont font = restart->GetFont();
1414 font.SetStyle (wxFONTSTYLE_ITALIC);
1415 font.SetPointSize (font.GetPointSize() - 1);
1416 restart->SetFont (font);
1417 table->AddSpacer (0);
1419 _allow_any_dcp_frame_rate = new CheckBox (_panel, _("Allow any DCP frame rate"));
1420 table->Add (_allow_any_dcp_frame_rate, 1, wxEXPAND | wxALL);
1421 table->AddSpacer (0);
1423 _allow_any_container = new CheckBox (_panel, _("Allow non-standard container ratios"));
1424 table->Add (_allow_any_container, 1, wxEXPAND | wxALL);
1425 table->AddSpacer (0);
1427 restart = add_label_to_sizer (table, _panel, _("(restart DCP-o-matic to see all ratios)"), false);
1428 restart->SetFont (font);
1429 table->AddSpacer (0);
1431 _only_servers_encode = new CheckBox (_panel, _("Only servers encode"));
1432 table->Add (_only_servers_encode, 1, wxEXPAND | wxALL);
1433 table->AddSpacer (0);
1436 add_label_to_sizer (table, _panel, _("Maximum number of frames to store per thread"), true);
1437 wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL);
1438 _frames_in_memory_multiplier = new wxSpinCtrl (_panel);
1439 s->Add (_frames_in_memory_multiplier, 1);
1444 add_top_aligned_label_to_sizer (table, _panel, _("DCP metadata filename format"));
1445 dcp::NameFormat::Map titles;
1446 titles['t'] = wx_to_std (_("type (cpl/pkl)"));
1447 dcp::NameFormat::Map examples;
1448 examples['t'] = "cpl";
1449 _dcp_metadata_filename_format = new NameFormatEditor (
1450 _panel, Config::instance()->dcp_metadata_filename_format(), titles, examples, "_eb1c112c-ca3c-4ae6-9263-c6714ff05d64.xml"
1452 table->Add (_dcp_metadata_filename_format->panel(), 1, wxEXPAND | wxALL);
1456 add_top_aligned_label_to_sizer (table, _panel, _("DCP asset filename format"));
1457 dcp::NameFormat::Map titles;
1458 titles['t'] = wx_to_std (_("type (j2c/pcm/sub)"));
1459 titles['r'] = wx_to_std (_("reel number"));
1460 titles['n'] = wx_to_std (_("number of reels"));
1461 titles['c'] = wx_to_std (_("content filename"));
1462 dcp::NameFormat::Map examples;
1463 examples['t'] = "j2c";
1464 examples['r'] = "1";
1465 examples['n'] = "4";
1466 examples['c'] = "myfile.mp4";
1467 _dcp_asset_filename_format = new NameFormatEditor (
1468 _panel, Config::instance()->dcp_asset_filename_format(), titles, examples, "_eb1c112c-ca3c-4ae6-9263-c6714ff05d64.mxf"
1470 table->Add (_dcp_asset_filename_format->panel(), 1, wxEXPAND | wxALL);
1474 add_top_aligned_label_to_sizer (table, _panel, _("Log"));
1475 wxBoxSizer* t = new wxBoxSizer (wxVERTICAL);
1476 _log_general = new CheckBox (_panel, _("General"));
1477 t->Add (_log_general, 1, wxEXPAND | wxALL);
1478 _log_warning = new CheckBox (_panel, _("Warnings"));
1479 t->Add (_log_warning, 1, wxEXPAND | wxALL);
1480 _log_error = new CheckBox (_panel, _("Errors"));
1481 t->Add (_log_error, 1, wxEXPAND | wxALL);
1482 /// TRANSLATORS: translate the word "Timing" here; do not include the "Config|" prefix
1483 _log_timing = new CheckBox (_panel, S_("Config|Timing"));
1484 t->Add (_log_timing, 1, wxEXPAND | wxALL);
1485 _log_debug_decode = new CheckBox (_panel, _("Debug: decode"));
1486 t->Add (_log_debug_decode, 1, wxEXPAND | wxALL);
1487 _log_debug_encode = new CheckBox (_panel, _("Debug: encode"));
1488 t->Add (_log_debug_encode, 1, wxEXPAND | wxALL);
1489 _log_debug_email = new CheckBox (_panel, _("Debug: email sending"));
1490 t->Add (_log_debug_email, 1, wxEXPAND | wxALL);
1491 table->Add (t, 0, wxALL, 6);
1494 #ifdef DCPOMATIC_WINDOWS
1495 _win32_console = new CheckBox (_panel, _("Open console window"));
1496 table->Add (_win32_console, 1, wxEXPAND | wxALL);
1497 table->AddSpacer (0);
1500 _maximum_j2k_bandwidth->SetRange (1, 1000);
1501 _maximum_j2k_bandwidth->Bind (wxEVT_SPINCTRL, boost::bind (&AdvancedPage::maximum_j2k_bandwidth_changed, this));
1502 _video_display_mode->Append (_("Simple (safer)"));
1503 _video_display_mode->Append (_("OpenGL (faster)"));
1504 _video_display_mode->Bind (wxEVT_CHOICE, boost::bind(&AdvancedPage::video_display_mode_changed, this));
1505 _allow_any_dcp_frame_rate->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::allow_any_dcp_frame_rate_changed, this));
1506 _allow_any_container->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::allow_any_container_changed, this));
1507 _only_servers_encode->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::only_servers_encode_changed, this));
1508 _frames_in_memory_multiplier->Bind (wxEVT_SPINCTRL, boost::bind(&AdvancedPage::frames_in_memory_multiplier_changed, this));
1509 _dcp_metadata_filename_format->Changed.connect (boost::bind (&AdvancedPage::dcp_metadata_filename_format_changed, this));
1510 _dcp_asset_filename_format->Changed.connect (boost::bind (&AdvancedPage::dcp_asset_filename_format_changed, this));
1511 _log_general->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::log_changed, this));
1512 _log_warning->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::log_changed, this));
1513 _log_error->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::log_changed, this));
1514 _log_timing->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::log_changed, this));
1515 _log_debug_decode->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::log_changed, this));
1516 _log_debug_encode->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::log_changed, this));
1517 _log_debug_email->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::log_changed, this));
1518 #ifdef DCPOMATIC_WINDOWS
1519 _win32_console->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::win32_console_changed, this));
1523 void config_changed ()
1525 Config* config = Config::instance ();
1527 checked_set (_maximum_j2k_bandwidth, config->maximum_j2k_bandwidth() / 1000000);
1528 switch (config->video_view_type()) {
1529 case Config::VIDEO_VIEW_SIMPLE:
1530 checked_set (_video_display_mode, 0);
1532 case Config::VIDEO_VIEW_OPENGL:
1533 checked_set (_video_display_mode, 1);
1536 checked_set (_allow_any_dcp_frame_rate, config->allow_any_dcp_frame_rate ());
1537 checked_set (_allow_any_container, config->allow_any_container ());
1538 checked_set (_only_servers_encode, config->only_servers_encode ());
1539 checked_set (_log_general, config->log_types() & LogEntry::TYPE_GENERAL);
1540 checked_set (_log_warning, config->log_types() & LogEntry::TYPE_WARNING);
1541 checked_set (_log_error, config->log_types() & LogEntry::TYPE_ERROR);
1542 checked_set (_log_timing, config->log_types() & LogEntry::TYPE_TIMING);
1543 checked_set (_log_debug_decode, config->log_types() & LogEntry::TYPE_DEBUG_DECODE);
1544 checked_set (_log_debug_encode, config->log_types() & LogEntry::TYPE_DEBUG_ENCODE);
1545 checked_set (_log_debug_email, config->log_types() & LogEntry::TYPE_DEBUG_EMAIL);
1546 checked_set (_frames_in_memory_multiplier, config->frames_in_memory_multiplier());
1547 #ifdef DCPOMATIC_WINDOWS
1548 checked_set (_win32_console, config->win32_console());
1552 void maximum_j2k_bandwidth_changed ()
1554 Config::instance()->set_maximum_j2k_bandwidth (_maximum_j2k_bandwidth->GetValue() * 1000000);
1557 void video_display_mode_changed ()
1559 if (_video_display_mode->GetSelection() == 0) {
1560 Config::instance()->set_video_view_type (Config::VIDEO_VIEW_SIMPLE);
1562 Config::instance()->set_video_view_type (Config::VIDEO_VIEW_OPENGL);
1566 void frames_in_memory_multiplier_changed ()
1568 Config::instance()->set_frames_in_memory_multiplier (_frames_in_memory_multiplier->GetValue());
1571 void allow_any_dcp_frame_rate_changed ()
1573 Config::instance()->set_allow_any_dcp_frame_rate (_allow_any_dcp_frame_rate->GetValue ());
1576 void allow_any_container_changed ()
1578 Config::instance()->set_allow_any_container (_allow_any_container->GetValue ());
1581 void only_servers_encode_changed ()
1583 Config::instance()->set_only_servers_encode (_only_servers_encode->GetValue ());
1586 void dcp_metadata_filename_format_changed ()
1588 Config::instance()->set_dcp_metadata_filename_format (_dcp_metadata_filename_format->get ());
1591 void dcp_asset_filename_format_changed ()
1593 Config::instance()->set_dcp_asset_filename_format (_dcp_asset_filename_format->get ());
1599 if (_log_general->GetValue ()) {
1600 types |= LogEntry::TYPE_GENERAL;
1602 if (_log_warning->GetValue ()) {
1603 types |= LogEntry::TYPE_WARNING;
1605 if (_log_error->GetValue ()) {
1606 types |= LogEntry::TYPE_ERROR;
1608 if (_log_timing->GetValue ()) {
1609 types |= LogEntry::TYPE_TIMING;
1611 if (_log_debug_decode->GetValue ()) {
1612 types |= LogEntry::TYPE_DEBUG_DECODE;
1614 if (_log_debug_encode->GetValue ()) {
1615 types |= LogEntry::TYPE_DEBUG_ENCODE;
1617 if (_log_debug_email->GetValue ()) {
1618 types |= LogEntry::TYPE_DEBUG_EMAIL;
1620 Config::instance()->set_log_types (types);
1623 #ifdef DCPOMATIC_WINDOWS
1624 void win32_console_changed ()
1626 Config::instance()->set_win32_console (_win32_console->GetValue ());
1630 wxSpinCtrl* _maximum_j2k_bandwidth;
1631 wxChoice* _video_display_mode;
1632 wxSpinCtrl* _frames_in_memory_multiplier;
1633 wxCheckBox* _allow_any_dcp_frame_rate;
1634 wxCheckBox* _allow_any_container;
1635 wxCheckBox* _only_servers_encode;
1636 NameFormatEditor* _dcp_metadata_filename_format;
1637 NameFormatEditor* _dcp_asset_filename_format;
1638 wxCheckBox* _log_general;
1639 wxCheckBox* _log_warning;
1640 wxCheckBox* _log_error;
1641 wxCheckBox* _log_timing;
1642 wxCheckBox* _log_debug_decode;
1643 wxCheckBox* _log_debug_encode;
1644 wxCheckBox* _log_debug_email;
1645 #ifdef DCPOMATIC_WINDOWS
1646 wxCheckBox* _win32_console;
1650 wxPreferencesEditor*
1651 create_full_config_dialog ()
1653 wxPreferencesEditor* e = new wxPreferencesEditor ();
1655 #ifdef DCPOMATIC_OSX
1656 /* Width that we force some of the config panels to be on OSX so that
1657 the containing window doesn't shrink too much when we select those panels.
1658 This is obviously an unpleasant hack.
1660 wxSize ps = wxSize (700, -1);
1661 int const border = 16;
1663 wxSize ps = wxSize (-1, -1);
1664 int const border = 8;
1667 e->AddPage (new FullGeneralPage (ps, border));
1668 e->AddPage (new DefaultsPage (ps, border));
1669 e->AddPage (new EncodingServersPage (ps, border));
1670 e->AddPage (new KeysPage (ps, border));
1671 e->AddPage (new TMSPage (ps, border));
1672 e->AddPage (new EmailPage (ps, border));
1673 e->AddPage (new KDMEmailPage (ps, border));
1674 e->AddPage (new AccountsPage (ps, border));
1675 e->AddPage (new NotificationsPage (ps, border));
1676 e->AddPage (new CoverSheetPage (ps, border));
1677 e->AddPage (new AdvancedPage (ps, border));