2 Copyright (C) 2012-2018 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 "lib/config.h"
43 #include "lib/ratio.h"
44 #include "lib/filter.h"
45 #include "lib/dcp_content_type.h"
48 #include "lib/cross.h"
49 #include "lib/exceptions.h"
50 #include <dcp/locale_convert.h>
51 #include <dcp/exceptions.h>
52 #include <dcp/certificate_chain.h>
53 #include <wx/stdpaths.h>
54 #include <wx/preferences.h>
55 #include <wx/spinctrl.h>
56 #include <wx/filepicker.h>
58 #include <boost/filesystem.hpp>
59 #include <boost/foreach.hpp>
70 using boost::shared_ptr;
71 using boost::function;
72 using boost::optional;
73 using dcp::locale_convert;
75 class FullGeneralPage : public GeneralPage
78 FullGeneralPage (wxSize panel_size, int border)
79 : GeneralPage (panel_size, border)
85 wxGridBagSizer* table = new wxGridBagSizer (DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
86 _panel->GetSizer()->Add (table, 1, wxALL | wxEXPAND, _border);
89 add_language_controls (table, r);
91 add_label_to_sizer (table, _panel, _("Interface complexity"), true, wxGBPosition(r, 0));
92 _interface_complexity = new wxChoice (_panel, wxID_ANY);
93 table->Add (_interface_complexity, wxGBPosition (r, 1));
96 add_label_to_sizer (table, _panel, _("Number of threads DCP-o-matic should use"), true, wxGBPosition (r, 0));
97 _master_encoding_threads = new wxSpinCtrl (_panel);
98 table->Add (_master_encoding_threads, wxGBPosition (r, 1));
101 add_label_to_sizer (table, _panel, _("Number of threads DCP-o-matic encode server should use"), true, wxGBPosition (r, 0));
102 _server_encoding_threads = new wxSpinCtrl (_panel);
103 table->Add (_server_encoding_threads, wxGBPosition (r, 1));
106 add_label_to_sizer (table, _panel, _("Configuration file"), true, wxGBPosition (r, 0));
107 _config_file = new FilePickerCtrl (_panel, _("Select configuration file"), "*.xml", true);
108 table->Add (_config_file, wxGBPosition (r, 1));
111 add_label_to_sizer (table, _panel, _("Cinema and screen database file"), true, wxGBPosition (r, 0));
112 _cinemas_file = new FilePickerCtrl (_panel, _("Select cinema and screen database file"), "*.xml", true);
113 table->Add (_cinemas_file, wxGBPosition (r, 1));
114 Button* export_cinemas = new Button (_panel, _("Export..."));
115 table->Add (export_cinemas, wxGBPosition (r, 2));
118 add_play_sound_controls (table, r);
120 #ifdef DCPOMATIC_HAVE_EBUR128_PATCHED_FFMPEG
121 _analyse_ebur128 = new CheckBox (_panel, _("Find integrated loudness, true peak and loudness range when analysing audio"));
122 table->Add (_analyse_ebur128, wxGBPosition (r, 0), wxGBSpan (1, 2));
126 _automatic_audio_analysis = new CheckBox (_panel, _("Automatically analyse content audio"));
127 table->Add (_automatic_audio_analysis, wxGBPosition (r, 0), wxGBSpan (1, 2));
130 add_update_controls (table, r);
132 wxFlexGridSizer* bottom_table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
133 bottom_table->AddGrowableCol (1, 1);
135 add_label_to_sizer (bottom_table, _panel, _("Issuer"), true);
136 _issuer = new wxTextCtrl (_panel, wxID_ANY);
137 bottom_table->Add (_issuer, 1, wxALL | wxEXPAND);
139 add_label_to_sizer (bottom_table, _panel, _("Creator"), true);
140 _creator = new wxTextCtrl (_panel, wxID_ANY);
141 bottom_table->Add (_creator, 1, wxALL | wxEXPAND);
143 table->Add (bottom_table, wxGBPosition (r, 0), wxGBSpan (2, 2), wxEXPAND);
146 _config_file->Bind (wxEVT_FILEPICKER_CHANGED, boost::bind (&FullGeneralPage::config_file_changed, this));
147 _cinemas_file->Bind (wxEVT_FILEPICKER_CHANGED, boost::bind (&FullGeneralPage::cinemas_file_changed, this));
149 _interface_complexity->Append (_("Simple"));
150 _interface_complexity->Append (_("Full"));
151 _interface_complexity->Bind (wxEVT_CHOICE, boost::bind(&FullGeneralPage::interface_complexity_changed, this));
153 _master_encoding_threads->SetRange (1, 128);
154 _master_encoding_threads->Bind (wxEVT_SPINCTRL, boost::bind (&FullGeneralPage::master_encoding_threads_changed, this));
155 _server_encoding_threads->SetRange (1, 128);
156 _server_encoding_threads->Bind (wxEVT_SPINCTRL, boost::bind (&FullGeneralPage::server_encoding_threads_changed, this));
157 export_cinemas->Bind (wxEVT_BUTTON, boost::bind (&FullGeneralPage::export_cinemas_file, this));
159 #ifdef DCPOMATIC_HAVE_EBUR128_PATCHED_FFMPEG
160 _analyse_ebur128->Bind (wxEVT_CHECKBOX, boost::bind (&FullGeneralPage::analyse_ebur128_changed, this));
162 _automatic_audio_analysis->Bind (wxEVT_CHECKBOX, boost::bind (&FullGeneralPage::automatic_audio_analysis_changed, this));
164 _issuer->Bind (wxEVT_TEXT, boost::bind (&FullGeneralPage::issuer_changed, this));
165 _creator->Bind (wxEVT_TEXT, boost::bind (&FullGeneralPage::creator_changed, this));
168 void config_changed ()
170 Config* config = Config::instance ();
172 switch (config->interface_complexity()) {
173 case Config::INTERFACE_SIMPLE:
174 checked_set (_interface_complexity, 0);
176 case Config::INTERFACE_FULL:
177 checked_set (_interface_complexity, 1);
180 checked_set (_master_encoding_threads, config->master_encoding_threads ());
181 checked_set (_server_encoding_threads, config->server_encoding_threads ());
182 #ifdef DCPOMATIC_HAVE_EBUR128_PATCHED_FFMPEG
183 checked_set (_analyse_ebur128, config->analyse_ebur128 ());
185 checked_set (_automatic_audio_analysis, config->automatic_audio_analysis ());
186 checked_set (_issuer, config->dcp_issuer ());
187 checked_set (_creator, config->dcp_creator ());
188 checked_set (_config_file, config->config_file());
189 checked_set (_cinemas_file, config->cinemas_file());
191 GeneralPage::config_changed ();
194 void export_cinemas_file ()
196 wxFileDialog* d = new wxFileDialog (
197 _panel, _("Select Cinemas File"), wxEmptyString, wxEmptyString, wxT ("XML files (*.xml)|*.xml"),
198 wxFD_SAVE | wxFD_OVERWRITE_PROMPT
201 if (d->ShowModal () == wxID_OK) {
202 boost::filesystem::copy_file (Config::instance()->cinemas_file(), wx_to_std(d->GetPath()));
207 void interface_complexity_changed ()
209 if (_interface_complexity->GetSelection() == 0) {
210 Config::instance()->set_interface_complexity (Config::INTERFACE_SIMPLE);
212 Config::instance()->set_interface_complexity (Config::INTERFACE_FULL);
217 #ifdef DCPOMATIC_HAVE_EBUR128_PATCHED_FFMPEG
218 void analyse_ebur128_changed ()
220 Config::instance()->set_analyse_ebur128 (_analyse_ebur128->GetValue ());
224 void automatic_audio_analysis_changed ()
226 Config::instance()->set_automatic_audio_analysis (_automatic_audio_analysis->GetValue ());
229 void master_encoding_threads_changed ()
231 Config::instance()->set_master_encoding_threads (_master_encoding_threads->GetValue ());
234 void server_encoding_threads_changed ()
236 Config::instance()->set_server_encoding_threads (_server_encoding_threads->GetValue ());
239 void issuer_changed ()
241 Config::instance()->set_dcp_issuer (wx_to_std (_issuer->GetValue ()));
244 void creator_changed ()
246 Config::instance()->set_dcp_creator (wx_to_std (_creator->GetValue ()));
249 void config_file_changed ()
251 Config* config = Config::instance();
252 boost::filesystem::path new_file = wx_to_std(_config_file->GetPath());
253 if (new_file == config->config_file()) {
256 bool copy_and_link = true;
257 if (boost::filesystem::exists(new_file)) {
258 ConfigMoveDialog* d = new ConfigMoveDialog (_panel, new_file);
259 if (d->ShowModal() == wxID_OK) {
260 copy_and_link = false;
267 if (new_file != config->config_file()) {
268 config->copy_and_link (new_file);
271 config->link (new_file);
275 void cinemas_file_changed ()
277 Config::instance()->set_cinemas_file (wx_to_std (_cinemas_file->GetPath ()));
280 wxChoice* _interface_complexity;
281 wxSpinCtrl* _master_encoding_threads;
282 wxSpinCtrl* _server_encoding_threads;
283 FilePickerCtrl* _config_file;
284 FilePickerCtrl* _cinemas_file;
285 #ifdef DCPOMATIC_HAVE_EBUR128_PATCHED_FFMPEG
286 wxCheckBox* _analyse_ebur128;
288 wxCheckBox* _automatic_audio_analysis;
290 wxTextCtrl* _creator;
293 class DefaultsPage : public StandardPage
296 DefaultsPage (wxSize panel_size, int border)
297 : StandardPage (panel_size, border)
300 wxString GetName () const
302 return _("Defaults");
306 wxBitmap GetLargeIcon () const
308 return wxBitmap ("defaults", wxBITMAP_TYPE_PNG_RESOURCE);
315 wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
316 table->AddGrowableCol (1, 1);
317 _panel->GetSizer()->Add (table, 1, wxALL | wxEXPAND, _border);
320 add_label_to_sizer (table, _panel, _("Default duration of still images"), true);
321 wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL);
322 _still_length = new wxSpinCtrl (_panel);
323 s->Add (_still_length);
324 add_label_to_sizer (s, _panel, _("s"), false);
328 add_label_to_sizer (table, _panel, _("Default directory for new films"), true);
329 #ifdef DCPOMATIC_USE_OWN_PICKER
330 _directory = new DirPickerCtrl (_panel);
332 _directory = new wxDirPickerCtrl (_panel, wxDD_DIR_MUST_EXIST);
334 table->Add (_directory, 1, wxEXPAND);
336 add_label_to_sizer (table, _panel, _("Default ISDCF name details"), true);
337 _isdcf_metadata_button = new Button (_panel, _("Edit..."));
338 table->Add (_isdcf_metadata_button);
340 add_label_to_sizer (table, _panel, _("Default container"), true);
341 _container = new wxChoice (_panel, wxID_ANY);
342 table->Add (_container);
344 add_label_to_sizer (table, _panel, _("Default scale-to"), true);
345 _scale_to = new wxChoice (_panel, wxID_ANY);
346 table->Add (_scale_to);
348 add_label_to_sizer (table, _panel, _("Default content type"), true);
349 _dcp_content_type = new wxChoice (_panel, wxID_ANY);
350 table->Add (_dcp_content_type);
352 add_label_to_sizer (table, _panel, _("Default DCP audio channels"), true);
353 _dcp_audio_channels = new wxChoice (_panel, wxID_ANY);
354 table->Add (_dcp_audio_channels);
357 add_label_to_sizer (table, _panel, _("Default JPEG2000 bandwidth"), true);
358 wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL);
359 _j2k_bandwidth = new wxSpinCtrl (_panel);
360 s->Add (_j2k_bandwidth);
361 add_label_to_sizer (s, _panel, _("Mbit/s"), false);
366 add_label_to_sizer (table, _panel, _("Default audio delay"), true);
367 wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL);
368 _audio_delay = new wxSpinCtrl (_panel);
369 s->Add (_audio_delay);
370 add_label_to_sizer (s, _panel, _("ms"), false);
374 add_label_to_sizer (table, _panel, _("Default standard"), true);
375 _standard = new wxChoice (_panel, wxID_ANY);
376 table->Add (_standard);
378 add_label_to_sizer (table, _panel, _("Default KDM directory"), true);
379 #ifdef DCPOMATIC_USE_OWN_PICKER
380 _kdm_directory = new DirPickerCtrl (_panel);
382 _kdm_directory = new wxDirPickerCtrl (_panel, wxDD_DIR_MUST_EXIST);
385 table->Add (_kdm_directory, 1, wxEXPAND);
387 _upload_after_make_dcp = new CheckBox (_panel, _("Default to enabling upload of DCP to TMS"));
388 table->Add (_upload_after_make_dcp, 1, wxEXPAND);
390 _still_length->SetRange (1, 3600);
391 _still_length->Bind (wxEVT_SPINCTRL, boost::bind (&DefaultsPage::still_length_changed, this));
393 _directory->Bind (wxEVT_DIRPICKER_CHANGED, boost::bind (&DefaultsPage::directory_changed, this));
394 _kdm_directory->Bind (wxEVT_DIRPICKER_CHANGED, boost::bind (&DefaultsPage::kdm_directory_changed, this));
396 _isdcf_metadata_button->Bind (wxEVT_BUTTON, boost::bind (&DefaultsPage::edit_isdcf_metadata_clicked, this));
398 BOOST_FOREACH (Ratio const * i, Ratio::containers()) {
399 _container->Append (std_to_wx(i->container_nickname()));
402 _container->Bind (wxEVT_CHOICE, boost::bind (&DefaultsPage::container_changed, this));
404 _scale_to->Append (_("Guess from content"));
406 BOOST_FOREACH (Ratio const * i, Ratio::all()) {
407 _scale_to->Append (std_to_wx(i->image_nickname()));
410 _scale_to->Bind (wxEVT_CHOICE, boost::bind (&DefaultsPage::scale_to_changed, this));
412 BOOST_FOREACH (DCPContentType const * i, DCPContentType::all()) {
413 _dcp_content_type->Append (std_to_wx (i->pretty_name ()));
416 setup_audio_channels_choice (_dcp_audio_channels, 2);
418 _dcp_content_type->Bind (wxEVT_CHOICE, boost::bind (&DefaultsPage::dcp_content_type_changed, this));
419 _dcp_audio_channels->Bind (wxEVT_CHOICE, boost::bind (&DefaultsPage::dcp_audio_channels_changed, this));
421 _j2k_bandwidth->SetRange (50, 250);
422 _j2k_bandwidth->Bind (wxEVT_SPINCTRL, boost::bind (&DefaultsPage::j2k_bandwidth_changed, this));
424 _audio_delay->SetRange (-1000, 1000);
425 _audio_delay->Bind (wxEVT_SPINCTRL, boost::bind (&DefaultsPage::audio_delay_changed, this));
427 _standard->Append (_("SMPTE"));
428 _standard->Append (_("Interop"));
429 _standard->Bind (wxEVT_CHOICE, boost::bind (&DefaultsPage::standard_changed, this));
431 _upload_after_make_dcp->Bind (wxEVT_CHECKBOX, boost::bind (&DefaultsPage::upload_after_make_dcp_changed, this));
434 void config_changed ()
436 Config* config = Config::instance ();
438 vector<Ratio const *> containers = Ratio::containers ();
439 for (size_t i = 0; i < containers.size(); ++i) {
440 if (containers[i] == config->default_container ()) {
441 _container->SetSelection (i);
445 vector<Ratio const *> ratios = Ratio::all ();
446 for (size_t i = 0; i < ratios.size(); ++i) {
447 if (ratios[i] == config->default_scale_to ()) {
448 _scale_to->SetSelection (i + 1);
452 if (!config->default_scale_to()) {
453 _scale_to->SetSelection (0);
456 vector<DCPContentType const *> const ct = DCPContentType::all ();
457 for (size_t i = 0; i < ct.size(); ++i) {
458 if (ct[i] == config->default_dcp_content_type ()) {
459 _dcp_content_type->SetSelection (i);
463 checked_set (_still_length, config->default_still_length ());
464 _directory->SetPath (std_to_wx (config->default_directory_or (wx_to_std (wxStandardPaths::Get().GetDocumentsDir())).string ()));
465 _kdm_directory->SetPath (std_to_wx (config->default_kdm_directory_or (wx_to_std (wxStandardPaths::Get().GetDocumentsDir())).string ()));
466 checked_set (_j2k_bandwidth, config->default_j2k_bandwidth() / 1000000);
467 _j2k_bandwidth->SetRange (50, config->maximum_j2k_bandwidth() / 1000000);
468 checked_set (_dcp_audio_channels, locale_convert<string> (config->default_dcp_audio_channels()));
469 checked_set (_audio_delay, config->default_audio_delay ());
470 checked_set (_standard, config->default_interop() ? 1 : 0);
471 checked_set (_upload_after_make_dcp, config->default_upload_after_make_dcp());
474 void j2k_bandwidth_changed ()
476 Config::instance()->set_default_j2k_bandwidth (_j2k_bandwidth->GetValue() * 1000000);
479 void audio_delay_changed ()
481 Config::instance()->set_default_audio_delay (_audio_delay->GetValue());
484 void dcp_audio_channels_changed ()
486 int const s = _dcp_audio_channels->GetSelection ();
487 if (s != wxNOT_FOUND) {
488 Config::instance()->set_default_dcp_audio_channels (
489 locale_convert<int> (string_client_data (_dcp_audio_channels->GetClientObject (s)))
494 void directory_changed ()
496 Config::instance()->set_default_directory (wx_to_std (_directory->GetPath ()));
499 void kdm_directory_changed ()
501 Config::instance()->set_default_kdm_directory (wx_to_std (_kdm_directory->GetPath ()));
504 void edit_isdcf_metadata_clicked ()
506 ISDCFMetadataDialog* d = new ISDCFMetadataDialog (_panel, Config::instance()->default_isdcf_metadata (), false);
508 Config::instance()->set_default_isdcf_metadata (d->isdcf_metadata ());
512 void still_length_changed ()
514 Config::instance()->set_default_still_length (_still_length->GetValue ());
517 void container_changed ()
519 vector<Ratio const *> ratio = Ratio::containers ();
520 Config::instance()->set_default_container (ratio[_container->GetSelection()]);
523 void scale_to_changed ()
525 int const s = _scale_to->GetSelection ();
527 Config::instance()->set_default_scale_to (0);
529 vector<Ratio const *> ratio = Ratio::all ();
530 Config::instance()->set_default_scale_to (ratio[s - 1]);
534 void dcp_content_type_changed ()
536 vector<DCPContentType const *> ct = DCPContentType::all ();
537 Config::instance()->set_default_dcp_content_type (ct[_dcp_content_type->GetSelection()]);
540 void standard_changed ()
542 Config::instance()->set_default_interop (_standard->GetSelection() == 1);
545 void upload_after_make_dcp_changed ()
547 Config::instance()->set_default_upload_after_make_dcp (_upload_after_make_dcp->GetValue ());
550 wxSpinCtrl* _j2k_bandwidth;
551 wxSpinCtrl* _audio_delay;
552 wxButton* _isdcf_metadata_button;
553 wxSpinCtrl* _still_length;
554 #ifdef DCPOMATIC_USE_OWN_PICKER
555 DirPickerCtrl* _directory;
556 DirPickerCtrl* _kdm_directory;
558 wxDirPickerCtrl* _directory;
559 wxDirPickerCtrl* _kdm_directory;
561 wxChoice* _container;
563 wxChoice* _dcp_content_type;
564 wxChoice* _dcp_audio_channels;
566 wxCheckBox* _upload_after_make_dcp;
569 class EncodingServersPage : public StandardPage
572 EncodingServersPage (wxSize panel_size, int border)
573 : StandardPage (panel_size, border)
576 wxString GetName () const
582 wxBitmap GetLargeIcon () const
584 return wxBitmap ("servers", wxBITMAP_TYPE_PNG_RESOURCE);
591 _use_any_servers = new CheckBox (_panel, _("Search network for servers"));
592 _panel->GetSizer()->Add (_use_any_servers, 0, wxALL, _border);
594 vector<string> columns;
595 columns.push_back (wx_to_std (_("IP address / host name")));
596 _servers_list = new EditableList<string, ServerDialog> (
599 boost::bind (&Config::servers, Config::instance()),
600 boost::bind (&Config::set_servers, Config::instance(), _1),
601 boost::bind (&EncodingServersPage::server_column, this, _1)
604 _panel->GetSizer()->Add (_servers_list, 1, wxEXPAND | wxALL, _border);
606 _use_any_servers->Bind (wxEVT_CHECKBOX, boost::bind (&EncodingServersPage::use_any_servers_changed, this));
609 void config_changed ()
611 checked_set (_use_any_servers, Config::instance()->use_any_servers ());
612 _servers_list->refresh ();
615 void use_any_servers_changed ()
617 Config::instance()->set_use_any_servers (_use_any_servers->GetValue ());
620 string server_column (string s)
625 wxCheckBox* _use_any_servers;
626 EditableList<string, ServerDialog>* _servers_list;
629 class TMSPage : public StandardPage
632 TMSPage (wxSize panel_size, int border)
633 : StandardPage (panel_size, border)
636 wxString GetName () const
642 wxBitmap GetLargeIcon () const
644 return wxBitmap ("tms", wxBITMAP_TYPE_PNG_RESOURCE);
651 wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
652 table->AddGrowableCol (1, 1);
653 _panel->GetSizer()->Add (table, 1, wxALL | wxEXPAND, _border);
655 add_label_to_sizer (table, _panel, _("Protocol"), true);
656 _tms_protocol = new wxChoice (_panel, wxID_ANY);
657 table->Add (_tms_protocol, 1, wxEXPAND);
659 add_label_to_sizer (table, _panel, _("IP address"), true);
660 _tms_ip = new wxTextCtrl (_panel, wxID_ANY);
661 table->Add (_tms_ip, 1, wxEXPAND);
663 add_label_to_sizer (table, _panel, _("Target path"), true);
664 _tms_path = new wxTextCtrl (_panel, wxID_ANY);
665 table->Add (_tms_path, 1, wxEXPAND);
667 add_label_to_sizer (table, _panel, _("User name"), true);
668 _tms_user = new wxTextCtrl (_panel, wxID_ANY);
669 table->Add (_tms_user, 1, wxEXPAND);
671 add_label_to_sizer (table, _panel, _("Password"), true);
672 _tms_password = new wxTextCtrl (_panel, wxID_ANY);
673 table->Add (_tms_password, 1, wxEXPAND);
675 _tms_protocol->Append (_("SCP (for AAM and Doremi)"));
676 _tms_protocol->Append (_("FTP (for Dolby)"));
678 _tms_protocol->Bind (wxEVT_CHOICE, boost::bind (&TMSPage::tms_protocol_changed, this));
679 _tms_ip->Bind (wxEVT_TEXT, boost::bind (&TMSPage::tms_ip_changed, this));
680 _tms_path->Bind (wxEVT_TEXT, boost::bind (&TMSPage::tms_path_changed, this));
681 _tms_user->Bind (wxEVT_TEXT, boost::bind (&TMSPage::tms_user_changed, this));
682 _tms_password->Bind (wxEVT_TEXT, boost::bind (&TMSPage::tms_password_changed, this));
685 void config_changed ()
687 Config* config = Config::instance ();
689 checked_set (_tms_protocol, config->tms_protocol ());
690 checked_set (_tms_ip, config->tms_ip ());
691 checked_set (_tms_path, config->tms_path ());
692 checked_set (_tms_user, config->tms_user ());
693 checked_set (_tms_password, config->tms_password ());
696 void tms_protocol_changed ()
698 Config::instance()->set_tms_protocol(static_cast<FileTransferProtocol>(_tms_protocol->GetSelection()));
701 void tms_ip_changed ()
703 Config::instance()->set_tms_ip (wx_to_std (_tms_ip->GetValue ()));
706 void tms_path_changed ()
708 Config::instance()->set_tms_path (wx_to_std (_tms_path->GetValue ()));
711 void tms_user_changed ()
713 Config::instance()->set_tms_user (wx_to_std (_tms_user->GetValue ()));
716 void tms_password_changed ()
718 Config::instance()->set_tms_password (wx_to_std (_tms_password->GetValue ()));
721 wxChoice* _tms_protocol;
723 wxTextCtrl* _tms_path;
724 wxTextCtrl* _tms_user;
725 wxTextCtrl* _tms_password;
734 class EmailPage : public StandardPage
737 EmailPage (wxSize panel_size, int border)
738 : StandardPage (panel_size, border)
741 wxString GetName () const
747 wxBitmap GetLargeIcon () const
749 return wxBitmap ("email", wxBITMAP_TYPE_PNG_RESOURCE);
756 wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
757 table->AddGrowableCol (1, 1);
758 _panel->GetSizer()->Add (table, 1, wxEXPAND | wxALL, _border);
760 add_label_to_sizer (table, _panel, _("Outgoing mail server"), true);
762 wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL);
763 _server = new wxTextCtrl (_panel, wxID_ANY);
764 s->Add (_server, 1, wxEXPAND | wxALL);
765 add_label_to_sizer (s, _panel, _("port"), false);
766 _port = new wxSpinCtrl (_panel, wxID_ANY);
767 _port->SetRange (0, 65535);
769 add_label_to_sizer (s, _panel, _("protocol"), false);
770 _protocol = new wxChoice (_panel, wxID_ANY);
771 /* Make sure this matches the switches in config_changed and port_changed below */
772 _protocol->Append (_("Auto"));
773 _protocol->Append (_("Plain"));
774 _protocol->Append (_("STARTTLS"));
775 _protocol->Append (_("SSL"));
777 table->Add (s, 1, wxEXPAND | wxALL);
780 add_label_to_sizer (table, _panel, _("User name"), true);
781 _user = new wxTextCtrl (_panel, wxID_ANY);
782 table->Add (_user, 1, wxEXPAND | wxALL);
784 add_label_to_sizer (table, _panel, _("Password"), true);
785 _password = new wxTextCtrl (_panel, wxID_ANY);
786 table->Add (_password, 1, wxEXPAND | wxALL);
788 _server->Bind (wxEVT_TEXT, boost::bind (&EmailPage::server_changed, this));
789 _port->Bind (wxEVT_SPINCTRL, boost::bind (&EmailPage::port_changed, this));
790 _protocol->Bind (wxEVT_CHOICE, boost::bind (&EmailPage::protocol_changed, this));
791 _user->Bind (wxEVT_TEXT, boost::bind (&EmailPage::user_changed, this));
792 _password->Bind (wxEVT_TEXT, boost::bind (&EmailPage::password_changed, this));
795 void config_changed ()
797 Config* config = Config::instance ();
799 checked_set (_server, config->mail_server ());
800 checked_set (_port, config->mail_port ());
801 switch (config->mail_protocol()) {
802 case EMAIL_PROTOCOL_AUTO:
803 checked_set (_protocol, 0);
805 case EMAIL_PROTOCOL_PLAIN:
806 checked_set (_protocol, 1);
808 case EMAIL_PROTOCOL_STARTTLS:
809 checked_set (_protocol, 2);
811 case EMAIL_PROTOCOL_SSL:
812 checked_set (_protocol, 3);
815 checked_set (_user, config->mail_user ());
816 checked_set (_password, config->mail_password ());
819 void server_changed ()
821 Config::instance()->set_mail_server (wx_to_std (_server->GetValue ()));
826 Config::instance()->set_mail_port (_port->GetValue ());
829 void protocol_changed ()
831 switch (_protocol->GetSelection()) {
833 Config::instance()->set_mail_protocol(EMAIL_PROTOCOL_AUTO);
836 Config::instance()->set_mail_protocol(EMAIL_PROTOCOL_PLAIN);
839 Config::instance()->set_mail_protocol(EMAIL_PROTOCOL_STARTTLS);
842 Config::instance()->set_mail_protocol(EMAIL_PROTOCOL_SSL);
849 Config::instance()->set_mail_user (wx_to_std (_user->GetValue ()));
852 void password_changed ()
854 Config::instance()->set_mail_password (wx_to_std (_password->GetValue ()));
861 wxTextCtrl* _password;
864 class KDMEmailPage : public StandardPage
868 KDMEmailPage (wxSize panel_size, int border)
870 /* We have to force both width and height of this one */
871 : StandardPage (wxSize (panel_size.GetWidth(), 128), border)
873 : StandardPage (panel_size, border)
877 wxString GetName () const
879 return _("KDM Email");
883 wxBitmap GetLargeIcon () const
885 return wxBitmap ("kdm_email", wxBITMAP_TYPE_PNG_RESOURCE);
892 wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
893 table->AddGrowableCol (1, 1);
894 _panel->GetSizer()->Add (table, 1, wxEXPAND | wxALL, _border);
896 add_label_to_sizer (table, _panel, _("Subject"), true);
897 _subject = new wxTextCtrl (_panel, wxID_ANY);
898 table->Add (_subject, 1, wxEXPAND | wxALL);
900 add_label_to_sizer (table, _panel, _("From address"), true);
901 _from = new wxTextCtrl (_panel, wxID_ANY);
902 table->Add (_from, 1, wxEXPAND | wxALL);
904 vector<string> columns;
905 columns.push_back (wx_to_std (_("Address")));
906 add_label_to_sizer (table, _panel, _("CC addresses"), true);
907 _cc = new EditableList<string, EmailDialog> (
910 bind (&Config::kdm_cc, Config::instance()),
911 bind (&Config::set_kdm_cc, Config::instance(), _1),
914 table->Add (_cc, 1, wxEXPAND | wxALL);
916 add_label_to_sizer (table, _panel, _("BCC address"), true);
917 _bcc = new wxTextCtrl (_panel, wxID_ANY);
918 table->Add (_bcc, 1, wxEXPAND | wxALL);
920 _email = new wxTextCtrl (_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize (-1, 200), wxTE_MULTILINE);
921 _panel->GetSizer()->Add (_email, 0, wxEXPAND | wxALL, _border);
923 _reset_email = new Button (_panel, _("Reset to default subject and text"));
924 _panel->GetSizer()->Add (_reset_email, 0, wxEXPAND | wxALL, _border);
928 _subject->Bind (wxEVT_TEXT, boost::bind (&KDMEmailPage::kdm_subject_changed, this));
929 _from->Bind (wxEVT_TEXT, boost::bind (&KDMEmailPage::kdm_from_changed, this));
930 _bcc->Bind (wxEVT_TEXT, boost::bind (&KDMEmailPage::kdm_bcc_changed, this));
931 _email->Bind (wxEVT_TEXT, boost::bind (&KDMEmailPage::kdm_email_changed, this));
932 _reset_email->Bind (wxEVT_BUTTON, boost::bind (&KDMEmailPage::reset_email, this));
935 void config_changed ()
937 Config* config = Config::instance ();
939 checked_set (_subject, config->kdm_subject ());
940 checked_set (_from, config->kdm_from ());
941 checked_set (_bcc, config->kdm_bcc ());
942 checked_set (_email, Config::instance()->kdm_email ());
945 void kdm_subject_changed ()
947 Config::instance()->set_kdm_subject (wx_to_std (_subject->GetValue ()));
950 void kdm_from_changed ()
952 Config::instance()->set_kdm_from (wx_to_std (_from->GetValue ()));
955 void kdm_bcc_changed ()
957 Config::instance()->set_kdm_bcc (wx_to_std (_bcc->GetValue ()));
960 void kdm_email_changed ()
962 if (_email->GetValue().IsEmpty ()) {
963 /* Sometimes we get sent an erroneous notification that the email
964 is empty; I don't know why.
968 Config::instance()->set_kdm_email (wx_to_std (_email->GetValue ()));
973 Config::instance()->reset_kdm_email ();
974 checked_set (_email, Config::instance()->kdm_email ());
977 wxTextCtrl* _subject;
979 EditableList<string, EmailDialog>* _cc;
982 wxButton* _reset_email;
985 class AccountsPage : public StandardPage
988 AccountsPage (wxSize panel_size, int border)
989 : StandardPage (panel_size, border)
992 wxString GetName () const
994 return _("Accounts");
998 wxBitmap GetLargeIcon () const
1000 return wxBitmap ("accounts", wxBITMAP_TYPE_PNG_RESOURCE);
1006 wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
1007 table->AddGrowableCol (1, 1);
1008 _panel->GetSizer()->Add (table, 1, wxEXPAND | wxALL, _border);
1010 add_label_to_sizer (table, _panel, _("certificates.barco.com user name"), true);
1011 _barco_username = new wxTextCtrl (_panel, wxID_ANY);
1012 table->Add (_barco_username, 1, wxEXPAND | wxALL);
1014 add_label_to_sizer (table, _panel, _("certificates.barco.com password"), true);
1015 _barco_password = new wxTextCtrl (_panel, wxID_ANY);
1016 table->Add (_barco_password, 1, wxEXPAND | wxALL);
1018 add_label_to_sizer (table, _panel, _("certificates.christiedigital.com user name"), true);
1019 _christie_username = new wxTextCtrl (_panel, wxID_ANY);
1020 table->Add (_christie_username, 1, wxEXPAND | wxALL);
1022 add_label_to_sizer (table, _panel, _("certificates.christiedigital.com password"), true);
1023 _christie_password = new wxTextCtrl (_panel, wxID_ANY);
1024 table->Add (_christie_password, 1, wxEXPAND | wxALL);
1026 add_label_to_sizer (table, _panel, _("GDC user name"), true);
1027 _gdc_username = new wxTextCtrl (_panel, wxID_ANY);
1028 table->Add (_gdc_username, 1, wxEXPAND | wxALL);
1030 add_label_to_sizer (table, _panel, _("GDC password"), true);
1031 _gdc_password = new wxTextCtrl (_panel, wxID_ANY);
1032 table->Add (_gdc_password, 1, wxEXPAND | wxALL);
1034 _barco_username->Bind (wxEVT_TEXT, boost::bind(&AccountsPage::barco_username_changed, this));
1035 _barco_password->Bind (wxEVT_TEXT, boost::bind(&AccountsPage::barco_password_changed, this));
1036 _christie_username->Bind (wxEVT_TEXT, boost::bind(&AccountsPage::christie_username_changed, this));
1037 _christie_password->Bind (wxEVT_TEXT, boost::bind(&AccountsPage::christie_password_changed, this));
1038 _gdc_username->Bind (wxEVT_TEXT, boost::bind(&AccountsPage::gdc_username_changed, this));
1039 _gdc_password->Bind (wxEVT_TEXT, boost::bind(&AccountsPage::gdc_password_changed, this));
1042 void config_changed ()
1044 Config* config = Config::instance ();
1046 checked_set (_barco_username, config->barco_username().get_value_or(""));
1047 checked_set (_barco_password, config->barco_password().get_value_or(""));
1048 checked_set (_christie_username, config->christie_username().get_value_or(""));
1049 checked_set (_christie_password, config->christie_password().get_value_or(""));
1050 checked_set (_gdc_username, config->gdc_username().get_value_or(""));
1051 checked_set (_gdc_password, config->gdc_password().get_value_or(""));
1054 void barco_username_changed ()
1056 wxString const s = _barco_username->GetValue();
1058 Config::instance()->set_barco_username (wx_to_std(s));
1060 Config::instance()->unset_barco_username ();
1064 void barco_password_changed ()
1066 wxString const s = _barco_password->GetValue();
1068 Config::instance()->set_barco_password (wx_to_std(s));
1070 Config::instance()->unset_barco_password ();
1074 void christie_username_changed ()
1076 wxString const s = _christie_username->GetValue();
1078 Config::instance()->set_christie_username (wx_to_std(s));
1080 Config::instance()->unset_christie_username ();
1084 void christie_password_changed ()
1086 wxString const s = _christie_password->GetValue();
1088 Config::instance()->set_christie_password (wx_to_std(s));
1090 Config::instance()->unset_christie_password ();
1094 void gdc_username_changed ()
1096 wxString const s = _gdc_username->GetValue();
1098 Config::instance()->set_gdc_username (wx_to_std(s));
1100 Config::instance()->unset_gdc_username ();
1104 void gdc_password_changed ()
1106 wxString const s = _gdc_password->GetValue();
1108 Config::instance()->set_gdc_password (wx_to_std(s));
1110 Config::instance()->unset_gdc_password ();
1115 wxTextCtrl* _barco_username;
1116 wxTextCtrl* _barco_password;
1117 wxTextCtrl* _christie_username;
1118 wxTextCtrl* _christie_password;
1119 wxTextCtrl* _gdc_username;
1120 wxTextCtrl* _gdc_password;
1124 class NotificationsPage : public StandardPage
1127 NotificationsPage (wxSize panel_size, int border)
1128 #ifdef DCPOMATIC_OSX
1129 /* We have to force both width and height of this one */
1130 : StandardPage (wxSize (panel_size.GetWidth(), 128), border)
1132 : StandardPage (panel_size, border)
1136 wxString GetName () const
1138 return _("Notifications");
1141 #ifdef DCPOMATIC_OSX
1142 wxBitmap GetLargeIcon () const
1144 return wxBitmap ("notifications", wxBITMAP_TYPE_PNG_RESOURCE);
1151 wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
1152 table->AddGrowableCol (1, 1);
1153 _panel->GetSizer()->Add (table, 1, wxEXPAND | wxALL, _border);
1155 _enable_message_box = new CheckBox (_panel, _("Message box"));
1156 table->Add (_enable_message_box, 1, wxEXPAND | wxALL);
1157 table->AddSpacer (0);
1159 _enable_email = new CheckBox (_panel, _("Email"));
1160 table->Add (_enable_email, 1, wxEXPAND | wxALL);
1161 table->AddSpacer (0);
1163 add_label_to_sizer (table, _panel, _("Subject"), true);
1164 _subject = new wxTextCtrl (_panel, wxID_ANY);
1165 table->Add (_subject, 1, wxEXPAND | wxALL);
1167 add_label_to_sizer (table, _panel, _("From address"), true);
1168 _from = new wxTextCtrl (_panel, wxID_ANY);
1169 table->Add (_from, 1, wxEXPAND | wxALL);
1171 add_label_to_sizer (table, _panel, _("To address"), true);
1172 _to = new wxTextCtrl (_panel, wxID_ANY);
1173 table->Add (_to, 1, wxEXPAND | wxALL);
1175 vector<string> columns;
1176 columns.push_back (wx_to_std (_("Address")));
1177 add_label_to_sizer (table, _panel, _("CC addresses"), true);
1178 _cc = new EditableList<string, EmailDialog> (
1181 bind (&Config::notification_cc, Config::instance()),
1182 bind (&Config::set_notification_cc, Config::instance(), _1),
1185 table->Add (_cc, 1, wxEXPAND | wxALL);
1187 add_label_to_sizer (table, _panel, _("BCC address"), true);
1188 _bcc = new wxTextCtrl (_panel, wxID_ANY);
1189 table->Add (_bcc, 1, wxEXPAND | wxALL);
1191 _email = new wxTextCtrl (_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize (-1, 200), wxTE_MULTILINE);
1192 _panel->GetSizer()->Add (_email, 0, wxEXPAND | wxALL, _border);
1194 _reset_email = new Button (_panel, _("Reset to default subject and text"));
1195 _panel->GetSizer()->Add (_reset_email, 0, wxEXPAND | wxALL, _border);
1199 _enable_message_box->Bind (wxEVT_CHECKBOX, boost::bind (&NotificationsPage::type_changed, this, _enable_message_box, Config::MESSAGE_BOX));
1200 _enable_email->Bind (wxEVT_CHECKBOX, boost::bind (&NotificationsPage::type_changed, this, _enable_email, Config::EMAIL));
1202 _subject->Bind (wxEVT_TEXT, boost::bind (&NotificationsPage::notification_subject_changed, this));
1203 _from->Bind (wxEVT_TEXT, boost::bind (&NotificationsPage::notification_from_changed, this));
1204 _to->Bind (wxEVT_TEXT, boost::bind (&NotificationsPage::notification_to_changed, this));
1205 _bcc->Bind (wxEVT_TEXT, boost::bind (&NotificationsPage::notification_bcc_changed, this));
1206 _email->Bind (wxEVT_TEXT, boost::bind (&NotificationsPage::notification_email_changed, this));
1207 _reset_email->Bind (wxEVT_BUTTON, boost::bind (&NotificationsPage::reset_email, this));
1209 update_sensitivity ();
1212 void update_sensitivity ()
1214 bool const s = _enable_email->GetValue();
1215 _subject->Enable(s);
1221 _reset_email->Enable(s);
1224 void config_changed ()
1226 Config* config = Config::instance ();
1228 checked_set (_enable_message_box, config->notification(Config::MESSAGE_BOX));
1229 checked_set (_enable_email, config->notification(Config::EMAIL));
1230 checked_set (_subject, config->notification_subject ());
1231 checked_set (_from, config->notification_from ());
1232 checked_set (_to, config->notification_to ());
1233 checked_set (_bcc, config->notification_bcc ());
1234 checked_set (_email, Config::instance()->notification_email ());
1236 update_sensitivity ();
1239 void notification_subject_changed ()
1241 Config::instance()->set_notification_subject (wx_to_std (_subject->GetValue ()));
1244 void notification_from_changed ()
1246 Config::instance()->set_notification_from (wx_to_std (_from->GetValue ()));
1249 void notification_to_changed ()
1251 Config::instance()->set_notification_to (wx_to_std (_to->GetValue ()));
1254 void notification_bcc_changed ()
1256 Config::instance()->set_notification_bcc (wx_to_std (_bcc->GetValue ()));
1259 void notification_email_changed ()
1261 if (_email->GetValue().IsEmpty ()) {
1262 /* Sometimes we get sent an erroneous notification that the email
1263 is empty; I don't know why.
1267 Config::instance()->set_notification_email (wx_to_std (_email->GetValue ()));
1272 Config::instance()->reset_notification_email ();
1273 checked_set (_email, Config::instance()->notification_email ());
1276 void type_changed (wxCheckBox* b, Config::Notification n)
1278 Config::instance()->set_notification(n, b->GetValue());
1279 update_sensitivity ();
1282 wxCheckBox* _enable_message_box;
1283 wxCheckBox* _enable_email;
1285 wxTextCtrl* _subject;
1288 EditableList<string, EmailDialog>* _cc;
1291 wxButton* _reset_email;
1294 class CoverSheetPage : public StandardPage
1298 CoverSheetPage (wxSize panel_size, int border)
1299 #ifdef DCPOMATIC_OSX
1300 /* We have to force both width and height of this one */
1301 : StandardPage (wxSize (panel_size.GetWidth(), 128), border)
1303 : StandardPage (panel_size, border)
1307 wxString GetName () const
1309 return _("Cover Sheet");
1312 #ifdef DCPOMATIC_OSX
1313 wxBitmap GetLargeIcon () const
1315 return wxBitmap ("cover_sheet", wxBITMAP_TYPE_PNG_RESOURCE);
1322 _cover_sheet = new wxTextCtrl (_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize (-1, 200), wxTE_MULTILINE);
1323 _panel->GetSizer()->Add (_cover_sheet, 0, wxEXPAND | wxALL, _border);
1325 _reset_cover_sheet = new Button (_panel, _("Reset to default text"));
1326 _panel->GetSizer()->Add (_reset_cover_sheet, 0, wxEXPAND | wxALL, _border);
1328 _cover_sheet->Bind (wxEVT_TEXT, boost::bind (&CoverSheetPage::cover_sheet_changed, this));
1329 _reset_cover_sheet->Bind (wxEVT_BUTTON, boost::bind (&CoverSheetPage::reset_cover_sheet, this));
1332 void config_changed ()
1334 checked_set (_cover_sheet, Config::instance()->cover_sheet ());
1337 void cover_sheet_changed ()
1339 if (_cover_sheet->GetValue().IsEmpty ()) {
1340 /* Sometimes we get sent an erroneous notification that the cover sheet
1341 is empty; I don't know why.
1345 Config::instance()->set_cover_sheet (wx_to_std (_cover_sheet->GetValue ()));
1348 void reset_cover_sheet ()
1350 Config::instance()->reset_cover_sheet ();
1351 checked_set (_cover_sheet, Config::instance()->cover_sheet ());
1354 wxTextCtrl* _cover_sheet;
1355 wxButton* _reset_cover_sheet;
1359 /** @class AdvancedPage
1360 * @brief Advanced page of the preferences dialog.
1362 class AdvancedPage : public StockPage
1365 AdvancedPage (wxSize panel_size, int border)
1366 : StockPage (Kind_Advanced, panel_size, border)
1367 , _maximum_j2k_bandwidth (0)
1368 , _allow_any_dcp_frame_rate (0)
1369 , _allow_any_container (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 _allow_any_dcp_frame_rate = new CheckBox (_panel, _("Allow any DCP frame rate"));
1408 table->Add (_allow_any_dcp_frame_rate, 1, wxEXPAND | wxALL);
1409 table->AddSpacer (0);
1411 _allow_any_container = new CheckBox (_panel, _("Allow non-standard container ratios"));
1412 table->Add (_allow_any_container, 1, wxEXPAND | wxALL);
1413 table->AddSpacer (0);
1415 wxStaticText* restart = add_label_to_sizer (table, _panel, _("(restart DCP-o-matic to see all ratios)"), false);
1416 wxFont font = restart->GetFont();
1417 font.SetStyle (wxFONTSTYLE_ITALIC);
1418 font.SetPointSize (font.GetPointSize() - 1);
1419 restart->SetFont (font);
1420 table->AddSpacer (0);
1422 _only_servers_encode = new CheckBox (_panel, _("Only servers encode"));
1423 table->Add (_only_servers_encode, 1, wxEXPAND | wxALL);
1424 table->AddSpacer (0);
1427 add_label_to_sizer (table, _panel, _("Maximum number of frames to store per thread"), true);
1428 wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL);
1429 _frames_in_memory_multiplier = new wxSpinCtrl (_panel);
1430 s->Add (_frames_in_memory_multiplier, 1);
1435 add_top_aligned_label_to_sizer (table, _panel, _("DCP metadata filename format"));
1436 dcp::NameFormat::Map titles;
1437 titles['t'] = wx_to_std (_("type (cpl/pkl)"));
1438 dcp::NameFormat::Map examples;
1439 examples['t'] = "cpl";
1440 _dcp_metadata_filename_format = new NameFormatEditor (
1441 _panel, Config::instance()->dcp_metadata_filename_format(), titles, examples, "_eb1c112c-ca3c-4ae6-9263-c6714ff05d64.xml"
1443 table->Add (_dcp_metadata_filename_format->panel(), 1, wxEXPAND | wxALL);
1447 add_top_aligned_label_to_sizer (table, _panel, _("DCP asset filename format"));
1448 dcp::NameFormat::Map titles;
1449 titles['t'] = wx_to_std (_("type (j2c/pcm/sub)"));
1450 titles['r'] = wx_to_std (_("reel number"));
1451 titles['n'] = wx_to_std (_("number of reels"));
1452 titles['c'] = wx_to_std (_("content filename"));
1453 dcp::NameFormat::Map examples;
1454 examples['t'] = "j2c";
1455 examples['r'] = "1";
1456 examples['n'] = "4";
1457 examples['c'] = "myfile.mp4";
1458 _dcp_asset_filename_format = new NameFormatEditor (
1459 _panel, Config::instance()->dcp_asset_filename_format(), titles, examples, "_eb1c112c-ca3c-4ae6-9263-c6714ff05d64.mxf"
1461 table->Add (_dcp_asset_filename_format->panel(), 1, wxEXPAND | wxALL);
1465 add_top_aligned_label_to_sizer (table, _panel, _("Log"));
1466 wxBoxSizer* t = new wxBoxSizer (wxVERTICAL);
1467 _log_general = new CheckBox (_panel, _("General"));
1468 t->Add (_log_general, 1, wxEXPAND | wxALL);
1469 _log_warning = new CheckBox (_panel, _("Warnings"));
1470 t->Add (_log_warning, 1, wxEXPAND | wxALL);
1471 _log_error = new CheckBox (_panel, _("Errors"));
1472 t->Add (_log_error, 1, wxEXPAND | wxALL);
1473 /// TRANSLATORS: translate the word "Timing" here; do not include the "Config|" prefix
1474 _log_timing = new CheckBox (_panel, S_("Config|Timing"));
1475 t->Add (_log_timing, 1, wxEXPAND | wxALL);
1476 _log_debug_decode = new CheckBox (_panel, _("Debug: decode"));
1477 t->Add (_log_debug_decode, 1, wxEXPAND | wxALL);
1478 _log_debug_encode = new CheckBox (_panel, _("Debug: encode"));
1479 t->Add (_log_debug_encode, 1, wxEXPAND | wxALL);
1480 _log_debug_email = new CheckBox (_panel, _("Debug: email sending"));
1481 t->Add (_log_debug_email, 1, wxEXPAND | wxALL);
1482 table->Add (t, 0, wxALL, 6);
1485 #ifdef DCPOMATIC_WINDOWS
1486 _win32_console = new CheckBox (_panel, _("Open console window"));
1487 table->Add (_win32_console, 1, wxEXPAND | wxALL);
1488 table->AddSpacer (0);
1491 _maximum_j2k_bandwidth->SetRange (1, 1000);
1492 _maximum_j2k_bandwidth->Bind (wxEVT_SPINCTRL, boost::bind (&AdvancedPage::maximum_j2k_bandwidth_changed, this));
1493 _allow_any_dcp_frame_rate->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::allow_any_dcp_frame_rate_changed, this));
1494 _allow_any_container->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::allow_any_container_changed, this));
1495 _only_servers_encode->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::only_servers_encode_changed, this));
1496 _frames_in_memory_multiplier->Bind (wxEVT_SPINCTRL, boost::bind(&AdvancedPage::frames_in_memory_multiplier_changed, this));
1497 _dcp_metadata_filename_format->Changed.connect (boost::bind (&AdvancedPage::dcp_metadata_filename_format_changed, this));
1498 _dcp_asset_filename_format->Changed.connect (boost::bind (&AdvancedPage::dcp_asset_filename_format_changed, this));
1499 _log_general->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::log_changed, this));
1500 _log_warning->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::log_changed, this));
1501 _log_error->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::log_changed, this));
1502 _log_timing->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::log_changed, this));
1503 _log_debug_decode->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::log_changed, this));
1504 _log_debug_encode->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::log_changed, this));
1505 _log_debug_email->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::log_changed, this));
1506 #ifdef DCPOMATIC_WINDOWS
1507 _win32_console->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::win32_console_changed, this));
1511 void config_changed ()
1513 Config* config = Config::instance ();
1515 checked_set (_maximum_j2k_bandwidth, config->maximum_j2k_bandwidth() / 1000000);
1516 checked_set (_allow_any_dcp_frame_rate, config->allow_any_dcp_frame_rate ());
1517 checked_set (_allow_any_container, config->allow_any_container ());
1518 checked_set (_only_servers_encode, config->only_servers_encode ());
1519 checked_set (_log_general, config->log_types() & LogEntry::TYPE_GENERAL);
1520 checked_set (_log_warning, config->log_types() & LogEntry::TYPE_WARNING);
1521 checked_set (_log_error, config->log_types() & LogEntry::TYPE_ERROR);
1522 checked_set (_log_timing, config->log_types() & LogEntry::TYPE_TIMING);
1523 checked_set (_log_debug_decode, config->log_types() & LogEntry::TYPE_DEBUG_DECODE);
1524 checked_set (_log_debug_encode, config->log_types() & LogEntry::TYPE_DEBUG_ENCODE);
1525 checked_set (_log_debug_email, config->log_types() & LogEntry::TYPE_DEBUG_EMAIL);
1526 checked_set (_frames_in_memory_multiplier, config->frames_in_memory_multiplier());
1527 #ifdef DCPOMATIC_WINDOWS
1528 checked_set (_win32_console, config->win32_console());
1532 void maximum_j2k_bandwidth_changed ()
1534 Config::instance()->set_maximum_j2k_bandwidth (_maximum_j2k_bandwidth->GetValue() * 1000000);
1537 void frames_in_memory_multiplier_changed ()
1539 Config::instance()->set_frames_in_memory_multiplier (_frames_in_memory_multiplier->GetValue());
1542 void allow_any_dcp_frame_rate_changed ()
1544 Config::instance()->set_allow_any_dcp_frame_rate (_allow_any_dcp_frame_rate->GetValue ());
1547 void allow_any_container_changed ()
1549 Config::instance()->set_allow_any_container (_allow_any_container->GetValue ());
1552 void only_servers_encode_changed ()
1554 Config::instance()->set_only_servers_encode (_only_servers_encode->GetValue ());
1557 void dcp_metadata_filename_format_changed ()
1559 Config::instance()->set_dcp_metadata_filename_format (_dcp_metadata_filename_format->get ());
1562 void dcp_asset_filename_format_changed ()
1564 Config::instance()->set_dcp_asset_filename_format (_dcp_asset_filename_format->get ());
1570 if (_log_general->GetValue ()) {
1571 types |= LogEntry::TYPE_GENERAL;
1573 if (_log_warning->GetValue ()) {
1574 types |= LogEntry::TYPE_WARNING;
1576 if (_log_error->GetValue ()) {
1577 types |= LogEntry::TYPE_ERROR;
1579 if (_log_timing->GetValue ()) {
1580 types |= LogEntry::TYPE_TIMING;
1582 if (_log_debug_decode->GetValue ()) {
1583 types |= LogEntry::TYPE_DEBUG_DECODE;
1585 if (_log_debug_encode->GetValue ()) {
1586 types |= LogEntry::TYPE_DEBUG_ENCODE;
1588 if (_log_debug_email->GetValue ()) {
1589 types |= LogEntry::TYPE_DEBUG_EMAIL;
1591 Config::instance()->set_log_types (types);
1594 #ifdef DCPOMATIC_WINDOWS
1595 void win32_console_changed ()
1597 Config::instance()->set_win32_console (_win32_console->GetValue ());
1601 wxSpinCtrl* _maximum_j2k_bandwidth;
1602 wxSpinCtrl* _frames_in_memory_multiplier;
1603 wxCheckBox* _allow_any_dcp_frame_rate;
1604 wxCheckBox* _allow_any_container;
1605 wxCheckBox* _only_servers_encode;
1606 NameFormatEditor* _dcp_metadata_filename_format;
1607 NameFormatEditor* _dcp_asset_filename_format;
1608 wxCheckBox* _log_general;
1609 wxCheckBox* _log_warning;
1610 wxCheckBox* _log_error;
1611 wxCheckBox* _log_timing;
1612 wxCheckBox* _log_debug_decode;
1613 wxCheckBox* _log_debug_encode;
1614 wxCheckBox* _log_debug_email;
1615 #ifdef DCPOMATIC_WINDOWS
1616 wxCheckBox* _win32_console;
1620 wxPreferencesEditor*
1621 create_full_config_dialog ()
1623 wxPreferencesEditor* e = new wxPreferencesEditor ();
1625 #ifdef DCPOMATIC_OSX
1626 /* Width that we force some of the config panels to be on OSX so that
1627 the containing window doesn't shrink too much when we select those panels.
1628 This is obviously an unpleasant hack.
1630 wxSize ps = wxSize (700, -1);
1631 int const border = 16;
1633 wxSize ps = wxSize (-1, -1);
1634 int const border = 8;
1637 e->AddPage (new FullGeneralPage (ps, border));
1638 e->AddPage (new DefaultsPage (ps, border));
1639 e->AddPage (new EncodingServersPage (ps, border));
1640 e->AddPage (new KeysPage (ps, border));
1641 e->AddPage (new TMSPage (ps, border));
1642 e->AddPage (new EmailPage (ps, border));
1643 e->AddPage (new KDMEmailPage (ps, border));
1644 e->AddPage (new AccountsPage (ps, border));
1645 e->AddPage (new NotificationsPage (ps, border));
1646 e->AddPage (new CoverSheetPage (ps, border));
1647 e->AddPage (new AdvancedPage (ps, border));