Merge master.
authorCarl Hetherington <cth@carlh.net>
Thu, 12 Jun 2014 21:27:50 +0000 (22:27 +0100)
committerCarl Hetherington <cth@carlh.net>
Thu, 12 Jun 2014 21:27:50 +0000 (22:27 +0100)
ChangeLog
debian/changelog
src/lib/video_content.cc
src/lib/video_content.h
src/tools/dcpomatic.cc

index 126730e27f8e232e481b470e7fda00549606f49e..3194262ef06886fa797af33075cf0ad15cf0948f 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -4,6 +4,13 @@
 
 2014-06-12  Carl Hetherington  <cth@carlh.net>
 
+       * Version 1.69.27 released.
+
+2014-06-12  Carl Hetherington  <cth@carlh.net>
+
+       * Add Content menu with "scale to fit width" and "scale
+       to fit height" options.
+
        * Version 1.69.26 released.
 
 2014-06-12  Carl Hetherington  <cth@carlh.net>
index 182f621b6f81a8684af464c1eccb7b1d58030d3a..41c9652c50033e6c69b580313c6da91460ddc8a6 100644 (file)
@@ -1,4 +1,4 @@
-dcpomatic (1.69.26-1) UNRELEASED; urgency=low
+dcpomatic (1.69.27-1) UNRELEASED; urgency=low
 
   * New upstream release.
   * New upstream release.
@@ -150,8 +150,9 @@ dcpomatic (1.69.26-1) UNRELEASED; urgency=low
   * New upstream release.
   * New upstream release.
   * New upstream release.
+  * New upstream release.
 
- -- Carl Hetherington <carl@d1stkfactory>  Thu, 12 Jun 2014 10:52:11 +0100
+ -- Carl Hetherington <carl@d1stkfactory>  Thu, 12 Jun 2014 16:51:24 +0100
 
 dcpomatic (0.87-1) UNRELEASED; urgency=low
 
index f871f2df666438a1846d465642f8cb991e729723..05f5c538eee2a81c6344f603ab2bfa3e60dfd2cb 100644 (file)
@@ -46,6 +46,8 @@ using std::stringstream;
 using std::setprecision;
 using std::cout;
 using std::vector;
+using std::min;
+using std::max;
 using boost::shared_ptr;
 using boost::optional;
 using boost::dynamic_pointer_cast;
@@ -380,6 +382,32 @@ VideoContent::dcp_time_to_content_time (DCPTime t) const
        return ContentTime (t, FrameRateChange (video_frame_rate(), film->video_frame_rate()));
 }
 
+void
+VideoContent::scale_and_crop_to_fit_width ()
+{
+       shared_ptr<const Film> film = _film.lock ();
+       assert (film);
+
+       set_scale (VideoContentScale (film->container ()));
+
+       int const crop = max (0, int (video_size().height - double (film->frame_size().height) * video_size().width / film->frame_size().width));
+       set_top_crop (crop / 2);
+       set_bottom_crop (crop / 2);
+}
+
+void
+VideoContent::scale_and_crop_to_fit_height ()
+{
+       shared_ptr<const Film> film = _film.lock ();
+       assert (film);
+
+       set_scale (VideoContentScale (film->container ()));
+
+       int const crop = max (0, int (video_size().width - double (film->frame_size().width) * video_size().height / film->frame_size().height));
+       set_left_crop (crop / 2);
+       set_right_crop (crop / 2);
+}
+
 VideoContentScale::VideoContentScale (Ratio const * r)
        : _ratio (r)
        , _scale (true)
index 8313c73eeb8a32b8d65a79e2caa6d22466966042..4206efc2c487d047a744d6634271f810d6d447e2 100644 (file)
@@ -171,6 +171,9 @@ public:
 
        ContentTime dcp_time_to_content_time (DCPTime) const;
 
+       void scale_and_crop_to_fit_width ();
+       void scale_and_crop_to_fit_height ();
+
 protected:
        void take_from_video_examiner (boost::shared_ptr<VideoExaminer>);
 
index 23c1e500512a750f17468445a2cfcfd1cd78f7de..d46ddf1d712ab171f403e689de32f9395156ab6d 100644 (file)
@@ -72,16 +72,12 @@ using std::exception;
 using boost::shared_ptr;
 using boost::dynamic_pointer_cast;
 
-static FilmEditor* film_editor = 0;
-static FilmViewer* film_viewer = 0;
 static shared_ptr<Film> film;
 static std::string film_to_load;
 static std::string film_to_create;
 static std::string content_to_add;
 static wxMenu* jobs_menu = 0;
 
-static void set_menu_sensitivity ();
-
 // #define DCPOMATIC_WINDOWS_CONSOLE 1
 
 class FilmChangedDialog
