summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2016-01-30 20:39:12 +0000
committerCarl Hetherington <cth@carlh.net>2016-01-30 20:39:12 +0000
commita1839a88ab0cffdf04737dae783c21f27f65d491 (patch)
treed29b528c385a591a4bd46e1da23be6e4aae255a5 /src/lib
parent4e617f7dee7b4b78555ca3e80e77d26d4fa8f884 (diff)
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.
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/film.cc7
-rw-r--r--src/lib/film.h4
-rw-r--r--src/lib/playlist.cc45
-rw-r--r--src/lib/playlist.h3
4 files changed, 45 insertions, 14 deletions
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<Content>, int, bool frequent);
void maybe_add_content (boost::weak_ptr<Job>, boost::weak_ptr<Content>);
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<boost::signals2::connection> _job_connections;
std::list<boost::signals2::connection> _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> 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<const Film> 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<Content> a, shared_ptr<Content> 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<VideoContent>(a) && !dynamic_pointer_cast<VideoContent>(b)) {
+ return true;
+ } else if (!dynamic_pointer_cast<VideoContent>(a) && dynamic_pointer_cast<VideoContent>(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<Content> 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<Content> 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<Content> 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<Content> 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<void ()> Changed;
+ mutable boost::signals2::signal<void ()> 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.