Merge branch 'v2.15.x' of ssh://localhost:2222/home/carl/git/dcpomatic into v2.15.x
[dcpomatic.git] / src / wx / config_dialog.cc
index 8b6d215a2759bc37f3fbc68415ebfe3be01ba822..98a1a1a8e231c29505ab2385fc41a4e892aede45 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2012-2018 Carl Hetherington <cth@carlh.net>
+    Copyright (C) 2012-2019 Carl Hetherington <cth@carlh.net>
 
     This file is part of DCP-o-matic.
 
@@ -23,6 +23,7 @@
 #include "check_box.h"
 #include "nag_dialog.h"
 #include "dcpomatic_button.h"
+#include <iostream>
 
 using std::string;
 using std::vector;
@@ -134,6 +135,7 @@ GeneralPage::add_language_controls (wxGridBagSizer* table, int& r)
        languages.push_back (make_pair ("Português do Brasil", "pt_BR"));
        languages.push_back (make_pair ("Svenska", "sv_SE"));
        languages.push_back (make_pair ("Slovenský jazyk", "sk_SK"));
+       languages.push_back (make_pair ("Türkçe", "tr_TR"));
        languages.push_back (make_pair ("українська мова", "uk_UA"));
        checked_set (_language, languages);
        table->Add (_language, wxGBPosition (r, 1));
@@ -157,10 +159,19 @@ GeneralPage::add_play_sound_controls (wxGridBagSizer* table, int& r)
 {
        _sound = new CheckBox (_panel, _("Play sound via"));
        table->Add (_sound, wxGBPosition (r, 0), wxDefaultSpan, wxALIGN_CENTER_VERTICAL);
+       wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL);
        _sound_output = new wxChoice (_panel, wxID_ANY);
-       table->Add (_sound_output, wxGBPosition (r, 1));
+       s->Add (_sound_output, 0);
+       _sound_output_details = new wxStaticText (_panel, wxID_ANY, wxT(""));
+       s->Add (_sound_output_details, 1, wxALIGN_CENTER_VERTICAL | wxLEFT, DCPOMATIC_SIZER_X_GAP);
+       table->Add (s, wxGBPosition(r, 1));
        ++r;
 
+       wxFont font = _sound_output_details->GetFont();
+       font.SetStyle (wxFONTSTYLE_ITALIC);
+       font.SetPointSize (font.GetPointSize() - 1);
+       _sound_output_details->SetFont (font);
+
        RtAudio audio (DCPOMATIC_RTAUDIO_API);
        for (unsigned int i = 0; i < audio.getDeviceCount(); ++i) {
                RtAudio::DeviceInfo dev = audio.getDeviceInfo (i);
@@ -251,6 +262,33 @@ GeneralPage::config_changed ()
                }
        }
 
+       RtAudio audio (DCPOMATIC_RTAUDIO_API);
+
+       map<int, wxString> apis;
+       apis[RtAudio::MACOSX_CORE]    = _("CoreAudio");
+       apis[RtAudio::WINDOWS_ASIO]   = _("ASIO");
+       apis[RtAudio::WINDOWS_DS]     = _("Direct Sound");
+       apis[RtAudio::WINDOWS_WASAPI] = _("WASAPI");
+       apis[RtAudio::UNIX_JACK]      = _("JACK");
+       apis[RtAudio::LINUX_ALSA]     = _("ALSA");
+       apis[RtAudio::LINUX_PULSE]    = _("PulseAudio");
+       apis[RtAudio::LINUX_OSS]      = _("OSS");
+       apis[RtAudio::RTAUDIO_DUMMY]  = _("Dummy");
+
+       int channels = 0;
+       if (configured_so) {
+               for (unsigned int i = 0; i < audio.getDeviceCount(); ++i) {
+                       RtAudio::DeviceInfo info = audio.getDeviceInfo(i);
+                       if (info.name == *configured_so && info.outputChannels > 0) {
+                               channels = info.outputChannels;
+                       }
+               }
+       }
+
+       _sound_output_details->SetLabel (
+               wxString::Format(_("%d channels on %s"), channels, apis[audio.getCurrentApi()])
+               );
+
        setup_sensitivity ();
 }
 
@@ -332,12 +370,12 @@ CertificateChainEditor::CertificateChainEditor (
        int border,
        function<void (shared_ptr<dcp::CertificateChain>)> set,
        function<shared_ptr<const dcp::CertificateChain> (void)> get,
-       function<bool (void)> nag_remake
+       function<bool (void)> nag_alter
        )
        : wxDialog (parent, wxID_ANY, title)
        , _set (set)
        , _get (get)
