Set up new watermark config.
[dcpomatic.git] / src / wx / player_config_dialog.cc
1 /*
2     Copyright (C) 2012-2018 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 "file_picker_ctrl.h"
30 #include "dir_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, _("Dual-screen 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                 add_label_to_sizer (table, _panel, _("DCP directory"), true, wxGBPosition (r, 0));
114                 _dcp_directory = new wxDirPickerCtrl (_panel, wxID_ANY, wxEmptyString, wxDirSelectorPromptStr, wxDefaultPosition, wxSize (300, -1));
115                 table->Add (_dcp_directory, wxGBPosition (r, 1));
116                 ++r;
117
118                 add_label_to_sizer (table, _panel, _("KDM directory"), true, wxGBPosition (r, 0));
119                 _kdm_directory = new wxDirPickerCtrl (_panel, wxID_ANY, wxEmptyString, wxDirSelectorPromptStr, wxDefaultPosition, wxSize (300, -1));
120                 table->Add (_kdm_directory, wxGBPosition (r, 1));
121                 ++r;
122
123 #ifdef DCPOMATIC_VARIANT_SWAROOP
124                 add_label_to_sizer (table, _panel, _("Background image"), true, wxGBPosition (r, 0));
125                 _background_image = new FilePickerCtrl (_panel, _("Select image file"), "*.png;*.jpg;*.jpeg;*.tif;*.tiff", true);
126                 table->Add (_background_image, wxGBPosition (r, 1));
127                 ++r;
128
129                 add_label_to_sizer (table, _panel, _("KDM server URL"), true, wxGBPosition(r, 0));
130                 _kdm_server_url = new wxTextCtrl (_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(400, -1));
131                 table->Add (_kdm_server_url, wxGBPosition (r, 1));
132                 ++r;
133 #endif
134
135                 _player_mode->Bind (wxEVT_CHOICE, bind(&PlayerGeneralPage::player_mode_changed, this));
136                 _image_display->Bind (wxEVT_CHOICE, bind(&PlayerGeneralPage::image_display_changed, this));
137                 _respect_kdm->Bind (wxEVT_CHECKBOX, bind(&PlayerGeneralPage::respect_kdm_changed, this));
138                 _log_file->Bind (wxEVT_FILEPICKER_CHANGED, bind(&PlayerGeneralPage::log_file_changed, this));
139                 _dcp_directory->Bind (wxEVT_DIRPICKER_CHANGED, bind(&PlayerGeneralPage::dcp_directory_changed, this));
140                 _kdm_directory->Bind (wxEVT_DIRPICKER_CHANGED, bind(&PlayerGeneralPage::kdm_directory_changed, this));
141 #ifdef DCPOMATIC_VARIANT_SWAROOP
142                 _background_image->Bind (wxEVT_FILEPICKER_CHANGED, bind(&PlayerGeneralPage::background_image_changed, this));
143                 _kdm_server_url->Bind (wxEVT_TEXT, bind(&PlayerGeneralPage::kdm_server_url_changed, this));
144 #endif
145         }
146
147         void config_changed ()
148         {
149                 GeneralPage::config_changed ();
150
151                 Config* config = Config::instance ();
152
153                 switch (config->player_mode()) {
154                 case Config::PLAYER_MODE_WINDOW:
155                         checked_set (_player_mode, 0);
156                         break;
157                 case Config::PLAYER_MODE_FULL:
158                         checked_set (_player_mode, 1);
159                         break;
160                 case Config::PLAYER_MODE_DUAL:
161                         checked_set (_player_mode, 2);
162                         break;
163                 }
164
165                 checked_set (_image_display, config->image_display());
166                 checked_set (_respect_kdm, config->respect_kdm_validity_periods());
167                 if (config->player_log_file()) {
168                         checked_set (_log_file, *config->player_log_file());
169                 }
170                 if (config->player_dcp_directory()) {
171                         checked_set (_dcp_directory, *config->player_dcp_directory());
172                 }
173                 if (config->player_kdm_directory()) {
174                         checked_set (_kdm_directory, *config->player_kdm_directory());
175                 }
176 #ifdef DCPOMATIC_VARIANT_SWAROOP
177                 if (config->player_background_image()) {
178                         checked_set (_background_image, *config->player_background_image());
179                 }
180                 checked_set (_kdm_server_url, config->kdm_server_url());
181 #endif
182         }
183
184 private:
185         void player_mode_changed ()
186         {
187                 switch (_player_mode->GetSelection()) {
188                 case 0:
189                         Config::instance()->set_player_mode(Config::PLAYER_MODE_WINDOW);
190                         break;
191                 case 1:
192                         Config::instance()->set_player_mode(Config::PLAYER_MODE_FULL);
193                         break;
194                 case 2:
195                         Config::instance()->set_player_mode(Config::PLAYER_MODE_DUAL);
196                         break;
197                 }
198         }
199
200         void image_display_changed ()
201         {
202                 Config::instance()->set_image_display(_image_display->GetSelection());
203         }
204
205         void respect_kdm_changed ()
206         {
207                 Config::instance()->set_respect_kdm_validity_periods(_respect_kdm->GetValue());
208         }
209
210         void log_file_changed ()
211         {
212                 Config::instance()->set_player_log_file(wx_to_std(_log_file->GetPath()));
213         }
214
215         void dcp_directory_changed ()
216         {
217                 Config::instance()->set_player_dcp_directory(wx_to_std(_dcp_directory->GetPath()));
218         }
219
220         void kdm_directory_changed ()
221         {
222                 Config::instance()->set_player_kdm_directory(wx_to_std(_kdm_directory->GetPath()));
223         }
224
225 #ifdef DCPOMATIC_VARIANT_SWAROOP
226         void background_image_changed ()
227         {
228                 Config::instance()->set_player_background_image(wx_to_std(_background_image->GetPath()));
229         }
230
231         void kdm_server_url_changed ()
232         {
233                 Config::instance()->set_kdm_server_url(wx_to_std(_kdm_server_url->GetValue()));
234         }
235 #endif
236
237         wxChoice* _player_mode;
238         wxChoice* _image_display;
239         wxCheckBox* _respect_kdm;
240         FilePickerCtrl* _log_file;
241         wxDirPickerCtrl* _dcp_directory;
242         wxDirPickerCtrl* _kdm_directory;
243 #ifdef DCPOMATIC_VARIANT_SWAROOP
244         FilePickerCtrl* _background_image;
245         wxTextCtrl* _kdm_server_url;
246 #endif
247 };
248
249 #ifdef DCPOMATIC_VARIANT_SWAROOP
250 class WatermarkPage : public StandardPage
251 {
252 public:
253         WatermarkPage (wxSize panel_size, int border)
254                 : StandardPage (panel_size, border)
255         {}
256
257         wxString GetName () const
258         {
259                 return _("Watermark");
260         }
261
262 private:
263         void setup ()
264         {
265                 wxGridBagSizer* table = new wxGridBagSizer (DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
266                 _panel->GetSizer()->Add (table, 1, wxALL | wxEXPAND, _border);
267
268                 int r = 0;
269
270                 add_label_to_sizer (table, _panel, _("Theatre name"), true, wxGBPosition(r, 0));
271                 _theatre = new wxTextCtrl (_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(300, -1));
272                 table->Add (_theatre, wxGBPosition(r, 1), wxGBSpan(1, 2));
273                 ++r;
274
275                 add_label_to_sizer (table, _panel, _("Period"), true, wxGBPosition(r, 0));
276                 _period = new wxSpinCtrl (_panel, wxID_ANY);
277                 _period->SetRange (1, 60);
278                 table->Add (_period, wxGBPosition(r, 1));
279                 add_label_to_sizer (table, _panel, _("minutes"), false, wxGBPosition(r, 2));
280                 ++r;
281
282                 add_label_to_sizer (table, _panel, _("Duration"), true, wxGBPosition(r, 0));
283                 _duration = new wxSpinCtrl (_panel, wxID_ANY);
284                 _duration->SetRange (1, 200);
285                 table->Add (_duration, wxGBPosition(r, 1));
286                 add_label_to_sizer (table, _panel, _("milliseconds"), false, wxGBPosition(r, 2));
287                 ++r;
288
289                 _theatre->Bind (wxEVT_TEXT, bind(&WatermarkPage::theatre_changed, this));
290                 _duration->Bind (wxEVT_SPINCTRL, bind(&WatermarkPage::duration_changed, this));
291                 _period->Bind (wxEVT_SPINCTRL, bind(&WatermarkPage::period_changed, this));
292         }
293
294         void config_changed ()
295         {
296                 Config* config = Config::instance ();
297                 checked_set (_theatre, config->player_watermark_theatre());
298                 checked_set (_duration, config->player_watermark_duration());
299                 checked_set (_period, config->player_watermark_period());
300         }
301
302         void theatre_changed ()
303         {
304                 Config::instance()->set_player_watermark_theatre(wx_to_std(_theatre->GetValue()));
305         }
306
307         void period_changed ()
308         {
309                 Config::instance()->set_player_watermark_period(_period->GetValue());
310         }
311
312         void duration_changed ()
313         {
314                 Config::instance()->set_player_watermark_duration(_duration->GetValue());
315         }
316
317         wxTextCtrl* _theatre;
318         wxSpinCtrl* _period;
319         wxSpinCtrl* _duration;
320 };
321 #endif
322
323 wxPreferencesEditor*
324 create_player_config_dialog ()
325 {
326         wxPreferencesEditor* e = new wxPreferencesEditor ();
327
328 #ifdef DCPOMATIC_OSX
329         /* Width that we force some of the config panels to be on OSX so that
330            the containing window doesn't shrink too much when we select those panels.
331            This is obviously an unpleasant hack.
332         */
333         wxSize ps = wxSize (520, -1);
334         int const border = 16;
335 #else
336         wxSize ps = wxSize (-1, -1);
337         int const border = 8;
338 #endif
339
340         e->AddPage (new PlayerGeneralPage (ps, border));
341         e->AddPage (new KeysPage (ps, border));
342 #ifdef DCPOMATIC_VARIANT_SWAROOP
343         e->AddPage (new WatermarkPage (ps, border));
344 #endif
345         return e;
346 }