2 Copyright (C) 2012-2015 Carl Hetherington <cth@carlh.net>
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 /** @file src/config_dialog.cc
21 * @brief A dialogue to edit DCP-o-matic configuration.
24 #include "config_dialog.h"
26 #include "editable_list.h"
27 #include "filter_dialog.h"
28 #include "dir_picker_ctrl.h"
29 #include "isdcf_metadata_dialog.h"
30 #include "server_dialog.h"
31 #include "make_chain_dialog.h"
32 #include "lib/config.h"
33 #include "lib/ratio.h"
34 #include "lib/filter.h"
35 #include "lib/dcp_content_type.h"
38 #include "lib/raw_convert.h"
39 #include "lib/cross.h"
40 #include "lib/exceptions.h"
41 #include <dcp/exceptions.h>
42 #include <dcp/certificate_chain.h>
43 #include <wx/stdpaths.h>
44 #include <wx/preferences.h>
45 #include <wx/filepicker.h>
46 #include <wx/spinctrl.h>
47 #include <boost/lexical_cast.hpp>
48 #include <boost/filesystem.hpp>
49 #include <boost/foreach.hpp>
57 using boost::shared_ptr;
58 using boost::lexical_cast;
59 using boost::function;
64 Page (wxSize panel_size, int border)
67 , _panel_size (panel_size)
68 , _window_exists (false)
70 _config_connection = Config::instance()->Changed.connect (boost::bind (&Page::config_changed_wrapper, this));
76 wxWindow* create_window (wxWindow* parent)
78 _panel = new wxPanel (parent, wxID_ANY, wxDefaultPosition, _panel_size);
79 wxBoxSizer* s = new wxBoxSizer (wxVERTICAL);
83 _window_exists = true;
86 _panel->Bind (wxEVT_DESTROY, boost::bind (&Page::window_destroyed, this));
95 virtual void config_changed () = 0;
96 virtual void setup () = 0;
98 void config_changed_wrapper ()
100 if (_window_exists) {
105 void window_destroyed ()
107 _window_exists = false;
111 boost::signals2::scoped_connection _config_connection;
115 class StockPage : public wxStockPreferencesPage, public Page
118 StockPage (Kind kind, wxSize panel_size, int border)
119 : wxStockPreferencesPage (kind)
120 , Page (panel_size, border)
123 wxWindow* CreateWindow (wxWindow* parent)
125 return create_window (parent);
129 class StandardPage : public wxPreferencesPage, public Page
132 StandardPage (wxSize panel_size, int border)
133 : Page (panel_size, border)
136 wxWindow* CreateWindow (wxWindow* parent)
138 return create_window (parent);
142 class GeneralPage : public StockPage
145 GeneralPage (wxSize panel_size, int border)
146 : StockPage (Kind_General, panel_size, border)
152 wxGridBagSizer* table = new wxGridBagSizer (DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
153 _panel->GetSizer()->Add (table, 1, wxALL | wxEXPAND, _border);
156 _set_language = new wxCheckBox (_panel, wxID_ANY, _("Set language"));
157 table->Add (_set_language, wxGBPosition (r, 0));
158 _language = new wxChoice (_panel, wxID_ANY);
159 _language->Append (wxT ("Deutsch"));
160 _language->Append (wxT ("English"));
161 _language->Append (wxT ("Español"));
162 _language->Append (wxT ("Français"));
163 _language->Append (wxT ("Italiano"));
164 _language->Append (wxT ("Nederlands"));
165 _language->Append (wxT ("Svenska"));
166 _language->Append (wxT ("Русский"));
167 _language->Append (wxT ("Polski"));
168 _language->Append (wxT ("Danske"));
169 table->Add (_language, wxGBPosition (r, 1));
172 wxStaticText* restart = add_label_to_grid_bag_sizer (
173 table, _panel, _("(restart DCP-o-matic to see language changes)"), false, wxGBPosition (r, 0), wxGBSpan (1, 2)
175 wxFont font = restart->GetFont();
176 font.SetStyle (wxFONTSTYLE_ITALIC);
177 font.SetPointSize (font.GetPointSize() - 1);
178 restart->SetFont (font);
181 add_label_to_grid_bag_sizer (table, _panel, _("Threads to use for encoding on this host"), true, wxGBPosition (r, 0));
182 _num_local_encoding_threads = new wxSpinCtrl (_panel);
183 table->Add (_num_local_encoding_threads, wxGBPosition (r, 1));
186 _automatic_audio_analysis = new wxCheckBox (_panel, wxID_ANY, _("Automatically analyse content audio"));
187 table->Add (_automatic_audio_analysis, wxGBPosition (r, 0), wxGBSpan (1, 2));
190 _check_for_updates = new wxCheckBox (_panel, wxID_ANY, _("Check for updates on startup"));
191 table->Add (_check_for_updates, wxGBPosition (r, 0), wxGBSpan (1, 2));
194 _check_for_test_updates = new wxCheckBox (_panel, wxID_ANY, _("Check for testing updates as well as stable ones"));
195 table->Add (_check_for_test_updates, wxGBPosition (r, 0), wxGBSpan (1, 2));
198 wxFlexGridSizer* bottom_table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
199 bottom_table->AddGrowableCol (1, 1);
201 add_label_to_sizer (bottom_table, _panel, _("Issuer"), true);
202 _issuer = new wxTextCtrl (_panel, wxID_ANY);
203 bottom_table->Add (_issuer, 1, wxALL | wxEXPAND);
205 add_label_to_sizer (bottom_table, _panel, _("Creator"), true);
206 _creator = new wxTextCtrl (_panel, wxID_ANY);
207 bottom_table->Add (_creator, 1, wxALL | wxEXPAND);
209 table->Add (bottom_table, wxGBPosition (r, 0), wxGBSpan (2, 2), wxEXPAND);
212 _set_language->Bind (wxEVT_COMMAND_CHECKBOX_CLICKED, boost::bind (&GeneralPage::set_language_changed, this));
213 _language->Bind (wxEVT_COMMAND_CHOICE_SELECTED, boost::bind (&GeneralPage::language_changed, this));
215 _num_local_encoding_threads->SetRange (1, 128);
216 _num_local_encoding_threads->Bind (wxEVT_COMMAND_SPINCTRL_UPDATED, boost::bind (&GeneralPage::num_local_encoding_threads_changed, this));
218 _automatic_audio_analysis->Bind (wxEVT_COMMAND_CHECKBOX_CLICKED, boost::bind (&GeneralPage::automatic_audio_analysis_changed, this));
219 _check_for_updates->Bind (wxEVT_COMMAND_CHECKBOX_CLICKED, boost::bind (&GeneralPage::check_for_updates_changed, this));
220 _check_for_test_updates->Bind (wxEVT_COMMAND_CHECKBOX_CLICKED, boost::bind (&GeneralPage::check_for_test_updates_changed, this));
222 _issuer->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&GeneralPage::issuer_changed, this));
223 _creator->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&GeneralPage::creator_changed, this));
226 void config_changed ()
228 Config* config = Config::instance ();
230 checked_set (_set_language, static_cast<bool>(config->language()));
232 if (config->language().get_value_or ("") == "fr") {
233 checked_set (_language, 3);
234 } else if (config->language().get_value_or ("") == "it") {
235 checked_set (_language, 4);
236 } else if (config->language().get_value_or ("") == "es") {
237 checked_set (_language, 2);
238 } else if (config->language().get_value_or ("") == "sv") {
239 checked_set (_language, 6);
240 } else if (config->language().get_value_or ("") == "de") {
241 checked_set (_language, 0);
242 } else if (config->language().get_value_or ("") == "nl") {
243 checked_set (_language, 5);
244 } else if (config->language().get_value_or ("") == "ru") {
245 checked_set (_language, 7);
246 } else if (config->language().get_value_or ("") == "pl") {
247 checked_set (_language, 8);
248 } else if (config->language().get_value_or ("") == "da") {
249 checked_set (_language, 9);
251 _language->SetSelection (1);
254 setup_language_sensitivity ();
256 checked_set (_num_local_encoding_threads, config->num_local_encoding_threads ());
257 checked_set (_automatic_audio_analysis, config->automatic_audio_analysis ());
258 checked_set (_check_for_updates, config->check_for_updates ());
259 checked_set (_check_for_test_updates, config->check_for_test_updates ());
260 checked_set (_issuer, config->dcp_issuer ());
261 checked_set (_creator, config->dcp_creator ());
264 void setup_language_sensitivity ()
266 _language->Enable (_set_language->GetValue ());
269 void set_language_changed ()
271 setup_language_sensitivity ();
272 if (_set_language->GetValue ()) {
275 Config::instance()->unset_language ();
279 void language_changed ()
281 switch (_language->GetSelection ()) {
283 Config::instance()->set_language ("de");
286 Config::instance()->set_language ("en");
289 Config::instance()->set_language ("es");
292 Config::instance()->set_language ("fr");
295 Config::instance()->set_language ("it");
298 Config::instance()->set_language ("nl");
301 Config::instance()->set_language ("sv");
304 Config::instance()->set_language ("ru");
307 Config::instance()->set_language ("pl");
310 Config::instance()->set_language ("da");
315 void automatic_audio_analysis_changed ()
317 Config::instance()->set_automatic_audio_analysis (_automatic_audio_analysis->GetValue ());
320 void check_for_updates_changed ()
322 Config::instance()->set_check_for_updates (_check_for_updates->GetValue ());
325 void check_for_test_updates_changed ()
327 Config::instance()->set_check_for_test_updates (_check_for_test_updates->GetValue ());
330 void num_local_encoding_threads_changed ()
332 Config::instance()->set_num_local_encoding_threads (_num_local_encoding_threads->GetValue ());
335 void issuer_changed ()
337 Config::instance()->set_dcp_issuer (wx_to_std (_issuer->GetValue ()));
340 void creator_changed ()
342 Config::instance()->set_dcp_creator (wx_to_std (_creator->GetValue ()));
345 wxCheckBox* _set_language;
347 wxSpinCtrl* _num_local_encoding_threads;
348 wxCheckBox* _automatic_audio_analysis;
349 wxCheckBox* _check_for_updates;
350 wxCheckBox* _check_for_test_updates;
352 wxTextCtrl* _creator;
355 class DefaultsPage : public StandardPage
358 DefaultsPage (wxSize panel_size, int border)
359 : StandardPage (panel_size, border)
362 wxString GetName () const
364 return _("Defaults");
368 wxBitmap GetLargeIcon () const
370 return wxBitmap ("defaults", wxBITMAP_TYPE_PNG_RESOURCE);
377 wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
378 table->AddGrowableCol (1, 1);
379 _panel->GetSizer()->Add (table, 1, wxALL | wxEXPAND, _border);
382 add_label_to_sizer (table, _panel, _("Default duration of still images"), true);
383 wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL);
384 _still_length = new wxSpinCtrl (_panel);
385 s->Add (_still_length);
386 add_label_to_sizer (s, _panel, _("s"), false);
390 add_label_to_sizer (table, _panel, _("Default directory for new films"), true);
391 #ifdef DCPOMATIC_USE_OWN_DIR_PICKER
392 _directory = new DirPickerCtrl (_panel);
394 _directory = new wxDirPickerCtrl (_panel, wxDD_DIR_MUST_EXIST);
396 table->Add (_directory, 1, wxEXPAND);
398 add_label_to_sizer (table, _panel, _("Default ISDCF name details"), true);
399 _isdcf_metadata_button = new wxButton (_panel, wxID_ANY, _("Edit..."));
400 table->Add (_isdcf_metadata_button);
402 add_label_to_sizer (table, _panel, _("Default container"), true);
403 _container = new wxChoice (_panel, wxID_ANY);
404 table->Add (_container);
406 add_label_to_sizer (table, _panel, _("Default content type"), true);
407 _dcp_content_type = new wxChoice (_panel, wxID_ANY);
408 table->Add (_dcp_content_type);
411 add_label_to_sizer (table, _panel, _("Default JPEG2000 bandwidth"), true);
412 wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL);
413 _j2k_bandwidth = new wxSpinCtrl (_panel);
414 s->Add (_j2k_bandwidth);
415 add_label_to_sizer (s, _panel, _("Mbit/s"), false);
420 add_label_to_sizer (table, _panel, _("Default audio delay"), true);
421 wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL);
422 _audio_delay = new wxSpinCtrl (_panel);
423 s->Add (_audio_delay);
424 add_label_to_sizer (s, _panel, _("ms"), false);
428 add_label_to_sizer (table, _panel, _("Default standard"), true);
429 _standard = new wxChoice (_panel, wxID_ANY);
430 table->Add (_standard);
432 _still_length->SetRange (1, 3600);
433 _still_length->Bind (wxEVT_COMMAND_SPINCTRL_UPDATED, boost::bind (&DefaultsPage::still_length_changed, this));
435 _directory->Bind (wxEVT_COMMAND_DIRPICKER_CHANGED, boost::bind (&DefaultsPage::directory_changed, this));
437 _isdcf_metadata_button->Bind (wxEVT_COMMAND_BUTTON_CLICKED, boost::bind (&DefaultsPage::edit_isdcf_metadata_clicked, this));
439 vector<Ratio const *> ratios = Ratio::all ();
440 for (size_t i = 0; i < ratios.size(); ++i) {
441 _container->Append (std_to_wx (ratios[i]->nickname ()));
444 _container->Bind (wxEVT_COMMAND_CHOICE_SELECTED, boost::bind (&DefaultsPage::container_changed, this));
446 vector<DCPContentType const *> const ct = DCPContentType::all ();
447 for (size_t i = 0; i < ct.size(); ++i) {
448 _dcp_content_type->Append (std_to_wx (ct[i]->pretty_name ()));
451 _dcp_content_type->Bind (wxEVT_COMMAND_CHOICE_SELECTED, boost::bind (&DefaultsPage::dcp_content_type_changed, this));
453 _j2k_bandwidth->SetRange (50, 250);
454 _j2k_bandwidth->Bind (wxEVT_COMMAND_SPINCTRL_UPDATED, boost::bind (&DefaultsPage::j2k_bandwidth_changed, this));
456 _audio_delay->SetRange (-1000, 1000);
457 _audio_delay->Bind (wxEVT_COMMAND_SPINCTRL_UPDATED, boost::bind (&DefaultsPage::audio_delay_changed, this));
459 _standard->Append (_("SMPTE"));
460 _standard->Append (_("Interop"));
461 _standard->Bind (wxEVT_COMMAND_CHOICE_SELECTED, boost::bind (&DefaultsPage::standard_changed, this));
464 void config_changed ()
466 Config* config = Config::instance ();
468 vector<Ratio const *> ratios = Ratio::all ();
469 for (size_t i = 0; i < ratios.size(); ++i) {
470 if (ratios[i] == config->default_container ()) {
471 _container->SetSelection (i);
475 vector<DCPContentType const *> const ct = DCPContentType::all ();
476 for (size_t i = 0; i < ct.size(); ++i) {
477 if (ct[i] == config->default_dcp_content_type ()) {
478 _dcp_content_type->SetSelection (i);
482 checked_set (_still_length, config->default_still_length ());
483 _directory->SetPath (std_to_wx (config->default_directory_or (wx_to_std (wxStandardPaths::Get().GetDocumentsDir())).string ()));
484 checked_set (_j2k_bandwidth, config->default_j2k_bandwidth() / 1000000);
485 _j2k_bandwidth->SetRange (50, config->maximum_j2k_bandwidth() / 1000000);
486 checked_set (_audio_delay, config->default_audio_delay ());
487 checked_set (_standard, config->default_interop() ? 1 : 0);
490 void j2k_bandwidth_changed ()
492 Config::instance()->set_default_j2k_bandwidth (_j2k_bandwidth->GetValue() * 1000000);
495 void audio_delay_changed ()
497 Config::instance()->set_default_audio_delay (_audio_delay->GetValue());
500 void directory_changed ()
502 Config::instance()->set_default_directory (wx_to_std (_directory->GetPath ()));
505 void edit_isdcf_metadata_clicked ()
507 ISDCFMetadataDialog* d = new ISDCFMetadataDialog (_panel, Config::instance()->default_isdcf_metadata (), false);
509 Config::instance()->set_default_isdcf_metadata (d->isdcf_metadata ());
513 void still_length_changed ()
515 Config::instance()->set_default_still_length (_still_length->GetValue ());
518 void container_changed ()
520 vector<Ratio const *> ratio = Ratio::all ();
521 Config::instance()->set_default_container (ratio[_container->GetSelection()]);
524 void dcp_content_type_changed ()
526 vector<DCPContentType const *> ct = DCPContentType::all ();
527 Config::instance()->set_default_dcp_content_type (ct[_dcp_content_type->GetSelection()]);
530 void standard_changed ()
532 Config::instance()->set_default_interop (_standard->GetSelection() == 1);
535 wxSpinCtrl* _j2k_bandwidth;
536 wxSpinCtrl* _audio_delay;
537 wxButton* _isdcf_metadata_button;
538 wxSpinCtrl* _still_length;
539 #ifdef DCPOMATIC_USE_OWN_DIR_PICKER
540 DirPickerCtrl* _directory;
542 wxDirPickerCtrl* _directory;
544 wxChoice* _container;
545 wxChoice* _dcp_content_type;
549 class EncodingServersPage : public StandardPage
552 EncodingServersPage (wxSize panel_size, int border)
553 : StandardPage (panel_size, border)
556 wxString GetName () const
562 wxBitmap GetLargeIcon () const
564 return wxBitmap ("servers", wxBITMAP_TYPE_PNG_RESOURCE);
571 _use_any_servers = new wxCheckBox (_panel, wxID_ANY, _("Use all servers"));
572 _panel->GetSizer()->Add (_use_any_servers, 0, wxALL, _border);
574 vector<string> columns;
575 columns.push_back (wx_to_std (_("IP address / host name")));
576 _servers_list = new EditableList<string, ServerDialog> (
579 boost::bind (&Config::servers, Config::instance()),
580 boost::bind (&Config::set_servers, Config::instance(), _1),
581 boost::bind (&EncodingServersPage::server_column, this, _1)
584 _panel->GetSizer()->Add (_servers_list, 1, wxEXPAND | wxALL, _border);
586 _use_any_servers->Bind (wxEVT_COMMAND_CHECKBOX_CLICKED, boost::bind (&EncodingServersPage::use_any_servers_changed, this));
589 void config_changed ()
591 checked_set (_use_any_servers, Config::instance()->use_any_servers ());
592 _servers_list->refresh ();
595 void use_any_servers_changed ()
597 Config::instance()->set_use_any_servers (_use_any_servers->GetValue ());
600 string server_column (string s)
605 wxCheckBox* _use_any_servers;
606 EditableList<string, ServerDialog>* _servers_list;
609 class CertificateChainEditor : public wxPanel
612 CertificateChainEditor (
616 function<void (shared_ptr<dcp::CertificateChain>)> set,
617 function<shared_ptr<const dcp::CertificateChain> (void)> get
623 wxFont subheading_font (*wxNORMAL_FONT);
624 subheading_font.SetWeight (wxFONTWEIGHT_BOLD);
626 _sizer = new wxBoxSizer (wxVERTICAL);
629 wxStaticText* m = new wxStaticText (this, wxID_ANY, title);
630 m->SetFont (subheading_font);
631 _sizer->Add (m, 0, wxALL, border);
634 wxBoxSizer* certificates_sizer = new wxBoxSizer (wxHORIZONTAL);
635 _sizer->Add (certificates_sizer, 0, wxLEFT | wxRIGHT, border);
637 _certificates = new wxListCtrl (this, wxID_ANY, wxDefaultPosition, wxSize (400, 150), wxLC_REPORT | wxLC_SINGLE_SEL);
642 ip.SetText (_("Type"));
644 _certificates->InsertColumn (0, ip);
650 ip.SetText (_("Thumbprint"));
653 wxFont font = ip.GetFont ();
654 font.SetFamily (wxFONTFAMILY_TELETYPE);
657 _certificates->InsertColumn (1, ip);
660 certificates_sizer->Add (_certificates, 1, wxEXPAND);
663 wxSizer* s = new wxBoxSizer (wxVERTICAL);
664 _add_certificate = new wxButton (this, wxID_ANY, _("Add..."));
665 s->Add (_add_certificate, 0, wxTOP | wxBOTTOM, DCPOMATIC_BUTTON_STACK_GAP);
666 _remove_certificate = new wxButton (this, wxID_ANY, _("Remove"));
667 s->Add (_remove_certificate, 0, wxTOP | wxBOTTOM, DCPOMATIC_BUTTON_STACK_GAP);
668 _export_certificate = new wxButton (this, wxID_ANY, _("Export"));
669 s->Add (_export_certificate, 0, wxTOP | wxBOTTOM, DCPOMATIC_BUTTON_STACK_GAP);
670 certificates_sizer->Add (s, 0, wxLEFT, DCPOMATIC_SIZER_X_GAP);
673 wxGridBagSizer* table = new wxGridBagSizer (DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
674 _sizer->Add (table, 1, wxALL | wxEXPAND, border);
677 add_label_to_grid_bag_sizer (table, this, _("Leaf private key"), true, wxGBPosition (r, 0));
678 _private_key = new wxStaticText (this, wxID_ANY, wxT (""));
679 wxFont font = _private_key->GetFont ();
680 font.SetFamily (wxFONTFAMILY_TELETYPE);
681 _private_key->SetFont (font);
682 table->Add (_private_key, wxGBPosition (r, 1), wxDefaultSpan, wxALIGN_CENTER_VERTICAL);
683 _load_private_key = new wxButton (this, wxID_ANY, _("Load..."));
684 table->Add (_load_private_key, wxGBPosition (r, 2));
687 _button_sizer = new wxBoxSizer (wxHORIZONTAL);
688 _remake_certificates = new wxButton (this, wxID_ANY, _("Re-make certificates and key..."));
689 _button_sizer->Add (_remake_certificates, 1, wxRIGHT, border);
690 table->Add (_button_sizer, wxGBPosition (r, 0), wxGBSpan (1, 3));
693 _add_certificate->Bind (wxEVT_COMMAND_BUTTON_CLICKED, boost::bind (&CertificateChainEditor::add_certificate, this));
694 _remove_certificate->Bind (wxEVT_COMMAND_BUTTON_CLICKED, boost::bind (&CertificateChainEditor::remove_certificate, this));
695 _export_certificate->Bind (wxEVT_COMMAND_BUTTON_CLICKED, boost::bind (&CertificateChainEditor::export_certificate, this));
696 _certificates->Bind (wxEVT_COMMAND_LIST_ITEM_SELECTED, boost::bind (&CertificateChainEditor::update_sensitivity, this));
697 _certificates->Bind (wxEVT_COMMAND_LIST_ITEM_DESELECTED, boost::bind (&CertificateChainEditor::update_sensitivity, this));
698 _remake_certificates->Bind (wxEVT_COMMAND_BUTTON_CLICKED, boost::bind (&CertificateChainEditor::remake_certificates, this));
699 _load_private_key->Bind (wxEVT_COMMAND_BUTTON_CLICKED, boost::bind (&CertificateChainEditor::load_private_key, this));
701 SetSizerAndFit (_sizer);
704 void config_changed ()
706 _chain.reset (new dcp::CertificateChain (*_get().get ()));
708 update_certificate_list ();
709 update_private_key ();
710 update_sensitivity ();
713 void add_button (wxWindow* button)
715 _button_sizer->Add (button);
720 void add_certificate ()
722 wxFileDialog* d = new wxFileDialog (this, _("Select Certificate File"));
724 if (d->ShowModal() == wxID_OK) {
726 dcp::Certificate c (dcp::file_to_string (wx_to_std (d->GetPath ())));
729 update_certificate_list ();
730 } catch (dcp::MiscError& e) {
731 error_dialog (this, wxString::Format (_("Could not read certificate file (%s)"), e.what ()));
737 update_sensitivity ();
740 void remove_certificate ()
742 int i = _certificates->GetNextItem (-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
747 _certificates->DeleteItem (i);
751 update_sensitivity ();
754 void export_certificate ()
756 int i = _certificates->GetNextItem (-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
761 wxFileDialog* d = new wxFileDialog (
762 this, _("Select Certificate File"), wxEmptyString, wxEmptyString, wxT ("PEM files (*.pem)|*.pem"),
763 wxFD_SAVE | wxFD_OVERWRITE_PROMPT
766 dcp::CertificateChain::List all = _chain->root_to_leaf ();
767 dcp::CertificateChain::List::iterator j = all.begin ();
768 for (int k = 0; k < i; ++k) {
772 if (d->ShowModal () == wxID_OK) {
773 FILE* f = fopen_boost (wx_to_std (d->GetPath ()), "w");
775 throw OpenFileError (wx_to_std (d->GetPath ()));
778 string const s = j->certificate (true);
779 fwrite (s.c_str(), 1, s.length(), f);
785 void update_certificate_list ()
787 _certificates->DeleteAllItems ();
789 dcp::CertificateChain::List certs = _chain->root_to_leaf ();
790 BOOST_FOREACH (dcp::Certificate const & i, certs) {
793 _certificates->InsertItem (item);
794 _certificates->SetItem (n, 1, std_to_wx (i.thumbprint ()));
797 _certificates->SetItem (n, 0, _("Root"));
798 } else if (n == (certs.size() - 1)) {
799 _certificates->SetItem (n, 0, _("Leaf"));
801 _certificates->SetItem (n, 0, _("Intermediate"));
808 void remake_certificates ()
810 shared_ptr<const dcp::CertificateChain> chain = _get ();
812 string subject_organization_name;
813 string subject_organizational_unit_name;
814 string root_common_name;
815 string intermediate_common_name;
816 string leaf_common_name;
818 dcp::CertificateChain::List all = chain->root_to_leaf ();
820 if (all.size() >= 1) {
822 subject_organization_name = chain->root().subject_organization_name ();
823 subject_organizational_unit_name = chain->root().subject_organizational_unit_name ();
824 root_common_name = chain->root().subject_common_name ();
827 if (all.size() >= 2) {
829 leaf_common_name = chain->leaf().subject_common_name ();
832 if (all.size() >= 3) {
833 /* Have an intermediate */
834 dcp::CertificateChain::List::iterator i = all.begin ();
836 intermediate_common_name = i->subject_common_name ();
839 MakeChainDialog* d = new MakeChainDialog (
841 subject_organization_name,
842 subject_organizational_unit_name,
844 intermediate_common_name,
848 if (d->ShowModal () == wxID_OK) {
850 new dcp::CertificateChain (
853 d->organisational_unit (),
854 d->root_common_name (),
855 d->intermediate_common_name (),
856 d->leaf_common_name ()
861 update_certificate_list ();
862 update_private_key ();
868 void update_sensitivity ()
870 _remove_certificate->Enable (_certificates->GetNextItem (-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED) != -1);
871 _export_certificate->Enable (_certificates->GetNextItem (-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED) != -1);
874 void update_private_key ()
876 checked_set (_private_key, dcp::private_key_fingerprint (_chain->key().get ()));
880 void load_private_key ()
882 wxFileDialog* d = new wxFileDialog (this, _("Select Key File"));
884 if (d->ShowModal() == wxID_OK) {
886 boost::filesystem::path p (wx_to_std (d->GetPath ()));
887 if (boost::filesystem::file_size (p) > 1024) {
888 error_dialog (this, wxString::Format (_("Could not read key file (%s)"), std_to_wx (p.string ())));
892 _chain->set_key (dcp::file_to_string (p));
894 update_private_key ();
895 } catch (dcp::MiscError& e) {
896 error_dialog (this, wxString::Format (_("Could not read certificate file (%s)"), e.what ()));
902 update_sensitivity ();
905 wxListCtrl* _certificates;
906 wxButton* _add_certificate;
907 wxButton* _export_certificate;
908 wxButton* _remove_certificate;
909 wxButton* _remake_certificates;
910 wxStaticText* _private_key;
911 wxButton* _load_private_key;
913 wxBoxSizer* _button_sizer;
914 shared_ptr<dcp::CertificateChain> _chain;
915 boost::function<void (shared_ptr<dcp::CertificateChain>)> _set;
916 boost::function<shared_ptr<const dcp::CertificateChain> (void)> _get;
919 class KeysPage : public StandardPage
922 KeysPage (wxSize panel_size, int border)
923 : StandardPage (panel_size, border)
926 wxString GetName () const
932 wxBitmap GetLargeIcon () const
934 return wxBitmap ("keys", wxBITMAP_TYPE_PNG_RESOURCE);
942 _signer = new CertificateChainEditor (
943 _panel, _("Signing DCPs and KDMs"), _border,
944 boost::bind (&Config::set_signer_chain, Config::instance (), _1),
945 boost::bind (&Config::signer_chain, Config::instance ())
948 _panel->GetSizer()->Add (_signer);
950 _decryption = new CertificateChainEditor (
951 _panel, _("Decrypting DCPs"), _border,
952 boost::bind (&Config::set_decryption_chain, Config::instance (), _1),
953 boost::bind (&Config::decryption_chain, Config::instance ())
956 _panel->GetSizer()->Add (_decryption);
958 _export_decryption_certificate = new wxButton (_decryption, wxID_ANY, _("Export DCP decryption certificate..."));
959 _decryption->add_button (_export_decryption_certificate);
961 _export_decryption_certificate->Bind (wxEVT_COMMAND_BUTTON_CLICKED, boost::bind (&KeysPage::export_decryption_certificate, this));
964 void export_decryption_certificate ()
966 wxFileDialog* d = new wxFileDialog (
967 _panel, _("Select Certificate File"), wxEmptyString, wxEmptyString, wxT ("PEM files (*.pem)|*.pem"),
968 wxFD_SAVE | wxFD_OVERWRITE_PROMPT
971 if (d->ShowModal () == wxID_OK) {
972 FILE* f = fopen_boost (wx_to_std (d->GetPath ()), "w");
974 throw OpenFileError (wx_to_std (d->GetPath ()));
977 string const s = Config::instance()->decryption_chain()->leaf().certificate (true);
978 fwrite (s.c_str(), 1, s.length(), f);
984 void config_changed ()
986 _signer->config_changed ();
987 _decryption->config_changed ();
990 CertificateChainEditor* _signer;
991 CertificateChainEditor* _decryption;
992 wxButton* _export_decryption_certificate;
995 class TMSPage : public StandardPage
998 TMSPage (wxSize panel_size, int border)
999 : StandardPage (panel_size, border)
1002 wxString GetName () const
1007 #ifdef DCPOMATIC_OSX
1008 wxBitmap GetLargeIcon () const
1010 return wxBitmap ("tms", wxBITMAP_TYPE_PNG_RESOURCE);
1017 wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
1018 table->AddGrowableCol (1, 1);
1019 _panel->GetSizer()->Add (table, 1, wxALL | wxEXPAND, _border);
1021 add_label_to_sizer (table, _panel, _("Protocol"), true);
1022 _tms_protocol = new wxChoice (_panel, wxID_ANY);
1023 table->Add (_tms_protocol, 1, wxEXPAND);
1025 add_label_to_sizer (table, _panel, _("IP address"), true);
1026 _tms_ip = new wxTextCtrl (_panel, wxID_ANY);
1027 table->Add (_tms_ip, 1, wxEXPAND);
1029 add_label_to_sizer (table, _panel, _("Target path"), true);
1030 _tms_path = new wxTextCtrl (_panel, wxID_ANY);
1031 table->Add (_tms_path, 1, wxEXPAND);
1033 add_label_to_sizer (table, _panel, _("User name"), true);
1034 _tms_user = new wxTextCtrl (_panel, wxID_ANY);
1035 table->Add (_tms_user, 1, wxEXPAND);
1037 add_label_to_sizer (table, _panel, _("Password"), true);
1038 _tms_password = new wxTextCtrl (_panel, wxID_ANY);
1039 table->Add (_tms_password, 1, wxEXPAND);
1041 _tms_protocol->Append (_("SCP (for AAM and Doremi)"));
1042 _tms_protocol->Append (_("FTP (for Dolby)"));
1044 _tms_protocol->Bind (wxEVT_COMMAND_CHOICE_SELECTED, boost::bind (&TMSPage::tms_protocol_changed, this));
1045 _tms_ip->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&TMSPage::tms_ip_changed, this));
1046 _tms_path->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&TMSPage::tms_path_changed, this));
1047 _tms_user->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&TMSPage::tms_user_changed, this));
1048 _tms_password->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&TMSPage::tms_password_changed, this));
1051 void config_changed ()
1053 Config* config = Config::instance ();
1055 checked_set (_tms_protocol, config->tms_protocol ());
1056 checked_set (_tms_ip, config->tms_ip ());
1057 checked_set (_tms_path, config->tms_path ());
1058 checked_set (_tms_user, config->tms_user ());
1059 checked_set (_tms_password, config->tms_password ());
1062 void tms_protocol_changed ()
1064 Config::instance()->set_tms_protocol (static_cast<Protocol> (_tms_protocol->GetSelection ()));
1067 void tms_ip_changed ()
1069 Config::instance()->set_tms_ip (wx_to_std (_tms_ip->GetValue ()));
1072 void tms_path_changed ()
1074 Config::instance()->set_tms_path (wx_to_std (_tms_path->GetValue ()));
1077 void tms_user_changed ()
1079 Config::instance()->set_tms_user (wx_to_std (_tms_user->GetValue ()));
1082 void tms_password_changed ()
1084 Config::instance()->set_tms_password (wx_to_std (_tms_password->GetValue ()));
1087 wxChoice* _tms_protocol;
1088 wxTextCtrl* _tms_ip;
1089 wxTextCtrl* _tms_path;
1090 wxTextCtrl* _tms_user;
1091 wxTextCtrl* _tms_password;
1094 class KDMEmailPage : public StandardPage
1098 KDMEmailPage (wxSize panel_size, int border)
1099 #ifdef DCPOMATIC_OSX
1100 /* We have to force both width and height of this one */
1101 : StandardPage (wxSize (480, 128), border)
1103 : StandardPage (panel_size, border)
1107 wxString GetName () const
1109 return _("KDM Email");
1112 #ifdef DCPOMATIC_OSX
1113 wxBitmap GetLargeIcon () const
1115 return wxBitmap ("kdm_email", wxBITMAP_TYPE_PNG_RESOURCE);
1122 wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
1123 table->AddGrowableCol (1, 1);
1124 _panel->GetSizer()->Add (table, 1, wxEXPAND | wxALL, _border);
1126 add_label_to_sizer (table, _panel, _("Outgoing mail server"), true);
1128 wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL);
1129 _mail_server = new wxTextCtrl (_panel, wxID_ANY);
1130 s->Add (_mail_server, 1, wxEXPAND | wxALL);
1131 add_label_to_sizer (s, _panel, _("port"), false);
1132 _mail_port = new wxSpinCtrl (_panel, wxID_ANY);
1133 _mail_port->SetRange (0, 65535);
1134 s->Add (_mail_port);
1135 table->Add (s, 1, wxEXPAND | wxALL);
1138 add_label_to_sizer (table, _panel, _("Mail user name"), true);
1139 _mail_user = new wxTextCtrl (_panel, wxID_ANY);
1140 table->Add (_mail_user, 1, wxEXPAND | wxALL);
1142 add_label_to_sizer (table, _panel, _("Mail password"), true);
1143 _mail_password = new wxTextCtrl (_panel, wxID_ANY);
1144 table->Add (_mail_password, 1, wxEXPAND | wxALL);
1146 add_label_to_sizer (table, _panel, _("Subject"), true);
1147 _kdm_subject = new wxTextCtrl (_panel, wxID_ANY);
1148 table->Add (_kdm_subject, 1, wxEXPAND | wxALL);
1150 add_label_to_sizer (table, _panel, _("From address"), true);
1151 _kdm_from = new wxTextCtrl (_panel, wxID_ANY);
1152 table->Add (_kdm_from, 1, wxEXPAND | wxALL);
1154 add_label_to_sizer (table, _panel, _("CC address"), true);
1155 _kdm_cc = new wxTextCtrl (_panel, wxID_ANY);
1156 table->Add (_kdm_cc, 1, wxEXPAND | wxALL);
1158 add_label_to_sizer (table, _panel, _("BCC address"), true);
1159 _kdm_bcc = new wxTextCtrl (_panel, wxID_ANY);
1160 table->Add (_kdm_bcc, 1, wxEXPAND | wxALL);
1162 _kdm_email = new wxTextCtrl (_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize (480, 128), wxTE_MULTILINE);
1163 _panel->GetSizer()->Add (_kdm_email, 1, wxEXPAND | wxALL, _border);
1165 _reset_kdm_email = new wxButton (_panel, wxID_ANY, _("Reset to default text"));
1166 _panel->GetSizer()->Add (_reset_kdm_email, 0, wxEXPAND | wxALL, _border);
1168 _mail_server->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&KDMEmailPage::mail_server_changed, this));
1169 _mail_port->Bind (wxEVT_COMMAND_SPINCTRL_UPDATED, boost::bind (&KDMEmailPage::mail_port_changed, this));
1170 _mail_user->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&KDMEmailPage::mail_user_changed, this));
1171 _mail_password->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&KDMEmailPage::mail_password_changed, this));
1172 _kdm_subject->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&KDMEmailPage::kdm_subject_changed, this));
1173 _kdm_from->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&KDMEmailPage::kdm_from_changed, this));
1174 _kdm_cc->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&KDMEmailPage::kdm_cc_changed, this));
1175 _kdm_bcc->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&KDMEmailPage::kdm_bcc_changed, this));
1176 _kdm_email->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&KDMEmailPage::kdm_email_changed, this));
1177 _reset_kdm_email->Bind (wxEVT_COMMAND_BUTTON_CLICKED, boost::bind (&KDMEmailPage::reset_kdm_email, this));
1180 void config_changed ()
1182 Config* config = Config::instance ();
1184 checked_set (_mail_server, config->mail_server ());
1185 checked_set (_mail_port, config->mail_port ());
1186 checked_set (_mail_user, config->mail_user ());
1187 checked_set (_mail_password, config->mail_password ());
1188 checked_set (_kdm_subject, config->kdm_subject ());
1189 checked_set (_kdm_from, config->kdm_from ());
1190 checked_set (_kdm_cc, config->kdm_cc ());
1191 checked_set (_kdm_bcc, config->kdm_bcc ());
1192 checked_set (_kdm_email, Config::instance()->kdm_email ());
1195 void mail_server_changed ()
1197 Config::instance()->set_mail_server (wx_to_std (_mail_server->GetValue ()));
1200 void mail_port_changed ()
1202 Config::instance()->set_mail_port (_mail_port->GetValue ());
1205 void mail_user_changed ()
1207 Config::instance()->set_mail_user (wx_to_std (_mail_user->GetValue ()));
1210 void mail_password_changed ()
1212 Config::instance()->set_mail_password (wx_to_std (_mail_password->GetValue ()));
1215 void kdm_subject_changed ()
1217 Config::instance()->set_kdm_subject (wx_to_std (_kdm_subject->GetValue ()));
1220 void kdm_from_changed ()
1222 Config::instance()->set_kdm_from (wx_to_std (_kdm_from->GetValue ()));
1225 void kdm_cc_changed ()
1227 Config::instance()->set_kdm_cc (wx_to_std (_kdm_cc->GetValue ()));
1230 void kdm_bcc_changed ()
1232 Config::instance()->set_kdm_bcc (wx_to_std (_kdm_bcc->GetValue ()));
1235 void kdm_email_changed ()
1237 if (_kdm_email->GetValue().IsEmpty ()) {
1238 /* Sometimes we get sent an erroneous notification that the email
1239 is empty; I don't know why.
1243 Config::instance()->set_kdm_email (wx_to_std (_kdm_email->GetValue ()));
1246 void reset_kdm_email ()
1248 Config::instance()->reset_kdm_email ();
1249 checked_set (_kdm_email, Config::instance()->kdm_email ());
1252 wxTextCtrl* _mail_server;
1253 wxSpinCtrl* _mail_port;
1254 wxTextCtrl* _mail_user;
1255 wxTextCtrl* _mail_password;
1256 wxTextCtrl* _kdm_subject;
1257 wxTextCtrl* _kdm_from;
1258 wxTextCtrl* _kdm_cc;
1259 wxTextCtrl* _kdm_bcc;
1260 wxTextCtrl* _kdm_email;
1261 wxButton* _reset_kdm_email;
1264 /** @class AdvancedPage
1265 * @brief Advanced page of the preferences dialog.
1267 class AdvancedPage : public StockPage
1270 AdvancedPage (wxSize panel_size, int border)
1271 : StockPage (Kind_Advanced, panel_size, border)
1272 , _maximum_j2k_bandwidth (0)
1273 , _allow_any_dcp_frame_rate (0)
1274 , _only_servers_encode (0)
1279 , _log_debug_decode (0)
1280 , _log_debug_encode (0)
1286 wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
1287 table->AddGrowableCol (1, 1);
1288 _panel->GetSizer()->Add (table, 1, wxALL | wxEXPAND, _border);
1291 add_label_to_sizer (table, _panel, _("Maximum JPEG2000 bandwidth"), true);
1292 wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL);
1293 _maximum_j2k_bandwidth = new wxSpinCtrl (_panel);
1294 s->Add (_maximum_j2k_bandwidth, 1);
1295 add_label_to_sizer (s, _panel, _("Mbit/s"), false);
1299 _allow_any_dcp_frame_rate = new wxCheckBox (_panel, wxID_ANY, _("Allow any DCP frame rate"));
1300 table->Add (_allow_any_dcp_frame_rate, 1, wxEXPAND | wxALL);
1301 table->AddSpacer (0);
1303 _only_servers_encode = new wxCheckBox (_panel, wxID_ANY, _("Only servers encode"));
1304 table->Add (_only_servers_encode, 1, wxEXPAND | wxALL);
1305 table->AddSpacer (0);
1308 wxStaticText* m = new wxStaticText (_panel, wxID_ANY, _("Log:"));
1309 table->Add (m, 0, wxALIGN_TOP | wxLEFT | wxRIGHT | wxEXPAND | wxALL | wxALIGN_RIGHT, 6);
1311 wxStaticText* m = new wxStaticText (_panel, wxID_ANY, _("Log"));
1312 table->Add (m, 0, wxALIGN_TOP | wxLEFT | wxRIGHT | wxEXPAND | wxALL, 6);
1316 wxBoxSizer* t = new wxBoxSizer (wxVERTICAL);
1317 _log_general = new wxCheckBox (_panel, wxID_ANY, _("General"));
1318 t->Add (_log_general, 1, wxEXPAND | wxALL);
1319 _log_warning = new wxCheckBox (_panel, wxID_ANY, _("Warnings"));
1320 t->Add (_log_warning, 1, wxEXPAND | wxALL);
1321 _log_error = new wxCheckBox (_panel, wxID_ANY, _("Errors"));
1322 t->Add (_log_error, 1, wxEXPAND | wxALL);
1323 _log_timing = new wxCheckBox (_panel, wxID_ANY, S_("Config|Timing"));
1324 t->Add (_log_timing, 1, wxEXPAND | wxALL);
1325 _log_debug_decode = new wxCheckBox (_panel, wxID_ANY, _("Debug: decode"));
1326 t->Add (_log_debug_decode, 1, wxEXPAND | wxALL);
1327 _log_debug_encode = new wxCheckBox (_panel, wxID_ANY, _("Debug: encode"));
1328 t->Add (_log_debug_encode, 1, wxEXPAND | wxALL);
1329 table->Add (t, 0, wxALL, 6);
1332 #ifdef DCPOMATIC_WINDOWS
1333 _win32_console = new wxCheckBox (_panel, wxID_ANY, _("Open console window"));
1334 table->Add (_win32_console, 1, wxEXPAND | wxALL);
1335 table->AddSpacer (0);
1338 _maximum_j2k_bandwidth->SetRange (1, 1000);
1339 _maximum_j2k_bandwidth->Bind (wxEVT_COMMAND_SPINCTRL_UPDATED, boost::bind (&AdvancedPage::maximum_j2k_bandwidth_changed, this));
1340 _allow_any_dcp_frame_rate->Bind (wxEVT_COMMAND_CHECKBOX_CLICKED, boost::bind (&AdvancedPage::allow_any_dcp_frame_rate_changed, this));
1341 _only_servers_encode->Bind (wxEVT_COMMAND_CHECKBOX_CLICKED, boost::bind (&AdvancedPage::only_servers_encode_changed, this));
1342 _log_general->Bind (wxEVT_COMMAND_CHECKBOX_CLICKED, boost::bind (&AdvancedPage::log_changed, this));
1343 _log_warning->Bind (wxEVT_COMMAND_CHECKBOX_CLICKED, boost::bind (&AdvancedPage::log_changed, this));
1344 _log_error->Bind (wxEVT_COMMAND_CHECKBOX_CLICKED, boost::bind (&AdvancedPage::log_changed, this));
1345 _log_timing->Bind (wxEVT_COMMAND_CHECKBOX_CLICKED, boost::bind (&AdvancedPage::log_changed, this));
1346 _log_debug_decode->Bind (wxEVT_COMMAND_CHECKBOX_CLICKED, boost::bind (&AdvancedPage::log_changed, this));
1347 _log_debug_encode->Bind (wxEVT_COMMAND_CHECKBOX_CLICKED, boost::bind (&AdvancedPage::log_changed, this));
1348 #ifdef DCPOMATIC_WINDOWS
1349 _win32_console->Bind (wxEVT_COMMAND_CHECKBOX_CLICKED, boost::bind (&AdvancedPage::win32_console_changed, this));
1353 void config_changed ()
1355 Config* config = Config::instance ();
1357 checked_set (_maximum_j2k_bandwidth, config->maximum_j2k_bandwidth() / 1000000);
1358 checked_set (_allow_any_dcp_frame_rate, config->allow_any_dcp_frame_rate ());
1359 checked_set (_only_servers_encode, config->only_servers_encode ());
1360 checked_set (_log_general, config->log_types() & Log::TYPE_GENERAL);
1361 checked_set (_log_warning, config->log_types() & Log::TYPE_WARNING);
1362 checked_set (_log_error, config->log_types() & Log::TYPE_ERROR);
1363 checked_set (_log_timing, config->log_types() & Log::TYPE_TIMING);
1364 checked_set (_log_debug_decode, config->log_types() & Log::TYPE_DEBUG_DECODE);
1365 checked_set (_log_debug_encode, config->log_types() & Log::TYPE_DEBUG_ENCODE);
1366 #ifdef DCPOMATIC_WINDOWS
1367 checked_set (_win32_console, config->win32_console());
1371 void maximum_j2k_bandwidth_changed ()
1373 Config::instance()->set_maximum_j2k_bandwidth (_maximum_j2k_bandwidth->GetValue() * 1000000);
1376 void allow_any_dcp_frame_rate_changed ()
1378 Config::instance()->set_allow_any_dcp_frame_rate (_allow_any_dcp_frame_rate->GetValue ());
1381 void only_servers_encode_changed ()
1383 Config::instance()->set_only_servers_encode (_only_servers_encode->GetValue ());
1389 if (_log_general->GetValue ()) {
1390 types |= Log::TYPE_GENERAL;
1392 if (_log_warning->GetValue ()) {
1393 types |= Log::TYPE_WARNING;
1395 if (_log_error->GetValue ()) {
1396 types |= Log::TYPE_ERROR;
1398 if (_log_timing->GetValue ()) {
1399 types |= Log::TYPE_TIMING;
1401 if (_log_debug_decode->GetValue ()) {
1402 types |= Log::TYPE_DEBUG_DECODE;
1404 if (_log_debug_encode->GetValue ()) {
1405 types |= Log::TYPE_DEBUG_ENCODE;
1407 Config::instance()->set_log_types (types);
1410 #ifdef DCPOMATIC_WINDOWS
1411 void win32_console_changed ()
1413 Config::instance()->set_win32_console (_win32_console->GetValue ());
1417 wxSpinCtrl* _maximum_j2k_bandwidth;
1418 wxCheckBox* _allow_any_dcp_frame_rate;
1419 wxCheckBox* _only_servers_encode;
1420 wxCheckBox* _log_general;
1421 wxCheckBox* _log_warning;
1422 wxCheckBox* _log_error;
1423 wxCheckBox* _log_timing;
1424 wxCheckBox* _log_debug_decode;
1425 wxCheckBox* _log_debug_encode;
1426 #ifdef DCPOMATIC_WINDOWS
1427 wxCheckBox* _win32_console;
1431 wxPreferencesEditor*
1432 create_config_dialog ()
1434 wxPreferencesEditor* e = new wxPreferencesEditor ();
1436 #ifdef DCPOMATIC_OSX
1437 /* Width that we force some of the config panels to be on OSX so that
1438 the containing window doesn't shrink too much when we select those panels.
1439 This is obviously an unpleasant hack.
1441 wxSize ps = wxSize (520, -1);
1442 int const border = 16;
1444 wxSize ps = wxSize (-1, -1);
1445 int const border = 8;
1448 e->AddPage (new GeneralPage (ps, border));
1449 e->AddPage (new DefaultsPage (ps, border));
1450 e->AddPage (new EncodingServersPage (ps, border));
1451 e->AddPage (new KeysPage (ps, border));
1452 e->AddPage (new TMSPage (ps, border));
1453 e->AddPage (new KDMEmailPage (ps, border));
1454 e->AddPage (new AdvancedPage (ps, border));