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, _("Number of threads DCP-o-matic should use"), true, wxGBPosition (r, 0));
89 _master_encoding_threads = new wxSpinCtrl (_panel);
90 table->Add (_master_encoding_threads, wxGBPosition (r, 1));
93 add_label_to_sizer (table, _panel, _("Number of threads DCP-o-matic encode server should use"), true, wxGBPosition (r, 0));
94 _server_encoding_threads = new wxSpinCtrl (_panel);
95 table->Add (_server_encoding_threads, wxGBPosition (r, 1));
98 add_label_to_sizer (table, _panel, _("Configuration file"), true, wxGBPosition (r, 0));
99 _config_file = new FilePickerCtrl (_panel, _("Select configuration file"), "*.xml", true);
100 table->Add (_config_file, wxGBPosition (r, 1));
103 add_label_to_sizer (table, _panel, _("Cinema and screen database file"), true, wxGBPosition (r, 0));
104 _cinemas_file = new FilePickerCtrl (_panel, _("Select cinema and screen database file"), "*.xml", true);
105 table->Add (_cinemas_file, wxGBPosition (r, 1));
106 wxButton* export_cinemas = new wxButton (_panel, wxID_ANY, _("Export..."));
107 table->Add (export_cinemas, wxGBPosition (r, 2));
110 add_play_sound_controls (table, r);
112 #ifdef DCPOMATIC_HAVE_EBUR128_PATCHED_FFMPEG
113 _analyse_ebur128 = new wxCheckBox (_panel, wxID_ANY, _("Find integrated loudness, true peak and loudness range when analysing audio"));
114 table->Add (_analyse_ebur128, wxGBPosition (r, 0), wxGBSpan (1, 2));
118 _automatic_audio_analysis = new wxCheckBox (_panel, wxID_ANY, _("Automatically analyse content audio"));
119 table->Add (_automatic_audio_analysis, wxGBPosition (r, 0), wxGBSpan (1, 2));
122 add_update_controls (table, r);
124 wxFlexGridSizer* bottom_table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
125 bottom_table->AddGrowableCol (1, 1);
127 add_label_to_sizer (bottom_table, _panel, _("Issuer"), true);
128 _issuer = new wxTextCtrl (_panel, wxID_ANY);
129 bottom_table->Add (_issuer, 1, wxALL | wxEXPAND);
131 add_label_to_sizer (bottom_table, _panel, _("Creator"), true);
132 _creator = new wxTextCtrl (_panel, wxID_ANY);
133 bottom_table->Add (_creator, 1, wxALL | wxEXPAND);
135 table->Add (bottom_table, wxGBPosition (r, 0), wxGBSpan (2, 2), wxEXPAND);
138 _config_file->Bind (wxEVT_FILEPICKER_CHANGED, boost::bind (&FullGeneralPage::config_file_changed, this));
139 _cinemas_file->Bind (wxEVT_FILEPICKER_CHANGED, boost::bind (&FullGeneralPage::cinemas_file_changed, this));
141 _master_encoding_threads->SetRange (1, 128);
142 _master_encoding_threads->Bind (wxEVT_SPINCTRL, boost::bind (&FullGeneralPage::master_encoding_threads_changed, this));
143 _server_encoding_threads->SetRange (1, 128);
144 _server_encoding_threads->Bind (wxEVT_SPINCTRL, boost::bind (&FullGeneralPage::server_encoding_threads_changed, this));
145 export_cinemas->Bind (wxEVT_BUTTON, boost::bind (&FullGeneralPage::export_cinemas_file, this));
147 #ifdef DCPOMATIC_HAVE_EBUR128_PATCHED_FFMPEG
148 _analyse_ebur128->Bind (wxEVT_CHECKBOX, boost::bind (&FullGeneralPage::analyse_ebur128_changed, this));
150 _automatic_audio_analysis->Bind (wxEVT_CHECKBOX, boost::bind (&FullGeneralPage::automatic_audio_analysis_changed, this));
152 _issuer->Bind (wxEVT_TEXT, boost::bind (&FullGeneralPage::issuer_changed, this));
153 _creator->Bind (wxEVT_TEXT, boost::bind (&FullGeneralPage::creator_changed, this));
156 void config_changed ()
158 Config* config = Config::instance ();
160 checked_set (_master_encoding_threads, config->master_encoding_threads ());
161 checked_set (_server_encoding_threads, config->server_encoding_threads ());
162 #ifdef DCPOMATIC_HAVE_EBUR128_PATCHED_FFMPEG
163 checked_set (_analyse_ebur128, config->analyse_ebur128 ());
165 checked_set (_automatic_audio_analysis, config->automatic_audio_analysis ());
166 checked_set (_issuer, config->dcp_issuer ());
167 checked_set (_creator, config->dcp_creator ());
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(), path_from_file_dialog (d, "xml"));
188 #ifdef DCPOMATIC_HAVE_EBUR128_PATCHED_FFMPEG
189 void analyse_ebur128_changed ()
191 Config::instance()->set_analyse_ebur128 (_analyse_ebur128->GetValue ());
195 void automatic_audio_analysis_changed ()
197 Config::instance()->set_automatic_audio_analysis (_automatic_audio_analysis->GetValue ());
200 void master_encoding_threads_changed ()
202 Config::instance()->set_master_encoding_threads (_master_encoding_threads->GetValue ());
205 void server_encoding_threads_changed ()
207 Config::instance()->set_server_encoding_threads (_server_encoding_threads->GetValue ());
210 void issuer_changed ()
212 Config::instance()->set_dcp_issuer (wx_to_std (_issuer->GetValue ()));
215 void creator_changed ()
217 Config::instance()->set_dcp_creator (wx_to_std (_creator->GetValue ()));
220 void config_file_changed ()
222 Config* config = Config::instance();
223 boost::filesystem::path new_file = wx_to_std(_config_file->GetPath());
224 if (new_file == config->config_file()) {
227 bool copy_and_link = true;
228 if (boost::filesystem::exists(new_file)) {
229 ConfigMoveDialog* d = new ConfigMoveDialog (_panel, new_file);
230 if (d->ShowModal() == wxID_OK) {
231 copy_and_link = false;
238 if (new_file != config->config_file()) {
239 config->copy_and_link (new_file);
242 config->link (new_file);
246 void cinemas_file_changed ()
248 Config::instance()->set_cinemas_file (wx_to_std (_cinemas_file->GetPath ()));
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;
260 wxTextCtrl* _creator;
263 class DefaultsPage : public StandardPage
266 DefaultsPage (wxSize panel_size, int border)
267 : StandardPage (panel_size, border)
270 wxString GetName () const
272 return _("Defaults");
276 wxBitmap GetLargeIcon () const
278 return wxBitmap ("defaults", wxBITMAP_TYPE_PNG_RESOURCE);
285 wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
286 table->AddGrowableCol (1, 1);
287 _panel->GetSizer()->Add (table, 1, wxALL | wxEXPAND, _border);
290 add_label_to_sizer (table, _panel, _("Default duration of still images"), true);
291 wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL);
292 _still_length = new wxSpinCtrl (_panel);
293 s->Add (_still_length);
294 add_label_to_sizer (s, _panel, _("s"), false);
298 add_label_to_sizer (table, _panel, _("Default directory for new films"), true);
299 #ifdef DCPOMATIC_USE_OWN_PICKER
300 _directory = new DirPickerCtrl (_panel);
302 _directory = new wxDirPickerCtrl (_panel, wxDD_DIR_MUST_EXIST);
304 table->Add (_directory, 1, wxEXPAND);
306 add_label_to_sizer (table, _panel, _("Default ISDCF name details"), true);
307 _isdcf_metadata_button = new wxButton (_panel, wxID_ANY, _("Edit..."));
308 table->Add (_isdcf_metadata_button);
310 add_label_to_sizer (table, _panel, _("Default container"), true);
311 _container = new wxChoice (_panel, wxID_ANY);
312 table->Add (_container);
314 add_label_to_sizer (table, _panel, _("Default scale-to"), true);
315 _scale_to = new wxChoice (_panel, wxID_ANY);
316 table->Add (_scale_to);
318 add_label_to_sizer (table, _panel, _("Default content type"), true);
319 _dcp_content_type = new wxChoice (_panel, wxID_ANY);
320 table->Add (_dcp_content_type);
322 add_label_to_sizer (table, _panel, _("Default DCP audio channels"), true);
323 _dcp_audio_channels = new wxChoice (_panel, wxID_ANY);
324 table->Add (_dcp_audio_channels);
327 add_label_to_sizer (table, _panel, _("Default JPEG2000 bandwidth"), true);
328 wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL);
329 _j2k_bandwidth = new wxSpinCtrl (_panel);
330 s->Add (_j2k_bandwidth);
331 add_label_to_sizer (s, _panel, _("Mbit/s"), false);
336 add_label_to_sizer (table, _panel, _("Default audio delay"), true);
337 wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL);
338 _audio_delay = new wxSpinCtrl (_panel);
339 s->Add (_audio_delay);
340 add_label_to_sizer (s, _panel, _("ms"), false);
344 add_label_to_sizer (table, _panel, _("Default standard"), true);
345 _standard = new wxChoice (_panel, wxID_ANY);
346 table->Add (_standard);
348 add_label_to_sizer (table, _panel, _("Default KDM directory"), true);
349 #ifdef DCPOMATIC_USE_OWN_PICKER
350 _kdm_directory = new DirPickerCtrl (_panel);
352 _kdm_directory = new wxDirPickerCtrl (_panel, wxDD_DIR_MUST_EXIST);
355 table->Add (_kdm_directory, 1, wxEXPAND);
357 _upload_after_make_dcp = new wxCheckBox (_panel, wxID_ANY, _("Default to enabling upload of DCP to TMS"));
358 table->Add (_upload_after_make_dcp, 1, wxEXPAND);
360 _still_length->SetRange (1, 3600);
361 _still_length->Bind (wxEVT_SPINCTRL, boost::bind (&DefaultsPage::still_length_changed, this));
363 _directory->Bind (wxEVT_DIRPICKER_CHANGED, boost::bind (&DefaultsPage::directory_changed, this));
364 _kdm_directory->Bind (wxEVT_DIRPICKER_CHANGED, boost::bind (&DefaultsPage::kdm_directory_changed, this));
366 _isdcf_metadata_button->Bind (wxEVT_BUTTON, boost::bind (&DefaultsPage::edit_isdcf_metadata_clicked, this));
368 BOOST_FOREACH (Ratio const * i, Ratio::containers()) {
369 _container->Append (std_to_wx(i->container_nickname()));
372 _container->Bind (wxEVT_CHOICE, boost::bind (&DefaultsPage::container_changed, this));
374 _scale_to->Append (_("Guess from content"));
376 BOOST_FOREACH (Ratio const * i, Ratio::all()) {
377 _scale_to->Append (std_to_wx(i->image_nickname()));
380 _scale_to->Bind (wxEVT_CHOICE, boost::bind (&DefaultsPage::scale_to_changed, this));
382 BOOST_FOREACH (DCPContentType const * i, DCPContentType::all()) {
383 _dcp_content_type->Append (std_to_wx (i->pretty_name ()));
386 setup_audio_channels_choice (_dcp_audio_channels, 2);
388 _dcp_content_type->Bind (wxEVT_CHOICE, boost::bind (&DefaultsPage::dcp_content_type_changed, this));
389 _dcp_audio_channels->Bind (wxEVT_CHOICE, boost::bind (&DefaultsPage::dcp_audio_channels_changed, this));
391 _j2k_bandwidth->SetRange (50, 250);
392 _j2k_bandwidth->Bind (wxEVT_SPINCTRL, boost::bind (&DefaultsPage::j2k_bandwidth_changed, this));
394 _audio_delay->SetRange (-1000, 1000);
395 _audio_delay->Bind (wxEVT_SPINCTRL, boost::bind (&DefaultsPage::audio_delay_changed, this));
397 _standard->Append (_("SMPTE"));
398 _standard->Append (_("Interop"));
399 _standard->Bind (wxEVT_CHOICE, boost::bind (&DefaultsPage::standard_changed, this));
401 _upload_after_make_dcp->Bind (wxEVT_CHECKBOX, boost::bind (&DefaultsPage::upload_after_make_dcp_changed, this));
404 void config_changed ()
406 Config* config = Config::instance ();
408 vector<Ratio const *> containers = Ratio::containers ();
409 for (size_t i = 0; i < containers.size(); ++i) {
410 if (containers[i] == config->default_container ()) {
411 _container->SetSelection (i);
415 vector<Ratio const *> ratios = Ratio::all ();
416 for (size_t i = 0; i < ratios.size(); ++i) {
417 if (ratios[i] == config->default_scale_to ()) {
418 _scale_to->SetSelection (i + 1);
422 if (!config->default_scale_to()) {
423 _scale_to->SetSelection (0);
426 vector<DCPContentType const *> const ct = DCPContentType::all ();
427 for (size_t i = 0; i < ct.size(); ++i) {
428 if (ct[i] == config->default_dcp_content_type ()) {
429 _dcp_content_type->SetSelection (i);
433 checked_set (_still_length, config->default_still_length ());
434 _directory->SetPath (std_to_wx (config->default_directory_or (wx_to_std (wxStandardPaths::Get().GetDocumentsDir())).string ()));
435 _kdm_directory->SetPath (std_to_wx (config->default_kdm_directory_or (wx_to_std (wxStandardPaths::Get().GetDocumentsDir())).string ()));
436 checked_set (_j2k_bandwidth, config->default_j2k_bandwidth() / 1000000);
437 _j2k_bandwidth->SetRange (50, config->maximum_j2k_bandwidth() / 1000000);
438 checked_set (_dcp_audio_channels, locale_convert<string> (config->default_dcp_audio_channels()));
439 checked_set (_audio_delay, config->default_audio_delay ());
440 checked_set (_standard, config->default_interop() ? 1 : 0);
441 checked_set (_upload_after_make_dcp, config->default_upload_after_make_dcp());
444 void j2k_bandwidth_changed ()
446 Config::instance()->set_default_j2k_bandwidth (_j2k_bandwidth->GetValue() * 1000000);
449 void audio_delay_changed ()
451 Config::instance()->set_default_audio_delay (_audio_delay->GetValue());
454 void dcp_audio_channels_changed ()
456 int const s = _dcp_audio_channels->GetSelection ();
457 if (s != wxNOT_FOUND) {
458 Config::instance()->set_default_dcp_audio_channels (
459 locale_convert<int> (string_client_data (_dcp_audio_channels->GetClientObject (s)))
464 void directory_changed ()
466 Config::instance()->set_default_directory (wx_to_std (_directory->GetPath ()));
469 void kdm_directory_changed ()
471 Config::instance()->set_default_kdm_directory (wx_to_std (_kdm_directory->GetPath ()));
474 void edit_isdcf_metadata_clicked ()
476 ISDCFMetadataDialog* d = new ISDCFMetadataDialog (_panel, Config::instance()->default_isdcf_metadata (), false);
478 Config::instance()->set_default_isdcf_metadata (d->isdcf_metadata ());
482 void still_length_changed ()
484 Config::instance()->set_default_still_length (_still_length->GetValue ());
487 void container_changed ()
489 vector<Ratio const *> ratio = Ratio::containers ();
490 Config::instance()->set_default_container (ratio[_container->GetSelection()]);
493 void scale_to_changed ()
495 int const s = _scale_to->GetSelection ();
497 Config::instance()->set_default_scale_to (0);
499 vector<Ratio const *> ratio = Ratio::all ();
500 Config::instance()->set_default_scale_to (ratio[s - 1]);
504 void dcp_content_type_changed ()
506 vector<DCPContentType const *> ct = DCPContentType::all ();
507 Config::instance()->set_default_dcp_content_type (ct[_dcp_content_type->GetSelection()]);
510 void standard_changed ()
512 Config::instance()->set_default_interop (_standard->GetSelection() == 1);
515 void upload_after_make_dcp_changed ()
517 Config::instance()->set_default_upload_after_make_dcp (_upload_after_make_dcp->GetValue ());
520 wxSpinCtrl* _j2k_bandwidth;
521 wxSpinCtrl* _audio_delay;
522 wxButton* _isdcf_metadata_button;
523 wxSpinCtrl* _still_length;
524 #ifdef DCPOMATIC_USE_OWN_PICKER
525 DirPickerCtrl* _directory;
526 DirPickerCtrl* _kdm_directory;
528 wxDirPickerCtrl* _directory;
529 wxDirPickerCtrl* _kdm_directory;
531 wxChoice* _container;
533 wxChoice* _dcp_content_type;
534 wxChoice* _dcp_audio_channels;
536 wxCheckBox* _upload_after_make_dcp;
539 class EncodingServersPage : public StandardPage
542 EncodingServersPage (wxSize panel_size, int border)
543 : StandardPage (panel_size, border)
546 wxString GetName () const
552 wxBitmap GetLargeIcon () const
554 return wxBitmap ("servers", wxBITMAP_TYPE_PNG_RESOURCE);
561 _use_any_servers = new wxCheckBox (_panel, wxID_ANY, _("Search network for servers"));
562 _panel->GetSizer()->Add (_use_any_servers, 0, wxALL, _border);
564 vector<string> columns;
565 columns.push_back (wx_to_std (_("IP address / host name")));
566 _servers_list = new EditableList<string, ServerDialog> (
569 boost::bind (&Config::servers, Config::instance()),
570 boost::bind (&Config::set_servers, Config::instance(), _1),
571 boost::bind (&EncodingServersPage::server_column, this, _1)
574 _panel->GetSizer()->Add (_servers_list, 1, wxEXPAND | wxALL, _border);
576 _use_any_servers->Bind (wxEVT_CHECKBOX, boost::bind (&EncodingServersPage::use_any_servers_changed, this));
579 void config_changed ()
581 checked_set (_use_any_servers, Config::instance()->use_any_servers ());
582 _servers_list->refresh ();
585 void use_any_servers_changed ()
587 Config::instance()->set_use_any_servers (_use_any_servers->GetValue ());
590 string server_column (string s)
595 wxCheckBox* _use_any_servers;
596 EditableList<string, ServerDialog>* _servers_list;
599 class TMSPage : public StandardPage
602 TMSPage (wxSize panel_size, int border)
603 : StandardPage (panel_size, border)
606 wxString GetName () const
612 wxBitmap GetLargeIcon () const
614 return wxBitmap ("tms", wxBITMAP_TYPE_PNG_RESOURCE);
621 wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
622 table->AddGrowableCol (1, 1);
623 _panel->GetSizer()->Add (table, 1, wxALL | wxEXPAND, _border);
625 add_label_to_sizer (table, _panel, _("Protocol"), true);
626 _tms_protocol = new wxChoice (_panel, wxID_ANY);
627 table->Add (_tms_protocol, 1, wxEXPAND);
629 add_label_to_sizer (table, _panel, _("IP address"), true);
630 _tms_ip = new wxTextCtrl (_panel, wxID_ANY);
631 table->Add (_tms_ip, 1, wxEXPAND);
633 add_label_to_sizer (table, _panel, _("Target path"), true);
634 _tms_path = new wxTextCtrl (_panel, wxID_ANY);
635 table->Add (_tms_path, 1, wxEXPAND);
637 add_label_to_sizer (table, _panel, _("User name"), true);
638 _tms_user = new wxTextCtrl (_panel, wxID_ANY);
639 table->Add (_tms_user, 1, wxEXPAND);
641 add_label_to_sizer (table, _panel, _("Password"), true);
642 _tms_password = new wxTextCtrl (_panel, wxID_ANY);
643 table->Add (_tms_password, 1, wxEXPAND);
645 _tms_protocol->Append (_("SCP (for AAM and Doremi)"));
646 _tms_protocol->Append (_("FTP (for Dolby)"));
648 _tms_protocol->Bind (wxEVT_CHOICE, boost::bind (&TMSPage::tms_protocol_changed, this));
649 _tms_ip->Bind (wxEVT_TEXT, boost::bind (&TMSPage::tms_ip_changed, this));
650 _tms_path->Bind (wxEVT_TEXT, boost::bind (&TMSPage::tms_path_changed, this));
651 _tms_user->Bind (wxEVT_TEXT, boost::bind (&TMSPage::tms_user_changed, this));
652 _tms_password->Bind (wxEVT_TEXT, boost::bind (&TMSPage::tms_password_changed, this));
655 void config_changed ()
657 Config* config = Config::instance ();
659 checked_set (_tms_protocol, config->tms_protocol ());
660 checked_set (_tms_ip, config->tms_ip ());
661 checked_set (_tms_path, config->tms_path ());
662 checked_set (_tms_user, config->tms_user ());
663 checked_set (_tms_password, config->tms_password ());
666 void tms_protocol_changed ()
668 Config::instance()->set_tms_protocol (static_cast<Protocol> (_tms_protocol->GetSelection ()));
671 void tms_ip_changed ()
673 Config::instance()->set_tms_ip (wx_to_std (_tms_ip->GetValue ()));
676 void tms_path_changed ()
678 Config::instance()->set_tms_path (wx_to_std (_tms_path->GetValue ()));
681 void tms_user_changed ()
683 Config::instance()->set_tms_user (wx_to_std (_tms_user->GetValue ()));
686 void tms_password_changed ()
688 Config::instance()->set_tms_password (wx_to_std (_tms_password->GetValue ()));
691 wxChoice* _tms_protocol;
693 wxTextCtrl* _tms_path;
694 wxTextCtrl* _tms_user;
695 wxTextCtrl* _tms_password;
704 class EmailPage : public StandardPage
707 EmailPage (wxSize panel_size, int border)
708 : StandardPage (panel_size, border)
711 wxString GetName () const
717 wxBitmap GetLargeIcon () const
719 return wxBitmap ("email", wxBITMAP_TYPE_PNG_RESOURCE);
726 wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
727 table->AddGrowableCol (1, 1);
728 _panel->GetSizer()->Add (table, 1, wxEXPAND | wxALL, _border);
730 add_label_to_sizer (table, _panel, _("Outgoing mail server"), true);
732 wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL);
733 _server = new wxTextCtrl (_panel, wxID_ANY);
734 s->Add (_server, 1, wxEXPAND | wxALL);
735 add_label_to_sizer (s, _panel, _("port"), false);
736 _port = new wxSpinCtrl (_panel, wxID_ANY);
737 _port->SetRange (0, 65535);
739 table->Add (s, 1, wxEXPAND | wxALL);
742 add_label_to_sizer (table, _panel, _("Mail user name"), true);
743 _user = new wxTextCtrl (_panel, wxID_ANY);
744 table->Add (_user, 1, wxEXPAND | wxALL);
746 add_label_to_sizer (table, _panel, _("Mail password"), true);
747 _password = new wxTextCtrl (_panel, wxID_ANY);
748 table->Add (_password, 1, wxEXPAND | wxALL);
750 _server->Bind (wxEVT_TEXT, boost::bind (&EmailPage::server_changed, this));
751 _port->Bind (wxEVT_SPINCTRL, boost::bind (&EmailPage::port_changed, this));
752 _user->Bind (wxEVT_TEXT, boost::bind (&EmailPage::user_changed, this));
753 _password->Bind (wxEVT_TEXT, boost::bind (&EmailPage::password_changed, this));
756 void config_changed ()
758 Config* config = Config::instance ();
760 checked_set (_server, config->mail_server ());
761 checked_set (_port, config->mail_port ());
762 checked_set (_user, config->mail_user ());
763 checked_set (_password, config->mail_password ());
766 void server_changed ()
768 Config::instance()->set_mail_server (wx_to_std (_server->GetValue ()));
773 Config::instance()->set_mail_port (_port->GetValue ());
778 Config::instance()->set_mail_user (wx_to_std (_user->GetValue ()));
781 void password_changed ()
783 Config::instance()->set_mail_password (wx_to_std (_password->GetValue ()));
789 wxTextCtrl* _password;
792 class KDMEmailPage : public StandardPage
796 KDMEmailPage (wxSize panel_size, int border)
798 /* We have to force both width and height of this one */
799 : StandardPage (wxSize (panel_size.GetWidth(), 128), border)
801 : StandardPage (panel_size, border)
805 wxString GetName () const
807 return _("KDM Email");
811 wxBitmap GetLargeIcon () const
813 return wxBitmap ("kdm_email", wxBITMAP_TYPE_PNG_RESOURCE);
820 wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
821 table->AddGrowableCol (1, 1);
822 _panel->GetSizer()->Add (table, 1, wxEXPAND | wxALL, _border);
824 add_label_to_sizer (table, _panel, _("Subject"), true);
825 _subject = new wxTextCtrl (_panel, wxID_ANY);
826 table->Add (_subject, 1, wxEXPAND | wxALL);
828 add_label_to_sizer (table, _panel, _("From address"), true);
829 _from = new wxTextCtrl (_panel, wxID_ANY);
830 table->Add (_from, 1, wxEXPAND | wxALL);
832 vector<string> columns;
833 columns.push_back (wx_to_std (_("Address")));
834 add_label_to_sizer (table, _panel, _("CC addresses"), true);
835 _cc = new EditableList<string, EmailDialog> (
838 bind (&Config::kdm_cc, Config::instance()),
839 bind (&Config::set_kdm_cc, Config::instance(), _1),
842 table->Add (_cc, 1, wxEXPAND | wxALL);
844 add_label_to_sizer (table, _panel, _("BCC address"), true);
845 _bcc = new wxTextCtrl (_panel, wxID_ANY);
846 table->Add (_bcc, 1, wxEXPAND | wxALL);
848 _email = new wxTextCtrl (_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize (-1, 200), wxTE_MULTILINE);
849 _panel->GetSizer()->Add (_email, 0, wxEXPAND | wxALL, _border);
851 _reset_email = new wxButton (_panel, wxID_ANY, _("Reset to default subject and text"));
852 _panel->GetSizer()->Add (_reset_email, 0, wxEXPAND | wxALL, _border);
856 _subject->Bind (wxEVT_TEXT, boost::bind (&KDMEmailPage::kdm_subject_changed, this));
857 _from->Bind (wxEVT_TEXT, boost::bind (&KDMEmailPage::kdm_from_changed, this));
858 _bcc->Bind (wxEVT_TEXT, boost::bind (&KDMEmailPage::kdm_bcc_changed, this));
859 _email->Bind (wxEVT_TEXT, boost::bind (&KDMEmailPage::kdm_email_changed, this));
860 _reset_email->Bind (wxEVT_BUTTON, boost::bind (&KDMEmailPage::reset_email, this));
863 void config_changed ()
865 Config* config = Config::instance ();
867 checked_set (_subject, config->kdm_subject ());
868 checked_set (_from, config->kdm_from ());
869 checked_set (_bcc, config->kdm_bcc ());
870 checked_set (_email, Config::instance()->kdm_email ());
873 void kdm_subject_changed ()
875 Config::instance()->set_kdm_subject (wx_to_std (_subject->GetValue ()));
878 void kdm_from_changed ()
880 Config::instance()->set_kdm_from (wx_to_std (_from->GetValue ()));
883 void kdm_bcc_changed ()
885 Config::instance()->set_kdm_bcc (wx_to_std (_bcc->GetValue ()));
888 void kdm_email_changed ()
890 if (_email->GetValue().IsEmpty ()) {
891 /* Sometimes we get sent an erroneous notification that the email
892 is empty; I don't know why.
896 Config::instance()->set_kdm_email (wx_to_std (_email->GetValue ()));
901 Config::instance()->reset_kdm_email ();
902 checked_set (_email, Config::instance()->kdm_email ());
905 wxTextCtrl* _subject;
907 EditableList<string, EmailDialog>* _cc;
910 wxButton* _reset_email;
913 class AccountsPage : public StandardPage
916 AccountsPage (wxSize panel_size, int border)
917 : StandardPage (panel_size, border)
920 wxString GetName () const
922 return _("Accounts");
926 wxBitmap GetLargeIcon () const
928 return wxBitmap ("accounts", wxBITMAP_TYPE_PNG_RESOURCE);
934 wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
935 table->AddGrowableCol (1, 1);
936 _panel->GetSizer()->Add (table, 1, wxEXPAND | wxALL, _border);
938 add_label_to_sizer (table, _panel, _("certificates.barco.com username"), true);
939 _barco_username = new wxTextCtrl (_panel, wxID_ANY);
940 table->Add (_barco_username, 1, wxEXPAND | wxALL);
942 add_label_to_sizer (table, _panel, _("certificates.barco.com password"), true);
943 _barco_password = new wxTextCtrl (_panel, wxID_ANY);
944 table->Add (_barco_password, 1, wxEXPAND | wxALL);
946 add_label_to_sizer (table, _panel, _("certificates.christiedigital.com username"), true);
947 _christie_username = new wxTextCtrl (_panel, wxID_ANY);
948 table->Add (_christie_username, 1, wxEXPAND | wxALL);
950 add_label_to_sizer (table, _panel, _("certificates.christiedigital.com password"), true);
951 _christie_password = new wxTextCtrl (_panel, wxID_ANY);
952 table->Add (_christie_password, 1, wxEXPAND | wxALL);
954 _barco_username->Bind (wxEVT_TEXT, boost::bind(&AccountsPage::barco_username_changed, this));
955 _barco_password->Bind (wxEVT_TEXT, boost::bind(&AccountsPage::barco_password_changed, this));
956 _christie_username->Bind (wxEVT_TEXT, boost::bind(&AccountsPage::christie_username_changed, this));
957 _christie_password->Bind (wxEVT_TEXT, boost::bind(&AccountsPage::christie_password_changed, this));
960 void config_changed ()
962 Config* config = Config::instance ();
964 checked_set (_barco_username, config->barco_username().get_value_or(""));
965 checked_set (_barco_password, config->barco_password().get_value_or(""));
966 checked_set (_christie_username, config->christie_username().get_value_or(""));
967 checked_set (_christie_password, config->christie_password().get_value_or(""));
970 void barco_username_changed ()
972 wxString const s = _barco_username->GetValue();
974 Config::instance()->set_barco_username (wx_to_std(s));
976 Config::instance()->unset_barco_username ();
980 void barco_password_changed ()
982 wxString const s = _barco_password->GetValue();
984 Config::instance()->set_barco_password (wx_to_std(s));
986 Config::instance()->unset_barco_password ();
990 void christie_username_changed ()
992 wxString const s = _christie_username->GetValue();
994 Config::instance()->set_christie_username (wx_to_std(s));
996 Config::instance()->unset_christie_username ();
1000 void christie_password_changed ()
1002 wxString const s = _christie_password->GetValue();
1004 Config::instance()->set_christie_password (wx_to_std(s));
1006 Config::instance()->unset_christie_password ();
1011 wxTextCtrl* _barco_username;
1012 wxTextCtrl* _barco_password;
1013 wxTextCtrl* _christie_username;
1014 wxTextCtrl* _christie_password;
1018 class NotificationsPage : public StandardPage
1021 NotificationsPage (wxSize panel_size, int border)
1022 #ifdef DCPOMATIC_OSX
1023 /* We have to force both width and height of this one */
1024 : StandardPage (wxSize (panel_size.GetWidth(), 128), border)
1026 : StandardPage (panel_size, border)
1030 wxString GetName () const
1032 return _("Notifications");
1035 #ifdef DCPOMATIC_OSX
1036 wxBitmap GetLargeIcon () const
1038 return wxBitmap ("notifications", wxBITMAP_TYPE_PNG_RESOURCE);
1045 wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
1046 table->AddGrowableCol (1, 1);
1047 _panel->GetSizer()->Add (table, 1, wxEXPAND | wxALL, _border);
1049 _enable_message_box = new wxCheckBox (_panel, wxID_ANY, _("Message box"));
1050 table->Add (_enable_message_box, 1, wxEXPAND | wxALL);
1051 table->AddSpacer (0);
1053 _enable_email = new wxCheckBox (_panel, wxID_ANY, _("Email"));
1054 table->Add (_enable_email, 1, wxEXPAND | wxALL);
1055 table->AddSpacer (0);
1057 add_label_to_sizer (table, _panel, _("Subject"), true);
1058 _subject = new wxTextCtrl (_panel, wxID_ANY);
1059 table->Add (_subject, 1, wxEXPAND | wxALL);
1061 add_label_to_sizer (table, _panel, _("From address"), true);
1062 _from = new wxTextCtrl (_panel, wxID_ANY);
1063 table->Add (_from, 1, wxEXPAND | wxALL);
1065 add_label_to_sizer (table, _panel, _("To address"), true);
1066 _to = new wxTextCtrl (_panel, wxID_ANY);
1067 table->Add (_to, 1, wxEXPAND | wxALL);
1069 vector<string> columns;
1070 columns.push_back (wx_to_std (_("Address")));
1071 add_label_to_sizer (table, _panel, _("CC addresses"), true);
1072 _cc = new EditableList<string, EmailDialog> (
1075 bind (&Config::notification_cc, Config::instance()),
1076 bind (&Config::set_notification_cc, Config::instance(), _1),
1079 table->Add (_cc, 1, wxEXPAND | wxALL);
1081 add_label_to_sizer (table, _panel, _("BCC address"), true);
1082 _bcc = new wxTextCtrl (_panel, wxID_ANY);
1083 table->Add (_bcc, 1, wxEXPAND | wxALL);
1085 _email = new wxTextCtrl (_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize (-1, 200), wxTE_MULTILINE);
1086 _panel->GetSizer()->Add (_email, 0, wxEXPAND | wxALL, _border);
1088 _reset_email = new wxButton (_panel, wxID_ANY, _("Reset to default subject and text"));
1089 _panel->GetSizer()->Add (_reset_email, 0, wxEXPAND | wxALL, _border);
1093 _enable_message_box->Bind (wxEVT_CHECKBOX, boost::bind (&NotificationsPage::type_changed, this, _enable_message_box, Config::MESSAGE_BOX));
1094 _enable_email->Bind (wxEVT_CHECKBOX, boost::bind (&NotificationsPage::type_changed, this, _enable_email, Config::EMAIL));
1096 _subject->Bind (wxEVT_TEXT, boost::bind (&NotificationsPage::notification_subject_changed, this));
1097 _from->Bind (wxEVT_TEXT, boost::bind (&NotificationsPage::notification_from_changed, this));
1098 _to->Bind (wxEVT_TEXT, boost::bind (&NotificationsPage::notification_to_changed, this));
1099 _bcc->Bind (wxEVT_TEXT, boost::bind (&NotificationsPage::notification_bcc_changed, this));
1100 _email->Bind (wxEVT_TEXT, boost::bind (&NotificationsPage::notification_email_changed, this));
1101 _reset_email->Bind (wxEVT_BUTTON, boost::bind (&NotificationsPage::reset_email, this));
1103 update_sensitivity ();
1106 void update_sensitivity ()
1108 bool const s = _enable_email->GetValue();
1109 _subject->Enable(s);
1115 _reset_email->Enable(s);
1118 void config_changed ()
1120 Config* config = Config::instance ();
1122 checked_set (_enable_message_box, config->notification(Config::MESSAGE_BOX));
1123 checked_set (_enable_email, config->notification(Config::EMAIL));
1124 checked_set (_subject, config->notification_subject ());
1125 checked_set (_from, config->notification_from ());
1126 checked_set (_to, config->notification_to ());
1127 checked_set (_bcc, config->notification_bcc ());
1128 checked_set (_email, Config::instance()->notification_email ());
1130 update_sensitivity ();
1133 void notification_subject_changed ()
1135 Config::instance()->set_notification_subject (wx_to_std (_subject->GetValue ()));
1138 void notification_from_changed ()
1140 Config::instance()->set_notification_from (wx_to_std (_from->GetValue ()));
1143 void notification_to_changed ()
1145 Config::instance()->set_notification_to (wx_to_std (_to->GetValue ()));
1148 void notification_bcc_changed ()
1150 Config::instance()->set_notification_bcc (wx_to_std (_bcc->GetValue ()));
1153 void notification_email_changed ()
1155 if (_email->GetValue().IsEmpty ()) {
1156 /* Sometimes we get sent an erroneous notification that the email
1157 is empty; I don't know why.
1161 Config::instance()->set_notification_email (wx_to_std (_email->GetValue ()));
1166 Config::instance()->reset_notification_email ();
1167 checked_set (_email, Config::instance()->notification_email ());
1170 void type_changed (wxCheckBox* b, Config::Notification n)
1172 Config::instance()->set_notification(n, b->GetValue());
1173 update_sensitivity ();
1176 wxCheckBox* _enable_message_box;
1177 wxCheckBox* _enable_email;
1179 wxTextCtrl* _subject;
1182 EditableList<string, EmailDialog>* _cc;
1185 wxButton* _reset_email;
1188 class CoverSheetPage : public StandardPage
1192 CoverSheetPage (wxSize panel_size, int border)
1193 #ifdef DCPOMATIC_OSX
1194 /* We have to force both width and height of this one */
1195 : StandardPage (wxSize (panel_size.GetWidth(), 128), border)
1197 : StandardPage (panel_size, border)
1201 wxString GetName () const
1203 return _("Cover Sheet");
1206 #ifdef DCPOMATIC_OSX
1207 wxBitmap GetLargeIcon () const
1209 return wxBitmap ("cover_sheet", wxBITMAP_TYPE_PNG_RESOURCE);
1216 _cover_sheet = new wxTextCtrl (_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize (-1, 200), wxTE_MULTILINE);
1217 _panel->GetSizer()->Add (_cover_sheet, 0, wxEXPAND | wxALL, _border);
1219 _reset_cover_sheet = new wxButton (_panel, wxID_ANY, _("Reset to default text"));
1220 _panel->GetSizer()->Add (_reset_cover_sheet, 0, wxEXPAND | wxALL, _border);
1222 _cover_sheet->Bind (wxEVT_TEXT, boost::bind (&CoverSheetPage::cover_sheet_changed, this));
1223 _reset_cover_sheet->Bind (wxEVT_BUTTON, boost::bind (&CoverSheetPage::reset_cover_sheet, this));
1226 void config_changed ()
1228 checked_set (_cover_sheet, Config::instance()->cover_sheet ());
1231 void cover_sheet_changed ()
1233 if (_cover_sheet->GetValue().IsEmpty ()) {
1234 /* Sometimes we get sent an erroneous notification that the cover sheet
1235 is empty; I don't know why.
1239 Config::instance()->set_cover_sheet (wx_to_std (_cover_sheet->GetValue ()));
1242 void reset_cover_sheet ()
1244 Config::instance()->reset_cover_sheet ();
1245 checked_set (_cover_sheet, Config::instance()->cover_sheet ());
1248 wxTextCtrl* _cover_sheet;
1249 wxButton* _reset_cover_sheet;
1253 /** @class AdvancedPage
1254 * @brief Advanced page of the preferences dialog.
1256 class AdvancedPage : public StockPage
1259 AdvancedPage (wxSize panel_size, int border)
1260 : StockPage (Kind_Advanced, panel_size, border)
1261 , _maximum_j2k_bandwidth (0)
1262 , _allow_any_dcp_frame_rate (0)
1263 , _allow_any_container (0)
1264 , _only_servers_encode (0)
1269 , _log_debug_decode (0)
1270 , _log_debug_encode (0)
1271 , _log_debug_email (0)
1275 void add_top_aligned_label_to_sizer (wxSizer* table, wxWindow* parent, wxString text)
1277 int flags = wxALIGN_TOP | wxTOP | wxLEFT;
1279 flags |= wxALIGN_RIGHT;
1282 wxStaticText* m = new wxStaticText (parent, wxID_ANY, text);
1283 table->Add (m, 0, flags, DCPOMATIC_SIZER_Y_GAP);
1288 wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
1289 table->AddGrowableCol (1, 1);
1290 _panel->GetSizer()->Add (table, 1, wxALL | wxEXPAND, _border);
1293 add_label_to_sizer (table, _panel, _("Maximum JPEG2000 bandwidth"), true);
1294 wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL);
1295 _maximum_j2k_bandwidth = new wxSpinCtrl (_panel);
1296 s->Add (_maximum_j2k_bandwidth, 1);
1297 add_label_to_sizer (s, _panel, _("Mbit/s"), false);
1301 _allow_any_dcp_frame_rate = new wxCheckBox (_panel, wxID_ANY, _("Allow any DCP frame rate"));
1302 table->Add (_allow_any_dcp_frame_rate, 1, wxEXPAND | wxALL);
1303 table->AddSpacer (0);
1305 _allow_any_container = new wxCheckBox (_panel, wxID_ANY, _("Allow non-standard container ratios"));
1306 table->Add (_allow_any_container, 1, wxEXPAND | wxALL);
1307 table->AddSpacer (0);
1309 wxStaticText* restart = add_label_to_sizer (table, _panel, _("(restart DCP-o-matic to see all ratios)"), false);
1310 wxFont font = restart->GetFont();
1311 font.SetStyle (wxFONTSTYLE_ITALIC);
1312 font.SetPointSize (font.GetPointSize() - 1);
1313 restart->SetFont (font);
1314 table->AddSpacer (0);
1316 _only_servers_encode = new wxCheckBox (_panel, wxID_ANY, _("Only servers encode"));
1317 table->Add (_only_servers_encode, 1, wxEXPAND | wxALL);
1318 table->AddSpacer (0);
1321 add_label_to_sizer (table, _panel, _("Maximum number of frames to store per thread"), true);
1322 wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL);
1323 _frames_in_memory_multiplier = new wxSpinCtrl (_panel);
1324 s->Add (_frames_in_memory_multiplier, 1);
1329 add_top_aligned_label_to_sizer (table, _panel, _("DCP metadata filename format"));
1330 dcp::NameFormat::Map titles;
1331 titles['t'] = "type (cpl/pkl)";
1332 dcp::NameFormat::Map examples;
1333 examples['t'] = "cpl";
1334 _dcp_metadata_filename_format = new NameFormatEditor (
1335 _panel, Config::instance()->dcp_metadata_filename_format(), titles, examples, "_eb1c112c-ca3c-4ae6-9263-c6714ff05d64.xml"
1337 table->Add (_dcp_metadata_filename_format->panel(), 1, wxEXPAND | wxALL);
1341 add_top_aligned_label_to_sizer (table, _panel, _("DCP asset filename format"));
1342 dcp::NameFormat::Map titles;
1343 titles['t'] = "type (j2c/pcm/sub)";
1344 titles['r'] = "reel number";
1345 titles['n'] = "number of reels";
1346 titles['c'] = "content filename";
1347 dcp::NameFormat::Map examples;
1348 examples['t'] = "j2c";
1349 examples['r'] = "1";
1350 examples['n'] = "4";
1351 examples['c'] = "myfile.mp4";
1352 _dcp_asset_filename_format = new NameFormatEditor (
1353 _panel, Config::instance()->dcp_asset_filename_format(), titles, examples, "_eb1c112c-ca3c-4ae6-9263-c6714ff05d64.mxf"
1355 table->Add (_dcp_asset_filename_format->panel(), 1, wxEXPAND | wxALL);
1359 add_top_aligned_label_to_sizer (table, _panel, _("Log"));
1360 wxBoxSizer* t = new wxBoxSizer (wxVERTICAL);
1361 _log_general = new wxCheckBox (_panel, wxID_ANY, _("General"));
1362 t->Add (_log_general, 1, wxEXPAND | wxALL);
1363 _log_warning = new wxCheckBox (_panel, wxID_ANY, _("Warnings"));
1364 t->Add (_log_warning, 1, wxEXPAND | wxALL);
1365 _log_error = new wxCheckBox (_panel, wxID_ANY, _("Errors"));
1366 t->Add (_log_error, 1, wxEXPAND | wxALL);
1367 /// TRANSLATORS: translate the word "Timing" here; do not include the "Config|" prefix
1368 _log_timing = new wxCheckBox (_panel, wxID_ANY, S_("Config|Timing"));
1369 t->Add (_log_timing, 1, wxEXPAND | wxALL);
1370 _log_debug_decode = new wxCheckBox (_panel, wxID_ANY, _("Debug: decode"));
1371 t->Add (_log_debug_decode, 1, wxEXPAND | wxALL);
1372 _log_debug_encode = new wxCheckBox (_panel, wxID_ANY, _("Debug: encode"));
1373 t->Add (_log_debug_encode, 1, wxEXPAND | wxALL);
1374 _log_debug_email = new wxCheckBox (_panel, wxID_ANY, _("Debug: email sending"));
1375 t->Add (_log_debug_email, 1, wxEXPAND | wxALL);
1376 table->Add (t, 0, wxALL, 6);
1379 #ifdef DCPOMATIC_WINDOWS
1380 _win32_console = new wxCheckBox (_panel, wxID_ANY, _("Open console window"));
1381 table->Add (_win32_console, 1, wxEXPAND | wxALL);
1382 table->AddSpacer (0);
1385 _maximum_j2k_bandwidth->SetRange (1, 1000);
1386 _maximum_j2k_bandwidth->Bind (wxEVT_SPINCTRL, boost::bind (&AdvancedPage::maximum_j2k_bandwidth_changed, this));
1387 _allow_any_dcp_frame_rate->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::allow_any_dcp_frame_rate_changed, this));
1388 _allow_any_container->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::allow_any_container_changed, this));
1389 _only_servers_encode->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::only_servers_encode_changed, this));
1390 _frames_in_memory_multiplier->Bind (wxEVT_SPINCTRL, boost::bind(&AdvancedPage::frames_in_memory_multiplier_changed, this));
1391 _dcp_metadata_filename_format->Changed.connect (boost::bind (&AdvancedPage::dcp_metadata_filename_format_changed, this));
1392 _dcp_asset_filename_format->Changed.connect (boost::bind (&AdvancedPage::dcp_asset_filename_format_changed, this));
1393 _log_general->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::log_changed, this));
1394 _log_warning->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::log_changed, this));
1395 _log_error->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::log_changed, this));
1396 _log_timing->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::log_changed, this));
1397 _log_debug_decode->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::log_changed, this));
1398 _log_debug_encode->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::log_changed, this));
1399 _log_debug_email->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::log_changed, this));
1400 #ifdef DCPOMATIC_WINDOWS
1401 _win32_console->Bind (wxEVT_CHECKBOX, boost::bind (&AdvancedPage::win32_console_changed, this));
1405 void config_changed ()
1407 Config* config = Config::instance ();
1409 checked_set (_maximum_j2k_bandwidth, config->maximum_j2k_bandwidth() / 1000000);
1410 checked_set (_allow_any_dcp_frame_rate, config->allow_any_dcp_frame_rate ());
1411 checked_set (_allow_any_container, config->allow_any_container ());
1412 checked_set (_only_servers_encode, config->only_servers_encode ());
1413 checked_set (_log_general, config->log_types() & LogEntry::TYPE_GENERAL);
1414 checked_set (_log_warning, config->log_types() & LogEntry::TYPE_WARNING);
1415 checked_set (_log_error, config->log_types() & LogEntry::TYPE_ERROR);
1416 checked_set (_log_timing, config->log_types() & LogEntry::TYPE_TIMING);
1417 checked_set (_log_debug_decode, config->log_types() & LogEntry::TYPE_DEBUG_DECODE);
1418 checked_set (_log_debug_encode, config->log_types() & LogEntry::TYPE_DEBUG_ENCODE);
1419 checked_set (_log_debug_email, config->log_types() & LogEntry::TYPE_DEBUG_EMAIL);
1420 checked_set (_frames_in_memory_multiplier, config->frames_in_memory_multiplier());
1421 #ifdef DCPOMATIC_WINDOWS
1422 checked_set (_win32_console, config->win32_console());
1426 void maximum_j2k_bandwidth_changed ()
1428 Config::instance()->set_maximum_j2k_bandwidth (_maximum_j2k_bandwidth->GetValue() * 1000000);
1431 void frames_in_memory_multiplier_changed ()
1433 Config::instance()->set_frames_in_memory_multiplier (_frames_in_memory_multiplier->GetValue());
1436 void allow_any_dcp_frame_rate_changed ()
1438 Config::instance()->set_allow_any_dcp_frame_rate (_allow_any_dcp_frame_rate->GetValue ());
1441 void allow_any_container_changed ()
1443 Config::instance()->set_allow_any_container (_allow_any_container->GetValue ());
1446 void only_servers_encode_changed ()
1448 Config::instance()->set_only_servers_encode (_only_servers_encode->GetValue ());
1451 void dcp_metadata_filename_format_changed ()
1453 Config::instance()->set_dcp_metadata_filename_format (_dcp_metadata_filename_format->get ());
1456 void dcp_asset_filename_format_changed ()
1458 Config::instance()->set_dcp_asset_filename_format (_dcp_asset_filename_format->get ());
1464 if (_log_general->GetValue ()) {
1465 types |= LogEntry::TYPE_GENERAL;
1467 if (_log_warning->GetValue ()) {
1468 types |= LogEntry::TYPE_WARNING;
1470 if (_log_error->GetValue ()) {
1471 types |= LogEntry::TYPE_ERROR;
1473 if (_log_timing->GetValue ()) {
1474 types |= LogEntry::TYPE_TIMING;
1476 if (_log_debug_decode->GetValue ()) {
1477 types |= LogEntry::TYPE_DEBUG_DECODE;
1479 if (_log_debug_encode->GetValue ()) {
1480 types |= LogEntry::TYPE_DEBUG_ENCODE;
1482 if (_log_debug_email->GetValue ()) {
1483 types |= LogEntry::TYPE_DEBUG_EMAIL;
1485 Config::instance()->set_log_types (types);
1488 #ifdef DCPOMATIC_WINDOWS
1489 void win32_console_changed ()
1491 Config::instance()->set_win32_console (_win32_console->GetValue ());
1495 wxSpinCtrl* _maximum_j2k_bandwidth;
1496 wxSpinCtrl* _frames_in_memory_multiplier;
1497 wxCheckBox* _allow_any_dcp_frame_rate;
1498 wxCheckBox* _allow_any_container;
1499 wxCheckBox* _only_servers_encode;
1500 NameFormatEditor* _dcp_metadata_filename_format;
1501 NameFormatEditor* _dcp_asset_filename_format;
1502 wxCheckBox* _log_general;
1503 wxCheckBox* _log_warning;
1504 wxCheckBox* _log_error;
1505 wxCheckBox* _log_timing;
1506 wxCheckBox* _log_debug_decode;
1507 wxCheckBox* _log_debug_encode;
1508 wxCheckBox* _log_debug_email;
1509 #ifdef DCPOMATIC_WINDOWS
1510 wxCheckBox* _win32_console;
1514 wxPreferencesEditor*
1515 create_full_config_dialog ()
1517 wxPreferencesEditor* e = new wxPreferencesEditor ();
1519 #ifdef DCPOMATIC_OSX
1520 /* Width that we force some of the config panels to be on OSX so that
1521 the containing window doesn't shrink too much when we select those panels.
1522 This is obviously an unpleasant hack.
1524 wxSize ps = wxSize (600, -1);
1525 int const border = 16;
1527 wxSize ps = wxSize (-1, -1);
1528 int const border = 8;
1531 e->AddPage (new FullGeneralPage (ps, border));
1532 e->AddPage (new DefaultsPage (ps, border));
1533 e->AddPage (new EncodingServersPage (ps, border));
1534 e->AddPage (new KeysPage (ps, border));
1535 e->AddPage (new TMSPage (ps, border));
1536 e->AddPage (new EmailPage (ps, border));
1537 e->AddPage (new KDMEmailPage (ps, border));
1538 e->AddPage (new AccountsPage (ps, border));
1539 e->AddPage (new NotificationsPage (ps, border));
1540 e->AddPage (new CoverSheetPage (ps, border));
1541 e->AddPage (new AdvancedPage (ps, border));