-       , _nag_remake (nag_remake)
+       , _nag_alter (nag_alter)
 {
        wxFont subheading_font (*wxNORMAL_FONT);
        subheading_font.SetWeight (wxFONTWEIGHT_BOLD);
@@ -408,6 +446,8 @@ CertificateChainEditor::CertificateChainEditor (
        _button_sizer = new wxBoxSizer (wxHORIZONTAL);
        _remake_certificates = new Button (this, _("Re-make certificates and key..."));
        _button_sizer->Add (_remake_certificates, 1, wxRIGHT, border);
+       _export_chain = new Button (this, _("Export chain..."));
+       _button_sizer->Add (_export_chain, 1, wxRIGHT, border);
        table->Add (_button_sizer, wxGBPosition (r, 0), wxGBSpan (1, 4));
        ++r;
 
@@ -424,6 +464,7 @@ CertificateChainEditor::CertificateChainEditor (
        _certificates->Bind        (wxEVT_LIST_ITEM_SELECTED,   bind (&CertificateChainEditor::update_sensitivity, this));
        _certificates->Bind        (wxEVT_LIST_ITEM_DESELECTED, bind (&CertificateChainEditor::update_sensitivity, this));
        _remake_certificates->Bind (wxEVT_BUTTON,       bind (&CertificateChainEditor::remake_certificates, this));
+       _export_chain->Bind        (wxEVT_BUTTON,       bind (&CertificateChainEditor::export_chain, this));
        _import_private_key->Bind  (wxEVT_BUTTON,       bind (&CertificateChainEditor::import_private_key, this));
        _export_private_key->Bind  (wxEVT_BUTTON,       bind (&CertificateChainEditor::export_private_key, this));
 
@@ -496,6 +537,11 @@ CertificateChainEditor::add_certificate ()
 void
 CertificateChainEditor::remove_certificate ()
 {
+       if (_nag_alter()) {
+               /* Cancel was clicked */
+               return;
+       }
+
        int i = _certificates->GetNextItem (-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
        if (i == -1) {
                return;
@@ -507,6 +553,7 @@ CertificateChainEditor::remove_certificate ()
        _set (chain);
 
        update_sensitivity ();
+       update_certificate_list ();
 }
 
 void
@@ -532,7 +579,7 @@ CertificateChainEditor::export_certificate ()
                boost::filesystem::path path (wx_to_std(d->GetPath()));
                FILE* f = fopen_boost (path, "w");
                if (!f) {
-                       throw OpenFileError (path, errno, false);
+                       throw OpenFileError (path, errno, OpenFileError::WRITE);
                }
 
                string const s = j->certificate (true);
@@ -542,6 +589,29 @@ CertificateChainEditor::export_certificate ()
        d->Destroy ();
 }
 
+void
+CertificateChainEditor::export_chain ()
+{
+       wxFileDialog* d = new wxFileDialog (
+               this, _("Select Chain File"), wxEmptyString, wxEmptyString, wxT("PEM files (*.pem)|*.pem"),
+               wxFD_SAVE | wxFD_OVERWRITE_PROMPT
+               );
+
+       if (d->ShowModal () == wxID_OK) {
+               boost::filesystem::path path (wx_to_std(d->GetPath()));
+               FILE* f = fopen_boost (path, "w");
+               if (!f) {
+                       throw OpenFileError (path, errno, OpenFileError::WRITE);
+               }
+
+               string const s = _get()->chain();
+               checked_fwrite (s.c_str(), s.length(), f, path);
+               fclose (f);
+       }
+
+       d->Destroy ();
+}
+
 void
 CertificateChainEditor::update_certificate_list ()
 {
@@ -608,7 +678,7 @@ CertificateChainEditor::remake_certificates ()
                intermediate_common_name = i->subject_common_name ();
        }
 
-       if (_nag_remake()) {
+       if (_nag_alter()) {
                /* Cancel was clicked */
                return;
        }
@@ -705,7 +775,7 @@ CertificateChainEditor::export_private_key ()
                boost::filesystem::path path (wx_to_std(d->GetPath()));
                FILE* f = fopen_boost (path, "w");
                if (!f) {
-                       throw OpenFileError (path, errno, false);
+                       throw OpenFileError (path, errno, OpenFileError::WRITE);
                }
 
                string const s = _get()->key().get ();
@@ -737,8 +807,6 @@ KeysPage::setup ()
 
        wxButton* export_decryption_certificate = new Button (_panel, _("Export KDM decryption certificate..."));
        sizer->Add (export_decryption_certificate, 0, wxLEFT, _border);
-       wxButton* export_decryption_chain = new Button (_panel, _("Export KDM decryption chain..."));
-       sizer->Add (export_decryption_chain, 0, wxLEFT, _border);
        wxButton* export_settings = new Button (_panel, _("Export all KDM decryption settings..."));
        sizer->Add (export_settings, 0, wxLEFT, _border);
        wxButton* import_settings = new Button (_panel, _("Import all KDM decryption settings..."));
@@ -747,7 +815,6 @@ KeysPage::setup ()
        sizer->Add (decryption_advanced, 0, wxALL, _border);
 
        export_decryption_certificate->Bind (wxEVT_BUTTON, bind (&KeysPage::export_decryption_certificate, this));
-       export_decryption_chain->Bind (wxEVT_BUTTON, bind (&KeysPage::export_decryption_chain, this));
        export_settings->Bind (wxEVT_BUTTON, bind (&KeysPage::export_decryption_chain_and_key, this));
        import_settings->Bind (wxEVT_BUTTON, bind (&KeysPage::import_decryption_chain_and_key, this));
        decryption_advanced->Bind (wxEVT_BUTTON, bind (&KeysPage::decryption_advanced, this));
@@ -770,7 +837,7 @@ KeysPage::decryption_advanced ()
                _panel, _("Decrypting KDMs"), _border,
                bind (&Config::set_decryption_chain, Config::instance (), _1),
                bind (&Config::decryption_chain, Config::instance ()),
-               bind (&KeysPage::nag_remake_decryption_chain, this)
+               bind (&KeysPage::nag_alter_decryption_chain, this)
                );
 
        c->ShowModal();
@@ -801,7 +868,7 @@ KeysPage::export_decryption_chain_and_key ()
                boost::filesystem::path path (wx_to_std(d->GetPath()));
                FILE* f = fopen_boost (path, "w");
                if (!f) {
-                       throw OpenFileError (path, errno, false);
+                       throw OpenFileError (path, errno, OpenFileError::WRITE);
                }
 
                string const chain = Config::instance()->decryption_chain()->chain();
@@ -818,6 +885,15 @@ KeysPage::export_decryption_chain_and_key ()
 void
 KeysPage::import_decryption_chain_and_key ()
 {
+       if (NagDialog::maybe_nag (
+                   _panel,
+                   Config::NAG_IMPORT_DECRYPTION_CHAIN,
+                   _("If you continue with this operation you will no longer be able to use any DKDMs that you have created with the current certificates and key.  Also, any KDMs that have been sent to you for those certificates will become useless.  Proceed with caution!"),
+                   true
+                   )) {
+               return;
+       }
+
        wxFileDialog* d = new wxFileDialog (
                _panel, _("Select File To Import"), wxEmptyString, wxEmptyString, wxT ("DOM files (*.dom)|*.dom")
                );
@@ -827,7 +903,7 @@ KeysPage::import_decryption_chain_and_key ()
 
                FILE* f = fopen_boost (wx_to_std (d->GetPath ()), "r");
                if (!f) {
-                       throw OpenFileError (wx_to_std (d->GetPath ()), errno, false);
+                       throw OpenFileError (wx_to_std (d->GetPath ()), errno, OpenFileError::WRITE);
                }
 
                string current;
@@ -857,38 +933,16 @@ KeysPage::import_decryption_chain_and_key ()
 }
 
 bool
-KeysPage::nag_remake_decryption_chain ()
+KeysPage::nag_alter_decryption_chain ()
 {
        return NagDialog::maybe_nag (
                _panel,
-               Config::NAG_REMAKE_DECRYPTION_CHAIN,
+               Config::NAG_ALTER_DECRYPTION_CHAIN,
                _("If you continue with this operation you will no longer be able to use any DKDMs that you have created.  Also, any KDMs that have been sent to you will become useless.  Proceed with caution!"),
                true
                );
 }
 
-void
-KeysPage::export_decryption_chain ()
-{
-       wxFileDialog* d = new wxFileDialog (
-               _panel, _("Select Chain File"), wxEmptyString, _("dcpomatic_kdm_decryption_chain.pem"), wxT ("PEM files (*.pem)|*.pem"),
-               wxFD_SAVE | wxFD_OVERWRITE_PROMPT
-               );
-
-       if (d->ShowModal () == wxID_OK) {
-               boost::filesystem::path path (wx_to_std(d->GetPath()));
-               FILE* f = fopen_boost (path, "w");
-               if (!f) {
-                       throw OpenFileError (path, errno, false);
-               }
-
-               string const s = Config::instance()->decryption_chain()->chain();
-               checked_fwrite (s.c_str(), s.length(), f, path);
-               fclose (f);
-       }
-       d->Destroy ();
-}
-
 void
 KeysPage::export_decryption_certificate ()
 {
@@ -901,7 +955,7 @@ KeysPage::export_decryption_certificate ()
                boost::filesystem::path path (wx_to_std(d->GetPath()));
                FILE* f = fopen_boost (path, "w");
                if (!f) {
-                       throw OpenFileError (path, errno, false);
+                       throw OpenFileError (path, errno, OpenFileError::WRITE);
                }
 
                string const s = Config::instance()->decryption_chain()->leaf().certificate (true);