Hand-apply bbfb370d7de28ec1e8f307865cc6253bb5d4366e from master; quicker digest calcu...
[dcpomatic.git] / src / wx / content_panel.cc
index b752a0e5fe3d41d5dfde90a4b275f3385e3a9e07..8bcf46f5c3151e2c0a2fe3f844e76483377833bc 100644 (file)
@@ -35,6 +35,7 @@
 #include "subtitle_panel.h"
 #include "timing_panel.h"
 #include "timeline_dialog.h"
+#include "image_sequence_dialog.h"
 
 using std::list;
 using std::string;
@@ -64,27 +65,36 @@ ContentPanel::ContentPanel (wxNotebook* n, boost::shared_ptr<Film> f)
                _content->SetColumnWidth (0, 512);
 
                wxBoxSizer* b = new wxBoxSizer (wxVERTICAL);
+               
                _add_file = new wxButton (_panel, wxID_ANY, _("Add file(s)..."));
-               b->Add (_add_file, 1, wxEXPAND | wxALL, DCPOMATIC_BUTTON_STACK_GAP);
+               _add_file->SetToolTip (_("Add video, image or sound files to the film."));
+               b->Add (_add_file, 0, wxEXPAND | wxALL, DCPOMATIC_BUTTON_STACK_GAP);
+               
                _add_folder = new wxButton (_panel, wxID_ANY, _("Add folder..."));
+               _add_folder->SetToolTip (_("Add a folder of image files (which will be used as a moving image sequence) or a DCP."));
                b->Add (_add_folder, 1, wxEXPAND | wxALL, DCPOMATIC_BUTTON_STACK_GAP);
+               
                _remove = new wxButton (_panel, wxID_ANY, _("Remove"));
-               b->Add (_remove, 1, wxEXPAND | wxALL, DCPOMATIC_BUTTON_STACK_GAP);
+               _remove->SetToolTip (_("Remove the selected piece of content from the film."));
+               b->Add (_remove, 0, wxEXPAND | wxALL, DCPOMATIC_BUTTON_STACK_GAP);
+               
                _earlier = new wxButton (_panel, wxID_ANY, _("Up"));
-               b->Add (_earlier, 1, wxEXPAND | wxALL, DCPOMATIC_BUTTON_STACK_GAP);
+               _earlier->SetToolTip (_("Move the selected piece of content earlier in the film."));
+               b->Add (_earlier, 0, wxEXPAND | wxALL, DCPOMATIC_BUTTON_STACK_GAP);
+               
                _later = new wxButton (_panel, wxID_ANY, _("Down"));
-               b->Add (_later, 1, wxEXPAND | wxALL, DCPOMATIC_BUTTON_STACK_GAP);
+               _later->SetToolTip (_("Move the selected piece of content later in the film."));
+               b->Add (_later, 0, wxEXPAND | wxALL, DCPOMATIC_BUTTON_STACK_GAP);
+               
                _timeline = new wxButton (_panel, wxID_ANY, _("Timeline..."));
-               b->Add (_timeline, 1, wxEXPAND | wxALL, DCPOMATIC_BUTTON_STACK_GAP);
+               _timeline->SetToolTip (_("Open the timeline for the film."));
+               b->Add (_timeline, 0, wxEXPAND | wxALL, DCPOMATIC_BUTTON_STACK_GAP);
 
                s->Add (b, 0, wxALL, 4);
 
                _sizer->Add (s, 0, wxEXPAND | wxALL, 6);
        }
 
-       _sequence_video = new wxCheckBox (_panel, wxID_ANY, _("Keep video in sequence"));
-       _sizer->Add (_sequence_video);
-
        _notebook = new wxNotebook (_panel, wxID_ANY);
        _sizer->Add (_notebook, 1, wxEXPAND | wxTOP, 6);
 
@@ -100,13 +110,13 @@ ContentPanel::ContentPanel (wxNotebook* n, boost::shared_ptr<Film> f)
        _content->Bind (wxEVT_COMMAND_LIST_ITEM_SELECTED, boost::bind (&ContentPanel::selection_changed, this));
        _content->Bind (wxEVT_COMMAND_LIST_ITEM_DESELECTED, boost::bind (&ContentPanel::selection_changed, this));
        _content->Bind (wxEVT_COMMAND_LIST_ITEM_RIGHT_CLICK, boost::bind (&ContentPanel::right_click, this, _1));
+       _content->Bind (wxEVT_DROP_FILES, boost::bind (&ContentPanel::files_dropped, this, _1));
        _add_file->Bind (wxEVT_COMMAND_BUTTON_CLICKED, boost::bind (&ContentPanel::add_file_clicked, this));
        _add_folder->Bind (wxEVT_COMMAND_BUTTON_CLICKED, boost::bind (&ContentPanel::add_folder_clicked, this));
        _remove->Bind (wxEVT_COMMAND_BUTTON_CLICKED, boost::bind (&ContentPanel::remove_clicked, this));
        _earlier->Bind (wxEVT_COMMAND_BUTTON_CLICKED, boost::bind (&ContentPanel::earlier_clicked, this));
        _later->Bind (wxEVT_COMMAND_BUTTON_CLICKED, boost::bind (&ContentPanel::later_clicked, this));
        _timeline->Bind (wxEVT_COMMAND_BUTTON_CLICKED, boost::bind (&ContentPanel::timeline_clicked, this));
