[pitivi] Avoid collapses when trimming. Fixes #589694.
- From: Edward Hervey <edwardrv src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [pitivi] Avoid collapses when trimming. Fixes #589694.
- Date: Fri, 31 Jul 2009 08:32:42 +0000 (UTC)
commit 268d057cc1a06a5dcce05c2a6c05aaa67b7d7e84
Author: Alessandro Decina <alessandro d gmail com>
Date: Wed Jul 29 20:21:23 2009 +0200
Avoid collapses when trimming. Fixes #589694.
pitivi/timeline/timeline.py | 68 +++++++++++++++++++++++++++++++++++++------
tests/test_timeline.py | 62 ++++++++++++++++++++++++++++++++-------
tests/test_track.py | 23 ++++++++++++--
3 files changed, 130 insertions(+), 23 deletions(-)
---
diff --git a/pitivi/timeline/timeline.py b/pitivi/timeline/timeline.py
index ca153a5..0cb05a0 100644
--- a/pitivi/timeline/timeline.py
+++ b/pitivi/timeline/timeline.py
@@ -1011,7 +1011,7 @@ class EditingContext(object):
pass
def _rippleTo(self, position, priority):
- pass
+ return position, priority
def _finishDefault(self):
pass
@@ -1037,6 +1037,17 @@ class EditingContext(object):
return position, priority
+ def _getGapsAtPriority(self, priority, timeline_objects):
+ 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))
+
+ return gaps.left_gap, gaps.right_gap
+
+
class MoveContext(EditingContext):
"""An editing context which sets the start point of the editing targets.
@@ -1098,14 +1109,9 @@ class MoveContext(EditingContext):
timeline_objects = self.timeline_objects_plus_ripple
else:
timeline_objects = self.timeline_objects
- 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))
- return gaps.left_gap, gaps.right_gap
+ return EditingContext._getGapsAtPriority(self,
+ priority, timeline_objects)
def setMode(self, mode):
if mode == self.ROLL:
@@ -1224,6 +1230,12 @@ class TrimStartContext(EditingContext):
EditingContext.__init__(self, timeline, focus, other)
self.adjacent = timeline.edges.getObjsAdjacentToStart(focus)
self.adjacent_originals = self._saveValues(self.adjacent)
+ if isinstance(self.focus, TrackObject):
+ focus_timeline_object = self.focus.timeline_object
+ else:
+ focus_timeline_object = self.focus
+ self.focus_timeline_object = focus_timeline_object
+ self.default_originals = self._saveValues([focus_timeline_object])
def _rollTo(self, position, priority):
earliest = self.focus.start - self.focus.in_point
@@ -1236,17 +1248,38 @@ class TrimStartContext(EditingContext):
self._restoreValues(self.adjacent_originals)
def _defaultTo(self, position, priority):
- earliest = self.focus.start - self.focus.in_point
+ earliest = max(0, self.focus.start - self.focus.in_point)
self.focus.trimStart(max(position, earliest), snap=self.snap)
return position, priority
+ def finish(self):
+ EditingContext.finish(self)
+
+ initial_position = self.default_originals[self.focus_timeline_object][0]
+
+ timeline_objects = [self.focus_timeline_object]
+ left_gap, right_gap = self._getGapsAtPriority(self.focus.priority,
+ timeline_objects)
+
+ if left_gap is invalid_gap:
+ self._defaultTo(initial_position, self.focus.priority)
+ left_gap, right_gap = Gap.findAroundObject(self.focus_timeline_object)
+ position = initial_position - left_gap.duration
+ self._defaultTo(position, self.focus.priority)
+
class TrimEndContext(EditingContext):
def __init__(self, timeline, focus, other):
EditingContext.__init__(self, timeline, focus, other)
self.adjacent = timeline.edges.getObjsAdjacentToEnd(focus)
self.adjacent_originals = self._saveValues(self.adjacent)
+ if isinstance(self.focus, TrackObject):
+ focus_timeline_object = self.focus.timeline_object
+ else:
+ focus_timeline_object = self.focus
+ self.focus_timeline_object = focus_timeline_object
+ self.default_originals = self._saveValues([focus_timeline_object])
def _rollTo(self, position, priority):
if self._snap:
@@ -1265,6 +1298,23 @@ class TrimEndContext(EditingContext):
return position, priority
+ def finish(self):
+ EditingContext.finish(self)
+
+ initial_position, initial_duration = \
+ self.default_originals[self.focus_timeline_object][0:2]
+ absolute_initial_duration = initial_position + initial_duration
+
+ timeline_objects = [self.focus_timeline_object]
+ left_gap, right_gap = self._getGapsAtPriority(self.focus.priority,
+ timeline_objects)
+
+ if right_gap is invalid_gap:
+ self._defaultTo(absolute_initial_duration, self.focus.priority)
+ left_gap, right_gap = Gap.findAroundObject(self.focus_timeline_object)
+ duration = absolute_initial_duration + right_gap.duration
+ self._defaultTo(duration, self.focus.priority)
+
class Timeline(Signallable, Loggable):
"""
Top-level container for L{TimelineObject}s.
diff --git a/tests/test_timeline.py b/tests/test_timeline.py
index 587908d..821fca6 100644
--- a/tests/test_timeline.py
+++ b/tests/test_timeline.py
@@ -1149,33 +1149,54 @@ class TestContexts(TestCase):
def testTrimStartContext(self):
self.track_object1.start = 1 * gst.SECOND
self.track_object1.in_point = 3 * gst.SECOND
- self.track_object2.start = 1 * gst.SECOND
+ self.track_object1.duration = 10 * gst.SECOND
+ self.track_object2.start = 11 * gst.SECOND
self.track_object2.in_point = 10 * gst.SECOND
- self.track_object3.start = 15 * gst.SECOND
+ self.track_object2.duration = 10 * gst.SECOND
+ self.track_object3.start = 25 * gst.SECOND
self.track_object3.in_point = 20 * gst.SECOND
+ self.track_object3.duration = 10 * gst.SECOND
# set up the initial state of the timeline and create the track object
# [focus] [t2 ] [t3 ]
context = TrimStartContext(self.timeline, self.track_object1, self.other)
- context.editTo(gst.SECOND * 10, 0)
+ context.editTo(gst.SECOND * 5, 0)
context.finish()
- self.failUnlessEqual(self.track_object1.start, 10 * gst.SECOND)
- self.failUnlessEqual(self.track_object1.in_point, 12 * gst.SECOND)
- self.failUnlessEqual(self.track_object2.start, 1 * gst.SECOND)
+ self.failUnlessEqual(self.track_object1.start, 5 * gst.SECOND)
+ self.failUnlessEqual(self.track_object1.in_point, 7 * gst.SECOND)
+ self.failUnlessEqual(self.track_object2.start, 11 * gst.SECOND)
self.failUnlessEqual(self.track_object2.in_point, 10 * gst.SECOND)
- self.failUnlessEqual(self.track_object3.start, 15 * gst.SECOND)
+ self.failUnlessEqual(self.track_object3.start, 25 * gst.SECOND)
self.failUnlessEqual(self.track_object3.in_point, 20 * gst.SECOND)
+ def testTrimStartContextMargins(self):
+ self.track_object1.start = 1 * gst.SECOND
+ self.track_object1.in_point = 2 * gst.SECOND
+ self.track_object1.duration = 10 * gst.SECOND
+ self.track_object2.start = 12 * gst.SECOND
+ self.track_object2.in_point = 3 * gst.SECOND
+ self.track_object2.duration = 10 * gst.SECOND
+
+ context = TrimStartContext(self.timeline, self.track_object2, self.other)
+ context.editTo(gst.SECOND * 9, 0)
+ context.finish()
+
+ self.failUnlessEqual(self.track_object1.start, 1 * gst.SECOND)
+ self.failUnlessEqual(self.track_object1.in_point, 2 * 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.in_point, 2 * gst.SECOND)
+ self.failUnlessEqual(self.track_object2.duration, 11 * gst.SECOND)
def testTrimEndContext(self):
self.track_object1.start = 1 * gst.SECOND
self.track_object1.in_point = 3 * gst.SECOND
self.track_object1.duration = 15 * gst.SECOND
- self.track_object2.start = 1 * gst.SECOND
+ self.track_object2.start = 16 * gst.SECOND
self.track_object2.in_point = 10 * gst.SECOND
self.track_object2.duration = 16 * gst.SECOND
- self.track_object3.start = 15 * gst.SECOND
+ self.track_object3.start = 32 * gst.SECOND
self.track_object3.in_point = 19 * gst.SECOND
self.track_object3.duration = 23 * gst.SECOND
@@ -1186,13 +1207,32 @@ class TestContexts(TestCase):
self.failUnlessEqual(self.track_object1.start, 1 * gst.SECOND)
self.failUnlessEqual(self.track_object1.in_point, 3 * gst.SECOND)
self.failUnlessEqual(self.track_object1.duration, 9 * gst.SECOND)
- self.failUnlessEqual(self.track_object2.start, 1 * gst.SECOND)
+ self.failUnlessEqual(self.track_object2.start, 16 * gst.SECOND)
self.failUnlessEqual(self.track_object2.in_point, 10 * gst.SECOND)
self.failUnlessEqual(self.track_object2.duration, 16 * gst.SECOND)
- self.failUnlessEqual(self.track_object3.start, 15 * gst.SECOND)
+ self.failUnlessEqual(self.track_object3.start, 32 * gst.SECOND)
self.failUnlessEqual(self.track_object3.in_point, 19 * gst.SECOND)
self.failUnlessEqual(self.track_object3.duration, 23 * gst.SECOND)
+ def testTrimEndContextMargins(self):
+ self.track_object1.start = 1 * gst.SECOND
+ self.track_object1.in_point = 2 * gst.SECOND
+ self.track_object1.duration = 10 * gst.SECOND
+ self.track_object2.start = 12 * gst.SECOND
+ self.track_object2.in_point = 3 * gst.SECOND
+ self.track_object2.duration = 10 * gst.SECOND
+
+ context = TrimEndContext(self.timeline, self.track_object1, self.other)
+ context.editTo(gst.SECOND * 13, 0)
+ context.finish()
+
+ self.failUnlessEqual(self.track_object1.start, 1 * gst.SECOND)
+ self.failUnlessEqual(self.track_object1.in_point, 2 * gst.SECOND)
+ self.failUnlessEqual(self.track_object1.duration, 11 * gst.SECOND)
+ self.failUnlessEqual(self.track_object2.start, 12 * gst.SECOND)
+ self.failUnlessEqual(self.track_object2.in_point, 3 * gst.SECOND)
+ self.failUnlessEqual(self.track_object2.duration, 10 * gst.SECOND)
+
def testEmptyOther(self):
context = MoveContext(self.timeline, self.track_object1, set())
context.finish()
diff --git a/tests/test_track.py b/tests/test_track.py
index aa41697..f862d52 100644
--- a/tests/test_track.py
+++ b/tests/test_track.py
@@ -203,16 +203,33 @@ class TestTrackObject(TestCase):
# trim somewhere in the middle
monitor = TrackSignalMonitor(obj)
- time = 4 * gst.SECOND
+ time = 7 * gst.SECOND
obj.trimStart(time)
self.failUnlessEqual(obj.start, time)
- self.failUnlessEqual(obj.in_point, 3 * gst.SECOND)
- self.failUnlessEqual(obj.duration, 8 * gst.SECOND)
+ self.failUnlessEqual(obj.in_point, 6 * gst.SECOND)
+ self.failUnlessEqual(obj.duration, 5 * gst.SECOND)
self.failUnlessEqual(obj.rate, 1)
self.failUnlessEqual(monitor.start_changed_count, 1)
self.failUnlessEqual(monitor.in_point_changed_count, 1)
self.failUnlessEqual(monitor.duration_changed_count, 1)
+ obj.start = 10 * gst.SECOND
+ obj.in_point = 11 * gst.SECOND
+ obj.duration = 15 * gst.SECOND
+
+ # this should be possible
+ monitor = TrackSignalMonitor(obj)
+ time = 0 * gst.SECOND
+ obj.trimStart(time)
+ self.failUnlessEqual(obj.start, 0 * gst.SECOND)
+ self.failUnlessEqual(obj.in_point, 1 * gst.SECOND)
+ self.failUnlessEqual(obj.duration, 25 * gst.SECOND)
+ self.failUnlessEqual(obj.rate, 1)
+ self.failUnlessEqual(monitor.start_changed_count, 1)
+ self.failUnlessEqual(monitor.in_point_changed_count, 1)
+ self.failUnlessEqual(monitor.duration_changed_count, 1)
+
+
def testSplitObject(self):
DURATION = 10 * gst.SECOND
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]