2 Copyright (C) 2012-2019 Carl Hetherington <cth@carlh.net>
4 This file is part of DCP-o-matic.
6 DCP-o-matic is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 DCP-o-matic is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with DCP-o-matic. If not, see <http://www.gnu.org/licenses/>.
21 /** @file src/full_config_dialog.cc
22 * @brief A dialogue to edit all DCP-o-matic configuration.
25 #include "full_config_dialog.h"
27 #include "editable_list.h"
28 #include "filter_dialog.h"
29 #include "dir_picker_ctrl.h"
30 #include "file_picker_ctrl.h"
31 #include "isdcf_metadata_dialog.h"
32 #include "server_dialog.h"
33 #include "make_chain_dialog.h"
34 #include "email_dialog.h"
35 #include "name_format_editor.h"
36 #include "nag_dialog.h"
37 #include "config_move_dialog.h"
38 #include "config_dialog.h"
39 #include "static_text.h"
40 #include "check_box.h"
41 #include "dcpomatic_button.h"
42 #include "password_entry.h"
43 #include "lib/config.h"
44 #include "lib/ratio.h"
45 #include "lib/filter.h"
46 #include "lib/dcp_content_type.h"
49 #include "lib/cross.h"
50 #include "lib/exceptions.h"
51 #include <dcp/locale_convert.h>
52 #include <dcp/exceptions.h>
53 #include <dcp/certificate_chain.h>
54 #include <wx/stdpaths.h>
55 #include <wx/preferences.h>
56 #include <wx/spinctrl.h>
57 #include <wx/filepicker.h>
59 #include <boost/filesystem.hpp>
60 #include <boost/foreach.hpp>
71 using boost::shared_ptr;
72 using boost::function;
73 using boost::optional;
74 using dcp::locale_convert;
76 class FullGeneralPage : public GeneralPage
79 FullGeneralPage (wxSize panel_size, int border)
80 : GeneralPage (panel_size, border)
86 wxGridBagSizer* table = new wxGridBagSizer (DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
87 _panel->GetSizer()->Add (table, 1, wxALL | wxEXPAND, _border);
90 add_language_controls (table, r);
92 add_label_to_sizer (table, _panel, _("Interface complexity"), true, wxGBPosition(r, 0));
93 _interface_complexity = new wxChoice (_panel, wxID_ANY);
94 table->Add (_interface_complexity, wxGBPosition (r, 1));
97 add_label_to_sizer (table, _panel, _("Number of threads DCP-o-matic should use"), true, wxGBPosition (r, 0));
98 _master_encoding_threads = new wxSpinCtrl (_panel);
99 table->Add (_master_encoding_threads, wxGBPosition (r, 1));
102 add_label_to_sizer (table, _panel, _("Number of threads DCP-o-matic encode server should use"), true, wxGBPosition (r, 0));
103 _server_encoding_threads = new wxSpinCtrl (_panel);
104 table->Add (_server_encoding_threads, wxGBPosition (r, 1));
107 add_label_to_sizer (table, _panel, _("Configuration file"), true, wxGBPosition (r, 0));
108 _config_file = new FilePickerCtrl (_panel, _("Select configuration file"), "*.xml", true, true);
109 table->Add (_config_file, wxGBPosition (r, 1));
112 add_label_to_sizer (table, _panel, _("Cinema and screen database file"), true, wxGBPosition (r, 0));
113 _cinemas_file = new FilePickerCtrl (_panel, _("Select cinema and screen database file"), "*.xml", true, true);
114 table->Add (_cinemas_file, wxGBPosition (r, 1));
115 Button* export_cinemas = new Button (_panel, _("Export..."));
116 table->Add (export_cinemas, wxGBPosition (r, 2));
119 #ifdef DCPOMATIC_HAVE_EBUR128_PATCHED_FFMPEG
120 _analyse_ebur128 = new CheckBox (_panel, _("Find integrated loudness, true peak and loudness range when analysing audio"));
121 table->Add (_analyse_ebur128, wxGBPosition (r, 0), wxGBSpan (1, 2));
125 _automatic_audio_analysis = new CheckBox (_panel, _("Automatically analyse content audio"));
126 table->Add (_automatic_audio_analysis, wxGBPosition (r, 0), wxGBSpan (1, 2));
129 add_update_controls (table, r);
131 _config_file->Bind (wxEVT_FILEPICKER_CHANGED, boost::bind (&FullGeneralPage::config_file_changed, this));
132 _cinemas_file->Bind (wxEVT_FILEPICKER_CHANGED, boost::bind (&FullGeneralPage::cinemas_file_changed, this));
134 _interface_complexity->Append (_("Simple"));
135 _interface_complexity->Append (_("Full"));
136 _interface_complexity->Bind (wxEVT_CHOICE, boost::bind(&FullGeneralPage::interface_complexity_changed, this));
138 _master_encoding_threads->SetRange (1, 128);
139 _master_encoding_threads->Bind (wxEVT_SPINCTRL, boost::bind (&FullGeneralPage::master_encoding_threads_changed, this));
140 _server_encoding_threads->SetRange (1, 128);
141 _server_encoding_threads->Bind (wxEVT_SPINCTRL, boost::bind (&FullGeneralPage::server_encoding_threads_changed, this));
142 export_cinemas->Bind (wxEVT_BUTTON, boost::bind (&FullGeneralPage::export_cinemas_file, this));
144 #ifdef DCPOMATIC_HAVE_EBUR128_PATCHED_FFMPEG
145 _analyse_ebur128->Bind (wxEVT_CHECKBOX, boost::bind (&FullGeneralPage::analyse_ebur128_changed, this));
147 _automatic_audio_analysis->Bind (wxEVT_CHECKBOX, boost::bind (&FullGeneralPage::automatic_audio_analysis_changed, this));
150 void config_changed ()
152 Config* config = Config::instance ();
154 switch (config->interface_complexity()) {
155 case Config::INTERFACE_SIMPLE:
156 checked_set (_interface_complexity, 0);
158 case Config::INTERFACE_FULL:
159 checked_set (_interface_complexity, 1);
162 checked_set (_master_encoding_threads, config->master_encoding_threads ());
163 checked_set (_server_encoding_threads, config->server_encoding_threads ());
164 #ifdef DCPOMATIC_HAVE_EBUR128_PATCHED_FFMPEG
165 checked_set (_analyse_ebur128, config->analyse_ebur128 ());
167 checked_set (_automatic_audio_analysis, config->automatic_audio_analysis ());
168 checked_set (_config_file, config->config_file());
169 checked_set (_cinemas_file, config->cinemas_file());
171 GeneralPage::config_changed ();
174 void export_cinemas_file ()
176 wxFileDialog* d = new wxFileDialog (
177 _panel, _("Select Cinemas File"), wxEmptyString, wxEmptyString, wxT ("XML files (*.xml)|*.xml"),
178 wxFD_SAVE | wxFD_OVERWRITE_PROMPT
181 if (d->ShowModal () == wxID_OK) {
182 boost::filesystem::copy_file (Config::instance()->cinemas_file(), wx_to_std(d->GetPath()));
187 void interface_complexity_changed ()
189 if (_interface_complexity->GetSelection() == 0) {
190 Config::instance()->set_interface_complexity (Config::INTERFACE_SIMPLE);
192 Config::instance()->set_interface_complexity (Config::INTERFACE_FULL);
197 #ifdef DCPOMATIC_HAVE_EBUR128_PATCHED_FFMPEG
198 void analyse_ebur128_changed ()
200 Config::instance()->set_analyse_ebur128 (_analyse_ebur128->GetValue ());
204 void automatic_audio_analysis_changed ()
206 Config::instance()->set_automatic_audio_analysis (_automatic_audio_analysis->GetValue ());
209 void master_encoding_threads_changed ()
211 Config::instance()->set_master_encoding_threads (_master_encoding_threads->GetValue ());
214 void server_encoding_threads_changed ()
216 Config::instance()->set_server_encoding_threads (_server_encoding_threads->GetValue ());
219 void config_file_changed ()
221 Config* config = Config::instance();
222 boost::filesystem::path new_file = wx_to_std(_config_file->GetPath());
223 if (new_file == config->config_file()) {
226 bool copy_and_link = true;
227 if (boost::filesystem::exists(new_file)) {
228 ConfigMoveDialog* d = new ConfigMoveDialog (_panel, new_file);
229 if (d->ShowModal() == wxID_OK) {
230 copy_and_link = false;
237 if (new_file != config->config_file()) {
238 config->copy_and_link (new_file);
241 config->link (new_file);
245 void cinemas_file_changed ()
247 Config::instance()->set_cinemas_file (wx_to_std (_cinemas_file->GetPath ()));
250 wxChoice* _interface_complexity;
251 wxSpinCtrl* _master_encoding_threads;
252 wxSpinCtrl* _server_encoding_threads;
253 FilePickerCtrl* _config_file;
254 FilePickerCtrl* _cinemas_file;
255 #ifdef DCPOMATIC_HAVE_EBUR128_PATCHED_FFMPEG
256 wxCheckBox* _analyse_ebur128;
258 wxCheckBox* _automatic_audio_analysis;
261 class DefaultsPage : public StandardPage
264 DefaultsPage (wxSize panel_size, int border)
265 : StandardPage (panel_size, border)
268 wxString GetName () const
270 return _("Defaults");
274 wxBitmap GetLargeIcon () const
276 return wxBitmap ("defaults", wxBITMAP_TYPE_PNG_RESOURCE);
283 wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
284 table->AddGrowableCol (1, 1);
285 _panel->GetSizer()->Add (table, 1, wxALL | wxEXPAND, _border);
288 add_label_to_sizer (table, _panel, _("Default duration of still images"), true);
289 wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL);
290 _still_length = new wxSpinCtrl (_panel);
291 s->Add (_still_length);
292 add_label_to_sizer (s, _panel, _("s"), false);
296 add_label_to_sizer (table, _panel, _("Default directory for new films"), true);
297 #ifdef DCPOMATIC_USE_OWN_PICKER
298 _directory = new DirPickerCtrl (_panel);
300 _directory = new wxDirPickerCtrl (_panel, wxDD_DIR_MUST_EXIST);
302 table->Add (_directory, 1, wxEXPAND);
304 add_label_to_sizer (table, _panel, _("Default ISDCF name details"), true);
305 _isdcf_metadata_button = new Button (_panel, _("Edit..."));
306 table->Add (_isdcf_metadata_button);
308 add_label_to_sizer (table, _panel, _("Default container"), true);
309 _container = new wxChoice (_panel, wxID_ANY);
310 table->Add (_container);
312 add_label_to_sizer (table, _panel, _("Default content type"), true);
313 _dcp_content_type = new wxChoice (_panel, wxID_ANY);
314 table->Add (_dcp_content_type);
316 add_label_to_sizer (table, _panel, _("Default DCP audio channels"), true);
317 _dcp_audio_channels = new wxChoice (_panel, wxID_ANY);
318 table->Add (_dcp_audio_channels);
321 add_label_to_sizer (table, _panel, _("Default JPEG2000 bandwidth"), true);
322 wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL);
323 _j2k_bandwidth = new wxSpinCtrl (_panel);
324 s->Add (_j2k_bandwidth);
325 add_label_to_sizer (s, _panel, _("Mbit/s"), false);
330 add_label_to_sizer (table, _panel, _("Default audio delay"), true);
331 wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL);
332 _audio_delay = new wxSpinCtrl (_panel);
333 s->Add (_audio_delay);
334 add_label_to_sizer (s, _panel, _("ms"), false);
338 add_label_to_sizer (table, _panel, _("Default standard"), true);
339 _standard = new wxChoice (_panel, wxID_ANY);
340 table->Add (_standard);
342 add_label_to_sizer (table, _panel, _("Default KDM directory"), true);
343 #ifdef DCPOMATIC_USE_OWN_PICKER
344 _kdm_directory = new DirPickerCtrl (_panel);
346 _kdm_directory = new wxDirPickerCtrl (_panel, wxDD_DIR_MUST_EXIST);
349 table->Add (_kdm_directory, 1, wxEXPAND);
351 _still_length->SetRange (1, 3600);
352 _still_length->Bind (wxEVT_SPINCTRL, boost::bind (&DefaultsPage::still_length_changed, this));
354 _directory->Bind (wxEVT_DIRPICKER_CHANGED, boost::bind (&DefaultsPage::directory_changed, this));
355 _kdm_directory->Bind (wxEVT_DIRPICKER_CHANGED, boost::bind (&DefaultsPage::kdm_directory_changed, this));
357 _isdcf_metadata_button->Bind (wxEVT_BUTTON, boost::bind (&DefaultsPage::edit_isdcf_metadata_clicked, this));
359 BOOST_FOREACH (Ratio const * i, Ratio::containers()) {
360 _container->Append (std_to_wx(i->container_nickname()));
363 _container->Bind (wxEVT_CHOICE, boost::bind (&DefaultsPage::container_changed, this));
365 BOOST_FOREACH (DCPContentType const * i, DCPContentType::all()) {
366 _dcp_content_type->Append (std_to_wx (i->pretty_name ()));
369 setup_audio_channels_choice (_dcp_audio_channels, 2);
371 _dcp_content_type->Bind (wxEVT_CHOICE, boost::bind (&DefaultsPage::dcp_content_type_changed, this));
372 _dcp_audio_channels->Bind (wxEVT_CHOICE, boost::bind (&DefaultsPage::dcp_audio_channels_changed, this));
374 _j2k_bandwidth->SetRange (50, 250);
375 _j2k_bandwidth->Bind (wxEVT_SPINCTRL, boost::bind (&DefaultsPage::j2k_bandwidth_changed, this));
377 _audio_delay->SetRange (-1000, 1000);
378 _audio_delay->Bind (wxEVT_SPINCTRL, boost::bind (&DefaultsPage::audio_delay_changed, this));
380 _standard->Append (_("SMPTE"));
381 _standard->Append (_("Interop"));
382 _standard->Bind (wxEVT_CHOICE, boost::bind (&DefaultsPage::standard_changed, this));
385 void config_changed ()
387 Config* config = Config::instance ();
389 vector<Ratio const *> containers = Ratio::containers ();
390 for (size_t i = 0; i < containers.size(); ++i) {
391 if (containers[i] == config->default_container ()) {
392 _container->SetSelection (i);
396 vector<DCPContentType const *> const ct = DCPContentType::all ();
397 for (size_t i = 0; i < ct.size(); ++i) {
398 if (ct[i] == config->default_dcp_content_type ()) {
399 _dcp_content_type->SetSelection (i);
403 checked_set (_still_length, config->default_still_length ());
404 _directory->SetPath (std_to_wx (config->default_directory_or (wx_to_std (wxStandardPaths::Get().GetDocumentsDir())).string ()));
405 _kdm_directory->SetPath (std_to_wx (config->default_kdm_directory_or (wx_to_std (wxStandardPaths::Get().GetDocumentsDir())).string ()));
406 checked_set (_j2k_bandwidth, config->default_j2k_bandwidth() / 1000000);
407 _j2k_bandwidth->SetRange (50, config->maximum_j2k_bandwidth() / 1000000);
408 checked_set (_dcp_audio_channels, locale_convert<string> (config->default_dcp_audio_channels()));
409 checked_set (_audio_delay, config->default_audio_delay ());
410 checked_set (_standard, config->default_interop() ? 1 : 0);
413 void j2k_bandwidth_changed ()
415 Config::instance()->set_default_j2k_bandwidth (_j2k_bandwidth->GetValue() * 1000000);
418 void audio_delay_changed ()
420 Config::instance()->set_default_audio_delay (_audio_delay->GetValue());
423 void dcp_audio_channels_changed ()
425 int const s = _dcp_audio_channels->GetSelection ();
426 if (s != wxNOT_FOUND) {
427 Config::instance()->set_default_dcp_audio_channels (
428 locale_convert<int> (string_client_data (_dcp_audio_channels->GetClientObject (s)))
433 void directory_changed ()
435 Config::instance()->set_default_directory (wx_to_std (_directory->GetPath ()));
438 void kdm_directory_changed ()
440 Config::instance()->set_default_kdm_directory (wx_to_std (_kdm_directory->GetPath ()));
443 void edit_isdcf_metadata_clicked ()
445 ISDCFMetadataDialog* d = new ISDCFMetadataDialog (_panel, Config::instance()->default_isdcf_metadata (), false);
447 Config::instance()->set_default_isdcf_metadata (d->isdcf_metadata ());
451 void still_length_changed ()
453 Config::instance()->set_default_still_length (_still_length->GetValue ());
456 void container_changed ()
458 vector<Ratio const *> ratio = Ratio::containers ();
459 Config::instance()->set_default_container (ratio[_container->GetSelection()]);
462 void dcp_content_type_changed ()
464 vector<DCPContentType const *> ct = DCPContentType::all ();
465 Config::instance()->set_default_dcp_content_type (ct[_dcp_content_type->GetSelection()]);
468 void standard_changed ()
470 Config::instance()->set_default_interop (_standard->GetSelection() == 1);
473 wxSpinCtrl* _j2k_bandwidth;
474 wxSpinCtrl* _audio_delay;
475 wxButton* _isdcf_metadata_button;
476 wxSpinCtrl* _still_length;
477 #ifdef DCPOMATIC_USE_OWN_PICKER
478 DirPickerCtrl* _directory;
479 DirPickerCtrl* _kdm_directory;
481 wxDirPickerCtrl* _directory;
482 wxDirPickerCtrl* _kdm_directory;
484 wxChoice* _container;
485 wxChoice* _dcp_content_type;
486 wxChoice* _dcp_audio_channels;
490 class EncodingServersPage : public StandardPage
493 EncodingServersPage (wxSize panel_size, int border)
494 : StandardPage (panel_size, border)
497 wxString GetName () const
503 wxBitmap GetLargeIcon () const
505 return wxBitmap ("servers", wxBITMAP_TYPE_PNG_RESOURCE);
512 _use_any_servers = new CheckBox (_panel, _("Search network for servers"));
513 _panel->GetSizer()->Add (_use_any_servers, 0, wxALL, _border);
515 vector<EditableListColumn> columns;
516 columns.push_back (EditableListColumn(wx_to_std(_("IP address / host name"))));
517 _servers_list = new EditableList<string, ServerDialog> (
520 boost::bind (&Config::servers, Config::instance()),
521 boost::bind (&Config::set_servers, Config::instance(), _1),
522 boost::bind (&EncodingServersPage::server_column, this, _1)
525 _panel->GetSizer()->Add (_servers_list, 1, wxEXPAND | wxALL, _border);
527 _use_any_servers->Bind (wxEVT_CHECKBOX, boost::bind (&EncodingServersPage::use_any_servers_changed, this));
530 void config_changed ()
532 checked_set (_use_any_servers, Config::instance()->use_any_servers ());
533 _servers_list->refresh ();
536 void use_any_servers_changed ()
538 Config::instance()->set_use_any_servers (_use_any_servers->GetValue ());
541 string server_column (string s)
546 wxCheckBox* _use_any_servers;
547 EditableList<string, ServerDialog>* _servers_list;
550 class TMSPage : public StandardPage
553 TMSPage (wxSize panel_size, int border)
554 : StandardPage (panel_size, border)
557 wxString GetName () const
563 wxBitmap GetLargeIcon () const
565 return wxBitmap ("tms", wxBITMAP_TYPE_PNG_RESOURCE);
572 _upload = new CheckBox (_panel, _("Upload DCP to TMS after creation"));
573 _panel->GetSizer()->Add (_upload, 0, wxALL | wxEXPAND, _border);
575 wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
576 table->AddGrowableCol (1, 1);
577 _panel->GetSizer()->Add (table, 1, wxALL | wxEXPAND, _border);
579 add_label_to_sizer (table, _panel, _("Protocol"), true);
580 _tms_protocol = new wxChoice (_panel, wxID_ANY);
581 table->Add (_tms_protocol, 1, wxEXPAND);
583 add_label_to_sizer (table, _panel, _("IP address"), true);
584 _tms_ip = new wxTextCtrl (_panel, wxID_ANY);
585 table->Add (_tms_ip, 1, wxEXPAND);
587 add_label_to_sizer (table, _panel, _("Target path"), true);
588 _tms_path = new wxTextCtrl (_panel, wxID_ANY);
589 table->Add (_tms_path, 1, wxEXPAND);
591 add_label_to_sizer (table, _panel, _("User name"), true);
592 _tms_user = new wxTextCtrl (_panel, wxID_ANY);
593 table->Add (_tms_user, 1, wxEXPAND);
595 add_label_to_sizer (table, _panel, _("Password"), true);
596 _tms_password = new PasswordEntry (_panel);
597 table->Add (_tms_password->get_panel(), 1, wxEXPAND);
599 _tms_protocol->Append (_("SCP (for AAM and Doremi)"));
600 _tms_protocol->Append (_("FTP (for Dolby)"));
602 _upload->Bind (wxEVT_CHECKBOX, boost::bind(&TMSPage::upload_changed, this));
603 _tms_protocol->Bind (wxEVT_CHOICE, boost::bind (&TMSPage::tms_protocol_changed, this));
604 _tms_ip->Bind (wxEVT_TEXT, boost::bind (&TMSPage::tms_ip_changed, this));
605 _tms_path->Bind (wxEVT_TEXT, boost::bind (&TMSPage::tms_path_changed, this));
606 _tms_user->Bind (wxEVT_TEXT, boost::bind (&TMSPage::tms_user_changed, this));
607 _tms_password->Changed.connect (boost::bind (&TMSPage::tms_password_changed, this));
610 void config_changed ()
612 Config* config = Config::instance ();
614 checked_set (_upload, config->upload_after_make_dcp());
615 checked_set (_tms_protocol, config->tms_protocol ());
616 checked_set (_tms_ip, config->tms_ip ());
617 checked_set (_tms_path, config->tms_path ());
618 checked_set (_tms_user, config->tms_user ());
619 checked_set (_tms_password, config->tms_password ());
622 void upload_changed ()
624 Config::instance()->set_upload_after_make_dcp (_upload->GetValue());
627 void tms_protocol_changed ()
629 Config::instance()->set_tms_protocol(static_cast<FileTransferProtocol>(_tms_protocol->GetSelection()));
632 void tms_ip_changed ()
634 Config::instance()->set_tms_ip (wx_to_std (_tms_ip->GetValue ()));
637 void tms_path_changed ()
639 Config::instance()->set_tms_path (wx_to_std (_tms_path->GetValue ()));
642 void tms_user_changed ()
644 Config::instance()->set_tms_user (wx_to_std (_tms_user->GetValue ()));
647 void tms_password_changed ()
649 Config::instance()->set_tms_password (_tms_password->get());
653 wxChoice* _tms_protocol;
655 wxTextCtrl* _tms_path;
656 wxTextCtrl* _tms_user;
657 PasswordEntry* _tms_password;
666 class EmailPage : public StandardPage
669 EmailPage (wxSize panel_size, int border)
670 : StandardPage (panel_size, border)
673 wxString GetName () const
679 wxBitmap GetLargeIcon () const
681 return wxBitmap ("email", wxBITMAP_TYPE_PNG_RESOURCE);
688 wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
689 table->AddGrowableCol (1, 1);
690 _panel->GetSizer()->Add (table, 1, wxEXPAND | wxALL, _border);
692 add_label_to_sizer (table, _panel, _("Outgoing mail server"), true);
694 wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL);
695 _server = new wxTextCtrl (_panel, wxID_ANY);
696 s->Add (_server, 1, wxEXPAND | wxALL);
697 add_label_to_sizer (s, _panel, _("port"), false);
698 _port = new wxSpinCtrl (_panel, wxID_ANY);
699 _port->SetRange (0, 65535);
701 add_label_to_sizer (s, _panel, _("protocol"), false);
702 _protocol = new wxChoice (_panel, wxID_ANY);
703 /* Make sure this matches the switches in config_changed and port_changed below */
704 _protocol->Append (_("Auto"));
705 _protocol->Append (_("Plain"));
706 _protocol->Append (_("STARTTLS"));
707 _protocol->Append (_("SSL"));
709 table->Add (s, 1, wxEXPAND | wxALL);
712 add_label_to_sizer (table, _panel, _("User name"), true);
713 _user = new wxTextCtrl (_panel, wxID_ANY);
714 table->Add (_user, 1, wxEXPAND | wxALL);
716 add_label_to_sizer (table, _panel, _("Password"), true);
717 _password = new PasswordEntry (_panel);
718 table->Add (_password->get_panel(), 1, wxEXPAND | wxALL);
720 _server->Bind (wxEVT_TEXT, boost::bind (&EmailPage::server_changed, this));
721 _port->Bind (wxEVT_SPINCTRL, boost::bind (&EmailPage::port_changed, this));
722 _protocol->Bind (wxEVT_CHOICE, boost::bind (&EmailPage::protocol_changed, this));
723 _user->Bind (wxEVT_TEXT, boost::bind (&EmailPage::user_changed, this));
724 _password->Changed.connect (boost::bind (&EmailPage::password_changed, this));
727 void config_changed ()
729 Config* config = Config::instance ();
731 checked_set (_server, config->mail_server ());
732 checked_set (_port, config->mail_port ());
733 switch (config->mail_protocol()) {
734 case EMAIL_PROTOCOL_AUTO:
735 checked_set (_protocol, 0);
737 case EMAIL_PROTOCOL_PLAIN:
738 checked_set (_protocol, 1);
740 case EMAIL_PROTOCOL_STARTTLS:
741 checked_set (_protocol, 2);
743 case EMAIL_PROTOCOL_SSL:
744 checked_set (_protocol, 3);
747 checked_set (_user, config->mail_user ());
748 checked_set (_password, config->mail_password());
751 void server_changed ()
753 Config::instance()->set_mail_server (wx_to_std (_server->GetValue ()));
758 Config::instance()->set_mail_port (_port->GetValue ());
761 void protocol_changed ()
763 switch (_protocol->GetSelection()) {
765 Config::instance()->set_mail_protocol(EMAIL_PROTOCOL_AUTO);
768 Config::instance()->set_mail_protocol(EMAIL_PROTOCOL_PLAIN);
771 Config::instance()->set_mail_protocol(EMAIL_PROTOCOL_STARTTLS);
774 Config::instance()->set_mail_protocol(EMAIL_PROTOCOL_SSL);
781 Config::instance()->set_mail_user (wx_to_std (_user->GetValue ()));
784 void password_changed ()
786 Config::instance()->set_mail_password(_password->get());
793 PasswordEntry* _password;
796 class KDMEmailPage : public StandardPage
800 KDMEmailPage (wxSize panel_size, int border)
802 /* We have to force both width and height of this one */
803 : StandardPage (wxSize (panel_size.GetWidth(), 128), border)
805 : StandardPage (panel_size, border)
809 wxString GetName () const
811 return _("KDM Email");
815 wxBitmap GetLargeIcon () const
817 return wxBitmap ("kdm_email", wxBITMAP_TYPE_PNG_RESOURCE);
824 wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
825 table->AddGrowableCol (1, 1);
826 _panel->GetSizer()->Add (table, 1, wxEXPAND | wxALL, _border);
828 add_label_to_sizer (table, _panel, _("Subject"), true);
829 _subject = new wxTextCtrl (_panel, wxID_ANY);
830 table->Add (_subject, 1, wxEXPAND | wxALL);
832 add_label_to_sizer (table, _panel, _("From address"), true);
833 _from = new wxTextCtrl (_panel, wxID_ANY);
834 table->Add (_from, 1, wxEXPAND | wxALL);
836 vector<EditableListColumn> columns;
837 columns.push_back (EditableListColumn(wx_to_std(_("Address"))));
838 add_label_to_sizer (table, _panel, _("CC addresses"), true);
839 _cc = new EditableList<string, EmailDialog> (
842 bind (&Config::kdm_cc, Config::instance()),
843 bind (&Config::set_kdm_cc, Config::instance(), _1),
846 table->Add (_cc, 1, wxEXPAND | wxALL);
848 add_label_to_sizer (table, _panel, _("BCC address"), true);
849 _bcc = new wxTextCtrl (_panel, wxID_ANY);
850 table->Add (_bcc, 1, wxEXPAND | wxALL);
852 _email = new wxTextCtrl (_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize (-1, 200), wxTE_MULTILINE);
853 _panel->GetSizer()->Add (_email, 0, wxEXPAND | wxALL, _border);
855 _reset_email = new Button (_panel, _("Reset to default subject and text"));
856 _panel->GetSizer()->Add (_reset_email, 0, wxEXPAND | wxALL, _border);
860 _subject->Bind (wxEVT_TEXT, boost::bind (&KDMEmailPage::kdm_subject_changed, this));
861 _from->Bind (wxEVT_TEXT, boost::bind (&KDMEmailPage::kdm_from_changed, this));
862 _bcc->Bind (wxEVT_TEXT, boost::bind (&KDMEmailPage::kdm_bcc_changed, this));
863 _email->Bind (wxEVT_TEXT, boost::bind (&KDMEmailPage::kdm_email_changed, this));
864 _reset_email->Bind (wxEVT_BUTTON, boost::bind (&KDMEmailPage::reset_email, this));
867 void config_changed ()
869 Config* config = Config::instance ();
871 checked_set (_subject, config->kdm_subject ());
872 checked_set (_from, config->kdm_from ());
873 checked_set (_bcc, config->kdm_bcc ());
874 checked_set (_email, Config::instance()->kdm_email ());
877 void kdm_subject_changed ()
879 Config::instance()->set_kdm_subject (wx_to_std (_subject->GetValue ()));
882 void kdm_from_changed ()
884 Config::instance()->set_kdm_from (wx_to_std (_from->GetValue ()));
887 void kdm_bcc_changed ()
889 Config::instance()->set_kdm_bcc (wx_to_std (_bcc->GetValue ()));
892 void kdm_email_changed ()
894 if (_email->GetValue().IsEmpty ()) {
895 /* Sometimes we get sent an erroneous notification that the email
896 is empty; I don't know why.
900 Config::instance()->set_kdm_email (wx_to_std (_email->GetValue ()));
905 Config::instance()->reset_kdm_email ();
906 checked_set (_email, Config::instance()->kdm_email ());
909 wxTextCtrl* _subject;
911 EditableList<string, EmailDialog>* _cc;
914 wxButton* _reset_email;
917 class NotificationsPage : public StandardPage
920 NotificationsPage (wxSize panel_size, int border)
922 /* We have to force both width and height of this one */
923 : StandardPage (wxSize (panel_size.GetWidth(), 128), border)
925 : StandardPage (panel_size, border)
929 wxString GetName () const
931 return _("Notifications");
935 wxBitmap GetLargeIcon () const
937 return wxBitmap ("notifications", wxBITMAP_TYPE_PNG_RESOURCE);
944 wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
945 table->AddGrowableCol (1, 1);
946 _panel->GetSizer()->Add (table, 1, wxEXPAND | wxALL, _border);
948 _enable_message_box = new CheckBox (_panel, _("Message box"));
949 table->Add (_enable_message_box, 1, wxEXPAND | wxALL);
950 table->AddSpacer (0);
952 _enable_email = new CheckBox (_panel, _("Email"));
953 table->Add (_enable_email, 1, wxEXPAND | wxALL);
954 table->AddSpacer (0);
956 add_label_to_sizer (table, _panel, _("Subject"), true);
957 _subject = new wxTextCtrl (_panel, wxID_ANY);
958 table->Add (_subject, 1, wxEXPAND | wxALL);
960 add_label_to_sizer (table, _panel, _("From address"), true);
961 _from = new wxTextCtrl (_panel, wxID_ANY);
962 table->Add (_from, 1, wxEXPAND | wxALL);
964 add_label_to_sizer (table, _panel, _("To address"), true);
965 _to = new wxTextCtrl (_panel, wxID_ANY);
966 table->Add (_to, 1, wxEXPAND | wxALL);
968 vector<EditableListColumn> columns;
969 columns.push_back (EditableListColumn(wx_to_std(_("Address"))));
970 add_label_to_sizer (table, _panel, _("CC addresses"), true);
971 _cc = new EditableList<string, EmailDialog> (
974 bind (&Config::notification_cc, Config::instance()),
975 bind (&Config::set_notification_cc, Config::instance(), _1),
978 table->Add (_cc, 1, wxEXPAND | wxALL);
980 add_label_to_sizer (table, _panel, _("BCC address"), true);
981 _bcc = new wxTextCtrl (_panel, wxID_ANY);
982 table->Add (_bcc, 1, wxEXPAND | wxALL);
984 _email = new wxTextCtrl (_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize (-1, 200), wxTE_MULTILINE);
985 _panel->GetSizer()->Add (_email, 0, wxEXPAND | wxALL, _border);
987 _reset_email = new Button (_panel, _("Reset to default subject and text"));
988 _panel->GetSizer()->Add (_reset_email, 0, wxEXPAND | wxALL, _border);
992 _enable_message_box->Bind (wxEVT_CHECKBOX, boost::bind (&NotificationsPage::type_changed, this, _enable_message_box, Config::MESSAGE_BOX));
993 _enable_email->Bind (wxEVT_CHECKBOX, boost::bind (&NotificationsPage::type_changed, this, _enable_email, Config::EMAIL));
995 _subject->Bind (wxEVT_TEXT, boost::bind (&NotificationsPage::notification_subject_changed, this));
996 _from->Bind (wxEVT_TEXT, boost::bind (&NotificationsPage::notification_from_changed, this));
997 _to->Bind (wxEVT_TEXT, boost::bind (&NotificationsPage::notification_to_changed, this));
998 _bcc->Bind (wxEVT_TEXT, boost::bind (&NotificationsPage::notification_bcc_changed, this));
999 _email->Bind (wxEVT_TEXT, boost::bind (&NotificationsPage::notification_email_changed, this));
1000 _reset_email->Bind (wxEVT_BUTTON, boost::bind (&NotificationsPage::reset_email, this));
1002 update_sensitivity ();
1005 void update_sensitivity ()
1007 bool const s = _enable_email->GetValue();
1008 _subject->Enable(s);
1014 _reset_email->Enable(s);
1017 void config_changed ()
1019 Config* config = Config::instance ();
1021 checked_set (_enable_message_box, config->notification(Config::MESSAGE_BOX));
1022 checked_set (_enable_email, config->notification(Config::EMAIL));
1023 checked_set (_subject, config->notification_subject ());
1024 checked_set (_from, config->notification_from ());
1025 checked_set (_to, config->notification_to ());
1026 checked_set (_bcc, config->notification_bcc ());
1027 checked_set (_email, Config::instance()->notification_email ());
1029 update_sensitivity ();
1032 void notification_subject_changed ()
1034 Config::instance()->set_notification_subject (wx_to_std (_subject->GetValue ()));
1037 void notification_from_changed ()
1039 Config::instance()->set_notification_from (wx_to_std (_from->GetValue ()));
1042 void notification_to_changed ()
1044 Config::instance()->set_notification_to (wx_to_std (_to->GetValue ()));
1047 void notification_bcc_changed ()
1049 Config::instance()->set_notification_bcc (wx_to_std (_bcc->GetValue ()));
1052 void notification_email_changed ()
1054 if (_email->GetValue().IsEmpty ()) {
1055 /* Sometimes we get sent an erroneous notification that the email
1056 is empty; I don't know why.
1060 Config::instance()->set_notification_email (wx_to_std (_email->GetValue ()));
1065 Config::instance()->reset_notification_email ();
1066 checked_set (_email, Config::instance()->notification_email ());
1069 void type_changed (wxCheckBox* b, Config::Notification n)
1071 Config::instance()->set_notification(n, b->GetValue());
1072 update_sensitivity ();
1075 wxCheckBox* _enable_message_box;
1076 wxCheckBox* _enable_email;
1078 wxTextCtrl* _subject;
1081 EditableList<string, EmailDialog>* _cc;
1084 wxButton* _reset_email;
1087 class CoverSheetPage : public StandardPage
1091 CoverSheetPage (wxSize panel_size, int border)
1092 #ifdef DCPOMATIC_OSX
1093 /* We have to force both width and height of this one */
1094 : StandardPage (wxSize (panel_size.GetWidth(), 128), border)
1096 : StandardPage (panel_size, border)
1100 wxString GetName () const
1102 return _("Cover Sheet");
1105 #ifdef DCPOMATIC_OSX
1106 wxBitmap GetLargeIcon () const
1108 return wxBitmap ("cover_sheet", wxBITMAP_TYPE_PNG_RESOURCE);
1115 _cover_sheet = new wxTextCtrl (_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize (-1, 200), wxTE_MULTILINE);
1116 _panel->GetSizer()->Add (_cover_sheet, 0, wxEXPAND | wxALL, _border);
1118 _reset_cover_sheet = new Button (_panel, _("Reset to default text"));
1119 _panel->GetSizer()->Add (_reset_cover_sheet, 0, wxEXPAND | wxALL, _border);
1121 _cover_sheet->Bind (wxEVT_TEXT, boost::bind (&CoverSheetPage::cover_sheet_changed, this));
1122 _reset_cover_sheet->Bind (wxEVT_BUTTON, boost::bind (&CoverSheetPage::reset_cover_sheet, this));
1125 void config_changed ()
1127 checked_set (_cover_sheet, Config::instance()->cover_sheet ());
1130 void cover_sheet_changed ()
1132 if (_cover_sheet->GetValue().IsEmpty ()) {
1133 /* Sometimes we get sent an erroneous notification that the cover sheet
1134 is empty; I don't know why.
1138 Config::instance()->set_cover_sheet (wx_to_std (_cover_sheet->GetValue ()));
1141 void reset_cover_sheet ()
1143 Config::instance()->reset_cover_sheet ();
1144 checked_set (_cover_sheet, Config::instance()->cover_sheet ());
1147 wxTextCtrl* _cover_sheet;
1148 wxButton* _reset_cover_sheet;
1152 class IdentifiersPage : public StandardPage
1155 IdentifiersPage (wxSize panel_size, int border)
1156 : StandardPage (panel_size, border)
1159 wxString GetName () const
1161 return _("Identifiers");
1164 #ifdef DCPOMATIC_OSX
1165 wxBitmap GetLargeIcon () const
1167 return wxBitmap ("identifiers", wxBITMAP_TYPE_PNG_RESOURCE);
1174 wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
1175 table->AddGrowableCol (1, 1);
1177 add_label_to_sizer (table, _panel, _("Issuer"), true);
1178 _issuer = new wxTextCtrl (_panel, wxID_ANY);
1179 _issuer->SetToolTip (_("This will be written to the DCP's XML files as the <Issuer>. If it is blank, a default value mentioning DCP-o-matic will be used."));
1180 table->Add (_issuer, 1, wxALL | wxEXPAND);
1182 add_label_to_sizer (table, _panel, _("Creator"), true);
1183 _creator = new wxTextCtrl (_panel, wxID_ANY);
1184 _creator->SetToolTip (_("This will be written to the DCP's XML files as the <Creator>. If it is blank, a default value mentioning DCP-o-matic will be used."));
1185 table->Add (_creator, 1, wxALL | wxEXPAND);
1187 add_label_to_sizer (table, _panel, _("Company name"), true);
1188 _company_name = new wxTextCtrl (_panel, wxID_ANY);
1189 _company_name->SetToolTip (_("This will be written to the DCP's MXF files as the 'company name'. If it is blank, a default value mentioning libdcp (an internal DCP-o-matic library) will be used."));
1190 table->Add (_company_name, 1, wxALL | wxEXPAND);
1192 add_label_to_sizer (table, _panel, _("Product name"), true);
1193 _product_name = new wxTextCtrl (_panel, wxID_ANY);
1194 _product_name->SetToolTip (_("This will be written to the DCP's MXF files as the 'product name'. If it is blank, a default value mentioning libdcp (an internal DCP-o-matic library) will be used."));
1195 table->Add (_product_name, 1, wxALL | wxEXPAND);
1197 add_label_to_sizer (table, _panel, _("Product version"), true);
1198 _product_version = new wxTextCtrl (_panel, wxID_ANY);
1199 _product_version->SetToolTip (_("This will be written to the DCP's MXF files as the 'product version'. If it is blank, a default value mentioning libdcp (an internal DCP-o-matic library) will be used."));
1200 table->Add (_product_version, 1, wxALL | wxEXPAND);
1202 add_label_to_sizer (table, _panel, _("JPEG2000 comment"), true);
1203 _j2k_comment = new wxTextCtrl (_panel, wxID_ANY);
1204 _j2k_comment->SetToolTip (_("This will be written to the DCP's JPEG2000 data as a comment. If it is blank, a default value mentioning libdcp (an internal DCP-o-matic library) will be used."));
1205 table->Add (_j2k_comment, 1, wxALL | wxEXPAND);
1207 _panel->GetSizer()->Add (table, 0, wxEXPAND | wxALL, _border);
1209 _issuer->Bind (wxEVT_TEXT, boost::bind(&IdentifiersPage::issuer_changed, this));
1210 _creator->Bind (wxEVT_TEXT, boost::bind(&IdentifiersPage::creator_changed, this));
1211 _company_name->Bind (wxEVT_TEXT, boost::bind(&IdentifiersPage::company_name_changed, this));
1212 _product_name->Bind (wxEVT_TEXT, boost::bind(&IdentifiersPage::product_name_changed, this));
1213 _product_version->Bind (wxEVT_TEXT, boost::bind(&IdentifiersPage::product_version_changed, this));
1214 _j2k_comment->Bind (wxEVT_TEXT, boost::bind(&IdentifiersPage::j2k_comment_changed, this));
1217 void config_changed ()
1219 Config* config = Config::instance ();
1220 checked_set (_issuer, config->dcp_issuer ());
1221 checked_set (_creator, config->dcp_creator ());
1222 checked_set (_company_name, config->dcp_company_name ());
1223 checked_set (_product_name, config->dcp_product_name ());
1224 checked_set (_product_version, config->dcp_product_version ());
1225 checked_set (_j2k_comment, config->dcp_j2k_comment ());
1228 void issuer_changed ()
1230 Config::instance()->set_dcp_issuer (wx_to_std (_issuer->GetValue ()));
1233 void creator_changed ()
1235 Config::instance()->set_dcp_creator (wx_to_std (_creator->GetValue ()));
1238 void company_name_changed ()
1240 Config::instance()->set_dcp_company_name (wx_to_std(_company_name->GetValue()));
1243 void product_name_changed ()
1245 Config::instance()->set_dcp_product_name (wx_to_std(_product_name->GetValue()));
1248 void product_version_changed ()
1250 Config::instance()->set_dcp_product_version (wx_to_std(_product_version->GetValue()));
1253 void j2k_comment_changed ()
1255 Config::instance()->set_dcp_j2k_comment (wx_to_std(_j2k_comment->GetValue()));
1258 wxTextCtrl* _issuer;
1259 wxTextCtrl* _creator;
1260 wxTextCtrl* _company_name;
1261 wxTextCtrl* _product_name;
1262 wxTextCtrl* _product_version;
1263 wxTextCtrl* _j2k_comment;
1267 /** @class AdvancedPage
1268 * @brief Advanced page of the preferences dialog.
1270 class AdvancedPage : public StockPage
1273 AdvancedPage (wxSize panel_size, int border)
1274 : StockPage (Kind_Advanced, panel_size, border)
1275 , _maximum_j2k_bandwidth (0)
1276 , _allow_any_dcp_frame_rate (0)
1277 , _allow_any_container (0)
1278 , _show_experimental_audio_processors (0)
1279 , _only_servers_encode (0)
1284 , _log_debug_threed (0)
1285 , _log_debug_encode (0)
1286 , _log_debug_email (0)
1290 void add_top_aligned_label_to_sizer (wxSizer* table, wxWindow* parent, wxString text)
1292 int flags = wxALIGN_TOP | wxTOP | wxLEFT;
1294 flags |= wxALIGN_RIGHT;
1297 wxStaticText* m = new StaticText (parent, text);
1298 table->Add (m, 0, flags, DCPOMATIC_SIZER_Y_GAP);
1303 wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
1304 table->AddGrowableCol (1, 1);
1305 _panel->GetSizer()->Add (table, 1, wxALL | wxEXPAND, _border);
1308 add_label_to_sizer (table, _panel, _("Maximum JPEG2000 bandwidth"), true);
1309 wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL);
1310 _maximum_j2k_bandwidth = new wxSpinCtrl (_panel);
1311 s->Add (_maximum_j2k_bandwidth, 1);
1312 add_label_to_sizer (s, _panel, _("Mbit/s"), false);
1316 add_label_to_sizer (table, _panel, _("Video display mode"), true);
1317 _video_display_mode = new wxChoice (_panel, wxID_ANY);
1318 table->Add (_video_display_mode);
1320 wxStaticText* restart = add_label_to_sizer (table, _panel, _("(restart DCP-o-matic to change display mode)"), false);
1321 wxFont font = restart->GetFont();
1322 font.SetStyle (wxFONTSTYLE_ITALIC);
1323 font.SetPointSize (font.GetPointSize() - 1);
1324 restart->SetFont (font);
1325 table->AddSpacer (0);
1327 _allow_any_dcp_frame_rate = new CheckBox (_panel, _("Allow any DCP frame rate"));
1328 table->Add (_allow_any_dcp_frame_rate, 1, wxEXPAND | wxALL);
1329 table->AddSpacer (0);
1331 _allow_any_container = new CheckBox (_panel, _("Allow full-frame and non-standard container ratios"));
1332 table->Add (_allow_any_container, 1, wxEXPAND | wxALL);
1333 table->AddSpacer (0);
1335 restart = add_label_to_sizer (table, _panel, _("(restart DCP-o-matic to see all ratios)"), false);
1336 restart->SetFont (font);
1337 table->AddSpacer (0);
1339 _show_experimental_audio_processors = new CheckBox (_panel, _("Show experimental audio processors"));
1340 table->Add (_show_experimental_audio_processors, 1, wxEXPAND | wxALL);
1341 table->AddSpacer (0);
1343 _only_servers_encode = new CheckBox (_panel, _("Only servers encode"));
1344 table->Add (_only_servers_encode, 1, wxEXPAND | wxALL);
1345 table->AddSpacer (0);
1348 add_label_to_sizer (table, _panel, _("Maximum number of frames to store per thread"), true);
1349 wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL);
1350 _frames_in_memory_multiplier = new wxSpinCtrl (_panel);
1351 s->Add (_frames_in_memory_multiplier, 1);
1356 add_top_aligned_label_to_sizer (table, _panel, _("DCP metadata filename format"));
1357 dcp::NameFormat::Map titles;
1358 titles['t'] = wx_to_std (_("type (cpl/pkl)"));
1359 dcp::NameFormat::Map examples;
1360 examples['t'] = "cpl";
1361 _dcp_metadata_filename_format = new NameFormatEditor (
1362 _panel, Config::instance()->dcp_metadata_filename_format(), titles, examples, "_eb1c112c-ca3c-4ae6-9263-c6714ff05d64.xml"
1364 table->Add (_dcp_metadata_filename_format->panel(), 1, wxEXPAND | wxALL);
1368 add_top_aligned_label_to_sizer (table, _panel, _("DCP asset filename format"));
1369 dcp::NameFormat::Map titles;
1370 titles['t'] = wx_to_std (_("type (j2c/pcm/sub)"));
1371 titles['r'] = wx_to_std (_("reel number"));
1372 titles['n'] = wx_to_std (_("number of reels"));
1373 titles['c'] = wx_to_std (_("content filename"));
1374 dcp::NameFormat::Map examples;
1375 examples['t'] = "j2c";
1376 examples['r'] = "1";
1377 examples['n'] = "4";
1378 examples['c'] = "myfile.mp4";
1379 _dcp_asset_filename_format = new NameFormatEditor (
1380 _panel, Config::instance()->dcp_asset_filename_format(), titles, examples, "_eb1c112c-ca3c-4ae6-9263-c6714ff05d64.mxf"
1382 table->Add (_dcp_asset_filename_format->panel(), 1, wxEXPAND | wxALL);
1386 add_top_aligned_label_to_sizer (table, _panel, _("Log"));
1387 wxBoxSizer* t = new wxBoxSizer (wxVERTICAL);
1388 _log_general = new CheckBox (_panel, _("General"));
1389 t->Add (_log_general, 1, wxEXPAND | wxALL);
1390 _log_warning = new CheckBox (_panel, _("Warnings"));
1391 t->Add (_log_warning, 1, wxEXPAND | wxALL);
1392 _log_error = new CheckBox (_panel, _("Errors"));
1393 t->Add (_log_error, 1, wxEXPAND | wxALL);
1394 /// TRANSLATORS: translate the word "Timing" here; do not include the "Config|" prefix
1395 _log_timing = new CheckBox (_panel, S_("Config|Timing"));
1396 t->Add (_log_timing, 1, wxEXPAND | wxALL);
1397 _log_debug_threed = new CheckBox (_panel, _("Debug: 3D"));
1398 t->Add (_log_debug_threed, 1, wxEXPAND | wxALL);
1399 _log_debug_encode = new CheckBox (_panel, _("Debug: encode"));
1400 t->Add (_log_debug_encode, 1, wxEXPAND | wxALL);
1401 _log_debug_email = new CheckBox (_panel, _("Debug: email sending"));
1402 t->Add (_log_debug_email, 1, wxEXPAND | wxALL);
1403 table->Add (t, 0, wxALL, 6);
1406 #ifdef DCPOMATIC_WINDOWS
1407 _win32_console = new CheckBox (_panel, _("Open console window"));
1408 table->Add (_win32_console, 1, wxEXPAND | wxALL);
1409 table->AddSpacer (0);
1412 _maximum_j2k_bandwidth->SetRange (1, 1000);
1413 _maximum_j2k_bandwidth->Bind (wxEVT_SPINCTRL, boost::bind (&AdvancedPage::maximum_j2k_bandwidth_changed, this));
1414 _video_display_mode->Append (_("Simple (safer)"));
1415 _video_display_mode->Append (_("OpenGL (faster)"));
1416 _video_display_mode->Bind (wxEVT_CHOICE, boost::bind(&AdvancedPage::video_display_mode_changed, this));
1417 _allow_any_dcp_frame_rate->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::allow_any_dcp_frame_rate_changed, this));
1418 _allow_any_container->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::allow_any_container_changed, this));
1419 _show_experimental_audio_processors->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::show_experimental_audio_processors_changed, this));
1420 _only_servers_encode->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::only_servers_encode_changed, this));
1421 _frames_in_memory_multiplier->Bind (wxEVT_SPINCTRL, boost::bind(&AdvancedPage::frames_in_memory_multiplier_changed, this));
1422 _dcp_metadata_filename_format->Changed.connect (boost::bind (&AdvancedPage::dcp_metadata_filename_format_changed, this));
1423 _dcp_asset_filename_format->Changed.connect (boost::bind (&AdvancedPage::dcp_asset_filename_format_changed, this));
1424 _log_general->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::log_changed, this));
1425 _log_warning->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::log_changed, this));
1426 _log_error->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::log_changed, this));
1427 _log_timing->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::log_changed, this));
1428 _log_debug_threed->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::log_changed, this));
1429 _log_debug_encode->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::log_changed, this));
1430 _log_debug_email->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::log_changed, this));
1431 #ifdef DCPOMATIC_WINDOWS
1432 _win32_console->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::win32_console_changed, this));
1436 void config_changed ()
1438 Config* config = Config::instance ();
1440 checked_set (_maximum_j2k_bandwidth, config->maximum_j2k_bandwidth() / 1000000);
1441 switch (config->video_view_type()) {
1442 case Config::VIDEO_VIEW_SIMPLE:
1443 checked_set (_video_display_mode, 0);
1445 case Config::VIDEO_VIEW_OPENGL:
1446 checked_set (_video_display_mode, 1);
1449 checked_set (_allow_any_dcp_frame_rate, config->allow_any_dcp_frame_rate ());
1450 checked_set (_allow_any_container, config->allow_any_container ());
1451 checked_set (_show_experimental_audio_processors, config->show_experimental_audio_processors ());
1452 checked_set (_only_servers_encode, config->only_servers_encode ());
1453 checked_set (_log_general, config->log_types() & LogEntry::TYPE_GENERAL);
1454 checked_set (_log_warning, config->log_types() & LogEntry::TYPE_WARNING);
1455 checked_set (_log_error, config->log_types() & LogEntry::TYPE_ERROR);
1456 checked_set (_log_timing, config->log_types() & LogEntry::TYPE_TIMING);
1457 checked_set (_log_debug_threed, config->log_types() & LogEntry::TYPE_DEBUG_THREED);
1458 checked_set (_log_debug_encode, config->log_types() & LogEntry::TYPE_DEBUG_ENCODE);
1459 checked_set (_log_debug_email, config->log_types() & LogEntry::TYPE_DEBUG_EMAIL);
1460 checked_set (_frames_in_memory_multiplier, config->frames_in_memory_multiplier());
1461 #ifdef DCPOMATIC_WINDOWS
1462 checked_set (_win32_console, config->win32_console());
1466 void maximum_j2k_bandwidth_changed ()
1468 Config::instance()->set_maximum_j2k_bandwidth (_maximum_j2k_bandwidth->GetValue() * 1000000);
1471 void video_display_mode_changed ()
1473 if (_video_display_mode->GetSelection() == 0) {
1474 Config::instance()->set_video_view_type (Config::VIDEO_VIEW_SIMPLE);
1476 Config::instance()->set_video_view_type (Config::VIDEO_VIEW_OPENGL);
1480 void frames_in_memory_multiplier_changed ()
1482 Config::instance()->set_frames_in_memory_multiplier (_frames_in_memory_multiplier->GetValue());
1485 void allow_any_dcp_frame_rate_changed ()
1487 Config::instance()->set_allow_any_dcp_frame_rate (_allow_any_dcp_frame_rate->GetValue ());
1490 void allow_any_container_changed ()
1492 Config::instance()->set_allow_any_container (_allow_any_container->GetValue ());
1495 void show_experimental_audio_processors_changed ()
1497 Config::instance()->set_show_experimental_audio_processors (_show_experimental_audio_processors->GetValue ());
1500 void only_servers_encode_changed ()
1502 Config::instance()->set_only_servers_encode (_only_servers_encode->GetValue ());
1505 void dcp_metadata_filename_format_changed ()
1507 Config::instance()->set_dcp_metadata_filename_format (_dcp_metadata_filename_format->get ());
1510 void dcp_asset_filename_format_changed ()
1512 Config::instance()->set_dcp_asset_filename_format (_dcp_asset_filename_format->get ());
1518 if (_log_general->GetValue ()) {
1519 types |= LogEntry::TYPE_GENERAL;
1521 if (_log_warning->GetValue ()) {
1522 types |= LogEntry::TYPE_WARNING;
1524 if (_log_error->GetValue ()) {
1525 types |= LogEntry::TYPE_ERROR;
1527 if (_log_timing->GetValue ()) {
1528 types |= LogEntry::TYPE_TIMING;
1530 if (_log_debug_threed->GetValue ()) {
1531 types |= LogEntry::TYPE_DEBUG_THREED;
1533 if (_log_debug_encode->GetValue ()) {
1534 types |= LogEntry::TYPE_DEBUG_ENCODE;
1536 if (_log_debug_email->GetValue ()) {
1537 types |= LogEntry::TYPE_DEBUG_EMAIL;
1539 Config::instance()->set_log_types (types);
1542 #ifdef DCPOMATIC_WINDOWS
1543 void win32_console_changed ()
1545 Config::instance()->set_win32_console (_win32_console->GetValue ());
1549 wxSpinCtrl* _maximum_j2k_bandwidth;
1550 wxChoice* _video_display_mode;
1551 wxSpinCtrl* _frames_in_memory_multiplier;
1552 wxCheckBox* _allow_any_dcp_frame_rate;
1553 wxCheckBox* _allow_any_container;
1554 wxCheckBox* _show_experimental_audio_processors;
1555 wxCheckBox* _only_servers_encode;
1556 NameFormatEditor* _dcp_metadata_filename_format;
1557 NameFormatEditor* _dcp_asset_filename_format;
1558 wxCheckBox* _log_general;
1559 wxCheckBox* _log_warning;
1560 wxCheckBox* _log_error;
1561 wxCheckBox* _log_timing;
1562 wxCheckBox* _log_debug_threed;
1563 wxCheckBox* _log_debug_encode;
1564 wxCheckBox* _log_debug_email;
1565 #ifdef DCPOMATIC_WINDOWS
1566 wxCheckBox* _win32_console;
1570 wxPreferencesEditor*
1571 create_full_config_dialog ()
1573 wxPreferencesEditor* e = new wxPreferencesEditor ();
1575 #ifdef DCPOMATIC_OSX
1576 /* Width that we force some of the config panels to be on OSX so that
1577 the containing window doesn't shrink too much when we select those panels.
1578 This is obviously an unpleasant hack.
1580 wxSize ps = wxSize (700, -1);
1581 int const border = 16;
1583 wxSize ps = wxSize (-1, -1);
1584 int const border = 8;
1587 e->AddPage (new FullGeneralPage (ps, border));
1588 e->AddPage (new SoundPage (ps, border));
1589 e->AddPage (new DefaultsPage (ps, border));
1590 e->AddPage (new EncodingServersPage (ps, border));
1591 e->AddPage (new KeysPage (ps, border));
1592 e->AddPage (new TMSPage (ps, border));
1593 e->AddPage (new EmailPage (ps, border));
1594 e->AddPage (new KDMEmailPage (ps, border));
1595 e->AddPage (new NotificationsPage (ps, border));
1596 e->AddPage (new CoverSheetPage (ps, border));
1597 e->AddPage (new IdentifiersPage (ps, border));
1598 e->AddPage (new AdvancedPage (ps, border));