Support drag-and-drop of DCPs onto the player (#1220).
[dcpomatic.git] / src / tools / dcpomatic_player.cc
index 043e90b9efd97104557d08d2bf126b0aeec416b7..d97bdd168edea4052da1a2ca1ec96b076566fefe 100644 (file)
@@ -71,6 +71,7 @@
 LIBDCP_DISABLE_WARNINGS
 #include <wx/cmdline.h>
 #include <wx/display.h>
+#include <wx/dnd.h>
 #include <wx/preferences.h>
 #include <wx/progdlg.h>
 #include <wx/splash.h>
@@ -148,9 +149,48 @@ enum {
        ID_go_to_end
 };
 
+
 class DOMFrame : public wxFrame
 {
 public:
+
+       class DCPDropTarget : public wxFileDropTarget
+       {
+       public:
+               DCPDropTarget(DOMFrame* owner)
+                       : _frame(owner)
+               {}
+
+               bool OnDropFiles(wxCoord, wxCoord, wxArrayString const& filenames) override
+               {
+                       if (filenames.GetCount() == 1) {
+                               /* Try to load a directory */
+                               auto path = boost::filesystem::path(wx_to_std(filenames[0]));
+                               if (boost::filesystem::is_directory(path)) {
+                                       _frame->load_dcp(wx_to_std(filenames[0]));
+                                       return true;
+                               }
+                       }
+
+                       if (filenames.GetCount() >= 1) {
+                               /* Try to load the parent if we drop some files, one if which is an asset map */
+                               for (size_t i = 0; i < filenames.GetCount(); ++i) {
+                                       auto path = boost::filesystem::path(wx_to_std(filenames[i]));
+                                       if (path.filename() == "ASSETMAP" || path.filename() == "ASSETMAP.xml") {
+                                               _frame->load_dcp(path.parent_path());
+                                               return true;
+                                       }
+                               }
+                       }
+
+                       return false;
+               }
+
+       private:
+               DOMFrame* _frame;
+       };
+
+
        DOMFrame ()
                : wxFrame (nullptr, -1, _("DCP-o-matic Player"))
                , _mode (Config::instance()->player_mode())
@@ -260,6 +300,8 @@ public:
                setup_screen ();
 
                _stress.LoadDCP.connect (boost::bind(&DOMFrame::load_dcp, this, _1));
+
+               SetDropTarget(new DCPDropTarget(this));
        }
 
        ~DOMFrame ()
@@ -338,7 +380,6 @@ public:
                reset_film ();
                try {
                        _stress.set_suspended (true);
-                       // here
                        auto dcp = make_shared<DCPContent>(dir);
                        auto job = make_shared<ExamineContentJob>(_film, dcp);
                        _examine_job_connection = job->Finished.connect(bind(&DOMFrame::add_dcp_to_film, this, weak_ptr<Job>(job), weak_ptr<Content>(dcp)));
@@ -354,7 +395,7 @@ public:
                                wxString::Format(_("Could not load a DCP from %s"), std_to_wx(dir.string())),
                                _(
                                        "This looks like a DCP-o-matic project folder, which cannot be loaded into the player.  "
-                                       "Choose the DCP directory inside the DCP-o-matic project folder if that's what you want to play."
+                                       "Choose the DCP folder inside the DCP-o-matic project folder if that's what you want to play."
                                 )
                                );
                } catch (dcp::ReadError& e) {
@@ -970,7 +1011,7 @@ private:
 
                int pos = _history_position;
 
-               /* Clear out non-existant history items before we re-build the menu */
+               /* Clear out non-existent history items before we re-build the menu */
                Config::instance()->clean_player_history ();
                auto history = Config::instance()->player_history ();