Rename Subtitle -> Text
[dcpomatic.git] / src / tools / dcpomatic_player.cc
index 2fe9aca8b83f585d88b0a73537c5b09467501207..3f56f47529fd59b41397f73b0d023ecda58e22cb 100644 (file)
 #include "lib/job_manager.h"
 #include "lib/job.h"
 #include "lib/video_content.h"
-#include "lib/subtitle_content.h"
+#include "lib/text_content.h"
 #include "lib/ratio.h"
 #include "lib/verify_dcp_job.h"
 #include "lib/dcp_examiner.h"
+#include "lib/examine_content_job.h"
+#include "lib/server.h"
+#include "lib/dcpomatic_socket.h"
 #include "wx/wx_signal_manager.h"
 #include "wx/wx_util.h"
 #include "wx/about_dialog.h"
@@ -64,8 +67,11 @@ using std::list;
 using std::exception;
 using std::vector;
 using boost::shared_ptr;
+using boost::scoped_array;
 using boost::optional;
 using boost::dynamic_pointer_cast;
+using boost::thread;
+using boost::bind;
 
 enum {
        ID_file_open = 1,
@@ -193,23 +199,8 @@ public:
                }
 
                _film->examine_and_add_content (dcp, true);
-
-               JobManager* jm = JobManager::instance ();
-
-               wxProgressDialog* progress = new wxProgressDialog (_("DCP-o-matic Player"), _("Loading DCP"));
-
-               while (jm->work_to_do() || signal_manager->ui_idle()) {
-                       dcpomatic_sleep (1);
-                       progress->Pulse ();
-               }
-
-               progress->Destroy ();
-
-               DCPOMATIC_ASSERT (!jm->get().empty());
-
-               shared_ptr<Job> last = jm->get().back();
-               if (last->finished_in_error()) {
-                       error_dialog(this, std_to_wx(last->error_summary()) + ".\n", std_to_wx(last->error_details()));
+               bool const ok = progress (_("Loading DCP"));
+               if (!ok || !report_errors_from_last_job()) {
                        return;
                }
 
@@ -356,7 +347,11 @@ private:
                        shared_ptr<DCPContent> dcp = boost::dynamic_pointer_cast<DCPContent>(_film->content().front());
                        DCPOMATIC_ASSERT (dcp);
                        dcp->add_ov (wx_to_std(c->GetPath()));
-                       dcp->examine (shared_ptr<Job>());
+                       JobManager::instance()->add(shared_ptr<Job>(new ExamineContentJob (_film, dcp)));
+                       bool const ok = progress (_("Loading DCP"));
+                       if (!ok || !report_errors_from_last_job()) {
+                               return;
+                       }
                        setup_from_dcp (dcp);
                }
 
@@ -442,16 +437,11 @@ private:
 
                JobManager* jm = JobManager::instance ();
                jm->add (shared_ptr<Job> (new VerifyDCPJob (dcp->directories())));
-
-               wxProgressDialog* progress = new wxProgressDialog (_("DCP-o-matic Player"), _("Verifying DCP"));
-
-               while (jm->work_to_do() || signal_manager->ui_idle()) {
-                       dcpomatic_sleep (1);
-                       progress->Pulse ();
+               bool const ok = progress (_("Verifying DCP"));
+               if (!ok) {
+                       return;
                }
 
-               progress->Destroy ();
-
                DCPOMATIC_ASSERT (!jm->get().empty());
                shared_ptr<VerifyDCPJob> last = dynamic_pointer_cast<VerifyDCPJob> (jm->get().back());
                DCPOMATIC_ASSERT (last);
@@ -586,6 +576,46 @@ private:
 
 private:
 
+       /** @return false if the task was cancelled */
+       bool progress (wxString task)
+       {
+               JobManager* jm = JobManager::instance ();
+
+               wxProgressDialog* progress = new wxProgressDialog (_("DCP-o-matic Player"), task, 100, 0, wxPD_CAN_ABORT);
+
+               bool ok = true;
+
+               while (jm->work_to_do() || signal_manager->ui_idle()) {
+                       dcpomatic_sleep (1);
+                       if (!progress->Pulse()) {
+                               /* user pressed cancel */
+                               BOOST_FOREACH (shared_ptr<Job> i, jm->get()) {
+                                       i->cancel();
+                               }
+                               ok = false;
+                               break;
+                       }
+               }
+
+               progress->Destroy ();
+               return ok;
+       }
+
+       bool report_errors_from_last_job ()
+       {
+               JobManager* jm = JobManager::instance ();
+
+               DCPOMATIC_ASSERT (!jm->get().empty());
+
+               shared_ptr<Job> last = jm->get().back();
+               if (last->finished_in_error()) {
+                       error_dialog(this, std_to_wx(last->error_summary()) + ".\n", std_to_wx(last->error_details()));
+                       return false;
+               }
+
+               return true;
+       }
+
        void setup_from_dcp (shared_ptr<DCPContent> dcp)
        {
                if (dcp->subtitle) {
@@ -622,6 +652,32 @@ static const wxCmdLineEntryDesc command_line_description[] = {
        { wxCMD_LINE_NONE, "", "", "", wxCmdLineParamType (0), 0 }
 };
 
+class PlayServer : public Server
+{
+public:
+       explicit PlayServer (DOMFrame* frame)
+               : Server (PLAYER_PLAY_PORT)
+               , _frame (frame)
+       {}
+
+       void handle (shared_ptr<Socket> socket)
+       {
+               try {
+                       int const length = socket->read_uint32 ();
+                       scoped_array<char> buffer (new char[length]);
+                       socket->read (reinterpret_cast<uint8_t*> (buffer.get()), length);
+                       string s (buffer.get());
+                       signal_manager->when_idle (bind (&DOMFrame::load_dcp, _frame, s));
+                       socket->write (reinterpret_cast<uint8_t const *> ("OK"), 3);
+               } catch (...) {
+
+               }
+       }
+
+private:
+       DOMFrame* _frame;
+};
+
 /** @class App
  *  @brief The magic App class for wxWidgets.
  */
@@ -691,6 +747,9 @@ private:
 
                signal_manager = new wxSignalManager (this);
 
+               PlayServer* server = new PlayServer (_frame);
+               new thread (boost::bind (&PlayServer::run, server));
+
                if (!_dcp_to_load.empty() && boost::filesystem::is_directory (_dcp_to_load)) {
                        try {
                                _frame->load_dcp (_dcp_to_load);