summaryrefslogtreecommitdiff
path: root/src
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
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')
-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
-rw-r--r--src/wx/content_panel.cc4
-rw-r--r--src/wx/timeline.cc16
6 files changed, 55 insertions, 24 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.
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<Content> 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 ();
}
}