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 DCPOMATIC_DISABLE_WARNINGS
36 #include <wx/propgrid/property.h>
37 #include <wx/propgrid/props.h>
38 DCPOMATIC_ENABLE_WARNINGS
39 #include <boost/bind/bind.hpp>
45 using boost::dynamic_pointer_cast;
46 using boost::optional;
47 using boost::shared_ptr;
48 #if BOOST_VERSION >= 106100
49 using namespace boost::placeholders;
51 using dcp::locale_convert;
55 ContentAdvancedDialog::ContentAdvancedDialog (wxWindow* parent, shared_ptr<Content> content)
56 : wxDialog (parent, wxID_ANY, _("Advanced content settings"))
59 wxGridBagSizer* sizer = new wxGridBagSizer (DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
64 wxSize size = dc.GetTextExtent (wxT ("A quite long name"));
66 size.SetWidth (size.GetWidth() + 64);
70 add_label_to_sizer (sizer, this, _("Video filters"), true, wxGBPosition(r, 0));
71 _filters = new StaticText (this, _("None"), wxDefaultPosition, size);
72 _filters_button = new Button (this, _("Edit..."));
73 wxBoxSizer* filters = new wxBoxSizer (wxHORIZONTAL);
74 filters->Add (_filters, 1, wxALL | wxALIGN_CENTER_VERTICAL, DCPOMATIC_SIZER_GAP);
75 filters->Add (_filters_button, 0, wxALL, DCPOMATIC_SIZER_GAP);
76 sizer->Add (filters, wxGBPosition(r, 1), wxGBSpan(1, 2));
79 wxStaticText* video_frame_rate_label;
80 if (_content->video) {
81 video_frame_rate_label = add_label_to_sizer (sizer, this, _("Override detected video frame rate"), true, wxGBPosition(r, 0));
83 video_frame_rate_label = add_label_to_sizer (sizer, this, _("Video frame rate that content was prepared for"), true, wxGBPosition(r, 0));
85 _video_frame_rate = new wxTextCtrl (this, wxID_ANY, wxT(""), wxDefaultPosition, wxDefaultSize, 0, wxNumericPropertyValidator(wxNumericPropertyValidator::Float));
86 sizer->Add (_video_frame_rate, wxGBPosition(r, 1));
87 _set_video_frame_rate = new Button (this, _("Set"));
88 _set_video_frame_rate->Enable (false);
89 sizer->Add (_set_video_frame_rate, wxGBPosition(r, 2));
92 wxCheckBox* ignore_video = new wxCheckBox (this, wxID_ANY, _("Ignore this content's video and use only audio, subtitles and closed captions"));
93 sizer->Add (ignore_video, wxGBPosition(r, 0), wxGBSpan(1, 3));
96 wxSizer* overall = new wxBoxSizer (wxVERTICAL);
97 overall->Add (sizer, 1, wxALL, DCPOMATIC_DIALOG_BORDER);
98 wxSizer* buttons = CreateSeparatedButtonSizer (wxOK | wxCANCEL);
100 overall->Add (buttons, wxSizerFlags().Expand().DoubleBorder());
103 SetSizerAndFit (overall);
105 ignore_video->Enable (static_cast<bool>(_content->video));
106 ignore_video->SetValue (_content->video ? !content->video->use() : false);
109 bool const single_frame_image_content = dynamic_pointer_cast<const ImageContent>(_content) && _content->number_of_paths() == 1;
110 video_frame_rate_label->Enable (!single_frame_image_content);
111 _video_frame_rate->Enable (!single_frame_image_content);
113 optional<double> vfr = _content->video_frame_rate ();
115 _video_frame_rate->SetValue (std_to_wx(locale_convert<string>(*vfr)));
118 ignore_video->Bind (wxEVT_CHECKBOX, bind(&ContentAdvancedDialog::ignore_video_changed, this, _1));
119 _filters_button->Bind (wxEVT_BUTTON, bind(&ContentAdvancedDialog::edit_filters, this));
120 _set_video_frame_rate->Bind (wxEVT_BUTTON, bind(&ContentAdvancedDialog::set_video_frame_rate, this));
121 _video_frame_rate->Bind (wxEVT_TEXT, boost::bind(&ContentAdvancedDialog::video_frame_rate_changed, this));
126 ContentAdvancedDialog::ignore_video_changed (wxCommandEvent& ev)
128 if (_content->video) {
129 _content->video->set_use (!ev.IsChecked());
135 ContentAdvancedDialog::setup_filters ()
137 shared_ptr<FFmpegContent> fcs = dynamic_pointer_cast<FFmpegContent>(_content);
139 checked_set (_filters, _("None"));
140 _filters->Enable (false);
141 _filters_button->Enable (false);
145 string p = Filter::ffmpeg_string (fcs->filters());
147 checked_set (_filters, _("None"));
149 if (p.length() > 25) {
150 p = p.substr(0, 25) + "...";
152 checked_set (_filters, p);
158 ContentAdvancedDialog::edit_filters ()
160 shared_ptr<FFmpegContent> fcs = dynamic_pointer_cast<FFmpegContent>(_content);
165 FilterDialog* d = new FilterDialog (this, fcs->filters());
166 d->ActiveChanged.connect (bind(&ContentAdvancedDialog::filters_changed, this, _1));
173 ContentAdvancedDialog::filters_changed (vector<Filter const *> filters)
175 shared_ptr<FFmpegContent> fcs = dynamic_pointer_cast<FFmpegContent>(_content);
180 fcs->set_filters (filters);
186 ContentAdvancedDialog::set_video_frame_rate ()
188 if (_video_frame_rate->GetValue() != wxT("")) {
189 _content->set_video_frame_rate (locale_convert<double>(wx_to_std(_video_frame_rate->GetValue())));
191 _content->unset_video_frame_rate ();
194 _set_video_frame_rate->Enable (false);
199 ContentAdvancedDialog::video_frame_rate_changed ()
202 /* If the user clicks "set" now, with no frame rate entered, it would unset the video
203 frame rate in the selected content. This can't be allowed for some content types.
205 if (_video_frame_rate->GetValue() == wxT("") && (dynamic_pointer_cast<DCPContent>(_content) || dynamic_pointer_cast<FFmpegContent>(_content))) {
209 _set_video_frame_rate->Enable (enable);