Support playlists in the player in dual-screen mode.
[dcpomatic.git] / src / wx / timing_panel.cc
index ebdd99487bff709b9f58e2999e1c40ecfa143068..184356a20cb39fc2ab80fcce5eac69f3ac529796 100644 (file)
@@ -25,6 +25,7 @@
 #include "content_panel.h"
 #include "move_to_dialog.h"
 #include "static_text.h"
+#include "dcpomatic_button.h"
 #include "lib/content.h"
 #include "lib/image_content.h"
 #include "lib/text_content.h"
@@ -32,6 +33,8 @@
 #include "lib/audio_content.h"
 #include "lib/string_text_file_content.h"
 #include "lib/video_content.h"
+#include "lib/dcp_content.h"
+#include "lib/ffmpeg_content.h"
 #include <dcp/locale_convert.h>
 #include <boost/foreach.hpp>
 #include <set>
@@ -45,12 +48,14 @@ using boost::weak_ptr;
 using boost::dynamic_pointer_cast;
 using boost::optional;
 using dcp::locale_convert;
+using namespace dcpomatic;
 
 TimingPanel::TimingPanel (ContentPanel* p, weak_ptr<FilmViewer> viewer)
        /* horrid hack for apparent lack of context support with wxWidgets i18n code */
        /// TRANSLATORS: translate the word "Timing" here; do not include the "Timing|" prefix
        : ContentSubPanel (p, S_("Timing|Timing"))
        , _viewer (viewer)
