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 table->Add (_language, wxGBPosition (r, 1));
173 wxStaticText* restart = add_label_to_grid_bag_sizer (
174 table, _panel, _("(restart DCP-o-matic to see language changes)"), false, wxGBPosition (r, 0), wxGBSpan (1, 2)
176 wxFont font = restart->GetFont();
177 font.SetStyle (wxFONTSTYLE_ITALIC);
178 font.SetPointSize (font.GetPointSize() - 1);
179 restart->SetFont (font);
182 add_label_to_grid_bag_sizer (table, _panel, _("Threads to use for encoding on this host"), true, wxGBPosition (r, 0));
183 _num_local_encoding_threads = new wxSpinCtrl (_panel);
184 table->Add (_num_local_encoding_threads, wxGBPosition (r, 1));
187 _automatic_audio_analysis = new wxCheckBox (_panel, wxID_ANY, _("Automatically analyse content audio"));
188 table->Add (_automatic_audio_analysis, wxGBPosition (r, 0), wxGBSpan (1, 2));
191 _check_for_updates = new wxCheckBox (_panel, wxID_ANY, _("Check for updates on startup"));
192 table->Add (_check_for_updates, wxGBPosition (r, 0), wxGBSpan (1, 2));
195 _check_for_test_updates = new wxCheckBox (_panel, wxID_ANY, _("Check for testing updates as well as stable ones"));
196 table->Add (_check_for_test_updates, wxGBPosition (r, 0), wxGBSpan (1, 2));
199 wxFlexGridSizer* bottom_table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
200 bottom_table->AddGrowableCol (1, 1);
202 add_label_to_sizer (bottom_table, _panel, _("Issuer"), true);
203 _issuer = new wxTextCtrl (_panel, wxID_ANY);
204 bottom_table->Add (_issuer, 1, wxALL | wxEXPAND);
206 add_label_to_sizer (bottom_table, _panel, _("Creator"), true);
207 _creator = new wxTextCtrl (_panel, wxID_ANY);
208 bottom_table->Add (_creator, 1, wxALL | wxEXPAND);
210 table->Add (bottom_table, wxGBPosition (r, 0), wxGBSpan (2, 2), wxEXPAND);
213 _set_language->Bind (wxEVT_COMMAND_CHECKBOX_CLICKED, boost::bind (&GeneralPage::set_language_changed, this));
214 _language->Bind (wxEVT_COMMAND_CHOICE_SELECTED, boost::bind (&GeneralPage::language_changed, this));
216 _num_local_encoding_threads->SetRange (1, 128);
217 _num_local_encoding_threads->Bind (wxEVT_COMMAND_SPINCTRL_UPDATED, boost::bind (&GeneralPage::num_local_encoding_threads_changed, this));
219 _automatic_audio_analysis->Bind (wxEVT_COMMAND_CHECKBOX_CLICKED, boost::bind (&GeneralPage::automatic_audio_analysis_changed, this));
220 _check_for_updates->Bind (wxEVT_COMMAND_CHECKBOX_CLICKED, boost::bind (&GeneralPage::check_for_updates_changed, this));
221 _check_for_test_updates->Bind (wxEVT_COMMAND_CHECKBOX_CLICKED, boost::bind (&GeneralPage::check_for_test_updates_changed, this));
223 _issuer->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&GeneralPage::issuer_changed, this));
224 _creator->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&GeneralPage::creator_changed, this));
227 void config_changed ()
229 Config* config = Config::instance ();
231 checked_set (_set_language, static_cast<bool>(config->language()));
233 if (config->language().get_value_or ("") == "fr") {
234 checked_set (_language, 3);
235 } else if (config->language().get_value_or ("") == "it") {
236 checked_set (_language, 4);
237 } else if (config->language().get_value_or ("") == "es") {
238 checked_set (_language, 2);
239 } else if (config->language().get_value_or ("") == "sv") {
240 checked_set (_language, 6);
241 } else if (config->language().get_value_or ("") == "de") {
242 checked_set (_language, 0);
243 } else if (config->language().get_value_or ("") == "nl") {
244 checked_set (_language, 5);
245 } else if (config->language().get_value_or ("") == "ru") {
246 checked_set (_language, 7);
247 } else if (config->language().get_value_or ("") == "pl") {
248 checked_set (_language, 8);
249 } else if (config->language().get_value_or ("") == "da") {
250 checked_set (_language, 9);
252 _language->SetSelection (1);
255 setup_language_sensitivity ();
257 checked_set (_num_local_encoding_threads, config->num_local_encoding_threads ());
258 checked_set (_automatic_audio_analysis, config->automatic_audio_analysis ());
259 checked_set (_check_for_updates, config->check_for_updates ());
260 checked_set (_check_for_test_updates, config->check_for_test_updates ());
261 checked_set (_issuer, config->dcp_issuer ());
262 checked_set (_creator, config->dcp_creator ());
265 void setup_language_sensitivity ()
267 _language->Enable (_set_language->GetValue ());
270 void set_language_changed ()
272 setup_language_sensitivity ();
273 if (_set_language->GetValue ()) {
276 Config::instance()->unset_language ();
280 void language_changed ()
282 switch (_language->GetSelection ()) {
284 Config::instance()->set_language ("de");
287 Config::instance()->set_language ("en");
290 Config::instance()->set_language ("es");
293 Config::instance()->set_language ("fr");
296 Config::instance()->set_language ("it");
299 Config::instance()->set_language ("nl");
302 Config::instance()->set_language ("sv");
305 Config::instance()->set_language ("ru");
308 Config::instance()->set_language ("pl");
311 Config::instance()->set_language ("da");
316 void automatic_audio_analysis_changed ()
318 Config::instance()->set_automatic_audio_analysis (_automatic_audio_analysis->GetValue ());
321 void check_for_updates_changed ()
323 Config::instance()->set_check_for_updates (_check_for_updates->GetValue ());
326 void check_for_test_updates_changed ()
328 Config::instance()->set_check_for_test_updates (_check_for_test_updates->GetValue ());
331 void num_local_encoding_threads_changed ()
333 Config::instance()->set_num_local_encoding_threads (_num_local_encoding_threads->GetValue ());
336 void issuer_changed ()
338 Config::instance()->set_dcp_issuer (wx_to_std (_issuer->GetValue ()));
341 void creator_changed ()
343 Config::instance()->set_dcp_creator (wx_to_std (_creator->GetValue ()));
346 wxCheckBox* _set_language;
348 wxSpinCtrl* _num_local_encoding_threads;
349 wxCheckBox* _automatic_audio_analysis;
350 wxCheckBox* _check_for_updates;
351 wxCheckBox* _check_for_test_updates;
353 wxTextCtrl* _creator;
356 class DefaultsPage : public StandardPage
359 DefaultsPage (wxSize panel_size, int border)
360 : StandardPage (panel_size, border)
363 wxString GetName () const
365 return _("Defaults");
369 wxBitmap GetLargeIcon () const
371 return wxBitmap ("defaults", wxBITMAP_TYPE_PNG_RESOURCE);
378 wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
379 table->AddGrowableCol (1, 1);
380 _panel->GetSizer()->Add (table, 1, wxALL | wxEXPAND, _border);
383 add_label_to_sizer (table, _panel, _("Default duration of still images"), true);
384 wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL);
385 _still_length = new wxSpinCtrl (_panel);
386 s->Add (_still_length);
387 add_label_to_sizer (s, _panel, _("s"), false);
391 add_label_to_sizer (table, _panel, _("Default directory for new films"), true);
392 #ifdef DCPOMATIC_USE_OWN_PICKER
393 _directory = new DirPickerCtrl (_panel);
395 _directory = new wxDirPickerCtrl (_panel, wxDD_DIR_MUST_EXIST);
397 table->Add (_directory, 1, wxEXPAND);
399 add_label_to_sizer (table, _panel, _("Default ISDCF name details"), true);
400 _isdcf_metadata_button = new wxButton (_panel, wxID_ANY, _("Edit..."));
401 table->Add (_isdcf_metadata_button);
403 add_label_to_sizer (table, _panel, _("Default container"), true);
404 _container = new wxChoice (_panel, wxID_ANY);
405 table->Add (_container);
407 add_label_to_sizer (table, _panel, _("Default content type"), true);
408 _dcp_content_type = new wxChoice (_panel, wxID_ANY);
409 table->Add (_dcp_content_type);
412 add_label_to_sizer (table, _panel, _("Default JPEG2000 bandwidth"), true);
413 wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL);
414 _j2k_bandwidth = new wxSpinCtrl (_panel);
415 s->Add (_j2k_bandwidth);
416 add_label_to_sizer (s, _panel, _("Mbit/s"), false);
421 add_label_to_sizer (table, _panel, _("Default audio delay"), true);
422 wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL);
423 _audio_delay = new wxSpinCtrl (_panel);
424 s->Add (_audio_delay);
425 add_label_to_sizer (s, _panel, _("ms"), false);
429 add_label_to_sizer (table, _panel, _("Default standard"), true);
430 _standard = new wxChoice (_panel, wxID_ANY);
431 table->Add (_standard);
433 _still_length->SetRange (1, 3600);
434 _still_length->Bind (wxEVT_COMMAND_SPINCTRL_UPDATED, boost::bind (&DefaultsPage::still_length_changed, this));
436 _directory->Bind (wxEVT_COMMAND_DIRPICKER_CHANGED, boost::bind (&DefaultsPage::directory_changed, this));
438 _isdcf_metadata_button->Bind (wxEVT_COMMAND_BUTTON_CLICKED, boost::bind (&DefaultsPage::edit_isdcf_metadata_clicked, this));
440 vector<Ratio const *> ratios = Ratio::all ();
441 for (size_t i = 0; i < ratios.size(); ++i) {
442 _container->Append (std_to_wx (ratios[i]->nickname ()));
445 _container->Bind (wxEVT_COMMAND_CHOICE_SELECTED, boost::bind (&DefaultsPage::container_changed, this));
447 vector<DCPContentType const *> const ct = DCPContentType::all ();
448 for (size_t i = 0; i < ct.size(); ++i) {
449 _dcp_content_type->Append (std_to_wx (ct[i]->pretty_name ()));
452 _dcp_content_type->Bind (wxEVT_COMMAND_CHOICE_SELECTED, boost::bind (&DefaultsPage::dcp_content_type_changed, this));
454 _j2k_bandwidth->SetRange (50, 250);
455 _j2k_bandwidth->Bind (wxEVT_COMMAND_SPINCTRL_UPDATED, boost::bind (&DefaultsPage::j2k_bandwidth_changed, this));
457 _audio_delay->SetRange (-1000, 1000);
458 _audio_delay->Bind (wxEVT_COMMAND_SPINCTRL_UPDATED, boost::bind (&DefaultsPage::audio_delay_changed, this));
460 _standard->Append (_("SMPTE"));
461 _standard->Append (_("Interop"));
462 _standard->Bind (wxEVT_COMMAND_CHOICE_SELECTED, boost::bind (&DefaultsPage::standard_changed, this));
465 void config_changed ()
467 Config* config = Config::instance ();
469 vector<Ratio const *> ratios = Ratio::all ();
470 for (size_t i = 0; i < ratios.size(); ++i) {
471 if (ratios[i] == config->default_container ()) {
472 _container->SetSelection (i);
476 vector<DCPContentType const *> const ct = DCPContentType::all ();
477 for (size_t i = 0; i < ct.size(); ++i) {
478 if (ct[i] == config->default_dcp_content_type ()) {
479 _dcp_content_type->SetSelection (i);
483 checked_set (_still_length, config->default_still_length ());
484 _directory->SetPath (std_to_wx (config->default_directory_or (wx_to_std (wxStandardPaths::Get().GetDocumentsDir())).string ()));
485 checked_set (_j2k_bandwidth, config->default_j2k_bandwidth() / 1000000);
486 _j2k_bandwidth->SetRange (50, config->maximum_j2k_bandwidth() / 1000000);
487 checked_set (_audio_delay, config->default_audio_delay ());
488 checked_set (_standard, config->default_interop() ? 1 : 0);
491 void j2k_bandwidth_changed ()
493 Config::instance()->set_default_j2k_bandwidth (_j2k_bandwidth->GetValue() * 1000000);
496 void audio_delay_changed ()
498 Config::instance()->set_default_audio_delay (_audio_delay->GetValue());
501 void directory_changed ()
503 Config::instance()->set_default_directory (wx_to_std (_directory->GetPath ()));
506 void edit_isdcf_metadata_clicked ()
508 ISDCFMetadataDialog* d = new ISDCFMetadataDialog (_panel, Config::instance()->default_isdcf_metadata (), false);
510 Config::instance()->set_default_isdcf_metadata (d->isdcf_metadata ());
514 void still_length_changed ()
516 Config::instance()->set_default_still_length (_still_length->GetValue ());
519 void container_changed ()
521 vector<Ratio const *> ratio = Ratio::all ();
522 Config::instance()->set_default_container (ratio[_container->GetSelection()]);
525 void dcp_content_type_changed ()
527 vector<DCPContentType const *> ct = DCPContentType::all ();
528 Config::instance()->set_default_dcp_content_type (ct[_dcp_content_type->GetSelection()]);
531 void standard_changed ()
533 Config::instance()->set_default_interop (_standard->GetSelection() == 1);
536 wxSpinCtrl* _j2k_bandwidth;
537 wxSpinCtrl* _audio_delay;
538 wxButton* _isdcf_metadata_button;
539 wxSpinCtrl* _still_length;
540 #ifdef DCPOMATIC_USE_OWN_PICKER
541 DirPickerCtrl* _directory;
543 wxDirPickerCtrl* _directory;
545 wxChoice* _container;
546 wxChoice* _dcp_content_type;
550 class EncodingServersPage : public StandardPage
553 EncodingServersPage (wxSize panel_size, int border)
554 : StandardPage (panel_size, border)
557 wxString GetName () const
563 wxBitmap GetLargeIcon () const
565 return wxBitmap ("servers", wxBITMAP_TYPE_PNG_RESOURCE);
572 _use_any_servers = new wxCheckBox (_panel, wxID_ANY, _("Use all servers"));
573 _panel->GetSizer()->Add (_use_any_servers, 0, wxALL, _border);
575 vector<string> columns;
576 columns.push_back (wx_to_std (_("IP address / host name")));
577 _servers_list = new EditableList<string, ServerDialog> (
580 boost::bind (&Config::servers, Config::instance()),
581 boost::bind (&Config::set_servers, Config::instance(), _1),
582 boost::bind (&EncodingServersPage::server_column, this, _1)
585 _panel->GetSizer()->Add (_servers_list, 1, wxEXPAND | wxALL, _border);
587 _use_any_servers->Bind (wxEVT_COMMAND_CHECKBOX_CLICKED, boost::bind (&EncodingServersPage::use_any_servers_changed, this));
590 void config_changed ()
592 checked_set (_use_any_servers, Config::instance()->use_any_servers ());
593 _servers_list->refresh ();
596 void use_any_servers_changed ()
598 Config::instance()->set_use_any_servers (_use_any_servers->GetValue ());
601 string server_column (string s)
606 wxCheckBox* _use_any_servers;
607 EditableList<string, ServerDialog>* _servers_list;
610 class CertificateChainEditor : public wxPanel
613 CertificateChainEditor (
617 function<void (shared_ptr<dcp::CertificateChain>)> set,
618 function<shared_ptr<const dcp::CertificateChain> (void)> get
624 wxFont subheading_font (*wxNORMAL_FONT);
625 subheading_font.SetWeight (wxFONTWEIGHT_BOLD);
627 _sizer = new wxBoxSizer (wxVERTICAL);
630 wxStaticText* m = new wxStaticText (this, wxID_ANY, title);
631 m->SetFont (subheading_font);
632 _sizer->Add (m, 0, wxALL, border);
635 wxBoxSizer* certificates_sizer = new wxBoxSizer (wxHORIZONTAL);
636 _sizer->Add (certificates_sizer, 0, wxLEFT | wxRIGHT, border);
638 _certificates = new wxListCtrl (this, wxID_ANY, wxDefaultPosition, wxSize (440, 150), wxLC_REPORT | wxLC_SINGLE_SEL);
643 ip.SetText (_("Type"));
645 _certificates->InsertColumn (0, ip);
651 ip.SetText (_("Thumbprint"));
654 wxFont font = ip.GetFont ();
655 font.SetFamily (wxFONTFAMILY_TELETYPE);
658 _certificates->InsertColumn (1, ip);
661 certificates_sizer->Add (_certificates, 1, wxEXPAND);
664 wxSizer* s = new wxBoxSizer (wxVERTICAL);
665 _add_certificate = new wxButton (this, wxID_ANY, _("Add..."));
666 s->Add (_add_certificate, 0, wxTOP | wxBOTTOM, DCPOMATIC_BUTTON_STACK_GAP);
667 _remove_certificate = new wxButton (this, wxID_ANY, _("Remove"));
668 s->Add (_remove_certificate, 0, wxTOP | wxBOTTOM, DCPOMATIC_BUTTON_STACK_GAP);
669 _export_certificate = new wxButton (this, wxID_ANY, _("Export"));
670 s->Add (_export_certificate, 0, wxTOP | wxBOTTOM, DCPOMATIC_BUTTON_STACK_GAP);
671 certificates_sizer->Add (s, 0, wxLEFT, DCPOMATIC_SIZER_X_GAP);
674 wxGridBagSizer* table = new wxGridBagSizer (DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
675 _sizer->Add (table, 1, wxALL | wxEXPAND, border);
678 add_label_to_grid_bag_sizer (table, this, _("Leaf private key"), true, wxGBPosition (r, 0));
679 _private_key = new wxStaticText (this, wxID_ANY, wxT (""));
680 wxFont font = _private_key->GetFont ();
681 font.SetFamily (wxFONTFAMILY_TELETYPE);
682 _private_key->SetFont (font);
683 table->Add (_private_key, wxGBPosition (r, 1), wxDefaultSpan, wxALIGN_CENTER_VERTICAL);
684 _load_private_key = new wxButton (this, wxID_ANY, _("Load..."));
685 table->Add (_load_private_key, wxGBPosition (r, 2));
686 _export_private_key = new wxButton (this, wxID_ANY, _("Export..."));
687 table->Add (_export_private_key, wxGBPosition (r, 3));
690 _button_sizer = new wxBoxSizer (wxHORIZONTAL);
691 _remake_certificates = new wxButton (this, wxID_ANY, _("Re-make certificates and key..."));
692 _button_sizer->Add (_remake_certificates, 1, wxRIGHT, border);
693 table->Add (_button_sizer, wxGBPosition (r, 0), wxGBSpan (1, 3));
696 _add_certificate->Bind (wxEVT_COMMAND_BUTTON_CLICKED, boost::bind (&CertificateChainEditor::add_certificate, this));
697 _remove_certificate->Bind (wxEVT_COMMAND_BUTTON_CLICKED, boost::bind (&CertificateChainEditor::remove_certificate, this));
698 _export_certificate->Bind (wxEVT_COMMAND_BUTTON_CLICKED, boost::bind (&CertificateChainEditor::export_certificate, this));
699 _certificates->Bind (wxEVT_COMMAND_LIST_ITEM_SELECTED, boost::bind (&CertificateChainEditor::update_sensitivity, this));
700 _certificates->Bind (wxEVT_COMMAND_LIST_ITEM_DESELECTED, boost::bind (&CertificateChainEditor::update_sensitivity, this));
701 _remake_certificates->Bind (wxEVT_COMMAND_BUTTON_CLICKED, boost::bind (&CertificateChainEditor::remake_certificates, this));
702 _load_private_key->Bind (wxEVT_COMMAND_BUTTON_CLICKED, boost::bind (&CertificateChainEditor::load_private_key, this));
703 _export_private_key->Bind (wxEVT_COMMAND_BUTTON_CLICKED, boost::bind (&CertificateChainEditor::export_private_key, this));
705 SetSizerAndFit (_sizer);
708 void config_changed ()
710 _chain.reset (new dcp::CertificateChain (*_get().get ()));
712 update_certificate_list ();
713 update_private_key ();
714 update_sensitivity ();
717 void add_button (wxWindow* button)
719 _button_sizer->Add (button);
724 void add_certificate ()
726 wxFileDialog* d = new wxFileDialog (this, _("Select Certificate File"));
728 if (d->ShowModal() == wxID_OK) {
730 dcp::Certificate c (dcp::file_to_string (wx_to_std (d->GetPath ())));
733 update_certificate_list ();
734 } catch (dcp::MiscError& e) {
735 error_dialog (this, wxString::Format (_("Could not read certificate file (%s)"), e.what ()));
741 update_sensitivity ();
744 void remove_certificate ()
746 int i = _certificates->GetNextItem (-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
751 _certificates->DeleteItem (i);
755 update_sensitivity ();
758 void export_certificate ()
760 int i = _certificates->GetNextItem (-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
765 wxFileDialog* d = new wxFileDialog (
766 this, _("Select Certificate File"), wxEmptyString, wxEmptyString, wxT ("PEM files (*.pem)|*.pem"),
767 wxFD_SAVE | wxFD_OVERWRITE_PROMPT
770 dcp::CertificateChain::List all = _chain->root_to_leaf ();
771 dcp::CertificateChain::List::iterator j = all.begin ();
772 for (int k = 0; k < i; ++k) {
776 if (d->ShowModal () == wxID_OK) {
777 FILE* f = fopen_boost (wx_to_std (d->GetPath ()), "w");
779 throw OpenFileError (wx_to_std (d->GetPath ()));
782 string const s = j->certificate (true);
783 fwrite (s.c_str(), 1, s.length(), f);
789 void update_certificate_list ()
791 _certificates->DeleteAllItems ();
793 dcp::CertificateChain::List certs = _chain->root_to_leaf ();
794 BOOST_FOREACH (dcp::Certificate const & i, certs) {
797 _certificates->InsertItem (item);
798 _certificates->SetItem (n, 1, std_to_wx (i.thumbprint ()));
801 _certificates->SetItem (n, 0, _("Root"));
802 } else if (n == (certs.size() - 1)) {
803 _certificates->SetItem (n, 0, _("Leaf"));
805 _certificates->SetItem (n, 0, _("Intermediate"));
812 void remake_certificates ()
814 shared_ptr<const dcp::CertificateChain> chain = _get ();
816 string subject_organization_name;
817 string subject_organizational_unit_name;
818 string root_common_name;
819 string intermediate_common_name;
820 string leaf_common_name;
822 dcp::CertificateChain::List all = chain->root_to_leaf ();
824 if (all.size() >= 1) {
826 subject_organization_name = chain->root().subject_organization_name ();
827 subject_organizational_unit_name = chain->root().subject_organizational_unit_name ();
828 root_common_name = chain->root().subject_common_name ();
831 if (all.size() >= 2) {
833 leaf_common_name = chain->leaf().subject_common_name ();
836 if (all.size() >= 3) {
837 /* Have an intermediate */
838 dcp::CertificateChain::List::iterator i = all.begin ();
840 intermediate_common_name = i->subject_common_name ();
843 MakeChainDialog* d = new MakeChainDialog (
845 subject_organization_name,
846 subject_organizational_unit_name,
848 intermediate_common_name,
852 if (d->ShowModal () == wxID_OK) {
854 new dcp::CertificateChain (
857 d->organisational_unit (),
858 d->root_common_name (),
859 d->intermediate_common_name (),
860 d->leaf_common_name ()
865 update_certificate_list ();
866 update_private_key ();
872 void update_sensitivity ()
874 _remove_certificate->Enable (_certificates->GetNextItem (-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED) != -1);
875 _export_certificate->Enable (_certificates->GetNextItem (-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED) != -1);
878 void update_private_key ()
880 checked_set (_private_key, dcp::private_key_fingerprint (_chain->key().get ()));
884 void load_private_key ()
886 wxFileDialog* d = new wxFileDialog (this, _("Select Key File"));
888 if (d->ShowModal() == wxID_OK) {
890 boost::filesystem::path p (wx_to_std (d->GetPath ()));
891 if (boost::filesystem::file_size (p) > 1024) {
892 error_dialog (this, wxString::Format (_("Could not read key file (%s)"), std_to_wx (p.string ())));
896 _chain->set_key (dcp::file_to_string (p));
898 update_private_key ();
899 } catch (dcp::MiscError& e) {
900 error_dialog (this, wxString::Format (_("Could not read certificate file (%s)"), e.what ()));
906 update_sensitivity ();
909 void export_private_key ()
911 optional<string> key = _chain->key ();
916 wxFileDialog* d = new wxFileDialog (
917 this, _("Select Key File"), wxEmptyString, wxEmptyString, wxT ("PEM files (*.pem)|*.pem"),
918 wxFD_SAVE | wxFD_OVERWRITE_PROMPT
921 if (d->ShowModal () == wxID_OK) {
922 FILE* f = fopen_boost (wx_to_std (d->GetPath ()), "w");
924 throw OpenFileError (wx_to_std (d->GetPath ()));
927 string const s = _chain->key().get ();
928 fwrite (s.c_str(), 1, s.length(), f);
934 wxListCtrl* _certificates;
935 wxButton* _add_certificate;
936 wxButton* _export_certificate;
937 wxButton* _remove_certificate;
938 wxButton* _remake_certificates;
939 wxStaticText* _private_key;
940 wxButton* _load_private_key;
941 wxButton* _export_private_key;
943 wxBoxSizer* _button_sizer;
944 shared_ptr<dcp::CertificateChain> _chain;
945 boost::function<void (shared_ptr<dcp::CertificateChain>)> _set;
946 boost::function<shared_ptr<const dcp::CertificateChain> (void)> _get;
949 class KeysPage : public StandardPage
952 KeysPage (wxSize panel_size, int border)
953 : StandardPage (panel_size, border)
956 wxString GetName () const
962 wxBitmap GetLargeIcon () const
964 return wxBitmap ("keys", wxBITMAP_TYPE_PNG_RESOURCE);
972 _signer = new CertificateChainEditor (
973 _panel, _("Signing DCPs and KDMs"), _border,
974 boost::bind (&Config::set_signer_chain, Config::instance (), _1),
975 boost::bind (&Config::signer_chain, Config::instance ())
978 _panel->GetSizer()->Add (_signer);
980 _decryption = new CertificateChainEditor (
981 _panel, _("Decrypting DCPs"), _border,
982 boost::bind (&Config::set_decryption_chain, Config::instance (), _1),
983 boost::bind (&Config::decryption_chain, Config::instance ())
986 _panel->GetSizer()->Add (_decryption);
988 _export_decryption_certificate = new wxButton (_decryption, wxID_ANY, _("Export DCP decryption certificate..."));
989 _decryption->add_button (_export_decryption_certificate);
991 _export_decryption_certificate->Bind (wxEVT_COMMAND_BUTTON_CLICKED, boost::bind (&KeysPage::export_decryption_certificate, this));
994 void export_decryption_certificate ()
996 wxFileDialog* d = new wxFileDialog (
997 _panel, _("Select Certificate File"), wxEmptyString, wxEmptyString, wxT ("PEM files (*.pem)|*.pem"),
998 wxFD_SAVE | wxFD_OVERWRITE_PROMPT
1001 if (d->ShowModal () == wxID_OK) {
1002 FILE* f = fopen_boost (wx_to_std (d->GetPath ()), "w");
1004 throw OpenFileError (wx_to_std (d->GetPath ()));
1007 string const s = Config::instance()->decryption_chain()->leaf().certificate (true);
1008 fwrite (s.c_str(), 1, s.length(), f);
1014 void config_changed ()
1016 _signer->config_changed ();
1017 _decryption->config_changed ();
1020 CertificateChainEditor* _signer;
1021 CertificateChainEditor* _decryption;
1022 wxButton* _export_decryption_certificate;
1025 class TMSPage : public StandardPage
1028 TMSPage (wxSize panel_size, int border)
1029 : StandardPage (panel_size, border)
1032 wxString GetName () const
1037 #ifdef DCPOMATIC_OSX
1038 wxBitmap GetLargeIcon () const
1040 return wxBitmap ("tms", wxBITMAP_TYPE_PNG_RESOURCE);
1047 wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
1048 table->AddGrowableCol (1, 1);
1049 _panel->GetSizer()->Add (table, 1, wxALL | wxEXPAND, _border);
1051 add_label_to_sizer (table, _panel, _("Protocol"), true);
1052 _tms_protocol = new wxChoice (_panel, wxID_ANY);
1053 table->Add (_tms_protocol, 1, wxEXPAND);
1055 add_label_to_sizer (table, _panel, _("IP address"), true);
1056 _tms_ip = new wxTextCtrl (_panel, wxID_ANY);
1057 table->Add (_tms_ip, 1, wxEXPAND);
1059 add_label_to_sizer (table, _panel, _("Target path"), true);
1060 _tms_path = new wxTextCtrl (_panel, wxID_ANY);
1061 table->Add (_tms_path, 1, wxEXPAND);
1063 add_label_to_sizer (table, _panel, _("User name"), true);
1064 _tms_user = new wxTextCtrl (_panel, wxID_ANY);
1065 table->Add (_tms_user, 1, wxEXPAND);
1067 add_label_to_sizer (table, _panel, _("Password"), true);
1068 _tms_password = new wxTextCtrl (_panel, wxID_ANY);
1069 table->Add (_tms_password, 1, wxEXPAND);
1071 _tms_protocol->Append (_("SCP (for AAM and Doremi)"));
1072 _tms_protocol->Append (_("FTP (for Dolby)"));
1074 _tms_protocol->Bind (wxEVT_COMMAND_CHOICE_SELECTED, boost::bind (&TMSPage::tms_protocol_changed, this));
1075 _tms_ip->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&TMSPage::tms_ip_changed, this));
1076 _tms_path->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&TMSPage::tms_path_changed, this));
1077 _tms_user->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&TMSPage::tms_user_changed, this));
1078 _tms_password->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&TMSPage::tms_password_changed, this));
1081 void config_changed ()
1083 Config* config = Config::instance ();
1085 checked_set (_tms_protocol, config->tms_protocol ());
1086 checked_set (_tms_ip, config->tms_ip ());
1087 checked_set (_tms_path, config->tms_path ());
1088 checked_set (_tms_user, config->tms_user ());
1089 checked_set (_tms_password, config->tms_password ());
1092 void tms_protocol_changed ()
1094 Config::instance()->set_tms_protocol (static_cast<Protocol> (_tms_protocol->GetSelection ()));
1097 void tms_ip_changed ()
1099 Config::instance()->set_tms_ip (wx_to_std (_tms_ip->GetValue ()));
1102 void tms_path_changed ()
1104 Config::instance()->set_tms_path (wx_to_std (_tms_path->GetValue ()));
1107 void tms_user_changed ()
1109 Config::instance()->set_tms_user (wx_to_std (_tms_user->GetValue ()));
1112 void tms_password_changed ()
1114 Config::instance()->set_tms_password (wx_to_std (_tms_password->GetValue ()));
1117 wxChoice* _tms_protocol;
1118 wxTextCtrl* _tms_ip;
1119 wxTextCtrl* _tms_path;
1120 wxTextCtrl* _tms_user;
1121 wxTextCtrl* _tms_password;
1124 class KDMEmailPage : public StandardPage
1128 KDMEmailPage (wxSize panel_size, int border)
1129 #ifdef DCPOMATIC_OSX
1130 /* We have to force both width and height of this one */
1131 : StandardPage (wxSize (480, 128), border)
1133 : StandardPage (panel_size, border)
1137 wxString GetName () const
1139 return _("KDM Email");
1142 #ifdef DCPOMATIC_OSX
1143 wxBitmap GetLargeIcon () const
1145 return wxBitmap ("kdm_email", wxBITMAP_TYPE_PNG_RESOURCE);
1152 wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
1153 table->AddGrowableCol (1, 1);
1154 _panel->GetSizer()->Add (table, 1, wxEXPAND | wxALL, _border);
1156 add_label_to_sizer (table, _panel, _("Outgoing mail server"), true);
1158 wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL);
1159 _mail_server = new wxTextCtrl (_panel, wxID_ANY);
1160 s->Add (_mail_server, 1, wxEXPAND | wxALL);
1161 add_label_to_sizer (s, _panel, _("port"), false);
1162 _mail_port = new wxSpinCtrl (_panel, wxID_ANY);
1163 _mail_port->SetRange (0, 65535);
1164 s->Add (_mail_port);
1165 table->Add (s, 1, wxEXPAND | wxALL);
1168 add_label_to_sizer (table, _panel, _("Mail user name"), true);
1169 _mail_user = new wxTextCtrl (_panel, wxID_ANY);
1170 table->Add (_mail_user, 1, wxEXPAND | wxALL);
1172 add_label_to_sizer (table, _panel, _("Mail password"), true);
1173 _mail_password = new wxTextCtrl (_panel, wxID_ANY);
1174 table->Add (_mail_password, 1, wxEXPAND | wxALL);
1176 add_label_to_sizer (table, _panel, _("Subject"), true);
1177 _kdm_subject = new wxTextCtrl (_panel, wxID_ANY);
1178 table->Add (_kdm_subject, 1, wxEXPAND | wxALL);
1180 add_label_to_sizer (table, _panel, _("From address"), true);
1181 _kdm_from = new wxTextCtrl (_panel, wxID_ANY);
1182 table->Add (_kdm_from, 1, wxEXPAND | wxALL);
1184 add_label_to_sizer (table, _panel, _("CC address"), true);
1185 _kdm_cc = new wxTextCtrl (_panel, wxID_ANY);
1186 table->Add (_kdm_cc, 1, wxEXPAND | wxALL);
1188 add_label_to_sizer (table, _panel, _("BCC address"), true);
1189 _kdm_bcc = new wxTextCtrl (_panel, wxID_ANY);
1190 table->Add (_kdm_bcc, 1, wxEXPAND | wxALL);
1192 _kdm_email = new wxTextCtrl (_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize (480, 128), wxTE_MULTILINE);
1193 _panel->GetSizer()->Add (_kdm_email, 1, wxEXPAND | wxALL, _border);
1195 _reset_kdm_email = new wxButton (_panel, wxID_ANY, _("Reset to default text"));
1196 _panel->GetSizer()->Add (_reset_kdm_email, 0, wxEXPAND | wxALL, _border);
1198 _mail_server->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&KDMEmailPage::mail_server_changed, this));
1199 _mail_port->Bind (wxEVT_COMMAND_SPINCTRL_UPDATED, boost::bind (&KDMEmailPage::mail_port_changed, this));
1200 _mail_user->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&KDMEmailPage::mail_user_changed, this));
1201 _mail_password->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&KDMEmailPage::mail_password_changed, this));
1202 _kdm_subject->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&KDMEmailPage::kdm_subject_changed, this));
1203 _kdm_from->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&KDMEmailPage::kdm_from_changed, this));
1204 _kdm_cc->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&KDMEmailPage::kdm_cc_changed, this));
1205 _kdm_bcc->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&KDMEmailPage::kdm_bcc_changed, this));
1206 _kdm_email->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&KDMEmailPage::kdm_email_changed, this));
1207 _reset_kdm_email->Bind (wxEVT_COMMAND_BUTTON_CLICKED, boost::bind (&KDMEmailPage::reset_kdm_email, this));
1210 void config_changed ()
1212 Config* config = Config::instance ();
1214 checked_set (_mail_server, config->mail_server ());
1215 checked_set (_mail_port, config->mail_port ());
1216 checked_set (_mail_user, config->mail_user ());
1217 checked_set (_mail_password, config->mail_password ());
1218 checked_set (_kdm_subject, config->kdm_subject ());
1219 checked_set (_kdm_from, config->kdm_from ());
1220 checked_set (_kdm_cc, config->kdm_cc ());
1221 checked_set (_kdm_bcc, config->kdm_bcc ());
1222 checked_set (_kdm_email, Config::instance()->kdm_email ());
1225 void mail_server_changed ()
1227 Config::instance()->set_mail_server (wx_to_std (_mail_server->GetValue ()));
1230 void mail_port_changed ()
1232 Config::instance()->set_mail_port (_mail_port->GetValue ());
1235 void mail_user_changed ()
1237 Config::instance()->set_mail_user (wx_to_std (_mail_user->GetValue ()));
1240 void mail_password_changed ()
1242 Config::instance()->set_mail_password (wx_to_std (_mail_password->GetValue ()));
1245 void kdm_subject_changed ()
1247 Config::instance()->set_kdm_subject (wx_to_std (_kdm_subject->GetValue ()));
1250 void kdm_from_changed ()
1252 Config::instance()->set_kdm_from (wx_to_std (_kdm_from->GetValue ()));
1255 void kdm_cc_changed ()
1257 Config::instance()->set_kdm_cc (wx_to_std (_kdm_cc->GetValue ()));
1260 void kdm_bcc_changed ()
1262 Config::instance()->set_kdm_bcc (wx_to_std (_kdm_bcc->GetValue ()));
1265 void kdm_email_changed ()
1267 if (_kdm_email->GetValue().IsEmpty ()) {
1268 /* Sometimes we get sent an erroneous notification that the email
1269 is empty; I don't know why.
1273 Config::instance()->set_kdm_email (wx_to_std (_kdm_email->GetValue ()));
1276 void reset_kdm_email ()
1278 Config::instance()->reset_kdm_email ();
1279 checked_set (_kdm_email, Config::instance()->kdm_email ());
1282 wxTextCtrl* _mail_server;
1283 wxSpinCtrl* _mail_port;
1284 wxTextCtrl* _mail_user;
1285 wxTextCtrl* _mail_password;
1286 wxTextCtrl* _kdm_subject;
1287 wxTextCtrl* _kdm_from;
1288 wxTextCtrl* _kdm_cc;
1289 wxTextCtrl* _kdm_bcc;
1290 wxTextCtrl* _kdm_email;
1291 wxButton* _reset_kdm_email;
1294 /** @class AdvancedPage
1295 * @brief Advanced page of the preferences dialog.
1297 class AdvancedPage : public StockPage
1300 AdvancedPage (wxSize panel_size, int border)
1301 : StockPage (Kind_Advanced, panel_size, border)
1302 , _maximum_j2k_bandwidth (0)
1303 , _allow_any_dcp_frame_rate (0)
1304 , _only_servers_encode (0)
1309 , _log_debug_decode (0)
1310 , _log_debug_encode (0)
1311 , _log_debug_email (0)
1317 wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
1318 table->AddGrowableCol (1, 1);
1319 _panel->GetSizer()->Add (table, 1, wxALL | wxEXPAND, _border);
1322 add_label_to_sizer (table, _panel, _("Maximum JPEG2000 bandwidth"), true);
1323 wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL);
1324 _maximum_j2k_bandwidth = new wxSpinCtrl (_panel);
1325 s->Add (_maximum_j2k_bandwidth, 1);
1326 add_label_to_sizer (s, _panel, _("Mbit/s"), false);
1330 _allow_any_dcp_frame_rate = new wxCheckBox (_panel, wxID_ANY, _("Allow any DCP frame rate"));
1331 table->Add (_allow_any_dcp_frame_rate, 1, wxEXPAND | wxALL);
1332 table->AddSpacer (0);
1334 _only_servers_encode = new wxCheckBox (_panel, wxID_ANY, _("Only servers encode"));
1335 table->Add (_only_servers_encode, 1, wxEXPAND | wxALL);
1336 table->AddSpacer (0);
1339 wxStaticText* m = new wxStaticText (_panel, wxID_ANY, _("Log:"));
1340 table->Add (m, 0, wxALIGN_TOP | wxLEFT | wxRIGHT | wxEXPAND | wxALL | wxALIGN_RIGHT, 6);
1342 wxStaticText* m = new wxStaticText (_panel, wxID_ANY, _("Log"));
1343 table->Add (m, 0, wxALIGN_TOP | wxLEFT | wxRIGHT | wxEXPAND | wxALL, 6);
1347 wxBoxSizer* t = new wxBoxSizer (wxVERTICAL);
1348 _log_general = new wxCheckBox (_panel, wxID_ANY, _("General"));
1349 t->Add (_log_general, 1, wxEXPAND | wxALL);
1350 _log_warning = new wxCheckBox (_panel, wxID_ANY, _("Warnings"));
1351 t->Add (_log_warning, 1, wxEXPAND | wxALL);
1352 _log_error = new wxCheckBox (_panel, wxID_ANY, _("Errors"));
1353 t->Add (_log_error, 1, wxEXPAND | wxALL);
1354 _log_timing = new wxCheckBox (_panel, wxID_ANY, S_("Config|Timing"));
1355 t->Add (_log_timing, 1, wxEXPAND | wxALL);
1356 _log_debug_decode = new wxCheckBox (_panel, wxID_ANY, _("Debug: decode"));
1357 t->Add (_log_debug_decode, 1, wxEXPAND | wxALL);
1358 _log_debug_encode = new wxCheckBox (_panel, wxID_ANY, _("Debug: encode"));
1359 t->Add (_log_debug_encode, 1, wxEXPAND | wxALL);
1360 _log_debug_email = new wxCheckBox (_panel, wxID_ANY, _("Debug: email sending"));
1361 t->Add (_log_debug_email, 1, wxEXPAND | wxALL);
1362 table->Add (t, 0, wxALL, 6);
1365 #ifdef DCPOMATIC_WINDOWS
1366 _win32_console = new wxCheckBox (_panel, wxID_ANY, _("Open console window"));
1367 table->Add (_win32_console, 1, wxEXPAND | wxALL);
1368 table->AddSpacer (0);
1371 _maximum_j2k_bandwidth->SetRange (1, 1000);
1372 _maximum_j2k_bandwidth->Bind (wxEVT_COMMAND_SPINCTRL_UPDATED, boost::bind (&AdvancedPage::maximum_j2k_bandwidth_changed, this));
1373 _allow_any_dcp_frame_rate->Bind (wxEVT_COMMAND_CHECKBOX_CLICKED, boost::bind (&AdvancedPage::allow_any_dcp_frame_rate_changed, this));
1374 _only_servers_encode->Bind (wxEVT_COMMAND_CHECKBOX_CLICKED, boost::bind (&AdvancedPage::only_servers_encode_changed, this));
1375 _log_general->Bind (wxEVT_COMMAND_CHECKBOX_CLICKED, boost::bind (&AdvancedPage::log_changed, this));
1376 _log_warning->Bind (wxEVT_COMMAND_CHECKBOX_CLICKED, boost::bind (&AdvancedPage::log_changed, this));
1377 _log_error->Bind (wxEVT_COMMAND_CHECKBOX_CLICKED, boost::bind (&AdvancedPage::log_changed, this));
1378 _log_timing->Bind (wxEVT_COMMAND_CHECKBOX_CLICKED, boost::bind (&AdvancedPage::log_changed, this));
1379 _log_debug_decode->Bind (wxEVT_COMMAND_CHECKBOX_CLICKED, boost::bind (&AdvancedPage::log_changed, this));
1380 _log_debug_encode->Bind (wxEVT_COMMAND_CHECKBOX_CLICKED, boost::bind (&AdvancedPage::log_changed, this));
1381 _log_debug_email->Bind (wxEVT_COMMAND_CHECKBOX_CLICKED, boost::bind (&AdvancedPage::log_changed, this));
1382 #ifdef DCPOMATIC_WINDOWS
1383 _win32_console->Bind (wxEVT_COMMAND_CHECKBOX_CLICKED, boost::bind (&AdvancedPage::win32_console_changed, this));
1387 void config_changed ()
1389 Config* config = Config::instance ();
1391 checked_set (_maximum_j2k_bandwidth, config->maximum_j2k_bandwidth() / 1000000);
1392 checked_set (_allow_any_dcp_frame_rate, config->allow_any_dcp_frame_rate ());
1393 checked_set (_only_servers_encode, config->only_servers_encode ());
1394 checked_set (_log_general, config->log_types() & LogEntry::TYPE_GENERAL);
1395 checked_set (_log_warning, config->log_types() & LogEntry::TYPE_WARNING);
1396 checked_set (_log_error, config->log_types() & LogEntry::TYPE_ERROR);
1397 checked_set (_log_timing, config->log_types() & LogEntry::TYPE_TIMING);
1398 checked_set (_log_debug_decode, config->log_types() & LogEntry::TYPE_DEBUG_DECODE);
1399 checked_set (_log_debug_encode, config->log_types() & LogEntry::TYPE_DEBUG_ENCODE);
1400 checked_set (_log_debug_email, config->log_types() & LogEntry::TYPE_DEBUG_EMAIL);
1401 #ifdef DCPOMATIC_WINDOWS
1402 checked_set (_win32_console, config->win32_console());
1406 void maximum_j2k_bandwidth_changed ()
1408 Config::instance()->set_maximum_j2k_bandwidth (_maximum_j2k_bandwidth->GetValue() * 1000000);
1411 void allow_any_dcp_frame_rate_changed ()
1413 Config::instance()->set_allow_any_dcp_frame_rate (_allow_any_dcp_frame_rate->GetValue ());
1416 void only_servers_encode_changed ()
1418 Config::instance()->set_only_servers_encode (_only_servers_encode->GetValue ());
1424 if (_log_general->GetValue ()) {
1425 types |= LogEntry::TYPE_GENERAL;
1427 if (_log_warning->GetValue ()) {
1428 types |= LogEntry::TYPE_WARNING;
1430 if (_log_error->GetValue ()) {
1431 types |= LogEntry::TYPE_ERROR;
1433 if (_log_timing->GetValue ()) {
1434 types |= LogEntry::TYPE_TIMING;
1436 if (_log_debug_decode->GetValue ()) {
1437 types |= LogEntry::TYPE_DEBUG_DECODE;
1439 if (_log_debug_encode->GetValue ()) {
1440 types |= LogEntry::TYPE_DEBUG_ENCODE;
1442 if (_log_debug_email->GetValue ()) {
1443 types |= LogEntry::TYPE_DEBUG_EMAIL;
1445 Config::instance()->set_log_types (types);
1448 #ifdef DCPOMATIC_WINDOWS
1449 void win32_console_changed ()
1451 Config::instance()->set_win32_console (_win32_console->GetValue ());
1455 wxSpinCtrl* _maximum_j2k_bandwidth;
1456 wxCheckBox* _allow_any_dcp_frame_rate;
1457 wxCheckBox* _only_servers_encode;
1458 wxCheckBox* _log_general;
1459 wxCheckBox* _log_warning;
1460 wxCheckBox* _log_error;
1461 wxCheckBox* _log_timing;
1462 wxCheckBox* _log_debug_decode;
1463 wxCheckBox* _log_debug_encode;
1464 wxCheckBox* _log_debug_email;
1465 #ifdef DCPOMATIC_WINDOWS
1466 wxCheckBox* _win32_console;
1470 wxPreferencesEditor*
1471 create_config_dialog ()
1473 wxPreferencesEditor* e = new wxPreferencesEditor ();
1475 #ifdef DCPOMATIC_OSX
1476 /* Width that we force some of the config panels to be on OSX so that
1477 the containing window doesn't shrink too much when we select those panels.
1478 This is obviously an unpleasant hack.
1480 wxSize ps = wxSize (520, -1);
1481 int const border = 16;
1483 wxSize ps = wxSize (-1, -1);
1484 int const border = 8;
1487 e->AddPage (new GeneralPage (ps, border));
1488 e->AddPage (new DefaultsPage (ps, border));
1489 e->AddPage (new EncodingServersPage (ps, border));
1490 e->AddPage (new KeysPage (ps, border));
1491 e->AddPage (new TMSPage (ps, border));
1492 e->AddPage (new KDMEmailPage (ps, border));
1493 e->AddPage (new AdvancedPage (ps, border));