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<Protocol> (_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 table->Add (s, 1, wxEXPAND | wxALL);
772 add_label_to_sizer (table, _panel, _("Mail user name"), true);
773 _user = new wxTextCtrl (_panel, wxID_ANY);
774 table->Add (_user, 1, wxEXPAND | wxALL);
776 add_label_to_sizer (table, _panel, _("Mail password"), true);
777 _password = new wxTextCtrl (_panel, wxID_ANY);
778 table->Add (_password, 1, wxEXPAND | wxALL);
780 _server->Bind (wxEVT_TEXT, boost::bind (&EmailPage::server_changed, this));
781 _port->Bind (wxEVT_SPINCTRL, boost::bind (&EmailPage::port_changed, this));
782 _user->Bind (wxEVT_TEXT, boost::bind (&EmailPage::user_changed, this));
783 _password->Bind (wxEVT_TEXT, boost::bind (&EmailPage::password_changed, this));
786 void config_changed ()
788 Config* config = Config::instance ();
790 checked_set (_server, config->mail_server ());
791 checked_set (_port, config->mail_port ());
792 checked_set (_user, config->mail_user ());
793 checked_set (_password, config->mail_password ());
796 void server_changed ()
798 Config::instance()->set_mail_server (wx_to_std (_server->GetValue ()));
803 Config::instance()->set_mail_port (_port->GetValue ());
808 Config::instance()->set_mail_user (wx_to_std (_user->GetValue ()));
811 void password_changed ()
813 Config::instance()->set_mail_password (wx_to_std (_password->GetValue ()));
819 wxTextCtrl* _password;
822 class KDMEmailPage : public StandardPage
826 KDMEmailPage (wxSize panel_size, int border)
828 /* We have to force both width and height of this one */
829 : StandardPage (wxSize (panel_size.GetWidth(), 128), border)
831 : StandardPage (panel_size, border)
835 wxString GetName () const
837 return _("KDM Email");
841 wxBitmap GetLargeIcon () const
843 return wxBitmap ("kdm_email", wxBITMAP_TYPE_PNG_RESOURCE);
850 wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
851 table->AddGrowableCol (1, 1);
852 _panel->GetSizer()->Add (table, 1, wxEXPAND | wxALL, _border);
854 add_label_to_sizer (table, _panel, _("Subject"), true);
855 _subject = new wxTextCtrl (_panel, wxID_ANY);
856 table->Add (_subject, 1, wxEXPAND | wxALL);
858 add_label_to_sizer (table, _panel, _("From address"), true);
859 _from = new wxTextCtrl (_panel, wxID_ANY);
860 table->Add (_from, 1, wxEXPAND | wxALL);
862 vector<string> columns;
863 columns.push_back (wx_to_std (_("Address")));
864 add_label_to_sizer (table, _panel, _("CC addresses"), true);
865 _cc = new EditableList<string, EmailDialog> (
868 bind (&Config::kdm_cc, Config::instance()),
869 bind (&Config::set_kdm_cc, Config::instance(), _1),
872 table->Add (_cc, 1, wxEXPAND | wxALL);
874 add_label_to_sizer (table, _panel, _("BCC address"), true);
875 _bcc = new wxTextCtrl (_panel, wxID_ANY);
876 table->Add (_bcc, 1, wxEXPAND | wxALL);
878 _email = new wxTextCtrl (_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize (-1, 200), wxTE_MULTILINE);
879 _panel->GetSizer()->Add (_email, 0, wxEXPAND | wxALL, _border);
881 _reset_email = new Button (_panel, _("Reset to default subject and text"));
882 _panel->GetSizer()->Add (_reset_email, 0, wxEXPAND | wxALL, _border);
886 _subject->Bind (wxEVT_TEXT, boost::bind (&KDMEmailPage::kdm_subject_changed, this));
887 _from->Bind (wxEVT_TEXT, boost::bind (&KDMEmailPage::kdm_from_changed, this));
888 _bcc->Bind (wxEVT_TEXT, boost::bind (&KDMEmailPage::kdm_bcc_changed, this));
889 _email->Bind (wxEVT_TEXT, boost::bind (&KDMEmailPage::kdm_email_changed, this));
890 _reset_email->Bind (wxEVT_BUTTON, boost::bind (&KDMEmailPage::reset_email, this));
893 void config_changed ()
895 Config* config = Config::instance ();
897 checked_set (_subject, config->kdm_subject ());
898 checked_set (_from, config->kdm_from ());
899 checked_set (_bcc, config->kdm_bcc ());
900 checked_set (_email, Config::instance()->kdm_email ());
903 void kdm_subject_changed ()
905 Config::instance()->set_kdm_subject (wx_to_std (_subject->GetValue ()));
908 void kdm_from_changed ()
910 Config::instance()->set_kdm_from (wx_to_std (_from->GetValue ()));
913 void kdm_bcc_changed ()
915 Config::instance()->set_kdm_bcc (wx_to_std (_bcc->GetValue ()));
918 void kdm_email_changed ()
920 if (_email->GetValue().IsEmpty ()) {
921 /* Sometimes we get sent an erroneous notification that the email
922 is empty; I don't know why.
926 Config::instance()->set_kdm_email (wx_to_std (_email->GetValue ()));
931 Config::instance()->reset_kdm_email ();
932 checked_set (_email, Config::instance()->kdm_email ());
935 wxTextCtrl* _subject;
937 EditableList<string, EmailDialog>* _cc;
940 wxButton* _reset_email;
943 class AccountsPage : public StandardPage
946 AccountsPage (wxSize panel_size, int border)
947 : StandardPage (panel_size, border)
950 wxString GetName () const
952 return _("Accounts");
956 wxBitmap GetLargeIcon () const
958 return wxBitmap ("accounts", wxBITMAP_TYPE_PNG_RESOURCE);
964 wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
965 table->AddGrowableCol (1, 1);
966 _panel->GetSizer()->Add (table, 1, wxEXPAND | wxALL, _border);
968 add_label_to_sizer (table, _panel, _("certificates.barco.com username"), true);
969 _barco_username = new wxTextCtrl (_panel, wxID_ANY);
970 table->Add (_barco_username, 1, wxEXPAND | wxALL);
972 add_label_to_sizer (table, _panel, _("certificates.barco.com password"), true);
973 _barco_password = new wxTextCtrl (_panel, wxID_ANY);
974 table->Add (_barco_password, 1, wxEXPAND | wxALL);
976 add_label_to_sizer (table, _panel, _("certificates.christiedigital.com username"), true);
977 _christie_username = new wxTextCtrl (_panel, wxID_ANY);
978 table->Add (_christie_username, 1, wxEXPAND | wxALL);
980 add_label_to_sizer (table, _panel, _("certificates.christiedigital.com password"), true);
981 _christie_password = new wxTextCtrl (_panel, wxID_ANY);
982 table->Add (_christie_password, 1, wxEXPAND | wxALL);
984 _barco_username->Bind (wxEVT_TEXT, boost::bind(&AccountsPage::barco_username_changed, this));
985 _barco_password->Bind (wxEVT_TEXT, boost::bind(&AccountsPage::barco_password_changed, this));
986 _christie_username->Bind (wxEVT_TEXT, boost::bind(&AccountsPage::christie_username_changed, this));
987 _christie_password->Bind (wxEVT_TEXT, boost::bind(&AccountsPage::christie_password_changed, this));
990 void config_changed ()
992 Config* config = Config::instance ();
994 checked_set (_barco_username, config->barco_username().get_value_or(""));
995 checked_set (_barco_password, config->barco_password().get_value_or(""));
996 checked_set (_christie_username, config->christie_username().get_value_or(""));
997 checked_set (_christie_password, config->christie_password().get_value_or(""));
1000 void barco_username_changed ()
1002 wxString const s = _barco_username->GetValue();
1004 Config::instance()->set_barco_username (wx_to_std(s));
1006 Config::instance()->unset_barco_username ();
1010 void barco_password_changed ()
1012 wxString const s = _barco_password->GetValue();
1014 Config::instance()->set_barco_password (wx_to_std(s));
1016 Config::instance()->unset_barco_password ();
1020 void christie_username_changed ()
1022 wxString const s = _christie_username->GetValue();
1024 Config::instance()->set_christie_username (wx_to_std(s));
1026 Config::instance()->unset_christie_username ();
1030 void christie_password_changed ()
1032 wxString const s = _christie_password->GetValue();
1034 Config::instance()->set_christie_password (wx_to_std(s));
1036 Config::instance()->unset_christie_password ();
1041 wxTextCtrl* _barco_username;
1042 wxTextCtrl* _barco_password;
1043 wxTextCtrl* _christie_username;
1044 wxTextCtrl* _christie_password;
1048 class NotificationsPage : public StandardPage
1051 NotificationsPage (wxSize panel_size, int border)
1052 #ifdef DCPOMATIC_OSX
1053 /* We have to force both width and height of this one */
1054 : StandardPage (wxSize (panel_size.GetWidth(), 128), border)
1056 : StandardPage (panel_size, border)
1060 wxString GetName () const
1062 return _("Notifications");
1065 #ifdef DCPOMATIC_OSX
1066 wxBitmap GetLargeIcon () const
1068 return wxBitmap ("notifications", wxBITMAP_TYPE_PNG_RESOURCE);
1075 wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
1076 table->AddGrowableCol (1, 1);
1077 _panel->GetSizer()->Add (table, 1, wxEXPAND | wxALL, _border);
1079 _enable_message_box = new CheckBox (_panel, _("Message box"));
1080 table->Add (_enable_message_box, 1, wxEXPAND | wxALL);
1081 table->AddSpacer (0);
1083 _enable_email = new CheckBox (_panel, _("Email"));
1084 table->Add (_enable_email, 1, wxEXPAND | wxALL);
1085 table->AddSpacer (0);
1087 add_label_to_sizer (table, _panel, _("Subject"), true);
1088 _subject = new wxTextCtrl (_panel, wxID_ANY);
1089 table->Add (_subject, 1, wxEXPAND | wxALL);
1091 add_label_to_sizer (table, _panel, _("From address"), true);
1092 _from = new wxTextCtrl (_panel, wxID_ANY);
1093 table->Add (_from, 1, wxEXPAND | wxALL);
1095 add_label_to_sizer (table, _panel, _("To address"), true);
1096 _to = new wxTextCtrl (_panel, wxID_ANY);
1097 table->Add (_to, 1, wxEXPAND | wxALL);
1099 vector<string> columns;
1100 columns.push_back (wx_to_std (_("Address")));
1101 add_label_to_sizer (table, _panel, _("CC addresses"), true);
1102 _cc = new EditableList<string, EmailDialog> (
1105 bind (&Config::notification_cc, Config::instance()),
1106 bind (&Config::set_notification_cc, Config::instance(), _1),
1109 table->Add (_cc, 1, wxEXPAND | wxALL);
1111 add_label_to_sizer (table, _panel, _("BCC address"), true);
1112 _bcc = new wxTextCtrl (_panel, wxID_ANY);
1113 table->Add (_bcc, 1, wxEXPAND | wxALL);
1115 _email = new wxTextCtrl (_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize (-1, 200), wxTE_MULTILINE);
1116 _panel->GetSizer()->Add (_email, 0, wxEXPAND | wxALL, _border);
1118 _reset_email = new Button (_panel, _("Reset to default subject and text"));
1119 _panel->GetSizer()->Add (_reset_email, 0, wxEXPAND | wxALL, _border);
1123 _enable_message_box->Bind (wxEVT_CHECKBOX, boost::bind (&NotificationsPage::type_changed, this, _enable_message_box, Config::MESSAGE_BOX));
1124 _enable_email->Bind (wxEVT_CHECKBOX, boost::bind (&NotificationsPage::type_changed, this, _enable_email, Config::EMAIL));
1126 _subject->Bind (wxEVT_TEXT, boost::bind (&NotificationsPage::notification_subject_changed, this));
1127 _from->Bind (wxEVT_TEXT, boost::bind (&NotificationsPage::notification_from_changed, this));
1128 _to->Bind (wxEVT_TEXT, boost::bind (&NotificationsPage::notification_to_changed, this));
1129 _bcc->Bind (wxEVT_TEXT, boost::bind (&NotificationsPage::notification_bcc_changed, this));
1130 _email->Bind (wxEVT_TEXT, boost::bind (&NotificationsPage::notification_email_changed, this));
1131 _reset_email->Bind (wxEVT_BUTTON, boost::bind (&NotificationsPage::reset_email, this));
1133 update_sensitivity ();
1136 void update_sensitivity ()
1138 bool const s = _enable_email->GetValue();
1139 _subject->Enable(s);
1145 _reset_email->Enable(s);
1148 void config_changed ()
1150 Config* config = Config::instance ();
1152 checked_set (_enable_message_box, config->notification(Config::MESSAGE_BOX));
1153 checked_set (_enable_email, config->notification(Config::EMAIL));
1154 checked_set (_subject, config->notification_subject ());
1155 checked_set (_from, config->notification_from ());
1156 checked_set (_to, config->notification_to ());
1157 checked_set (_bcc, config->notification_bcc ());
1158 checked_set (_email, Config::instance()->notification_email ());
1160 update_sensitivity ();
1163 void notification_subject_changed ()
1165 Config::instance()->set_notification_subject (wx_to_std (_subject->GetValue ()));
1168 void notification_from_changed ()
1170 Config::instance()->set_notification_from (wx_to_std (_from->GetValue ()));
1173 void notification_to_changed ()
1175 Config::instance()->set_notification_to (wx_to_std (_to->GetValue ()));
1178 void notification_bcc_changed ()
1180 Config::instance()->set_notification_bcc (wx_to_std (_bcc->GetValue ()));
1183 void notification_email_changed ()
1185 if (_email->GetValue().IsEmpty ()) {
1186 /* Sometimes we get sent an erroneous notification that the email
1187 is empty; I don't know why.
1191 Config::instance()->set_notification_email (wx_to_std (_email->GetValue ()));
1196 Config::instance()->reset_notification_email ();
1197 checked_set (_email, Config::instance()->notification_email ());
1200 void type_changed (wxCheckBox* b, Config::Notification n)
1202 Config::instance()->set_notification(n, b->GetValue());
1203 update_sensitivity ();
1206 wxCheckBox* _enable_message_box;
1207 wxCheckBox* _enable_email;
1209 wxTextCtrl* _subject;
1212 EditableList<string, EmailDialog>* _cc;
1215 wxButton* _reset_email;
1218 class CoverSheetPage : public StandardPage
1222 CoverSheetPage (wxSize panel_size, int border)
1223 #ifdef DCPOMATIC_OSX
1224 /* We have to force both width and height of this one */
1225 : StandardPage (wxSize (panel_size.GetWidth(), 128), border)
1227 : StandardPage (panel_size, border)
1231 wxString GetName () const
1233 return _("Cover Sheet");
1236 #ifdef DCPOMATIC_OSX
1237 wxBitmap GetLargeIcon () const
1239 return wxBitmap ("cover_sheet", wxBITMAP_TYPE_PNG_RESOURCE);
1246 _cover_sheet = new wxTextCtrl (_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize (-1, 200), wxTE_MULTILINE);
1247 _panel->GetSizer()->Add (_cover_sheet, 0, wxEXPAND | wxALL, _border);
1249 _reset_cover_sheet = new Button (_panel, _("Reset to default text"));
1250 _panel->GetSizer()->Add (_reset_cover_sheet, 0, wxEXPAND | wxALL, _border);
1252 _cover_sheet->Bind (wxEVT_TEXT, boost::bind (&CoverSheetPage::cover_sheet_changed, this));
1253 _reset_cover_sheet->Bind (wxEVT_BUTTON, boost::bind (&CoverSheetPage::reset_cover_sheet, this));
1256 void config_changed ()
1258 checked_set (_cover_sheet, Config::instance()->cover_sheet ());
1261 void cover_sheet_changed ()
1263 if (_cover_sheet->GetValue().IsEmpty ()) {
1264 /* Sometimes we get sent an erroneous notification that the cover sheet
1265 is empty; I don't know why.
1269 Config::instance()->set_cover_sheet (wx_to_std (_cover_sheet->GetValue ()));
1272 void reset_cover_sheet ()
1274 Config::instance()->reset_cover_sheet ();
1275 checked_set (_cover_sheet, Config::instance()->cover_sheet ());
1278 wxTextCtrl* _cover_sheet;
1279 wxButton* _reset_cover_sheet;
1283 /** @class AdvancedPage
1284 * @brief Advanced page of the preferences dialog.
1286 class AdvancedPage : public StockPage
1289 AdvancedPage (wxSize panel_size, int border)
1290 : StockPage (Kind_Advanced, panel_size, border)
1291 , _maximum_j2k_bandwidth (0)
1292 , _allow_any_dcp_frame_rate (0)
1293 , _allow_any_container (0)
1294 , _only_servers_encode (0)
1299 , _log_debug_decode (0)
1300 , _log_debug_encode (0)
1301 , _log_debug_email (0)
1305 void add_top_aligned_label_to_sizer (wxSizer* table, wxWindow* parent, wxString text)
1307 int flags = wxALIGN_TOP | wxTOP | wxLEFT;
1309 flags |= wxALIGN_RIGHT;
1312 wxStaticText* m = new StaticText (parent, text);
1313 table->Add (m, 0, flags, DCPOMATIC_SIZER_Y_GAP);
1318 wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
1319 table->AddGrowableCol (1, 1);
1320 _panel->GetSizer()->Add (table, 1, wxALL | wxEXPAND, _border);
1323 add_label_to_sizer (table, _panel, _("Maximum JPEG2000 bandwidth"), true);
1324 wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL);
1325 _maximum_j2k_bandwidth = new wxSpinCtrl (_panel);
1326 s->Add (_maximum_j2k_bandwidth, 1);
1327 add_label_to_sizer (s, _panel, _("Mbit/s"), false);
1331 _allow_any_dcp_frame_rate = new CheckBox (_panel, _("Allow any DCP frame rate"));
1332 table->Add (_allow_any_dcp_frame_rate, 1, wxEXPAND | wxALL);
1333 table->AddSpacer (0);
1335 _allow_any_container = new CheckBox (_panel, _("Allow non-standard container ratios"));
1336 table->Add (_allow_any_container, 1, wxEXPAND | wxALL);
1337 table->AddSpacer (0);
1339 wxStaticText* restart = add_label_to_sizer (table, _panel, _("(restart DCP-o-matic to see all ratios)"), false);
1340 wxFont font = restart->GetFont();
1341 font.SetStyle (wxFONTSTYLE_ITALIC);
1342 font.SetPointSize (font.GetPointSize() - 1);
1343 restart->SetFont (font);
1344 table->AddSpacer (0);
1346 _only_servers_encode = new CheckBox (_panel, _("Only servers encode"));
1347 table->Add (_only_servers_encode, 1, wxEXPAND | wxALL);
1348 table->AddSpacer (0);
1351 add_label_to_sizer (table, _panel, _("Maximum number of frames to store per thread"), true);
1352 wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL);
1353 _frames_in_memory_multiplier = new wxSpinCtrl (_panel);
1354 s->Add (_frames_in_memory_multiplier, 1);
1359 add_top_aligned_label_to_sizer (table, _panel, _("DCP metadata filename format"));
1360 dcp::NameFormat::Map titles;
1361 titles['t'] = "type (cpl/pkl)";
1362 dcp::NameFormat::Map examples;
1363 examples['t'] = "cpl";
1364 _dcp_metadata_filename_format = new NameFormatEditor (
1365 _panel, Config::instance()->dcp_metadata_filename_format(), titles, examples, "_eb1c112c-ca3c-4ae6-9263-c6714ff05d64.xml"
1367 table->Add (_dcp_metadata_filename_format->panel(), 1, wxEXPAND | wxALL);
1371 add_top_aligned_label_to_sizer (table, _panel, _("DCP asset filename format"));
1372 dcp::NameFormat::Map titles;
1373 titles['t'] = "type (j2c/pcm/sub)";
1374 titles['r'] = "reel number";
1375 titles['n'] = "number of reels";
1376 titles['c'] = "content filename";
1377 dcp::NameFormat::Map examples;
1378 examples['t'] = "j2c";
1379 examples['r'] = "1";
1380 examples['n'] = "4";
1381 examples['c'] = "myfile.mp4";
1382 _dcp_asset_filename_format = new NameFormatEditor (
1383 _panel, Config::instance()->dcp_asset_filename_format(), titles, examples, "_eb1c112c-ca3c-4ae6-9263-c6714ff05d64.mxf"
1385 table->Add (_dcp_asset_filename_format->panel(), 1, wxEXPAND | wxALL);
1389 add_top_aligned_label_to_sizer (table, _panel, _("Log"));
1390 wxBoxSizer* t = new wxBoxSizer (wxVERTICAL);
1391 _log_general = new CheckBox (_panel, _("General"));
1392 t->Add (_log_general, 1, wxEXPAND | wxALL);
1393 _log_warning = new CheckBox (_panel, _("Warnings"));
1394 t->Add (_log_warning, 1, wxEXPAND | wxALL);
1395 _log_error = new CheckBox (_panel, _("Errors"));
1396 t->Add (_log_error, 1, wxEXPAND | wxALL);
1397 /// TRANSLATORS: translate the word "Timing" here; do not include the "Config|" prefix
1398 _log_timing = new CheckBox (_panel, S_("Config|Timing"));
1399 t->Add (_log_timing, 1, wxEXPAND | wxALL);
1400 _log_debug_decode = new CheckBox (_panel, _("Debug: decode"));
1401 t->Add (_log_debug_decode, 1, wxEXPAND | wxALL);
1402 _log_debug_encode = new CheckBox (_panel, _("Debug: encode"));
1403 t->Add (_log_debug_encode, 1, wxEXPAND | wxALL);
1404 _log_debug_email = new CheckBox (_panel, _("Debug: email sending"));
1405 t->Add (_log_debug_email, 1, wxEXPAND | wxALL);
1406 table->Add (t, 0, wxALL, 6);
1409 #ifdef DCPOMATIC_WINDOWS
1410 _win32_console = new CheckBox (_panel, _("Open console window"));
1411 table->Add (_win32_console, 1, wxEXPAND | wxALL);
1412 table->AddSpacer (0);
1415 _maximum_j2k_bandwidth->SetRange (1, 1000);
1416 _maximum_j2k_bandwidth->Bind (wxEVT_SPINCTRL, boost::bind (&AdvancedPage::maximum_j2k_bandwidth_changed, this));
1417 _allow_any_dcp_frame_rate->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::allow_any_dcp_frame_rate_changed, this));
1418 _allow_any_container->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::allow_any_container_changed, this));
1419 _only_servers_encode->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::only_servers_encode_changed, this));
1420 _frames_in_memory_multiplier->Bind (wxEVT_SPINCTRL, boost::bind(&AdvancedPage::frames_in_memory_multiplier_changed, this));
1421 _dcp_metadata_filename_format->Changed.connect (boost::bind (&AdvancedPage::dcp_metadata_filename_format_changed, this));
1422 _dcp_asset_filename_format->Changed.connect (boost::bind (&AdvancedPage::dcp_asset_filename_format_changed, this));
1423 _log_general->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::log_changed, this));
1424 _log_warning->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::log_changed, this));
1425 _log_error->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::log_changed, this));
1426 _log_timing->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::log_changed, this));
1427 _log_debug_decode->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::log_changed, this));
1428 _log_debug_encode->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::log_changed, this));
1429 _log_debug_email->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::log_changed, this));
1430 #ifdef DCPOMATIC_WINDOWS
1431 _win32_console->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::win32_console_changed, this));
1435 void config_changed ()
1437 Config* config = Config::instance ();
1439 checked_set (_maximum_j2k_bandwidth, config->maximum_j2k_bandwidth() / 1000000);
1440 checked_set (_allow_any_dcp_frame_rate, config->allow_any_dcp_frame_rate ());
1441 checked_set (_allow_any_container, config->allow_any_container ());
1442 checked_set (_only_servers_encode, config->only_servers_encode ());
1443 checked_set (_log_general, config->log_types() & LogEntry::TYPE_GENERAL);
1444 checked_set (_log_warning, config->log_types() & LogEntry::TYPE_WARNING);
1445 checked_set (_log_error, config->log_types() & LogEntry::TYPE_ERROR);
1446 checked_set (_log_timing, config->log_types() & LogEntry::TYPE_TIMING);
1447 checked_set (_log_debug_decode, config->log_types() & LogEntry::TYPE_DEBUG_DECODE);
1448 checked_set (_log_debug_encode, config->log_types() & LogEntry::TYPE_DEBUG_ENCODE);
1449 checked_set (_log_debug_email, config->log_types() & LogEntry::TYPE_DEBUG_EMAIL);
1450 checked_set (_frames_in_memory_multiplier, config->frames_in_memory_multiplier());
1451 #ifdef DCPOMATIC_WINDOWS
1452 checked_set (_win32_console, config->win32_console());
1456 void maximum_j2k_bandwidth_changed ()
1458 Config::instance()->set_maximum_j2k_bandwidth (_maximum_j2k_bandwidth->GetValue() * 1000000);
1461 void frames_in_memory_multiplier_changed ()
1463 Config::instance()->set_frames_in_memory_multiplier (_frames_in_memory_multiplier->GetValue());
1466 void allow_any_dcp_frame_rate_changed ()
1468 Config::instance()->set_allow_any_dcp_frame_rate (_allow_any_dcp_frame_rate->GetValue ());
1471 void allow_any_container_changed ()
1473 Config::instance()->set_allow_any_container (_allow_any_container->GetValue ());
1476 void only_servers_encode_changed ()
1478 Config::instance()->set_only_servers_encode (_only_servers_encode->GetValue ());
1481 void dcp_metadata_filename_format_changed ()
1483 Config::instance()->set_dcp_metadata_filename_format (_dcp_metadata_filename_format->get ());
1486 void dcp_asset_filename_format_changed ()
1488 Config::instance()->set_dcp_asset_filename_format (_dcp_asset_filename_format->get ());
1494 if (_log_general->GetValue ()) {
1495 types |= LogEntry::TYPE_GENERAL;
1497 if (_log_warning->GetValue ()) {
1498 types |= LogEntry::TYPE_WARNING;
1500 if (_log_error->GetValue ()) {
1501 types |= LogEntry::TYPE_ERROR;
1503 if (_log_timing->GetValue ()) {
1504 types |= LogEntry::TYPE_TIMING;
1506 if (_log_debug_decode->GetValue ()) {
1507 types |= LogEntry::TYPE_DEBUG_DECODE;
1509 if (_log_debug_encode->GetValue ()) {
1510 types |= LogEntry::TYPE_DEBUG_ENCODE;
1512 if (_log_debug_email->GetValue ()) {
1513 types |= LogEntry::TYPE_DEBUG_EMAIL;
1515 Config::instance()->set_log_types (types);
1518 #ifdef DCPOMATIC_WINDOWS
1519 void win32_console_changed ()
1521 Config::instance()->set_win32_console (_win32_console->GetValue ());
1525 wxSpinCtrl* _maximum_j2k_bandwidth;
1526 wxSpinCtrl* _frames_in_memory_multiplier;
1527 wxCheckBox* _allow_any_dcp_frame_rate;
1528 wxCheckBox* _allow_any_container;
1529 wxCheckBox* _only_servers_encode;
1530 NameFormatEditor* _dcp_metadata_filename_format;
1531 NameFormatEditor* _dcp_asset_filename_format;
1532 wxCheckBox* _log_general;
1533 wxCheckBox* _log_warning;
1534 wxCheckBox* _log_error;
1535 wxCheckBox* _log_timing;
1536 wxCheckBox* _log_debug_decode;
1537 wxCheckBox* _log_debug_encode;
1538 wxCheckBox* _log_debug_email;
1539 #ifdef DCPOMATIC_WINDOWS
1540 wxCheckBox* _win32_console;
1544 wxPreferencesEditor*
1545 create_full_config_dialog ()
1547 wxPreferencesEditor* e = new wxPreferencesEditor ();
1549 #ifdef DCPOMATIC_OSX
1550 /* Width that we force some of the config panels to be on OSX so that
1551 the containing window doesn't shrink too much when we select those panels.
1552 This is obviously an unpleasant hack.
1554 wxSize ps = wxSize (600, -1);
1555 int const border = 16;
1557 wxSize ps = wxSize (-1, -1);
1558 int const border = 8;
1561 e->AddPage (new FullGeneralPage (ps, border));
1562 e->AddPage (new DefaultsPage (ps, border));
1563 e->AddPage (new EncodingServersPage (ps, border));
1564 e->AddPage (new KeysPage (ps, border));
1565 e->AddPage (new TMSPage (ps, border));
1566 e->AddPage (new EmailPage (ps, border));
1567 e->AddPage (new KDMEmailPage (ps, border));
1568 e->AddPage (new AccountsPage (ps, border));
1569 e->AddPage (new NotificationsPage (ps, border));
1570 e->AddPage (new CoverSheetPage (ps, border));
1571 e->AddPage (new AdvancedPage (ps, border));