+ shared_ptr<DCPDecoder> decoder;
+ try {
+ decoder.reset (new DCPDecoder (film, shared_from_this(), false, film->tolerant(), shared_ptr<DCPDecoder>()));
+ } catch (dcp::ReadError &) {
+ /* We couldn't read the DCP, so it's probably missing */
+ return false;
+ } catch (DCPError &) {
+ /* We couldn't read the DCP, so it's probably missing */
+ return false;
+ } catch (dcp::KDMDecryptionError &) {
+ /* We have an incorrect KDM */
+ return false;
+ }
+
+ BOOST_FOREACH (shared_ptr<dcp::Reel> i, decoder->reels()) {
+ if (!i->main_sound()) {
+ /// TRANSLATORS: this string will follow "Cannot reference this DCP: "
+ why_not = _("it does not have sound in all its reels.");
+ return false;
+ }
+ }
+
+ /// TRANSLATORS: this string will follow "Cannot reference this DCP: "
+ return can_reference (film, bind (&check_audio, _1), _("it overlaps other audio content; remove the other content."), why_not);
+}
+
+static
+bool check_text (shared_ptr<const Content> c)
+{
+ return !c->text.empty();
+}
+
+bool
+DCPContent::can_reference_text (shared_ptr<const Film> film, TextType type, string& why_not) const
+{
+ shared_ptr<DCPDecoder> decoder;
+ try {
+ decoder.reset (new DCPDecoder (film, shared_from_this(), false, film->tolerant(), shared_ptr<DCPDecoder>()));
+ } catch (dcp::ReadError &) {
+ /* We couldn't read the DCP, so it's probably missing */
+ return false;
+ } catch (dcp::KDMDecryptionError &) {
+ /* We have an incorrect KDM */
+ return false;
+ }
+
+ BOOST_FOREACH (shared_ptr<dcp::Reel> i, decoder->reels()) {
+ if (type == TEXT_OPEN_SUBTITLE && !i->main_subtitle()) {
+ /// TRANSLATORS: this string will follow "Cannot reference this DCP: "
+ why_not = _("it does not have open subtitles in all its reels.");
+ return false;
+ }
+ if (type == TEXT_CLOSED_CAPTION && i->closed_captions().empty()) {
+ /// TRANSLATORS: this string will follow "Cannot reference this DCP: "
+ why_not = _("it does not have closed captions in all its reels.");
+ return false;