From e0a70cd5cfb11fc2de167f3146acdd437a6faa82 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Tue, 23 Mar 2021 00:50:11 +0100 Subject: [PATCH] Put subtitle language back into content from the film (#1930). This also adds the main/additional language flag. Of all the considerations about how to specify subtitle language, the most important seems to be that the language specification happens for the content where the language is; i.e. in the content text tab. --- src/lib/content.h | 2 +- src/lib/film.cc | 94 ++++++++------------------- src/lib/film.h | 9 +-- src/lib/reel_writer.cc | 10 +-- src/lib/subtitle_encoder.cc | 10 +-- src/lib/text_content.cc | 49 +++++++++++++-- src/lib/text_content.h | 25 +++++++- src/lib/writer.cc | 12 ++-- src/wx/dcp_panel.cc | 2 + src/wx/dcp_text_track_dialog.cc | 3 +- src/wx/interop_metadata_dialog.cc | 78 ++++++----------------- src/wx/interop_metadata_dialog.h | 8 +-- src/wx/language_tag_dialog.cc | 1 + src/wx/language_tag_widget.cc | 34 ++++++++-- src/wx/language_tag_widget.h | 9 +-- src/wx/smpte_metadata_dialog.cc | 101 +----------------------------- src/wx/smpte_metadata_dialog.h | 10 +-- src/wx/text_panel.cc | 95 +++++++++++++++++++++++----- src/wx/text_panel.h | 10 ++- test/isdcf_name_test.cc | 2 +- test/subtitle_language_test.cc | 19 +++--- test/subtitle_metadata_test.cc | 33 +++------- 22 files changed, 280 insertions(+), 336 deletions(-) diff --git a/src/lib/content.h b/src/lib/content.h index b8626e212..567cd5c1f 100644 --- a/src/lib/content.h +++ b/src/lib/content.h @@ -196,7 +196,7 @@ public: std::shared_ptr video; std::shared_ptr audio; - std::list > text; + std::list> text; std::shared_ptr atmos; std::shared_ptr only_text () const; diff --git a/src/lib/film.cc b/src/lib/film.cc index 46074e2ad..763af8f8a 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -496,9 +496,6 @@ Film::metadata (bool with_content_paths) const } root->add_child("UserExplicitContainer")->add_child_text(_user_explicit_container ? "1" : "0"); root->add_child("UserExplicitResolution")->add_child_text(_user_explicit_resolution ? "1" : "0"); - for (auto i: _subtitle_languages) { - root->add_child("SubtitleLanguage")->add_child_text(i.to_string()); - } _playlist->as_xml (root->add_child ("Playlist"), with_content_paths); return doc; @@ -680,10 +677,6 @@ Film::read_metadata (optional path) _user_explicit_container = f.optional_bool_child("UserExplicitContainer").get_value_or(true); _user_explicit_resolution = f.optional_bool_child("UserExplicitResolution").get_value_or(true); - for (auto i: f.node_children("SubtitleLanguage")) { - _subtitle_languages.push_back (dcp::LanguageTag(i->content())); - } - list notes; _playlist->set_from_xml (shared_from_this(), f.node_child ("Playlist"), _state_version, notes); @@ -692,41 +685,6 @@ Film::read_metadata (optional path) set_backtrace_file (file ("backtrace.txt")); } - /* Around 2.15.108 we removed subtitle language state from the text content and the ISDCF - * metadata and put it into the Film instead. If we've loaded an old Film let's try and fish - * out the settings from where they were so that they don't get lost. - */ - - optional found_language; - - for (auto i: f.node_child("Playlist")->node_children("Content")) { - auto text = i->optional_node_child("Text"); - if (text && text->optional_string_child("Language") && !found_language) { - try { - found_language = dcp::LanguageTag(text->string_child("Language")); - } catch (...) {} - } - } - - if (_state_version >= 9) { - auto isdcf_language = f.node_child("ISDCFMetadata")->optional_string_child("SubtitleLanguage"); - if (isdcf_language && !found_language) { - try { - found_language = dcp::LanguageTag(*isdcf_language); - } catch (...) { - try { - found_language = dcp::LanguageTag(boost::algorithm::to_lower_copy(*isdcf_language)); - } catch (...) { - - } - } - } - } - - if (found_language) { - _subtitle_languages.push_back (*found_language); - } - _dirty = false; return notes; } @@ -793,6 +751,30 @@ Film::mapped_audio_channels () const return mapped; } + +pair, vector> +Film::subtitle_languages () const +{ + pair, vector> result; + for (auto i: content()) { + for (auto j: i->text) { + if (j->use() && j->type() == TextType::OPEN_SUBTITLE && j->language()) { + if (j->language_is_additional()) { + result.second.push_back (j->language().get()); + } else { + result.first = j->language().get(); + } + } + } + } + + std::sort (result.second.begin(), result.second.end()); + auto last = std::unique (result.second.begin(), result.second.end()); + result.second.erase (last, result.second.end()); + return result; +} + + /** @return a ISDCF-compliant name for a DCP of this film */ string Film::isdcf_name (bool if_created_now) const @@ -924,8 +906,9 @@ Film::isdcf_name (bool if_created_now) const } } - if (!_subtitle_languages.empty()) { - auto lang = _subtitle_languages.front().language().get_value_or("en").subtag(); + auto sublangs = subtitle_languages(); + if (sublangs.first && sublangs.first->language()) { + auto lang = sublangs.first->language()->subtag(); if (burnt_in) { transform (lang.begin(), lang.end(), lang.begin(), ::tolower); } else { @@ -2037,29 +2020,6 @@ Film::set_luminance (optional l) } -void -Film::set_subtitle_language (dcp::LanguageTag language) -{ - set_subtitle_languages ({language}); -} - - -void -Film::unset_subtitle_language () -{ - FilmChangeSignaller ch (this, Property::SUBTITLE_LANGUAGES); - _subtitle_languages.clear(); -} - - -void -Film::set_subtitle_languages (vector languages) -{ - FilmChangeSignaller ch (this, Property::SUBTITLE_LANGUAGES); - _subtitle_languages = languages; -} - - void Film::set_facility (optional f) { diff --git a/src/lib/film.h b/src/lib/film.h index 9b45fd073..9feb5d0d3 100644 --- a/src/lib/film.h +++ b/src/lib/film.h @@ -184,6 +184,7 @@ public: std::list reels () const; std::list mapped_audio_channels () const; + std::pair, std::vector> subtitle_languages () const; std::string content_summary (dcpomatic::DCPTimePeriod period) const; @@ -376,10 +377,6 @@ public: return _luminance; } - std::vector subtitle_languages () const { - return _subtitle_languages; - } - /* SET */ void set_directory (boost::filesystem::path); @@ -421,9 +418,6 @@ public: void set_facility (boost::optional f = boost::none); void set_distributor (boost::optional d = boost::none); void set_luminance (boost::optional l = boost::none); - void set_subtitle_language (dcp::LanguageTag language); - void unset_subtitle_language (); - void set_subtitle_languages (std::vector languages); void add_ffoc_lfoc (Markers& markers) const; @@ -529,7 +523,6 @@ private: boost::optional _distributor; boost::optional _facility; boost::optional _luminance; - std::vector _subtitle_languages; int _state_version; diff --git a/src/lib/reel_writer.cc b/src/lib/reel_writer.cc index 366e6edc6..2c55f0f06 100644 --- a/src/lib/reel_writer.cc +++ b/src/lib/reel_writer.cc @@ -623,8 +623,8 @@ ReelWriter::create_reel_text ( if (subtitle) { /* We have a subtitle asset that we either made or are referencing */ - if (!film()->subtitle_languages().empty()) { - subtitle->set_language (film()->subtitle_languages().front()); + if (auto main_language = film()->subtitle_languages().first) { + subtitle->set_language (*main_language); } } else if (ensure_subtitles) { /* We had no subtitle asset, but we've been asked to make sure there is one */ @@ -776,7 +776,7 @@ ReelWriter::empty_text_asset (TextType type, optional track) const auto s = make_shared(); s->set_movie_title (film()->name()); if (type == TextType::OPEN_SUBTITLE) { - s->set_language (lang.empty() ? "Unknown" : lang.front().to_string()); + s->set_language (lang.first ? lang.first->to_string() : "Unknown"); } else if (!track->language.empty()) { s->set_language (track->language); } @@ -786,8 +786,8 @@ ReelWriter::empty_text_asset (TextType type, optional track) const auto s = make_shared(); s->set_content_title_text (film()->name()); s->set_metadata (mxf_metadata()); - if (type == TextType::OPEN_SUBTITLE && !lang.empty()) { - s->set_language (lang.front()); + if (type == TextType::OPEN_SUBTITLE && lang.first) { + s->set_language (*lang.first); } else if (track && !track->language.empty()) { s->set_language (dcp::LanguageTag(track->language)); } diff --git a/src/lib/subtitle_encoder.cc b/src/lib/subtitle_encoder.cc index 3721ee02b..b61876ad6 100644 --- a/src/lib/subtitle_encoder.cc +++ b/src/lib/subtitle_encoder.cc @@ -135,20 +135,20 @@ SubtitleEncoder::text (PlayerText subs, TextType type, optional tr if (!_assets[_reel_index].first) { shared_ptr asset; - vector lang = _film->subtitle_languages (); + auto lang = _film->subtitle_languages (); if (_film->interop ()) { auto s = make_shared(); s->set_movie_title (_film->name()); - if (!lang.empty()) { - s->set_language (lang.front().to_string()); + if (lang.first) { + s->set_language (lang.first->to_string()); } s->set_reel_number (raw_convert(_reel_index + 1)); _assets[_reel_index].first = s; } else { auto s = make_shared(); s->set_content_title_text (_film->name()); - if (!lang.empty()) { - s->set_language (lang.front()); + if (lang.first) { + s->set_language (*lang.first); } else if (!track->language.empty()) { s->set_language (dcp::LanguageTag(track->language)); } diff --git a/src/lib/text_content.cc b/src/lib/text_content.cc index 0c25e5696..c86150881 100644 --- a/src/lib/text_content.cc +++ b/src/lib/text_content.cc @@ -18,6 +18,7 @@ */ + #include "text_content.h" #include "util.h" #include "exceptions.h" @@ -30,6 +31,7 @@ #include "i18n.h" + using std::string; using std::vector; using std::cout; @@ -41,6 +43,7 @@ using boost::optional; using dcp::raw_convert; using namespace dcpomatic; + int const TextContentProperty::X_OFFSET = 500; int const TextContentProperty::Y_OFFSET = 501; int const TextContentProperty::X_SCALE = 502; @@ -57,6 +60,9 @@ int const TextContentProperty::FADE_OUT = 512; int const TextContentProperty::OUTLINE_WIDTH = 513; int const TextContentProperty::TYPE = 514; int const TextContentProperty::DCP_TRACK = 515; +int const TextContentProperty::LANGUAGE = 516; +int const TextContentProperty::LANGUAGE_IS_ADDITIONAL = 517; + TextContent::TextContent (Content* parent, TextType type, TextType original_type) : ContentPart (parent) @@ -95,9 +101,7 @@ TextContent::from_xml (Content* parent, cxml::ConstNodePtr node, int version) if (!node->optional_number_child("SubtitleXOffset") && !node->optional_number_child("SubtitleOffset")) { return {}; } - list> c; - c.push_back (make_shared(parent, node, version)); - return c; + return { make_shared(parent, node, version) }; } if (!node->optional_node_child("Text")) { @@ -124,6 +128,7 @@ TextContent::TextContent (Content* parent, cxml::ConstNodePtr node, int version) , _outline_width (node->optional_number_child("OutlineWidth").get_value_or(4)) , _type (TextType::OPEN_SUBTITLE) , _original_type (TextType::OPEN_SUBTITLE) + , _language ("en-US") { if (version >= 37) { _use = node->bool_child ("Use"); @@ -231,6 +236,13 @@ TextContent::TextContent (Content* parent, cxml::ConstNodePtr node, int version) if (dt) { _dcp_track = DCPTextTrack (dt); } + + auto lang = node->optional_node_child("Language"); + if (lang) { + _language = dcp::LanguageTag(lang->content()); + auto add = lang->optional_bool_attribute("Additional"); + _language_is_additional = add && *add; + } } TextContent::TextContent (Content* parent, vector> c) @@ -290,6 +302,14 @@ TextContent::TextContent (Content* parent, vector> c) throw JoinError (_("Content to be joined must use the same DCP track.")); } + if (c[i]->only_text()->language() != ref->language()) { + throw JoinError (_("Content to be joined must use the same text language.")); + } + + if (c[i]->only_text()->language_is_additional() != ref->language_is_additional()) { + throw JoinError (_("Content to be joined must both be main subtitle languages or both additional.")); + } + auto j = ref_fonts.begin (); auto k = fonts.begin (); @@ -316,6 +336,8 @@ TextContent::TextContent (Content* parent, vector> c) _type = ref->type (); _original_type = ref->original_type (); _dcp_track = ref->dcp_track (); + _language = ref->language (); + _language_is_additional = ref->language_is_additional (); connect_to_fonts (); } @@ -375,6 +397,11 @@ TextContent::as_xml (xmlpp::Node* root) const if (_dcp_track) { _dcp_track->as_xml(text->add_child("DCPTrack")); } + if (_language) { + auto lang = text->add_child("Language"); + lang->add_child_text (_language->to_string()); + lang->set_attribute ("Additional", _language_is_additional ? "1" : "0"); + } } string @@ -400,7 +427,7 @@ TextContent::identifier () const s += "_" + f->file().get_value_or("Default").string(); } - /* The DCP track is for metadata only, and doesn't affect how this content looks */ + /* The DCP track and language are for metadata only, and don't affect how this content looks */ return s; } @@ -559,6 +586,18 @@ TextContent::unset_dcp_track () maybe_set (_dcp_track, optional(), TextContentProperty::DCP_TRACK); } +void +TextContent::set_language (optional language) +{ + maybe_set (_language, language, TextContentProperty::LANGUAGE); +} + +void +TextContent::set_language_is_additional (bool additional) +{ + maybe_set (_language_is_additional, additional, TextContentProperty::LANGUAGE_IS_ADDITIONAL); +} + void TextContent::take_settings_from (shared_ptr c) { @@ -595,4 +634,6 @@ TextContent::take_settings_from (shared_ptr c) } else { unset_dcp_track (); } + set_language (c->_language); + set_language_is_additional (c->_language_is_additional); } diff --git a/src/lib/text_content.h b/src/lib/text_content.h index e566d0552..4c6918a42 100644 --- a/src/lib/text_content.h +++ b/src/lib/text_content.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2013-2020 Carl Hetherington + Copyright (C) 2013-2021 Carl Hetherington This file is part of DCP-o-matic. @@ -18,15 +18,19 @@ */ + #ifndef DCPOMATIC_CAPTION_CONTENT_H #define DCPOMATIC_CAPTION_CONTENT_H + #include "content_part.h" #include "dcp_text_track.h" #include +#include #include #include + namespace dcpomatic { class Font; } @@ -50,8 +54,11 @@ public: static int const OUTLINE_WIDTH; static int const TYPE; static int const DCP_TRACK; + static int const LANGUAGE; + static int const LANGUAGE_IS_ADDITIONAL; }; + /** @class TextContent * @brief Description of how some text content should be presented. * @@ -92,6 +99,8 @@ public: void set_type (TextType type); void set_dcp_track (DCPTextTrack track); void unset_dcp_track (); + void set_language (boost::optional language = boost::none); + void set_language_is_additional (bool additional); bool use () const { boost::mutex::scoped_lock lm (_mutex); @@ -178,7 +187,17 @@ public: return _dcp_track; } - static std::list > from_xml (Content* parent, cxml::ConstNodePtr, int version); + boost::optional language () const { + boost::mutex::scoped_lock lm (_mutex); + return _language; + } + + bool language_is_additional () const { + boost::mutex::scoped_lock lm (_mutex); + return _language_is_additional; + } + + static std::list> from_xml (Content* parent, cxml::ConstNodePtr, int version); private: friend struct ffmpeg_pts_offset_test; @@ -219,6 +238,8 @@ private: TextType _original_type; /** the track of closed captions that this content should be put in, or empty to put in the default (only) track */ boost::optional _dcp_track; + boost::optional _language; + bool _language_is_additional = false; }; #endif diff --git a/src/lib/writer.cc b/src/lib/writer.cc index 839156d34..3448c5bca 100644 --- a/src/lib/writer.cc +++ b/src/lib/writer.cc @@ -663,9 +663,9 @@ Writer::finish (boost::filesystem::path output_dcp) cpl->set_main_picture_active_area (active_area); } - vector sl = film()->subtitle_languages(); - if (sl.size() > 1) { - cpl->set_additional_subtitle_languages(std::vector(sl.begin() + 1, sl.end())); + auto sl = film()->subtitle_languages().second; + if (!sl.empty()) { + cpl->set_additional_subtitle_languages(sl); } auto signer = Config::instance()->signer_chain(); @@ -709,10 +709,10 @@ Writer::write_cover_sheet (boost::filesystem::path output_dcp) boost::algorithm::replace_all (text, "$AUDIO_LANGUAGE", film()->isdcf_metadata().audio_language); auto subtitle_languages = film()->subtitle_languages(); - if (subtitle_languages.empty()) { - boost::algorithm::replace_all (text, "$SUBTITLE_LANGUAGE", "None"); + if (subtitle_languages.first) { + boost::algorithm::replace_all (text, "$SUBTITLE_LANGUAGE", subtitle_languages.first->description()); } else { - boost::algorithm::replace_all (text, "$SUBTITLE_LANGUAGE", subtitle_languages.front().description()); + boost::algorithm::replace_all (text, "$SUBTITLE_LANGUAGE", "None"); } boost::uintmax_t size = 0; diff --git a/src/wx/dcp_panel.cc b/src/wx/dcp_panel.cc index 6de9e3d75..3304f4d3c 100644 --- a/src/wx/dcp_panel.cc +++ b/src/wx/dcp_panel.cc @@ -456,6 +456,8 @@ DCPPanel::film_content_changed (int property) if (property == AudioContentProperty::STREAMS || property == TextContentProperty::USE || property == TextContentProperty::BURN || + property == TextContentProperty::LANGUAGE || + property == TextContentProperty::LANGUAGE_IS_ADDITIONAL || property == VideoContentProperty::SCALE || property == DCPContentProperty::REFERENCE_VIDEO || property == DCPContentProperty::REFERENCE_AUDIO || diff --git a/src/wx/dcp_text_track_dialog.cc b/src/wx/dcp_text_track_dialog.cc index 3e8750cd5..b884aba51 100644 --- a/src/wx/dcp_text_track_dialog.cc +++ b/src/wx/dcp_text_track_dialog.cc @@ -43,5 +43,6 @@ DCPTextTrackDialog::DCPTextTrackDialog (wxWindow* parent) DCPTextTrack DCPTextTrackDialog::get () const { - return DCPTextTrack(wx_to_std(_name->GetValue()), _language->get().to_string()); + DCPOMATIC_ASSERT (_language->get()); + return DCPTextTrack(wx_to_std(_name->GetValue()), _language->get()->to_string()); } diff --git a/src/wx/interop_metadata_dialog.cc b/src/wx/interop_metadata_dialog.cc index 7976e6d44..aa61984b3 100644 --- a/src/wx/interop_metadata_dialog.cc +++ b/src/wx/interop_metadata_dialog.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2020 Carl Hetherington + Copyright (C) 2020-2021 Carl Hetherington This file is part of DCP-o-matic. @@ -18,14 +18,16 @@ */ -#include "interop_metadata_dialog.h" + #include "editable_list.h" +#include "interop_metadata_dialog.h" #include "language_tag_widget.h" #include "rating_dialog.h" #include "lib/film.h" #include #include + using std::string; using std::vector; using std::weak_ptr; @@ -35,42 +37,25 @@ using namespace boost::placeholders; #endif -static string -column (dcp::Rating r, int c) -{ - if (c == 0) { - return r.agency; - } - - return r.label; -} - InteropMetadataDialog::InteropMetadataDialog (wxWindow* parent, weak_ptr film) : wxDialog (parent, wxID_ANY, _("Metadata")) , _film (film) { - wxBoxSizer* overall_sizer = new wxBoxSizer (wxVERTICAL); + auto overall_sizer = new wxBoxSizer (wxVERTICAL); SetSizer (overall_sizer); - wxFlexGridSizer* sizer = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP); + auto sizer = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP); sizer->AddGrowableCol (1, 1); - shared_ptr f = _film.lock(); + auto f = _film.lock(); DCPOMATIC_ASSERT (f); - _enable_subtitle_language = new wxCheckBox (this, wxID_ANY, _("Subtitle language")); - sizer->Add (_enable_subtitle_language, 0, wxLEFT | wxRIGHT | wxALIGN_CENTER_VERTICAL, DCPOMATIC_SIZER_GAP); - vector langs = f->subtitle_languages (); - _enable_subtitle_language->SetValue (!langs.empty()); - _subtitle_language = new LanguageTagWidget (this, wxT(""), langs.empty() ? dcp::LanguageTag("en-US") : langs.front()); - sizer->Add (_subtitle_language->sizer(), 1, wxEXPAND); - { int flags = wxALIGN_TOP | wxLEFT | wxRIGHT | wxTOP; #ifdef __WXOSX__ flags |= wxALIGN_RIGHT; #endif - wxStaticText* m = create_label (this, _("Ratings"), true); + auto m = create_label (this, _("Ratings"), true); sizer->Add (m, 0, flags, DCPOMATIC_SIZER_GAP); } @@ -82,7 +67,12 @@ InteropMetadataDialog::InteropMetadataDialog (wxWindow* parent, weak_ptr f columns, boost::bind(&InteropMetadataDialog::ratings, this), boost::bind(&InteropMetadataDialog::set_ratings, this, _1), - boost::bind(&column, _1, _2), + [](dcp::Rating r, int c) { + if (c == 0) { + return r.agency; + } + return r.label; + }, true, false ); @@ -92,12 +82,12 @@ InteropMetadataDialog::InteropMetadataDialog (wxWindow* parent, weak_ptr f _content_version = new wxTextCtrl (this, wxID_ANY); sizer->Add (_content_version, 1, wxEXPAND); - vector cv = f->content_versions(); + auto cv = f->content_versions(); _content_version->SetValue (std_to_wx(cv.empty() ? "" : cv[0])); overall_sizer->Add (sizer, 1, wxEXPAND | wxALL, DCPOMATIC_DIALOG_BORDER); - wxSizer* buttons = CreateSeparatedButtonSizer (wxCLOSE); + auto buttons = CreateSeparatedButtonSizer (wxCLOSE); if (buttons) { overall_sizer->Add (buttons, wxSizerFlags().Expand().DoubleBorder()); } @@ -105,45 +95,15 @@ InteropMetadataDialog::InteropMetadataDialog (wxWindow* parent, weak_ptr f overall_sizer->Layout (); overall_sizer->SetSizeHints (this); - _enable_subtitle_language->Bind (wxEVT_CHECKBOX, boost::bind(&InteropMetadataDialog::setup_sensitivity, this)); - _subtitle_language->Changed.connect (boost::bind(&InteropMetadataDialog::subtitle_language_changed, this, _1)); - _content_version->Bind (wxEVT_TEXT, boost::bind(&InteropMetadataDialog::content_version_changed, this)); _content_version->SetFocus (); - - setup_sensitivity (); -} - - -void -InteropMetadataDialog::setup_sensitivity () -{ - bool const enabled = _enable_subtitle_language->GetValue(); - _subtitle_language->enable (enabled); - - shared_ptr film = _film.lock (); - DCPOMATIC_ASSERT (film); - if (enabled) { - film->set_subtitle_language (_subtitle_language->get()); - } else { - film->unset_subtitle_language (); - } -} - - -void -InteropMetadataDialog::subtitle_language_changed (dcp::LanguageTag language) -{ - shared_ptr film = _film.lock (); - DCPOMATIC_ASSERT (film); - film->set_subtitle_language (language); } vector InteropMetadataDialog::ratings () const { - shared_ptr film = _film.lock (); + auto film = _film.lock (); DCPOMATIC_ASSERT (film); return film->ratings (); } @@ -151,7 +111,7 @@ InteropMetadataDialog::ratings () const void InteropMetadataDialog::set_ratings (vector r) { - shared_ptr film = _film.lock (); + auto film = _film.lock (); DCPOMATIC_ASSERT (film); film->set_ratings (r); } @@ -159,7 +119,7 @@ InteropMetadataDialog::set_ratings (vector r) void InteropMetadataDialog::content_version_changed () { - shared_ptr film = _film.lock (); + auto film = _film.lock (); DCPOMATIC_ASSERT (film); vector cv; cv.push_back (wx_to_std(_content_version->GetValue())); diff --git a/src/wx/interop_metadata_dialog.h b/src/wx/interop_metadata_dialog.h index 6e4eea40e..b8a1a36e6 100644 --- a/src/wx/interop_metadata_dialog.h +++ b/src/wx/interop_metadata_dialog.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2020 Carl Hetherington + Copyright (C) 2020-2021 Carl Hetherington This file is part of DCP-o-matic. @@ -18,12 +18,14 @@ */ + #include "editable_list.h" #include #include #include #include + class Film; class LanguageTagWidget; class RatingDialog; @@ -38,12 +40,8 @@ private: std::vector ratings () const; void set_ratings (std::vector r); void content_version_changed (); - void setup_sensitivity (); - void subtitle_language_changed (dcp::LanguageTag tag); std::weak_ptr _film; - wxCheckBox* _enable_subtitle_language; - LanguageTagWidget* _subtitle_language; EditableList* _ratings; wxTextCtrl* _content_version; }; diff --git a/src/wx/language_tag_dialog.cc b/src/wx/language_tag_dialog.cc index 96e7c5283..c72c64b31 100644 --- a/src/wx/language_tag_dialog.cc +++ b/src/wx/language_tag_dialog.cc @@ -125,6 +125,7 @@ LanguageTagDialog::set (dcp::LanguageTag tag) } _list->SetItemState (selection, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED); + _list->EnsureVisible (selection); } diff --git a/src/wx/language_tag_widget.cc b/src/wx/language_tag_widget.cc index d71b5fc7a..f0766c9d6 100644 --- a/src/wx/language_tag_widget.cc +++ b/src/wx/language_tag_widget.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2020 Carl Hetherington + Copyright (C) 2020-2021 Carl Hetherington This file is part of DCP-o-matic. @@ -26,13 +26,24 @@ #include -LanguageTagWidget::LanguageTagWidget (wxWindow* parent, wxString tooltip, dcp::LanguageTag tag) +using boost::optional; + + +LanguageTagWidget::LanguageTagWidget (wxWindow* parent, wxString tooltip, optional tag, optional size_to_fit) : _parent (parent) , _sizer (new wxBoxSizer(wxHORIZONTAL)) { - _language = new wxStaticText (parent, wxID_ANY, wxT("")); + _language = new wxStaticText (parent, wxID_ANY, wxT(""), wxDefaultPosition, wxDefaultSize, wxST_ELLIPSIZE_END); _language->SetToolTip (tooltip); set (tag); + + if (size_to_fit) { + int w; + int h; + _language->GetTextExtent (*size_to_fit, &w, &h); + _language->SetMinSize (wxSize(w, -1)); + } + _sizer->Add (_language, 1, wxLEFT | wxALIGN_CENTER_VERTICAL, DCPOMATIC_SIZER_X_GAP); _edit = new Button (parent, _("Edit...")); _sizer->Add (_edit, 0, wxLEFT, DCPOMATIC_SIZER_GAP); @@ -41,10 +52,17 @@ LanguageTagWidget::LanguageTagWidget (wxWindow* parent, wxString tooltip, dcp::L } +LanguageTagWidget::~LanguageTagWidget () +{ + _language->Destroy (); + _edit->Destroy (); +} + + void LanguageTagWidget::edit () { - auto d = new LanguageTagDialog(_parent, _tag); + auto d = new LanguageTagDialog(_parent, _tag.get_value_or(dcp::LanguageTag("en"))); d->ShowModal (); set (d->get()); Changed (d->get()); @@ -53,10 +71,14 @@ LanguageTagWidget::edit () void -LanguageTagWidget::set (dcp::LanguageTag tag) +LanguageTagWidget::set (optional tag) { _tag = tag; - checked_set (_language, std_to_wx(tag.to_string())); + if (tag) { + checked_set (_language, std_to_wx(tag->to_string())); + } else { + checked_set (_language, wxT("")); + } } diff --git a/src/wx/language_tag_widget.h b/src/wx/language_tag_widget.h index 336f7dce2..c2fd63d92 100644 --- a/src/wx/language_tag_widget.h +++ b/src/wx/language_tag_widget.h @@ -34,16 +34,17 @@ class wxWindow; class LanguageTagWidget : public boost::noncopyable { public: - LanguageTagWidget (wxWindow* parent, wxString tooltip, dcp::LanguageTag tag); + LanguageTagWidget (wxWindow* parent, wxString tooltip, boost::optional tag, boost::optional size_to_fit = boost::none); + ~LanguageTagWidget (); wxSizer* sizer () const { return _sizer; } - dcp::LanguageTag get () const { + boost::optional get () const { return _tag; } - void set (dcp::LanguageTag tag); + void set (boost::optional tag); void enable (bool e); boost::signals2::signal Changed; @@ -54,7 +55,7 @@ private: wxStaticText* _language; wxButton* _edit; wxWindow* _parent; - dcp::LanguageTag _tag; + boost::optional _tag; wxSizer* _sizer; }; diff --git a/src/wx/smpte_metadata_dialog.cc b/src/wx/smpte_metadata_dialog.cc index 36cf48489..470e9317e 100644 --- a/src/wx/smpte_metadata_dialog.cc +++ b/src/wx/smpte_metadata_dialog.cc @@ -91,38 +91,6 @@ SMPTEMetadataDialog::main_panel (wxWindow* parent) ); sizer->Add (_audio_language->sizer(), 0, wxEXPAND); - _enable_main_subtitle_language = new wxCheckBox (panel, wxID_ANY, _("Main subtitle language")); - sizer->Add (_enable_main_subtitle_language, 0, wxRIGHT | wxALIGN_CENTER_VERTICAL, DCPOMATIC_SIZER_GAP); - auto subtitle_languages = film()->subtitle_languages(); - _main_subtitle_language = new LanguageTagWidget( - panel, - _("The main language that is displayed in the film's subtitles"), - subtitle_languages.empty() ? dcp::LanguageTag("en-US") : subtitle_languages.front() - ); - sizer->Add (_main_subtitle_language->sizer(), 0, wxEXPAND); - - { - int flags = wxALIGN_TOP | wxRIGHT | wxTOP; -#ifdef __WXOSX__ - flags |= wxALIGN_RIGHT; -#endif - auto m = create_label (panel, _("Additional subtitle languages"), true); - sizer->Add (m, 0, flags, DCPOMATIC_SIZER_GAP); - } - - vector columns; - columns.push_back (EditableListColumn("Language", 250, true)); - _additional_subtitle_languages = new EditableList ( - panel, - columns, - boost::bind(&SMPTEMetadataDialog::additional_subtitle_languages, this), - boost::bind(&SMPTEMetadataDialog::set_additional_subtitle_languages, this, _1), - boost::bind(&additional_subtitle_language_column, _1, _2), - true, - false - ); - sizer->Add (_additional_subtitle_languages, 1, wxEXPAND); - { int flags = wxALIGN_TOP | wxRIGHT | wxTOP; #ifdef __WXOSX__ @@ -132,7 +100,7 @@ SMPTEMetadataDialog::main_panel (wxWindow* parent) sizer->Add (m, 0, flags, DCPOMATIC_SIZER_GAP); } - columns.clear (); + vector columns; columns.push_back (EditableListColumn("Agency", 200, true)); columns.push_back (EditableListColumn("Label", 50, true)); _ratings = new EditableList ( @@ -267,9 +235,7 @@ SMPTEMetadataDialog::SMPTEMetadataDialog (wxWindow* parent, weak_ptr weak_ _name_language->Changed.connect (boost::bind(&SMPTEMetadataDialog::name_language_changed, this, _1)); _audio_language->Changed.connect (boost::bind(&SMPTEMetadataDialog::audio_language_changed, this, _1)); - _enable_main_subtitle_language->Bind (wxEVT_CHECKBOX, boost::bind(&SMPTEMetadataDialog::enable_main_subtitle_changed, this)); _edit_release_territory->Bind (wxEVT_BUTTON, boost::bind(&SMPTEMetadataDialog::edit_release_territory, this)); - _main_subtitle_language->Changed.connect (boost::bind(&SMPTEMetadataDialog::main_subtitle_language_changed, this, _1)); _version_number->Bind (wxEVT_SPINCTRL, boost::bind(&SMPTEMetadataDialog::version_number_changed, this)); _status->Bind (wxEVT_CHOICE, boost::bind(&SMPTEMetadataDialog::status_changed, this)); _enable_chain->Bind (wxEVT_CHECKBOX, boost::bind(&SMPTEMetadataDialog::enable_chain_changed, this)); @@ -362,14 +328,6 @@ SMPTEMetadataDialog::film_changed (ChangeType type, Film::Property property) checked_set (_luminance_value, 4.5); checked_set (_luminance_unit, 1); } - } else if (property == Film::Property::SUBTITLE_LANGUAGES) { - auto languages = film()->subtitle_languages(); - checked_set (_enable_main_subtitle_language, !languages.empty()); - if (!languages.empty()) { - _main_subtitle_language->set (languages.front()); - } else { - _main_subtitle_language->set (dcp::LanguageTag("en-US")); - } } } @@ -495,20 +453,6 @@ SMPTEMetadataDialog::luminance_changed () } -void -SMPTEMetadataDialog::enable_main_subtitle_changed () -{ - setup_sensitivity (); - if (_enable_main_subtitle_language->GetValue()) { - film()->set_subtitle_language (_main_subtitle_language->get()); - } else { - set_additional_subtitle_languages (vector()); - _additional_subtitle_languages->refresh (); - film()->unset_subtitle_language (); - } -} - - void SMPTEMetadataDialog::setup_sensitivity () { @@ -521,49 +465,6 @@ SMPTEMetadataDialog::setup_sensitivity () _chain->Enable (_enable_chain->GetValue()); _distributor->Enable (_enable_distributor->GetValue()); _facility->Enable (_enable_facility->GetValue()); - - { - auto const enabled = _enable_main_subtitle_language->GetValue(); - _main_subtitle_language->enable (enabled); - _additional_subtitle_languages->Enable (enabled); - } -} - - -void -SMPTEMetadataDialog::main_subtitle_language_changed (dcp::LanguageTag tag) -{ - auto existing = film()->subtitle_languages(); - if (existing.empty()) { - existing.push_back (tag); - } else { - existing[0] = tag; - } - - film()->set_subtitle_languages (existing); -} - - -vector -SMPTEMetadataDialog::additional_subtitle_languages () -{ - auto all = film()->subtitle_languages(); - if (all.empty()) { - return all; - } - - return vector(all.begin() + 1, all.end()); -} - - -void -SMPTEMetadataDialog::set_additional_subtitle_languages (vector languages) -{ - auto all = film()->subtitle_languages(); - DCPOMATIC_ASSERT (!all.empty()); - all.resize (1); - copy (languages.begin(), languages.end(), back_inserter(all)); - film()->set_subtitle_languages (all); } diff --git a/src/wx/smpte_metadata_dialog.h b/src/wx/smpte_metadata_dialog.h index 63d90249c..83c1ab39c 100644 --- a/src/wx/smpte_metadata_dialog.h +++ b/src/wx/smpte_metadata_dialog.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2019-2020 Carl Hetherington + Copyright (C) 2019-2021 Carl Hetherington This file is part of DCP-o-matic. @@ -18,6 +18,7 @@ */ + #include "editable_list.h" #include "full_language_tag_dialog.h" #include "lib/film.h" @@ -49,10 +50,6 @@ private: void set_content_versions (std::vector v); void name_language_changed (dcp::LanguageTag tag); void audio_language_changed (dcp::LanguageTag tag); - void enable_main_subtitle_changed (); - void main_subtitle_language_changed (dcp::LanguageTag tag); - std::vector additional_subtitle_languages (); - void set_additional_subtitle_languages (std::vector languages); void edit_release_territory (); void version_number_changed (); void status_changed (); @@ -69,9 +66,6 @@ private: LanguageTagWidget* _name_language; LanguageTagWidget* _audio_language; - wxCheckBox* _enable_main_subtitle_language; - LanguageTagWidget* _main_subtitle_language; - EditableList* _additional_subtitle_languages; wxCheckBox* _enable_release_territory; /** The current release territory displayed in the UI; since we can't easily convert * the string in _release_territory_text to a RegionSubtag we just store the RegionSubtag diff --git a/src/wx/text_panel.cc b/src/wx/text_panel.cc index 3b617a031..5e00d4f41 100644 --- a/src/wx/text_panel.cc +++ b/src/wx/text_panel.cc @@ -18,7 +18,6 @@ */ - #include "check_box.h" #include "content_panel.h" #include "dcp_text_track_dialog.h" @@ -27,6 +26,7 @@ #include "film_editor.h" #include "film_viewer.h" #include "fonts_dialog.h" +#include "language_tag_widget.h" #include "static_text.h" #include "subtitle_appearance_dialog.h" #include "text_panel.h" @@ -153,7 +153,7 @@ TextPanel::setup_visibility () case TextType::OPEN_SUBTITLE: if (_dcp_track_label) { _dcp_track_label->Destroy (); - _dcp_track_label = 0; + _dcp_track_label = nullptr; } if (_dcp_track) { _dcp_track->Destroy (); @@ -164,23 +164,51 @@ TextPanel::setup_visibility () _outline_subtitles->Bind (wxEVT_CHECKBOX, boost::bind (&TextPanel::outline_subtitles_changed, this)); _grid->Add (_outline_subtitles, wxGBPosition(_outline_subtitles_row, 0), wxGBSpan(1, 2)); } - + if (!_language) { + _language_label = create_label (this, _("Language"), true); + add_label_to_sizer (_grid, _language_label, true, wxGBPosition(_ccap_track_or_language_row, 0)); + _language_sizer = new wxBoxSizer (wxHORIZONTAL); + _language = new LanguageTagWidget (this, _("Language of these subtitles"), boost::none, wxString("en-US-")); + _language->Changed.connect (boost::bind(&TextPanel::language_changed, this)); + _language_sizer->Add (_language->sizer(), 1, wxRIGHT, DCPOMATIC_SIZER_GAP); + _language_type = new wxChoice (this, wxID_ANY); + /// TRANSLATORS: Main and Additional here are a choice for whether a set of subtitles is in the "main" language of the + /// film or an "additional" language. + _language_type->Append (_("Main")); + _language_type->Append (_("Additional")); + _language_type->Bind (wxEVT_CHOICE, boost::bind(&TextPanel::language_is_additional_changed, this)); + _language_sizer->Add (_language_type, 0); + _grid->Add (_language_sizer, wxGBPosition(_ccap_track_or_language_row, 1), wxGBSpan(1, 2)); + film_content_changed (TextContentProperty::LANGUAGE); + film_content_changed (TextContentProperty::LANGUAGE_IS_ADDITIONAL); + } break; case TextType::CLOSED_CAPTION: + if (_language_label) { + _language_label->Destroy (); + _language_label = nullptr; + _grid->Remove (_language->sizer()); + delete _language; + _grid->Remove (_language_sizer); + _language_sizer = nullptr; + _language = nullptr; + _language_type->Destroy (); + _language_type = nullptr; + } if (!_dcp_track_label) { _dcp_track_label = create_label (this, _("CCAP track"), true); - add_label_to_sizer (_grid, _dcp_track_label, true, wxGBPosition(_ccap_track_row, 0)); + add_label_to_sizer (_grid, _dcp_track_label, true, wxGBPosition(_ccap_track_or_language_row, 0)); } if (!_dcp_track) { _dcp_track = new wxChoice (this, wxID_ANY); _dcp_track->Bind (wxEVT_CHOICE, boost::bind(&TextPanel::dcp_track_changed, this)); - _grid->Add (_dcp_track, wxGBPosition(_ccap_track_row, 1), wxDefaultSpan, wxEXPAND); + _grid->Add (_dcp_track, wxGBPosition(_ccap_track_or_language_row, 1), wxDefaultSpan, wxEXPAND); update_dcp_tracks (); film_content_changed (TextContentProperty::DCP_TRACK); } if (_outline_subtitles) { _outline_subtitles->Destroy (); - _outline_subtitles = 0; + _outline_subtitles = nullptr; clear_outline_subtitles (); } break; @@ -249,14 +277,14 @@ TextPanel::add_to_grid () { add_label_to_sizer (_grid, _line_spacing_label, true, wxGBPosition (r, 0)); - wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL); + auto s = new wxBoxSizer (wxHORIZONTAL); s->Add (_line_spacing); add_label_to_sizer (s, _line_spacing_pc_label, false, 0, wxLEFT | wxRIGHT | wxALIGN_CENTER_VERTICAL); _grid->Add (s, wxGBPosition (r, 1)); ++r; } - _ccap_track_row = r; + _ccap_track_or_language_row = r; ++r; add_label_to_sizer (_grid, _stream_label, true, wxGBPosition (r, 0)); @@ -454,6 +482,14 @@ TextPanel::film_content_changed (int property) if (_dcp_track) { update_dcp_track_selection (); } + } else if (property == TextContentProperty::LANGUAGE) { + if (_language) { + _language->set (text ? text->language() : boost::none); + } + } else if (property == TextContentProperty::LANGUAGE_IS_ADDITIONAL) { + if (_language_type) { + _language_type->SetSelection (text ? (text->language_is_additional() ? 1 : 0) : 0); + } } else if (property == DCPContentProperty::REFERENCE_TEXT) { if (scs) { auto dcp = dynamic_pointer_cast (scs); @@ -526,10 +562,10 @@ TextPanel::setup_sensitivity () auto sel = _parent->selected_text (); for (auto i: sel) { /* These are the content types that could include subtitles */ - auto fc = std::dynamic_pointer_cast (i); - auto sc = std::dynamic_pointer_cast (i); - auto dc = std::dynamic_pointer_cast (i); - auto dsc = std::dynamic_pointer_cast (i); + auto fc = std::dynamic_pointer_cast(i); + auto sc = std::dynamic_pointer_cast(i); + auto dc = std::dynamic_pointer_cast(i); + auto dsc = std::dynamic_pointer_cast(i); if (fc) { if (!fc->text.empty()) { ++ffmpeg_subs; @@ -548,7 +584,7 @@ TextPanel::setup_sensitivity () shared_ptr dcp; if (sel.size() == 1) { - dcp = dynamic_pointer_cast (sel.front ()); + dcp = dynamic_pointer_cast(sel.front()); } string why_not; @@ -563,7 +599,7 @@ TextPanel::setup_sensitivity () bool const reference = _reference->GetValue (); - TextType const type = current_type (); + auto const type = current_type (); /* Set up _type */ _type->Clear (); @@ -618,7 +654,7 @@ TextPanel::stream_changed () auto a = fcs->subtitle_streams (); auto i = a.begin (); - auto const s = string_client_data (_stream->GetClientObject (_stream->GetSelection ())); + auto const s = string_client_data (_stream->GetClientObject(_stream->GetSelection())); while (i != a.end() && (*i)->identifier () != s) { ++i; } @@ -688,6 +724,8 @@ TextPanel::content_selection_changed () film_content_changed (TextContentProperty::FONTS); film_content_changed (TextContentProperty::TYPE); film_content_changed (TextContentProperty::DCP_TRACK); + film_content_changed (TextContentProperty::LANGUAGE); + film_content_changed (TextContentProperty::LANGUAGE_IS_ADDITIONAL); film_content_changed (DCPContentProperty::REFERENCE_TEXT); } @@ -697,7 +735,7 @@ TextPanel::text_view_clicked () { if (_text_view) { _text_view->Destroy (); - _text_view = 0; + _text_view = nullptr; } auto c = _parent->selected_text (); @@ -759,7 +797,6 @@ TextPanel::appearance_dialog_clicked () } - /** The user has clicked on the outline subtitles check box */ void TextPanel::outline_subtitles_changed () @@ -882,3 +919,27 @@ TextPanel::analysis_finished () try_to_load_analysis (); } + +void +TextPanel::language_changed () +{ + for (auto i: _parent->selected_text()) { + auto t = i->text_of_original_type(_original_type); + if (t) { + t->set_language (_language->get()); + } + } +} + + +void +TextPanel::language_is_additional_changed () +{ + for (auto i: _parent->selected_text()) { + auto t = i->text_of_original_type(_original_type); + if (t) { + t->set_language_is_additional (_language_type->GetSelection() == 1); + } + } +} + diff --git a/src/wx/text_panel.h b/src/wx/text_panel.h index 7f38ff42b..7337e5258 100644 --- a/src/wx/text_panel.h +++ b/src/wx/text_panel.h @@ -23,6 +23,8 @@ class wxCheckBox; +class wxSpinCtrl; +class LanguageTagWidget; class TextView; class FontsDialog; class SpinCtrl; @@ -60,6 +62,8 @@ private: void add_to_grid (); void try_to_load_analysis (); void analysis_finished (); + void language_changed (); + void language_is_additional_changed (); void setup_sensitivity (); void setup_visibility (); @@ -100,9 +104,13 @@ private: FontsDialog* _fonts_dialog; wxButton* _appearance_dialog_button; TextType _original_type; + wxStaticText* _language_label = nullptr; + LanguageTagWidget* _language = nullptr; + wxSizer* _language_sizer = nullptr; + wxChoice* _language_type = nullptr; int _outline_subtitles_row; - int _ccap_track_row; + int _ccap_track_or_language_row; std::weak_ptr _analysis_content; boost::signals2::scoped_connection _analysis_finished_connection; diff --git a/test/isdcf_name_test.cc b/test/isdcf_name_test.cc index dad2ba7d9..59d8ec1b0 100644 --- a/test/isdcf_name_test.cc +++ b/test/isdcf_name_test.cc @@ -74,10 +74,10 @@ BOOST_AUTO_TEST_CASE (isdcf_name_test) film->_isdcf_date = boost::gregorian::date (2014, boost::gregorian::Jul, 4); film->set_audio_channels (1); film->set_resolution (Resolution::FOUR_K); - film->set_subtitle_language (dcp::LanguageTag("fr-FR")); shared_ptr text = content_factory("test/data/subrip.srt").front(); BOOST_REQUIRE_EQUAL (text->text.size(), 1U); text->text.front()->set_burn (true); + text->text.front()->set_language (dcp::LanguageTag("fr-FR")); film->examine_and_add_content (text); BOOST_REQUIRE (!wait_for_jobs()); m.content_version = 2; diff --git a/test/subtitle_language_test.cc b/test/subtitle_language_test.cc index f0f2ad162..af5dee001 100644 --- a/test/subtitle_language_test.cc +++ b/test/subtitle_language_test.cc @@ -18,13 +18,16 @@ */ + /** @file test/subtitle_language_test.cc * @brief Test that subtitle language information is correctly written to DCPs. */ +#include "lib/content.h" #include "lib/content_factory.h" #include "lib/film.h" +#include "lib/text_content.h" #include "test.h" #include #include @@ -39,12 +42,10 @@ using std::shared_ptr; BOOST_AUTO_TEST_CASE (subtitle_language_interop_test) { string const name = "subtitle_language_interop_test"; - auto film = new_test_film2 (name, { content_factory("test/data/frames.srt").front() }); + auto fr = content_factory("test/data/frames.srt").front(); + auto film = new_test_film2 (name, { fr }); - vector langs = { - dcp::LanguageTag("fr-FR"), dcp::LanguageTag("de-DE") - }; - film->set_subtitle_languages(langs); + fr->only_text()->set_language (dcp::LanguageTag("fr-FR")); film->set_interop (true); make_and_verify_dcp ( @@ -62,12 +63,10 @@ BOOST_AUTO_TEST_CASE (subtitle_language_interop_test) BOOST_AUTO_TEST_CASE (subtitle_language_smpte_test) { string const name = "subtitle_language_smpte_test"; - auto film = new_test_film2 (name, { content_factory("test/data/frames.srt").front() }); + auto fr = content_factory("test/data/frames.srt").front(); + auto film = new_test_film2 (name, { fr }); - vector langs = { - dcp::LanguageTag("fr-FR"), dcp::LanguageTag("de-DE") - }; - film->set_subtitle_languages (langs); + fr->only_text()->set_language (dcp::LanguageTag("fr-FR")); film->set_interop (false); make_and_verify_dcp ( diff --git a/test/subtitle_metadata_test.cc b/test/subtitle_metadata_test.cc index 6eaa77100..91372d2a5 100644 --- a/test/subtitle_metadata_test.cc +++ b/test/subtitle_metadata_test.cc @@ -30,46 +30,27 @@ #include -using std::vector; +using std::make_shared; using std::shared_ptr; +using std::vector; BOOST_AUTO_TEST_CASE (subtitle_metadata_test1) { using namespace boost::filesystem; - path p = test_film_dir ("subtitle_metadata_test1"); + auto p = test_film_dir ("subtitle_metadata_test1"); if (exists (p)) { remove_all (p); } create_directory (p); copy_file ("test/data/subtitle_metadata1.xml", p / "metadata.xml"); - shared_ptr film(new Film(p)); - film->read_metadata(); - - vector langs = film->subtitle_languages (); - BOOST_REQUIRE (!langs.empty()); - BOOST_CHECK_EQUAL (langs.front().to_string(), "de-DE"); -} - - -BOOST_AUTO_TEST_CASE (subtitle_metadata_test2) -{ - using namespace boost::filesystem; - - path p = test_film_dir ("subtitle_metadata_test2"); - if (exists (p)) { - remove_all (p); - } - create_directory (p); - - copy_file ("test/data/subtitle_metadata2.xml", p / "metadata.xml"); - shared_ptr film(new Film(p)); + auto film = make_shared(p); film->read_metadata(); - vector langs = film->subtitle_languages (); - BOOST_REQUIRE (!langs.empty()); - BOOST_CHECK_EQUAL (langs.front().to_string(), "FR"); + auto langs = film->subtitle_languages (); + BOOST_REQUIRE (langs.first); + BOOST_CHECK_EQUAL (langs.first->to_string(), "de-DE"); } -- 2.30.2