@@ -159,10 +155,11 @@ load_film (boost::filesystem::path file)
        }
 }
 
-#define ALWAYS                  0x0
-#define NEEDS_FILM              0x1
-#define NOT_DURING_DCP_CREATION 0x2
-#define NEEDS_CPL               0x4
+#define ALWAYS                       0x0
+#define NEEDS_FILM                   0x1
+#define NOT_DURING_DCP_CREATION      0x2
+#define NEEDS_CPL                    0x4
+#define NEEDS_SELECTED_VIDEO_CONTENT 0x8
 
 map<wxMenuItem*, int> menu_items;
        
@@ -173,42 +170,13 @@ add_item (wxMenu* menu, wxString text, int id, int sens)
        menu_items.insert (make_pair (item, sens));
 }
 
-static void
-set_menu_sensitivity ()
-{
-       list<shared_ptr<Job> > jobs = JobManager::instance()->get ();
-       list<shared_ptr<Job> >::iterator i = jobs.begin();
-       while (i != jobs.end() && dynamic_pointer_cast<TranscodeJob> (*i) == 0) {
-               ++i;
-       }
-       bool const dcp_creation = (i != jobs.end ()) && !(*i)->finished ();
-       bool const have_cpl = film && !film->cpls().empty ();
-
-       for (map<wxMenuItem*, int>::iterator j = menu_items.begin(); j != menu_items.end(); ++j) {
-
-               bool enabled = true;
-
-               if ((j->second & NEEDS_FILM) && film == 0) {
-                       enabled = false;
-               }
-
-               if ((j->second & NOT_DURING_DCP_CREATION) && dcp_creation) {
-                       enabled = false;
-               }
-
-               if ((j->second & NEEDS_CPL) && !have_cpl) {
-                       enabled = false;
-               }
-               
-               j->first->Enable (enabled);
-       }
-}
-
 enum {
        ID_file_new = 1,
        ID_file_open,
        ID_file_save,
        ID_file_properties,
+       ID_content_scale_to_fit_width,
+       ID_content_scale_to_fit_height,
        ID_jobs_make_dcp,
        ID_jobs_make_kdms,
        ID_jobs_send_dcp_to_tms,
@@ -244,7 +212,11 @@ setup_menu (wxMenuBar* m)
 #else
        wxMenu* edit = new wxMenu;
        add_item (edit, _("&Preferences..."), wxID_PREFERENCES, ALWAYS);
-#endif 
+#endif
+
+       wxMenu* content = new wxMenu;
+       add_item (content, _("Scale to fit &width"), ID_content_scale_to_fit_width, NEEDS_FILM | NEEDS_SELECTED_VIDEO_CONTENT);
+       add_item (content, _("Scale to fit &height"), ID_content_scale_to_fit_height, NEEDS_FILM | NEEDS_SELECTED_VIDEO_CONTENT);
 
        jobs_menu = new wxMenu;
        add_item (jobs_menu, _("&Make DCP"), ID_jobs_make_dcp, NEEDS_FILM | NOT_DURING_DCP_CREATION);
@@ -267,7 +239,8 @@ setup_menu (wxMenuBar* m)
        m->Append (file, _("&File"));
 #ifndef __WXOSX__      
        m->Append (edit, _("&Edit"));
-#endif 
+#endif
+       m->Append (content, _("&Content"));
        m->Append (jobs_menu, _("&Jobs"));
        m->Append (tools, _("&Tools"));
        m->Append (help, _("&Help"));
@@ -308,6 +281,8 @@ public:
                Bind (wxEVT_COMMAND_MENU_SELECTED, boost::bind (&Frame::file_properties, this),         ID_file_properties);
                Bind (wxEVT_COMMAND_MENU_SELECTED, boost::bind (&Frame::file_exit, this),               wxID_EXIT);
                Bind (wxEVT_COMMAND_MENU_SELECTED, boost::bind (&Frame::edit_preferences, this),        wxID_PREFERENCES);
+               Bind (wxEVT_COMMAND_MENU_SELECTED, boost::bind (&Frame::content_scale_to_fit_width, this), ID_content_scale_to_fit_width);
+               Bind (wxEVT_COMMAND_MENU_SELECTED, boost::bind (&Frame::content_scale_to_fit_height, this), ID_content_scale_to_fit_height);
                Bind (wxEVT_COMMAND_MENU_SELECTED, boost::bind (&Frame::jobs_make_dcp, this),           ID_jobs_make_dcp);
                Bind (wxEVT_COMMAND_MENU_SELECTED, boost::bind (&Frame::jobs_make_kdms, this),          ID_jobs_make_kdms);
                Bind (wxEVT_COMMAND_MENU_SELECTED, boost::bind (&Frame::jobs_send_dcp_to_tms, this),    ID_jobs_send_dcp_to_tms);
@@ -324,28 +299,28 @@ public:
                */
                wxPanel* overall_panel = new wxPanel (this, wxID_ANY);
 
-               film_editor = new FilmEditor (film, overall_panel);
-               film_viewer = new FilmViewer (film, overall_panel);
+               _film_editor = new FilmEditor (film, overall_panel);
+               _film_viewer = new FilmViewer (film, overall_panel);
                JobManagerView* job_manager_view = new JobManagerView (overall_panel, static_cast<JobManagerView::Buttons> (0));
 
                wxBoxSizer* right_sizer = new wxBoxSizer (wxVERTICAL);
-               right_sizer->Add (film_viewer, 2, wxEXPAND | wxALL, 6);
+               right_sizer->Add (_film_viewer, 2, wxEXPAND | wxALL, 6);
                right_sizer->Add (job_manager_view, 1, wxEXPAND | wxALL, 6);
 
                wxBoxSizer* main_sizer = new wxBoxSizer (wxHORIZONTAL);
-               main_sizer->Add (film_editor, 1, wxEXPAND | wxALL, 6);
+               main_sizer->Add (_film_editor, 1, wxEXPAND | wxALL, 6);
                main_sizer->Add (right_sizer, 2, wxEXPAND | wxALL, 6);
 
                set_menu_sensitivity ();
 
-               film_editor->FileChanged.connect (bind (&Frame::file_changed, this, _1));
+               _film_editor->FileChanged.connect (bind (&Frame::file_changed, this, _1));
                if (film) {
                        file_changed (film->directory ());
                } else {
                        file_changed ("");
                }
 
-               JobManager::instance()->ActiveJobsChanged.connect (boost::bind (set_menu_sensitivity));
+               JobManager::instance()->ActiveJobsChanged.connect (boost::bind (&Frame::set_menu_sensitivity, this));
 
                set_film ();
                overall_panel->SetSizer (main_sizer);
@@ -355,8 +330,8 @@ private:
 
        void set_film ()
        {
-               film_viewer->set_film (film);
-               film_editor->set_film (film);
+               _film_viewer->set_film (film);
+               _film_editor->set_film (film);
                set_menu_sensitivity ();
        }
 
@@ -511,6 +486,22 @@ private:
        
                d->Destroy ();
        }
