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 "wx_variant.h"
41 #include "lib/config.h"
42 #include "lib/cross.h"
43 #include "lib/dcp_content_type.h"
44 #include "lib/exceptions.h"
45 #include "lib/filter.h"
47 #include "lib/ratio.h"
49 #include <dcp/certificate_chain.h>
50 #include <dcp/exceptions.h>
51 #include <dcp/locale_convert.h>
52 #include <dcp/warnings.h>
53 LIBDCP_DISABLE_WARNINGS
54 #include <wx/filepicker.h>
55 #include <wx/preferences.h>
56 #include <wx/spinctrl.h>
57 #include <wx/stdpaths.h>
58 LIBDCP_ENABLE_WARNINGS
60 #include <boost/filesystem.hpp>
68 using std::shared_ptr;
72 using boost::optional;
73 #if BOOST_VERSION >= 106100
74 using namespace boost::placeholders;
76 using dcp::locale_convert;
79 class PlayerGeneralPage : public GeneralPage
82 PlayerGeneralPage (wxSize panel_size, int border)
83 : GeneralPage (panel_size, border)
87 void setup () override
89 wxGridBagSizer* table = new wxGridBagSizer (DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
90 _panel->GetSizer()->Add (table, 1, wxALL | wxEXPAND, _border);
93 add_language_controls (table, r);
94 add_update_controls (table, r);
96 add_label_to_sizer (table, _panel, _("Start player as"), true, wxGBPosition(r, 0));
97 _player_mode = new wxChoice (_panel, wxID_ANY);
98 _player_mode->Append (_("window"));
99 _player_mode->Append (_("full screen"));
100 _player_mode->Append (_("full screen with separate advanced controls"));
101 table->Add (_player_mode, wxGBPosition(r, 1));
104 add_label_to_sizer (table, _panel, _("Dual-screen displays"), true, wxGBPosition(r, 0));
105 _image_display = new wxChoice (_panel, wxID_ANY);
106 _image_display->Append (_("Image on primary, controls on secondary"));
107 _image_display->Append (_("Image on secondary, controls on primary"));
108 table->Add (_image_display, wxGBPosition(r, 1));
111 add_label_to_sizer (table, _panel, _("Video display mode"), true, wxGBPosition(r, 0));
112 _video_display_mode = new wxChoice (_panel, wxID_ANY);
113 _video_display_mode->Append (_("Simple (safer)"));
114 _video_display_mode->Append (_("OpenGL (faster)"));
115 table->Add (_video_display_mode, wxGBPosition(r, 1));
118 wxStaticText* restart = add_label_to_sizer(table, _panel, variant::wx::insert_dcpomatic_player(_("(restart %s to change display mode)")), false, wxGBPosition(r, 0));
119 wxFont font = restart->GetFont();
120 font.SetStyle (wxFONTSTYLE_ITALIC);
121 font.SetPointSize (font.GetPointSize() - 1);
122 restart->SetFont (font);
125 _respect_kdm = new CheckBox (_panel, _("Respect KDM validity periods"));
126 table->Add (_respect_kdm, wxGBPosition(r, 0), wxGBSpan(1, 2));
129 add_label_to_sizer (table, _panel, _("Debug log file"), true, wxGBPosition (r, 0));
130 _debug_log_file = new FilePickerCtrl(_panel, _("Select debug log file"), "*", false, true, "DebugLogPath");
131 table->Add (_debug_log_file, wxGBPosition(r, 1));
134 _player_mode->Bind (wxEVT_CHOICE, bind(&PlayerGeneralPage::player_mode_changed, this));
135 _image_display->Bind (wxEVT_CHOICE, bind(&PlayerGeneralPage::image_display_changed, this));
136 _video_display_mode->Bind (wxEVT_CHOICE, bind(&PlayerGeneralPage::video_display_mode_changed, this));
137 _respect_kdm->bind(&PlayerGeneralPage::respect_kdm_changed, this);
138 _debug_log_file->Bind (wxEVT_FILEPICKER_CHANGED, bind(&PlayerGeneralPage::debug_log_file_changed, this));
141 void config_changed () override
143 GeneralPage::config_changed ();
145 Config* config = Config::instance ();
147 switch (config->player_mode()) {
148 case Config::PLAYER_MODE_WINDOW:
149 checked_set (_player_mode, 0);
151 case Config::PLAYER_MODE_FULL:
152 checked_set (_player_mode, 1);
154 case Config::PLAYER_MODE_DUAL:
155 checked_set (_player_mode, 2);
159 switch (config->video_view_type()) {
160 case Config::VIDEO_VIEW_SIMPLE:
161 checked_set (_video_display_mode, 0);
163 case Config::VIDEO_VIEW_OPENGL:
164 checked_set (_video_display_mode, 1);
168 checked_set (_image_display, config->image_display());
169 checked_set (_respect_kdm, config->respect_kdm_validity_periods());
170 if (config->player_debug_log_file()) {
171 checked_set (_debug_log_file, *config->player_debug_log_file());
176 void player_mode_changed ()
178 switch (_player_mode->GetSelection()) {
180 Config::instance()->set_player_mode(Config::PLAYER_MODE_WINDOW);
183 Config::instance()->set_player_mode(Config::PLAYER_MODE_FULL);
186 Config::instance()->set_player_mode(Config::PLAYER_MODE_DUAL);
191 void image_display_changed ()
193 Config::instance()->set_image_display(_image_display->GetSelection());
196 void video_display_mode_changed ()
198 if (_video_display_mode->GetSelection() == 0) {
199 Config::instance()->set_video_view_type (Config::VIDEO_VIEW_SIMPLE);
201 Config::instance()->set_video_view_type (Config::VIDEO_VIEW_OPENGL);
205 void respect_kdm_changed ()
207 Config::instance()->set_respect_kdm_validity_periods(_respect_kdm->GetValue());
210 void debug_log_file_changed ()
212 if (auto path = _debug_log_file->path()) {
213 Config::instance()->set_player_debug_log_file(*path);
217 wxChoice* _player_mode;
218 wxChoice* _image_display;
219 wxChoice* _video_display_mode;
220 CheckBox* _respect_kdm;
221 FilePickerCtrl* _debug_log_file;
225 /** @class PlayerAdvancedPage
226 * @brief Advanced page of the preferences dialog for the player.
228 class PlayerAdvancedPage : public Page
231 PlayerAdvancedPage (wxSize panel_size, int border)
232 : Page (panel_size, border)
239 wxString GetName () const override
241 return _("Advanced");
245 wxBitmap GetLargeIcon () const override
247 return wxBitmap(icon_path("advanced"), wxBITMAP_TYPE_PNG);
252 void add_top_aligned_label_to_sizer (wxSizer* table, wxWindow* parent, wxString text)
254 int flags = wxALIGN_TOP | wxTOP | wxLEFT;
256 flags |= wxALIGN_RIGHT;
259 wxStaticText* m = new StaticText (parent, text);
260 table->Add (m, 0, flags, DCPOMATIC_SIZER_Y_GAP);
263 void setup () override
265 auto table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
266 table->AddGrowableCol (1, 1);
267 _panel->GetSizer()->Add (table, 1, wxALL | wxEXPAND, _border);
270 add_top_aligned_label_to_sizer (table, _panel, _("Log"));
271 wxBoxSizer* t = new wxBoxSizer (wxVERTICAL);
272 _log_general = new CheckBox (_panel, _("General"));
273 t->Add (_log_general, 1, wxEXPAND | wxALL);
274 _log_warning = new CheckBox (_panel, _("Warnings"));
275 t->Add (_log_warning, 1, wxEXPAND | wxALL);
276 _log_error = new CheckBox (_panel, _("Errors"));
277 t->Add (_log_error, 1, wxEXPAND | wxALL);
278 /// TRANSLATORS: translate the word "Timing" here; do not include the "Config|" prefix
279 _log_timing = new CheckBox (_panel, S_("Config|Timing"));
280 t->Add (_log_timing, 1, wxEXPAND | wxALL);
281 _log_debug_video_view = new CheckBox(_panel, _("Debug: video view"));
282 t->Add(_log_debug_video_view, 1, wxEXPAND | wxALL);
283 table->Add (t, 0, wxALL, 6);
286 #ifdef DCPOMATIC_WINDOWS
287 _win32_console = new CheckBox (_panel, _("Open console window"));
288 table->Add (_win32_console, 1, wxEXPAND | wxALL);
289 table->AddSpacer (0);
292 _log_general->bind(&PlayerAdvancedPage::log_changed, this);
293 _log_warning->bind(&PlayerAdvancedPage::log_changed, this);
294 _log_error->bind(&PlayerAdvancedPage::log_changed, this);
295 _log_timing->bind(&PlayerAdvancedPage::log_changed, this);
296 _log_debug_video_view->bind(&PlayerAdvancedPage::log_changed, this);
297 #ifdef DCPOMATIC_WINDOWS
298 _win32_console->bind(&PlayerAdvancedPage::win32_console_changed, this);
302 void config_changed () override
304 auto config = Config::instance ();
306 checked_set (_log_general, config->log_types() & LogEntry::TYPE_GENERAL);
307 checked_set (_log_warning, config->log_types() & LogEntry::TYPE_WARNING);
308 checked_set (_log_error, config->log_types() & LogEntry::TYPE_ERROR);
309 checked_set (_log_timing, config->log_types() & LogEntry::TYPE_TIMING);
310 #ifdef DCPOMATIC_WINDOWS
311 checked_set (_win32_console, config->win32_console());
318 if (_log_general->GetValue ()) {
319 types |= LogEntry::TYPE_GENERAL;
321 if (_log_warning->GetValue ()) {
322 types |= LogEntry::TYPE_WARNING;
324 if (_log_error->GetValue ()) {
325 types |= LogEntry::TYPE_ERROR;
327 if (_log_timing->GetValue ()) {
328 types |= LogEntry::TYPE_TIMING;
330 if (_log_debug_video_view->GetValue()) {
331 types |= LogEntry::TYPE_DEBUG_VIDEO_VIEW;
333 Config::instance()->set_log_types (types);
336 #ifdef DCPOMATIC_WINDOWS
337 void win32_console_changed ()
339 Config::instance()->set_win32_console (_win32_console->GetValue ());
343 CheckBox* _log_general;
344 CheckBox* _log_warning;
345 CheckBox* _log_error;
346 CheckBox* _log_timing;
347 CheckBox* _log_debug_video_view;
348 #ifdef DCPOMATIC_WINDOWS
349 CheckBox* _win32_console;
355 create_player_config_dialog ()
357 auto e = new wxPreferencesEditor(variant::wx::insert_dcpomatic_player(_("%s Preferences")));
360 /* Width that we force some of the config panels to be on OSX so that
361 the containing window doesn't shrink too much when we select those panels.
362 This is obviously an unpleasant hack.
364 auto ps = wxSize (520, -1);
365 int const border = 16;
367 auto ps = wxSize (-1, -1);
368 int const border = 8;
371 e->AddPage (new PlayerGeneralPage(wxSize(-1, 500), border));
372 e->AddPage (new SoundPage(ps, border));
373 e->AddPage (new LocationsPage(ps, border));
374 e->AddPage (new KeysPage(ps, border));
375 e->AddPage (new PlayerAdvancedPage(ps, border));