From: Carl Hetherington Date: Sun, 14 May 2023 21:42:27 +0000 (+0200) Subject: Add Version File dialog. X-Git-Url: https://git.carlh.net/gitweb/?a=commitdiff_plain;h=4d987183766ee0d054b6462cf54afb86be1646c8;p=dcpomatic.git Add Version File dialog. --- diff --git a/src/tools/dcpomatic.cc b/src/tools/dcpomatic.cc index 956735198..3464a73d5 100644 --- a/src/tools/dcpomatic.cc +++ b/src/tools/dcpomatic.cc @@ -26,6 +26,7 @@ #include "wx/about_dialog.h" #include "wx/content_panel.h" +#include "wx/dcp_referencing_dialog.h" #include "wx/dkdm_dialog.h" #include "wx/export_subtitles_dialog.h" #include "wx/export_video_file_dialog.h" @@ -209,6 +210,7 @@ private: #define NEEDS_SELECTED_VIDEO_CONTENT 0x20 #define NEEDS_CLIPBOARD 0x40 #define NEEDS_ENCRYPTION 0x80 +#define NEEDS_DCP_CONTENT 0x100 map menu_items; @@ -238,6 +240,7 @@ enum { ID_jobs_open_dcp_in_player, ID_view_closed_captions, ID_view_video_waveform, + ID_tools_version_file, ID_tools_hints, ID_tools_encoding_servers, ID_tools_manage_templates, @@ -349,6 +352,7 @@ public: Bind (wxEVT_MENU, boost::bind (&DOMFrame::jobs_open_dcp_in_player, this), ID_jobs_open_dcp_in_player); Bind (wxEVT_MENU, boost::bind (&DOMFrame::view_closed_captions, this), ID_view_closed_captions); Bind (wxEVT_MENU, boost::bind (&DOMFrame::view_video_waveform, this), ID_view_video_waveform); + Bind (wxEVT_MENU, boost::bind (&DOMFrame::tools_version_file, this), ID_tools_version_file); Bind (wxEVT_MENU, boost::bind (&DOMFrame::tools_hints, this), ID_tools_hints); Bind (wxEVT_MENU, boost::bind (&DOMFrame::tools_encoding_servers, this), ID_tools_encoding_servers); Bind (wxEVT_MENU, boost::bind (&DOMFrame::tools_manage_templates, this), ID_tools_manage_templates); @@ -1065,6 +1069,17 @@ private: _system_information_dialog->Show (); } + void tools_version_file() + { + if (_dcp_referencing_dialog) { + _dcp_referencing_dialog->Destroy(); + _dcp_referencing_dialog = nullptr; + } + + _dcp_referencing_dialog = new DCPReferencingDialog(this, _film); + _dcp_referencing_dialog->Show(); + } + void tools_hints () { if (!_hints_dialog) { @@ -1217,6 +1232,13 @@ private: bool const have_single_selected_content = _film_editor->content_panel()->selected().size() == 1; bool const have_selected_content = !_film_editor->content_panel()->selected().empty(); bool const have_selected_video_content = !_film_editor->content_panel()->selected_video().empty(); + vector> content; + if (_film) { + content = _film->content(); + } + bool const have_dcp_content = std::find_if(content.begin(), content.end(), [](shared_ptr content) { + return static_cast(dynamic_pointer_cast(content)); + }) != content.end(); for (auto j: menu_items) { @@ -1254,6 +1276,10 @@ private: enabled = false; } + if ((j.second & NEEDS_DCP_CONTENT) && !have_dcp_content) { + enabled = false; + } + j.first->Enable (enabled); } } @@ -1387,6 +1413,7 @@ private: add_item (view, _("Video waveform..."), ID_view_video_waveform, NEEDS_FILM); auto tools = new wxMenu; + add_item (tools, _("Version File (VF)..."), ID_tools_version_file, NEEDS_FILM | NEEDS_DCP_CONTENT); add_item (tools, _("Hints..."), ID_tools_hints, NEEDS_FILM); add_item (tools, _("Encoding servers..."), ID_tools_encoding_servers, 0); add_item (tools, _("Manage templates..."), ID_tools_manage_templates, 0); @@ -1557,6 +1584,7 @@ private: StandardControls* _controls; wx_ptr _video_waveform_dialog; SystemInformationDialog* _system_information_dialog = nullptr; + DCPReferencingDialog* _dcp_referencing_dialog = nullptr; HintsDialog* _hints_dialog = nullptr; ServersListDialog* _servers_list_dialog = nullptr; wxPreferencesEditor* _config_dialog = nullptr; diff --git a/src/wx/dcp_referencing_dialog.cc b/src/wx/dcp_referencing_dialog.cc new file mode 100644 index 000000000..853391bd3 --- /dev/null +++ b/src/wx/dcp_referencing_dialog.cc @@ -0,0 +1,231 @@ +/* + Copyright (C) 2023 Carl Hetherington + + This file is part of DCP-o-matic. + + DCP-o-matic is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + DCP-o-matic is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with DCP-o-matic. If not, see . + +*/ + + +#include "check_box.h" +#include "dcp_referencing_dialog.h" +#include "static_text.h" +#include "wx_util.h" +#include "lib/dcp_content.h" +#include "lib/film.h" +#include "lib/types.h" +#include +#include + + +using std::dynamic_pointer_cast; +using std::shared_ptr; +using std::string; +using std::vector; +using std::weak_ptr; +#if BOOST_VERSION >= 106100 +using namespace boost::placeholders; +#endif + + +DCPReferencingDialog::DCPReferencingDialog(wxWindow* parent, shared_ptr film) + : wxDialog(parent, wxID_ANY, _("Version file (VF) setup")) + , _film(film) + , _dcp_grid(new wxGridBagSizer(DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP)) + , _overall_sizer(new wxBoxSizer(wxVERTICAL)) +{ + _film_connection = film->Change.connect(boost::bind(&DCPReferencingDialog::film_changed, this, _1, _2)); + _film_content_connection = film->ContentChange.connect(boost::bind(&DCPReferencingDialog::film_content_changed, this, _1, _3)); + + _overall_sizer->Add(_dcp_grid, 1, wxALL, DCPOMATIC_DIALOG_BORDER); + SetSizer(_overall_sizer); + + auto buttons = CreateSeparatedButtonSizer(wxOK); + if (buttons) { + _overall_sizer->Add(buttons, wxSizerFlags().Expand().DoubleBorder()); + } + + setup(); +} + + +void +DCPReferencingDialog::film_changed(ChangeType type, FilmProperty property) +{ + if (type != ChangeType::DONE) { + return; + } + + if ( + property == FilmProperty::INTEROP || + property == FilmProperty::RESOLUTION || + property == FilmProperty::CONTAINER || + property == FilmProperty::REEL_TYPE || + property == FilmProperty::VIDEO_FRAME_RATE || + property == FilmProperty::CONTENT) { + setup(); + } +} + + +void +DCPReferencingDialog::film_content_changed(ChangeType type, int property) +{ + if (type != ChangeType::DONE) { + return; + } + + if ( + property != DCPContentProperty::REFERENCE_VIDEO && + property != DCPContentProperty::REFERENCE_AUDIO && + property != DCPContentProperty::REFERENCE_TEXT) { + setup(); + } +} + + +void +DCPReferencingDialog::setup() +{ + _dcps.clear(); + _dcp_grid->Clear(true); + + int column = 0; + for (auto const& heading: { _("DCP"), _("Picture"), _("Sound"), _("Subtitles"), _("Closed captions") }) { + auto text = new StaticText(this, heading); + wxFont font(*wxNORMAL_FONT); + font.SetWeight(wxFONTWEIGHT_BOLD); + text->SetFont(font); + _dcp_grid->Add(text, wxGBPosition(0, column), wxDefaultSpan, wxALL, DCPOMATIC_SIZER_GAP); + ++column; + }; + + auto const all_parts = { Part::VIDEO, Part::AUDIO, Part::SUBTITLES, Part::CLOSED_CAPTIONS }; + + int row = 1; + for (auto& content: _film->content()) { + auto dcp_content = dynamic_pointer_cast(content); + if (!dcp_content) { + continue; + } + + DCP record; + record.content = dcp_content; + _dcp_grid->Add(new StaticText(this, std_to_wx(dcp_content->name())), wxGBPosition(row, 0)); + column = 1; + for (auto const& part: all_parts) { + record.check_box[part] = new CheckBox(this, wxT("")); + switch (part) { + case Part::VIDEO: + record.check_box[part]->set(dcp_content->reference_video()); + break; + case Part::AUDIO: + record.check_box[part]->set(dcp_content->reference_audio()); + break; + case Part::SUBTITLES: + record.check_box[part]->set(dcp_content->reference_text(TextType::OPEN_SUBTITLE)); + break; + case Part::CLOSED_CAPTIONS: + record.check_box[part]->set(dcp_content->reference_text(TextType::CLOSED_CAPTION)); + break; + default: + DCPOMATIC_ASSERT(false); + } + record.check_box[part]->bind(&DCPReferencingDialog::checkbox_changed, this, weak_ptr(dcp_content), record.check_box[part], part); + _dcp_grid->Add(record.check_box[part], wxGBPosition(row, column++), wxDefaultSpan, wxALIGN_CENTER); + } + ++row; + + auto add_problem = [this, &row](wxString const& cannot, string why_not) { + auto reason = new StaticText(this, cannot + wxT(": ") + std_to_wx(why_not)); + wxFont font(*wxNORMAL_FONT); + font.SetStyle(wxFONTSTYLE_ITALIC); + reason->SetFont(font); + _dcp_grid->Add(reason, wxGBPosition(row, 0), wxGBSpan(1, 5), wxLEFT, DCPOMATIC_SIZER_X_GAP * 4); + ++row; + }; + + string why_not; + + if (!dcp_content->can_reference_anything(_film, why_not)) { + for (auto const& part: all_parts) { + record.check_box[part]->Enable(false); + } + add_problem(_("Cannot reference this DCP"), why_not); + } else { + if (!dcp_content->can_reference_video(_film, why_not)) { + record.check_box[Part::VIDEO]->Enable(false); + if (dcp_content->video) { + add_problem(_("Cannot reference this DCP's video"), why_not); + } + } + + if (!dcp_content->can_reference_audio(_film, why_not)) { + record.check_box[Part::AUDIO]->Enable(false); + if (dcp_content->audio) { + add_problem(_("Cannot reference this DCP's audio"), why_not); + } + } + + if (!dcp_content->can_reference_text(_film, TextType::OPEN_SUBTITLE, why_not)) { + record.check_box[Part::SUBTITLES]->Enable(false); + if (dcp_content->text_of_original_type(TextType::OPEN_SUBTITLE)) { + add_problem(_("Cannot reference this DCP's subtitles"), why_not); + } + } + + if (!dcp_content->can_reference_text(_film, TextType::CLOSED_CAPTION, why_not)) { + record.check_box[Part::CLOSED_CAPTIONS]->Enable(false); + if (dcp_content->text_of_original_type(TextType::CLOSED_CAPTION)) { + add_problem(_("Cannot reference this DCP's closed captions"), why_not); + } + } + } + + _dcps.push_back(record); + } + + _dcp_grid->Layout(); + _overall_sizer->Layout(); + _overall_sizer->SetSizeHints(this); +} + + +void +DCPReferencingDialog::checkbox_changed(weak_ptr weak_content, CheckBox* check_box, Part part) +{ + auto content = weak_content.lock(); + if (!content) { + return; + } + + switch (part) { + case Part::VIDEO: + content->set_reference_video(check_box->get()); + break; + case Part::AUDIO: + content->set_reference_audio(check_box->get()); + break; + case Part::SUBTITLES: + content->set_reference_text(TextType::OPEN_SUBTITLE, check_box->get()); + break; + case Part::CLOSED_CAPTIONS: + content->set_reference_text(TextType::CLOSED_CAPTION, check_box->get()); + break; + default: + DCPOMATIC_ASSERT(false); + } +} + diff --git a/src/wx/dcp_referencing_dialog.h b/src/wx/dcp_referencing_dialog.h new file mode 100644 index 000000000..e49292c22 --- /dev/null +++ b/src/wx/dcp_referencing_dialog.h @@ -0,0 +1,70 @@ +/* + Copyright (C) 2023 Carl Hetherington + + This file is part of DCP-o-matic. + + DCP-o-matic is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + DCP-o-matic is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with DCP-o-matic. If not, see . + +*/ + + +#include "lib/enum_indexed_vector.h" +#include "lib/film.h" +#include +#include +#include + + +class CheckBox; +class DCPContent; +class Film; +class wxBoxSizer; +class wxGridBagSizer; + + +class DCPReferencingDialog : public wxDialog +{ +public: + DCPReferencingDialog(wxWindow* parent, std::shared_ptr film); + +private: + enum class Part { + VIDEO, + AUDIO, + SUBTITLES, + CLOSED_CAPTIONS, + COUNT + }; + + void setup(); + void checkbox_changed(std::weak_ptr content, CheckBox* check_box, Part part); + void film_changed(ChangeType type, FilmProperty property); + void film_content_changed(ChangeType type, int property); + + std::shared_ptr _film; + + wxGridBagSizer* _dcp_grid; + wxBoxSizer* _overall_sizer; + + struct DCP { + std::shared_ptr content; + EnumIndexedVector check_box; + }; + + std::vector _dcps; + + boost::signals2::scoped_connection _film_connection; + boost::signals2::scoped_connection _film_content_connection; +}; + diff --git a/src/wx/wscript b/src/wx/wscript index 9c6ea6b84..7dbd214c6 100644 --- a/src/wx/wscript +++ b/src/wx/wscript @@ -53,6 +53,7 @@ sources = """ controls.cc credentials_download_certificate_panel.cc custom_scale_dialog.cc + dcp_referencing_dialog.cc dcp_panel.cc dcp_text_track_dialog.cc dcpomatic_button.cc