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 "lib/config.h"
40 #include "lib/ratio.h"
41 #include "lib/filter.h"
42 #include "lib/dcp_content_type.h"
45 #include "lib/cross.h"
46 #include "lib/exceptions.h"
47 #include <dcp/locale_convert.h>
48 #include <dcp/exceptions.h>
49 #include <dcp/certificate_chain.h>
50 #include <wx/stdpaths.h>
51 #include <wx/preferences.h>
52 #include <wx/spinctrl.h>
53 #include <wx/filepicker.h>
55 #include <boost/filesystem.hpp>
56 #include <boost/foreach.hpp>
67 using boost::shared_ptr;
68 using boost::function;
69 using boost::optional;
70 using dcp::locale_convert;
72 class FullGeneralPage : public GeneralPage
75 FullGeneralPage (wxSize panel_size, int border)
76 : GeneralPage (panel_size, border)
82 wxGridBagSizer* table = new wxGridBagSizer (DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
83 _panel->GetSizer()->Add (table, 1, wxALL | wxEXPAND, _border);
86 add_language_controls (table, r);
88 add_label_to_sizer (table, _panel, _("Interface complexity"), true, wxGBPosition(r, 0));
89 _interface_complexity = new wxChoice (_panel, wxID_ANY);
90 table->Add (_interface_complexity, wxGBPosition (r, 1));
93 add_label_to_sizer (table, _panel, _("Number of threads DCP-o-matic should use"), true, wxGBPosition (r, 0));
94 _master_encoding_threads = new wxSpinCtrl (_panel);
95 table->Add (_master_encoding_threads, wxGBPosition (r, 1));
98 add_label_to_sizer (table, _panel, _("Number of threads DCP-o-matic encode server should use"), true, wxGBPosition (r, 0));
99 _server_encoding_threads = new wxSpinCtrl (_panel);
100 table->Add (_server_encoding_threads, wxGBPosition (r, 1));
103 add_label_to_sizer (table, _panel, _("Configuration file"), true, wxGBPosition (r, 0));
104 _config_file = new FilePickerCtrl (_panel, _("Select configuration file"), "*.xml", true);
105 table->Add (_config_file, wxGBPosition (r, 1));
108 add_label_to_sizer (table, _panel, _("Cinema and screen database file"), true, wxGBPosition (r, 0));
109 _cinemas_file = new FilePickerCtrl (_panel, _("Select cinema and screen database file"), "*.xml", true);
110 table->Add (_cinemas_file, wxGBPosition (r, 1));
111 wxButton* export_cinemas = new wxButton (_panel, wxID_ANY, _("Export..."));
112 table->Add (export_cinemas, wxGBPosition (r, 2));
115 add_play_sound_controls (table, r);
117 #ifdef DCPOMATIC_HAVE_EBUR128_PATCHED_FFMPEG
118 _analyse_ebur128 = new wxCheckBox (_panel, wxID_ANY, _("Find integrated loudness, true peak and loudness range when analysing audio"));
119 table->Add (_analyse_ebur128, wxGBPosition (r, 0), wxGBSpan (1, 2));
123 _automatic_audio_analysis = new wxCheckBox (_panel, wxID_ANY, _("Automatically analyse content audio"));
124 table->Add (_automatic_audio_analysis, wxGBPosition (r, 0), wxGBSpan (1, 2));
127 add_update_controls (table, r);
129 wxFlexGridSizer* bottom_table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
130 bottom_table->AddGrowableCol (1, 1);
132 add_label_to_sizer (bottom_table, _panel, _("Issuer"), true);
133 _issuer = new wxTextCtrl (_panel, wxID_ANY);
134 bottom_table->Add (_issuer, 1, wxALL | wxEXPAND);
136 add_label_to_sizer (bottom_table, _panel, _("Creator"), true);
137 _creator = new wxTextCtrl (_panel, wxID_ANY);
138 bottom_table->Add (_creator, 1, wxALL | wxEXPAND);
140 table->Add (bottom_table, wxGBPosition (r, 0), wxGBSpan (2, 2), wxEXPAND);
143 _config_file->Bind (wxEVT_FILEPICKER_CHANGED, boost::bind (&FullGeneralPage::config_file_changed, this));
144 _cinemas_file->Bind (wxEVT_FILEPICKER_CHANGED, boost::bind (&FullGeneralPage::cinemas_file_changed, this));
146 _interface_complexity->Append (_("Simple"));
147 _interface_complexity->Append (_("Full"));
148 _interface_complexity->Bind (wxEVT_CHOICE, boost::bind(&FullGeneralPage::interface_complexity_changed, this));
150 _master_encoding_threads->SetRange (1, 128);
151 _master_encoding_threads->Bind (wxEVT_SPINCTRL, boost::bind (&FullGeneralPage::master_encoding_threads_changed, this));
152 _server_encoding_threads->SetRange (1, 128);
153 _server_encoding_threads->Bind (wxEVT_SPINCTRL, boost::bind (&FullGeneralPage::server_encoding_threads_changed, this));
154 export_cinemas->Bind (wxEVT_BUTTON, boost::bind (&FullGeneralPage::export_cinemas_file, this));
156 #ifdef DCPOMATIC_HAVE_EBUR128_PATCHED_FFMPEG
157 _analyse_ebur128->Bind (wxEVT_CHECKBOX, boost::bind (&FullGeneralPage::analyse_ebur128_changed, this));
159 _automatic_audio_analysis->Bind (wxEVT_CHECKBOX, boost::bind (&FullGeneralPage::automatic_audio_analysis_changed, this));
161 _issuer->Bind (wxEVT_TEXT, boost::bind (&FullGeneralPage::issuer_changed, this));
162 _creator->Bind (wxEVT_TEXT, boost::bind (&FullGeneralPage::creator_changed, this));
165 void config_changed ()
167 Config* config = Config::instance ();
169 switch (config->interface_complexity()) {
170 case Config::INTERFACE_SIMPLE:
171 checked_set (_interface_complexity, 0);
173 case Config::INTERFACE_FULL:
174 checked_set (_interface_complexity, 1);
177 checked_set (_master_encoding_threads, config->master_encoding_threads ());
178 checked_set (_server_encoding_threads, config->server_encoding_threads ());
179 #ifdef DCPOMATIC_HAVE_EBUR128_PATCHED_FFMPEG
180 checked_set (_analyse_ebur128, config->analyse_ebur128 ());
182 checked_set (_automatic_audio_analysis, config->automatic_audio_analysis ());
183 checked_set (_issuer, config->dcp_issuer ());
184 checked_set (_creator, config->dcp_creator ());
185 checked_set (_config_file, config->config_file());
186 checked_set (_cinemas_file, config->cinemas_file());
188 GeneralPage::config_changed ();
191 void export_cinemas_file ()
193 wxFileDialog* d = new wxFileDialog (
194 _panel, _("Select Cinemas File"), wxEmptyString, wxEmptyString, wxT ("XML files (*.xml)|*.xml"),
195 wxFD_SAVE | wxFD_OVERWRITE_PROMPT
198 if (d->ShowModal () == wxID_OK) {
199 boost::filesystem::copy_file (Config::instance()->cinemas_file(), path_from_file_dialog (d, "xml"));
204 void interface_complexity_changed ()
206 if (_interface_complexity->GetSelection() == 0) {
207 Config::instance()->set_interface_complexity (Config::INTERFACE_SIMPLE);
209 Config::instance()->set_interface_complexity (Config::INTERFACE_FULL);
214 #ifdef DCPOMATIC_HAVE_EBUR128_PATCHED_FFMPEG
215 void analyse_ebur128_changed ()
217 Config::instance()->set_analyse_ebur128 (_analyse_ebur128->GetValue ());
221 void automatic_audio_analysis_changed ()
223 Config::instance()->set_automatic_audio_analysis (_automatic_audio_analysis->GetValue ());
226 void master_encoding_threads_changed ()
228 Config::instance()->set_master_encoding_threads (_master_encoding_threads->GetValue ());
231 void server_encoding_threads_changed ()
233 Config::instance()->set_server_encoding_threads (_server_encoding_threads->GetValue ());
236 void issuer_changed ()
238 Config::instance()->set_dcp_issuer (wx_to_std (_issuer->GetValue ()));
241 void creator_changed ()
243 Config::instance()->set_dcp_creator (wx_to_std (_creator->GetValue ()));
246 void config_file_changed ()
248 Config* config = Config::instance();
249 boost::filesystem::path new_file = wx_to_std(_config_file->GetPath());
250 if (new_file == config->config_file()) {
253 bool copy_and_link = true;
254 if (boost::filesystem::exists(new_file)) {
255 ConfigMoveDialog* d = new ConfigMoveDialog (_panel, new_file);
256 if (d->ShowModal() == wxID_OK) {
257 copy_and_link = false;
264 if (new_file != config->config_file()) {
265 config->copy_and_link (new_file);
268 config->link (new_file);
272 void cinemas_file_changed ()
274 Config::instance()->set_cinemas_file (wx_to_std (_cinemas_file->GetPath ()));
277 wxChoice* _interface_complexity;
278 wxSpinCtrl* _master_encoding_threads;
279 wxSpinCtrl* _server_encoding_threads;
280 FilePickerCtrl* _config_file;
281 FilePickerCtrl* _cinemas_file;
282 #ifdef DCPOMATIC_HAVE_EBUR128_PATCHED_FFMPEG
283 wxCheckBox* _analyse_ebur128;
285 wxCheckBox* _automatic_audio_analysis;
287 wxTextCtrl* _creator;
290 class DefaultsPage : public StandardPage
293 DefaultsPage (wxSize panel_size, int border)
294 : StandardPage (panel_size, border)
297 wxString GetName () const
299 return _("Defaults");
303 wxBitmap GetLargeIcon () const
305 return wxBitmap ("defaults", wxBITMAP_TYPE_PNG_RESOURCE);
312 wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
313 table->AddGrowableCol (1, 1);
314 _panel->GetSizer()->Add (table, 1, wxALL | wxEXPAND, _border);
317 add_label_to_sizer (table, _panel, _("Default duration of still images"), true);
318 wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL);
319 _still_length = new wxSpinCtrl (_panel);
320 s->Add (_still_length);
321 add_label_to_sizer (s, _panel, _("s"), false);
325 add_label_to_sizer (table, _panel, _("Default directory for new films"), true);
326 #ifdef DCPOMATIC_USE_OWN_PICKER
327 _directory = new DirPickerCtrl (_panel);
329 _directory = new wxDirPickerCtrl (_panel, wxDD_DIR_MUST_EXIST);
331 table->Add (_directory, 1, wxEXPAND);
333 add_label_to_sizer (table, _panel, _("Default ISDCF name details"), true);
334 _isdcf_metadata_button = new wxButton (_panel, wxID_ANY, _("Edit..."));
335 table->Add (_isdcf_metadata_button);
337 add_label_to_sizer (table, _panel, _("Default container"), true);
338 _container = new wxChoice (_panel, wxID_ANY);
339 table->Add (_container);
341 add_label_to_sizer (table, _panel, _("Default scale-to"), true);
342 _scale_to = new wxChoice (_panel, wxID_ANY);
343 table->Add (_scale_to);
345 add_label_to_sizer (table, _panel, _("Default content type"), true);
346 _dcp_content_type = new wxChoice (_panel, wxID_ANY);
347 table->Add (_dcp_content_type);
349 add_label_to_sizer (table, _panel, _("Default DCP audio channels"), true);
350 _dcp_audio_channels = new wxChoice (_panel, wxID_ANY);
351 table->Add (_dcp_audio_channels);
354 add_label_to_sizer (table, _panel, _("Default JPEG2000 bandwidth"), true);
355 wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL);
356 _j2k_bandwidth = new wxSpinCtrl (_panel);
357 s->Add (_j2k_bandwidth);
358 add_label_to_sizer (s, _panel, _("Mbit/s"), false);
363 add_label_to_sizer (table, _panel, _("Default audio delay"), true);
364 wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL);
365 _audio_delay = new wxSpinCtrl (_panel);
366 s->Add (_audio_delay);
367 add_label_to_sizer (s, _panel, _("ms"), false);
371 add_label_to_sizer (table, _panel, _("Default standard"), true);
372 _standard = new wxChoice (_panel, wxID_ANY);
373 table->Add (_standard);
375 add_label_to_sizer (table, _panel, _("Default KDM directory"), true);
376 #ifdef DCPOMATIC_USE_OWN_PICKER
377 _kdm_directory = new DirPickerCtrl (_panel);
379 _kdm_directory = new wxDirPickerCtrl (_panel, wxDD_DIR_MUST_EXIST);
382 table->Add (_kdm_directory, 1, wxEXPAND);
384 _upload_after_make_dcp = new wxCheckBox (_panel, wxID_ANY, _("Default to enabling upload of DCP to TMS"));
385 table->Add (_upload_after_make_dcp, 1, wxEXPAND);
387 _still_length->SetRange (1, 3600);
388 _still_length->Bind (wxEVT_SPINCTRL, boost::bind (&DefaultsPage::still_length_changed, this));
390 _directory->Bind (wxEVT_DIRPICKER_CHANGED, boost::bind (&DefaultsPage::directory_changed, this));
391 _kdm_directory->Bind (wxEVT_DIRPICKER_CHANGED, boost::bind (&DefaultsPage::kdm_directory_changed, this));
393 _isdcf_metadata_button->Bind (wxEVT_BUTTON, boost::bind (&DefaultsPage::edit_isdcf_metadata_clicked, this));
395 BOOST_FOREACH (Ratio const * i, Ratio::containers()) {
396 _container->Append (std_to_wx(i->container_nickname()));
399 _container->Bind (wxEVT_CHOICE, boost::bind (&DefaultsPage::container_changed, this));
401 _scale_to->Append (_("Guess from content"));
403 BOOST_FOREACH (Ratio const * i, Ratio::all()) {
404 _scale_to->Append (std_to_wx(i->image_nickname()));
407 _scale_to->Bind (wxEVT_CHOICE, boost::bind (&DefaultsPage::scale_to_changed, this));
409 BOOST_FOREACH (DCPContentType const * i, DCPContentType::all()) {
410 _dcp_content_type->Append (std_to_wx (i->pretty_name ()));
413 setup_audio_channels_choice (_dcp_audio_channels, 2);
415 _dcp_content_type->Bind (wxEVT_CHOICE, boost::bind (&DefaultsPage::dcp_content_type_changed, this));
416 _dcp_audio_channels->Bind (wxEVT_CHOICE, boost::bind (&DefaultsPage::dcp_audio_channels_changed, this));
418 _j2k_bandwidth->SetRange (50, 250);
419 _j2k_bandwidth->Bind (wxEVT_SPINCTRL, boost::bind (&DefaultsPage::j2k_bandwidth_changed, this));
421 _audio_delay->SetRange (-1000, 1000);
422 _audio_delay->Bind (wxEVT_SPINCTRL, boost::bind (&DefaultsPage::audio_delay_changed, this));
424 _standard->Append (_("SMPTE"));
425 _standard->Append (_("Interop"));
426 _standard->Bind (wxEVT_CHOICE, boost::bind (&DefaultsPage::standard_changed, this));
428 _upload_after_make_dcp->Bind (wxEVT_CHECKBOX, boost::bind (&DefaultsPage::upload_after_make_dcp_changed, this));
431 void config_changed ()
433 Config* config = Config::instance ();
435 vector<Ratio const *> containers = Ratio::containers ();
436 for (size_t i = 0; i < containers.size(); ++i) {
437 if (containers[i] == config->default_container ()) {
438 _container->SetSelection (i);
442 vector<Ratio const *> ratios = Ratio::all ();
443 for (size_t i = 0; i < ratios.size(); ++i) {
444 if (ratios[i] == config->default_scale_to ()) {
445 _scale_to->SetSelection (i + 1);
449 if (!config->default_scale_to()) {
450 _scale_to->SetSelection (0);
453 vector<DCPContentType const *> const ct = DCPContentType::all ();
454 for (size_t i = 0; i < ct.size(); ++i) {
455 if (ct[i] == config->default_dcp_content_type ()) {
456 _dcp_content_type->SetSelection (i);
460 checked_set (_still_length, config->default_still_length ());
461 _directory->SetPath (std_to_wx (config->default_directory_or (wx_to_std (wxStandardPaths::Get().GetDocumentsDir())).string ()));
462 _kdm_directory->SetPath (std_to_wx (config->default_kdm_directory_or (wx_to_std (wxStandardPaths::Get().GetDocumentsDir())).string ()));
463 checked_set (_j2k_bandwidth, config->default_j2k_bandwidth() / 1000000);
464 _j2k_bandwidth->SetRange (50, config->maximum_j2k_bandwidth() / 1000000);
465 checked_set (_dcp_audio_channels, locale_convert<string> (config->default_dcp_audio_channels()));
466 checked_set (_audio_delay, config->default_audio_delay ());
467 checked_set (_standard, config->default_interop() ? 1 : 0);
468 checked_set (_upload_after_make_dcp, config->default_upload_after_make_dcp());
471 void j2k_bandwidth_changed ()
473 Config::instance()->set_default_j2k_bandwidth (_j2k_bandwidth->GetValue() * 1000000);
476 void audio_delay_changed ()
478 Config::instance()->set_default_audio_delay (_audio_delay->GetValue());
481 void dcp_audio_channels_changed ()
483 int const s = _dcp_audio_channels->GetSelection ();
484 if (s != wxNOT_FOUND) {
485 Config::instance()->set_default_dcp_audio_channels (
486 locale_convert<int> (string_client_data (_dcp_audio_channels->GetClientObject (s)))
491 void directory_changed ()
493 Config::instance()->set_default_directory (wx_to_std (_directory->GetPath ()));
496 void kdm_directory_changed ()
498 Config::instance()->set_default_kdm_directory (wx_to_std (_kdm_directory->GetPath ()));
501 void edit_isdcf_metadata_clicked ()
503 ISDCFMetadataDialog* d = new ISDCFMetadataDialog (_panel, Config::instance()->default_isdcf_metadata (), false);
505 Config::instance()->set_default_isdcf_metadata (d->isdcf_metadata ());
509 void still_length_changed ()
511 Config::instance()->set_default_still_length (_still_length->GetValue ());
514 void container_changed ()
516 vector<Ratio const *> ratio = Ratio::containers ();
517 Config::instance()->set_default_container (ratio[_container->GetSelection()]);
520 void scale_to_changed ()
522 int const s = _scale_to->GetSelection ();
524 Config::instance()->set_default_scale_to (0);
526 vector<Ratio const *> ratio = Ratio::all ();
527 Config::instance()->set_default_scale_to (ratio[s - 1]);
531 void dcp_content_type_changed ()
533 vector<DCPContentType const *> ct = DCPContentType::all ();
534 Config::instance()->set_default_dcp_content_type (ct[_dcp_content_type->GetSelection()]);
537 void standard_changed ()
539 Config::instance()->set_default_interop (_standard->GetSelection() == 1);
542 void upload_after_make_dcp_changed ()
544 Config::instance()->set_default_upload_after_make_dcp (_upload_after_make_dcp->GetValue ());
547 wxSpinCtrl* _j2k_bandwidth;
548 wxSpinCtrl* _audio_delay;
549 wxButton* _isdcf_metadata_button;
550 wxSpinCtrl* _still_length;
551 #ifdef DCPOMATIC_USE_OWN_PICKER
552 DirPickerCtrl* _directory;
553 DirPickerCtrl* _kdm_directory;
555 wxDirPickerCtrl* _directory;
556 wxDirPickerCtrl* _kdm_directory;
558 wxChoice* _container;
560 wxChoice* _dcp_content_type;
561 wxChoice* _dcp_audio_channels;
563 wxCheckBox* _upload_after_make_dcp;
566 class EncodingServersPage : public StandardPage
569 EncodingServersPage (wxSize panel_size, int border)
570 : StandardPage (panel_size, border)
573 wxString GetName () const
579 wxBitmap GetLargeIcon () const
581 return wxBitmap ("servers", wxBITMAP_TYPE_PNG_RESOURCE);
588 _use_any_servers = new wxCheckBox (_panel, wxID_ANY, _("Search network for servers"));
589 _panel->GetSizer()->Add (_use_any_servers, 0, wxALL, _border);
591 vector<string> columns;
592 columns.push_back (wx_to_std (_("IP address / host name")));
593 _servers_list = new EditableList<string, ServerDialog> (
596 boost::bind (&Config::servers, Config::instance()),
597 boost::bind (&Config::set_servers, Config::instance(), _1),
598 boost::bind (&EncodingServersPage::server_column, this, _1)
601 _panel->GetSizer()->Add (_servers_list, 1, wxEXPAND | wxALL, _border);
603 _use_any_servers->Bind (wxEVT_CHECKBOX, boost::bind (&EncodingServersPage::use_any_servers_changed, this));
606 void config_changed ()
608 checked_set (_use_any_servers, Config::instance()->use_any_servers ());
609 _servers_list->refresh ();
612 void use_any_servers_changed ()
614 Config::instance()->set_use_any_servers (_use_any_servers->GetValue ());
617 string server_column (string s)
622 wxCheckBox* _use_any_servers;
623 EditableList<string, ServerDialog>* _servers_list;
626 class TMSPage : public StandardPage
629 TMSPage (wxSize panel_size, int border)
630 : StandardPage (panel_size, border)
633 wxString GetName () const
639 wxBitmap GetLargeIcon () const
641 return wxBitmap ("tms", wxBITMAP_TYPE_PNG_RESOURCE);
648 wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
649 table->AddGrowableCol (1, 1);
650 _panel->GetSizer()->Add (table, 1, wxALL | wxEXPAND, _border);
652 add_label_to_sizer (table, _panel, _("Protocol"), true);
653 _tms_protocol = new wxChoice (_panel, wxID_ANY);
654 table->Add (_tms_protocol, 1, wxEXPAND);
656 add_label_to_sizer (table, _panel, _("IP address"), true);
657 _tms_ip = new wxTextCtrl (_panel, wxID_ANY);
658 table->Add (_tms_ip, 1, wxEXPAND);
660 add_label_to_sizer (table, _panel, _("Target path"), true);
661 _tms_path = new wxTextCtrl (_panel, wxID_ANY);
662 table->Add (_tms_path, 1, wxEXPAND);
664 add_label_to_sizer (table, _panel, _("User name"), true);
665 _tms_user = new wxTextCtrl (_panel, wxID_ANY);
666 table->Add (_tms_user, 1, wxEXPAND);
668 add_label_to_sizer (table, _panel, _("Password"), true);
669 _tms_password = new wxTextCtrl (_panel, wxID_ANY);
670 table->Add (_tms_password, 1, wxEXPAND);
672 _tms_protocol->Append (_("SCP (for AAM and Doremi)"));
673 _tms_protocol->Append (_("FTP (for Dolby)"));
675 _tms_protocol->Bind (wxEVT_CHOICE, boost::bind (&TMSPage::tms_protocol_changed, this));
676 _tms_ip->Bind (wxEVT_TEXT, boost::bind (&TMSPage::tms_ip_changed, this));
677 _tms_path->Bind (wxEVT_TEXT, boost::bind (&TMSPage::tms_path_changed, this));
678 _tms_user->Bind (wxEVT_TEXT, boost::bind (&TMSPage::tms_user_changed, this));
679 _tms_password->Bind (wxEVT_TEXT, boost::bind (&TMSPage::tms_password_changed, this));
682 void config_changed ()
684 Config* config = Config::instance ();
686 checked_set (_tms_protocol, config->tms_protocol ());
687 checked_set (_tms_ip, config->tms_ip ());
688 checked_set (_tms_path, config->tms_path ());
689 checked_set (_tms_user, config->tms_user ());
690 checked_set (_tms_password, config->tms_password ());
693 void tms_protocol_changed ()
695 Config::instance()->set_tms_protocol (static_cast<Protocol> (_tms_protocol->GetSelection ()));
698 void tms_ip_changed ()
700 Config::instance()->set_tms_ip (wx_to_std (_tms_ip->GetValue ()));
703 void tms_path_changed ()
705 Config::instance()->set_tms_path (wx_to_std (_tms_path->GetValue ()));
708 void tms_user_changed ()
710 Config::instance()->set_tms_user (wx_to_std (_tms_user->GetValue ()));
713 void tms_password_changed ()
715 Config::instance()->set_tms_password (wx_to_std (_tms_password->GetValue ()));
718 wxChoice* _tms_protocol;
720 wxTextCtrl* _tms_path;
721 wxTextCtrl* _tms_user;
722 wxTextCtrl* _tms_password;
731 class EmailPage : public StandardPage
734 EmailPage (wxSize panel_size, int border)
735 : StandardPage (panel_size, border)
738 wxString GetName () const
744 wxBitmap GetLargeIcon () const
746 return wxBitmap ("email", wxBITMAP_TYPE_PNG_RESOURCE);
753 wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
754 table->AddGrowableCol (1, 1);
755 _panel->GetSizer()->Add (table, 1, wxEXPAND | wxALL, _border);
757 add_label_to_sizer (table, _panel, _("Outgoing mail server"), true);
759 wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL);
760 _server = new wxTextCtrl (_panel, wxID_ANY);
761 s->Add (_server, 1, wxEXPAND | wxALL);
762 add_label_to_sizer (s, _panel, _("port"), false);
763 _port = new wxSpinCtrl (_panel, wxID_ANY);
764 _port->SetRange (0, 65535);
766 table->Add (s, 1, wxEXPAND | wxALL);
769 add_label_to_sizer (table, _panel, _("Mail user name"), true);
770 _user = new wxTextCtrl (_panel, wxID_ANY);
771 table->Add (_user, 1, wxEXPAND | wxALL);
773 add_label_to_sizer (table, _panel, _("Mail password"), true);
774 _password = new wxTextCtrl (_panel, wxID_ANY);
775 table->Add (_password, 1, wxEXPAND | wxALL);
777 _server->Bind (wxEVT_TEXT, boost::bind (&EmailPage::server_changed, this));
778 _port->Bind (wxEVT_SPINCTRL, boost::bind (&EmailPage::port_changed, this));
779 _user->Bind (wxEVT_TEXT, boost::bind (&EmailPage::user_changed, this));
780 _password->Bind (wxEVT_TEXT, boost::bind (&EmailPage::password_changed, this));
783 void config_changed ()
785 Config* config = Config::instance ();
787 checked_set (_server, config->mail_server ());
788 checked_set (_port, config->mail_port ());
789 checked_set (_user, config->mail_user ());
790 checked_set (_password, config->mail_password ());
793 void server_changed ()
795 Config::instance()->set_mail_server (wx_to_std (_server->GetValue ()));
800 Config::instance()->set_mail_port (_port->GetValue ());
805 Config::instance()->set_mail_user (wx_to_std (_user->GetValue ()));
808 void password_changed ()
810 Config::instance()->set_mail_password (wx_to_std (_password->GetValue ()));
816 wxTextCtrl* _password;
819 class KDMEmailPage : public StandardPage
823 KDMEmailPage (wxSize panel_size, int border)
825 /* We have to force both width and height of this one */
826 : StandardPage (wxSize (panel_size.GetWidth(), 128), border)
828 : StandardPage (panel_size, border)
832 wxString GetName () const
834 return _("KDM Email");
838 wxBitmap GetLargeIcon () const
840 return wxBitmap ("kdm_email", wxBITMAP_TYPE_PNG_RESOURCE);
847 wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
848 table->AddGrowableCol (1, 1);
849 _panel->GetSizer()->Add (table, 1, wxEXPAND | wxALL, _border);
851 add_label_to_sizer (table, _panel, _("Subject"), true);
852 _subject = new wxTextCtrl (_panel, wxID_ANY);
853 table->Add (_subject, 1, wxEXPAND | wxALL);
855 add_label_to_sizer (table, _panel, _("From address"), true);
856 _from = new wxTextCtrl (_panel, wxID_ANY);
857 table->Add (_from, 1, wxEXPAND | wxALL);
859 vector<string> columns;
860 columns.push_back (wx_to_std (_("Address")));
861 add_label_to_sizer (table, _panel, _("CC addresses"), true);
862 _cc = new EditableList<string, EmailDialog> (
865 bind (&Config::kdm_cc, Config::instance()),
866 bind (&Config::set_kdm_cc, Config::instance(), _1),
869 table->Add (_cc, 1, wxEXPAND | wxALL);
871 add_label_to_sizer (table, _panel, _("BCC address"), true);
872 _bcc = new wxTextCtrl (_panel, wxID_ANY);
873 table->Add (_bcc, 1, wxEXPAND | wxALL);
875 _email = new wxTextCtrl (_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize (-1, 200), wxTE_MULTILINE);
876 _panel->GetSizer()->Add (_email, 0, wxEXPAND | wxALL, _border);
878 _reset_email = new wxButton (_panel, wxID_ANY, _("Reset to default subject and text"));
879 _panel->GetSizer()->Add (_reset_email, 0, wxEXPAND | wxALL, _border);
883 _subject->Bind (wxEVT_TEXT, boost::bind (&KDMEmailPage::kdm_subject_changed, this));
884 _from->Bind (wxEVT_TEXT, boost::bind (&KDMEmailPage::kdm_from_changed, this));
885 _bcc->Bind (wxEVT_TEXT, boost::bind (&KDMEmailPage::kdm_bcc_changed, this));
886 _email->Bind (wxEVT_TEXT, boost::bind (&KDMEmailPage::kdm_email_changed, this));
887 _reset_email->Bind (wxEVT_BUTTON, boost::bind (&KDMEmailPage::reset_email, this));
890 void config_changed ()
892 Config* config = Config::instance ();
894 checked_set (_subject, config->kdm_subject ());
895 checked_set (_from, config->kdm_from ());
896 checked_set (_bcc, config->kdm_bcc ());
897 checked_set (_email, Config::instance()->kdm_email ());
900 void kdm_subject_changed ()
902 Config::instance()->set_kdm_subject (wx_to_std (_subject->GetValue ()));
905 void kdm_from_changed ()
907 Config::instance()->set_kdm_from (wx_to_std (_from->GetValue ()));
910 void kdm_bcc_changed ()
912 Config::instance()->set_kdm_bcc (wx_to_std (_bcc->GetValue ()));
915 void kdm_email_changed ()
917 if (_email->GetValue().IsEmpty ()) {
918 /* Sometimes we get sent an erroneous notification that the email
919 is empty; I don't know why.
923 Config::instance()->set_kdm_email (wx_to_std (_email->GetValue ()));
928 Config::instance()->reset_kdm_email ();
929 checked_set (_email, Config::instance()->kdm_email ());
932 wxTextCtrl* _subject;
934 EditableList<string, EmailDialog>* _cc;
937 wxButton* _reset_email;
940 class AccountsPage : public StandardPage
943 AccountsPage (wxSize panel_size, int border)
944 : StandardPage (panel_size, border)
947 wxString GetName () const
949 return _("Accounts");
953 wxBitmap GetLargeIcon () const
955 return wxBitmap ("accounts", wxBITMAP_TYPE_PNG_RESOURCE);
961 wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
962 table->AddGrowableCol (1, 1);
963 _panel->GetSizer()->Add (table, 1, wxEXPAND | wxALL, _border);
965 add_label_to_sizer (table, _panel, _("certificates.barco.com username"), true);
966 _barco_username = new wxTextCtrl (_panel, wxID_ANY);
967 table->Add (_barco_username, 1, wxEXPAND | wxALL);
969 add_label_to_sizer (table, _panel, _("certificates.barco.com password"), true);
970 _barco_password = new wxTextCtrl (_panel, wxID_ANY);
971 table->Add (_barco_password, 1, wxEXPAND | wxALL);
973 add_label_to_sizer (table, _panel, _("certificates.christiedigital.com username"), true);
974 _christie_username = new wxTextCtrl (_panel, wxID_ANY);
975 table->Add (_christie_username, 1, wxEXPAND | wxALL);
977 add_label_to_sizer (table, _panel, _("certificates.christiedigital.com password"), true);
978 _christie_password = new wxTextCtrl (_panel, wxID_ANY);
979 table->Add (_christie_password, 1, wxEXPAND | wxALL);
981 _barco_username->Bind (wxEVT_TEXT, boost::bind(&AccountsPage::barco_username_changed, this));
982 _barco_password->Bind (wxEVT_TEXT, boost::bind(&AccountsPage::barco_password_changed, this));
983 _christie_username->Bind (wxEVT_TEXT, boost::bind(&AccountsPage::christie_username_changed, this));
984 _christie_password->Bind (wxEVT_TEXT, boost::bind(&AccountsPage::christie_password_changed, this));
987 void config_changed ()
989 Config* config = Config::instance ();
991 checked_set (_barco_username, config->barco_username().get_value_or(""));
992 checked_set (_barco_password, config->barco_password().get_value_or(""));
993 checked_set (_christie_username, config->christie_username().get_value_or(""));
994 checked_set (_christie_password, config->christie_password().get_value_or(""));
997 void barco_username_changed ()
999 wxString const s = _barco_username->GetValue();
1001 Config::instance()->set_barco_username (wx_to_std(s));
1003 Config::instance()->unset_barco_username ();
1007 void barco_password_changed ()
1009 wxString const s = _barco_password->GetValue();
1011 Config::instance()->set_barco_password (wx_to_std(s));
1013 Config::instance()->unset_barco_password ();
1017 void christie_username_changed ()
1019 wxString const s = _christie_username->GetValue();
1021 Config::instance()->set_christie_username (wx_to_std(s));
1023 Config::instance()->unset_christie_username ();
1027 void christie_password_changed ()
1029 wxString const s = _christie_password->GetValue();
1031 Config::instance()->set_christie_password (wx_to_std(s));
1033 Config::instance()->unset_christie_password ();
1038 wxTextCtrl* _barco_username;
1039 wxTextCtrl* _barco_password;
1040 wxTextCtrl* _christie_username;
1041 wxTextCtrl* _christie_password;
1045 class NotificationsPage : public StandardPage
1048 NotificationsPage (wxSize panel_size, int border)
1049 #ifdef DCPOMATIC_OSX
1050 /* We have to force both width and height of this one */
1051 : StandardPage (wxSize (panel_size.GetWidth(), 128), border)
1053 : StandardPage (panel_size, border)
1057 wxString GetName () const
1059 return _("Notifications");
1062 #ifdef DCPOMATIC_OSX
1063 wxBitmap GetLargeIcon () const
1065 return wxBitmap ("notifications", wxBITMAP_TYPE_PNG_RESOURCE);
1072 wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
1073 table->AddGrowableCol (1, 1);
1074 _panel->GetSizer()->Add (table, 1, wxEXPAND | wxALL, _border);
1076 _enable_message_box = new wxCheckBox (_panel, wxID_ANY, _("Message box"));
1077 table->Add (_enable_message_box, 1, wxEXPAND | wxALL);
1078 table->AddSpacer (0);
1080 _enable_email = new wxCheckBox (_panel, wxID_ANY, _("Email"));
1081 table->Add (_enable_email, 1, wxEXPAND | wxALL);
1082 table->AddSpacer (0);
1084 add_label_to_sizer (table, _panel, _("Subject"), true);
1085 _subject = new wxTextCtrl (_panel, wxID_ANY);
1086 table->Add (_subject, 1, wxEXPAND | wxALL);
1088 add_label_to_sizer (table, _panel, _("From address"), true);
1089 _from = new wxTextCtrl (_panel, wxID_ANY);
1090 table->Add (_from, 1, wxEXPAND | wxALL);
1092 add_label_to_sizer (table, _panel, _("To address"), true);
1093 _to = new wxTextCtrl (_panel, wxID_ANY);
1094 table->Add (_to, 1, wxEXPAND | wxALL);
1096 vector<string> columns;
1097 columns.push_back (wx_to_std (_("Address")));
1098 add_label_to_sizer (table, _panel, _("CC addresses"), true);
1099 _cc = new EditableList<string, EmailDialog> (
1102 bind (&Config::notification_cc, Config::instance()),
1103 bind (&Config::set_notification_cc, Config::instance(), _1),
1106 table->Add (_cc, 1, wxEXPAND | wxALL);
1108 add_label_to_sizer (table, _panel, _("BCC address"), true);
1109 _bcc = new wxTextCtrl (_panel, wxID_ANY);
1110 table->Add (_bcc, 1, wxEXPAND | wxALL);
1112 _email = new wxTextCtrl (_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize (-1, 200), wxTE_MULTILINE);
1113 _panel->GetSizer()->Add (_email, 0, wxEXPAND | wxALL, _border);
1115 _reset_email = new wxButton (_panel, wxID_ANY, _("Reset to default subject and text"));
1116 _panel->GetSizer()->Add (_reset_email, 0, wxEXPAND | wxALL, _border);
1120 _enable_message_box->Bind (wxEVT_CHECKBOX, boost::bind (&NotificationsPage::type_changed, this, _enable_message_box, Config::MESSAGE_BOX));
1121 _enable_email->Bind (wxEVT_CHECKBOX, boost::bind (&NotificationsPage::type_changed, this, _enable_email, Config::EMAIL));
1123 _subject->Bind (wxEVT_TEXT, boost::bind (&NotificationsPage::notification_subject_changed, this));
1124 _from->Bind (wxEVT_TEXT, boost::bind (&NotificationsPage::notification_from_changed, this));
1125 _to->Bind (wxEVT_TEXT, boost::bind (&NotificationsPage::notification_to_changed, this));
1126 _bcc->Bind (wxEVT_TEXT, boost::bind (&NotificationsPage::notification_bcc_changed, this));
1127 _email->Bind (wxEVT_TEXT, boost::bind (&NotificationsPage::notification_email_changed, this));
1128 _reset_email->Bind (wxEVT_BUTTON, boost::bind (&NotificationsPage::reset_email, this));
1130 update_sensitivity ();
1133 void update_sensitivity ()
1135 bool const s = _enable_email->GetValue();
1136 _subject->Enable(s);
1142 _reset_email->Enable(s);
1145 void config_changed ()
1147 Config* config = Config::instance ();
1149 checked_set (_enable_message_box, config->notification(Config::MESSAGE_BOX));
1150 checked_set (_enable_email, config->notification(Config::EMAIL));
1151 checked_set (_subject, config->notification_subject ());
1152 checked_set (_from, config->notification_from ());
1153 checked_set (_to, config->notification_to ());
1154 checked_set (_bcc, config->notification_bcc ());
1155 checked_set (_email, Config::instance()->notification_email ());
1157 update_sensitivity ();
1160 void notification_subject_changed ()
1162 Config::instance()->set_notification_subject (wx_to_std (_subject->GetValue ()));
1165 void notification_from_changed ()
1167 Config::instance()->set_notification_from (wx_to_std (_from->GetValue ()));
1170 void notification_to_changed ()
1172 Config::instance()->set_notification_to (wx_to_std (_to->GetValue ()));
1175 void notification_bcc_changed ()
1177 Config::instance()->set_notification_bcc (wx_to_std (_bcc->GetValue ()));
1180 void notification_email_changed ()
1182 if (_email->GetValue().IsEmpty ()) {
1183 /* Sometimes we get sent an erroneous notification that the email
1184 is empty; I don't know why.
1188 Config::instance()->set_notification_email (wx_to_std (_email->GetValue ()));
1193 Config::instance()->reset_notification_email ();
1194 checked_set (_email, Config::instance()->notification_email ());
1197 void type_changed (wxCheckBox* b, Config::Notification n)
1199 Config::instance()->set_notification(n, b->GetValue());
1200 update_sensitivity ();
1203 wxCheckBox* _enable_message_box;
1204 wxCheckBox* _enable_email;
1206 wxTextCtrl* _subject;
1209 EditableList<string, EmailDialog>* _cc;
1212 wxButton* _reset_email;
1215 class CoverSheetPage : public StandardPage
1219 CoverSheetPage (wxSize panel_size, int border)
1220 #ifdef DCPOMATIC_OSX
1221 /* We have to force both width and height of this one */
1222 : StandardPage (wxSize (panel_size.GetWidth(), 128), border)
1224 : StandardPage (panel_size, border)
1228 wxString GetName () const
1230 return _("Cover Sheet");
1233 #ifdef DCPOMATIC_OSX
1234 wxBitmap GetLargeIcon () const
1236 return wxBitmap ("cover_sheet", wxBITMAP_TYPE_PNG_RESOURCE);
1243 _cover_sheet = new wxTextCtrl (_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize (-1, 200), wxTE_MULTILINE);
1244 _panel->GetSizer()->Add (_cover_sheet, 0, wxEXPAND | wxALL, _border);
1246 _reset_cover_sheet = new wxButton (_panel, wxID_ANY, _("Reset to default text"));
1247 _panel->GetSizer()->Add (_reset_cover_sheet, 0, wxEXPAND | wxALL, _border);
1249 _cover_sheet->Bind (wxEVT_TEXT, boost::bind (&CoverSheetPage::cover_sheet_changed, this));
1250 _reset_cover_sheet->Bind (wxEVT_BUTTON, boost::bind (&CoverSheetPage::reset_cover_sheet, this));
1253 void config_changed ()
1255 checked_set (_cover_sheet, Config::instance()->cover_sheet ());
1258 void cover_sheet_changed ()
1260 if (_cover_sheet->GetValue().IsEmpty ()) {
1261 /* Sometimes we get sent an erroneous notification that the cover sheet
1262 is empty; I don't know why.
1266 Config::instance()->set_cover_sheet (wx_to_std (_cover_sheet->GetValue ()));
1269 void reset_cover_sheet ()
1271 Config::instance()->reset_cover_sheet ();
1272 checked_set (_cover_sheet, Config::instance()->cover_sheet ());
1275 wxTextCtrl* _cover_sheet;
1276 wxButton* _reset_cover_sheet;
1280 /** @class AdvancedPage
1281 * @brief Advanced page of the preferences dialog.
1283 class AdvancedPage : public StockPage
1286 AdvancedPage (wxSize panel_size, int border)
1287 : StockPage (Kind_Advanced, panel_size, border)
1288 , _maximum_j2k_bandwidth (0)
1289 , _allow_any_dcp_frame_rate (0)
1290 , _allow_any_container (0)
1291 , _only_servers_encode (0)
1296 , _log_debug_decode (0)
1297 , _log_debug_encode (0)
1298 , _log_debug_email (0)
1302 void add_top_aligned_label_to_sizer (wxSizer* table, wxWindow* parent, wxString text)
1304 int flags = wxALIGN_TOP | wxTOP | wxLEFT;
1306 flags |= wxALIGN_RIGHT;
1309 wxStaticText* m = new wxStaticText (parent, wxID_ANY, text);
1310 table->Add (m, 0, flags, DCPOMATIC_SIZER_Y_GAP);
1315 wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
1316 table->AddGrowableCol (1, 1);
1317 _panel->GetSizer()->Add (table, 1, wxALL | wxEXPAND, _border);
1320 add_label_to_sizer (table, _panel, _("Maximum JPEG2000 bandwidth"), true);
1321 wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL);
1322 _maximum_j2k_bandwidth = new wxSpinCtrl (_panel);
1323 s->Add (_maximum_j2k_bandwidth, 1);
1324 add_label_to_sizer (s, _panel, _("Mbit/s"), false);
1328 _allow_any_dcp_frame_rate = new wxCheckBox (_panel, wxID_ANY, _("Allow any DCP frame rate"));
1329 table->Add (_allow_any_dcp_frame_rate, 1, wxEXPAND | wxALL);
1330 table->AddSpacer (0);
1332 _allow_any_container = new wxCheckBox (_panel, wxID_ANY, _("Allow non-standard container ratios"));
1333 table->Add (_allow_any_container, 1, wxEXPAND | wxALL);
1334 table->AddSpacer (0);
1336 wxStaticText* restart = add_label_to_sizer (table, _panel, _("(restart DCP-o-matic to see all ratios)"), false);
1337 wxFont font = restart->GetFont();
1338 font.SetStyle (wxFONTSTYLE_ITALIC);
1339 font.SetPointSize (font.GetPointSize() - 1);
1340 restart->SetFont (font);
1341 table->AddSpacer (0);
1343 _only_servers_encode = new wxCheckBox (_panel, wxID_ANY, _("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'] = "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'] = "type (j2c/pcm/sub)";
1371 titles['r'] = "reel number";
1372 titles['n'] = "number of reels";
1373 titles['c'] = "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 wxCheckBox (_panel, wxID_ANY, _("General"));
1389 t->Add (_log_general, 1, wxEXPAND | wxALL);
1390 _log_warning = new wxCheckBox (_panel, wxID_ANY, _("Warnings"));
1391 t->Add (_log_warning, 1, wxEXPAND | wxALL);
1392 _log_error = new wxCheckBox (_panel, wxID_ANY, _("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 wxCheckBox (_panel, wxID_ANY, S_("Config|Timing"));
1396 t->Add (_log_timing, 1, wxEXPAND | wxALL);
1397 _log_debug_decode = new wxCheckBox (_panel, wxID_ANY, _("Debug: decode"));
1398 t->Add (_log_debug_decode, 1, wxEXPAND | wxALL);
1399 _log_debug_encode = new wxCheckBox (_panel, wxID_ANY, _("Debug: encode"));
1400 t->Add (_log_debug_encode, 1, wxEXPAND | wxALL);
1401 _log_debug_email = new wxCheckBox (_panel, wxID_ANY, _("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 wxCheckBox (_panel, wxID_ANY, _("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 _allow_any_dcp_frame_rate->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::allow_any_dcp_frame_rate_changed, this));
1415 _allow_any_container->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::allow_any_container_changed, this));
1416 _only_servers_encode->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::only_servers_encode_changed, this));
1417 _frames_in_memory_multiplier->Bind (wxEVT_SPINCTRL, boost::bind(&AdvancedPage::frames_in_memory_multiplier_changed, this));
1418 _dcp_metadata_filename_format->Changed.connect (boost::bind (&AdvancedPage::dcp_metadata_filename_format_changed, this));
1419 _dcp_asset_filename_format->Changed.connect (boost::bind (&AdvancedPage::dcp_asset_filename_format_changed, this));
1420 _log_general->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::log_changed, this));
1421 _log_warning->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::log_changed, this));
1422 _log_error->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::log_changed, this));
1423 _log_timing->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::log_changed, this));
1424 _log_debug_decode->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::log_changed, this));
1425 _log_debug_encode->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::log_changed, this));
1426 _log_debug_email->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::log_changed, this));
1427 #ifdef DCPOMATIC_WINDOWS
1428 _win32_console->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::win32_console_changed, this));
1432 void config_changed ()
1434 Config* config = Config::instance ();
1436 checked_set (_maximum_j2k_bandwidth, config->maximum_j2k_bandwidth() / 1000000);
1437 checked_set (_allow_any_dcp_frame_rate, config->allow_any_dcp_frame_rate ());
1438 checked_set (_allow_any_container, config->allow_any_container ());
1439 checked_set (_only_servers_encode, config->only_servers_encode ());
1440 checked_set (_log_general, config->log_types() & LogEntry::TYPE_GENERAL);
1441 checked_set (_log_warning, config->log_types() & LogEntry::TYPE_WARNING);
1442 checked_set (_log_error, config->log_types() & LogEntry::TYPE_ERROR);
1443 checked_set (_log_timing, config->log_types() & LogEntry::TYPE_TIMING);
1444 checked_set (_log_debug_decode, config->log_types() & LogEntry::TYPE_DEBUG_DECODE);
1445 checked_set (_log_debug_encode, config->log_types() & LogEntry::TYPE_DEBUG_ENCODE);
1446 checked_set (_log_debug_email, config->log_types() & LogEntry::TYPE_DEBUG_EMAIL);
1447 checked_set (_frames_in_memory_multiplier, config->frames_in_memory_multiplier());
1448 #ifdef DCPOMATIC_WINDOWS
1449 checked_set (_win32_console, config->win32_console());
1453 void maximum_j2k_bandwidth_changed ()
1455 Config::instance()->set_maximum_j2k_bandwidth (_maximum_j2k_bandwidth->GetValue() * 1000000);
1458 void frames_in_memory_multiplier_changed ()
1460 Config::instance()->set_frames_in_memory_multiplier (_frames_in_memory_multiplier->GetValue());
1463 void allow_any_dcp_frame_rate_changed ()
1465 Config::instance()->set_allow_any_dcp_frame_rate (_allow_any_dcp_frame_rate->GetValue ());
1468 void allow_any_container_changed ()
1470 Config::instance()->set_allow_any_container (_allow_any_container->GetValue ());
1473 void only_servers_encode_changed ()
1475 Config::instance()->set_only_servers_encode (_only_servers_encode->GetValue ());
1478 void dcp_metadata_filename_format_changed ()
1480 Config::instance()->set_dcp_metadata_filename_format (_dcp_metadata_filename_format->get ());
1483 void dcp_asset_filename_format_changed ()
1485 Config::instance()->set_dcp_asset_filename_format (_dcp_asset_filename_format->get ());
1491 if (_log_general->GetValue ()) {
1492 types |= LogEntry::TYPE_GENERAL;
1494 if (_log_warning->GetValue ()) {
1495 types |= LogEntry::TYPE_WARNING;
1497 if (_log_error->GetValue ()) {
1498 types |= LogEntry::TYPE_ERROR;
1500 if (_log_timing->GetValue ()) {
1501 types |= LogEntry::TYPE_TIMING;
1503 if (_log_debug_decode->GetValue ()) {
1504 types |= LogEntry::TYPE_DEBUG_DECODE;
1506 if (_log_debug_encode->GetValue ()) {
1507 types |= LogEntry::TYPE_DEBUG_ENCODE;
1509 if (_log_debug_email->GetValue ()) {
1510 types |= LogEntry::TYPE_DEBUG_EMAIL;
1512 Config::instance()->set_log_types (types);
1515 #ifdef DCPOMATIC_WINDOWS
1516 void win32_console_changed ()
1518 Config::instance()->set_win32_console (_win32_console->GetValue ());
1522 wxSpinCtrl* _maximum_j2k_bandwidth;
1523 wxSpinCtrl* _frames_in_memory_multiplier;
1524 wxCheckBox* _allow_any_dcp_frame_rate;
1525 wxCheckBox* _allow_any_container;
1526 wxCheckBox* _only_servers_encode;
1527 NameFormatEditor* _dcp_metadata_filename_format;
1528 NameFormatEditor* _dcp_asset_filename_format;
1529 wxCheckBox* _log_general;
1530 wxCheckBox* _log_warning;
1531 wxCheckBox* _log_error;
1532 wxCheckBox* _log_timing;
1533 wxCheckBox* _log_debug_decode;
1534 wxCheckBox* _log_debug_encode;
1535 wxCheckBox* _log_debug_email;
1536 #ifdef DCPOMATIC_WINDOWS
1537 wxCheckBox* _win32_console;
1541 wxPreferencesEditor*
1542 create_full_config_dialog ()
1544 wxPreferencesEditor* e = new wxPreferencesEditor ();
1546 #ifdef DCPOMATIC_OSX
1547 /* Width that we force some of the config panels to be on OSX so that
1548 the containing window doesn't shrink too much when we select those panels.
1549 This is obviously an unpleasant hack.
1551 wxSize ps = wxSize (600, -1);
1552 int const border = 16;
1554 wxSize ps = wxSize (-1, -1);
1555 int const border = 8;
1558 e->AddPage (new FullGeneralPage (ps, border));
1559 e->AddPage (new DefaultsPage (ps, border));
1560 e->AddPage (new EncodingServersPage (ps, border));
1561 e->AddPage (new KeysPage (ps, border));
1562 e->AddPage (new TMSPage (ps, border));
1563 e->AddPage (new EmailPage (ps, border));
1564 e->AddPage (new KDMEmailPage (ps, border));
1565 e->AddPage (new AccountsPage (ps, border));
1566 e->AddPage (new NotificationsPage (ps, border));
1567 e->AddPage (new CoverSheetPage (ps, border));
1568 e->AddPage (new AdvancedPage (ps, border));