[pitivi: 2/8] Fix some overlap checks.
- From: Edward Hervey <edwardrv src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [pitivi: 2/8] Fix some overlap checks.
- Date: Mon, 3 Aug 2009 08:51:52 +0000 (UTC)
commit 32bbd39204ad02ac732e78023c178cbb3e045905
Author: Alessandro Decina <alessandro d gmail com>
Date: Fri Jul 31 19:04:38 2009 +0200
Fix some overlap checks.
This commit makes Timeline.get(Next|Prev)TimelineObject aware of tracks, fixing
overlap checks editing objects having the same priority but different track.
pitivi/timeline/gap.py | 8 ++-
pitivi/timeline/timeline.py | 58 +++++++++++++++++++++----
pitivi/timeline/track.py | 10 +++--
pitivi/utils.py | 26 ++++--------
tests/test_timeline.py | 97 +++++++++++++++++++++++++++++++++++++++++++
5 files changed, 165 insertions(+), 34 deletions(-)
---
diff --git a/pitivi/timeline/gap.py b/pitivi/timeline/gap.py
index c99e8a9..99f9d9b 100644
--- a/pitivi/timeline/gap.py
+++ b/pitivi/timeline/gap.py
@@ -34,12 +34,13 @@ class Gap(object):
return cmp(self.duration, other.duration)
@classmethod
- def findAroundObject(self, timeline_object, priority=-1):
+ def findAroundObject(self, timeline_object, priority=-1, tracks=None):
from pitivi.timeline.timeline import TimelineError
timeline = timeline_object.timeline
try:
- prev = timeline.getPreviousTimelineObject(timeline_object, priority)
+ prev = timeline.getPreviousTimelineObject(timeline_object,
+ priority, tracks)
except TimelineError:
left_object = None
right_object = timeline_object
@@ -54,7 +55,8 @@ class Gap(object):
left_gap = Gap(left_object, right_object, start, duration)
try:
- next = timeline.getNextTimelineObject(timeline_object, priority)
+ next = timeline.getNextTimelineObject(timeline_object,
+ priority, tracks)
except TimelineError:
left_object = timeline_object
right_object = None
diff --git a/pitivi/timeline/timeline.py b/pitivi/timeline/timeline.py
index 0cb05a0..77e8ed8 100644
--- a/pitivi/timeline/timeline.py
+++ b/pitivi/timeline/timeline.py
@@ -1037,13 +1037,14 @@ class EditingContext(object):
return position, priority
- def _getGapsAtPriority(self, priority, timeline_objects):
+ def _getGapsAtPriority(self, priority, timeline_objects, tracks=None):
gaps = SmallestGapsFinder(timeline_objects)
prio_diff = priority - self.focus.priority
for timeline_object in timeline_objects:
- gaps.update(*Gap.findAroundObject(timeline_object,
- timeline_object.priority + prio_diff))
+ left_gap, right_gap = Gap.findAroundObject(timeline_object,
+ timeline_object.priority + prio_diff, tracks)
+ gaps.update(left_gap, right_gap)
return gaps.left_gap, gaps.right_gap
@@ -1061,13 +1062,18 @@ class MoveContext(EditingContext):
latest = 0
self.default_originals = {}
self.timeline_objects = set([])
+ self.tracks = set([])
all_objects = set(other)
all_objects.add(focus)
for obj in all_objects:
if isinstance(obj, TrackObject):
timeline_object = obj.timeline_object
+ self.tracks.add(obj.track)
else:
timeline_object = obj
+ timeline_object_tracks = set(track_object.track for track_object
+ in timeline_object.track_objects)
+ self.tracks.update(timeline_object_tracks)
self.timeline_objects.add(timeline_object)
@@ -1111,7 +1117,7 @@ class MoveContext(EditingContext):
timeline_objects = self.timeline_objects
return EditingContext._getGapsAtPriority(self,
- priority, timeline_objects)
+ priority, timeline_objects, self.tracks)
def setMode(self, mode):
if mode == self.ROLL:
@@ -1230,10 +1236,15 @@ class TrimStartContext(EditingContext):
EditingContext.__init__(self, timeline, focus, other)
self.adjacent = timeline.edges.getObjsAdjacentToStart(focus)
self.adjacent_originals = self._saveValues(self.adjacent)
+ self.tracks = set([])
if isinstance(self.focus, TrackObject):
focus_timeline_object = self.focus.timeline_object
+ self.tracks.add(self.focus.track)
else:
focus_timeline_object = self.focus
+ tracks = set(track_object.track for track_object in
+ focus.track_objects)
+ self.tracks.update(tracks)
self.focus_timeline_object = focus_timeline_object
self.default_originals = self._saveValues([focus_timeline_object])
@@ -1260,7 +1271,7 @@ class TrimStartContext(EditingContext):
timeline_objects = [self.focus_timeline_object]
left_gap, right_gap = self._getGapsAtPriority(self.focus.priority,
- timeline_objects)
+ timeline_objects, self.tracks)
if left_gap is invalid_gap:
self._defaultTo(initial_position, self.focus.priority)
@@ -1274,10 +1285,15 @@ class TrimEndContext(EditingContext):
EditingContext.__init__(self, timeline, focus, other)
self.adjacent = timeline.edges.getObjsAdjacentToEnd(focus)
self.adjacent_originals = self._saveValues(self.adjacent)
+ self.tracks = set([])
if isinstance(self.focus, TrackObject):
focus_timeline_object = self.focus.timeline_object
+ self.tracks.add(focus.track)
else:
focus_timeline_object = self.focus
+ tracks = set(track_object.track for track_object in
+ focus.track_objects)
+ self.tracks.update(tracks)
self.focus_timeline_object = focus_timeline_object
self.default_originals = self._saveValues([focus_timeline_object])
@@ -1307,7 +1323,7 @@ class TrimEndContext(EditingContext):
timeline_objects = [self.focus_timeline_object]
left_gap, right_gap = self._getGapsAtPriority(self.focus.priority,
- timeline_objects)
+ timeline_objects, self.tracks)
if right_gap is invalid_gap:
self._defaultTo(absolute_initial_duration, self.focus.priority)
@@ -1553,20 +1569,42 @@ class Timeline(Signallable, Loggable):
return output_stream_to_track_map
- def getPreviousTimelineObject(self, obj, priority=-1):
- prev = getPreviousObject(obj, self.timeline_objects, priority)
+ def getPreviousTimelineObject(self, obj, priority=-1, tracks=None):
+ if tracks is None:
+ skip = None
+ else:
+ def skipIfNotInTheseTracks(timeline_object):
+ return self._skipIfNotInTracks(timeline_object, tracks)
+ skip = skipIfNotInTheseTracks
+
+ prev = getPreviousObject(obj, self.timeline_objects,
+ priority, skip=skip)
+
if prev is None:
raise TimelineError("no previous timeline object", obj)
return prev
- def getNextTimelineObject(self, obj, priority=-1):
- next = getNextObject(obj, self.timeline_objects, priority)
+ def getNextTimelineObject(self, obj, priority=-1, tracks=None):
+ if tracks is None:
+ skip = None
+ else:
+ def skipIfNotInTheseTracks(timeline_object):
+ return self._skipIfNotInTracks(timeline_object, tracks)
+ skip = skipIfNotInTheseTracks
+
+ next = getNextObject(obj, self.timeline_objects, priority, skip)
if next is None:
raise TimelineError("no next timeline object", obj)
return next
+ def _skipIfNotInTracks(self, timeline_object, tracks):
+ timeline_object_tracks = set(track_object.track for track_object in
+ timeline_object.track_objects)
+
+ return not tracks.intersection(timeline_object_tracks)
+
def setSelectionToObj(self, obj, mode):
"""
Update the timeline's selection with the given object and mode.
diff --git a/pitivi/timeline/track.py b/pitivi/timeline/track.py
index 020c6a2..a951095 100644
--- a/pitivi/timeline/track.py
+++ b/pitivi/timeline/track.py
@@ -20,7 +20,6 @@
# Boston, MA 02111-1307, USA.
import gst
-import weakref
from pitivi.signalinterface import Signallable
from pitivi.utils import get_controllable_properties, getPreviousObject, \
@@ -675,9 +674,12 @@ class Track(Signallable):
self.default_track_object = None
raise
+ def _skipDefaultTrackObject(self, timeline_object):
+ return timeline_object is self.default_track_object
+
def getPreviousTrackObject(self, obj, priority=-1):
prev = getPreviousObject(obj, self.track_objects, priority,
- [self.default_track_object])
+ self._skipDefaultTrackObject)
if prev is None:
raise TrackError("no previous track object", obj)
@@ -685,7 +687,7 @@ class Track(Signallable):
def getNextTrackObject(self, obj, priority=-1):
next = getNextObject(obj, self.track_objects, priority,
- [self.default_track_object])
+ self._skipDefaultTrackObject)
if next is None:
raise TrackError("no next track object", obj)
@@ -730,7 +732,7 @@ class Track(Signallable):
raise TrackError()
track_object.makeBin()
- track_object.track = weakref.proxy(self)
+ track_object.track = self
start_insort_right(self.track_objects, track_object)
diff --git a/pitivi/utils.py b/pitivi/utils.py
index 67200aa..02db982 100644
--- a/pitivi/utils.py
+++ b/pitivi/utils.py
@@ -380,21 +380,19 @@ def findObject(obj, objects):
return low
-def getPreviousObject(obj, objects, priority=-1, exclude=None):
+def getPreviousObject(obj, objects, priority=-1, skip=None):
if priority == -1:
priority = obj.priority
- if exclude is None:
- exclude = []
-
obj_index = findObject(obj, objects)
if obj_index is None:
- import pdb; pdb.set_trace()
+ raise Exception("woot this should never happen")
# check if there are same-start objects
prev_obj_index = obj_index + 1
while prev_obj_index < len(objects):
prev_obj = objects[prev_obj_index]
- if prev_obj in exclude:
+ prev_obj_index += 1
+ if skip is not None and skip(prev_obj):
continue
if prev_obj.start != obj.start:
@@ -403,36 +401,30 @@ def getPreviousObject(obj, objects, priority=-1, exclude=None):
if priority is None or prev_obj.priority == priority:
return prev_obj
- prev_obj_index += 1
# check if there are objects with start < obj.start
prev_obj_index = obj_index - 1
while prev_obj_index >= 0:
prev_obj = objects[prev_obj_index]
- if prev_obj not in exclude and \
- (priority is None or \
- prev_obj.priority == priority):
+ if (priority is None or prev_obj.priority == priority) \
+ and (skip is None or not skip(prev_obj)):
return prev_obj
prev_obj_index -= 1
return None
-def getNextObject(obj, objects, priority=-1, exclude=None):
+def getNextObject(obj, objects, priority=-1, skip=None):
if priority == -1:
priority = obj.priority
- if exclude is None:
- exclude = []
-
obj_index = findObject(obj, objects)
next_obj_index = obj_index + 1
objs_len = len(objects)
while next_obj_index < objs_len:
next_obj = objects[next_obj_index]
- if next_obj not in exclude and \
- (priority is None or \
- next_obj.priority == priority):
+ if (priority is None or next_obj.priority == priority) and \
+ (skip is None or not skip(next_obj)):
return next_obj
next_obj_index += 1
diff --git a/tests/test_timeline.py b/tests/test_timeline.py
index 821fca6..2b835f4 100644
--- a/tests/test_timeline.py
+++ b/tests/test_timeline.py
@@ -886,8 +886,49 @@ class TestContexts(TestCase):
self.failUnlessEqual(self.track_object1.in_point, 0)
self.failUnlessEqual(self.track_object2.start, gst.SECOND * 15)
self.failUnlessEqual(self.track_object3.start, gst.SECOND * 25)
+ context.finish()
+
+ def testMoveContextOverlapDifferentTracks(self):
+ # start
+ # track1: [focus][t2]
+ # track2: [t3 ]
+ self.track_object1.start = 20 * gst.SECOND
+ self.track_object1.duration = 10 * gst.SECOND
+ self.track_object1.priority = 1
+ self.track_object2.start = 30 * gst.SECOND
+ self.track_object2.duration = 10 * gst.SECOND
+ self.track_object2.priority = 1
+ self.track_object3.start = 1 * gst.SECOND
+ self.track_object3.duration = 10 * gst.SECOND
+ self.track_object3.priority = 1
+ # move to
+ # track1: [focus][t2]
+ # track2: [t3 ]
+ context = MoveContext(self.timeline, self.track_object1,
+ set([self.track_object2]))
+ context.editTo(gst.SECOND * 1, 0)
+ context.finish()
+ self.failUnlessEqual(self.track_object1.start, 1 * gst.SECOND)
+ self.failUnlessEqual(self.track_object1.duration, 10 * gst.SECOND)
+ self.failUnlessEqual(self.track_object2.start, 11 * gst.SECOND)
+ self.failUnlessEqual(self.track_object2.duration, 10 * gst.SECOND)
+ self.failUnlessEqual(self.track_object3.start, 1 * gst.SECOND)
+ self.failUnlessEqual(self.track_object3.duration, 10 * gst.SECOND)
+
+ # move to
+ # track1: [focus][t2]
+ # track2: [t3 ]
+ context = MoveContext(self.timeline, self.track_object3,
+ set([]))
+ context.editTo(gst.SECOND * 10, 0)
context.finish()
+ self.failUnlessEqual(self.track_object1.start, 1 * gst.SECOND)
+ self.failUnlessEqual(self.track_object1.duration, 10 * gst.SECOND)
+ self.failUnlessEqual(self.track_object2.start, 11 * gst.SECOND)
+ self.failUnlessEqual(self.track_object2.duration, 10 * gst.SECOND)
+ self.failUnlessEqual(self.track_object3.start, 10 * gst.SECOND)
+ self.failUnlessEqual(self.track_object3.duration, 10 * gst.SECOND)
def testMoveContextFocusNotEarliest(self):
# [t2 ][focus] [t3 ]
@@ -1189,6 +1230,34 @@ class TestContexts(TestCase):
self.failUnlessEqual(self.track_object2.in_point, 2 * gst.SECOND)
self.failUnlessEqual(self.track_object2.duration, 11 * gst.SECOND)
+ def testTrimStartContextMarginsDifferentTracks(self):
+ # start
+ # track1: [focus][t2]
+ # track2: [t3 ]
+ self.track_object1.start = 20 * gst.SECOND
+ self.track_object1.in_point = 15 * gst.SECOND
+ self.track_object1.duration = 10 * gst.SECOND
+ self.track_object1.priority = 1
+ self.track_object2.start = 30 * gst.SECOND
+ self.track_object2.duration = 10 * gst.SECOND
+ self.track_object2.priority = 1
+ self.track_object3.start = 1 * gst.SECOND
+ self.track_object3.duration = 10 * gst.SECOND
+ self.track_object3.priority = 1
+
+ # trim back to
+ # track1: [ focus][t2]
+ # track2: [t3 ]
+ context = TrimStartContext(self.timeline, self.track_object1, set([]))
+ context.editTo(gst.SECOND * 5, 0)
+ context.finish()
+ self.failUnlessEqual(self.track_object1.start, 5 * gst.SECOND)
+ self.failUnlessEqual(self.track_object1.duration, 25 * gst.SECOND)
+ self.failUnlessEqual(self.track_object2.start, 30 * gst.SECOND)
+ self.failUnlessEqual(self.track_object2.duration, 10 * gst.SECOND)
+ self.failUnlessEqual(self.track_object3.start, 1 * gst.SECOND)
+ self.failUnlessEqual(self.track_object3.duration, 10 * gst.SECOND)
+
def testTrimEndContext(self):
self.track_object1.start = 1 * gst.SECOND
self.track_object1.in_point = 3 * gst.SECOND
@@ -1233,6 +1302,34 @@ class TestContexts(TestCase):
self.failUnlessEqual(self.track_object2.in_point, 3 * gst.SECOND)
self.failUnlessEqual(self.track_object2.duration, 10 * gst.SECOND)
+ def testTrimEndContextMarginsDifferentTracks(self):
+ # start
+ # track1: [t1][t2 ]
+ # track2: [t3 ]
+ self.track_object1.start = 1 * gst.SECOND
+ self.track_object1.duration = 10 * gst.SECOND
+ self.track_object1.priority = 1
+ self.track_object2.start = 10 * gst.SECOND
+ self.track_object2.duration = 10 * gst.SECOND
+ self.track_object2.timeline_object.factory.duration = 30 * gst.SECOND
+ self.track_object2.priority = 1
+ self.track_object3.start = 25 * gst.SECOND
+ self.track_object3.duration = 10 * gst.SECOND
+ self.track_object3.priority = 1
+
+ # extend to
+ # track1: [t1][t2 ]
+ # track2: [t3 ]
+ context = TrimEndContext(self.timeline, self.track_object2, set([]))
+ context.editTo(gst.SECOND * 30, 0)
+ context.finish()
+ self.failUnlessEqual(self.track_object1.start, 1 * gst.SECOND)
+ self.failUnlessEqual(self.track_object1.duration, 10 * gst.SECOND)
+ self.failUnlessEqual(self.track_object2.start, 10 * gst.SECOND)
+ self.failUnlessEqual(self.track_object2.duration, 20 * gst.SECOND)
+ self.failUnlessEqual(self.track_object3.start, 25 * gst.SECOND)
+ self.failUnlessEqual(self.track_object3.duration, 10 * gst.SECOND)
+
def testEmptyOther(self):
context = MoveContext(self.timeline, self.track_object1, set())
context.finish()
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]