Use a vector rather than a list when returning from content_factory().
[dcpomatic.git] / src / wx / content_view.cc
index aeefb65df7cdc20e963f49f53fb476043c1cd70d..95b481e0b75d5a74a56b1d5f4a0decadd44c7898 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2018 Carl Hetherington <cth@carlh.net>
+    Copyright (C) 2018-2021 Carl Hetherington <cth@carlh.net>
 
     This file is part of DCP-o-matic.
 
 
 */
 
+
 #include "content_view.h"
 #include "wx_util.h"
-#include "lib/dcpomatic_assert.h"
 #include "lib/config.h"
-#include "lib/dcp_content.h"
 #include "lib/content_factory.h"
+#include "lib/cross.h"
+#include "lib/dcp_content.h"
+#include "lib/dcpomatic_assert.h"
 #include "lib/examine_content_job.h"
 #include "lib/job_manager.h"
-#include "lib/cross.h"
 #include <dcp/exceptions.h>
+#include <dcp/warnings.h>
 #include <boost/filesystem.hpp>
 #include <boost/optional.hpp>
+LIBDCP_DISABLE_WARNINGS
 #include <wx/progdlg.h>
+LIBDCP_ENABLE_WARNINGS
+
 
+using std::cout;
+using std::dynamic_pointer_cast;
+using std::list;
+using std::make_shared;
+using std::shared_ptr;
 using std::string;
-using boost::shared_ptr;
-using boost::weak_ptr;
+using std::weak_ptr;
 using boost::optional;
-using boost::dynamic_pointer_cast;
+using namespace dcpomatic;
 
-ContentView::ContentView (wxWindow* parent, weak_ptr<Film> film)
+
+ContentView::ContentView (wxWindow* parent)
        : wxListCtrl (parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_REPORT | wxLC_NO_HEADER)
-       , _film (film)
 {
        AppendColumn (wxT(""), wxLIST_FORMAT_LEFT, 80);
        /* type */
@@ -49,76 +58,86 @@ ContentView::ContentView (wxWindow* parent, weak_ptr<Film> film)
        AppendColumn (wxT(""), wxLIST_FORMAT_LEFT, 580);
 }
 
+
 shared_ptr<Content>
 ContentView::selected () const
 {
        long int s = GetNextItem (-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
        if (s == -1) {
-               return shared_ptr<Content>();
+               return {};
        }
 
        DCPOMATIC_ASSERT (s < int(_content.size()));
        return _content[s];
 }
 
+
 void
 ContentView::update ()
 {
-       if (!IsShown()) {
-               return;
-       }
-
-       shared_ptr<Film> film = _film.lock ();
-       if (!film) {
-               return;
-       }
-
        using namespace boost::filesystem;
 
        DeleteAllItems ();
        _content.clear ();
-       optional<path> dir = Config::instance()->player_content_directory();
-       if (!dir) {
-               return;
+       auto dir = Config::instance()->player_content_directory();
+       if (!dir || !boost::filesystem::is_directory(*dir)) {
+               dir = home_directory ();
        }
 
        wxProgressDialog progress (_("DCP-o-matic"), _("Reading content directory"));
-       JobManager* jm = JobManager::instance ();
+       auto jm = JobManager::instance ();
 
-       for (directory_iterator i = directory_iterator(*dir); i != directory_iterator(); ++i) {
+       list<shared_ptr<ExamineContentJob>> jobs;
+
+       for (auto i: directory_iterator(*dir)) {
                try {
+                       progress.Pulse ();
+
                        shared_ptr<Content> content;
-                       if (is_directory(*i) && (is_regular_file(*i / "ASSETMAP") || is_regular_file(*i / "ASSETMAP.xml"))) {
-                               content.reset (new DCPContent(film, *i));
-                       } else if (i->path().extension() == ".mp4" || i->path().extension() == ".ecinema") {
-                               content = content_factory(film, *i).front();
+                       if (is_directory(i) && (is_regular_file(i / "ASSETMAP") || is_regular_file(i / "ASSETMAP.xml"))) {
+                               content = make_shared<DCPContent>(i);
+                       } else if (i.path().extension() == ".mp4") {
+                               auto all_content = content_factory(i);
+                               if (!all_content.empty()) {
+                                       content = all_content[0];
+                               }
                        }
 
                        if (content) {
-                               jm->add (shared_ptr<Job>(new ExamineContentJob(film, content)));
-                               while (jm->work_to_do()) {
-                                       if (!progress.Pulse()) {
-                                               /* user pressed cancel */
-                                               BOOST_FOREACH (shared_ptr<Job> i, jm->get()) {
-                                                       i->cancel();
-                                               }
-                                               return;
-                                       }
-                                       dcpomatic_sleep (1);
-                               }
-                               if (report_errors_from_last_job (this)) {
-                                       add (content);
-                                       _content.push_back (content);
-                               }
+                               auto job = make_shared<ExamineContentJob>(shared_ptr<Film>(), content);
+                               jm->add (job);
+                               jobs.push_back (job);
                        }
                } catch (boost::filesystem::filesystem_error& e) {
                        /* Never mind */
-               } catch (dcp::DCPReadError& e) {
+               } catch (dcp::ReadError& e) {
                        /* Never mind */
                }
        }
+
+       while (jm->work_to_do()) {
+               if (!progress.Pulse()) {
+                       /* user pressed cancel */
+                       for (auto i: jm->get()) {
+                               i->cancel();
+                       }
+                       return;
+               }
+               dcpomatic_sleep_seconds (1);
+       }
+
+       /* Add content from successful jobs and report errors */
+       for (auto i: jobs) {
+               if (i->finished_in_error()) {
+                       error_dialog(this, std_to_wx(i->error_summary()) + ".\n", std_to_wx(i->error_details()));
+               } else {
+                       add (i->content());
+                       _content.push_back (i->content());
+               }
+       }
 }
 
+
 void
 ContentView::add (shared_ptr<Content> content)
 {
@@ -127,13 +146,12 @@ ContentView::add (shared_ptr<Content> content)
        wxListItem it;
        it.SetId(N);
        it.SetColumn(0);
-       DCPTime length = content->length_after_trim ();
-       int h, m, s, f;
-       length.split (24, h, m, s, f);
-       it.SetText(wxString::Format("%02d:%02d:%02d", h, m, s));
+       auto length = content->approximate_length ();
+       auto const hmsf = length.split (24);
+       it.SetText(wxString::Format("%02d:%02d:%02d", hmsf.h, hmsf.m, hmsf.s));
        InsertItem(it);
 
-       shared_ptr<DCPContent> dcp = dynamic_pointer_cast<DCPContent>(content);
+       auto dcp = dynamic_pointer_cast<DCPContent>(content);
        if (dcp && dcp->content_kind()) {
                it.SetId(N);
                it.SetColumn(1);
@@ -147,14 +165,15 @@ ContentView::add (shared_ptr<Content> content)
        SetItem(it);
 }
 
+
 shared_ptr<Content>
 ContentView::get (string digest) const
 {
-       BOOST_FOREACH (shared_ptr<Content> i, _content) {
+       for (auto i: _content) {
                if (i->digest() == digest) {
                        return i;
                }
        }
 
-       return shared_ptr<Content>();
+       return {};
 }