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;
60 using boost::optional;
65 Page (wxSize panel_size, int border)
68 , _panel_size (panel_size)
69 , _window_exists (false)
71 _config_connection = Config::instance()->Changed.connect (boost::bind (&Page::config_changed_wrapper, this));
77 wxWindow* create_window (wxWindow* parent)
79 _panel = new wxPanel (parent, wxID_ANY, wxDefaultPosition, _panel_size);
80 wxBoxSizer* s = new wxBoxSizer (wxVERTICAL);
84 _window_exists = true;
87 _panel->Bind (wxEVT_DESTROY, boost::bind (&Page::window_destroyed, this));
96 virtual void config_changed () = 0;
97 virtual void setup () = 0;
99 void config_changed_wrapper ()
101 if (_window_exists) {
106 void window_destroyed ()
108 _window_exists = false;
112 boost::signals2::scoped_connection _config_connection;
116 class StockPage : public wxStockPreferencesPage, public Page
119 StockPage (Kind kind, wxSize panel_size, int border)
120 : wxStockPreferencesPage (kind)
121 , Page (panel_size, border)
124 wxWindow* CreateWindow (wxWindow* parent)
126 return create_window (parent);
130 class StandardPage : public wxPreferencesPage, public Page
133 StandardPage (wxSize panel_size, int border)
134 : Page (panel_size, border)
137 wxWindow* CreateWindow (wxWindow* parent)
139 return create_window (parent);
143 class GeneralPage : public StockPage
146 GeneralPage (wxSize panel_size, int border)
147 : StockPage (Kind_General, panel_size, border)
153 wxGridBagSizer* table = new wxGridBagSizer (DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
154 _panel->GetSizer()->Add (table, 1, wxALL | wxEXPAND, _border);
157 _set_language = new wxCheckBox (_panel, wxID_ANY, _("Set language"));
158 table->Add (_set_language, wxGBPosition (r, 0));
159 _language = new wxChoice (_panel, wxID_ANY);
160 _language->Append (wxT ("Deutsch"));
161 _language->Append (wxT ("English"));
162 _language->Append (wxT ("Español"));
163 _language->Append (wxT ("Français"));
164 _language->Append (wxT ("Italiano"));
165 _language->Append (wxT ("Nederlands"));
166 _language->Append (wxT ("Svenska"));
167 _language->Append (wxT ("Русский"));
168 _language->Append (wxT ("Polski"));
169 _language->Append (wxT ("Dansk"));
170 _language->Append (wxT ("Português europeu"));
171 table->Add (_language, wxGBPosition (r, 1));
174 wxStaticText* restart = add_label_to_sizer (
175 table, _panel, _("(restart DCP-o-matic to see language changes)"), false, wxGBPosition (r, 0), wxGBSpan (1, 2)
177 wxFont font = restart->GetFont();
178 font.SetStyle (wxFONTSTYLE_ITALIC);
179 font.SetPointSize (font.GetPointSize() - 1);
180 restart->SetFont (font);
183 add_label_to_sizer (table, _panel, _("Threads to use for encoding on this host"), true, wxGBPosition (r, 0));
184 _num_local_encoding_threads = new wxSpinCtrl (_panel);
185 table->Add (_num_local_encoding_threads, wxGBPosition (r, 1));
188 _automatic_audio_analysis = new wxCheckBox (_panel, wxID_ANY, _("Automatically analyse content audio"));
189 table->Add (_automatic_audio_analysis, wxGBPosition (r, 0), wxGBSpan (1, 2));
192 _check_for_updates = new wxCheckBox (_panel, wxID_ANY, _("Check for updates on startup"));
193 table->Add (_check_for_updates, wxGBPosition (r, 0), wxGBSpan (1, 2));
196 _check_for_test_updates = new wxCheckBox (_panel, wxID_ANY, _("Check for testing updates as well as stable ones"));
197 table->Add (_check_for_test_updates, wxGBPosition (r, 0), wxGBSpan (1, 2));
200 wxFlexGridSizer* bottom_table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
201 bottom_table->AddGrowableCol (1, 1);
203 add_label_to_sizer (bottom_table, _panel, _("Issuer"), true);
204 _issuer = new wxTextCtrl (_panel, wxID_ANY);
205 bottom_table->Add (_issuer, 1, wxALL | wxEXPAND);
207 add_label_to_sizer (bottom_table, _panel, _("Creator"), true);
208 _creator = new wxTextCtrl (_panel, wxID_ANY);
209 bottom_table->Add (_creator, 1, wxALL | wxEXPAND);
211 table->Add (bottom_table, wxGBPosition (r, 0), wxGBSpan (2, 2), wxEXPAND);
214 _set_language->Bind (wxEVT_COMMAND_CHECKBOX_CLICKED, boost::bind (&GeneralPage::set_language_changed, this));
215 _language->Bind (wxEVT_COMMAND_CHOICE_SELECTED, boost::bind (&GeneralPage::language_changed, this));
217 _num_local_encoding_threads->SetRange (1, 128);
218 _num_local_encoding_threads->Bind (wxEVT_COMMAND_SPINCTRL_UPDATED, boost::bind (&GeneralPage::num_local_encoding_threads_changed, this));
220 _automatic_audio_analysis->Bind (wxEVT_COMMAND_CHECKBOX_CLICKED, boost::bind (&GeneralPage::automatic_audio_analysis_changed, this));
221 _check_for_updates->Bind (wxEVT_COMMAND_CHECKBOX_CLICKED, boost::bind (&GeneralPage::check_for_updates_changed, this));
222 _check_for_test_updates->Bind (wxEVT_COMMAND_CHECKBOX_CLICKED, boost::bind (&GeneralPage::check_for_test_updates_changed, this));
224 _issuer->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&GeneralPage::issuer_changed, this));
225 _creator->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&GeneralPage::creator_changed, this));
228 void config_changed ()
230 Config* config = Config::instance ();
232 checked_set (_set_language, static_cast<bool>(config->language()));
234 if (config->language().get_value_or ("") == "fr") {
235 checked_set (_language, 3);
236 } else if (config->language().get_value_or ("") == "it") {
237 checked_set (_language, 4);
238 } else if (config->language().get_value_or ("") == "es") {
239 checked_set (_language, 2);
240 } else if (config->language().get_value_or ("") == "sv") {
241 checked_set (_language, 6);
242 } else if (config->language().get_value_or ("") == "de") {
243 checked_set (_language, 0);
244 } else if (config->language().get_value_or ("") == "nl") {
245 checked_set (_language, 5);
246 } else if (config->language().get_value_or ("") == "ru") {
247 checked_set (_language, 7);
248 } else if (config->language().get_value_or ("") == "pl") {
249 checked_set (_language, 8);
250 } else if (config->language().get_value_or ("") == "da") {
251 checked_set (_language, 9);
252 } else if (config->language().get_value_or ("") == "pt") {
253 checked_set (_language, 10);
255 _language->SetSelection (1);
258 setup_language_sensitivity ();
260 checked_set (_num_local_encoding_threads, config->num_local_encoding_threads ());
261 checked_set (_automatic_audio_analysis, config->automatic_audio_analysis ());
262 checked_set (_check_for_updates, config->check_for_updates ());
263 checked_set (_check_for_test_updates, config->check_for_test_updates ());
264 checked_set (_issuer, config->dcp_issuer ());
265 checked_set (_creator, config->dcp_creator ());
268 void setup_language_sensitivity ()
270 _language->Enable (_set_language->GetValue ());
273 void set_language_changed ()
275 setup_language_sensitivity ();
276 if (_set_language->GetValue ()) {
279 Config::instance()->unset_language ();
283 void language_changed ()
285 switch (_language->GetSelection ()) {
287 Config::instance()->set_language ("de");
290 Config::instance()->set_language ("en");
293 Config::instance()->set_language ("es");
296 Config::instance()->set_language ("fr");
299 Config::instance()->set_language ("it");
302 Config::instance()->set_language ("nl");
305 Config::instance()->set_language ("sv");
308 Config::instance()->set_language ("ru");
311 Config::instance()->set_language ("pl");
314 Config::instance()->set_language ("da");
317 Config::instance()->set_language ("pt");
322 void automatic_audio_analysis_changed ()
324 Config::instance()->set_automatic_audio_analysis (_automatic_audio_analysis->GetValue ());
327 void check_for_updates_changed ()
329 Config::instance()->set_check_for_updates (_check_for_updates->GetValue ());
332 void check_for_test_updates_changed ()
334 Config::instance()->set_check_for_test_updates (_check_for_test_updates->GetValue ());
337 void num_local_encoding_threads_changed ()
339 Config::instance()->set_num_local_encoding_threads (_num_local_encoding_threads->GetValue ());
342 void issuer_changed ()
344 Config::instance()->set_dcp_issuer (wx_to_std (_issuer->GetValue ()));
347 void creator_changed ()
349 Config::instance()->set_dcp_creator (wx_to_std (_creator->GetValue ()));
352 wxCheckBox* _set_language;
354 wxSpinCtrl* _num_local_encoding_threads;
355 wxCheckBox* _automatic_audio_analysis;
356 wxCheckBox* _check_for_updates;
357 wxCheckBox* _check_for_test_updates;
359 wxTextCtrl* _creator;
362 class DefaultsPage : public StandardPage
365 DefaultsPage (wxSize panel_size, int border)
366 : StandardPage (panel_size, border)
369 wxString GetName () const
371 return _("Defaults");
375 wxBitmap GetLargeIcon () const
377 return wxBitmap ("defaults", wxBITMAP_TYPE_PNG_RESOURCE);
384 wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
385 table->AddGrowableCol (1, 1);
386 _panel->GetSizer()->Add (table, 1, wxALL | wxEXPAND, _border);
389 add_label_to_sizer (table, _panel, _("Default duration of still images"), true);
390 wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL);
391 _still_length = new wxSpinCtrl (_panel);
392 s->Add (_still_length);
393 add_label_to_sizer (s, _panel, _("s"), false);
397 add_label_to_sizer (table, _panel, _("Default directory for new films"), true);
398 #ifdef DCPOMATIC_USE_OWN_PICKER
399 _directory = new DirPickerCtrl (_panel);
401 _directory = new wxDirPickerCtrl (_panel, wxDD_DIR_MUST_EXIST);
403 table->Add (_directory, 1, wxEXPAND);
405 add_label_to_sizer (table, _panel, _("Default ISDCF name details"), true);
406 _isdcf_metadata_button = new wxButton (_panel, wxID_ANY, _("Edit..."));
407 table->Add (_isdcf_metadata_button);
409 add_label_to_sizer (table, _panel, _("Default container"), true);
410 _container = new wxChoice (_panel, wxID_ANY);
411 table->Add (_container);
413 add_label_to_sizer (table, _panel, _("Default content type"), true);
414 _dcp_content_type = new wxChoice (_panel, wxID_ANY);
415 table->Add (_dcp_content_type);
418 add_label_to_sizer (table, _panel, _("Default JPEG2000 bandwidth"), true);
419 wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL);
420 _j2k_bandwidth = new wxSpinCtrl (_panel);
421 s->Add (_j2k_bandwidth);
422 add_label_to_sizer (s, _panel, _("Mbit/s"), false);
427 add_label_to_sizer (table, _panel, _("Default audio delay"), true);
428 wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL);
429 _audio_delay = new wxSpinCtrl (_panel);
430 s->Add (_audio_delay);
431 add_label_to_sizer (s, _panel, _("ms"), false);
435 add_label_to_sizer (table, _panel, _("Default standard"), true);
436 _standard = new wxChoice (_panel, wxID_ANY);
437 table->Add (_standard);
439 _still_length->SetRange (1, 3600);
440 _still_length->Bind (wxEVT_COMMAND_SPINCTRL_UPDATED, boost::bind (&DefaultsPage::still_length_changed, this));
442 _directory->Bind (wxEVT_COMMAND_DIRPICKER_CHANGED, boost::bind (&DefaultsPage::directory_changed, this));
444 _isdcf_metadata_button->Bind (wxEVT_COMMAND_BUTTON_CLICKED, boost::bind (&DefaultsPage::edit_isdcf_metadata_clicked, this));
446 vector<Ratio const *> ratios = Ratio::all ();
447 for (size_t i = 0; i < ratios.size(); ++i) {
448 _container->Append (std_to_wx (ratios[i]->nickname ()));
451 _container->Bind (wxEVT_COMMAND_CHOICE_SELECTED, boost::bind (&DefaultsPage::container_changed, this));
453 vector<DCPContentType const *> const ct = DCPContentType::all ();
454 for (size_t i = 0; i < ct.size(); ++i) {
455 _dcp_content_type->Append (std_to_wx (ct[i]->pretty_name ()));
458 _dcp_content_type->Bind (wxEVT_COMMAND_CHOICE_SELECTED, boost::bind (&DefaultsPage::dcp_content_type_changed, this));
460 _j2k_bandwidth->SetRange (50, 250);
461 _j2k_bandwidth->Bind (wxEVT_COMMAND_SPINCTRL_UPDATED, boost::bind (&DefaultsPage::j2k_bandwidth_changed, this));
463 _audio_delay->SetRange (-1000, 1000);
464 _audio_delay->Bind (wxEVT_COMMAND_SPINCTRL_UPDATED, boost::bind (&DefaultsPage::audio_delay_changed, this));
466 _standard->Append (_("SMPTE"));
467 _standard->Append (_("Interop"));
468 _standard->Bind (wxEVT_COMMAND_CHOICE_SELECTED, boost::bind (&DefaultsPage::standard_changed, this));
471 void config_changed ()
473 Config* config = Config::instance ();
475 vector<Ratio const *> ratios = Ratio::all ();
476 for (size_t i = 0; i < ratios.size(); ++i) {
477 if (ratios[i] == config->default_container ()) {
478 _container->SetSelection (i);
482 vector<DCPContentType const *> const ct = DCPContentType::all ();
483 for (size_t i = 0; i < ct.size(); ++i) {
484 if (ct[i] == config->default_dcp_content_type ()) {
485 _dcp_content_type->SetSelection (i);
489 checked_set (_still_length, config->default_still_length ());
490 _directory->SetPath (std_to_wx (config->default_directory_or (wx_to_std (wxStandardPaths::Get().GetDocumentsDir())).string ()));
491 checked_set (_j2k_bandwidth, config->default_j2k_bandwidth() / 1000000);
492 _j2k_bandwidth->SetRange (50, config->maximum_j2k_bandwidth() / 1000000);
493 checked_set (_audio_delay, config->default_audio_delay ());
494 checked_set (_standard, config->default_interop() ? 1 : 0);
497 void j2k_bandwidth_changed ()
499 Config::instance()->set_default_j2k_bandwidth (_j2k_bandwidth->GetValue() * 1000000);
502 void audio_delay_changed ()
504 Config::instance()->set_default_audio_delay (_audio_delay->GetValue());
507 void directory_changed ()
509 Config::instance()->set_default_directory (wx_to_std (_directory->GetPath ()));
512 void edit_isdcf_metadata_clicked ()
514 ISDCFMetadataDialog* d = new ISDCFMetadataDialog (_panel, Config::instance()->default_isdcf_metadata (), false);
516 Config::instance()->set_default_isdcf_metadata (d->isdcf_metadata ());
520 void still_length_changed ()
522 Config::instance()->set_default_still_length (_still_length->GetValue ());
525 void container_changed ()
527 vector<Ratio const *> ratio = Ratio::all ();
528 Config::instance()->set_default_container (ratio[_container->GetSelection()]);
531 void dcp_content_type_changed ()
533 vector<DCPContentType const *> ct = DCPContentType::all ();
534 Config::instance()->set_default_dcp_content_type (ct[_dcp_content_type->GetSelection()]);
537 void standard_changed ()
539 Config::instance()->set_default_interop (_standard->GetSelection() == 1);
542 wxSpinCtrl* _j2k_bandwidth;
543 wxSpinCtrl* _audio_delay;
544 wxButton* _isdcf_metadata_button;
545 wxSpinCtrl* _still_length;
546 #ifdef DCPOMATIC_USE_OWN_PICKER
547 DirPickerCtrl* _directory;
549 wxDirPickerCtrl* _directory;
551 wxChoice* _container;
552 wxChoice* _dcp_content_type;
556 class EncodingServersPage : public StandardPage
559 EncodingServersPage (wxSize panel_size, int border)
560 : StandardPage (panel_size, border)
563 wxString GetName () const
569 wxBitmap GetLargeIcon () const
571 return wxBitmap ("servers", wxBITMAP_TYPE_PNG_RESOURCE);
578 _use_any_servers = new wxCheckBox (_panel, wxID_ANY, _("Search network for servers"));
579 _panel->GetSizer()->Add (_use_any_servers, 0, wxALL, _border);
581 vector<string> columns;
582 columns.push_back (wx_to_std (_("IP address / host name")));
583 _servers_list = new EditableList<string, ServerDialog> (
586 boost::bind (&Config::servers, Config::instance()),
587 boost::bind (&Config::set_servers, Config::instance(), _1),
588 boost::bind (&EncodingServersPage::server_column, this, _1)
591 _panel->GetSizer()->Add (_servers_list, 1, wxEXPAND | wxALL, _border);
593 _use_any_servers->Bind (wxEVT_COMMAND_CHECKBOX_CLICKED, boost::bind (&EncodingServersPage::use_any_servers_changed, this));
596 void config_changed ()
598 checked_set (_use_any_servers, Config::instance()->use_any_servers ());
599 _servers_list->refresh ();
602 void use_any_servers_changed ()
604 Config::instance()->set_use_any_servers (_use_any_servers->GetValue ());
607 string server_column (string s)
612 wxCheckBox* _use_any_servers;
613 EditableList<string, ServerDialog>* _servers_list;
616 class CertificateChainEditor : public wxPanel
619 CertificateChainEditor (
623 function<void (shared_ptr<dcp::CertificateChain>)> set,
624 function<shared_ptr<const dcp::CertificateChain> (void)> get
630 wxFont subheading_font (*wxNORMAL_FONT);
631 subheading_font.SetWeight (wxFONTWEIGHT_BOLD);
633 _sizer = new wxBoxSizer (wxVERTICAL);
636 wxStaticText* m = new wxStaticText (this, wxID_ANY, title);
637 m->SetFont (subheading_font);
638 _sizer->Add (m, 0, wxALL, border);
641 wxBoxSizer* certificates_sizer = new wxBoxSizer (wxHORIZONTAL);
642 _sizer->Add (certificates_sizer, 0, wxLEFT | wxRIGHT, border);
644 _certificates = new wxListCtrl (this, wxID_ANY, wxDefaultPosition, wxSize (440, 150), wxLC_REPORT | wxLC_SINGLE_SEL);
649 ip.SetText (_("Type"));
651 _certificates->InsertColumn (0, ip);
657 ip.SetText (_("Thumbprint"));
660 wxFont font = ip.GetFont ();
661 font.SetFamily (wxFONTFAMILY_TELETYPE);
664 _certificates->InsertColumn (1, ip);
667 certificates_sizer->Add (_certificates, 1, wxEXPAND);
670 wxSizer* s = new wxBoxSizer (wxVERTICAL);
671 _add_certificate = new wxButton (this, wxID_ANY, _("Add..."));
672 s->Add (_add_certificate, 0, wxTOP | wxBOTTOM, DCPOMATIC_BUTTON_STACK_GAP);
673 _remove_certificate = new wxButton (this, wxID_ANY, _("Remove"));
674 s->Add (_remove_certificate, 0, wxTOP | wxBOTTOM, DCPOMATIC_BUTTON_STACK_GAP);
675 _export_certificate = new wxButton (this, wxID_ANY, _("Export"));
676 s->Add (_export_certificate, 0, wxTOP | wxBOTTOM, DCPOMATIC_BUTTON_STACK_GAP);
677 certificates_sizer->Add (s, 0, wxLEFT, DCPOMATIC_SIZER_X_GAP);
680 wxGridBagSizer* table = new wxGridBagSizer (DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
681 _sizer->Add (table, 1, wxALL | wxEXPAND, border);
684 add_label_to_sizer (table, this, _("Leaf private key"), true, wxGBPosition (r, 0));
685 _private_key = new wxStaticText (this, wxID_ANY, wxT (""));
686 wxFont font = _private_key->GetFont ();
687 font.SetFamily (wxFONTFAMILY_TELETYPE);
688 _private_key->SetFont (font);
689 table->Add (_private_key, wxGBPosition (r, 1), wxDefaultSpan, wxALIGN_CENTER_VERTICAL);
690 _load_private_key = new wxButton (this, wxID_ANY, _("Load..."));
691 table->Add (_load_private_key, wxGBPosition (r, 2));
692 _export_private_key = new wxButton (this, wxID_ANY, _("Export..."));
693 table->Add (_export_private_key, wxGBPosition (r, 3));
696 _button_sizer = new wxBoxSizer (wxHORIZONTAL);
697 _remake_certificates = new wxButton (this, wxID_ANY, _("Re-make certificates and key..."));
698 _button_sizer->Add (_remake_certificates, 1, wxRIGHT, border);
699 table->Add (_button_sizer, wxGBPosition (r, 0), wxGBSpan (1, 3));
702 _add_certificate->Bind (wxEVT_COMMAND_BUTTON_CLICKED, boost::bind (&CertificateChainEditor::add_certificate, this));
703 _remove_certificate->Bind (wxEVT_COMMAND_BUTTON_CLICKED, boost::bind (&CertificateChainEditor::remove_certificate, this));
704 _export_certificate->Bind (wxEVT_COMMAND_BUTTON_CLICKED, boost::bind (&CertificateChainEditor::export_certificate, this));
705 _certificates->Bind (wxEVT_COMMAND_LIST_ITEM_SELECTED, boost::bind (&CertificateChainEditor::update_sensitivity, this));
706 _certificates->Bind (wxEVT_COMMAND_LIST_ITEM_DESELECTED, boost::bind (&CertificateChainEditor::update_sensitivity, this));
707 _remake_certificates->Bind (wxEVT_COMMAND_BUTTON_CLICKED, boost::bind (&CertificateChainEditor::remake_certificates, this));
708 _load_private_key->Bind (wxEVT_COMMAND_BUTTON_CLICKED, boost::bind (&CertificateChainEditor::load_private_key, this));
709 _export_private_key->Bind (wxEVT_COMMAND_BUTTON_CLICKED, boost::bind (&CertificateChainEditor::export_private_key, this));
711 SetSizerAndFit (_sizer);
714 void config_changed ()
716 _chain.reset (new dcp::CertificateChain (*_get().get ()));
718 update_certificate_list ();
719 update_private_key ();
720 update_sensitivity ();
723 void add_button (wxWindow* button)
725 _button_sizer->Add (button);
730 void add_certificate ()
732 wxFileDialog* d = new wxFileDialog (this, _("Select Certificate File"));
734 if (d->ShowModal() == wxID_OK) {
736 dcp::Certificate c (dcp::file_to_string (wx_to_std (d->GetPath ())));
739 update_certificate_list ();
740 } catch (dcp::MiscError& e) {
741 error_dialog (this, wxString::Format (_("Could not read certificate file (%s)"), e.what ()));
747 update_sensitivity ();
750 void remove_certificate ()
752 int i = _certificates->GetNextItem (-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
757 _certificates->DeleteItem (i);
761 update_sensitivity ();
764 void export_certificate ()
766 int i = _certificates->GetNextItem (-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
771 wxFileDialog* d = new wxFileDialog (
772 this, _("Select Certificate File"), wxEmptyString, wxEmptyString, wxT ("PEM files (*.pem)|*.pem"),
773 wxFD_SAVE | wxFD_OVERWRITE_PROMPT
776 dcp::CertificateChain::List all = _chain->root_to_leaf ();
777 dcp::CertificateChain::List::iterator j = all.begin ();
778 for (int k = 0; k < i; ++k) {
782 if (d->ShowModal () == wxID_OK) {
783 FILE* f = fopen_boost (wx_to_std (d->GetPath ()), "w");
785 throw OpenFileError (wx_to_std (d->GetPath ()));
788 string const s = j->certificate (true);
789 fwrite (s.c_str(), 1, s.length(), f);
795 void update_certificate_list ()
797 _certificates->DeleteAllItems ();
799 dcp::CertificateChain::List certs = _chain->root_to_leaf ();
800 BOOST_FOREACH (dcp::Certificate const & i, certs) {
803 _certificates->InsertItem (item);
804 _certificates->SetItem (n, 1, std_to_wx (i.thumbprint ()));
807 _certificates->SetItem (n, 0, _("Root"));
808 } else if (n == (certs.size() - 1)) {
809 _certificates->SetItem (n, 0, _("Leaf"));
811 _certificates->SetItem (n, 0, _("Intermediate"));
818 void remake_certificates ()
820 shared_ptr<const dcp::CertificateChain> chain = _get ();
822 string subject_organization_name;
823 string subject_organizational_unit_name;
824 string root_common_name;
825 string intermediate_common_name;
826 string leaf_common_name;
828 dcp::CertificateChain::List all = chain->root_to_leaf ();
830 if (all.size() >= 1) {
832 subject_organization_name = chain->root().subject_organization_name ();
833 subject_organizational_unit_name = chain->root().subject_organizational_unit_name ();
834 root_common_name = chain->root().subject_common_name ();
837 if (all.size() >= 2) {
839 leaf_common_name = chain->leaf().subject_common_name ();
842 if (all.size() >= 3) {
843 /* Have an intermediate */
844 dcp::CertificateChain::List::iterator i = all.begin ();
846 intermediate_common_name = i->subject_common_name ();
849 MakeChainDialog* d = new MakeChainDialog (
851 subject_organization_name,
852 subject_organizational_unit_name,
854 intermediate_common_name,
858 if (d->ShowModal () == wxID_OK) {
860 new dcp::CertificateChain (
863 d->organisational_unit (),
864 d->root_common_name (),
865 d->intermediate_common_name (),
866 d->leaf_common_name ()
871 update_certificate_list ();
872 update_private_key ();
878 void update_sensitivity ()
880 _remove_certificate->Enable (_certificates->GetNextItem (-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED) != -1);
881 _export_certificate->Enable (_certificates->GetNextItem (-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED) != -1);
884 void update_private_key ()
886 checked_set (_private_key, dcp::private_key_fingerprint (_chain->key().get ()));
890 void load_private_key ()
892 wxFileDialog* d = new wxFileDialog (this, _("Select Key File"));
894 if (d->ShowModal() == wxID_OK) {
896 boost::filesystem::path p (wx_to_std (d->GetPath ()));
897 if (boost::filesystem::file_size (p) > 1024) {
898 error_dialog (this, wxString::Format (_("Could not read key file (%s)"), std_to_wx (p.string ())));
902 _chain->set_key (dcp::file_to_string (p));
904 update_private_key ();
905 } catch (dcp::MiscError& e) {
906 error_dialog (this, wxString::Format (_("Could not read certificate file (%s)"), e.what ()));
912 update_sensitivity ();
915 void export_private_key ()
917 optional<string> key = _chain->key ();
922 wxFileDialog* d = new wxFileDialog (
923 this, _("Select Key File"), wxEmptyString, wxEmptyString, wxT ("PEM files (*.pem)|*.pem"),
924 wxFD_SAVE | wxFD_OVERWRITE_PROMPT
927 if (d->ShowModal () == wxID_OK) {
928 FILE* f = fopen_boost (wx_to_std (d->GetPath ()), "w");
930 throw OpenFileError (wx_to_std (d->GetPath ()));
933 string const s = _chain->key().get ();
934 fwrite (s.c_str(), 1, s.length(), f);
940 wxListCtrl* _certificates;
941 wxButton* _add_certificate;
942 wxButton* _export_certificate;
943 wxButton* _remove_certificate;
944 wxButton* _remake_certificates;
945 wxStaticText* _private_key;
946 wxButton* _load_private_key;
947 wxButton* _export_private_key;
949 wxBoxSizer* _button_sizer;
950 shared_ptr<dcp::CertificateChain> _chain;
951 boost::function<void (shared_ptr<dcp::CertificateChain>)> _set;
952 boost::function<shared_ptr<const dcp::CertificateChain> (void)> _get;
955 class KeysPage : public StandardPage
958 KeysPage (wxSize panel_size, int border)
959 : StandardPage (panel_size, border)
962 wxString GetName () const
968 wxBitmap GetLargeIcon () const
970 return wxBitmap ("keys", wxBITMAP_TYPE_PNG_RESOURCE);
978 _signer = new CertificateChainEditor (
979 _panel, _("Signing DCPs and KDMs"), _border,
980 boost::bind (&Config::set_signer_chain, Config::instance (), _1),
981 boost::bind (&Config::signer_chain, Config::instance ())
984 _panel->GetSizer()->Add (_signer);
986 _decryption = new CertificateChainEditor (
987 _panel, _("Decrypting DCPs"), _border,
988 boost::bind (&Config::set_decryption_chain, Config::instance (), _1),
989 boost::bind (&Config::decryption_chain, Config::instance ())
992 _panel->GetSizer()->Add (_decryption);
994 _export_decryption_certificate = new wxButton (_decryption, wxID_ANY, _("Export DCP decryption certificate..."));
995 _decryption->add_button (_export_decryption_certificate);
997 _export_decryption_certificate->Bind (wxEVT_COMMAND_BUTTON_CLICKED, boost::bind (&KeysPage::export_decryption_certificate, this));
1000 void export_decryption_certificate ()
1002 wxFileDialog* d = new wxFileDialog (
1003 _panel, _("Select Certificate File"), wxEmptyString, wxEmptyString, wxT ("PEM files (*.pem)|*.pem"),
1004 wxFD_SAVE | wxFD_OVERWRITE_PROMPT
1007 if (d->ShowModal () == wxID_OK) {
1008 FILE* f = fopen_boost (wx_to_std (d->GetPath ()), "w");
1010 throw OpenFileError (wx_to_std (d->GetPath ()));
1013 string const s = Config::instance()->decryption_chain()->leaf().certificate (true);
1014 fwrite (s.c_str(), 1, s.length(), f);
1020 void config_changed ()
1022 _signer->config_changed ();
1023 _decryption->config_changed ();
1026 CertificateChainEditor* _signer;
1027 CertificateChainEditor* _decryption;
1028 wxButton* _export_decryption_certificate;
1031 class TMSPage : public StandardPage
1034 TMSPage (wxSize panel_size, int border)
1035 : StandardPage (panel_size, border)
1038 wxString GetName () const
1043 #ifdef DCPOMATIC_OSX
1044 wxBitmap GetLargeIcon () const
1046 return wxBitmap ("tms", wxBITMAP_TYPE_PNG_RESOURCE);
1053 wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
1054 table->AddGrowableCol (1, 1);
1055 _panel->GetSizer()->Add (table, 1, wxALL | wxEXPAND, _border);
1057 add_label_to_sizer (table, _panel, _("Protocol"), true);
1058 _tms_protocol = new wxChoice (_panel, wxID_ANY);
1059 table->Add (_tms_protocol, 1, wxEXPAND);
1061 add_label_to_sizer (table, _panel, _("IP address"), true);
1062 _tms_ip = new wxTextCtrl (_panel, wxID_ANY);
1063 table->Add (_tms_ip, 1, wxEXPAND);
1065 add_label_to_sizer (table, _panel, _("Target path"), true);
1066 _tms_path = new wxTextCtrl (_panel, wxID_ANY);
1067 table->Add (_tms_path, 1, wxEXPAND);
1069 add_label_to_sizer (table, _panel, _("User name"), true);
1070 _tms_user = new wxTextCtrl (_panel, wxID_ANY);
1071 table->Add (_tms_user, 1, wxEXPAND);
1073 add_label_to_sizer (table, _panel, _("Password"), true);
1074 _tms_password = new wxTextCtrl (_panel, wxID_ANY);
1075 table->Add (_tms_password, 1, wxEXPAND);
1077 _tms_protocol->Append (_("SCP (for AAM and Doremi)"));
1078 _tms_protocol->Append (_("FTP (for Dolby)"));
1080 _tms_protocol->Bind (wxEVT_COMMAND_CHOICE_SELECTED, boost::bind (&TMSPage::tms_protocol_changed, this));
1081 _tms_ip->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&TMSPage::tms_ip_changed, this));
1082 _tms_path->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&TMSPage::tms_path_changed, this));
1083 _tms_user->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&TMSPage::tms_user_changed, this));
1084 _tms_password->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&TMSPage::tms_password_changed, this));
1087 void config_changed ()
1089 Config* config = Config::instance ();
1091 checked_set (_tms_protocol, config->tms_protocol ());
1092 checked_set (_tms_ip, config->tms_ip ());
1093 checked_set (_tms_path, config->tms_path ());
1094 checked_set (_tms_user, config->tms_user ());
1095 checked_set (_tms_password, config->tms_password ());
1098 void tms_protocol_changed ()
1100 Config::instance()->set_tms_protocol (static_cast<Protocol> (_tms_protocol->GetSelection ()));
1103 void tms_ip_changed ()
1105 Config::instance()->set_tms_ip (wx_to_std (_tms_ip->GetValue ()));
1108 void tms_path_changed ()
1110 Config::instance()->set_tms_path (wx_to_std (_tms_path->GetValue ()));
1113 void tms_user_changed ()
1115 Config::instance()->set_tms_user (wx_to_std (_tms_user->GetValue ()));
1118 void tms_password_changed ()
1120 Config::instance()->set_tms_password (wx_to_std (_tms_password->GetValue ()));
1123 wxChoice* _tms_protocol;
1124 wxTextCtrl* _tms_ip;
1125 wxTextCtrl* _tms_path;
1126 wxTextCtrl* _tms_user;
1127 wxTextCtrl* _tms_password;
1130 class KDMEmailPage : public StandardPage
1134 KDMEmailPage (wxSize panel_size, int border)
1135 #ifdef DCPOMATIC_OSX
1136 /* We have to force both width and height of this one */
1137 : StandardPage (wxSize (480, 128), border)
1139 : StandardPage (panel_size, border)
1143 wxString GetName () const
1145 return _("KDM Email");
1148 #ifdef DCPOMATIC_OSX
1149 wxBitmap GetLargeIcon () const
1151 return wxBitmap ("kdm_email", wxBITMAP_TYPE_PNG_RESOURCE);
1158 wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
1159 table->AddGrowableCol (1, 1);
1160 _panel->GetSizer()->Add (table, 1, wxEXPAND | wxALL, _border);
1162 add_label_to_sizer (table, _panel, _("Outgoing mail server"), true);
1164 wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL);
1165 _mail_server = new wxTextCtrl (_panel, wxID_ANY);
1166 s->Add (_mail_server, 1, wxEXPAND | wxALL);
1167 add_label_to_sizer (s, _panel, _("port"), false);
1168 _mail_port = new wxSpinCtrl (_panel, wxID_ANY);
1169 _mail_port->SetRange (0, 65535);
1170 s->Add (_mail_port);
1171 table->Add (s, 1, wxEXPAND | wxALL);
1174 add_label_to_sizer (table, _panel, _("Mail user name"), true);
1175 _mail_user = new wxTextCtrl (_panel, wxID_ANY);
1176 table->Add (_mail_user, 1, wxEXPAND | wxALL);
1178 add_label_to_sizer (table, _panel, _("Mail password"), true);
1179 _mail_password = new wxTextCtrl (_panel, wxID_ANY);
1180 table->Add (_mail_password, 1, wxEXPAND | wxALL);
1182 add_label_to_sizer (table, _panel, _("Subject"), true);
1183 _kdm_subject = new wxTextCtrl (_panel, wxID_ANY);
1184 table->Add (_kdm_subject, 1, wxEXPAND | wxALL);
1186 add_label_to_sizer (table, _panel, _("From address"), true);
1187 _kdm_from = new wxTextCtrl (_panel, wxID_ANY);
1188 table->Add (_kdm_from, 1, wxEXPAND | wxALL);
1190 add_label_to_sizer (table, _panel, _("CC address"), true);
1191 _kdm_cc = new wxTextCtrl (_panel, wxID_ANY);
1192 table->Add (_kdm_cc, 1, wxEXPAND | wxALL);
1194 add_label_to_sizer (table, _panel, _("BCC address"), true);
1195 _kdm_bcc = new wxTextCtrl (_panel, wxID_ANY);
1196 table->Add (_kdm_bcc, 1, wxEXPAND | wxALL);
1198 _kdm_email = new wxTextCtrl (_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize (480, 128), wxTE_MULTILINE);
1199 _panel->GetSizer()->Add (_kdm_email, 1, wxEXPAND | wxALL, _border);
1201 _reset_kdm_email = new wxButton (_panel, wxID_ANY, _("Reset to default subject and text"));
1202 _panel->GetSizer()->Add (_reset_kdm_email, 0, wxEXPAND | wxALL, _border);
1204 _mail_server->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&KDMEmailPage::mail_server_changed, this));
1205 _mail_port->Bind (wxEVT_COMMAND_SPINCTRL_UPDATED, boost::bind (&KDMEmailPage::mail_port_changed, this));
1206 _mail_user->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&KDMEmailPage::mail_user_changed, this));
1207 _mail_password->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&KDMEmailPage::mail_password_changed, this));
1208 _kdm_subject->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&KDMEmailPage::kdm_subject_changed, this));
1209 _kdm_from->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&KDMEmailPage::kdm_from_changed, this));
1210 _kdm_cc->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&KDMEmailPage::kdm_cc_changed, this));
1211 _kdm_bcc->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&KDMEmailPage::kdm_bcc_changed, this));
1212 _kdm_email->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&KDMEmailPage::kdm_email_changed, this));
1213 _reset_kdm_email->Bind (wxEVT_COMMAND_BUTTON_CLICKED, boost::bind (&KDMEmailPage::reset_kdm_email, this));
1216 void config_changed ()
1218 Config* config = Config::instance ();
1220 checked_set (_mail_server, config->mail_server ());
1221 checked_set (_mail_port, config->mail_port ());
1222 checked_set (_mail_user, config->mail_user ());
1223 checked_set (_mail_password, config->mail_password ());
1224 checked_set (_kdm_subject, config->kdm_subject ());
1225 checked_set (_kdm_from, config->kdm_from ());
1226 checked_set (_kdm_cc, config->kdm_cc ());
1227 checked_set (_kdm_bcc, config->kdm_bcc ());
1228 checked_set (_kdm_email, Config::instance()->kdm_email ());
1231 void mail_server_changed ()
1233 Config::instance()->set_mail_server (wx_to_std (_mail_server->GetValue ()));
1236 void mail_port_changed ()
1238 Config::instance()->set_mail_port (_mail_port->GetValue ());
1241 void mail_user_changed ()
1243 Config::instance()->set_mail_user (wx_to_std (_mail_user->GetValue ()));
1246 void mail_password_changed ()
1248 Config::instance()->set_mail_password (wx_to_std (_mail_password->GetValue ()));
1251 void kdm_subject_changed ()
1253 Config::instance()->set_kdm_subject (wx_to_std (_kdm_subject->GetValue ()));
1256 void kdm_from_changed ()
1258 Config::instance()->set_kdm_from (wx_to_std (_kdm_from->GetValue ()));
1261 void kdm_cc_changed ()
1263 Config::instance()->set_kdm_cc (wx_to_std (_kdm_cc->GetValue ()));
1266 void kdm_bcc_changed ()
1268 Config::instance()->set_kdm_bcc (wx_to_std (_kdm_bcc->GetValue ()));
1271 void kdm_email_changed ()
1273 if (_kdm_email->GetValue().IsEmpty ()) {
1274 /* Sometimes we get sent an erroneous notification that the email
1275 is empty; I don't know why.
1279 Config::instance()->set_kdm_email (wx_to_std (_kdm_email->GetValue ()));
1282 void reset_kdm_email ()
1284 Config::instance()->reset_kdm_email ();
1285 checked_set (_kdm_email, Config::instance()->kdm_email ());
1288 wxTextCtrl* _mail_server;
1289 wxSpinCtrl* _mail_port;
1290 wxTextCtrl* _mail_user;
1291 wxTextCtrl* _mail_password;
1292 wxTextCtrl* _kdm_subject;
1293 wxTextCtrl* _kdm_from;
1294 wxTextCtrl* _kdm_cc;
1295 wxTextCtrl* _kdm_bcc;
1296 wxTextCtrl* _kdm_email;
1297 wxButton* _reset_kdm_email;
1300 /** @class AdvancedPage
1301 * @brief Advanced page of the preferences dialog.
1303 class AdvancedPage : public StockPage
1306 AdvancedPage (wxSize panel_size, int border)
1307 : StockPage (Kind_Advanced, panel_size, border)
1308 , _maximum_j2k_bandwidth (0)
1309 , _allow_any_dcp_frame_rate (0)
1310 , _only_servers_encode (0)
1315 , _log_debug_decode (0)
1316 , _log_debug_encode (0)
1317 , _log_debug_email (0)
1323 wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
1324 table->AddGrowableCol (1, 1);
1325 _panel->GetSizer()->Add (table, 1, wxALL | wxEXPAND, _border);
1328 add_label_to_sizer (table, _panel, _("Maximum JPEG2000 bandwidth"), true);
1329 wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL);
1330 _maximum_j2k_bandwidth = new wxSpinCtrl (_panel);
1331 s->Add (_maximum_j2k_bandwidth, 1);
1332 add_label_to_sizer (s, _panel, _("Mbit/s"), false);
1336 _allow_any_dcp_frame_rate = new wxCheckBox (_panel, wxID_ANY, _("Allow any DCP frame rate"));
1337 table->Add (_allow_any_dcp_frame_rate, 1, wxEXPAND | wxALL);
1338 table->AddSpacer (0);
1340 _only_servers_encode = new wxCheckBox (_panel, wxID_ANY, _("Only servers encode"));
1341 table->Add (_only_servers_encode, 1, wxEXPAND | wxALL);
1342 table->AddSpacer (0);
1345 wxStaticText* m = new wxStaticText (_panel, wxID_ANY, _("Log:"));
1346 table->Add (m, 0, wxALIGN_TOP | wxLEFT | wxRIGHT | wxEXPAND | wxALL | wxALIGN_RIGHT, 6);
1348 wxStaticText* m = new wxStaticText (_panel, wxID_ANY, _("Log"));
1349 table->Add (m, 0, wxALIGN_TOP | wxLEFT | wxRIGHT | wxEXPAND | wxALL, 6);
1353 wxBoxSizer* t = new wxBoxSizer (wxVERTICAL);
1354 _log_general = new wxCheckBox (_panel, wxID_ANY, _("General"));
1355 t->Add (_log_general, 1, wxEXPAND | wxALL);
1356 _log_warning = new wxCheckBox (_panel, wxID_ANY, _("Warnings"));
1357 t->Add (_log_warning, 1, wxEXPAND | wxALL);
1358 _log_error = new wxCheckBox (_panel, wxID_ANY, _("Errors"));
1359 t->Add (_log_error, 1, wxEXPAND | wxALL);
1360 _log_timing = new wxCheckBox (_panel, wxID_ANY, S_("Config|Timing"));
1361 t->Add (_log_timing, 1, wxEXPAND | wxALL);
1362 _log_debug_decode = new wxCheckBox (_panel, wxID_ANY, _("Debug: decode"));
1363 t->Add (_log_debug_decode, 1, wxEXPAND | wxALL);
1364 _log_debug_encode = new wxCheckBox (_panel, wxID_ANY, _("Debug: encode"));
1365 t->Add (_log_debug_encode, 1, wxEXPAND | wxALL);
1366 _log_debug_email = new wxCheckBox (_panel, wxID_ANY, _("Debug: email sending"));
1367 t->Add (_log_debug_email, 1, wxEXPAND | wxALL);
1368 table->Add (t, 0, wxALL, 6);
1371 #ifdef DCPOMATIC_WINDOWS
1372 _win32_console = new wxCheckBox (_panel, wxID_ANY, _("Open console window"));
1373 table->Add (_win32_console, 1, wxEXPAND | wxALL);
1374 table->AddSpacer (0);
1377 _maximum_j2k_bandwidth->SetRange (1, 1000);
1378 _maximum_j2k_bandwidth->Bind (wxEVT_COMMAND_SPINCTRL_UPDATED, boost::bind (&AdvancedPage::maximum_j2k_bandwidth_changed, this));
1379 _allow_any_dcp_frame_rate->Bind (wxEVT_COMMAND_CHECKBOX_CLICKED, boost::bind (&AdvancedPage::allow_any_dcp_frame_rate_changed, this));
1380 _only_servers_encode->Bind (wxEVT_COMMAND_CHECKBOX_CLICKED, boost::bind (&AdvancedPage::only_servers_encode_changed, this));
1381 _log_general->Bind (wxEVT_COMMAND_CHECKBOX_CLICKED, boost::bind (&AdvancedPage::log_changed, this));
1382 _log_warning->Bind (wxEVT_COMMAND_CHECKBOX_CLICKED, boost::bind (&AdvancedPage::log_changed, this));
1383 _log_error->Bind (wxEVT_COMMAND_CHECKBOX_CLICKED, boost::bind (&AdvancedPage::log_changed, this));
1384 _log_timing->Bind (wxEVT_COMMAND_CHECKBOX_CLICKED, boost::bind (&AdvancedPage::log_changed, this));
1385 _log_debug_decode->Bind (wxEVT_COMMAND_CHECKBOX_CLICKED, boost::bind (&AdvancedPage::log_changed, this));
1386 _log_debug_encode->Bind (wxEVT_COMMAND_CHECKBOX_CLICKED, boost::bind (&AdvancedPage::log_changed, this));
1387 _log_debug_email->Bind (wxEVT_COMMAND_CHECKBOX_CLICKED, boost::bind (&AdvancedPage::log_changed, this));
1388 #ifdef DCPOMATIC_WINDOWS
1389 _win32_console->Bind (wxEVT_COMMAND_CHECKBOX_CLICKED, boost::bind (&AdvancedPage::win32_console_changed, this));
1393 void config_changed ()
1395 Config* config = Config::instance ();
1397 checked_set (_maximum_j2k_bandwidth, config->maximum_j2k_bandwidth() / 1000000);
1398 checked_set (_allow_any_dcp_frame_rate, config->allow_any_dcp_frame_rate ());
1399 checked_set (_only_servers_encode, config->only_servers_encode ());
1400 checked_set (_log_general, config->log_types() & LogEntry::TYPE_GENERAL);
1401 checked_set (_log_warning, config->log_types() & LogEntry::TYPE_WARNING);
1402 checked_set (_log_error, config->log_types() & LogEntry::TYPE_ERROR);
1403 checked_set (_log_timing, config->log_types() & LogEntry::TYPE_TIMING);
1404 checked_set (_log_debug_decode, config->log_types() & LogEntry::TYPE_DEBUG_DECODE);
1405 checked_set (_log_debug_encode, config->log_types() & LogEntry::TYPE_DEBUG_ENCODE);
1406 checked_set (_log_debug_email, config->log_types() & LogEntry::TYPE_DEBUG_EMAIL);
1407 #ifdef DCPOMATIC_WINDOWS
1408 checked_set (_win32_console, config->win32_console());
1412 void maximum_j2k_bandwidth_changed ()
1414 Config::instance()->set_maximum_j2k_bandwidth (_maximum_j2k_bandwidth->GetValue() * 1000000);
1417 void allow_any_dcp_frame_rate_changed ()
1419 Config::instance()->set_allow_any_dcp_frame_rate (_allow_any_dcp_frame_rate->GetValue ());
1422 void only_servers_encode_changed ()
1424 Config::instance()->set_only_servers_encode (_only_servers_encode->GetValue ());
1430 if (_log_general->GetValue ()) {
1431 types |= LogEntry::TYPE_GENERAL;
1433 if (_log_warning->GetValue ()) {
1434 types |= LogEntry::TYPE_WARNING;
1436 if (_log_error->GetValue ()) {
1437 types |= LogEntry::TYPE_ERROR;
1439 if (_log_timing->GetValue ()) {
1440 types |= LogEntry::TYPE_TIMING;
1442 if (_log_debug_decode->GetValue ()) {
1443 types |= LogEntry::TYPE_DEBUG_DECODE;
1445 if (_log_debug_encode->GetValue ()) {
1446 types |= LogEntry::TYPE_DEBUG_ENCODE;
1448 if (_log_debug_email->GetValue ()) {
1449 types |= LogEntry::TYPE_DEBUG_EMAIL;
1451 Config::instance()->set_log_types (types);
1454 #ifdef DCPOMATIC_WINDOWS
1455 void win32_console_changed ()
1457 Config::instance()->set_win32_console (_win32_console->GetValue ());
1461 wxSpinCtrl* _maximum_j2k_bandwidth;
1462 wxCheckBox* _allow_any_dcp_frame_rate;
1463 wxCheckBox* _only_servers_encode;
1464 wxCheckBox* _log_general;
1465 wxCheckBox* _log_warning;
1466 wxCheckBox* _log_error;
1467 wxCheckBox* _log_timing;
1468 wxCheckBox* _log_debug_decode;
1469 wxCheckBox* _log_debug_encode;
1470 wxCheckBox* _log_debug_email;
1471 #ifdef DCPOMATIC_WINDOWS
1472 wxCheckBox* _win32_console;
1476 wxPreferencesEditor*
1477 create_config_dialog ()
1479 wxPreferencesEditor* e = new wxPreferencesEditor ();
1481 #ifdef DCPOMATIC_OSX
1482 /* Width that we force some of the config panels to be on OSX so that
1483 the containing window doesn't shrink too much when we select those panels.
1484 This is obviously an unpleasant hack.
1486 wxSize ps = wxSize (520, -1);
1487 int const border = 16;
1489 wxSize ps = wxSize (-1, -1);
1490 int const border = 8;
1493 e->AddPage (new GeneralPage (ps, border));
1494 e->AddPage (new DefaultsPage (ps, border));
1495 e->AddPage (new EncodingServersPage (ps, border));
1496 e->AddPage (new KeysPage (ps, border));
1497 e->AddPage (new TMSPage (ps, border));
1498 e->AddPage (new KDMEmailPage (ps, border));
1499 e->AddPage (new AdvancedPage (ps, border));