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, _("User name"), true);
773 _user = new wxTextCtrl (_panel, wxID_ANY);
774 table->Add (_user, 1, wxEXPAND | wxALL);
776 add_label_to_sizer (table, _panel, _("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 user name"), 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 user name"), 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 add_label_to_sizer (table, _panel, _("GDC user name"), true);
985 _gdc_username = new wxTextCtrl (_panel, wxID_ANY);
986 table->Add (_gdc_username, 1, wxEXPAND | wxALL);
988 add_label_to_sizer (table, _panel, _("GDC password"), true);
989 _gdc_password = new wxTextCtrl (_panel, wxID_ANY);
990 table->Add (_gdc_password, 1, wxEXPAND | wxALL);
992 _barco_username->Bind (wxEVT_TEXT, boost::bind(&AccountsPage::barco_username_changed, this));
993 _barco_password->Bind (wxEVT_TEXT, boost::bind(&AccountsPage::barco_password_changed, this));
994 _christie_username->Bind (wxEVT_TEXT, boost::bind(&AccountsPage::christie_username_changed, this));
995 _christie_password->Bind (wxEVT_TEXT, boost::bind(&AccountsPage::christie_password_changed, this));
996 _gdc_username->Bind (wxEVT_TEXT, boost::bind(&AccountsPage::gdc_username_changed, this));
997 _gdc_password->Bind (wxEVT_TEXT, boost::bind(&AccountsPage::gdc_password_changed, this));
1000 void config_changed ()
1002 Config* config = Config::instance ();
1004 checked_set (_barco_username, config->barco_username().get_value_or(""));
1005 checked_set (_barco_password, config->barco_password().get_value_or(""));
1006 checked_set (_christie_username, config->christie_username().get_value_or(""));
1007 checked_set (_christie_password, config->christie_password().get_value_or(""));
1008 checked_set (_gdc_username, config->gdc_username().get_value_or(""));
1009 checked_set (_gdc_password, config->gdc_password().get_value_or(""));
1012 void barco_username_changed ()
1014 wxString const s = _barco_username->GetValue();
1016 Config::instance()->set_barco_username (wx_to_std(s));
1018 Config::instance()->unset_barco_username ();
1022 void barco_password_changed ()
1024 wxString const s = _barco_password->GetValue();
1026 Config::instance()->set_barco_password (wx_to_std(s));
1028 Config::instance()->unset_barco_password ();
1032 void christie_username_changed ()
1034 wxString const s = _christie_username->GetValue();
1036 Config::instance()->set_christie_username (wx_to_std(s));
1038 Config::instance()->unset_christie_username ();
1042 void christie_password_changed ()
1044 wxString const s = _christie_password->GetValue();
1046 Config::instance()->set_christie_password (wx_to_std(s));
1048 Config::instance()->unset_christie_password ();
1052 void gdc_username_changed ()
1054 wxString const s = _gdc_username->GetValue();
1056 Config::instance()->set_gdc_username (wx_to_std(s));
1058 Config::instance()->unset_gdc_username ();
1062 void gdc_password_changed ()
1064 wxString const s = _gdc_password->GetValue();
1066 Config::instance()->set_gdc_password (wx_to_std(s));
1068 Config::instance()->unset_gdc_password ();
1073 wxTextCtrl* _barco_username;
1074 wxTextCtrl* _barco_password;
1075 wxTextCtrl* _christie_username;
1076 wxTextCtrl* _christie_password;
1077 wxTextCtrl* _gdc_username;
1078 wxTextCtrl* _gdc_password;
1082 class NotificationsPage : public StandardPage
1085 NotificationsPage (wxSize panel_size, int border)
1086 #ifdef DCPOMATIC_OSX
1087 /* We have to force both width and height of this one */
1088 : StandardPage (wxSize (panel_size.GetWidth(), 128), border)
1090 : StandardPage (panel_size, border)
1094 wxString GetName () const
1096 return _("Notifications");
1099 #ifdef DCPOMATIC_OSX
1100 wxBitmap GetLargeIcon () const
1102 return wxBitmap ("notifications", wxBITMAP_TYPE_PNG_RESOURCE);
1109 wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
1110 table->AddGrowableCol (1, 1);
1111 _panel->GetSizer()->Add (table, 1, wxEXPAND | wxALL, _border);
1113 _enable_message_box = new CheckBox (_panel, _("Message box"));
1114 table->Add (_enable_message_box, 1, wxEXPAND | wxALL);
1115 table->AddSpacer (0);
1117 _enable_email = new CheckBox (_panel, _("Email"));
1118 table->Add (_enable_email, 1, wxEXPAND | wxALL);
1119 table->AddSpacer (0);
1121 add_label_to_sizer (table, _panel, _("Subject"), true);
1122 _subject = new wxTextCtrl (_panel, wxID_ANY);
1123 table->Add (_subject, 1, wxEXPAND | wxALL);
1125 add_label_to_sizer (table, _panel, _("From address"), true);
1126 _from = new wxTextCtrl (_panel, wxID_ANY);
1127 table->Add (_from, 1, wxEXPAND | wxALL);
1129 add_label_to_sizer (table, _panel, _("To address"), true);
1130 _to = new wxTextCtrl (_panel, wxID_ANY);
1131 table->Add (_to, 1, wxEXPAND | wxALL);
1133 vector<string> columns;
1134 columns.push_back (wx_to_std (_("Address")));
1135 add_label_to_sizer (table, _panel, _("CC addresses"), true);
1136 _cc = new EditableList<string, EmailDialog> (
1139 bind (&Config::notification_cc, Config::instance()),
1140 bind (&Config::set_notification_cc, Config::instance(), _1),
1143 table->Add (_cc, 1, wxEXPAND | wxALL);
1145 add_label_to_sizer (table, _panel, _("BCC address"), true);
1146 _bcc = new wxTextCtrl (_panel, wxID_ANY);
1147 table->Add (_bcc, 1, wxEXPAND | wxALL);
1149 _email = new wxTextCtrl (_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize (-1, 200), wxTE_MULTILINE);
1150 _panel->GetSizer()->Add (_email, 0, wxEXPAND | wxALL, _border);
1152 _reset_email = new Button (_panel, _("Reset to default subject and text"));
1153 _panel->GetSizer()->Add (_reset_email, 0, wxEXPAND | wxALL, _border);
1157 _enable_message_box->Bind (wxEVT_CHECKBOX, boost::bind (&NotificationsPage::type_changed, this, _enable_message_box, Config::MESSAGE_BOX));
1158 _enable_email->Bind (wxEVT_CHECKBOX, boost::bind (&NotificationsPage::type_changed, this, _enable_email, Config::EMAIL));
1160 _subject->Bind (wxEVT_TEXT, boost::bind (&NotificationsPage::notification_subject_changed, this));
1161 _from->Bind (wxEVT_TEXT, boost::bind (&NotificationsPage::notification_from_changed, this));
1162 _to->Bind (wxEVT_TEXT, boost::bind (&NotificationsPage::notification_to_changed, this));
1163 _bcc->Bind (wxEVT_TEXT, boost::bind (&NotificationsPage::notification_bcc_changed, this));
1164 _email->Bind (wxEVT_TEXT, boost::bind (&NotificationsPage::notification_email_changed, this));
1165 _reset_email->Bind (wxEVT_BUTTON, boost::bind (&NotificationsPage::reset_email, this));
1167 update_sensitivity ();
1170 void update_sensitivity ()
1172 bool const s = _enable_email->GetValue();
1173 _subject->Enable(s);
1179 _reset_email->Enable(s);
1182 void config_changed ()
1184 Config* config = Config::instance ();
1186 checked_set (_enable_message_box, config->notification(Config::MESSAGE_BOX));
1187 checked_set (_enable_email, config->notification(Config::EMAIL));
1188 checked_set (_subject, config->notification_subject ());
1189 checked_set (_from, config->notification_from ());
1190 checked_set (_to, config->notification_to ());
1191 checked_set (_bcc, config->notification_bcc ());
1192 checked_set (_email, Config::instance()->notification_email ());
1194 update_sensitivity ();
1197 void notification_subject_changed ()
1199 Config::instance()->set_notification_subject (wx_to_std (_subject->GetValue ()));
1202 void notification_from_changed ()
1204 Config::instance()->set_notification_from (wx_to_std (_from->GetValue ()));
1207 void notification_to_changed ()
1209 Config::instance()->set_notification_to (wx_to_std (_to->GetValue ()));
1212 void notification_bcc_changed ()
1214 Config::instance()->set_notification_bcc (wx_to_std (_bcc->GetValue ()));
1217 void notification_email_changed ()
1219 if (_email->GetValue().IsEmpty ()) {
1220 /* Sometimes we get sent an erroneous notification that the email
1221 is empty; I don't know why.
1225 Config::instance()->set_notification_email (wx_to_std (_email->GetValue ()));
1230 Config::instance()->reset_notification_email ();
1231 checked_set (_email, Config::instance()->notification_email ());
1234 void type_changed (wxCheckBox* b, Config::Notification n)
1236 Config::instance()->set_notification(n, b->GetValue());
1237 update_sensitivity ();
1240 wxCheckBox* _enable_message_box;
1241 wxCheckBox* _enable_email;
1243 wxTextCtrl* _subject;
1246 EditableList<string, EmailDialog>* _cc;
1249 wxButton* _reset_email;
1252 class CoverSheetPage : public StandardPage
1256 CoverSheetPage (wxSize panel_size, int border)
1257 #ifdef DCPOMATIC_OSX
1258 /* We have to force both width and height of this one */
1259 : StandardPage (wxSize (panel_size.GetWidth(), 128), border)
1261 : StandardPage (panel_size, border)
1265 wxString GetName () const
1267 return _("Cover Sheet");
1270 #ifdef DCPOMATIC_OSX
1271 wxBitmap GetLargeIcon () const
1273 return wxBitmap ("cover_sheet", wxBITMAP_TYPE_PNG_RESOURCE);
1280 _cover_sheet = new wxTextCtrl (_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize (-1, 200), wxTE_MULTILINE);
1281 _panel->GetSizer()->Add (_cover_sheet, 0, wxEXPAND | wxALL, _border);
1283 _reset_cover_sheet = new Button (_panel, _("Reset to default text"));
1284 _panel->GetSizer()->Add (_reset_cover_sheet, 0, wxEXPAND | wxALL, _border);
1286 _cover_sheet->Bind (wxEVT_TEXT, boost::bind (&CoverSheetPage::cover_sheet_changed, this));
1287 _reset_cover_sheet->Bind (wxEVT_BUTTON, boost::bind (&CoverSheetPage::reset_cover_sheet, this));
1290 void config_changed ()
1292 checked_set (_cover_sheet, Config::instance()->cover_sheet ());
1295 void cover_sheet_changed ()
1297 if (_cover_sheet->GetValue().IsEmpty ()) {
1298 /* Sometimes we get sent an erroneous notification that the cover sheet
1299 is empty; I don't know why.
1303 Config::instance()->set_cover_sheet (wx_to_std (_cover_sheet->GetValue ()));
1306 void reset_cover_sheet ()
1308 Config::instance()->reset_cover_sheet ();
1309 checked_set (_cover_sheet, Config::instance()->cover_sheet ());
1312 wxTextCtrl* _cover_sheet;
1313 wxButton* _reset_cover_sheet;
1317 /** @class AdvancedPage
1318 * @brief Advanced page of the preferences dialog.
1320 class AdvancedPage : public StockPage
1323 AdvancedPage (wxSize panel_size, int border)
1324 : StockPage (Kind_Advanced, panel_size, border)
1325 , _maximum_j2k_bandwidth (0)
1326 , _allow_any_dcp_frame_rate (0)
1327 , _allow_any_container (0)
1328 , _only_servers_encode (0)
1333 , _log_debug_decode (0)
1334 , _log_debug_encode (0)
1335 , _log_debug_email (0)
1339 void add_top_aligned_label_to_sizer (wxSizer* table, wxWindow* parent, wxString text)
1341 int flags = wxALIGN_TOP | wxTOP | wxLEFT;
1343 flags |= wxALIGN_RIGHT;
1346 wxStaticText* m = new StaticText (parent, text);
1347 table->Add (m, 0, flags, DCPOMATIC_SIZER_Y_GAP);
1352 wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
1353 table->AddGrowableCol (1, 1);
1354 _panel->GetSizer()->Add (table, 1, wxALL | wxEXPAND, _border);
1357 add_label_to_sizer (table, _panel, _("Maximum JPEG2000 bandwidth"), true);
1358 wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL);
1359 _maximum_j2k_bandwidth = new wxSpinCtrl (_panel);
1360 s->Add (_maximum_j2k_bandwidth, 1);
1361 add_label_to_sizer (s, _panel, _("Mbit/s"), false);
1365 _allow_any_dcp_frame_rate = new CheckBox (_panel, _("Allow any DCP frame rate"));
1366 table->Add (_allow_any_dcp_frame_rate, 1, wxEXPAND | wxALL);
1367 table->AddSpacer (0);
1369 _allow_any_container = new CheckBox (_panel, _("Allow non-standard container ratios"));
1370 table->Add (_allow_any_container, 1, wxEXPAND | wxALL);
1371 table->AddSpacer (0);
1373 wxStaticText* restart = add_label_to_sizer (table, _panel, _("(restart DCP-o-matic to see all ratios)"), false);
1374 wxFont font = restart->GetFont();
1375 font.SetStyle (wxFONTSTYLE_ITALIC);
1376 font.SetPointSize (font.GetPointSize() - 1);
1377 restart->SetFont (font);
1378 table->AddSpacer (0);
1380 _only_servers_encode = new CheckBox (_panel, _("Only servers encode"));
1381 table->Add (_only_servers_encode, 1, wxEXPAND | wxALL);
1382 table->AddSpacer (0);
1385 add_label_to_sizer (table, _panel, _("Maximum number of frames to store per thread"), true);
1386 wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL);
1387 _frames_in_memory_multiplier = new wxSpinCtrl (_panel);
1388 s->Add (_frames_in_memory_multiplier, 1);
1393 add_top_aligned_label_to_sizer (table, _panel, _("DCP metadata filename format"));
1394 dcp::NameFormat::Map titles;
1395 titles['t'] = "type (cpl/pkl)";
1396 dcp::NameFormat::Map examples;
1397 examples['t'] = "cpl";
1398 _dcp_metadata_filename_format = new NameFormatEditor (
1399 _panel, Config::instance()->dcp_metadata_filename_format(), titles, examples, "_eb1c112c-ca3c-4ae6-9263-c6714ff05d64.xml"
1401 table->Add (_dcp_metadata_filename_format->panel(), 1, wxEXPAND | wxALL);
1405 add_top_aligned_label_to_sizer (table, _panel, _("DCP asset filename format"));
1406 dcp::NameFormat::Map titles;
1407 titles['t'] = "type (j2c/pcm/sub)";
1408 titles['r'] = "reel number";
1409 titles['n'] = "number of reels";
1410 titles['c'] = "content filename";
1411 dcp::NameFormat::Map examples;
1412 examples['t'] = "j2c";
1413 examples['r'] = "1";
1414 examples['n'] = "4";
1415 examples['c'] = "myfile.mp4";
1416 _dcp_asset_filename_format = new NameFormatEditor (
1417 _panel, Config::instance()->dcp_asset_filename_format(), titles, examples, "_eb1c112c-ca3c-4ae6-9263-c6714ff05d64.mxf"
1419 table->Add (_dcp_asset_filename_format->panel(), 1, wxEXPAND | wxALL);
1423 add_top_aligned_label_to_sizer (table, _panel, _("Log"));
1424 wxBoxSizer* t = new wxBoxSizer (wxVERTICAL);
1425 _log_general = new CheckBox (_panel, _("General"));
1426 t->Add (_log_general, 1, wxEXPAND | wxALL);
1427 _log_warning = new CheckBox (_panel, _("Warnings"));
1428 t->Add (_log_warning, 1, wxEXPAND | wxALL);
1429 _log_error = new CheckBox (_panel, _("Errors"));
1430 t->Add (_log_error, 1, wxEXPAND | wxALL);
1431 /// TRANSLATORS: translate the word "Timing" here; do not include the "Config|" prefix
1432 _log_timing = new CheckBox (_panel, S_("Config|Timing"));
1433 t->Add (_log_timing, 1, wxEXPAND | wxALL);
1434 _log_debug_decode = new CheckBox (_panel, _("Debug: decode"));
1435 t->Add (_log_debug_decode, 1, wxEXPAND | wxALL);
1436 _log_debug_encode = new CheckBox (_panel, _("Debug: encode"));
1437 t->Add (_log_debug_encode, 1, wxEXPAND | wxALL);
1438 _log_debug_email = new CheckBox (_panel, _("Debug: email sending"));
1439 t->Add (_log_debug_email, 1, wxEXPAND | wxALL);
1440 table->Add (t, 0, wxALL, 6);
1443 #ifdef DCPOMATIC_WINDOWS
1444 _win32_console = new CheckBox (_panel, _("Open console window"));
1445 table->Add (_win32_console, 1, wxEXPAND | wxALL);
1446 table->AddSpacer (0);
1449 _maximum_j2k_bandwidth->SetRange (1, 1000);
1450 _maximum_j2k_bandwidth->Bind (wxEVT_SPINCTRL, boost::bind (&AdvancedPage::maximum_j2k_bandwidth_changed, this));
1451 _allow_any_dcp_frame_rate->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::allow_any_dcp_frame_rate_changed, this));
1452 _allow_any_container->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::allow_any_container_changed, this));
1453 _only_servers_encode->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::only_servers_encode_changed, this));
1454 _frames_in_memory_multiplier->Bind (wxEVT_SPINCTRL, boost::bind(&AdvancedPage::frames_in_memory_multiplier_changed, this));
1455 _dcp_metadata_filename_format->Changed.connect (boost::bind (&AdvancedPage::dcp_metadata_filename_format_changed, this));
1456 _dcp_asset_filename_format->Changed.connect (boost::bind (&AdvancedPage::dcp_asset_filename_format_changed, this));
1457 _log_general->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::log_changed, this));
1458 _log_warning->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::log_changed, this));
1459 _log_error->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::log_changed, this));
1460 _log_timing->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::log_changed, this));
1461 _log_debug_decode->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::log_changed, this));
1462 _log_debug_encode->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::log_changed, this));
1463 _log_debug_email->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::log_changed, this));
1464 #ifdef DCPOMATIC_WINDOWS
1465 _win32_console->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::win32_console_changed, this));
1469 void config_changed ()
1471 Config* config = Config::instance ();
1473 checked_set (_maximum_j2k_bandwidth, config->maximum_j2k_bandwidth() / 1000000);
1474 checked_set (_allow_any_dcp_frame_rate, config->allow_any_dcp_frame_rate ());
1475 checked_set (_allow_any_container, config->allow_any_container ());
1476 checked_set (_only_servers_encode, config->only_servers_encode ());
1477 checked_set (_log_general, config->log_types() & LogEntry::TYPE_GENERAL);
1478 checked_set (_log_warning, config->log_types() & LogEntry::TYPE_WARNING);
1479 checked_set (_log_error, config->log_types() & LogEntry::TYPE_ERROR);
1480 checked_set (_log_timing, config->log_types() & LogEntry::TYPE_TIMING);
1481 checked_set (_log_debug_decode, config->log_types() & LogEntry::TYPE_DEBUG_DECODE);
1482 checked_set (_log_debug_encode, config->log_types() & LogEntry::TYPE_DEBUG_ENCODE);
1483 checked_set (_log_debug_email, config->log_types() & LogEntry::TYPE_DEBUG_EMAIL);
1484 checked_set (_frames_in_memory_multiplier, config->frames_in_memory_multiplier());
1485 #ifdef DCPOMATIC_WINDOWS
1486 checked_set (_win32_console, config->win32_console());
1490 void maximum_j2k_bandwidth_changed ()
1492 Config::instance()->set_maximum_j2k_bandwidth (_maximum_j2k_bandwidth->GetValue() * 1000000);
1495 void frames_in_memory_multiplier_changed ()
1497 Config::instance()->set_frames_in_memory_multiplier (_frames_in_memory_multiplier->GetValue());
1500 void allow_any_dcp_frame_rate_changed ()
1502 Config::instance()->set_allow_any_dcp_frame_rate (_allow_any_dcp_frame_rate->GetValue ());
1505 void allow_any_container_changed ()
1507 Config::instance()->set_allow_any_container (_allow_any_container->GetValue ());
1510 void only_servers_encode_changed ()
1512 Config::instance()->set_only_servers_encode (_only_servers_encode->GetValue ());
1515 void dcp_metadata_filename_format_changed ()
1517 Config::instance()->set_dcp_metadata_filename_format (_dcp_metadata_filename_format->get ());
1520 void dcp_asset_filename_format_changed ()
1522 Config::instance()->set_dcp_asset_filename_format (_dcp_asset_filename_format->get ());
1528 if (_log_general->GetValue ()) {
1529 types |= LogEntry::TYPE_GENERAL;
1531 if (_log_warning->GetValue ()) {
1532 types |= LogEntry::TYPE_WARNING;
1534 if (_log_error->GetValue ()) {
1535 types |= LogEntry::TYPE_ERROR;
1537 if (_log_timing->GetValue ()) {
1538 types |= LogEntry::TYPE_TIMING;
1540 if (_log_debug_decode->GetValue ()) {
1541 types |= LogEntry::TYPE_DEBUG_DECODE;
1543 if (_log_debug_encode->GetValue ()) {
1544 types |= LogEntry::TYPE_DEBUG_ENCODE;
1546 if (_log_debug_email->GetValue ()) {
1547 types |= LogEntry::TYPE_DEBUG_EMAIL;
1549 Config::instance()->set_log_types (types);
1552 #ifdef DCPOMATIC_WINDOWS
1553 void win32_console_changed ()
1555 Config::instance()->set_win32_console (_win32_console->GetValue ());
1559 wxSpinCtrl* _maximum_j2k_bandwidth;
1560 wxSpinCtrl* _frames_in_memory_multiplier;
1561 wxCheckBox* _allow_any_dcp_frame_rate;
1562 wxCheckBox* _allow_any_container;
1563 wxCheckBox* _only_servers_encode;
1564 NameFormatEditor* _dcp_metadata_filename_format;
1565 NameFormatEditor* _dcp_asset_filename_format;
1566 wxCheckBox* _log_general;
1567 wxCheckBox* _log_warning;
1568 wxCheckBox* _log_error;
1569 wxCheckBox* _log_timing;
1570 wxCheckBox* _log_debug_decode;
1571 wxCheckBox* _log_debug_encode;
1572 wxCheckBox* _log_debug_email;
1573 #ifdef DCPOMATIC_WINDOWS
1574 wxCheckBox* _win32_console;
1578 wxPreferencesEditor*
1579 create_full_config_dialog ()
1581 wxPreferencesEditor* e = new wxPreferencesEditor ();
1583 #ifdef DCPOMATIC_OSX
1584 /* Width that we force some of the config panels to be on OSX so that
1585 the containing window doesn't shrink too much when we select those panels.
1586 This is obviously an unpleasant hack.
1588 wxSize ps = wxSize (600, -1);
1589 int const border = 16;
1591 wxSize ps = wxSize (-1, -1);
1592 int const border = 8;
1595 e->AddPage (new FullGeneralPage (ps, border));
1596 e->AddPage (new DefaultsPage (ps, border));
1597 e->AddPage (new EncodingServersPage (ps, border));
1598 e->AddPage (new KeysPage (ps, border));
1599 e->AddPage (new TMSPage (ps, border));
1600 e->AddPage (new EmailPage (ps, border));
1601 e->AddPage (new KDMEmailPage (ps, border));
1602 e->AddPage (new AccountsPage (ps, border));
1603 e->AddPage (new NotificationsPage (ps, border));
1604 e->AddPage (new CoverSheetPage (ps, border));
1605 e->AddPage (new AdvancedPage (ps, border));