+
+       void content_scale_to_fit_width ()
+       {
+               VideoContentList vc = _film_editor->selected_video_content ();
+               for (VideoContentList::iterator i = vc.begin(); i != vc.end(); ++i) {
+                       (*i)->scale_and_crop_to_fit_width ();
+               }
+       }
+
+       void content_scale_to_fit_height ()
+       {
+               VideoContentList vc = _film_editor->selected_video_content ();
+               for (VideoContentList::iterator i = vc.begin(); i != vc.end(); ++i) {
+                       (*i)->scale_and_crop_to_fit_height ();
+               }
+       }
        
        void jobs_send_dcp_to_tms ()
        {
@@ -603,6 +594,43 @@ private:
                ev.Skip ();
        }
 
+       void set_menu_sensitivity ()
+       {
+               list<shared_ptr<Job> > jobs = JobManager::instance()->get ();
+               list<shared_ptr<Job> >::iterator i = jobs.begin();
+               while (i != jobs.end() && dynamic_pointer_cast<TranscodeJob> (*i) == 0) {
+                       ++i;
+               }
+               bool const dcp_creation = (i != jobs.end ()) && !(*i)->finished ();
+               bool const have_cpl = film && !film->cpls().empty ();
+               bool const have_selected_video_content = !_film_editor->selected_video_content().empty();
+               
+               for (map<wxMenuItem*, int>::iterator j = menu_items.begin(); j != menu_items.end(); ++j) {
+                       
+                       bool enabled = true;
+                       
+                       if ((j->second & NEEDS_FILM) && film == 0) {
+                               enabled = false;
+                       }
+                       
+                       if ((j->second & NOT_DURING_DCP_CREATION) && dcp_creation) {
+                               enabled = false;
+                       }
+                       
+                       if ((j->second & NEEDS_CPL) && !have_cpl) {
+                               enabled = false;
+                       }
+                       
+                       if ((j->second & NEEDS_SELECTED_VIDEO_CONTENT) && !have_selected_video_content) {
+                               enabled = false;
+                       }
+                       
+                       j->first->Enable (enabled);
+               }
+       }
+       
+       FilmEditor* _film_editor;
+       FilmViewer* _film_viewer;
        HintsDialog* _hints_dialog;
        ServersListDialog* _servers_list_dialog;
        wxPreferencesEditor* _config_dialog;