2 Copyright (C) 2012-2019 Carl Hetherington <cth@carlh.net>
4 This file is part of DCP-o-matic.
6 DCP-o-matic is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 DCP-o-matic is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with DCP-o-matic. If not, see <http://www.gnu.org/licenses/>.
22 /** @file src/player_config_dialog.cc
23 * @brief A dialogue to edit DCP-o-matic Player configuration.
27 #include "check_box.h"
28 #include "config_dialog.h"
29 #include "dir_picker_ctrl.h"
30 #include "editable_list.h"
31 #include "email_dialog.h"
32 #include "file_picker_ctrl.h"
33 #include "filter_dialog.h"
34 #include "make_chain_dialog.h"
35 #include "nag_dialog.h"
36 #include "name_format_editor.h"
37 #include "server_dialog.h"
38 #include "static_text.h"
40 #include "lib/config.h"
41 #include "lib/cross.h"
42 #include "lib/dcp_content_type.h"
43 #include "lib/exceptions.h"
44 #include "lib/filter.h"
46 #include "lib/ratio.h"
48 #include <dcp/certificate_chain.h>
49 #include <dcp/exceptions.h>
50 #include <dcp/locale_convert.h>
51 #include <wx/filepicker.h>
52 #include <wx/preferences.h>
53 #include <wx/spinctrl.h>
54 #include <wx/stdpaths.h>
56 #include <boost/filesystem.hpp>
64 using std::shared_ptr;
68 using boost::optional;
69 #if BOOST_VERSION >= 106100
70 using namespace boost::placeholders;
72 using dcp::locale_convert;
75 class PlayerGeneralPage : public GeneralPage
78 PlayerGeneralPage (wxSize panel_size, int border)
79 : GeneralPage (panel_size, border)
83 void setup () override
85 wxGridBagSizer* table = new wxGridBagSizer (DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
86 _panel->GetSizer()->Add (table, 1, wxALL | wxEXPAND, _border);
89 add_language_controls (table, r);
90 add_update_controls (table, r);
92 add_label_to_sizer (table, _panel, _("Start player as"), true, wxGBPosition(r, 0));
93 _player_mode = new wxChoice (_panel, wxID_ANY);
94 _player_mode->Append (_("window"));
95 _player_mode->Append (_("full screen"));
96 _player_mode->Append (_("full screen with controls on other monitor"));
97 table->Add (_player_mode, wxGBPosition(r, 1));
100 add_label_to_sizer (table, _panel, _("Dual-screen displays"), true, wxGBPosition(r, 0));
101 _image_display = new wxChoice (_panel, wxID_ANY);
102 _image_display->Append (_("Image on primary, controls on secondary"));
103 _image_display->Append (_("Image on secondary, controls on primary"));
104 table->Add (_image_display, wxGBPosition(r, 1));
107 add_label_to_sizer (table, _panel, _("Video display mode"), true, wxGBPosition(r, 0));
108 _video_display_mode = new wxChoice (_panel, wxID_ANY);
109 _video_display_mode->Append (_("Simple (safer)"));
110 _video_display_mode->Append (_("OpenGL (faster)"));
111 table->Add (_video_display_mode, wxGBPosition(r, 1));
114 wxStaticText* restart = add_label_to_sizer (table, _panel, _("(restart DCP-o-matic to change display mode)"), false, wxGBPosition(r, 0));
115 wxFont font = restart->GetFont();
116 font.SetStyle (wxFONTSTYLE_ITALIC);
117 font.SetPointSize (font.GetPointSize() - 1);
118 restart->SetFont (font);
121 _respect_kdm = new CheckBox (_panel, _("Respect KDM validity periods"));
122 table->Add (_respect_kdm, wxGBPosition(r, 0), wxGBSpan(1, 2));
125 add_label_to_sizer (table, _panel, _("Debug log file"), true, wxGBPosition (r, 0));
126 _debug_log_file = new FilePickerCtrl (_panel, _("Select debug log file"), "*", false, true);
127 table->Add (_debug_log_file, wxGBPosition(r, 1));
130 _player_mode->Bind (wxEVT_CHOICE, bind(&PlayerGeneralPage::player_mode_changed, this));
131 _image_display->Bind (wxEVT_CHOICE, bind(&PlayerGeneralPage::image_display_changed, this));
132 _video_display_mode->Bind (wxEVT_CHOICE, bind(&PlayerGeneralPage::video_display_mode_changed, this));
133 _respect_kdm->Bind (wxEVT_CHECKBOX, bind(&PlayerGeneralPage::respect_kdm_changed, this));
134 _debug_log_file->Bind (wxEVT_FILEPICKER_CHANGED, bind(&PlayerGeneralPage::debug_log_file_changed, this));
137 void config_changed () override
139 GeneralPage::config_changed ();
141 Config* config = Config::instance ();
143 switch (config->player_mode()) {
144 case Config::PLAYER_MODE_WINDOW:
145 checked_set (_player_mode, 0);
147 case Config::PLAYER_MODE_FULL:
148 checked_set (_player_mode, 1);
150 case Config::PLAYER_MODE_DUAL:
151 checked_set (_player_mode, 2);
155 switch (config->video_view_type()) {
156 case Config::VIDEO_VIEW_SIMPLE:
157 checked_set (_video_display_mode, 0);
159 case Config::VIDEO_VIEW_OPENGL:
160 checked_set (_video_display_mode, 1);
164 checked_set (_image_display, config->image_display());
165 checked_set (_respect_kdm, config->respect_kdm_validity_periods());
166 if (config->player_debug_log_file()) {
167 checked_set (_debug_log_file, *config->player_debug_log_file());
172 void player_mode_changed ()
174 switch (_player_mode->GetSelection()) {
176 Config::instance()->set_player_mode(Config::PLAYER_MODE_WINDOW);
179 Config::instance()->set_player_mode(Config::PLAYER_MODE_FULL);
182 Config::instance()->set_player_mode(Config::PLAYER_MODE_DUAL);
187 void image_display_changed ()
189 Config::instance()->set_image_display(_image_display->GetSelection());
192 void video_display_mode_changed ()
194 if (_video_display_mode->GetSelection() == 0) {
195 Config::instance()->set_video_view_type (Config::VIDEO_VIEW_SIMPLE);
197 Config::instance()->set_video_view_type (Config::VIDEO_VIEW_OPENGL);
201 void respect_kdm_changed ()
203 Config::instance()->set_respect_kdm_validity_periods(_respect_kdm->GetValue());
206 void debug_log_file_changed ()
208 Config::instance()->set_player_debug_log_file(wx_to_std(_debug_log_file->GetPath()));
211 wxChoice* _player_mode;
212 wxChoice* _image_display;
213 wxChoice* _video_display_mode;
214 wxCheckBox* _respect_kdm;
215 FilePickerCtrl* _debug_log_file;
219 /** @class PlayerAdvancedPage
220 * @brief Advanced page of the preferences dialog for the player.
222 class PlayerAdvancedPage : public Page
225 PlayerAdvancedPage (wxSize panel_size, int border)
226 : Page (panel_size, border)
233 wxString GetName () const override
235 return _("Advanced");
239 wxBitmap GetLargeIcon () const override
241 return wxBitmap ("advanced", wxBITMAP_TYPE_PNG_RESOURCE);
246 void add_top_aligned_label_to_sizer (wxSizer* table, wxWindow* parent, wxString text)
248 int flags = wxALIGN_TOP | wxTOP | wxLEFT;
250 flags |= wxALIGN_RIGHT;
253 wxStaticText* m = new StaticText (parent, text);
254 table->Add (m, 0, flags, DCPOMATIC_SIZER_Y_GAP);
257 void setup () override
259 auto table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
260 table->AddGrowableCol (1, 1);
261 _panel->GetSizer()->Add (table, 1, wxALL | wxEXPAND, _border);
264 add_top_aligned_label_to_sizer (table, _panel, _("Log"));
265 wxBoxSizer* t = new wxBoxSizer (wxVERTICAL);
266 _log_general = new CheckBox (_panel, _("General"));
267 t->Add (_log_general, 1, wxEXPAND | wxALL);
268 _log_warning = new CheckBox (_panel, _("Warnings"));
269 t->Add (_log_warning, 1, wxEXPAND | wxALL);
270 _log_error = new CheckBox (_panel, _("Errors"));
271 t->Add (_log_error, 1, wxEXPAND | wxALL);
272 /// TRANSLATORS: translate the word "Timing" here; do not include the "Config|" prefix
273 _log_timing = new CheckBox (_panel, S_("Config|Timing"));
274 t->Add (_log_timing, 1, wxEXPAND | wxALL);
275 table->Add (t, 0, wxALL, 6);
278 #ifdef DCPOMATIC_WINDOWS
279 _win32_console = new CheckBox (_panel, _("Open console window"));
280 table->Add (_win32_console, 1, wxEXPAND | wxALL);
281 table->AddSpacer (0);
284 _log_general->Bind (wxEVT_CHECKBOX, boost::bind (&PlayerAdvancedPage::log_changed, this));
285 _log_warning->Bind (wxEVT_CHECKBOX, boost::bind (&PlayerAdvancedPage::log_changed, this));
286 _log_error->Bind (wxEVT_CHECKBOX, boost::bind (&PlayerAdvancedPage::log_changed, this));
287 _log_timing->Bind (wxEVT_CHECKBOX, boost::bind (&PlayerAdvancedPage::log_changed, this));
288 #ifdef DCPOMATIC_WINDOWS
289 _win32_console->Bind (wxEVT_CHECKBOX, boost::bind (&PlayerAdvancedPage::win32_console_changed, this));
293 void config_changed () override
295 auto config = Config::instance ();
297 checked_set (_log_general, config->log_types() & LogEntry::TYPE_GENERAL);
298 checked_set (_log_warning, config->log_types() & LogEntry::TYPE_WARNING);
299 checked_set (_log_error, config->log_types() & LogEntry::TYPE_ERROR);
300 checked_set (_log_timing, config->log_types() & LogEntry::TYPE_TIMING);
301 #ifdef DCPOMATIC_WINDOWS
302 checked_set (_win32_console, config->win32_console());
309 if (_log_general->GetValue ()) {
310 types |= LogEntry::TYPE_GENERAL;
312 if (_log_warning->GetValue ()) {
313 types |= LogEntry::TYPE_WARNING;
315 if (_log_error->GetValue ()) {
316 types |= LogEntry::TYPE_ERROR;
318 if (_log_timing->GetValue ()) {
319 types |= LogEntry::TYPE_TIMING;
321 Config::instance()->set_log_types (types);
324 #ifdef DCPOMATIC_WINDOWS
325 void win32_console_changed ()
327 Config::instance()->set_win32_console (_win32_console->GetValue ());
331 wxCheckBox* _log_general;
332 wxCheckBox* _log_warning;
333 wxCheckBox* _log_error;
334 wxCheckBox* _log_timing;
335 #ifdef DCPOMATIC_WINDOWS
336 wxCheckBox* _win32_console;
342 create_player_config_dialog ()
344 auto e = new wxPreferencesEditor (_("DCP-o-matic Player Preferences"));
347 /* Width that we force some of the config panels to be on OSX so that
348 the containing window doesn't shrink too much when we select those panels.
349 This is obviously an unpleasant hack.
351 auto ps = wxSize (520, -1);
352 int const border = 16;
354 auto ps = wxSize (-1, -1);
355 int const border = 8;
358 e->AddPage (new PlayerGeneralPage(wxSize(-1, 500), border));
359 e->AddPage (new SoundPage(ps, border));
360 e->AddPage (new LocationsPage(ps, border));
361 e->AddPage (new KeysPage(ps, border));
362 e->AddPage (new PlayerAdvancedPage(ps, border));