2 Copyright (C) 2020 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 #include "content_advanced_dialog.h"
23 #include "dcpomatic_button.h"
24 #include "filter_dialog.h"
25 #include "static_text.h"
27 #include "lib/content.h"
28 #include "lib/dcp_content.h"
29 #include "lib/filter.h"
30 #include "lib/ffmpeg_content.h"
31 #include "lib/image_content.h"
32 #include "lib/video_content.h"
33 #include <wx/gbsizer.h>
34 #include <boost/bind.hpp>
40 using boost::dynamic_pointer_cast;
41 using boost::optional;
42 using boost::shared_ptr;
43 #if BOOST_VERSION >= 106100
44 using namespace boost::placeholders;
46 using dcp::locale_convert;
50 ContentAdvancedDialog::ContentAdvancedDialog (wxWindow* parent, shared_ptr<Content> content)
51 : wxDialog (parent, wxID_ANY, _("Advanced content settings"))
54 wxGridBagSizer* sizer = new wxGridBagSizer (DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
59 wxSize size = dc.GetTextExtent (wxT ("A quite long name"));
61 size.SetWidth (size.GetWidth() + 64);
65 add_label_to_sizer (sizer, this, _("Video filters"), true, wxGBPosition(r, 0));
66 _filters = new StaticText (this, _("None"), wxDefaultPosition, size);
67 _filters_button = new Button (this, _("Edit..."));
68 wxBoxSizer* filters = new wxBoxSizer (wxHORIZONTAL);
69 filters->Add (_filters, 1, wxALL | wxALIGN_CENTER_VERTICAL, DCPOMATIC_SIZER_GAP);
70 filters->Add (_filters_button, 0, wxALL, DCPOMATIC_SIZER_GAP);
71 sizer->Add (filters, wxGBPosition(r, 1), wxGBSpan(1, 2));
74 wxStaticText* video_frame_rate_label;
75 if (_content->video) {
76 video_frame_rate_label = add_label_to_sizer (sizer, this, _("Override detected video frame rate"), true, wxGBPosition(r, 0));
78 video_frame_rate_label = add_label_to_sizer (sizer, this, _("Video frame rate that content was prepared for"), true, wxGBPosition(r, 0));
80 _video_frame_rate = new wxTextCtrl (this, wxID_ANY);
81 sizer->Add (_video_frame_rate, wxGBPosition(r, 1));
82 _set_video_frame_rate = new Button (this, _("Set"));
83 _set_video_frame_rate->Enable (false);
84 sizer->Add (_set_video_frame_rate, wxGBPosition(r, 2));
87 wxCheckBox* ignore_video = new wxCheckBox (this, wxID_ANY, _("Ignore this content's video and use only audio, subtitles and closed captions"));
88 sizer->Add (ignore_video, wxGBPosition(r, 0), wxGBSpan(1, 3));
91 wxSizer* overall = new wxBoxSizer (wxVERTICAL);
92 overall->Add (sizer, 1, wxALL, DCPOMATIC_DIALOG_BORDER);
93 wxSizer* buttons = CreateSeparatedButtonSizer (wxOK | wxCANCEL);
95 overall->Add (buttons, wxSizerFlags().Expand().DoubleBorder());
98 SetSizerAndFit (overall);
100 ignore_video->Enable (static_cast<bool>(_content->video));
101 ignore_video->SetValue (_content->video ? !content->video->use() : false);
104 bool const single_frame_image_content = dynamic_pointer_cast<const ImageContent>(_content) && _content->number_of_paths() == 1;
105 video_frame_rate_label->Enable (!single_frame_image_content);
106 _video_frame_rate->Enable (!single_frame_image_content);
108 optional<double> vfr = _content->video_frame_rate ();
110 _video_frame_rate->SetValue (std_to_wx(locale_convert<string>(*vfr)));
113 ignore_video->Bind (wxEVT_CHECKBOX, bind(&ContentAdvancedDialog::ignore_video_changed, this, _1));
114 _filters_button->Bind (wxEVT_BUTTON, bind(&ContentAdvancedDialog::edit_filters, this));
115 _set_video_frame_rate->Bind (wxEVT_BUTTON, bind(&ContentAdvancedDialog::set_video_frame_rate, this));
116 _video_frame_rate->Bind (wxEVT_TEXT, boost::bind(&ContentAdvancedDialog::video_frame_rate_changed, this));
121 ContentAdvancedDialog::ignore_video_changed (wxCommandEvent& ev)
123 if (_content->video) {
124 _content->video->set_use (!ev.IsChecked());
130 ContentAdvancedDialog::setup_filters ()
132 shared_ptr<FFmpegContent> fcs = dynamic_pointer_cast<FFmpegContent>(_content);
134 checked_set (_filters, _("None"));
135 _filters->Enable (false);
136 _filters_button->Enable (false);
140 string p = Filter::ffmpeg_string (fcs->filters());
142 checked_set (_filters, _("None"));
144 if (p.length() > 25) {
145 p = p.substr(0, 25) + "...";
147 checked_set (_filters, p);
153 ContentAdvancedDialog::edit_filters ()
155 shared_ptr<FFmpegContent> fcs = dynamic_pointer_cast<FFmpegContent>(_content);
160 FilterDialog* d = new FilterDialog (this, fcs->filters());
161 d->ActiveChanged.connect (bind(&ContentAdvancedDialog::filters_changed, this, _1));
168 ContentAdvancedDialog::filters_changed (vector<Filter const *> filters)
170 shared_ptr<FFmpegContent> fcs = dynamic_pointer_cast<FFmpegContent>(_content);
175 fcs->set_filters (filters);
181 ContentAdvancedDialog::set_video_frame_rate ()
183 if (_video_frame_rate->GetValue() != wxT("")) {
184 _content->set_video_frame_rate (locale_convert<double>(wx_to_std(_video_frame_rate->GetValue())));
186 _content->unset_video_frame_rate ();
189 _set_video_frame_rate->Enable (false);
194 ContentAdvancedDialog::video_frame_rate_changed ()
197 /* If the user clicks "set" now, with no frame rate entered, it would unset the video
198 frame rate in the selected content. This can't be allowed for some content types.
200 if (_video_frame_rate->GetValue() == wxT("") && (dynamic_pointer_cast<DCPContent>(_content) || dynamic_pointer_cast<FFmpegContent>(_content))) {
204 _set_video_frame_rate->Enable (enable);