Try to clean up the mess of exporting subtitles when there is
authorCarl Hetherington <cth@carlh.net>
Tue, 25 Aug 2020 20:51:47 +0000 (22:51 +0200)
committerCarl Hetherington <cth@carlh.net>
Tue, 25 Aug 2020 20:51:47 +0000 (22:51 +0200)
one file vs many files (multiple reels or fonts).

src/lib/subtitle_encoder.cc
src/lib/subtitle_encoder.h
src/tools/dcpomatic.cc
src/wx/export_subtitles_dialog.cc
src/wx/export_subtitles_dialog.h

index a94b9106ab5266ab4e3f45e9f6c385c8a2485f5c..19241bd6ed994d0c39581394b68ce65b2f304ae4 100644 (file)
@@ -40,8 +40,11 @@ using boost::shared_ptr;
 using boost::optional;
 using dcp::raw_convert;
 
-/** @param include_font true to refer to and export any font file (for Interop; ignored for SMPTE) */
-SubtitleEncoder::SubtitleEncoder (shared_ptr<const Film> film, shared_ptr<Job> job, boost::filesystem::path output, bool split_reels, bool include_font)
+/** @param output Directory, if there will be multiple output files, or a filename.
+ *  @param initial_name Hint that may be used to create filenames, if @ref output is a directory.
+ *  @param include_font true to refer to and export any font file (for Interop; ignored for SMPTE).
+ */
+SubtitleEncoder::SubtitleEncoder (shared_ptr<const Film> film, shared_ptr<Job> job, boost::filesystem::path output, string initial_name, bool split_reels, bool include_font)
        : Encoder (film, job)
        , _split_reels (split_reels)
        , _include_font (include_font)
