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 #if BOOST_VERSION >= 106100
74 using namespace boost::placeholders;
76 using dcp::locale_convert;
78 class FullGeneralPage : public GeneralPage
81 FullGeneralPage (wxSize panel_size, int border)
82 : GeneralPage (panel_size, border)
88 wxGridBagSizer* table = new wxGridBagSizer (DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
89 _panel->GetSizer()->Add (table, 1, wxALL | wxEXPAND, _border);
92 add_language_controls (table, r);
94 add_label_to_sizer (table, _panel, _("Interface complexity"), true, wxGBPosition(r, 0));
95 _interface_complexity = new wxChoice (_panel, wxID_ANY);
96 table->Add (_interface_complexity, wxGBPosition (r, 1));
99 add_label_to_sizer (table, _panel, _("Number of threads DCP-o-matic should use"), true, wxGBPosition (r, 0));
100 _master_encoding_threads = new wxSpinCtrl (_panel);
101 table->Add (_master_encoding_threads, wxGBPosition (r, 1));
104 add_label_to_sizer (table, _panel, _("Number of threads DCP-o-matic encode server should use"), true, wxGBPosition (r, 0));
105 _server_encoding_threads = new wxSpinCtrl (_panel);
106 table->Add (_server_encoding_threads, wxGBPosition (r, 1));
109 add_label_to_sizer (table, _panel, _("Configuration file"), true, wxGBPosition (r, 0));
110 _config_file = new FilePickerCtrl (_panel, _("Select configuration file"), "*.xml", true);
111 table->Add (_config_file, wxGBPosition (r, 1));
114 add_label_to_sizer (table, _panel, _("Cinema and screen database file"), true, wxGBPosition (r, 0));
115 _cinemas_file = new FilePickerCtrl (_panel, _("Select cinema and screen database file"), "*.xml", true);
116 table->Add (_cinemas_file, wxGBPosition (r, 1));
117 Button* export_cinemas = new Button (_panel, _("Export..."));
118 table->Add (export_cinemas, wxGBPosition (r, 2));
121 add_play_sound_controls (table, r);
123 #ifdef DCPOMATIC_HAVE_EBUR128_PATCHED_FFMPEG
124 _analyse_ebur128 = new CheckBox (_panel, _("Find integrated loudness, true peak and loudness range when analysing audio"));
125 table->Add (_analyse_ebur128, wxGBPosition (r, 0), wxGBSpan (1, 2));
129 _automatic_audio_analysis = new CheckBox (_panel, _("Automatically analyse content audio"));
130 table->Add (_automatic_audio_analysis, wxGBPosition (r, 0), wxGBSpan (1, 2));
133 add_update_controls (table, r);
135 wxFlexGridSizer* bottom_table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
136 bottom_table->AddGrowableCol (1, 1);
138 add_label_to_sizer (bottom_table, _panel, _("Issuer"), true);
139 _issuer = new wxTextCtrl (_panel, wxID_ANY);
140 bottom_table->Add (_issuer, 1, wxALL | wxEXPAND);
142 add_label_to_sizer (bottom_table, _panel, _("Creator"), true);
143 _creator = new wxTextCtrl (_panel, wxID_ANY);
144 bottom_table->Add (_creator, 1, wxALL | wxEXPAND);
146 table->Add (bottom_table, wxGBPosition (r, 0), wxGBSpan (2, 2), wxEXPAND);
149 _config_file->Bind (wxEVT_FILEPICKER_CHANGED, boost::bind (&FullGeneralPage::config_file_changed, this));
150 _cinemas_file->Bind (wxEVT_FILEPICKER_CHANGED, boost::bind (&FullGeneralPage::cinemas_file_changed, this));
152 _interface_complexity->Append (_("Simple"));
153 _interface_complexity->Append (_("Full"));
154 _interface_complexity->Bind (wxEVT_CHOICE, boost::bind(&FullGeneralPage::interface_complexity_changed, this));
156 _master_encoding_threads->SetRange (1, 128);
157 _master_encoding_threads->Bind (wxEVT_SPINCTRL, boost::bind (&FullGeneralPage::master_encoding_threads_changed, this));
158 _server_encoding_threads->SetRange (1, 128);
159 _server_encoding_threads->Bind (wxEVT_SPINCTRL, boost::bind (&FullGeneralPage::server_encoding_threads_changed, this));
160 export_cinemas->Bind (wxEVT_BUTTON, boost::bind (&FullGeneralPage::export_cinemas_file, this));
162 #ifdef DCPOMATIC_HAVE_EBUR128_PATCHED_FFMPEG
163 _analyse_ebur128->Bind (wxEVT_CHECKBOX, boost::bind (&FullGeneralPage::analyse_ebur128_changed, this));
165 _automatic_audio_analysis->Bind (wxEVT_CHECKBOX, boost::bind (&FullGeneralPage::automatic_audio_analysis_changed, this));
167 _issuer->Bind (wxEVT_TEXT, boost::bind (&FullGeneralPage::issuer_changed, this));
168 _creator->Bind (wxEVT_TEXT, boost::bind (&FullGeneralPage::creator_changed, this));
171 void config_changed ()
173 Config* config = Config::instance ();
175 switch (config->interface_complexity()) {
176 case Config::INTERFACE_SIMPLE:
177 checked_set (_interface_complexity, 0);
179 case Config::INTERFACE_FULL:
180 checked_set (_interface_complexity, 1);
183 checked_set (_master_encoding_threads, config->master_encoding_threads ());
184 checked_set (_server_encoding_threads, config->server_encoding_threads ());
185 #ifdef DCPOMATIC_HAVE_EBUR128_PATCHED_FFMPEG
186 checked_set (_analyse_ebur128, config->analyse_ebur128 ());
188 checked_set (_automatic_audio_analysis, config->automatic_audio_analysis ());
189 checked_set (_issuer, config->dcp_issuer ());
190 checked_set (_creator, config->dcp_creator ());
191 checked_set (_config_file, config->config_file());
192 checked_set (_cinemas_file, config->cinemas_file());
194 GeneralPage::config_changed ();
197 void export_cinemas_file ()
199 wxFileDialog* d = new wxFileDialog (
200 _panel, _("Select Cinemas File"), wxEmptyString, wxEmptyString, wxT ("XML files (*.xml)|*.xml"),
201 wxFD_SAVE | wxFD_OVERWRITE_PROMPT
204 if (d->ShowModal () == wxID_OK) {
205 boost::filesystem::copy_file (Config::instance()->cinemas_file(), wx_to_std(d->GetPath()));
210 void interface_complexity_changed ()
212 if (_interface_complexity->GetSelection() == 0) {
213 Config::instance()->set_interface_complexity (Config::INTERFACE_SIMPLE);
215 Config::instance()->set_interface_complexity (Config::INTERFACE_FULL);
220 #ifdef DCPOMATIC_HAVE_EBUR128_PATCHED_FFMPEG
221 void analyse_ebur128_changed ()
223 Config::instance()->set_analyse_ebur128 (_analyse_ebur128->GetValue ());
227 void automatic_audio_analysis_changed ()
229 Config::instance()->set_automatic_audio_analysis (_automatic_audio_analysis->GetValue ());
232 void master_encoding_threads_changed ()
234 Config::instance()->set_master_encoding_threads (_master_encoding_threads->GetValue ());
237 void server_encoding_threads_changed ()
239 Config::instance()->set_server_encoding_threads (_server_encoding_threads->GetValue ());
242 void issuer_changed ()
244 Config::instance()->set_dcp_issuer (wx_to_std (_issuer->GetValue ()));
247 void creator_changed ()
249 Config::instance()->set_dcp_creator (wx_to_std (_creator->GetValue ()));
252 void config_file_changed ()
254 Config* config = Config::instance();
255 boost::filesystem::path new_file = wx_to_std(_config_file->GetPath());
256 if (new_file == config->config_file()) {
259 bool copy_and_link = true;
260 if (boost::filesystem::exists(new_file)) {
261 ConfigMoveDialog* d = new ConfigMoveDialog (_panel, new_file);
262 if (d->ShowModal() == wxID_OK) {
263 copy_and_link = false;
270 if (new_file != config->config_file()) {
271 config->copy_and_link (new_file);
274 config->link (new_file);
278 void cinemas_file_changed ()
280 Config::instance()->set_cinemas_file (wx_to_std (_cinemas_file->GetPath ()));
283 wxChoice* _interface_complexity;
284 wxSpinCtrl* _master_encoding_threads;
285 wxSpinCtrl* _server_encoding_threads;
286 FilePickerCtrl* _config_file;
287 FilePickerCtrl* _cinemas_file;
288 #ifdef DCPOMATIC_HAVE_EBUR128_PATCHED_FFMPEG
289 wxCheckBox* _analyse_ebur128;
291 wxCheckBox* _automatic_audio_analysis;
293 wxTextCtrl* _creator;
296 class DefaultsPage : public StandardPage
299 DefaultsPage (wxSize panel_size, int border)
300 : StandardPage (panel_size, border)
303 wxString GetName () const
305 return _("Defaults");
309 wxBitmap GetLargeIcon () const
311 return wxBitmap ("defaults", wxBITMAP_TYPE_PNG_RESOURCE);
318 wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
319 table->AddGrowableCol (1, 1);
320 _panel->GetSizer()->Add (table, 1, wxALL | wxEXPAND, _border);
323 add_label_to_sizer (table, _panel, _("Default duration of still images"), true);
324 wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL);
325 _still_length = new wxSpinCtrl (_panel);
326 s->Add (_still_length);
327 add_label_to_sizer (s, _panel, _("s"), false);
331 add_label_to_sizer (table, _panel, _("Default directory for new films"), true);
332 #ifdef DCPOMATIC_USE_OWN_PICKER
333 _directory = new DirPickerCtrl (_panel);
335 _directory = new wxDirPickerCtrl (_panel, wxDD_DIR_MUST_EXIST);
337 table->Add (_directory, 1, wxEXPAND);
339 add_label_to_sizer (table, _panel, _("Default ISDCF name details"), true);
340 _isdcf_metadata_button = new Button (_panel, _("Edit..."));
341 table->Add (_isdcf_metadata_button);
343 add_label_to_sizer (table, _panel, _("Default container"), true);
344 _container = new wxChoice (_panel, wxID_ANY);
345 table->Add (_container);
347 add_label_to_sizer (table, _panel, _("Default scale-to"), true);
348 _scale_to = new wxChoice (_panel, wxID_ANY);
349 table->Add (_scale_to);
351 add_label_to_sizer (table, _panel, _("Default content type"), true);
352 _dcp_content_type = new wxChoice (_panel, wxID_ANY);
353 table->Add (_dcp_content_type);
355 add_label_to_sizer (table, _panel, _("Default DCP audio channels"), true);
356 _dcp_audio_channels = new wxChoice (_panel, wxID_ANY);
357 table->Add (_dcp_audio_channels);
360 add_label_to_sizer (table, _panel, _("Default JPEG2000 bandwidth"), true);
361 wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL);
362 _j2k_bandwidth = new wxSpinCtrl (_panel);
363 s->Add (_j2k_bandwidth);
364 add_label_to_sizer (s, _panel, _("Mbit/s"), false);
369 add_label_to_sizer (table, _panel, _("Default audio delay"), true);
370 wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL);
371 _audio_delay = new wxSpinCtrl (_panel);
372 s->Add (_audio_delay);
373 add_label_to_sizer (s, _panel, _("ms"), false);
377 add_label_to_sizer (table, _panel, _("Default standard"), true);
378 _standard = new wxChoice (_panel, wxID_ANY);
379 table->Add (_standard);
381 add_label_to_sizer (table, _panel, _("Default KDM directory"), true);
382 #ifdef DCPOMATIC_USE_OWN_PICKER
383 _kdm_directory = new DirPickerCtrl (_panel);
385 _kdm_directory = new wxDirPickerCtrl (_panel, wxDD_DIR_MUST_EXIST);
388 table->Add (_kdm_directory, 1, wxEXPAND);
390 _upload_after_make_dcp = new CheckBox (_panel, _("Default to enabling upload of DCP to TMS"));
391 table->Add (_upload_after_make_dcp, 1, wxEXPAND);
393 _still_length->SetRange (1, 3600);
394 _still_length->Bind (wxEVT_SPINCTRL, boost::bind (&DefaultsPage::still_length_changed, this));
396 _directory->Bind (wxEVT_DIRPICKER_CHANGED, boost::bind (&DefaultsPage::directory_changed, this));
397 _kdm_directory->Bind (wxEVT_DIRPICKER_CHANGED, boost::bind (&DefaultsPage::kdm_directory_changed, this));
399 _isdcf_metadata_button->Bind (wxEVT_BUTTON, boost::bind (&DefaultsPage::edit_isdcf_metadata_clicked, this));
401 BOOST_FOREACH (Ratio const * i, Ratio::containers()) {
402 _container->Append (std_to_wx(i->container_nickname()));
405 _container->Bind (wxEVT_CHOICE, boost::bind (&DefaultsPage::container_changed, this));
407 _scale_to->Append (_("Guess from content"));
409 BOOST_FOREACH (Ratio const * i, Ratio::all()) {
410 _scale_to->Append (std_to_wx(i->image_nickname()));
413 _scale_to->Bind (wxEVT_CHOICE, boost::bind (&DefaultsPage::scale_to_changed, this));
415 BOOST_FOREACH (DCPContentType const * i, DCPContentType::all()) {
416 _dcp_content_type->Append (std_to_wx (i->pretty_name ()));
419 setup_audio_channels_choice (_dcp_audio_channels, 2);
421 _dcp_content_type->Bind (wxEVT_CHOICE, boost::bind (&DefaultsPage::dcp_content_type_changed, this));
422 _dcp_audio_channels->Bind (wxEVT_CHOICE, boost::bind (&DefaultsPage::dcp_audio_channels_changed, this));
424 _j2k_bandwidth->SetRange (50, 250);
425 _j2k_bandwidth->Bind (wxEVT_SPINCTRL, boost::bind (&DefaultsPage::j2k_bandwidth_changed, this));
427 _audio_delay->SetRange (-1000, 1000);
428 _audio_delay->Bind (wxEVT_SPINCTRL, boost::bind (&DefaultsPage::audio_delay_changed, this));
430 _standard->Append (_("SMPTE"));
431 _standard->Append (_("Interop"));
432 _standard->Bind (wxEVT_CHOICE, boost::bind (&DefaultsPage::standard_changed, this));
434 _upload_after_make_dcp->Bind (wxEVT_CHECKBOX, boost::bind (&DefaultsPage::upload_after_make_dcp_changed, this));
437 void config_changed ()
439 Config* config = Config::instance ();
441 vector<Ratio const *> containers = Ratio::containers ();
442 for (size_t i = 0; i < containers.size(); ++i) {
443 if (containers[i] == config->default_container ()) {
444 _container->SetSelection (i);
448 vector<Ratio const *> ratios = Ratio::all ();
449 for (size_t i = 0; i < ratios.size(); ++i) {
450 if (ratios[i] == config->default_scale_to ()) {
451 _scale_to->SetSelection (i + 1);
455 if (!config->default_scale_to()) {
456 _scale_to->SetSelection (0);
459 vector<DCPContentType const *> const ct = DCPContentType::all ();
460 for (size_t i = 0; i < ct.size(); ++i) {
461 if (ct[i] == config->default_dcp_content_type ()) {
462 _dcp_content_type->SetSelection (i);
466 checked_set (_still_length, config->default_still_length ());
467 _directory->SetPath (std_to_wx (config->default_directory_or (wx_to_std (wxStandardPaths::Get().GetDocumentsDir())).string ()));
468 _kdm_directory->SetPath (std_to_wx (config->default_kdm_directory_or (wx_to_std (wxStandardPaths::Get().GetDocumentsDir())).string ()));
469 checked_set (_j2k_bandwidth, config->default_j2k_bandwidth() / 1000000);
470 _j2k_bandwidth->SetRange (50, config->maximum_j2k_bandwidth() / 1000000);
471 checked_set (_dcp_audio_channels, locale_convert<string> (config->default_dcp_audio_channels()));
472 checked_set (_audio_delay, config->default_audio_delay ());
473 checked_set (_standard, config->default_interop() ? 1 : 0);
474 checked_set (_upload_after_make_dcp, config->default_upload_after_make_dcp());
477 void j2k_bandwidth_changed ()
479 Config::instance()->set_default_j2k_bandwidth (_j2k_bandwidth->GetValue() * 1000000);
482 void audio_delay_changed ()
484 Config::instance()->set_default_audio_delay (_audio_delay->GetValue());
487 void dcp_audio_channels_changed ()
489 int const s = _dcp_audio_channels->GetSelection ();
490 if (s != wxNOT_FOUND) {
491 Config::instance()->set_default_dcp_audio_channels (
492 locale_convert<int> (string_client_data (_dcp_audio_channels->GetClientObject (s)))
497 void directory_changed ()
499 Config::instance()->set_default_directory (wx_to_std (_directory->GetPath ()));
502 void kdm_directory_changed ()
504 Config::instance()->set_default_kdm_directory (wx_to_std (_kdm_directory->GetPath ()));
507 void edit_isdcf_metadata_clicked ()
509 ISDCFMetadataDialog* d = new ISDCFMetadataDialog (_panel, Config::instance()->default_isdcf_metadata (), false);
511 Config::instance()->set_default_isdcf_metadata (d->isdcf_metadata ());
515 void still_length_changed ()
517 Config::instance()->set_default_still_length (_still_length->GetValue ());
520 void container_changed ()
522 vector<Ratio const *> ratio = Ratio::containers ();
523 Config::instance()->set_default_container (ratio[_container->GetSelection()]);
526 void scale_to_changed ()
528 int const s = _scale_to->GetSelection ();
530 Config::instance()->set_default_scale_to (0);
532 vector<Ratio const *> ratio = Ratio::all ();
533 Config::instance()->set_default_scale_to (ratio[s - 1]);
537 void dcp_content_type_changed ()
539 vector<DCPContentType const *> ct = DCPContentType::all ();
540 Config::instance()->set_default_dcp_content_type (ct[_dcp_content_type->GetSelection()]);
543 void standard_changed ()
545 Config::instance()->set_default_interop (_standard->GetSelection() == 1);
548 void upload_after_make_dcp_changed ()
550 Config::instance()->set_default_upload_after_make_dcp (_upload_after_make_dcp->GetValue ());
553 wxSpinCtrl* _j2k_bandwidth;
554 wxSpinCtrl* _audio_delay;
555 wxButton* _isdcf_metadata_button;
556 wxSpinCtrl* _still_length;
557 #ifdef DCPOMATIC_USE_OWN_PICKER
558 DirPickerCtrl* _directory;
559 DirPickerCtrl* _kdm_directory;
561 wxDirPickerCtrl* _directory;
562 wxDirPickerCtrl* _kdm_directory;
564 wxChoice* _container;
566 wxChoice* _dcp_content_type;
567 wxChoice* _dcp_audio_channels;
569 wxCheckBox* _upload_after_make_dcp;
572 class EncodingServersPage : public StandardPage
575 EncodingServersPage (wxSize panel_size, int border)
576 : StandardPage (panel_size, border)
579 wxString GetName () const
585 wxBitmap GetLargeIcon () const
587 return wxBitmap ("servers", wxBITMAP_TYPE_PNG_RESOURCE);
594 _use_any_servers = new CheckBox (_panel, _("Search network for servers"));
595 _panel->GetSizer()->Add (_use_any_servers, 0, wxALL, _border);
597 vector<string> columns;
598 columns.push_back (wx_to_std (_("IP address / host name")));
599 _servers_list = new EditableList<string, ServerDialog> (
602 boost::bind (&Config::servers, Config::instance()),
603 boost::bind (&Config::set_servers, Config::instance(), _1),
604 boost::bind (&EncodingServersPage::server_column, this, _1)
607 _panel->GetSizer()->Add (_servers_list, 1, wxEXPAND | wxALL, _border);
609 _use_any_servers->Bind (wxEVT_CHECKBOX, boost::bind (&EncodingServersPage::use_any_servers_changed, this));
612 void config_changed ()
614 checked_set (_use_any_servers, Config::instance()->use_any_servers ());
615 _servers_list->refresh ();
618 void use_any_servers_changed ()
620 Config::instance()->set_use_any_servers (_use_any_servers->GetValue ());
623 string server_column (string s)
628 wxCheckBox* _use_any_servers;
629 EditableList<string, ServerDialog>* _servers_list;
632 class TMSPage : public StandardPage
635 TMSPage (wxSize panel_size, int border)
636 : StandardPage (panel_size, border)
639 wxString GetName () const
645 wxBitmap GetLargeIcon () const
647 return wxBitmap ("tms", wxBITMAP_TYPE_PNG_RESOURCE);
654 wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
655 table->AddGrowableCol (1, 1);
656 _panel->GetSizer()->Add (table, 1, wxALL | wxEXPAND, _border);
658 add_label_to_sizer (table, _panel, _("Protocol"), true);
659 _tms_protocol = new wxChoice (_panel, wxID_ANY);
660 table->Add (_tms_protocol, 1, wxEXPAND);
662 add_label_to_sizer (table, _panel, _("IP address"), true);
663 _tms_ip = new wxTextCtrl (_panel, wxID_ANY);
664 table->Add (_tms_ip, 1, wxEXPAND);
666 add_label_to_sizer (table, _panel, _("Target path"), true);
667 _tms_path = new wxTextCtrl (_panel, wxID_ANY);
668 table->Add (_tms_path, 1, wxEXPAND);
670 add_label_to_sizer (table, _panel, _("User name"), true);
671 _tms_user = new wxTextCtrl (_panel, wxID_ANY);
672 table->Add (_tms_user, 1, wxEXPAND);
674 add_label_to_sizer (table, _panel, _("Password"), true);
675 _tms_password = new wxTextCtrl (_panel, wxID_ANY);
676 table->Add (_tms_password, 1, wxEXPAND);
678 _tms_protocol->Append (_("SCP (for AAM and Doremi)"));
679 _tms_protocol->Append (_("FTP (for Dolby)"));
681 _tms_protocol->Bind (wxEVT_CHOICE, boost::bind (&TMSPage::tms_protocol_changed, this));
682 _tms_ip->Bind (wxEVT_TEXT, boost::bind (&TMSPage::tms_ip_changed, this));
683 _tms_path->Bind (wxEVT_TEXT, boost::bind (&TMSPage::tms_path_changed, this));
684 _tms_user->Bind (wxEVT_TEXT, boost::bind (&TMSPage::tms_user_changed, this));
685 _tms_password->Bind (wxEVT_TEXT, boost::bind (&TMSPage::tms_password_changed, this));
688 void config_changed ()
690 Config* config = Config::instance ();
692 checked_set (_tms_protocol, config->tms_protocol ());
693 checked_set (_tms_ip, config->tms_ip ());
694 checked_set (_tms_path, config->tms_path ());
695 checked_set (_tms_user, config->tms_user ());
696 checked_set (_tms_password, config->tms_password ());
699 void tms_protocol_changed ()
701 Config::instance()->set_tms_protocol(static_cast<FileTransferProtocol>(_tms_protocol->GetSelection()));
704 void tms_ip_changed ()
706 Config::instance()->set_tms_ip (wx_to_std (_tms_ip->GetValue ()));
709 void tms_path_changed ()
711 Config::instance()->set_tms_path (wx_to_std (_tms_path->GetValue ()));
714 void tms_user_changed ()
716 Config::instance()->set_tms_user (wx_to_std (_tms_user->GetValue ()));
719 void tms_password_changed ()
721 Config::instance()->set_tms_password (wx_to_std (_tms_password->GetValue ()));
724 wxChoice* _tms_protocol;
726 wxTextCtrl* _tms_path;
727 wxTextCtrl* _tms_user;
728 wxTextCtrl* _tms_password;
737 class EmailPage : public StandardPage
740 EmailPage (wxSize panel_size, int border)
741 : StandardPage (panel_size, border)
744 wxString GetName () const
750 wxBitmap GetLargeIcon () const
752 return wxBitmap ("email", wxBITMAP_TYPE_PNG_RESOURCE);
759 wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
760 table->AddGrowableCol (1, 1);
761 _panel->GetSizer()->Add (table, 1, wxEXPAND | wxALL, _border);
763 add_label_to_sizer (table, _panel, _("Outgoing mail server"), true);
765 wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL);
766 _server = new wxTextCtrl (_panel, wxID_ANY);
767 s->Add (_server, 1, wxEXPAND | wxALL);
768 add_label_to_sizer (s, _panel, _("port"), false);
769 _port = new wxSpinCtrl (_panel, wxID_ANY);
770 _port->SetRange (0, 65535);
772 add_label_to_sizer (s, _panel, _("protocol"), false);
773 _protocol = new wxChoice (_panel, wxID_ANY);
774 /* Make sure this matches the switches in config_changed and port_changed below */
775 _protocol->Append (_("Auto"));
776 _protocol->Append (_("Plain"));
777 _protocol->Append (_("STARTTLS"));
778 _protocol->Append (_("SSL"));
780 table->Add (s, 1, wxEXPAND | wxALL);
783 add_label_to_sizer (table, _panel, _("User name"), true);
784 _user = new wxTextCtrl (_panel, wxID_ANY);
785 table->Add (_user, 1, wxEXPAND | wxALL);
787 add_label_to_sizer (table, _panel, _("Password"), true);
788 _password = new wxTextCtrl (_panel, wxID_ANY);
789 table->Add (_password, 1, wxEXPAND | wxALL);
791 _server->Bind (wxEVT_TEXT, boost::bind (&EmailPage::server_changed, this));
792 _port->Bind (wxEVT_SPINCTRL, boost::bind (&EmailPage::port_changed, this));
793 _protocol->Bind (wxEVT_CHOICE, boost::bind (&EmailPage::protocol_changed, this));
794 _user->Bind (wxEVT_TEXT, boost::bind (&EmailPage::user_changed, this));
795 _password->Bind (wxEVT_TEXT, boost::bind (&EmailPage::password_changed, this));
798 void config_changed ()
800 Config* config = Config::instance ();
802 checked_set (_server, config->mail_server ());
803 checked_set (_port, config->mail_port ());
804 switch (config->mail_protocol()) {
805 case EMAIL_PROTOCOL_AUTO:
806 checked_set (_protocol, 0);
808 case EMAIL_PROTOCOL_PLAIN:
809 checked_set (_protocol, 1);
811 case EMAIL_PROTOCOL_STARTTLS:
812 checked_set (_protocol, 2);
814 case EMAIL_PROTOCOL_SSL:
815 checked_set (_protocol, 3);
818 checked_set (_user, config->mail_user ());
819 checked_set (_password, config->mail_password ());
822 void server_changed ()
824 Config::instance()->set_mail_server (wx_to_std (_server->GetValue ()));
829 Config::instance()->set_mail_port (_port->GetValue ());
832 void protocol_changed ()
834 switch (_protocol->GetSelection()) {
836 Config::instance()->set_mail_protocol(EMAIL_PROTOCOL_AUTO);
839 Config::instance()->set_mail_protocol(EMAIL_PROTOCOL_PLAIN);
842 Config::instance()->set_mail_protocol(EMAIL_PROTOCOL_STARTTLS);
845 Config::instance()->set_mail_protocol(EMAIL_PROTOCOL_SSL);
852 Config::instance()->set_mail_user (wx_to_std (_user->GetValue ()));
855 void password_changed ()
857 Config::instance()->set_mail_password (wx_to_std (_password->GetValue ()));
864 wxTextCtrl* _password;
867 class KDMEmailPage : public StandardPage
871 KDMEmailPage (wxSize panel_size, int border)
873 /* We have to force both width and height of this one */
874 : StandardPage (wxSize (panel_size.GetWidth(), 128), border)
876 : StandardPage (panel_size, border)
880 wxString GetName () const
882 return _("KDM Email");
886 wxBitmap GetLargeIcon () const
888 return wxBitmap ("kdm_email", wxBITMAP_TYPE_PNG_RESOURCE);
895 wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
896 table->AddGrowableCol (1, 1);
897 _panel->GetSizer()->Add (table, 1, wxEXPAND | wxALL, _border);
899 add_label_to_sizer (table, _panel, _("Subject"), true);
900 _subject = new wxTextCtrl (_panel, wxID_ANY);
901 table->Add (_subject, 1, wxEXPAND | wxALL);
903 add_label_to_sizer (table, _panel, _("From address"), true);
904 _from = new wxTextCtrl (_panel, wxID_ANY);
905 table->Add (_from, 1, wxEXPAND | wxALL);
907 vector<string> columns;
908 columns.push_back (wx_to_std (_("Address")));
909 add_label_to_sizer (table, _panel, _("CC addresses"), true);
910 _cc = new EditableList<string, EmailDialog> (
913 bind (&Config::kdm_cc, Config::instance()),
914 bind (&Config::set_kdm_cc, Config::instance(), _1),
917 table->Add (_cc, 1, wxEXPAND | wxALL);
919 add_label_to_sizer (table, _panel, _("BCC address"), true);
920 _bcc = new wxTextCtrl (_panel, wxID_ANY);
921 table->Add (_bcc, 1, wxEXPAND | wxALL);
923 _email = new wxTextCtrl (_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize (-1, 200), wxTE_MULTILINE);
924 _panel->GetSizer()->Add (_email, 0, wxEXPAND | wxALL, _border);
926 _reset_email = new Button (_panel, _("Reset to default subject and text"));
927 _panel->GetSizer()->Add (_reset_email, 0, wxEXPAND | wxALL, _border);
931 _subject->Bind (wxEVT_TEXT, boost::bind (&KDMEmailPage::kdm_subject_changed, this));
932 _from->Bind (wxEVT_TEXT, boost::bind (&KDMEmailPage::kdm_from_changed, this));
933 _bcc->Bind (wxEVT_TEXT, boost::bind (&KDMEmailPage::kdm_bcc_changed, this));
934 _email->Bind (wxEVT_TEXT, boost::bind (&KDMEmailPage::kdm_email_changed, this));
935 _reset_email->Bind (wxEVT_BUTTON, boost::bind (&KDMEmailPage::reset_email, this));
938 void config_changed ()
940 Config* config = Config::instance ();
942 checked_set (_subject, config->kdm_subject ());
943 checked_set (_from, config->kdm_from ());
944 checked_set (_bcc, config->kdm_bcc ());
945 checked_set (_email, Config::instance()->kdm_email ());
948 void kdm_subject_changed ()
950 Config::instance()->set_kdm_subject (wx_to_std (_subject->GetValue ()));
953 void kdm_from_changed ()
955 Config::instance()->set_kdm_from (wx_to_std (_from->GetValue ()));
958 void kdm_bcc_changed ()
960 Config::instance()->set_kdm_bcc (wx_to_std (_bcc->GetValue ()));
963 void kdm_email_changed ()
965 if (_email->GetValue().IsEmpty ()) {
966 /* Sometimes we get sent an erroneous notification that the email
967 is empty; I don't know why.
971 Config::instance()->set_kdm_email (wx_to_std (_email->GetValue ()));
976 Config::instance()->reset_kdm_email ();
977 checked_set (_email, Config::instance()->kdm_email ());
980 wxTextCtrl* _subject;
982 EditableList<string, EmailDialog>* _cc;
985 wxButton* _reset_email;
988 class AccountsPage : public StandardPage
991 AccountsPage (wxSize panel_size, int border)
992 : StandardPage (panel_size, border)
995 wxString GetName () const
997 return _("Accounts");
1000 #ifdef DCPOMATIC_OSX
1001 wxBitmap GetLargeIcon () const
1003 return wxBitmap ("accounts", wxBITMAP_TYPE_PNG_RESOURCE);
1009 wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
1010 table->AddGrowableCol (1, 1);
1011 _panel->GetSizer()->Add (table, 1, wxEXPAND | wxALL, _border);
1013 add_label_to_sizer (table, _panel, _("certificates.barco.com user name"), true);
1014 _barco_username = new wxTextCtrl (_panel, wxID_ANY);
1015 table->Add (_barco_username, 1, wxEXPAND | wxALL);
1017 add_label_to_sizer (table, _panel, _("certificates.barco.com password"), true);
1018 _barco_password = new wxTextCtrl (_panel, wxID_ANY);
1019 table->Add (_barco_password, 1, wxEXPAND | wxALL);
1021 add_label_to_sizer (table, _panel, _("certificates.christiedigital.com user name"), true);
1022 _christie_username = new wxTextCtrl (_panel, wxID_ANY);
1023 table->Add (_christie_username, 1, wxEXPAND | wxALL);
1025 add_label_to_sizer (table, _panel, _("certificates.christiedigital.com password"), true);
1026 _christie_password = new wxTextCtrl (_panel, wxID_ANY);
1027 table->Add (_christie_password, 1, wxEXPAND | wxALL);
1029 add_label_to_sizer (table, _panel, _("GDC user name"), true);
1030 _gdc_username = new wxTextCtrl (_panel, wxID_ANY);
1031 table->Add (_gdc_username, 1, wxEXPAND | wxALL);
1033 add_label_to_sizer (table, _panel, _("GDC password"), true);
1034 _gdc_password = new wxTextCtrl (_panel, wxID_ANY);
1035 table->Add (_gdc_password, 1, wxEXPAND | wxALL);
1037 _barco_username->Bind (wxEVT_TEXT, boost::bind(&AccountsPage::barco_username_changed, this));
1038 _barco_password->Bind (wxEVT_TEXT, boost::bind(&AccountsPage::barco_password_changed, this));
1039 _christie_username->Bind (wxEVT_TEXT, boost::bind(&AccountsPage::christie_username_changed, this));
1040 _christie_password->Bind (wxEVT_TEXT, boost::bind(&AccountsPage::christie_password_changed, this));
1041 _gdc_username->Bind (wxEVT_TEXT, boost::bind(&AccountsPage::gdc_username_changed, this));
1042 _gdc_password->Bind (wxEVT_TEXT, boost::bind(&AccountsPage::gdc_password_changed, this));
1045 void config_changed ()
1047 Config* config = Config::instance ();
1049 checked_set (_barco_username, config->barco_username().get_value_or(""));
1050 checked_set (_barco_password, config->barco_password().get_value_or(""));
1051 checked_set (_christie_username, config->christie_username().get_value_or(""));
1052 checked_set (_christie_password, config->christie_password().get_value_or(""));
1053 checked_set (_gdc_username, config->gdc_username().get_value_or(""));
1054 checked_set (_gdc_password, config->gdc_password().get_value_or(""));
1057 void barco_username_changed ()
1059 wxString const s = _barco_username->GetValue();
1061 Config::instance()->set_barco_username (wx_to_std(s));
1063 Config::instance()->unset_barco_username ();
1067 void barco_password_changed ()
1069 wxString const s = _barco_password->GetValue();
1071 Config::instance()->set_barco_password (wx_to_std(s));
1073 Config::instance()->unset_barco_password ();
1077 void christie_username_changed ()
1079 wxString const s = _christie_username->GetValue();
1081 Config::instance()->set_christie_username (wx_to_std(s));
1083 Config::instance()->unset_christie_username ();
1087 void christie_password_changed ()
1089 wxString const s = _christie_password->GetValue();
1091 Config::instance()->set_christie_password (wx_to_std(s));
1093 Config::instance()->unset_christie_password ();
1097 void gdc_username_changed ()
1099 wxString const s = _gdc_username->GetValue();
1101 Config::instance()->set_gdc_username (wx_to_std(s));
1103 Config::instance()->unset_gdc_username ();
1107 void gdc_password_changed ()
1109 wxString const s = _gdc_password->GetValue();
1111 Config::instance()->set_gdc_password (wx_to_std(s));
1113 Config::instance()->unset_gdc_password ();
1118 wxTextCtrl* _barco_username;
1119 wxTextCtrl* _barco_password;
1120 wxTextCtrl* _christie_username;
1121 wxTextCtrl* _christie_password;
1122 wxTextCtrl* _gdc_username;
1123 wxTextCtrl* _gdc_password;
1127 class NotificationsPage : public StandardPage
1130 NotificationsPage (wxSize panel_size, int border)
1131 #ifdef DCPOMATIC_OSX
1132 /* We have to force both width and height of this one */
1133 : StandardPage (wxSize (panel_size.GetWidth(), 128), border)
1135 : StandardPage (panel_size, border)
1139 wxString GetName () const
1141 return _("Notifications");
1144 #ifdef DCPOMATIC_OSX
1145 wxBitmap GetLargeIcon () const
1147 return wxBitmap ("notifications", wxBITMAP_TYPE_PNG_RESOURCE);
1154 wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
1155 table->AddGrowableCol (1, 1);
1156 _panel->GetSizer()->Add (table, 1, wxEXPAND | wxALL, _border);
1158 _enable_message_box = new CheckBox (_panel, _("Message box"));
1159 table->Add (_enable_message_box, 1, wxEXPAND | wxALL);
1160 table->AddSpacer (0);
1162 _enable_email = new CheckBox (_panel, _("Email"));
1163 table->Add (_enable_email, 1, wxEXPAND | wxALL);
1164 table->AddSpacer (0);
1166 add_label_to_sizer (table, _panel, _("Subject"), true);
1167 _subject = new wxTextCtrl (_panel, wxID_ANY);
1168 table->Add (_subject, 1, wxEXPAND | wxALL);
1170 add_label_to_sizer (table, _panel, _("From address"), true);
1171 _from = new wxTextCtrl (_panel, wxID_ANY);
1172 table->Add (_from, 1, wxEXPAND | wxALL);
1174 add_label_to_sizer (table, _panel, _("To address"), true);
1175 _to = new wxTextCtrl (_panel, wxID_ANY);
1176 table->Add (_to, 1, wxEXPAND | wxALL);
1178 vector<string> columns;
1179 columns.push_back (wx_to_std (_("Address")));
1180 add_label_to_sizer (table, _panel, _("CC addresses"), true);
1181 _cc = new EditableList<string, EmailDialog> (
1184 bind (&Config::notification_cc, Config::instance()),
1185 bind (&Config::set_notification_cc, Config::instance(), _1),
1188 table->Add (_cc, 1, wxEXPAND | wxALL);
1190 add_label_to_sizer (table, _panel, _("BCC address"), true);
1191 _bcc = new wxTextCtrl (_panel, wxID_ANY);
1192 table->Add (_bcc, 1, wxEXPAND | wxALL);
1194 _email = new wxTextCtrl (_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize (-1, 200), wxTE_MULTILINE);
1195 _panel->GetSizer()->Add (_email, 0, wxEXPAND | wxALL, _border);
1197 _reset_email = new Button (_panel, _("Reset to default subject and text"));
1198 _panel->GetSizer()->Add (_reset_email, 0, wxEXPAND | wxALL, _border);
1202 _enable_message_box->Bind (wxEVT_CHECKBOX, boost::bind (&NotificationsPage::type_changed, this, _enable_message_box, Config::MESSAGE_BOX));
1203 _enable_email->Bind (wxEVT_CHECKBOX, boost::bind (&NotificationsPage::type_changed, this, _enable_email, Config::EMAIL));
1205 _subject->Bind (wxEVT_TEXT, boost::bind (&NotificationsPage::notification_subject_changed, this));
1206 _from->Bind (wxEVT_TEXT, boost::bind (&NotificationsPage::notification_from_changed, this));
1207 _to->Bind (wxEVT_TEXT, boost::bind (&NotificationsPage::notification_to_changed, this));
1208 _bcc->Bind (wxEVT_TEXT, boost::bind (&NotificationsPage::notification_bcc_changed, this));
1209 _email->Bind (wxEVT_TEXT, boost::bind (&NotificationsPage::notification_email_changed, this));
1210 _reset_email->Bind (wxEVT_BUTTON, boost::bind (&NotificationsPage::reset_email, this));
1212 update_sensitivity ();
1215 void update_sensitivity ()
1217 bool const s = _enable_email->GetValue();
1218 _subject->Enable(s);
1224 _reset_email->Enable(s);
1227 void config_changed ()
1229 Config* config = Config::instance ();
1231 checked_set (_enable_message_box, config->notification(Config::MESSAGE_BOX));
1232 checked_set (_enable_email, config->notification(Config::EMAIL));
1233 checked_set (_subject, config->notification_subject ());
1234 checked_set (_from, config->notification_from ());
1235 checked_set (_to, config->notification_to ());
1236 checked_set (_bcc, config->notification_bcc ());
1237 checked_set (_email, Config::instance()->notification_email ());
1239 update_sensitivity ();
1242 void notification_subject_changed ()
1244 Config::instance()->set_notification_subject (wx_to_std (_subject->GetValue ()));
1247 void notification_from_changed ()
1249 Config::instance()->set_notification_from (wx_to_std (_from->GetValue ()));
1252 void notification_to_changed ()
1254 Config::instance()->set_notification_to (wx_to_std (_to->GetValue ()));
1257 void notification_bcc_changed ()
1259 Config::instance()->set_notification_bcc (wx_to_std (_bcc->GetValue ()));
1262 void notification_email_changed ()
1264 if (_email->GetValue().IsEmpty ()) {
1265 /* Sometimes we get sent an erroneous notification that the email
1266 is empty; I don't know why.
1270 Config::instance()->set_notification_email (wx_to_std (_email->GetValue ()));
1275 Config::instance()->reset_notification_email ();
1276 checked_set (_email, Config::instance()->notification_email ());
1279 void type_changed (wxCheckBox* b, Config::Notification n)
1281 Config::instance()->set_notification(n, b->GetValue());
1282 update_sensitivity ();
1285 wxCheckBox* _enable_message_box;
1286 wxCheckBox* _enable_email;
1288 wxTextCtrl* _subject;
1291 EditableList<string, EmailDialog>* _cc;
1294 wxButton* _reset_email;
1297 class CoverSheetPage : public StandardPage
1301 CoverSheetPage (wxSize panel_size, int border)
1302 #ifdef DCPOMATIC_OSX
1303 /* We have to force both width and height of this one */
1304 : StandardPage (wxSize (panel_size.GetWidth(), 128), border)
1306 : StandardPage (panel_size, border)
1310 wxString GetName () const
1312 return _("Cover Sheet");
1315 #ifdef DCPOMATIC_OSX
1316 wxBitmap GetLargeIcon () const
1318 return wxBitmap ("cover_sheet", wxBITMAP_TYPE_PNG_RESOURCE);
1325 _cover_sheet = new wxTextCtrl (_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize (-1, 200), wxTE_MULTILINE);
1326 _panel->GetSizer()->Add (_cover_sheet, 0, wxEXPAND | wxALL, _border);
1328 _reset_cover_sheet = new Button (_panel, _("Reset to default text"));
1329 _panel->GetSizer()->Add (_reset_cover_sheet, 0, wxEXPAND | wxALL, _border);
1331 _cover_sheet->Bind (wxEVT_TEXT, boost::bind (&CoverSheetPage::cover_sheet_changed, this));
1332 _reset_cover_sheet->Bind (wxEVT_BUTTON, boost::bind (&CoverSheetPage::reset_cover_sheet, this));
1335 void config_changed ()
1337 checked_set (_cover_sheet, Config::instance()->cover_sheet ());
1340 void cover_sheet_changed ()
1342 if (_cover_sheet->GetValue().IsEmpty ()) {
1343 /* Sometimes we get sent an erroneous notification that the cover sheet
1344 is empty; I don't know why.
1348 Config::instance()->set_cover_sheet (wx_to_std (_cover_sheet->GetValue ()));
1351 void reset_cover_sheet ()
1353 Config::instance()->reset_cover_sheet ();
1354 checked_set (_cover_sheet, Config::instance()->cover_sheet ());
1357 wxTextCtrl* _cover_sheet;
1358 wxButton* _reset_cover_sheet;
1362 /** @class AdvancedPage
1363 * @brief Advanced page of the preferences dialog.
1365 class AdvancedPage : public StockPage
1368 AdvancedPage (wxSize panel_size, int border)
1369 : StockPage (Kind_Advanced, panel_size, border)
1370 , _maximum_j2k_bandwidth (0)
1371 , _allow_any_dcp_frame_rate (0)
1372 , _allow_any_container (0)
1373 , _only_servers_encode (0)
1378 , _log_debug_decode (0)
1379 , _log_debug_encode (0)
1380 , _log_debug_email (0)
1384 void add_top_aligned_label_to_sizer (wxSizer* table, wxWindow* parent, wxString text)
1386 int flags = wxALIGN_TOP | wxTOP | wxLEFT;
1388 flags |= wxALIGN_RIGHT;
1391 wxStaticText* m = new StaticText (parent, text);
1392 table->Add (m, 0, flags, DCPOMATIC_SIZER_Y_GAP);
1397 wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
1398 table->AddGrowableCol (1, 1);
1399 _panel->GetSizer()->Add (table, 1, wxALL | wxEXPAND, _border);
1402 add_label_to_sizer (table, _panel, _("Maximum JPEG2000 bandwidth"), true);
1403 wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL);
1404 _maximum_j2k_bandwidth = new wxSpinCtrl (_panel);
1405 s->Add (_maximum_j2k_bandwidth, 1);
1406 add_label_to_sizer (s, _panel, _("Mbit/s"), false);
1410 _allow_any_dcp_frame_rate = new CheckBox (_panel, _("Allow any DCP frame rate"));
1411 table->Add (_allow_any_dcp_frame_rate, 1, wxEXPAND | wxALL);
1412 table->AddSpacer (0);
1414 _allow_any_container = new CheckBox (_panel, _("Allow non-standard container ratios"));
1415 table->Add (_allow_any_container, 1, wxEXPAND | wxALL);
1416 table->AddSpacer (0);
1418 wxStaticText* restart = add_label_to_sizer (table, _panel, _("(restart DCP-o-matic to see all ratios)"), false);
1419 wxFont font = restart->GetFont();
1420 font.SetStyle (wxFONTSTYLE_ITALIC);
1421 font.SetPointSize (font.GetPointSize() - 1);
1422 restart->SetFont (font);
1423 table->AddSpacer (0);
1425 _only_servers_encode = new CheckBox (_panel, _("Only servers encode"));
1426 table->Add (_only_servers_encode, 1, wxEXPAND | wxALL);
1427 table->AddSpacer (0);
1430 add_label_to_sizer (table, _panel, _("Maximum number of frames to store per thread"), true);
1431 wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL);
1432 _frames_in_memory_multiplier = new wxSpinCtrl (_panel);
1433 s->Add (_frames_in_memory_multiplier, 1);
1438 add_top_aligned_label_to_sizer (table, _panel, _("DCP metadata filename format"));
1439 dcp::NameFormat::Map titles;
1440 titles['t'] = wx_to_std (_("type (cpl/pkl)"));
1441 dcp::NameFormat::Map examples;
1442 examples['t'] = "cpl";
1443 _dcp_metadata_filename_format = new NameFormatEditor (
1444 _panel, Config::instance()->dcp_metadata_filename_format(), titles, examples, "_eb1c112c-ca3c-4ae6-9263-c6714ff05d64.xml"
1446 table->Add (_dcp_metadata_filename_format->panel(), 1, wxEXPAND | wxALL);
1450 add_top_aligned_label_to_sizer (table, _panel, _("DCP asset filename format"));
1451 dcp::NameFormat::Map titles;
1452 titles['t'] = wx_to_std (_("type (j2c/pcm/sub)"));
1453 titles['r'] = wx_to_std (_("reel number"));
1454 titles['n'] = wx_to_std (_("number of reels"));
1455 titles['c'] = wx_to_std (_("content filename"));
1456 dcp::NameFormat::Map examples;
1457 examples['t'] = "j2c";
1458 examples['r'] = "1";
1459 examples['n'] = "4";
1460 examples['c'] = "myfile.mp4";
1461 _dcp_asset_filename_format = new NameFormatEditor (
1462 _panel, Config::instance()->dcp_asset_filename_format(), titles, examples, "_eb1c112c-ca3c-4ae6-9263-c6714ff05d64.mxf"
1464 table->Add (_dcp_asset_filename_format->panel(), 1, wxEXPAND | wxALL);
1468 add_top_aligned_label_to_sizer (table, _panel, _("Log"));
1469 wxBoxSizer* t = new wxBoxSizer (wxVERTICAL);
1470 _log_general = new CheckBox (_panel, _("General"));
1471 t->Add (_log_general, 1, wxEXPAND | wxALL);
1472 _log_warning = new CheckBox (_panel, _("Warnings"));
1473 t->Add (_log_warning, 1, wxEXPAND | wxALL);
1474 _log_error = new CheckBox (_panel, _("Errors"));
1475 t->Add (_log_error, 1, wxEXPAND | wxALL);
1476 /// TRANSLATORS: translate the word "Timing" here; do not include the "Config|" prefix
1477 _log_timing = new CheckBox (_panel, S_("Config|Timing"));
1478 t->Add (_log_timing, 1, wxEXPAND | wxALL);
1479 _log_debug_decode = new CheckBox (_panel, _("Debug: decode"));
1480 t->Add (_log_debug_decode, 1, wxEXPAND | wxALL);
1481 _log_debug_encode = new CheckBox (_panel, _("Debug: encode"));
1482 t->Add (_log_debug_encode, 1, wxEXPAND | wxALL);
1483 _log_debug_email = new CheckBox (_panel, _("Debug: email sending"));
1484 t->Add (_log_debug_email, 1, wxEXPAND | wxALL);
1485 table->Add (t, 0, wxALL, 6);
1488 #ifdef DCPOMATIC_WINDOWS
1489 _win32_console = new CheckBox (_panel, _("Open console window"));
1490 table->Add (_win32_console, 1, wxEXPAND | wxALL);
1491 table->AddSpacer (0);
1494 _maximum_j2k_bandwidth->SetRange (1, 1000);
1495 _maximum_j2k_bandwidth->Bind (wxEVT_SPINCTRL, boost::bind (&AdvancedPage::maximum_j2k_bandwidth_changed, this));
1496 _allow_any_dcp_frame_rate->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::allow_any_dcp_frame_rate_changed, this));
1497 _allow_any_container->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::allow_any_container_changed, this));
1498 _only_servers_encode->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::only_servers_encode_changed, this));
1499 _frames_in_memory_multiplier->Bind (wxEVT_SPINCTRL, boost::bind(&AdvancedPage::frames_in_memory_multiplier_changed, this));
1500 _dcp_metadata_filename_format->Changed.connect (boost::bind (&AdvancedPage::dcp_metadata_filename_format_changed, this));
1501 _dcp_asset_filename_format->Changed.connect (boost::bind (&AdvancedPage::dcp_asset_filename_format_changed, this));
1502 _log_general->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::log_changed, this));
1503 _log_warning->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::log_changed, this));
1504 _log_error->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::log_changed, this));
1505 _log_timing->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::log_changed, this));
1506 _log_debug_decode->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::log_changed, this));
1507 _log_debug_encode->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::log_changed, this));
1508 _log_debug_email->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::log_changed, this));
1509 #ifdef DCPOMATIC_WINDOWS
1510 _win32_console->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::win32_console_changed, this));
1514 void config_changed ()
1516 Config* config = Config::instance ();
1518 checked_set (_maximum_j2k_bandwidth, config->maximum_j2k_bandwidth() / 1000000);
1519 checked_set (_allow_any_dcp_frame_rate, config->allow_any_dcp_frame_rate ());
1520 checked_set (_allow_any_container, config->allow_any_container ());
1521 checked_set (_only_servers_encode, config->only_servers_encode ());
1522 checked_set (_log_general, config->log_types() & LogEntry::TYPE_GENERAL);
1523 checked_set (_log_warning, config->log_types() & LogEntry::TYPE_WARNING);
1524 checked_set (_log_error, config->log_types() & LogEntry::TYPE_ERROR);
1525 checked_set (_log_timing, config->log_types() & LogEntry::TYPE_TIMING);
1526 checked_set (_log_debug_decode, config->log_types() & LogEntry::TYPE_DEBUG_DECODE);
1527 checked_set (_log_debug_encode, config->log_types() & LogEntry::TYPE_DEBUG_ENCODE);
1528 checked_set (_log_debug_email, config->log_types() & LogEntry::TYPE_DEBUG_EMAIL);
1529 checked_set (_frames_in_memory_multiplier, config->frames_in_memory_multiplier());
1530 #ifdef DCPOMATIC_WINDOWS
1531 checked_set (_win32_console, config->win32_console());
1535 void maximum_j2k_bandwidth_changed ()
1537 Config::instance()->set_maximum_j2k_bandwidth (_maximum_j2k_bandwidth->GetValue() * 1000000);
1540 void frames_in_memory_multiplier_changed ()
1542 Config::instance()->set_frames_in_memory_multiplier (_frames_in_memory_multiplier->GetValue());
1545 void allow_any_dcp_frame_rate_changed ()
1547 Config::instance()->set_allow_any_dcp_frame_rate (_allow_any_dcp_frame_rate->GetValue ());
1550 void allow_any_container_changed ()
1552 Config::instance()->set_allow_any_container (_allow_any_container->GetValue ());
1555 void only_servers_encode_changed ()
1557 Config::instance()->set_only_servers_encode (_only_servers_encode->GetValue ());
1560 void dcp_metadata_filename_format_changed ()
1562 Config::instance()->set_dcp_metadata_filename_format (_dcp_metadata_filename_format->get ());
1565 void dcp_asset_filename_format_changed ()
1567 Config::instance()->set_dcp_asset_filename_format (_dcp_asset_filename_format->get ());
1573 if (_log_general->GetValue ()) {
1574 types |= LogEntry::TYPE_GENERAL;
1576 if (_log_warning->GetValue ()) {
1577 types |= LogEntry::TYPE_WARNING;
1579 if (_log_error->GetValue ()) {
1580 types |= LogEntry::TYPE_ERROR;
1582 if (_log_timing->GetValue ()) {
1583 types |= LogEntry::TYPE_TIMING;
1585 if (_log_debug_decode->GetValue ()) {
1586 types |= LogEntry::TYPE_DEBUG_DECODE;
1588 if (_log_debug_encode->GetValue ()) {
1589 types |= LogEntry::TYPE_DEBUG_ENCODE;
1591 if (_log_debug_email->GetValue ()) {
1592 types |= LogEntry::TYPE_DEBUG_EMAIL;
1594 Config::instance()->set_log_types (types);
1597 #ifdef DCPOMATIC_WINDOWS
1598 void win32_console_changed ()
1600 Config::instance()->set_win32_console (_win32_console->GetValue ());
1604 wxSpinCtrl* _maximum_j2k_bandwidth;
1605 wxSpinCtrl* _frames_in_memory_multiplier;
1606 wxCheckBox* _allow_any_dcp_frame_rate;
1607 wxCheckBox* _allow_any_container;
1608 wxCheckBox* _only_servers_encode;
1609 NameFormatEditor* _dcp_metadata_filename_format;
1610 NameFormatEditor* _dcp_asset_filename_format;
1611 wxCheckBox* _log_general;
1612 wxCheckBox* _log_warning;
1613 wxCheckBox* _log_error;
1614 wxCheckBox* _log_timing;
1615 wxCheckBox* _log_debug_decode;
1616 wxCheckBox* _log_debug_encode;
1617 wxCheckBox* _log_debug_email;
1618 #ifdef DCPOMATIC_WINDOWS
1619 wxCheckBox* _win32_console;
1623 wxPreferencesEditor*
1624 create_full_config_dialog ()
1626 wxPreferencesEditor* e = new wxPreferencesEditor ();
1628 #ifdef DCPOMATIC_OSX
1629 /* Width that we force some of the config panels to be on OSX so that
1630 the containing window doesn't shrink too much when we select those panels.
1631 This is obviously an unpleasant hack.
1633 wxSize ps = wxSize (700, -1);
1634 int const border = 16;
1636 wxSize ps = wxSize (-1, -1);
1637 int const border = 8;
1640 e->AddPage (new FullGeneralPage (ps, border));
1641 e->AddPage (new DefaultsPage (ps, border));
1642 e->AddPage (new EncodingServersPage (ps, border));
1643 e->AddPage (new KeysPage (ps, border));
1644 e->AddPage (new TMSPage (ps, border));
1645 e->AddPage (new EmailPage (ps, border));
1646 e->AddPage (new KDMEmailPage (ps, border));
1647 e->AddPage (new AccountsPage (ps, border));
1648 e->AddPage (new NotificationsPage (ps, border));
1649 e->AddPage (new CoverSheetPage (ps, border));
1650 e->AddPage (new AdvancedPage (ps, border));