-       _sequence_video->Bind (wxEVT_COMMAND_CHECKBOX_CLICKED, boost::bind (&ContentPanel::sequence_video_changed, this));
 }
 
 ContentList
@@ -192,16 +202,6 @@ ContentPanel::selected_ffmpeg ()
        return sc;
 }
 
-void
-ContentPanel::sequence_video_changed ()
-{
-       if (!_film) {
-               return;
-       }
-       
-       _film->set_sequence_video (_sequence_video->GetValue ());
-}
-
 void
 ContentPanel::film_changed (Film::Property p)
 {
@@ -209,9 +209,6 @@ ContentPanel::film_changed (Film::Property p)
        case Film::CONTENT:
                setup ();
                break;
-       case Film::SEQUENCE_VIDEO:
-               checked_set (_sequence_video, _film->sequence_video ());
-               break;
        default:
                break;
        }
@@ -261,28 +258,54 @@ void
 ContentPanel::add_folder_clicked ()
 {
        wxDirDialog* d = new wxDirDialog (_panel, _("Choose a folder"), wxT (""), wxDD_DIR_MUST_EXIST);
-       int const r = d->ShowModal ();
+       int r = d->ShowModal ();
+       boost::filesystem::path const path (wx_to_std (d->GetPath ()));
        d->Destroy ();
        
        if (r != wxID_OK) {
                return;
        }
 
-       shared_ptr<Content> content;
-       
-       try {
-               content.reset (new ImageContent (_film, boost::filesystem::path (wx_to_std (d->GetPath ()))));
-       } catch (...) {
+       /* Guess if this is a DCP or a set of images: read the first ten filenames and if they
+          are all valid image files we assume it is a set of images.
+       */
+
+       bool is_dcp = false;
+       int read = 0;
+       for (boost::filesystem::directory_iterator i(path); i != boost::filesystem::directory_iterator() && read < 10; ++i, ++read) {
+               if (!boost::filesystem::is_regular_file (i->path()) || !valid_image_file (i->path())) {
+                       is_dcp = true;
+               }
+       }
+
+       if (is_dcp) {
                try {
-                       content.reset (new DCPContent (_film, boost::filesystem::path (wx_to_std (d->GetPath ()))));
+                       shared_ptr<DCPContent> content (new DCPContent (_film, path));
+                       _film->examine_and_add_content (content);
                } catch (...) {
-                       error_dialog (_panel, _("Could not find any images nor a DCP in that folder"));
+                       error_dialog (_panel, _("Could not find a DCP in that folder."));
+               }
+       } else {
+               
+               ImageSequenceDialog* e = new ImageSequenceDialog (_panel);
+               r = e->ShowModal ();
+               float const frame_rate = e->frame_rate ();
+               e->Destroy ();
+
+               if (r != wxID_OK) {
                        return;
                }
-       }
 
-       if (content) {
-               _film->examine_and_add_content (content);
+               shared_ptr<Content> content;
+               
+               try {
+                       shared_ptr<ImageContent> content (new ImageContent (_film, path));
+                       content->set_video_frame_rate (frame_rate);
+                       _film->examine_and_add_content (content);
+               } catch (...) {
+                       error_dialog (_panel, _("Could not find any images in that folder"));
+                       return;
+               }
        }
 }
 
@@ -341,6 +364,9 @@ void
 ContentPanel::set_film (shared_ptr<Film> f)
 {
        _film = f;
+
+       film_changed (Film::CONTENT);
+       film_changed (Film::AUDIO_CHANNELS);
        selection_changed ();
 }
 
@@ -356,7 +382,6 @@ ContentPanel::set_general_sensitivity (bool s)
        _earlier->Enable (s);
        _later->Enable (s);
        _timeline->Enable (s);
-       _sequence_video->Enable (s);
 
        /* Set the panels in the content notebook */
        for (list<ContentSubPanel*>::iterator i = _panels.begin(); i != _panels.end(); ++i) {
@@ -422,7 +447,7 @@ ContentPanel::setup ()
 
        ContentList content = _film->content ();
        sort (content.begin(), content.end(), ContentSorter ());
-       
+
        for (ContentList::iterator i = content.begin(); i != content.end(); ++i) {
                int const t = _content->GetItemCount ();
                bool const valid = (*i)->paths_valid ();
@@ -456,3 +481,15 @@ ContentPanel::setup ()
        }
 }
 
+void
+ContentPanel::files_dropped (wxDropFilesEvent& event)
+{
+       if (!_film) {
+               return;
+       }
+       
+       wxString* paths = event.GetFiles ();
+       for (int i = 0; i < event.GetNumberOfFiles(); i++) {
+               _film->examine_and_add_content (content_factory (_film, wx_to_std (paths[i])));
+       }
+}