1
# PiTiVi , Non-linear video editor
3
# pitivi/timeline/gap.py
5
# Copyright (c) 2009, Alessandro Decina <alessandro.decina@collabora.co.uk>
7
# This program is free software; you can redistribute it and/or
8
# modify it under the terms of the GNU Lesser General Public
9
# License as published by the Free Software Foundation; either
10
# version 2.1 of the License, or (at your option) any later version.
12
# This program is distributed in the hope that it will be useful,
13
# but WITHOUT ANY WARRANTY; without even the implied warranty of
14
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15
# Lesser General Public License for more details.
17
# You should have received a copy of the GNU Lesser General Public
18
# License along with this program; if not, write to the
19
# Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
20
# Boston, MA 02110-1301, USA.
22
from pitivi.utils import infinity
26
def __init__(self, left_object, right_object, start, duration):
27
self.left_object = left_object
28
self.right_object = right_object
30
self.initial_duration = duration
32
def __cmp__(self, other):
33
if other is None or other is invalid_gap:
35
return cmp(self.duration, other.duration)
38
def findAroundObject(self, timeline_object, priority=-1, tracks=None):
39
from pitivi.timeline.timeline import TimelineError
41
timeline = timeline_object.timeline
43
prev = timeline.getPreviousTimelineObject(timeline_object,
47
right_object = timeline_object
49
duration = timeline_object.start
52
right_object = timeline_object
53
start = prev.start + prev.duration
54
duration = timeline_object.start - start
56
left_gap = Gap(left_object, right_object, start, duration)
59
next = timeline.getNextTimelineObject(timeline_object,
62
left_object = timeline_object
64
start = timeline_object.start + timeline_object.duration
67
left_object = timeline_object
69
start = timeline_object.start + timeline_object.duration
70
duration = next.start - start
72
right_gap = Gap(left_object, right_object, start, duration)
74
return left_gap, right_gap
77
def findAllGaps(self, objs):
78
"""Find all the gaps in a given set of objects: i.e. find all the
79
spans of time which are covered by no object in the given set"""
84
# examine each object in order of increasing start time
85
for obj in sorted(objs, key=lambda x: x.start):
87
end = obj.start + obj.duration
89
# only if the current object starts after the total timeline
90
# duration is a gap created.
92
gaps.append(Gap(prev, obj, duration, start - duration))
93
duration = max(duration, end)
99
if self.left_object is None and self.right_object is None:
100
return self.initial_duration
102
if self.initial_duration is infinity:
103
return self.initial_duration
105
if self.left_object is None:
106
return self.right_object.start
108
if self.right_object is None:
111
res = self.right_object.start - \
112
(self.left_object.start + self.left_object.duration)
116
class InvalidGap(object):
119
invalid_gap = InvalidGap()
122
class SmallestGapsFinder(object):
123
def __init__(self, internal_objects):
125
self.right_gap = None
126
self.internal_objects = internal_objects
128
def update(self, left_gap, right_gap):
129
self.updateGap(left_gap, "left_gap")
130
self.updateGap(right_gap, "right_gap")
132
def updateGap(self, gap, min_gap_name):
133
if self.isInternalGap(gap):
136
min_gap = getattr(self, min_gap_name)
138
if min_gap is invalid_gap or gap.duration < 0:
139
setattr(self, min_gap_name, invalid_gap)
142
if min_gap is None or gap < min_gap:
143
setattr(self, min_gap_name, gap)
145
def isInternalGap(self, gap):
146
gap_objects = set([gap.left_object, gap.right_object])
148
return gap_objects.issubset(self.internal_objects)