Fix player config window on macOS (#2376).
[dcpomatic.git] / src / wx / player_config_dialog.cc
index a34f0bd3b4a897a78c544051a5a75391c33653dd..a7bb35bda427beca8e2e4b2f68f57d1ab46c119d 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.
 
 
 */
 
+
 /** @file src/player_config_dialog.cc
  *  @brief A dialogue to edit DCP-o-matic Player configuration.
  */
 
+
+#include "check_box.h"
 #include "config_dialog.h"
-#include "wx_util.h"
+#include "dir_picker_ctrl.h"
 #include "editable_list.h"
-#include "filter_dialog.h"
+#include "email_dialog.h"
 #include "file_picker_ctrl.h"
-#include "dir_picker_ctrl.h"
-#include "isdcf_metadata_dialog.h"
-#include "server_dialog.h"
+#include "filter_dialog.h"
 #include "make_chain_dialog.h"
-#include "email_dialog.h"
-#include "name_format_editor.h"
 #include "nag_dialog.h"
-#include "config_dialog.h"
+#include "name_format_editor.h"
+#include "server_dialog.h"
+#include "static_text.h"
+#include "wx_util.h"
 #include "lib/config.h"
-#include "lib/ratio.h"
-#include "lib/filter.h"
+#include "lib/cross.h"
 #include "lib/dcp_content_type.h"
+#include "lib/exceptions.h"
+#include "lib/filter.h"
 #include "lib/log.h"
+#include "lib/ratio.h"
 #include "lib/util.h"
-#include "lib/cross.h"
-#include "lib/exceptions.h"
-#include <dcp/locale_convert.h>
-#include <dcp/exceptions.h>
 #include <dcp/certificate_chain.h>
-#include <wx/stdpaths.h>
+#include <dcp/exceptions.h>
+#include <dcp/locale_convert.h>
+#include <dcp/warnings.h>
+LIBDCP_DISABLE_WARNINGS
+#include <wx/filepicker.h>
 #include <wx/preferences.h>
 #include <wx/spinctrl.h>
-#include <wx/filepicker.h>
+#include <wx/stdpaths.h>
+LIBDCP_ENABLE_WARNINGS
 #include <RtAudio.h>
 #include <boost/filesystem.hpp>
-#include <boost/foreach.hpp>
-#include <iostream>
 
-using std::vector;
-using std::string;
+
+using std::function;
 using std::list;
-using std::cout;
-using std::pair;
 using std::make_pair;
 using std::map;
+using std::pair;
+using std::shared_ptr;
+using std::string;
+using std::vector;
 using boost::bind;
-using boost::shared_ptr;
-using boost::function;
 using boost::optional;
+#if BOOST_VERSION >= 106100
+using namespace boost::placeholders;
+#endif
 using dcp::locale_convert;
 
+
 class PlayerGeneralPage : public GeneralPage
 {
 public:
@@ -76,14 +83,13 @@ public:
        {}
 
 private:
-       void setup ()
+       void setup () override
        {
                wxGridBagSizer* table = new wxGridBagSizer (DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
                _panel->GetSizer()->Add (table, 1, wxALL | wxEXPAND, _border);
 
                int r = 0;
                add_language_controls (table, r);
-               add_play_sound_controls (table, r);
                add_update_controls (table, r);
 
                add_label_to_sizer (table, _panel, _("Start player as"), true, wxGBPosition(r, 0));
@@ -101,34 +107,37 @@ private:
                table->Add (_image_display, wxGBPosition(r, 1));
                ++r;
 
-               _respect_kdm = new wxCheckBox (_panel, wxID_ANY, _("Respect KDM validity periods"));
-               table->Add (_respect_kdm, wxGBPosition(r, 0), wxGBSpan(1, 2));
+               add_label_to_sizer (table, _panel, _("Video display mode"), true, wxGBPosition(r, 0));
+               _video_display_mode = new wxChoice (_panel, wxID_ANY);
+               _video_display_mode->Append (_("Simple (safer)"));
+               _video_display_mode->Append (_("OpenGL (faster)"));
+               table->Add (_video_display_mode, wxGBPosition(r, 1));
                ++r;
 
-               add_label_to_sizer (table, _panel, _("Log file"), true, wxGBPosition (r, 0));
-               _log_file = new FilePickerCtrl (_panel, _("Select log file"), "*", true);
-               table->Add (_log_file, wxGBPosition (r, 1));
+               wxStaticText* restart = add_label_to_sizer (table, _panel, _("(restart DCP-o-matic to change display mode)"), false, wxGBPosition(r, 0));
+               wxFont font = restart->GetFont();
+               font.SetStyle (wxFONTSTYLE_ITALIC);
+               font.SetPointSize (font.GetPointSize() - 1);
+               restart->SetFont (font);
                ++r;
 
-               add_label_to_sizer (table, _panel, _("DCP directory"), true, wxGBPosition (r, 0));
-               _dcp_directory = new wxDirPickerCtrl (_panel, wxID_ANY, wxEmptyString, wxDirSelectorPromptStr, wxDefaultPosition, wxSize (300, -1));
-               table->Add (_dcp_directory, wxGBPosition (r, 1));
+               _respect_kdm = new CheckBox (_panel, _("Respect KDM validity periods"));
+               table->Add (_respect_kdm, wxGBPosition(r, 0), wxGBSpan(1, 2));
                ++r;
 
-               add_label_to_sizer (table, _panel, _("KDM directory"), true, wxGBPosition (r, 0));
-               _kdm_directory = new wxDirPickerCtrl (_panel, wxID_ANY, wxEmptyString, wxDirSelectorPromptStr, wxDefaultPosition, wxSize (300, -1));
-               table->Add (_kdm_directory, wxGBPosition (r, 1));
+               add_label_to_sizer (table, _panel, _("Debug log file"), true, wxGBPosition (r, 0));
+               _debug_log_file = new FilePickerCtrl (_panel, _("Select debug log file"), "*", false, true);
+               table->Add (_debug_log_file, wxGBPosition(r, 1));
                ++r;
 
                _player_mode->Bind (wxEVT_CHOICE, bind(&PlayerGeneralPage::player_mode_changed, this));
                _image_display->Bind (wxEVT_CHOICE, bind(&PlayerGeneralPage::image_display_changed, this));
-               _respect_kdm->Bind (wxEVT_CHECKBOX, bind(&PlayerGeneralPage::respect_kdm_changed, this));
-               _log_file->Bind (wxEVT_FILEPICKER_CHANGED, bind(&PlayerGeneralPage::log_file_changed, this));
-               _dcp_directory->Bind (wxEVT_DIRPICKER_CHANGED, bind(&PlayerGeneralPage::dcp_directory_changed, this));
-               _kdm_directory->Bind (wxEVT_DIRPICKER_CHANGED, bind(&PlayerGeneralPage::kdm_directory_changed, this));
+               _video_display_mode->Bind (wxEVT_CHOICE, bind(&PlayerGeneralPage::video_display_mode_changed, this));
+               _respect_kdm->bind(&PlayerGeneralPage::respect_kdm_changed, this);
+               _debug_log_file->Bind (wxEVT_FILEPICKER_CHANGED, bind(&PlayerGeneralPage::debug_log_file_changed, this));
        }
 
-       void config_changed ()
+       void config_changed () override
        {
                GeneralPage::config_changed ();
 
@@ -146,16 +155,19 @@ private:
                        break;
                }
 
+               switch (config->video_view_type()) {
+               case Config::VIDEO_VIEW_SIMPLE:
+                       checked_set (_video_display_mode, 0);
+                       break;
+               case Config::VIDEO_VIEW_OPENGL:
+                       checked_set (_video_display_mode, 1);
+                       break;
+               }
+
                checked_set (_image_display, config->image_display());
                checked_set (_respect_kdm, config->respect_kdm_validity_periods());
-               if (config->player_log_file()) {
-                       checked_set (_log_file, *config->player_log_file());
-               }
-               if (config->player_dcp_directory()) {
-                       checked_set (_dcp_directory, *config->player_dcp_directory());
-               }
-               if (config->player_kdm_directory()) {
-                       checked_set (_kdm_directory, *config->player_kdm_directory());
+               if (config->player_debug_log_file()) {
+                       checked_set (_debug_log_file, *config->player_debug_log_file());
                }
        }
 
@@ -180,52 +192,176 @@ private:
                Config::instance()->set_image_display(_image_display->GetSelection());
        }
 
+       void video_display_mode_changed ()
+       {
+               if (_video_display_mode->GetSelection() == 0) {
+                       Config::instance()->set_video_view_type (Config::VIDEO_VIEW_SIMPLE);
+               } else {
+                       Config::instance()->set_video_view_type (Config::VIDEO_VIEW_OPENGL);
+               }
+       }
+
        void respect_kdm_changed ()
        {
                Config::instance()->set_respect_kdm_validity_periods(_respect_kdm->GetValue());
        }
 
-       void log_file_changed ()
+       void debug_log_file_changed ()
        {
-               Config::instance()->set_player_log_file(wx_to_std(_log_file->GetPath()));
+               Config::instance()->set_player_debug_log_file(wx_to_std(_debug_log_file->GetPath()));
        }
 
-       void dcp_directory_changed ()
+       wxChoice* _player_mode;
+       wxChoice* _image_display;
+       wxChoice* _video_display_mode;
+       CheckBox* _respect_kdm;
+       FilePickerCtrl* _debug_log_file;
+};
+
+
+/** @class PlayerAdvancedPage
+ *  @brief Advanced page of the preferences dialog for the player.
+ */
+class PlayerAdvancedPage : public Page
+{
+public:
+       PlayerAdvancedPage (wxSize panel_size, int border)
+               : Page (panel_size, border)
+               , _log_general (0)
+               , _log_warning (0)
+               , _log_error (0)
+               , _log_timing (0)
+       {}
+
+       wxString GetName () const override
        {
-               Config::instance()->set_player_dcp_directory(wx_to_std(_dcp_directory->GetPath()));
+               return _("Advanced");
        }
 
-       void kdm_directory_changed ()
+#ifdef DCPOMATIC_OSX
+       wxBitmap GetLargeIcon () const override
        {
-               Config::instance()->set_player_kdm_directory(wx_to_std(_kdm_directory->GetPath()));
+               return wxBitmap(icon_path("advanced"), wxBITMAP_TYPE_PNG);
        }
+#endif
 
-       wxChoice* _player_mode;
-       wxChoice* _image_display;
-       wxCheckBox* _respect_kdm;
-       FilePickerCtrl* _log_file;
-       wxDirPickerCtrl* _dcp_directory;
-       wxDirPickerCtrl* _kdm_directory;
+private:
+       void add_top_aligned_label_to_sizer (wxSizer* table, wxWindow* parent, wxString text)
+       {
+               int flags = wxALIGN_TOP | wxTOP | wxLEFT;
+#ifdef __WXOSX__
+               flags |= wxALIGN_RIGHT;
+               text += wxT (":");
+#endif
+               wxStaticText* m = new StaticText (parent, text);
+               table->Add (m, 0, flags, DCPOMATIC_SIZER_Y_GAP);
+       }
+
+       void setup () override
+       {
+               auto table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
+               table->AddGrowableCol (1, 1);
+               _panel->GetSizer()->Add (table, 1, wxALL | wxEXPAND, _border);
+
+               {
+                       add_top_aligned_label_to_sizer (table, _panel, _("Log"));
+                       wxBoxSizer* t = new wxBoxSizer (wxVERTICAL);
+                       _log_general = new CheckBox (_panel, _("General"));
+                       t->Add (_log_general, 1, wxEXPAND | wxALL);
+                       _log_warning = new CheckBox (_panel, _("Warnings"));
+                       t->Add (_log_warning, 1, wxEXPAND | wxALL);
+                       _log_error = new CheckBox (_panel, _("Errors"));
+                       t->Add (_log_error, 1, wxEXPAND | wxALL);
+                       /// TRANSLATORS: translate the word "Timing" here; do not include the "Config|" prefix
+                       _log_timing = new CheckBox (_panel, S_("Config|Timing"));
+                       t->Add (_log_timing, 1, wxEXPAND | wxALL);
+                       table->Add (t, 0, wxALL, 6);
+               }
+
+#ifdef DCPOMATIC_WINDOWS
+               _win32_console = new CheckBox (_panel, _("Open console window"));
+               table->Add (_win32_console, 1, wxEXPAND | wxALL);
+               table->AddSpacer (0);
+#endif
+
+               _log_general->bind(&PlayerAdvancedPage::log_changed, this);
+               _log_warning->bind(&PlayerAdvancedPage::log_changed, this);
+               _log_error->bind(&PlayerAdvancedPage::log_changed, this);
+               _log_timing->bind(&PlayerAdvancedPage::log_changed, this);
+#ifdef DCPOMATIC_WINDOWS
+               _win32_console->bind(&PlayerAdvancedPage::win32_console_changed, this);
+#endif
+       }
+
+       void config_changed () override
+       {
+               auto config = Config::instance ();
+
+               checked_set (_log_general, config->log_types() & LogEntry::TYPE_GENERAL);
+               checked_set (_log_warning, config->log_types() & LogEntry::TYPE_WARNING);
+               checked_set (_log_error, config->log_types() & LogEntry::TYPE_ERROR);
+               checked_set (_log_timing, config->log_types() & LogEntry::TYPE_TIMING);
+#ifdef DCPOMATIC_WINDOWS
+               checked_set (_win32_console, config->win32_console());
+#endif
+       }
+
+       void log_changed ()
+       {
+               int types = 0;
+               if (_log_general->GetValue ()) {
+                       types |= LogEntry::TYPE_GENERAL;
+               }
+               if (_log_warning->GetValue ()) {
+                       types |= LogEntry::TYPE_WARNING;
+               }
+               if (_log_error->GetValue ())  {
+                       types |= LogEntry::TYPE_ERROR;
+               }
+               if (_log_timing->GetValue ()) {
+                       types |= LogEntry::TYPE_TIMING;
+               }
+               Config::instance()->set_log_types (types);
+       }
+
+#ifdef DCPOMATIC_WINDOWS
+       void win32_console_changed ()
+       {
+               Config::instance()->set_win32_console (_win32_console->GetValue ());
+       }
+#endif
+
+       CheckBox* _log_general;
+       CheckBox* _log_warning;
+       CheckBox* _log_error;
+       CheckBox* _log_timing;
+#ifdef DCPOMATIC_WINDOWS
+       CheckBox* _win32_console;
+#endif
 };
 
+
 wxPreferencesEditor*
 create_player_config_dialog ()
 {
-       wxPreferencesEditor* e = new wxPreferencesEditor ();
+       auto e = new wxPreferencesEditor (_("DCP-o-matic Player Preferences"));
 
 #ifdef DCPOMATIC_OSX
        /* Width that we force some of the config panels to be on OSX so that
           the containing window doesn't shrink too much when we select those panels.
           This is obviously an unpleasant hack.
        */
-       wxSize ps = wxSize (520, -1);
+       auto ps = wxSize (520, -1);
        int const border = 16;
 #else
-       wxSize ps = wxSize (-1, -1);
+       auto ps = wxSize (-1, -1);
        int const border = 8;
 #endif
 
-       e->AddPage (new PlayerGeneralPage (ps, border));
-       e->AddPage (new KeysPage (ps, border));
+       e->AddPage (new PlayerGeneralPage(wxSize(-1, 500), border));
+       e->AddPage (new SoundPage(ps, border));
+       e->AddPage (new LocationsPage(ps, border));
+       e->AddPage (new KeysPage(ps, border));
+       e->AddPage (new PlayerAdvancedPage(ps, border));
        return e;
 }