@@ -53,20 +56,23 @@ SubtitleEncoder::SubtitleEncoder (shared_ptr<const Film> film, shared_ptr<Job> j
        _player->set_ignore_audio ();
        _player->Text.connect (boost::bind(&SubtitleEncoder::text, this, _1, _2, _3, _4));
 
+       string const extension = film->interop() ? ".xml" : ".mxf";
+
        int const files = split_reels ? film->reels().size() : 1;
        for (int i = 0; i < files; ++i) {
 
                boost::filesystem::path filename = output;
-               string extension = boost::filesystem::extension (filename);
-               filename = boost::filesystem::change_extension (filename, "");
-
-               if (files > 1) {
-                       /// TRANSLATORS: _reel%1 here is to be added to an export filename to indicate
-                       /// which reel it is.  Preserve the %1; it will be replaced with the reel number.
-                       filename = filename.string() + String::compose(_("_reel%1"), i + 1);
+               if (boost::filesystem::is_directory(filename)) {
+                       if (files > 1) {
+                               /// TRANSLATORS: _reel%1 here is to be added to an export filename to indicate
+                               /// which reel it is.  Preserve the %1; it will be replaced with the reel number.
+                               filename /= String::compose("%1_reel%2", initial_name, i + 1);
+                       } else {
+                               filename /= initial_name;
+                       }
                }
 
-               _assets.push_back (make_pair(shared_ptr<dcp::SubtitleAsset>(), boost::filesystem::change_extension(filename, ".xml")));
+               _assets.push_back (make_pair(shared_ptr<dcp::SubtitleAsset>(), boost::filesystem::change_extension(filename, extension)));
        }
 
        BOOST_FOREACH (dcpomatic::DCPTimePeriod i, film->reels()) {
index b267c9bae0b620244d50bd9aff88f9078a2112e0..6484d1b0bb63ccfb66983abecb90f2f3c0f8e44c 100644 (file)
@@ -37,7 +37,7 @@ class Film;
 class SubtitleEncoder : public Encoder
 {
 public:
-       SubtitleEncoder (boost::shared_ptr<const Film> film, boost::shared_ptr<Job> job, boost::filesystem::path output, bool split_reels, bool include_font);
+       SubtitleEncoder (boost::shared_ptr<const Film> film, boost::shared_ptr<Job> job, boost::filesystem::path output, std::string intial_name, bool split_reels, bool include_font);
 
        void go ();
 
index 5c32fd487b735ee22200ae4aed35a6b6d5ffee1b..12b8e71dfbe325eba3d80e3143daba8e3a7c0da1 100644 (file)
@@ -990,23 +990,11 @@ private:
 
        void jobs_export_subtitles ()
        {
-               ExportSubtitlesDialog* d = new ExportSubtitlesDialog (this, _film->isdcf_name(true), _film->interop());
+               ExportSubtitlesDialog* d = new ExportSubtitlesDialog (this, _film->reels().size(), _film->interop());
                if (d->ShowModal() == wxID_OK) {
-                       if (boost::filesystem::exists(d->path())) {
-                               bool ok = confirm_dialog(
-                                               this,
-                                               wxString::Format (_("File %s already exists.  Do you want to overwrite it?"), std_to_wx(d->path().string()).data())
-                                               );
-
-                               if (!ok) {
-                                       d->Destroy ();
-                                       return;
-                               }
-                       }
-
                        shared_ptr<TranscodeJob> job (new TranscodeJob (_film));
                        job->set_encoder (
-                               shared_ptr<SubtitleEncoder>(new SubtitleEncoder(_film, job, d->path(), d->split_reels(), d->include_font()))
+                               shared_ptr<SubtitleEncoder>(new SubtitleEncoder(_film, job, d->path(), _film->isdcf_name(true), d->split_reels(), d->include_font()))
                                );
                        JobManager::instance()->add (job);
                }
index bcc8adbe14e1fd9ca9c3bceb9a47a6b90ca05c88..b2b6a63edc297cab156fee0af78d86d1810e370b 100644 (file)
@@ -34,45 +34,75 @@ using std::string;
 using boost::bind;
 
 
-ExportSubtitlesDialog::ExportSubtitlesDialog (wxWindow* parent, string name, bool interop)
+ExportSubtitlesDialog::ExportSubtitlesDialog (wxWindow* parent, int reels, bool interop)
        : TableDialog (parent, _("Export subtitles"), 2, 1, true)
-       , _initial_name (name)
+       , _interop (interop)
        , _include_font (0)
 {
        _split_reels = new CheckBox (this, _("Write reels into separate files"));
        add (_split_reels, false);
        add_spacer ();
-       if (interop) {
-               _include_font = new CheckBox (this, _("Define font in output and export font file"));
-               add (_include_font, false);
-               add_spacer ();
+
+       if (reels > 1) {
+               _split_reels->Enable (false);
+       }
+
+       _include_font = new CheckBox (this, _("Define font in output and export font file"));
+       add (_include_font, false);
+       add_spacer ();
+
+       if (!_interop) {
+               _include_font->Enable (false);
        }
 
-       add (_("Output file"), true);
-       /* Don't warn overwrite here, because on Linux (at least) if we specify a filename like foo
-          the wxFileDialog will check that foo exists, but we will add an extension so we actually
-          need to check if foo.mov (or similar) exists.  I can't find a way to make wxWidgets do this,
-          so disable its check and the caller will have to do it themselves.
-       */
-       _file = new FilePickerCtrl (this, _("Select output file"), _("Subtitle files (.xml)|*.xml"), false, false);
-       _file->SetPath (_initial_name);
+       wxString const wildcard = _interop ? _("Subtitle files (.xml)|*.xml") : _("Subtitle files (.mxf)|*.mxf");
+
+       _file_label = add (_("Output file"), true);
+       _file = new FilePickerCtrl (this, _("Select output file"), wildcard, false, true);
        add (_file);
 
-       _file->Bind (wxEVT_FILEPICKER_CHANGED, bind(&ExportSubtitlesDialog::file_changed, this));
+       _dir_label = add (_("Output folder"), true);
+       _dir = new DirPickerCtrl (this);
+       add (_dir);
+
+       _split_reels->Bind (wxEVT_CHECKBOX, bind(&ExportSubtitlesDialog::setup_sensitivity, this));
+       _include_font->Bind (wxEVT_CHECKBOX, bind(&ExportSubtitlesDialog::setup_sensitivity, this));
+       _file->Bind (wxEVT_FILEPICKER_CHANGED, bind(&ExportSubtitlesDialog::setup_sensitivity, this));
+       _dir->Bind (wxEVT_DIRPICKER_CHANGED, bind(&ExportSubtitlesDialog::setup_sensitivity, this));
 
        layout ();
+       setup_sensitivity ();
+}
+
+
+void
+ExportSubtitlesDialog::setup_sensitivity ()
+{
+       bool const multi = split_reels() || (_interop && _include_font->GetValue());
+       _file_label->Enable (!multi);
+       _file->Enable (!multi);
+       _dir_label->Enable (multi);
+       _dir->Enable (multi);
 
-       wxButton* ok = dynamic_cast<wxButton *>(FindWindowById(wxID_OK, this));
-       ok->Enable (false);
+       wxButton* ok = dynamic_cast<wxButton *> (FindWindowById(wxID_OK, this));
+       DCPOMATIC_ASSERT (ok);
+       ok->Enable (path().is_absolute());
 }
 
 
+/** @return Either a full path to a file, if the output will be one file, or
+ *  a full path to a directory.
+ */
 boost::filesystem::path
 ExportSubtitlesDialog::path () const
 {
-       wxFileName fn (_file->GetPath());
-       fn.SetExt (".xml");
-       return wx_to_std (fn.GetFullPath());
+       if (_file->IsEnabled()) {
+               wxFileName fn (_file->GetPath());
+               fn.SetExt (_interop ? "xml" : "mxf");
+               return wx_to_std (fn.GetFullPath());
+       }
+
+       return wx_to_std (_dir->GetPath());
 }
 
 
@@ -86,14 +116,6 @@ ExportSubtitlesDialog::split_reels () const
 bool
 ExportSubtitlesDialog::include_font () const
 {
-       return _include_font ? _include_font->GetValue () : true;
+       return !_interop || _include_font->GetValue();
 }
 
-
-void
-ExportSubtitlesDialog::file_changed ()
-{
-       wxButton* ok = dynamic_cast<wxButton *> (FindWindowById(wxID_OK, this));
-       DCPOMATIC_ASSERT (ok);
-       ok->Enable (path().is_absolute());
-}
index ee55729f731eb9ab4787eee975c4292f8c8f249a..173dd34625a2f566a090dd72353307dc6139a149 100644 (file)
@@ -18,6 +18,7 @@
 
 */
 
+#include "dir_picker_ctrl.h"
 #include "table_dialog.h"
 #include <wx/wx.h>
 #include <boost/filesystem.hpp>
@@ -27,17 +28,20 @@ class FilePickerCtrl;
 class ExportSubtitlesDialog : public TableDialog
 {
 public:
-       ExportSubtitlesDialog (wxWindow* parent, std::string name, bool interop);
+       ExportSubtitlesDialog (wxWindow* parent, int reels, bool interop);
 
        boost::filesystem::path path () const;
        bool split_reels () const;
        bool include_font () const;
 
 private:
-       void file_changed ();
+       void setup_sensitivity ();
 
-       std::string _initial_name;
+       bool _interop;
        wxCheckBox* _split_reels;
        wxCheckBox* _include_font;
+       wxStaticText* _file_label;
        FilePickerCtrl* _file;
+       DirPickerCtrl* _dir;
+       wxStaticText* _dir_label;
 };