+       , _film_content_changed_suspender (boost::bind(&TimingPanel::film_content_changed, this, _1))
 {
        wxSize size = TimecodeBase::size (this);
 
@@ -82,21 +87,21 @@ TimingPanel::TimingPanel (ContentPanel* p, weak_ptr<FilmViewer> viewer)
 
        _position_label = create_label (this, _("Position"), true);
        _position = new Timecode<DCPTime> (this);
-       _move_to_start_of_reel = new wxButton (this, wxID_ANY, _("Move to start of reel"));
+       _move_to_start_of_reel = new Button (this, _("Move to start of reel"));
        _full_length_label = create_label (this, _("Full length"), true);
        _full_length = new Timecode<DCPTime> (this);
        _trim_start_label = create_label (this, _("Trim from start"), true);
        _trim_start = new Timecode<ContentTime> (this);
-       _trim_start_to_playhead = new wxButton (this, wxID_ANY, _("Trim up to current position"));
+       _trim_start_to_playhead = new Button (this, _("Trim up to current position"));
        _trim_end_label = create_label (this, _("Trim from end"), true);
        _trim_end = new Timecode<ContentTime> (this);
-       _trim_end_to_playhead = new wxButton (this, wxID_ANY, _("Trim after current position"));
+       _trim_end_to_playhead = new Button (this, _("Trim after current position"));
        _play_length_label = create_label (this, _("Play length"), true);
        _play_length = new Timecode<DCPTime> (this);
 
        _video_frame_rate_label = create_label (this, _("Video frame rate"), true);
        _video_frame_rate = new wxTextCtrl (this, wxID_ANY);
-       _set_video_frame_rate = new wxButton (this, wxID_ANY, _("Set"));
+       _set_video_frame_rate = new Button (this, _("Set"));
        _set_video_frame_rate->Enable (false);
 
        /* We can't use Wrap() here as it doesn't work with markup:
@@ -168,12 +173,6 @@ TimingPanel::add_to_grid ()
        _move_to_start_of_reel->Show (full);
        _full_length_label->Show (full);
        _full_length->Show (full);
-       _trim_start_label->Show (full);
-       _trim_start->Show (full);
-       _trim_start_to_playhead->Show (full);
-       _trim_end_label->Show (full);
-       _trim_end->Show (full);
-       _trim_end_to_playhead->Show (full);
        _play_length_label->Show (full);
        _play_length->Show (full);
        _video_frame_rate_label->Show (full);
@@ -188,21 +187,23 @@ TimingPanel::add_to_grid ()
                add_label_to_sizer (_grid, _full_length_label, true, wxGBPosition(r, 0));
                _grid->Add (_full_length, wxGBPosition(r, 1));
                ++r;
+       }
 
-               add_label_to_sizer (_grid, _trim_start_label, true, wxGBPosition(r, 0));
-               _grid->Add (_trim_start, wxGBPosition(r, 1));
-               ++r;
+       add_label_to_sizer (_grid, _trim_start_label, true, wxGBPosition(r, 0));
+       _grid->Add (_trim_start, wxGBPosition(r, 1));
+       ++r;
 
-               _grid->Add (_trim_start_to_playhead, wxGBPosition(r, 1));
-               ++r;
+       _grid->Add (_trim_start_to_playhead, wxGBPosition(r, 1));
+       ++r;
 
-               add_label_to_sizer (_grid, _trim_end_label, true, wxGBPosition(r, 0));
-               _grid->Add (_trim_end, wxGBPosition(r, 1));
-               ++r;
+       add_label_to_sizer (_grid, _trim_end_label, true, wxGBPosition(r, 0));
+       _grid->Add (_trim_end, wxGBPosition(r, 1));
+       ++r;
 
-               _grid->Add (_trim_end_to_playhead, wxGBPosition(r, 1));
-               ++r;
+       _grid->Add (_trim_end_to_playhead, wxGBPosition(r, 1));
+       ++r;
 
+       if (full) {
                add_label_to_sizer (_grid, _play_length_label, true, wxGBPosition(r, 0));
                _grid->Add (_play_length, wxGBPosition(r, 1));
                ++r;
@@ -256,6 +257,10 @@ TimingPanel::update_play_length ()
 void
 TimingPanel::film_content_changed (int property)
 {
+       if (_film_content_changed_suspender.check(property)) {
+               return;
+       }
+
        int const film_video_frame_rate = _parent->film()->video_frame_rate ();
 
        /* Here we check to see if we have exactly one different value of various
@@ -405,8 +410,7 @@ TimingPanel::trim_start_changed ()
        optional<FrameRateChange> ref_frc;
        optional<DCPTime> ref_ph;
 
-       ContentTime const trim = _trim_start->get (_parent->film()->video_frame_rate ());
-
+       Suspender::Block bl = _film_content_changed_suspender.block ();
        BOOST_FOREACH (shared_ptr<Content> i, _parent->selected ()) {
                if (i->position() <= ph && ph < i->end(_parent->film())) {
                        /* The playhead is in i.  Use it as a reference to work out
@@ -418,6 +422,7 @@ TimingPanel::trim_start_changed ()
                        ref_ph = ph - i->position() + DCPTime (i->trim_start(), ref_frc.get());
                }
 
+               ContentTime const trim = _trim_start->get (i->video_frame_rate().get_value_or(_parent->film()->video_frame_rate()));
                i->set_trim_start (trim);
        }
 
@@ -438,8 +443,9 @@ TimingPanel::trim_end_changed ()
 
        fv->set_coalesce_player_changes (true);
 
-       ContentTime const trim = _trim_end->get (_parent->film()->video_frame_rate ());
+       Suspender::Block bl = _film_content_changed_suspender.block ();
        BOOST_FOREACH (shared_ptr<Content> i, _parent->selected ()) {
+               ContentTime const trim = _trim_end->get (i->video_frame_rate().get_value_or(_parent->film()->video_frame_rate()));
                i->set_trim_end (trim);
        }
 
@@ -448,13 +454,14 @@ TimingPanel::trim_end_changed ()
                fv->seek (_parent->film()->length() - DCPTime::from_frames(1, _parent->film()->video_frame_rate()), true);
        }
 
-       fv->set_coalesce_player_changes (true);
+       fv->set_coalesce_player_changes (false);
 }
 
 void
 TimingPanel::play_length_changed ()
 {
        DCPTime const play_length = _play_length->get (_parent->film()->video_frame_rate());
+       Suspender::Block bl = _film_content_changed_suspender.block ();
        BOOST_FOREACH (shared_ptr<Content> i, _parent->selected ()) {
                FrameRateChange const frc = _parent->film()->active_frame_rate_change (i->position ());
                i->set_trim_end (
@@ -466,7 +473,22 @@ TimingPanel::play_length_changed ()
 void
 TimingPanel::video_frame_rate_changed ()
 {
-       _set_video_frame_rate->Enable (true);
+       bool enable = true;
+       if (_video_frame_rate->GetValue() == wxT("")) {
+               /* No frame rate has been entered; if the user clicks "set" now it would unset the video
+                  frame rate in the selected content.  This can't be allowed for some content types.
+               */
+               BOOST_FOREACH (shared_ptr<Content> i, _parent->selected()) {
+                       if (
+                               dynamic_pointer_cast<DCPContent>(i) ||
+                               dynamic_pointer_cast<FFmpegContent>(i)
+                               ) {
+                               enable = false;
+                       }
+               }
+       }
+
+       _set_video_frame_rate->Enable (enable);
 }
 
 void
@@ -476,6 +498,7 @@ TimingPanel::set_video_frame_rate ()
        if (_video_frame_rate->GetValue() != wxT("")) {
                fr = locale_convert<double> (wx_to_std (_video_frame_rate->GetValue ()));
        }
+       Suspender::Block bl = _film_content_changed_suspender.block ();
        BOOST_FOREACH (shared_ptr<Content> i, _parent->selected ()) {
                if (fr) {
                        i->set_video_frame_rate (*fr);