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 subject_organization_name;
798 string subject_organizational_unit_name;
799 string root_common_name;
800 string intermediate_common_name;
801 string leaf_common_name;
803 dcp::CertificateChain::List all = chain->root_to_leaf ();
805 if (all.size() >= 1) {
807 subject_organization_name = chain->root().subject_organization_name ();
808 subject_organizational_unit_name = chain->root().subject_organizational_unit_name ();
809 root_common_name = chain->root().subject_common_name ();
812 if (all.size() >= 2) {
814 leaf_common_name = chain->leaf().subject_common_name ();
817 if (all.size() >= 3) {
818 /* Have an intermediate */
819 dcp::CertificateChain::List::iterator i = all.begin ();
821 intermediate_common_name = i->subject_common_name ();
824 MakeChainDialog* d = new MakeChainDialog (
826 subject_organization_name,
827 subject_organizational_unit_name,
829 intermediate_common_name,
833 if (d->ShowModal () == wxID_OK) {
835 new dcp::CertificateChain (
838 d->organisational_unit (),
839 d->root_common_name (),
840 d->intermediate_common_name (),
841 d->leaf_common_name ()
846 update_certificate_list ();
847 update_private_key ();
853 void update_sensitivity ()
855 _remove_certificate->Enable (_certificates->GetNextItem (-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED) != -1);
856 _export_certificate->Enable (_certificates->GetNextItem (-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED) != -1);
859 void update_private_key ()
861 checked_set (_private_key, dcp::private_key_fingerprint (_chain->key().get ()));
865 void load_private_key ()
867 wxFileDialog* d = new wxFileDialog (this, _("Select Key File"));
869 if (d->ShowModal() == wxID_OK) {
871 boost::filesystem::path p (wx_to_std (d->GetPath ()));
872 if (boost::filesystem::file_size (p) > 1024) {
873 error_dialog (this, wxString::Format (_("Could not read key file (%s)"), std_to_wx (p.string ())));
877 _chain->set_key (dcp::file_to_string (p));
879 update_private_key ();
880 } catch (dcp::MiscError& e) {
881 error_dialog (this, wxString::Format (_("Could not read certificate file (%s)"), e.what ()));
887 update_sensitivity ();
890 wxListCtrl* _certificates;
891 wxButton* _add_certificate;
892 wxButton* _export_certificate;
893 wxButton* _remove_certificate;
894 wxButton* _remake_certificates;
895 wxStaticText* _private_key;
896 wxButton* _load_private_key;
898 wxBoxSizer* _button_sizer;
899 shared_ptr<dcp::CertificateChain> _chain;
900 boost::function<void (shared_ptr<dcp::CertificateChain>)> _set;
901 boost::function<shared_ptr<const dcp::CertificateChain> (void)> _get;
904 class KeysPage : public StandardPage
907 KeysPage (wxSize panel_size, int border)
908 : StandardPage (panel_size, border)
911 wxString GetName () const
917 wxBitmap GetLargeIcon () const
919 return wxBitmap ("keys", wxBITMAP_TYPE_PNG_RESOURCE);
927 _signer = new CertificateChainEditor (
928 _panel, _("Signing DCPs and KDMs"), _border,
929 boost::bind (&Config::set_signer_chain, Config::instance (), _1),
930 boost::bind (&Config::signer_chain, Config::instance ())
933 _panel->GetSizer()->Add (_signer);
935 _decryption = new CertificateChainEditor (
936 _panel, _("Decrypting DCPs"), _border,
937 boost::bind (&Config::set_decryption_chain, Config::instance (), _1),
938 boost::bind (&Config::decryption_chain, Config::instance ())
941 _panel->GetSizer()->Add (_decryption);
943 _export_decryption_certificate = new wxButton (_decryption, wxID_ANY, _("Export DCP decryption certificate..."));
944 _decryption->add_button (_export_decryption_certificate);
946 _export_decryption_certificate->Bind (wxEVT_COMMAND_BUTTON_CLICKED, boost::bind (&KeysPage::export_decryption_certificate, this));
949 void export_decryption_certificate ()
951 wxFileDialog* d = new wxFileDialog (
952 _panel, _("Select Certificate File"), wxEmptyString, wxEmptyString, wxT ("PEM files (*.pem)|*.pem"),
953 wxFD_SAVE | wxFD_OVERWRITE_PROMPT
956 if (d->ShowModal () == wxID_OK) {
957 FILE* f = fopen_boost (wx_to_std (d->GetPath ()), "w");
959 throw OpenFileError (wx_to_std (d->GetPath ()));
962 string const s = Config::instance()->decryption_chain()->leaf().certificate (true);
963 fwrite (s.c_str(), 1, s.length(), f);
969 void config_changed ()
971 _signer->config_changed ();
972 _decryption->config_changed ();
975 CertificateChainEditor* _signer;
976 CertificateChainEditor* _decryption;
977 wxButton* _export_decryption_certificate;
980 class TMSPage : public StandardPage
983 TMSPage (wxSize panel_size, int border)
984 : StandardPage (panel_size, border)
987 wxString GetName () const
993 wxBitmap GetLargeIcon () const
995 return wxBitmap ("tms", wxBITMAP_TYPE_PNG_RESOURCE);
1002 wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
1003 table->AddGrowableCol (1, 1);
1004 _panel->GetSizer()->Add (table, 1, wxALL | wxEXPAND, _border);
1006 add_label_to_sizer (table, _panel, _("Protocol"), true);
1007 _tms_protocol = new wxChoice (_panel, wxID_ANY);
1008 table->Add (_tms_protocol, 1, wxEXPAND);
1010 add_label_to_sizer (table, _panel, _("IP address"), true);
1011 _tms_ip = new wxTextCtrl (_panel, wxID_ANY);
1012 table->Add (_tms_ip, 1, wxEXPAND);
1014 add_label_to_sizer (table, _panel, _("Target path"), true);
1015 _tms_path = new wxTextCtrl (_panel, wxID_ANY);
1016 table->Add (_tms_path, 1, wxEXPAND);
1018 add_label_to_sizer (table, _panel, _("User name"), true);
1019 _tms_user = new wxTextCtrl (_panel, wxID_ANY);
1020 table->Add (_tms_user, 1, wxEXPAND);
1022 add_label_to_sizer (table, _panel, _("Password"), true);
1023 _tms_password = new wxTextCtrl (_panel, wxID_ANY);
1024 table->Add (_tms_password, 1, wxEXPAND);
1026 _tms_protocol->Append (_("SCP (for AAM and Doremi)"));
1027 _tms_protocol->Append (_("FTP (for Dolby)"));
1029 _tms_protocol->Bind (wxEVT_COMMAND_CHOICE_SELECTED, boost::bind (&TMSPage::tms_protocol_changed, this));
1030 _tms_ip->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&TMSPage::tms_ip_changed, this));
1031 _tms_path->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&TMSPage::tms_path_changed, this));
1032 _tms_user->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&TMSPage::tms_user_changed, this));
1033 _tms_password->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&TMSPage::tms_password_changed, this));
1036 void config_changed ()
1038 Config* config = Config::instance ();
1040 checked_set (_tms_protocol, config->tms_protocol ());
1041 checked_set (_tms_ip, config->tms_ip ());
1042 checked_set (_tms_path, config->tms_path ());
1043 checked_set (_tms_user, config->tms_user ());
1044 checked_set (_tms_password, config->tms_password ());
1047 void tms_protocol_changed ()
1049 Config::instance()->set_tms_protocol (static_cast<Protocol> (_tms_protocol->GetSelection ()));
1052 void tms_ip_changed ()
1054 Config::instance()->set_tms_ip (wx_to_std (_tms_ip->GetValue ()));
1057 void tms_path_changed ()
1059 Config::instance()->set_tms_path (wx_to_std (_tms_path->GetValue ()));
1062 void tms_user_changed ()
1064 Config::instance()->set_tms_user (wx_to_std (_tms_user->GetValue ()));
1067 void tms_password_changed ()
1069 Config::instance()->set_tms_password (wx_to_std (_tms_password->GetValue ()));
1072 wxChoice* _tms_protocol;
1073 wxTextCtrl* _tms_ip;
1074 wxTextCtrl* _tms_path;
1075 wxTextCtrl* _tms_user;
1076 wxTextCtrl* _tms_password;
1079 class KDMEmailPage : public StandardPage
1083 KDMEmailPage (wxSize panel_size, int border)
1084 #ifdef DCPOMATIC_OSX
1085 /* We have to force both width and height of this one */
1086 : StandardPage (wxSize (480, 128), border)
1088 : StandardPage (panel_size, border)
1092 wxString GetName () const
1094 return _("KDM Email");
1097 #ifdef DCPOMATIC_OSX
1098 wxBitmap GetLargeIcon () const
1100 return wxBitmap ("kdm_email", wxBITMAP_TYPE_PNG_RESOURCE);
1107 wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
1108 table->AddGrowableCol (1, 1);
1109 _panel->GetSizer()->Add (table, 1, wxEXPAND | wxALL, _border);
1111 add_label_to_sizer (table, _panel, _("Outgoing mail server"), true);
1113 wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL);
1114 _mail_server = new wxTextCtrl (_panel, wxID_ANY);
1115 s->Add (_mail_server, 1, wxEXPAND | wxALL);
1116 add_label_to_sizer (s, _panel, _("port"), false);
1117 _mail_port = new wxSpinCtrl (_panel, wxID_ANY);
1118 _mail_port->SetRange (0, 65535);
1119 s->Add (_mail_port);
1120 table->Add (s, 1, wxEXPAND | wxALL);
1123 add_label_to_sizer (table, _panel, _("Mail user name"), true);
1124 _mail_user = new wxTextCtrl (_panel, wxID_ANY);
1125 table->Add (_mail_user, 1, wxEXPAND | wxALL);
1127 add_label_to_sizer (table, _panel, _("Mail password"), true);
1128 _mail_password = new wxTextCtrl (_panel, wxID_ANY);
1129 table->Add (_mail_password, 1, wxEXPAND | wxALL);
1131 add_label_to_sizer (table, _panel, _("Subject"), true);
1132 _kdm_subject = new wxTextCtrl (_panel, wxID_ANY);
1133 table->Add (_kdm_subject, 1, wxEXPAND | wxALL);
1135 add_label_to_sizer (table, _panel, _("From address"), true);
1136 _kdm_from = new wxTextCtrl (_panel, wxID_ANY);
1137 table->Add (_kdm_from, 1, wxEXPAND | wxALL);
1139 add_label_to_sizer (table, _panel, _("CC address"), true);
1140 _kdm_cc = new wxTextCtrl (_panel, wxID_ANY);
1141 table->Add (_kdm_cc, 1, wxEXPAND | wxALL);
1143 add_label_to_sizer (table, _panel, _("BCC address"), true);
1144 _kdm_bcc = new wxTextCtrl (_panel, wxID_ANY);
1145 table->Add (_kdm_bcc, 1, wxEXPAND | wxALL);
1147 _kdm_email = new wxTextCtrl (_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize (480, 128), wxTE_MULTILINE);
1148 _panel->GetSizer()->Add (_kdm_email, 1, wxEXPAND | wxALL, _border);
1150 _reset_kdm_email = new wxButton (_panel, wxID_ANY, _("Reset to default text"));
1151 _panel->GetSizer()->Add (_reset_kdm_email, 0, wxEXPAND | wxALL, _border);
1153 _mail_server->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&KDMEmailPage::mail_server_changed, this));
1154 _mail_port->Bind (wxEVT_COMMAND_SPINCTRL_UPDATED, boost::bind (&KDMEmailPage::mail_port_changed, this));
1155 _mail_user->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&KDMEmailPage::mail_user_changed, this));
1156 _mail_password->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&KDMEmailPage::mail_password_changed, this));
1157 _kdm_subject->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&KDMEmailPage::kdm_subject_changed, this));
1158 _kdm_from->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&KDMEmailPage::kdm_from_changed, this));
1159 _kdm_cc->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&KDMEmailPage::kdm_cc_changed, this));
1160 _kdm_bcc->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&KDMEmailPage::kdm_bcc_changed, this));
1161 _kdm_email->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&KDMEmailPage::kdm_email_changed, this));
1162 _reset_kdm_email->Bind (wxEVT_COMMAND_BUTTON_CLICKED, boost::bind (&KDMEmailPage::reset_kdm_email, this));
1165 void config_changed ()
1167 Config* config = Config::instance ();
1169 checked_set (_mail_server, config->mail_server ());
1170 checked_set (_mail_port, config->mail_port ());
1171 checked_set (_mail_user, config->mail_user ());
1172 checked_set (_mail_password, config->mail_password ());
1173 checked_set (_kdm_subject, config->kdm_subject ());
1174 checked_set (_kdm_from, config->kdm_from ());
1175 checked_set (_kdm_cc, config->kdm_cc ());
1176 checked_set (_kdm_bcc, config->kdm_bcc ());
1177 checked_set (_kdm_email, Config::instance()->kdm_email ());
1180 void mail_server_changed ()
1182 Config::instance()->set_mail_server (wx_to_std (_mail_server->GetValue ()));
1185 void mail_port_changed ()
1187 Config::instance()->set_mail_port (_mail_port->GetValue ());
1190 void mail_user_changed ()
1192 Config::instance()->set_mail_user (wx_to_std (_mail_user->GetValue ()));
1195 void mail_password_changed ()
1197 Config::instance()->set_mail_password (wx_to_std (_mail_password->GetValue ()));
1200 void kdm_subject_changed ()
1202 Config::instance()->set_kdm_subject (wx_to_std (_kdm_subject->GetValue ()));
1205 void kdm_from_changed ()
1207 Config::instance()->set_kdm_from (wx_to_std (_kdm_from->GetValue ()));
1210 void kdm_cc_changed ()
1212 Config::instance()->set_kdm_cc (wx_to_std (_kdm_cc->GetValue ()));
1215 void kdm_bcc_changed ()
1217 Config::instance()->set_kdm_bcc (wx_to_std (_kdm_bcc->GetValue ()));
1220 void kdm_email_changed ()
1222 if (_kdm_email->GetValue().IsEmpty ()) {
1223 /* Sometimes we get sent an erroneous notification that the email
1224 is empty; I don't know why.
1228 Config::instance()->set_kdm_email (wx_to_std (_kdm_email->GetValue ()));
1231 void reset_kdm_email ()
1233 Config::instance()->reset_kdm_email ();
1234 checked_set (_kdm_email, Config::instance()->kdm_email ());
1237 wxTextCtrl* _mail_server;
1238 wxSpinCtrl* _mail_port;
1239 wxTextCtrl* _mail_user;
1240 wxTextCtrl* _mail_password;
1241 wxTextCtrl* _kdm_subject;
1242 wxTextCtrl* _kdm_from;
1243 wxTextCtrl* _kdm_cc;
1244 wxTextCtrl* _kdm_bcc;
1245 wxTextCtrl* _kdm_email;
1246 wxButton* _reset_kdm_email;
1249 /** @class AdvancedPage
1250 * @brief Advanced page of the preferences dialog.
1252 class AdvancedPage : public StockPage
1255 AdvancedPage (wxSize panel_size, int border)
1256 : StockPage (Kind_Advanced, panel_size, border)
1257 , _maximum_j2k_bandwidth (0)
1258 , _allow_any_dcp_frame_rate (0)
1259 , _only_servers_encode (0)
1264 , _log_debug_decode (0)
1265 , _log_debug_encode (0)
1271 wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
1272 table->AddGrowableCol (1, 1);
1273 _panel->GetSizer()->Add (table, 1, wxALL | wxEXPAND, _border);
1276 add_label_to_sizer (table, _panel, _("Maximum JPEG2000 bandwidth"), true);
1277 wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL);
1278 _maximum_j2k_bandwidth = new wxSpinCtrl (_panel);
1279 s->Add (_maximum_j2k_bandwidth, 1);
1280 add_label_to_sizer (s, _panel, _("Mbit/s"), false);
1284 _allow_any_dcp_frame_rate = new wxCheckBox (_panel, wxID_ANY, _("Allow any DCP frame rate"));
1285 table->Add (_allow_any_dcp_frame_rate, 1, wxEXPAND | wxALL);
1286 table->AddSpacer (0);
1288 _only_servers_encode = new wxCheckBox (_panel, wxID_ANY, _("Only servers encode"));
1289 table->Add (_only_servers_encode, 1, wxEXPAND | wxALL);
1290 table->AddSpacer (0);
1293 wxStaticText* m = new wxStaticText (_panel, wxID_ANY, _("Log:"));
1294 table->Add (m, 0, wxALIGN_TOP | wxLEFT | wxRIGHT | wxEXPAND | wxALL | wxALIGN_RIGHT, 6);
1296 wxStaticText* m = new wxStaticText (_panel, wxID_ANY, _("Log"));
1297 table->Add (m, 0, wxALIGN_TOP | wxLEFT | wxRIGHT | wxEXPAND | wxALL, 6);
1301 wxBoxSizer* t = new wxBoxSizer (wxVERTICAL);
1302 _log_general = new wxCheckBox (_panel, wxID_ANY, _("General"));
1303 t->Add (_log_general, 1, wxEXPAND | wxALL);
1304 _log_warning = new wxCheckBox (_panel, wxID_ANY, _("Warnings"));
1305 t->Add (_log_warning, 1, wxEXPAND | wxALL);
1306 _log_error = new wxCheckBox (_panel, wxID_ANY, _("Errors"));
1307 t->Add (_log_error, 1, wxEXPAND | wxALL);
1308 _log_timing = new wxCheckBox (_panel, wxID_ANY, S_("Config|Timing"));
1309 t->Add (_log_timing, 1, wxEXPAND | wxALL);
1310 _log_debug_decode = new wxCheckBox (_panel, wxID_ANY, _("Debug: decode"));
1311 t->Add (_log_debug_decode, 1, wxEXPAND | wxALL);
1312 _log_debug_encode = new wxCheckBox (_panel, wxID_ANY, _("Debug: encode"));
1313 t->Add (_log_debug_encode, 1, wxEXPAND | wxALL);
1314 table->Add (t, 0, wxALL, 6);
1317 #ifdef DCPOMATIC_WINDOWS
1318 _win32_console = new wxCheckBox (_panel, wxID_ANY, _("Open console window"));
1319 table->Add (_win32_console, 1, wxEXPAND | wxALL);
1320 table->AddSpacer (0);
1323 _maximum_j2k_bandwidth->SetRange (1, 1000);
1324 _maximum_j2k_bandwidth->Bind (wxEVT_COMMAND_SPINCTRL_UPDATED, boost::bind (&AdvancedPage::maximum_j2k_bandwidth_changed, this));
1325 _allow_any_dcp_frame_rate->Bind (wxEVT_COMMAND_CHECKBOX_CLICKED, boost::bind (&AdvancedPage::allow_any_dcp_frame_rate_changed, this));
1326 _only_servers_encode->Bind (wxEVT_COMMAND_CHECKBOX_CLICKED, boost::bind (&AdvancedPage::only_servers_encode_changed, this));
1327 _log_general->Bind (wxEVT_COMMAND_CHECKBOX_CLICKED, boost::bind (&AdvancedPage::log_changed, this));
1328 _log_warning->Bind (wxEVT_COMMAND_CHECKBOX_CLICKED, boost::bind (&AdvancedPage::log_changed, this));
1329 _log_error->Bind (wxEVT_COMMAND_CHECKBOX_CLICKED, boost::bind (&AdvancedPage::log_changed, this));
1330 _log_timing->Bind (wxEVT_COMMAND_CHECKBOX_CLICKED, boost::bind (&AdvancedPage::log_changed, this));
1331 _log_debug_decode->Bind (wxEVT_COMMAND_CHECKBOX_CLICKED, boost::bind (&AdvancedPage::log_changed, this));
1332 _log_debug_encode->Bind (wxEVT_COMMAND_CHECKBOX_CLICKED, boost::bind (&AdvancedPage::log_changed, this));
1333 #ifdef DCPOMATIC_WINDOWS
1334 _win32_console->Bind (wxEVT_COMMAND_CHECKBOX_CLICKED, boost::bind (&AdvancedPage::win32_console_changed, this));
1338 void config_changed ()
1340 Config* config = Config::instance ();
1342 checked_set (_maximum_j2k_bandwidth, config->maximum_j2k_bandwidth() / 1000000);
1343 checked_set (_allow_any_dcp_frame_rate, config->allow_any_dcp_frame_rate ());
1344 checked_set (_only_servers_encode, config->only_servers_encode ());
1345 checked_set (_log_general, config->log_types() & Log::TYPE_GENERAL);
1346 checked_set (_log_warning, config->log_types() & Log::TYPE_WARNING);
1347 checked_set (_log_error, config->log_types() & Log::TYPE_ERROR);
1348 checked_set (_log_timing, config->log_types() & Log::TYPE_TIMING);
1349 checked_set (_log_debug_decode, config->log_types() & Log::TYPE_DEBUG_DECODE);
1350 checked_set (_log_debug_encode, config->log_types() & Log::TYPE_DEBUG_ENCODE);
1351 #ifdef DCPOMATIC_WINDOWS
1352 checked_set (_win32_console, config->win32_console());
1356 void maximum_j2k_bandwidth_changed ()
1358 Config::instance()->set_maximum_j2k_bandwidth (_maximum_j2k_bandwidth->GetValue() * 1000000);
1361 void allow_any_dcp_frame_rate_changed ()
1363 Config::instance()->set_allow_any_dcp_frame_rate (_allow_any_dcp_frame_rate->GetValue ());
1366 void only_servers_encode_changed ()
1368 Config::instance()->set_only_servers_encode (_only_servers_encode->GetValue ());
1374 if (_log_general->GetValue ()) {
1375 types |= Log::TYPE_GENERAL;
1377 if (_log_warning->GetValue ()) {
1378 types |= Log::TYPE_WARNING;
1380 if (_log_error->GetValue ()) {
1381 types |= Log::TYPE_ERROR;
1383 if (_log_timing->GetValue ()) {
1384 types |= Log::TYPE_TIMING;
1386 if (_log_debug_decode->GetValue ()) {
1387 types |= Log::TYPE_DEBUG_DECODE;
1389 if (_log_debug_encode->GetValue ()) {
1390 types |= Log::TYPE_DEBUG_ENCODE;
1392 Config::instance()->set_log_types (types);
1395 #ifdef DCPOMATIC_WINDOWS
1396 void win32_console_changed ()
1398 Config::instance()->set_win32_console (_win32_console->GetValue ());
1402 wxSpinCtrl* _maximum_j2k_bandwidth;
1403 wxCheckBox* _allow_any_dcp_frame_rate;
1404 wxCheckBox* _only_servers_encode;
1405 wxCheckBox* _log_general;
1406 wxCheckBox* _log_warning;
1407 wxCheckBox* _log_error;
1408 wxCheckBox* _log_timing;
1409 wxCheckBox* _log_debug_decode;
1410 wxCheckBox* _log_debug_encode;
1411 #ifdef DCPOMATIC_WINDOWS
1412 wxCheckBox* _win32_console;
1416 wxPreferencesEditor*
1417 create_config_dialog ()
1419 wxPreferencesEditor* e = new wxPreferencesEditor ();
1421 #ifdef DCPOMATIC_OSX
1422 /* Width that we force some of the config panels to be on OSX so that
1423 the containing window doesn't shrink too much when we select those panels.
1424 This is obviously an unpleasant hack.
1426 wxSize ps = wxSize (520, -1);
1427 int const border = 16;
1429 wxSize ps = wxSize (-1, -1);
1430 int const border = 8;
1433 e->AddPage (new GeneralPage (ps, border));
1434 e->AddPage (new DefaultsPage (ps, border));
1435 e->AddPage (new EncodingServersPage (ps, border));
1436 e->AddPage (new KeysPage (ps, border));
1437 e->AddPage (new TMSPage (ps, border));
1438 e->AddPage (new KDMEmailPage (ps, border));
1439 e->AddPage (new AdvancedPage (ps, border));