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, 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 _still_length->SetRange (1, 3600);
429 _still_length->Bind (wxEVT_COMMAND_SPINCTRL_UPDATED, boost::bind (&DefaultsPage::still_length_changed, this));
431 _directory->Bind (wxEVT_COMMAND_DIRPICKER_CHANGED, boost::bind (&DefaultsPage::directory_changed, this));
433 _isdcf_metadata_button->Bind (wxEVT_COMMAND_BUTTON_CLICKED, boost::bind (&DefaultsPage::edit_isdcf_metadata_clicked, this));
435 vector<Ratio const *> ratios = Ratio::all ();
436 for (size_t i = 0; i < ratios.size(); ++i) {
437 _container->Append (std_to_wx (ratios[i]->nickname ()));
440 _container->Bind (wxEVT_COMMAND_CHOICE_SELECTED, boost::bind (&DefaultsPage::container_changed, this));
442 vector<DCPContentType const *> const ct = DCPContentType::all ();
443 for (size_t i = 0; i < ct.size(); ++i) {
444 _dcp_content_type->Append (std_to_wx (ct[i]->pretty_name ()));
447 _dcp_content_type->Bind (wxEVT_COMMAND_CHOICE_SELECTED, boost::bind (&DefaultsPage::dcp_content_type_changed, this));
449 _j2k_bandwidth->SetRange (50, 250);
450 _j2k_bandwidth->Bind (wxEVT_COMMAND_SPINCTRL_UPDATED, boost::bind (&DefaultsPage::j2k_bandwidth_changed, this));
452 _audio_delay->SetRange (-1000, 1000);
453 _audio_delay->Bind (wxEVT_COMMAND_SPINCTRL_UPDATED, boost::bind (&DefaultsPage::audio_delay_changed, this));
456 void config_changed ()
458 Config* config = Config::instance ();
460 vector<Ratio const *> ratios = Ratio::all ();
461 for (size_t i = 0; i < ratios.size(); ++i) {
462 if (ratios[i] == config->default_container ()) {
463 _container->SetSelection (i);
467 vector<DCPContentType const *> const ct = DCPContentType::all ();
468 for (size_t i = 0; i < ct.size(); ++i) {
469 if (ct[i] == config->default_dcp_content_type ()) {
470 _dcp_content_type->SetSelection (i);
474 checked_set (_still_length, config->default_still_length ());
475 _directory->SetPath (std_to_wx (config->default_directory_or (wx_to_std (wxStandardPaths::Get().GetDocumentsDir())).string ()));
476 checked_set (_j2k_bandwidth, config->default_j2k_bandwidth() / 1000000);
477 _j2k_bandwidth->SetRange (50, config->maximum_j2k_bandwidth() / 1000000);
478 checked_set (_audio_delay, config->default_audio_delay ());
481 void j2k_bandwidth_changed ()
483 Config::instance()->set_default_j2k_bandwidth (_j2k_bandwidth->GetValue() * 1000000);
486 void audio_delay_changed ()
488 Config::instance()->set_default_audio_delay (_audio_delay->GetValue());
491 void directory_changed ()
493 Config::instance()->set_default_directory (wx_to_std (_directory->GetPath ()));
496 void edit_isdcf_metadata_clicked ()
498 ISDCFMetadataDialog* d = new ISDCFMetadataDialog (_panel, Config::instance()->default_isdcf_metadata (), false);
500 Config::instance()->set_default_isdcf_metadata (d->isdcf_metadata ());
504 void still_length_changed ()
506 Config::instance()->set_default_still_length (_still_length->GetValue ());
509 void container_changed ()
511 vector<Ratio const *> ratio = Ratio::all ();
512 Config::instance()->set_default_container (ratio[_container->GetSelection()]);
515 void dcp_content_type_changed ()
517 vector<DCPContentType const *> ct = DCPContentType::all ();
518 Config::instance()->set_default_dcp_content_type (ct[_dcp_content_type->GetSelection()]);
521 wxSpinCtrl* _j2k_bandwidth;
522 wxSpinCtrl* _audio_delay;
523 wxButton* _isdcf_metadata_button;
524 wxSpinCtrl* _still_length;
525 #ifdef DCPOMATIC_USE_OWN_DIR_PICKER
526 DirPickerCtrl* _directory;
528 wxDirPickerCtrl* _directory;
530 wxChoice* _container;
531 wxChoice* _dcp_content_type;
534 class EncodingServersPage : public StandardPage
537 EncodingServersPage (wxSize panel_size, int border)
538 : StandardPage (panel_size, border)
541 wxString GetName () const
547 wxBitmap GetLargeIcon () const
549 return wxBitmap ("servers", wxBITMAP_TYPE_PNG_RESOURCE);
556 _use_any_servers = new wxCheckBox (_panel, wxID_ANY, _("Use all servers"));
557 _panel->GetSizer()->Add (_use_any_servers, 0, wxALL, _border);
559 vector<string> columns;
560 columns.push_back (wx_to_std (_("IP address / host name")));
561 _servers_list = new EditableList<string, ServerDialog> (
564 boost::bind (&Config::servers, Config::instance()),
565 boost::bind (&Config::set_servers, Config::instance(), _1),
566 boost::bind (&EncodingServersPage::server_column, this, _1)
569 _panel->GetSizer()->Add (_servers_list, 1, wxEXPAND | wxALL, _border);
571 _use_any_servers->Bind (wxEVT_COMMAND_CHECKBOX_CLICKED, boost::bind (&EncodingServersPage::use_any_servers_changed, this));
574 void config_changed ()
576 checked_set (_use_any_servers, Config::instance()->use_any_servers ());
577 _servers_list->refresh ();
580 void use_any_servers_changed ()
582 Config::instance()->set_use_any_servers (_use_any_servers->GetValue ());
585 string server_column (string s)
590 wxCheckBox* _use_any_servers;
591 EditableList<string, ServerDialog>* _servers_list;
594 class CertificateChainEditor : public wxPanel
597 CertificateChainEditor (
601 function<void (shared_ptr<dcp::CertificateChain>)> set,
602 function<shared_ptr<const dcp::CertificateChain> (void)> get
608 wxFont subheading_font (*wxNORMAL_FONT);
609 subheading_font.SetWeight (wxFONTWEIGHT_BOLD);
611 _sizer = new wxBoxSizer (wxVERTICAL);
614 wxStaticText* m = new wxStaticText (this, wxID_ANY, title);
615 m->SetFont (subheading_font);
616 _sizer->Add (m, 0, wxALL, border);
619 wxBoxSizer* certificates_sizer = new wxBoxSizer (wxHORIZONTAL);
620 _sizer->Add (certificates_sizer, 0, wxLEFT | wxRIGHT, border);
622 _certificates = new wxListCtrl (this, wxID_ANY, wxDefaultPosition, wxSize (400, 150), wxLC_REPORT | wxLC_SINGLE_SEL);
627 ip.SetText (_("Type"));
629 _certificates->InsertColumn (0, ip);
635 ip.SetText (_("Thumbprint"));
638 wxFont font = ip.GetFont ();
639 font.SetFamily (wxFONTFAMILY_TELETYPE);
642 _certificates->InsertColumn (1, ip);
645 certificates_sizer->Add (_certificates, 1, wxEXPAND);
648 wxSizer* s = new wxBoxSizer (wxVERTICAL);
649 _add_certificate = new wxButton (this, wxID_ANY, _("Add..."));
650 s->Add (_add_certificate, 0, wxTOP | wxBOTTOM, DCPOMATIC_BUTTON_STACK_GAP);
651 _remove_certificate = new wxButton (this, wxID_ANY, _("Remove"));
652 s->Add (_remove_certificate, 0, wxTOP | wxBOTTOM, DCPOMATIC_BUTTON_STACK_GAP);
653 _export_certificate = new wxButton (this, wxID_ANY, _("Export"));
654 s->Add (_export_certificate, 0, wxTOP | wxBOTTOM, DCPOMATIC_BUTTON_STACK_GAP);
655 certificates_sizer->Add (s, 0, wxLEFT, DCPOMATIC_SIZER_X_GAP);
658 wxGridBagSizer* table = new wxGridBagSizer (DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
659 _sizer->Add (table, 1, wxALL | wxEXPAND, border);
662 add_label_to_grid_bag_sizer (table, this, _("Leaf private key"), true, wxGBPosition (r, 0));
663 _private_key = new wxStaticText (this, wxID_ANY, wxT (""));
664 wxFont font = _private_key->GetFont ();
665 font.SetFamily (wxFONTFAMILY_TELETYPE);
666 _private_key->SetFont (font);
667 table->Add (_private_key, wxGBPosition (r, 1), wxDefaultSpan, wxALIGN_CENTER_VERTICAL);
668 _load_private_key = new wxButton (this, wxID_ANY, _("Load..."));
669 table->Add (_load_private_key, wxGBPosition (r, 2));
672 _button_sizer = new wxBoxSizer (wxHORIZONTAL);
673 _remake_certificates = new wxButton (this, wxID_ANY, _("Re-make certificates and key..."));
674 _button_sizer->Add (_remake_certificates, 1, wxRIGHT, border);
675 table->Add (_button_sizer, wxGBPosition (r, 0), wxGBSpan (1, 3));
678 _add_certificate->Bind (wxEVT_COMMAND_BUTTON_CLICKED, boost::bind (&CertificateChainEditor::add_certificate, this));
679 _remove_certificate->Bind (wxEVT_COMMAND_BUTTON_CLICKED, boost::bind (&CertificateChainEditor::remove_certificate, this));
680 _export_certificate->Bind (wxEVT_COMMAND_BUTTON_CLICKED, boost::bind (&CertificateChainEditor::export_certificate, this));
681 _certificates->Bind (wxEVT_COMMAND_LIST_ITEM_SELECTED, boost::bind (&CertificateChainEditor::update_sensitivity, this));
682 _certificates->Bind (wxEVT_COMMAND_LIST_ITEM_DESELECTED, boost::bind (&CertificateChainEditor::update_sensitivity, this));
683 _remake_certificates->Bind (wxEVT_COMMAND_BUTTON_CLICKED, boost::bind (&CertificateChainEditor::remake_certificates, this));
684 _load_private_key->Bind (wxEVT_COMMAND_BUTTON_CLICKED, boost::bind (&CertificateChainEditor::load_private_key, this));
686 SetSizerAndFit (_sizer);
689 void config_changed ()
691 _chain.reset (new dcp::CertificateChain (*_get().get ()));
693 update_certificate_list ();
694 update_private_key ();
695 update_sensitivity ();
698 void add_button (wxWindow* button)
700 _button_sizer->Add (button);
705 void add_certificate ()
707 wxFileDialog* d = new wxFileDialog (this, _("Select Certificate File"));
709 if (d->ShowModal() == wxID_OK) {
711 dcp::Certificate c (dcp::file_to_string (wx_to_std (d->GetPath ())));
714 update_certificate_list ();
715 } catch (dcp::MiscError& e) {
716 error_dialog (this, wxString::Format (_("Could not read certificate file (%s)"), e.what ()));
722 update_sensitivity ();
725 void remove_certificate ()
727 int i = _certificates->GetNextItem (-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
732 _certificates->DeleteItem (i);
736 update_sensitivity ();
739 void export_certificate ()
741 int i = _certificates->GetNextItem (-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
746 wxFileDialog* d = new wxFileDialog (
747 this, _("Select Certificate File"), wxEmptyString, wxEmptyString, wxT ("PEM files (*.pem)|*.pem"),
748 wxFD_SAVE | wxFD_OVERWRITE_PROMPT
751 dcp::CertificateChain::List all = _chain->root_to_leaf ();
752 dcp::CertificateChain::List::iterator j = all.begin ();
753 for (int k = 0; k < i; ++k) {
757 if (d->ShowModal () == wxID_OK) {
758 FILE* f = fopen_boost (wx_to_std (d->GetPath ()), "w");
760 throw OpenFileError (wx_to_std (d->GetPath ()));
763 string const s = j->certificate (true);
764 fwrite (s.c_str(), 1, s.length(), f);
770 void update_certificate_list ()
772 _certificates->DeleteAllItems ();
774 dcp::CertificateChain::List certs = _chain->root_to_leaf ();
775 BOOST_FOREACH (dcp::Certificate const & i, certs) {
778 _certificates->InsertItem (item);
779 _certificates->SetItem (n, 1, std_to_wx (i.thumbprint ()));
782 _certificates->SetItem (n, 0, _("Root"));
783 } else if (n == (certs.size() - 1)) {
784 _certificates->SetItem (n, 0, _("Leaf"));
786 _certificates->SetItem (n, 0, _("Intermediate"));
793 void remake_certificates ()
795 shared_ptr<const dcp::CertificateChain> chain = _get ();
797 string intermediate_common_name;
798 if (chain->root_to_leaf().size() >= 3) {
799 dcp::CertificateChain::List all = chain->root_to_leaf ();
800 dcp::CertificateChain::List::iterator i = all.begin ();
802 intermediate_common_name = i->subject_common_name ();
805 MakeChainDialog* d = new MakeChainDialog (
807 chain->root().subject_organization_name (),
808 chain->root().subject_organizational_unit_name (),
809 chain->root().subject_common_name (),
810 intermediate_common_name,
811 chain->leaf().subject_common_name ()
814 if (d->ShowModal () == wxID_OK) {
816 new dcp::CertificateChain (
819 d->organisational_unit (),
820 d->root_common_name (),
821 d->intermediate_common_name (),
822 d->leaf_common_name ()
827 update_certificate_list ();
828 update_private_key ();
834 void update_sensitivity ()
836 _remove_certificate->Enable (_certificates->GetNextItem (-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED) != -1);
837 _export_certificate->Enable (_certificates->GetNextItem (-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED) != -1);
840 void update_private_key ()
842 checked_set (_private_key, dcp::private_key_fingerprint (_chain->key().get ()));
846 void load_private_key ()
848 wxFileDialog* d = new wxFileDialog (this, _("Select Key File"));
850 if (d->ShowModal() == wxID_OK) {
852 boost::filesystem::path p (wx_to_std (d->GetPath ()));
853 if (boost::filesystem::file_size (p) > 1024) {
854 error_dialog (this, wxString::Format (_("Could not read key file (%s)"), std_to_wx (p.string ())));
858 _chain->set_key (dcp::file_to_string (p));
860 update_private_key ();
861 } catch (dcp::MiscError& e) {
862 error_dialog (this, wxString::Format (_("Could not read certificate file (%s)"), e.what ()));
868 update_sensitivity ();
871 wxListCtrl* _certificates;
872 wxButton* _add_certificate;
873 wxButton* _export_certificate;
874 wxButton* _remove_certificate;
875 wxButton* _remake_certificates;
876 wxStaticText* _private_key;
877 wxButton* _load_private_key;
879 wxBoxSizer* _button_sizer;
880 shared_ptr<dcp::CertificateChain> _chain;
881 boost::function<void (shared_ptr<dcp::CertificateChain>)> _set;
882 boost::function<shared_ptr<const dcp::CertificateChain> (void)> _get;
885 class KeysPage : public StandardPage
888 KeysPage (wxSize panel_size, int border)
889 : StandardPage (panel_size, border)
892 wxString GetName () const
898 wxBitmap GetLargeIcon () const
900 return wxBitmap ("keys", wxBITMAP_TYPE_PNG_RESOURCE);
908 _signer = new CertificateChainEditor (
909 _panel, _("Signing DCPs and KDMs"), _border,
910 boost::bind (&Config::set_signer_chain, Config::instance (), _1),
911 boost::bind (&Config::signer_chain, Config::instance ())
914 _panel->GetSizer()->Add (_signer);
916 _decryption = new CertificateChainEditor (
917 _panel, _("Decrypting DCPs"), _border,
918 boost::bind (&Config::set_decryption_chain, Config::instance (), _1),
919 boost::bind (&Config::decryption_chain, Config::instance ())
922 _panel->GetSizer()->Add (_decryption);
924 _export_decryption_certificate = new wxButton (_decryption, wxID_ANY, _("Export DCP decryption certificate..."));
925 _decryption->add_button (_export_decryption_certificate);
927 _export_decryption_certificate->Bind (wxEVT_COMMAND_BUTTON_CLICKED, boost::bind (&KeysPage::export_decryption_certificate, this));
930 void export_decryption_certificate ()
932 wxFileDialog* d = new wxFileDialog (
933 _panel, _("Select Certificate File"), wxEmptyString, wxEmptyString, wxT ("PEM files (*.pem)|*.pem"),
934 wxFD_SAVE | wxFD_OVERWRITE_PROMPT
937 if (d->ShowModal () == wxID_OK) {
938 FILE* f = fopen_boost (wx_to_std (d->GetPath ()), "w");
940 throw OpenFileError (wx_to_std (d->GetPath ()));
943 string const s = Config::instance()->decryption_chain()->leaf().certificate (true);
944 fwrite (s.c_str(), 1, s.length(), f);
950 void config_changed ()
952 _signer->config_changed ();
953 _decryption->config_changed ();
956 CertificateChainEditor* _signer;
957 CertificateChainEditor* _decryption;
958 wxButton* _export_decryption_certificate;
961 class TMSPage : public StandardPage
964 TMSPage (wxSize panel_size, int border)
965 : StandardPage (panel_size, border)
968 wxString GetName () const
974 wxBitmap GetLargeIcon () const
976 return wxBitmap ("tms", wxBITMAP_TYPE_PNG_RESOURCE);
983 wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
984 table->AddGrowableCol (1, 1);
985 _panel->GetSizer()->Add (table, 1, wxALL | wxEXPAND, _border);
987 add_label_to_sizer (table, _panel, _("Protocol"), true);
988 _tms_protocol = new wxChoice (_panel, wxID_ANY);
989 table->Add (_tms_protocol, 1, wxEXPAND);
991 add_label_to_sizer (table, _panel, _("IP address"), true);
992 _tms_ip = new wxTextCtrl (_panel, wxID_ANY);
993 table->Add (_tms_ip, 1, wxEXPAND);
995 add_label_to_sizer (table, _panel, _("Target path"), true);
996 _tms_path = new wxTextCtrl (_panel, wxID_ANY);
997 table->Add (_tms_path, 1, wxEXPAND);
999 add_label_to_sizer (table, _panel, _("User name"), true);
1000 _tms_user = new wxTextCtrl (_panel, wxID_ANY);
1001 table->Add (_tms_user, 1, wxEXPAND);
1003 add_label_to_sizer (table, _panel, _("Password"), true);
1004 _tms_password = new wxTextCtrl (_panel, wxID_ANY);
1005 table->Add (_tms_password, 1, wxEXPAND);
1007 _tms_protocol->Append (_("SCP (for AAM and Doremi)"));
1008 _tms_protocol->Append (_("FTP (for Dolby)"));
1010 _tms_protocol->Bind (wxEVT_COMMAND_CHOICE_SELECTED, boost::bind (&TMSPage::tms_protocol_changed, this));
1011 _tms_ip->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&TMSPage::tms_ip_changed, this));
1012 _tms_path->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&TMSPage::tms_path_changed, this));
1013 _tms_user->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&TMSPage::tms_user_changed, this));
1014 _tms_password->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&TMSPage::tms_password_changed, this));
1017 void config_changed ()
1019 Config* config = Config::instance ();
1021 checked_set (_tms_protocol, config->tms_protocol ());
1022 checked_set (_tms_ip, config->tms_ip ());
1023 checked_set (_tms_path, config->tms_path ());
1024 checked_set (_tms_user, config->tms_user ());
1025 checked_set (_tms_password, config->tms_password ());
1028 void tms_protocol_changed ()
1030 Config::instance()->set_tms_protocol (static_cast<Protocol> (_tms_protocol->GetSelection ()));
1033 void tms_ip_changed ()
1035 Config::instance()->set_tms_ip (wx_to_std (_tms_ip->GetValue ()));
1038 void tms_path_changed ()
1040 Config::instance()->set_tms_path (wx_to_std (_tms_path->GetValue ()));
1043 void tms_user_changed ()
1045 Config::instance()->set_tms_user (wx_to_std (_tms_user->GetValue ()));
1048 void tms_password_changed ()
1050 Config::instance()->set_tms_password (wx_to_std (_tms_password->GetValue ()));
1053 wxChoice* _tms_protocol;
1054 wxTextCtrl* _tms_ip;
1055 wxTextCtrl* _tms_path;
1056 wxTextCtrl* _tms_user;
1057 wxTextCtrl* _tms_password;
1060 class KDMEmailPage : public StandardPage
1064 KDMEmailPage (wxSize panel_size, int border)
1065 #ifdef DCPOMATIC_OSX
1066 /* We have to force both width and height of this one */
1067 : StandardPage (wxSize (480, 128), border)
1069 : StandardPage (panel_size, border)
1073 wxString GetName () const
1075 return _("KDM Email");
1078 #ifdef DCPOMATIC_OSX
1079 wxBitmap GetLargeIcon () const
1081 return wxBitmap ("kdm_email", wxBITMAP_TYPE_PNG_RESOURCE);
1088 wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
1089 table->AddGrowableCol (1, 1);
1090 _panel->GetSizer()->Add (table, 1, wxEXPAND | wxALL, _border);
1092 add_label_to_sizer (table, _panel, _("Outgoing mail server"), true);
1094 wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL);
1095 _mail_server = new wxTextCtrl (_panel, wxID_ANY);
1096 s->Add (_mail_server, 1, wxEXPAND | wxALL);
1097 add_label_to_sizer (s, _panel, _("port"), false);
1098 _mail_port = new wxSpinCtrl (_panel, wxID_ANY);
1099 _mail_port->SetRange (0, 65535);
1100 s->Add (_mail_port);
1101 table->Add (s, 1, wxEXPAND | wxALL);
1104 add_label_to_sizer (table, _panel, _("Mail user name"), true);
1105 _mail_user = new wxTextCtrl (_panel, wxID_ANY);
1106 table->Add (_mail_user, 1, wxEXPAND | wxALL);
1108 add_label_to_sizer (table, _panel, _("Mail password"), true);
1109 _mail_password = new wxTextCtrl (_panel, wxID_ANY);
1110 table->Add (_mail_password, 1, wxEXPAND | wxALL);
1112 add_label_to_sizer (table, _panel, _("Subject"), true);
1113 _kdm_subject = new wxTextCtrl (_panel, wxID_ANY);
1114 table->Add (_kdm_subject, 1, wxEXPAND | wxALL);
1116 add_label_to_sizer (table, _panel, _("From address"), true);
1117 _kdm_from = new wxTextCtrl (_panel, wxID_ANY);
1118 table->Add (_kdm_from, 1, wxEXPAND | wxALL);
1120 add_label_to_sizer (table, _panel, _("CC address"), true);
1121 _kdm_cc = new wxTextCtrl (_panel, wxID_ANY);
1122 table->Add (_kdm_cc, 1, wxEXPAND | wxALL);
1124 add_label_to_sizer (table, _panel, _("BCC address"), true);
1125 _kdm_bcc = new wxTextCtrl (_panel, wxID_ANY);
1126 table->Add (_kdm_bcc, 1, wxEXPAND | wxALL);
1128 _kdm_email = new wxTextCtrl (_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize (480, 128), wxTE_MULTILINE);
1129 _panel->GetSizer()->Add (_kdm_email, 1, wxEXPAND | wxALL, _border);
1131 _reset_kdm_email = new wxButton (_panel, wxID_ANY, _("Reset to default text"));
1132 _panel->GetSizer()->Add (_reset_kdm_email, 0, wxEXPAND | wxALL, _border);
1134 _mail_server->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&KDMEmailPage::mail_server_changed, this));
1135 _mail_port->Bind (wxEVT_COMMAND_SPINCTRL_UPDATED, boost::bind (&KDMEmailPage::mail_port_changed, this));
1136 _mail_user->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&KDMEmailPage::mail_user_changed, this));
1137 _mail_password->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&KDMEmailPage::mail_password_changed, this));
1138 _kdm_subject->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&KDMEmailPage::kdm_subject_changed, this));
1139 _kdm_from->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&KDMEmailPage::kdm_from_changed, this));
1140 _kdm_cc->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&KDMEmailPage::kdm_cc_changed, this));
1141 _kdm_bcc->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&KDMEmailPage::kdm_bcc_changed, this));
1142 _kdm_email->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&KDMEmailPage::kdm_email_changed, this));
1143 _reset_kdm_email->Bind (wxEVT_COMMAND_BUTTON_CLICKED, boost::bind (&KDMEmailPage::reset_kdm_email, this));
1146 void config_changed ()
1148 Config* config = Config::instance ();
1150 checked_set (_mail_server, config->mail_server ());
1151 checked_set (_mail_port, config->mail_port ());
1152 checked_set (_mail_user, config->mail_user ());
1153 checked_set (_mail_password, config->mail_password ());
1154 checked_set (_kdm_subject, config->kdm_subject ());
1155 checked_set (_kdm_from, config->kdm_from ());
1156 checked_set (_kdm_cc, config->kdm_cc ());
1157 checked_set (_kdm_bcc, config->kdm_bcc ());
1158 checked_set (_kdm_email, Config::instance()->kdm_email ());
1161 void mail_server_changed ()
1163 Config::instance()->set_mail_server (wx_to_std (_mail_server->GetValue ()));
1166 void mail_port_changed ()
1168 Config::instance()->set_mail_port (_mail_port->GetValue ());
1171 void mail_user_changed ()
1173 Config::instance()->set_mail_user (wx_to_std (_mail_user->GetValue ()));
1176 void mail_password_changed ()
1178 Config::instance()->set_mail_password (wx_to_std (_mail_password->GetValue ()));
1181 void kdm_subject_changed ()
1183 Config::instance()->set_kdm_subject (wx_to_std (_kdm_subject->GetValue ()));
1186 void kdm_from_changed ()
1188 Config::instance()->set_kdm_from (wx_to_std (_kdm_from->GetValue ()));
1191 void kdm_cc_changed ()
1193 Config::instance()->set_kdm_cc (wx_to_std (_kdm_cc->GetValue ()));
1196 void kdm_bcc_changed ()
1198 Config::instance()->set_kdm_bcc (wx_to_std (_kdm_bcc->GetValue ()));
1201 void kdm_email_changed ()
1203 if (_kdm_email->GetValue().IsEmpty ()) {
1204 /* Sometimes we get sent an erroneous notification that the email
1205 is empty; I don't know why.
1209 Config::instance()->set_kdm_email (wx_to_std (_kdm_email->GetValue ()));
1212 void reset_kdm_email ()
1214 Config::instance()->reset_kdm_email ();
1215 checked_set (_kdm_email, Config::instance()->kdm_email ());
1218 wxTextCtrl* _mail_server;
1219 wxSpinCtrl* _mail_port;
1220 wxTextCtrl* _mail_user;
1221 wxTextCtrl* _mail_password;
1222 wxTextCtrl* _kdm_subject;
1223 wxTextCtrl* _kdm_from;
1224 wxTextCtrl* _kdm_cc;
1225 wxTextCtrl* _kdm_bcc;
1226 wxTextCtrl* _kdm_email;
1227 wxButton* _reset_kdm_email;
1230 /** @class AdvancedPage
1231 * @brief Advanced page of the preferences dialog.
1233 class AdvancedPage : public StockPage
1236 AdvancedPage (wxSize panel_size, int border)
1237 : StockPage (Kind_Advanced, panel_size, border)
1238 , _maximum_j2k_bandwidth (0)
1239 , _allow_any_dcp_frame_rate (0)
1240 , _only_servers_encode (0)
1245 , _log_debug_decode (0)
1246 , _log_debug_encode (0)
1252 wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
1253 table->AddGrowableCol (1, 1);
1254 _panel->GetSizer()->Add (table, 1, wxALL | wxEXPAND, _border);
1257 add_label_to_sizer (table, _panel, _("Maximum JPEG2000 bandwidth"), true);
1258 wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL);
1259 _maximum_j2k_bandwidth = new wxSpinCtrl (_panel);
1260 s->Add (_maximum_j2k_bandwidth, 1);
1261 add_label_to_sizer (s, _panel, _("Mbit/s"), false);
1265 _allow_any_dcp_frame_rate = new wxCheckBox (_panel, wxID_ANY, _("Allow any DCP frame rate"));
1266 table->Add (_allow_any_dcp_frame_rate, 1, wxEXPAND | wxALL);
1267 table->AddSpacer (0);
1269 _only_servers_encode = new wxCheckBox (_panel, wxID_ANY, _("Only servers encode"));
1270 table->Add (_only_servers_encode, 1, wxEXPAND | wxALL);
1271 table->AddSpacer (0);
1274 wxStaticText* m = new wxStaticText (_panel, wxID_ANY, _("Log:"));
1275 table->Add (m, 0, wxALIGN_TOP | wxLEFT | wxRIGHT | wxEXPAND | wxALL | wxALIGN_RIGHT, 6);
1277 wxStaticText* m = new wxStaticText (_panel, wxID_ANY, _("Log"));
1278 table->Add (m, 0, wxALIGN_TOP | wxLEFT | wxRIGHT | wxEXPAND | wxALL, 6);
1282 wxBoxSizer* t = new wxBoxSizer (wxVERTICAL);
1283 _log_general = new wxCheckBox (_panel, wxID_ANY, _("General"));
1284 t->Add (_log_general, 1, wxEXPAND | wxALL);
1285 _log_warning = new wxCheckBox (_panel, wxID_ANY, _("Warnings"));
1286 t->Add (_log_warning, 1, wxEXPAND | wxALL);
1287 _log_error = new wxCheckBox (_panel, wxID_ANY, _("Errors"));
1288 t->Add (_log_error, 1, wxEXPAND | wxALL);
1289 _log_timing = new wxCheckBox (_panel, wxID_ANY, S_("Config|Timing"));
1290 t->Add (_log_timing, 1, wxEXPAND | wxALL);
1291 _log_debug_decode = new wxCheckBox (_panel, wxID_ANY, _("Debug: decode"));
1292 t->Add (_log_debug_decode, 1, wxEXPAND | wxALL);
1293 _log_debug_encode = new wxCheckBox (_panel, wxID_ANY, _("Debug: encode"));
1294 t->Add (_log_debug_encode, 1, wxEXPAND | wxALL);
1295 table->Add (t, 0, wxALL, 6);
1298 #ifdef DCPOMATIC_WINDOWS
1299 _win32_console = new wxCheckBox (_panel, wxID_ANY, _("Open console window"));
1300 table->Add (_win32_console, 1, wxEXPAND | wxALL);
1301 table->AddSpacer (0);
1304 _maximum_j2k_bandwidth->SetRange (1, 1000);
1305 _maximum_j2k_bandwidth->Bind (wxEVT_COMMAND_SPINCTRL_UPDATED, boost::bind (&AdvancedPage::maximum_j2k_bandwidth_changed, this));
1306 _allow_any_dcp_frame_rate->Bind (wxEVT_COMMAND_CHECKBOX_CLICKED, boost::bind (&AdvancedPage::allow_any_dcp_frame_rate_changed, this));
1307 _only_servers_encode->Bind (wxEVT_COMMAND_CHECKBOX_CLICKED, boost::bind (&AdvancedPage::only_servers_encode_changed, this));
1308 _log_general->Bind (wxEVT_COMMAND_CHECKBOX_CLICKED, boost::bind (&AdvancedPage::log_changed, this));
1309 _log_warning->Bind (wxEVT_COMMAND_CHECKBOX_CLICKED, boost::bind (&AdvancedPage::log_changed, this));
1310 _log_error->Bind (wxEVT_COMMAND_CHECKBOX_CLICKED, boost::bind (&AdvancedPage::log_changed, this));
1311 _log_timing->Bind (wxEVT_COMMAND_CHECKBOX_CLICKED, boost::bind (&AdvancedPage::log_changed, this));
1312 _log_debug_decode->Bind (wxEVT_COMMAND_CHECKBOX_CLICKED, boost::bind (&AdvancedPage::log_changed, this));
1313 _log_debug_encode->Bind (wxEVT_COMMAND_CHECKBOX_CLICKED, boost::bind (&AdvancedPage::log_changed, this));
1314 #ifdef DCPOMATIC_WINDOWS
1315 _win32_console->Bind (wxEVT_COMMAND_CHECKBOX_CLICKED, boost::bind (&AdvancedPage::win32_console_changed, this));
1319 void config_changed ()
1321 Config* config = Config::instance ();
1323 checked_set (_maximum_j2k_bandwidth, config->maximum_j2k_bandwidth() / 1000000);
1324 checked_set (_allow_any_dcp_frame_rate, config->allow_any_dcp_frame_rate ());
1325 checked_set (_only_servers_encode, config->only_servers_encode ());
1326 checked_set (_log_general, config->log_types() & Log::TYPE_GENERAL);
1327 checked_set (_log_warning, config->log_types() & Log::TYPE_WARNING);
1328 checked_set (_log_error, config->log_types() & Log::TYPE_ERROR);
1329 checked_set (_log_timing, config->log_types() & Log::TYPE_TIMING);
1330 checked_set (_log_debug_decode, config->log_types() & Log::TYPE_DEBUG_DECODE);
1331 checked_set (_log_debug_encode, config->log_types() & Log::TYPE_DEBUG_ENCODE);
1332 #ifdef DCPOMATIC_WINDOWS
1333 checked_set (_win32_console, config->win32_console());
1337 void maximum_j2k_bandwidth_changed ()
1339 Config::instance()->set_maximum_j2k_bandwidth (_maximum_j2k_bandwidth->GetValue() * 1000000);
1342 void allow_any_dcp_frame_rate_changed ()
1344 Config::instance()->set_allow_any_dcp_frame_rate (_allow_any_dcp_frame_rate->GetValue ());
1347 void only_servers_encode_changed ()
1349 Config::instance()->set_only_servers_encode (_only_servers_encode->GetValue ());
1355 if (_log_general->GetValue ()) {
1356 types |= Log::TYPE_GENERAL;
1358 if (_log_warning->GetValue ()) {
1359 types |= Log::TYPE_WARNING;
1361 if (_log_error->GetValue ()) {
1362 types |= Log::TYPE_ERROR;
1364 if (_log_timing->GetValue ()) {
1365 types |= Log::TYPE_TIMING;
1367 if (_log_debug_decode->GetValue ()) {
1368 types |= Log::TYPE_DEBUG_DECODE;
1370 if (_log_debug_encode->GetValue ()) {
1371 types |= Log::TYPE_DEBUG_ENCODE;
1373 Config::instance()->set_log_types (types);
1376 #ifdef DCPOMATIC_WINDOWS
1377 void win32_console_changed ()
1379 Config::instance()->set_win32_console (_win32_console->GetValue ());
1383 wxSpinCtrl* _maximum_j2k_bandwidth;
1384 wxCheckBox* _allow_any_dcp_frame_rate;
1385 wxCheckBox* _only_servers_encode;
1386 wxCheckBox* _log_general;
1387 wxCheckBox* _log_warning;
1388 wxCheckBox* _log_error;
1389 wxCheckBox* _log_timing;
1390 wxCheckBox* _log_debug_decode;
1391 wxCheckBox* _log_debug_encode;
1392 #ifdef DCPOMATIC_WINDOWS
1393 wxCheckBox* _win32_console;
1397 wxPreferencesEditor*
1398 create_config_dialog ()
1400 wxPreferencesEditor* e = new wxPreferencesEditor ();
1402 #ifdef DCPOMATIC_OSX
1403 /* Width that we force some of the config panels to be on OSX so that
1404 the containing window doesn't shrink too much when we select those panels.
1405 This is obviously an unpleasant hack.
1407 wxSize ps = wxSize (520, -1);
1408 int const border = 16;
1410 wxSize ps = wxSize (-1, -1);
1411 int const border = 8;
1414 e->AddPage (new GeneralPage (ps, border));
1415 e->AddPage (new DefaultsPage (ps, border));
1416 e->AddPage (new EncodingServersPage (ps, border));
1417 e->AddPage (new KeysPage (ps, border));
1418 e->AddPage (new TMSPage (ps, border));
1419 e->AddPage (new KDMEmailPage (ps, border));
1420 e->AddPage (new AdvancedPage (ps, border));