From: Carl Hetherington Date: Sat, 30 Jan 2016 20:39:12 +0000 (+0000) Subject: Add a PlaylistOrderChanged signal and emit it when the playlist X-Git-Tag: v2.6.17~3 X-Git-Url: https://main.carlh.net/gitweb/?p=dcpomatic.git;a=commitdiff_plain;h=a1839a88ab0cffdf04737dae783c21f27f65d491 Add a PlaylistOrderChanged signal and emit it when the playlist is sorted. Do playlist sorting when content position / length etc. changes. Handle sorts better when comparing content at the same position. --- diff --git a/ChangeLog b/ChangeLog index c2d05c5eb..3ae8fe78a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2016-01-30 Carl Hetherington + + * Fix a collection of strange problems with the content list when + dragging content around in the timeline. + 2016-01-24 Carl Hetherington * Fix encodes getting stuck in some cases (#783). diff --git a/src/lib/film.cc b/src/lib/film.cc index 006cf8dca..20b959dd0 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -135,6 +135,7 @@ Film::Film (boost::filesystem::path dir, bool log) set_isdcf_date_today (); _playlist_changed_connection = _playlist->Changed.connect (bind (&Film::playlist_changed, this)); + _playlist_order_changed_connection = _playlist->OrderChanged.connect (bind (&Film::playlist_order_changed, this)); _playlist_content_changed_connection = _playlist->ContentChanged.connect (bind (&Film::playlist_content_changed, this, _1, _2, _3)); /* Make state.directory a complete path without ..s (where possible) @@ -1092,6 +1093,12 @@ Film::playlist_changed () signal_changed (NAME); } +void +Film::playlist_order_changed () +{ + signal_changed (CONTENT_ORDER); +} + int Film::audio_frame_rate () const { diff --git a/src/lib/film.h b/src/lib/film.h index 17bdd09eb..2fb3e810b 100644 --- a/src/lib/film.h +++ b/src/lib/film.h @@ -163,6 +163,8 @@ public: USE_ISDCF_NAME, /** The playlist's content list has changed (i.e. content has been added or removed) */ CONTENT, + /** The order of content in the playlist has changed */ + CONTENT_ORDER, DCP_CONTENT_TYPE, CONTAINER, RESOLUTION, @@ -309,6 +311,7 @@ private: void signal_changed (Property); std::string video_identifier () const; void playlist_changed (); + void playlist_order_changed (); void playlist_content_changed (boost::weak_ptr, int, bool frequent); void maybe_add_content (boost::weak_ptr, boost::weak_ptr); void audio_analysis_finished (); @@ -362,6 +365,7 @@ private: mutable bool _dirty; boost::signals2::scoped_connection _playlist_changed_connection; + boost::signals2::scoped_connection _playlist_order_changed_connection; boost::signals2::scoped_connection _playlist_content_changed_connection; std::list _job_connections; std::list _audio_analysis_connections; diff --git a/src/lib/playlist.cc b/src/lib/playlist.cc index 1eaef3a51..e3d0c8ebb 100644 --- a/src/lib/playlist.cc +++ b/src/lib/playlist.cc @@ -66,16 +66,28 @@ Playlist::~Playlist () void Playlist::content_changed (weak_ptr content, int property, bool frequent) { - /* Don't respond to position changes here, as: - - sequencing after earlier/later changes is handled by move_earlier/move_later - - any other position changes will be timeline drags which should not result in content - being sequenced. - */ - if (property == ContentProperty::LENGTH || property == VideoContentProperty::VIDEO_FRAME_TYPE) { + /* Don't respond to position changes here, as: + - sequencing after earlier/later changes is handled by move_earlier/move_later + - any other position changes will be timeline drags which should not result in content + being sequenced. + */ maybe_sequence_video (); } + if ( + property == ContentProperty::POSITION || + property == ContentProperty::LENGTH || + property == ContentProperty::TRIM_START || + property == ContentProperty::TRIM_END) { + + ContentList old = _content; + sort (_content.begin(), _content.end(), ContentSorter ()); + if (_content != old) { + OrderChanged (); + } + } + ContentChanged (content, property, frequent); } @@ -138,6 +150,7 @@ Playlist::set_from_xml (shared_ptr film, cxml::ConstNodePtr node, in _content.push_back (content_factory (film, i, version, notes)); } + /* This shouldn't be necessary but better safe than sorry (there could be old files) */ sort (_content.begin(), _content.end(), ContentSorter ()); reconnect (); @@ -349,7 +362,19 @@ Playlist::set_sequence_video (bool s) bool ContentSorter::operator() (shared_ptr a, shared_ptr b) { - return a->position() < b->position(); + if (a->position() != b->position()) { + return a->position() < b->position(); + } + + /* Put video before audio if they start at the same time */ + if (dynamic_pointer_cast(a) && !dynamic_pointer_cast(b)) { + return true; + } else if (!dynamic_pointer_cast(a) && dynamic_pointer_cast(b)) { + return false; + } + + /* Last resort */ + return a->digest() < b->digest(); } /** @return content in ascending order of position */ @@ -389,8 +414,6 @@ Playlist::repeat (ContentList c, int n) void Playlist::move_earlier (shared_ptr c) { - sort (_content.begin(), _content.end(), ContentSorter ()); - ContentList::iterator previous = _content.end (); ContentList::iterator i = _content.begin(); while (i != _content.end() && *i != c) { @@ -407,14 +430,11 @@ Playlist::move_earlier (shared_ptr c) DCPTime const p = (*previous)->position (); (*previous)->set_position (p + c->length_after_trim ()); c->set_position (p); - sort (_content.begin(), _content.end(), ContentSorter ()); } void Playlist::move_later (shared_ptr c) { - sort (_content.begin(), _content.end(), ContentSorter ()); - ContentList::iterator i = _content.begin(); while (i != _content.end() && *i != c) { ++i; @@ -431,7 +451,6 @@ Playlist::move_later (shared_ptr c) (*next)->set_position (c->position ()); c->set_position (c->position() + (*next)->length_after_trim ()); - sort (_content.begin(), _content.end(), ContentSorter ()); } int64_t diff --git a/src/lib/playlist.h b/src/lib/playlist.h index 0baf667fc..3af17bb6c 100644 --- a/src/lib/playlist.h +++ b/src/lib/playlist.h @@ -70,8 +70,9 @@ public: void repeat (ContentList, int); - /** Emitted when content has been added to or removed from the playlist */ + /** Emitted when content has been added to or removed from the playlist; implies OrderChanged */ mutable boost::signals2::signal Changed; + mutable boost::signals2::signal OrderChanged; /** Emitted when something about a piece of our content has changed; * these emissions include when the position of the content changes. * Third parameter is true if signals are currently being emitted frequently. diff --git a/src/wx/content_panel.cc b/src/wx/content_panel.cc index 1f9352f06..06c371348 100644 --- a/src/wx/content_panel.cc +++ b/src/wx/content_panel.cc @@ -210,6 +210,7 @@ ContentPanel::film_changed (Film::Property p) { switch (p) { case Film::CONTENT: + case Film::CONTENT_ORDER: setup (); break; default: @@ -422,7 +423,7 @@ ContentPanel::set_selection (weak_ptr wc) void ContentPanel::film_content_changed (int property) { - if (property == ContentProperty::PATH || property == ContentProperty::POSITION || property == DCPContentProperty::CAN_BE_PLAYED) { + if (property == ContentProperty::PATH || property == DCPContentProperty::CAN_BE_PLAYED) { setup (); } @@ -435,7 +436,6 @@ void ContentPanel::setup () { ContentList content = _film->content (); - sort (content.begin(), content.end(), ContentSorter ()); /* First, check to see if anything has changed and bail if not; this avoids flickering on OS X. diff --git a/src/wx/timeline.cc b/src/wx/timeline.cc index 952945884..8a61eccb0 100644 --- a/src/wx/timeline.cc +++ b/src/wx/timeline.cc @@ -101,6 +101,13 @@ Timeline::film_changed (Film::Property p) if (p == Film::CONTENT || p == Film::REEL_TYPE || p == Film::REEL_LENGTH) { ensure_ui_thread (); recreate_views (); + } else if (p == Film::CONTENT_ORDER) { + assign_tracks (); + if (!_left_down) { + /* Only do this if we are not dragging, as it's confusing otherwise */ + setup_pixels_per_second (); + } + Refresh (); } } @@ -142,14 +149,7 @@ Timeline::film_content_changed (int property) { ensure_ui_thread (); - if (property == ContentProperty::POSITION) { - assign_tracks (); - if (!_left_down) { - /* Only do this if we are not dragging, as it's confusing otherwise */ - setup_pixels_per_second (); - } - Refresh (); - } else if (property == AudioContentProperty::AUDIO_STREAMS) { + if (property == AudioContentProperty::AUDIO_STREAMS) { recreate_views (); } }