Configurable window arrangement in player dual-screen mode.
[dcpomatic.git] / src / wx / player_config_dialog.cc
1 /*
2     Copyright (C) 2012-2017 Carl Hetherington <cth@carlh.net>
3
4     This file is part of DCP-o-matic.
5
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.
10
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.
15
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/>.
18
19 */
20
21 /** @file src/player_config_dialog.cc
22  *  @brief A dialogue to edit DCP-o-matic Player configuration.
23  */
24
25 #include "config_dialog.h"
26 #include "wx_util.h"
27 #include "editable_list.h"
28 #include "filter_dialog.h"
29 #include "dir_picker_ctrl.h"
30 #include "file_picker_ctrl.h"
31 #include "isdcf_metadata_dialog.h"
32 #include "server_dialog.h"
33 #include "make_chain_dialog.h"
34 #include "email_dialog.h"
35 #include "name_format_editor.h"
36 #include "nag_dialog.h"
37 #include "config_dialog.h"
38 #include "lib/config.h"
39 #include "lib/ratio.h"
40 #include "lib/filter.h"
41 #include "lib/dcp_content_type.h"
42 #include "lib/log.h"
43 #include "lib/util.h"
44 #include "lib/cross.h"
45 #include "lib/exceptions.h"
46 #include <dcp/locale_convert.h>
47 #include <dcp/exceptions.h>
48 #include <dcp/certificate_chain.h>
49 #include <wx/stdpaths.h>
50 #include <wx/preferences.h>
51 #include <wx/spinctrl.h>
52 #include <wx/filepicker.h>
53 #include <RtAudio.h>
54 #include <boost/filesystem.hpp>
55 #include <boost/foreach.hpp>
56 #include <iostream>
57
58 using std::vector;
59 using std::string;
60 using std::list;
61 using std::cout;
62 using std::pair;
63 using std::make_pair;
64 using std::map;
65 using boost::bind;
66 using boost::shared_ptr;
67 using boost::function;
68 using boost::optional;
69 using dcp::locale_convert;
70
71 class PlayerGeneralPage : public GeneralPage
72 {
73 public:
74         PlayerGeneralPage (wxSize panel_size, int border)
75                 : GeneralPage (panel_size, border)
76         {}
77
78 private:
79         void setup ()
80         {
81                 wxGridBagSizer* table = new wxGridBagSizer (DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
82                 _panel->GetSizer()->Add (table, 1, wxALL | wxEXPAND, _border);
83
84                 int r = 0;
85                 add_language_controls (table, r);
86                 add_play_sound_controls (table, r);
87                 add_update_controls (table, r);
88
89                 add_label_to_sizer (table, _panel, _("Start player as"), true, wxGBPosition(r, 0));
90                 _player_mode = new wxChoice (_panel, wxID_ANY);
91                 _player_mode->Append (_("window"));
92                 _player_mode->Append (_("full screen"));
93                 _player_mode->Append (_("full screen with controls on other monitor"));
94                 table->Add (_player_mode, wxGBPosition(r, 1));
95                 ++r;
96
97                 add_label_to_sizer (table, _panel, _("Displays"), true, wxGBPosition(r, 0));
98                 _image_display = new wxChoice (_panel, wxID_ANY);
99                 _image_display->Append (_("Image on primary, controls on secondary"));
100                 _image_display->Append (_("Image on secondary, controls on primary"));
101                 table->Add (_image_display, wxGBPosition(r, 1));
102                 ++r;
103
104                 _respect_kdm = new wxCheckBox (_panel, wxID_ANY, _("Respect KDM validity periods"));
105                 table->Add (_respect_kdm, wxGBPosition(r, 0), wxGBSpan(1, 2));
106                 ++r;
107
108                 add_label_to_sizer (table, _panel, _("Log file"), true, wxGBPosition (r, 0));
109                 _log_file = new FilePickerCtrl (_panel, _("Select log file"), "*", true);
110                 table->Add (_log_file, wxGBPosition (r, 1));
111                 ++r;
112
113                 _player_mode->Bind (wxEVT_CHOICE, bind(&PlayerGeneralPage::player_mode_changed, this));
114                 _image_display->Bind (wxEVT_CHOICE, bind(&PlayerGeneralPage::image_display_changed, this));
115                 _respect_kdm->Bind (wxEVT_CHECKBOX, bind(&PlayerGeneralPage::respect_kdm_changed, this));
116                 _log_file->Bind (wxEVT_FILEPICKER_CHANGED, bind(&PlayerGeneralPage::log_file_changed, this));
117         }
118
119         void config_changed ()
120         {
121                 GeneralPage::config_changed ();
122
123                 Config* config = Config::instance ();
124
125                 switch (config->player_mode()) {
126                 case Config::PLAYER_MODE_WINDOW:
127                         checked_set (_player_mode, 0);
128                         break;
129                 case Config::PLAYER_MODE_FULL:
130                         checked_set (_player_mode, 1);
131                         break;
132                 case Config::PLAYER_MODE_DUAL:
133                         checked_set (_player_mode, 2);
134                         break;
135                 }
136
137                 checked_set (_image_display, config->image_display());
138                 checked_set (_respect_kdm, config->respect_kdm_validity_periods());
139                 if (config->player_log_file()) {
140                         checked_set (_log_file, *config->player_log_file());
141                 }
142         }
143
144 private:
145         void player_mode_changed ()
146         {
147                 switch (_player_mode->GetSelection()) {
148                 case 0:
149                         Config::instance()->set_player_mode(Config::PLAYER_MODE_WINDOW);
150                         break;
151                 case 1:
152                         Config::instance()->set_player_mode(Config::PLAYER_MODE_FULL);
153                         break;
154                 case 2:
155                         Config::instance()->set_player_mode(Config::PLAYER_MODE_DUAL);
156                         break;
157                 }
158         }
159
160         void image_display_changed ()
161         {
162                 Config::instance()->set_image_display(_image_display->GetSelection());
163         }
164
165         void respect_kdm_changed ()
166         {
167                 Config::instance()->set_respect_kdm_validity_periods(_respect_kdm->GetValue());
168         }
169
170         void log_file_changed ()
171         {
172                 Config::instance()->set_player_log_file(wx_to_std(_log_file->GetPath()));
173         }
174
175         wxChoice* _player_mode;
176         wxChoice* _image_display;
177         wxCheckBox* _respect_kdm;
178         FilePickerCtrl* _log_file;
179 };
180
181 wxPreferencesEditor*
182 create_player_config_dialog ()
183 {
184         wxPreferencesEditor* e = new wxPreferencesEditor ();
185
186 #ifdef DCPOMATIC_OSX
187         /* Width that we force some of the config panels to be on OSX so that
188            the containing window doesn't shrink too much when we select those panels.
189            This is obviously an unpleasant hack.
190         */
191         wxSize ps = wxSize (520, -1);
192         int const border = 16;
193 #else
194         wxSize ps = wxSize (-1, -1);
195         int const border = 8;
196 #endif
197
198         e->AddPage (new PlayerGeneralPage (ps, border));
199         e->AddPage (new KeysPage (ps, border));
200         return e;
201 }