[pitivi] pipeline: Get rid of Seeker



commit f9a143a9b56bbc3c33364636a99814bc7fc7d964
Author: Alexandru Băluț <alexandru balut gmail com>
Date:   Fri Nov 13 23:33:01 2015 +0100

    pipeline: Get rid of Seeker
    
    Fixes https://phabricator.freedesktop.org/T3055
    
    Reviewed-by: Thibault Saunier <tsaunier gnome org>
    Differential Revision: https://phabricator.freedesktop.org/D565

 pitivi/mediafilespreviewer.py |    2 +-
 pitivi/project.py             |   31 ++++++-------
 pitivi/timeline/ruler.py      |   19 ++++++--
 pitivi/timeline/timeline.py   |   10 ++--
 pitivi/titleeditor.py         |    9 ++--
 pitivi/transitions.py         |    6 +-
 pitivi/utils/pipeline.py      |   95 +++++++++-------------------------------
 pitivi/utils/widgets.py       |    1 -
 pitivi/viewer.py              |   62 +++++++++++---------------
 9 files changed, 91 insertions(+), 144 deletions(-)
---
diff --git a/pitivi/mediafilespreviewer.py b/pitivi/mediafilespreviewer.py
index 6e257c2..d258c52 100644
--- a/pitivi/mediafilespreviewer.py
+++ b/pitivi/mediafilespreviewer.py
@@ -108,7 +108,7 @@ class PreviewWidget(Gtk.Grid, Loggable):
 
         # Gui elements:
         # Drawing area for video output
-        self.preview_video = ViewerWidget(self.player.video_sink)
+        self.preview_video = ViewerWidget(self.player)
         self.preview_video.props.hexpand = minimal
         self.preview_video.props.vexpand = minimal
         self.preview_video.show_all()
diff --git a/pitivi/project.py b/pitivi/project.py
index a0e9af0..a30ba49 100644
--- a/pitivi/project.py
+++ b/pitivi/project.py
@@ -24,34 +24,34 @@
 Project related classes
 """
 
+import datetime
 import os
+import pwd
+import tarfile
+import time
+
 from gi.repository import GstPbutils
 from gi.repository import GES
 from gi.repository import Gst
 from gi.repository import Gtk
 from gi.repository import GLib
 from gi.repository import GObject
-import tarfile
 
-from time import time
-from datetime import datetime
 from gettext import gettext as _
-from pwd import getpwuid
 
 from pitivi.configure import get_ui_dir
+from pitivi.preset import AudioPresetManager, VideoPresetManager
+from pitivi.render import CachedEncoderList
 from pitivi.undo.undo import UndoableAction
-from pitivi.utils.validate import has_validate, create_monitor
-from pitivi.utils.misc import quote_uri, path_from_uri, isWritable, unicode_error_dialog
-from pitivi.utils.pipeline import PipelineError, Seeker
 from pitivi.utils.loggable import Loggable
-from pitivi.utils.pipeline import Pipeline
-from pitivi.utils.widgets import FractionWidget
+from pitivi.utils.misc import quote_uri, path_from_uri, isWritable, unicode_error_dialog
+from pitivi.utils.pipeline import Pipeline, PipelineError
 from pitivi.utils.ripple_update_group import RippleUpdateGroup
 from pitivi.utils.ui import frame_rates, audio_rates,\
     audio_channels, beautify_time_delta, get_combo_value, set_combo_value,\
     pixel_aspect_ratios, display_aspect_ratios, SPACING
-from pitivi.preset import AudioPresetManager, VideoPresetManager
-from pitivi.render import CachedEncoderList
+from pitivi.utils.validate import has_validate, create_monitor
+from pitivi.utils.widgets import FractionWidget
 
 
 DEFAULT_NAME = _("New Project")
@@ -592,7 +592,7 @@ class ProjectManager(GObject.Object, Loggable):
         project = Project(self.app, name=DEFAULT_NAME)
 
         # setting default values for project metadata
-        project.author = getpwuid(os.getuid()).pw_gecos.split(",")[0]
+        project.author = pwd.getpwuid(os.getuid()).pw_gecos.split(",")[0]
 
         project.createTimeline()
         project._ensureTracks()
@@ -604,7 +604,7 @@ class ProjectManager(GObject.Object, Loggable):
         project.pipeline.connect("died", self._pipelineDied)
         project.setModificationState(False)
         self.emit("new-project-loaded", self.current_project, emission)
-        self.time_loaded = time()
+        self.time_loaded = time.time()
 
         return True
 
@@ -680,7 +680,7 @@ class ProjectManager(GObject.Object, Loggable):
         self.emit("new-project-loaded", self.current_project, True)
         if self.__missing_uris:
             self.current_project.setModificationState(True)
-        self.time_loaded = time()
+        self.time_loaded = time.time()
 
 
 class Project(Loggable, GES.Project):
@@ -726,7 +726,6 @@ class Project(Loggable, GES.Project):
         self.log("name:%s, uri:%s", name, uri)
         self.pipeline = None
         self.timeline = None
-        self.seeker = Seeker()
         self.uri = uri
         self.loaded = False
         self._at_least_one_asset_missing = False
@@ -1696,7 +1695,7 @@ class ProjectSettingsDialog(object):
         if self.project.year:
             year = int(self.project.year)
         else:
-            year = datetime.now().year
+            year = datetime.datetime.now().year
         self.year_spinbutton.get_adjustment().set_value(year)
 
     def updateProject(self):
diff --git a/pitivi/timeline/ruler.py b/pitivi/timeline/ruler.py
index 52af7ff..14f4575 100644
--- a/pitivi/timeline/ruler.py
+++ b/pitivi/timeline/ruler.py
@@ -33,7 +33,6 @@ from gettext import gettext as _
 
 from pitivi import configure
 from pitivi.utils.loggable import Loggable
-from pitivi.utils.pipeline import Seeker
 from pitivi.utils.timeline import Zoomable
 from pitivi.utils.ui import NORMAL_FONT, PLAYHEAD_WIDTH, set_cairo_color, time_to_string, beautify_length
 
@@ -92,6 +91,9 @@ class ScaleRuler(Gtk.DrawingArea, Zoomable, Loggable):
 
     Displays a series of consecutive intervals. For each interval its beginning
     time is shown. If zoomed in enough, shows the frames in alternate colors.
+
+    @type timeline: L{pitivi.timeline.timeline.TimelineContainer}
+    @type _pipeline: L{pitivi.utils.pipeline.Pipeline}
     """
 
     def __init__(self, timeline, hadj):
@@ -101,7 +103,7 @@ class ScaleRuler(Gtk.DrawingArea, Zoomable, Loggable):
         self.log("Creating new ScaleRuler")
 
         self.timeline = timeline
-        self._seeker = Seeker()
+        self._pipeline = None
         self.hadj = hadj
         hadj.connect("value-changed", self._hadjValueChangedCb)
         self.add_events(Gdk.EventMask.POINTER_MOTION_MASK |
@@ -135,7 +137,8 @@ class ScaleRuler(Gtk.DrawingArea, Zoomable, Loggable):
 # Timeline position changed method
 
     def setPipeline(self, pipeline):
-        pipeline.connect('position', self.timelinePositionCb)
+        self._pipeline = pipeline
+        self._pipeline.connect('position', self.timelinePositionCb)
 
     def timelinePositionCb(self, unused_pipeline, position):
         self.position = position
@@ -188,9 +191,12 @@ class ScaleRuler(Gtk.DrawingArea, Zoomable, Loggable):
         return False
 
     def do_button_press_event(self, event):
+        if not self._pipeline:
+            return False
+
         self.debug("button pressed at x:%d", event.x)
         position = self.pixelToNs(event.x + self.pixbuf_offset)
-        self._seeker.seek(position)
+        self._pipeline.simple_seek(position)
         return False
 
     def do_button_release_event(self, event):
@@ -199,12 +205,15 @@ class ScaleRuler(Gtk.DrawingArea, Zoomable, Loggable):
         return False
 
     def do_motion_notify_event(self, event):
+        if not self._pipeline:
+            return False
+
         position = self.pixelToNs(event.x + self.pixbuf_offset)
         seek_mask = (Gdk.ModifierType.BUTTON3_MASK |
                      Gdk.ModifierType.BUTTON1_MASK)
         if event.state & seek_mask:
             self.debug("motion at event.x %d", event.x)
-            self._seeker.seek(position)
+            self._pipeline.simple_seek(position)
 
         human_time = beautify_length(position)
         cur_frame = int(position / self.ns_per_frame) + 1
diff --git a/pitivi/timeline/timeline.py b/pitivi/timeline/timeline.py
index 3903791..2bdc136 100644
--- a/pitivi/timeline/timeline.py
+++ b/pitivi/timeline/timeline.py
@@ -212,6 +212,8 @@ class Marquee(Gtk.Box, Loggable):
 class Timeline(Gtk.EventBox, Zoomable, Loggable):
     """
     Contains the layer controls and the layers representation.
+
+    @type _project: L{pitivi.project.Project}
     """
 
     __gtype_name__ = "PitiviTimeline"
@@ -684,7 +686,7 @@ class Timeline(Gtk.EventBox, Zoomable, Loggable):
         x -= CONTROL_WIDTH
         x += self.hadj.get_value()
         position = max(0, self.pixelToNs(x))
-        self._project.seeker.seek(position)
+        self._project.pipeline.simple_seek(position)
 
     def __scroll(self, event):
         # determine how much to move the canvas
@@ -1720,14 +1722,14 @@ class TimelineContainer(Gtk.Grid, Zoomable, Loggable):
         # shortcuts
         if event.keyval == Gdk.KEY_Left:
             if self._shiftMask:
-                self._seeker.seekRelative(0 - Gst.SECOND)
+                self._project.pipeline.seekRelative(0 - Gst.SECOND)
             else:
                 self._project.pipeline.stepFrame(self._framerate, -1)
             self.timeline.scrollToPlayhead(align=Gtk.Align.CENTER, when_not_in_view=True)
             return True
         elif event.keyval == Gdk.KEY_Right:
             if self._shiftMask:
-                self._seeker.seekRelative(Gst.SECOND)
+                self._project.pipeline.seekRelative(Gst.SECOND)
             else:
                 self._project.pipeline.stepFrame(self._framerate, 1)
             self.timeline.scrollToPlayhead(align=Gtk.Align.CENTER, when_not_in_view=True)
@@ -1778,7 +1780,6 @@ class TimelineContainer(Gtk.Grid, Zoomable, Loggable):
         """
         assert self._project is project
         if self._project:
-            self._seeker = self._project.seeker
             self.ruler.setPipeline(self._project.pipeline)
 
             self.ruler.setProjectFrameRate(self._project.videorate)
@@ -1805,7 +1806,6 @@ class TimelineContainer(Gtk.Grid, Zoomable, Loggable):
                 pass  # We were not connected no problem
 
             self.timeline._pipeline = None
-            self._seeker = None
 
         self.setProject(project)
 
diff --git a/pitivi/titleeditor.py b/pitivi/titleeditor.py
index 5325c0d..34b9eea 100644
--- a/pitivi/titleeditor.py
+++ b/pitivi/titleeditor.py
@@ -30,7 +30,6 @@ from gettext import gettext as _
 
 from pitivi.configure import get_ui_dir
 from pitivi.utils.loggable import Loggable
-from pitivi.utils.pipeline import Seeker
 from pitivi.utils.timeline import SELECT
 from pitivi.utils.ui import argb_to_gdk_rgba, gdk_rgba_to_argb
 
@@ -48,6 +47,7 @@ class TitleEditor(Loggable):
     Widget for configuring the selected title.
 
     @type app: L{Pitivi}
+    @type _project: L{pitivi.project.Project}
     """
 
     def __init__(self, app):
@@ -56,7 +56,7 @@ class TitleEditor(Loggable):
         self.action_log = app.action_log
         self.settings = {}
         self.source = None
-        self.seeker = Seeker()
+        self._project = None
         self._selection = None
 
         self._setting_props = False
@@ -229,7 +229,7 @@ class TitleEditor(Loggable):
 
     def _propertyChangedCb(self, source, unused_gstelement, pspec):
         if self._setting_props:
-            self.seeker.flush()
+            self._project.pipeline.flushSeek()
             return
 
         value = self.source.get_child_property(pspec.name)[1]
@@ -263,7 +263,7 @@ class TitleEditor(Loggable):
                 return
             self.background_color_button.set_rgba(color)
 
-        self.seeker.flush()
+        self._project.pipeline.flushSeek()
 
     def _newProjectLoadedCb(self, app, project, unused_fully_loaded):
         if self._selection is not None:
@@ -272,6 +272,7 @@ class TitleEditor(Loggable):
         if project:
             self._selection = project.timeline.ui.selection
             self._selection.connect('selection-changed', self._selectionChangedCb)
+        self._project = project
 
     def _selectionChangedCb(self, selection):
         selected_clip = selection.getSingleClip(GES.TitleClip)
diff --git a/pitivi/transitions.py b/pitivi/transitions.py
index dd5e37a..7fd56ad 100644
--- a/pitivi/transitions.py
+++ b/pitivi/transitions.py
@@ -182,7 +182,7 @@ class TransitionsListWidget(Gtk.Box, Loggable):
         self.app.write_action("element-set-asset", {
             "asset-id": transition_asset.get_id(),
             "element-name": self.element.get_name()})
-        self.app.project_manager.current_project.seeker.flush(True)
+        self.app.project_manager.current_project.pipeline.flushSeek()
 
         return True
 
@@ -191,14 +191,14 @@ class TransitionsListWidget(Gtk.Box, Loggable):
         self.debug("User changed the border property to %s", value)
         self.element.set_border(int(value))
         self.app.project_manager.current_project.setModificationState(True)
-        self.app.project_manager.current_project.seeker.flush(True)
+        self.app.project_manager.current_project.pipeline.flushSeek()
 
     def _invertCheckboxCb(self, widget):
         value = widget.get_active()
         self.debug("User changed the invert property to %s", value)
         self.element.set_inverted(value)
         self.app.project_manager.current_project.setModificationState(True)
-        self.app.project_manager.current_project.seeker.flush()
+        self.app.project_manager.current_project.pipeline.flushSeek()
 
     def _borderTypeChangedCb(self, widget):
         self.__updateBorderScale(widget == self.border_mode_loop)
diff --git a/pitivi/utils/pipeline.py b/pitivi/utils/pipeline.py
index c7323aa..8fe0e88 100644
--- a/pitivi/utils/pipeline.py
+++ b/pitivi/utils/pipeline.py
@@ -24,6 +24,7 @@
 """
 High-level pipelines
 """
+
 import os
 
 from gi.repository import GLib
@@ -57,52 +58,6 @@ class PipelineError(Exception):
     pass
 
 
-class Seeker(GObject.Object, Loggable):
-
-    """
-    The Seeker is a singleton helper class to do various seeking
-    operations in the pipeline.
-    """
-
-    _instance = None
-
-    __gsignals__ = {
-        "seek": (GObject.SIGNAL_RUN_LAST, None, (GObject.TYPE_UINT64,)),
-        "seek-relative": (GObject.SIGNAL_RUN_LAST, None, (GObject.TYPE_INT64,)),
-    }
-
-    def __new__(cls, *args, **kwargs):
-        """
-        Override the new method to return the singleton instance if available.
-        Otherwise, create one.
-        """
-        if not cls._instance:
-            cls._instance = super(Seeker, cls).__new__(cls, *args, **kwargs)
-        return cls._instance
-
-    def __init__(self):
-        GObject.Object.__init__(self)
-        Loggable.__init__(self)
-
-    def seek(self, position):
-        position = max(0, position)
-        try:
-            self.emit('seek', position)
-        except PipelineError as e:
-            self.error("Error while seeking to position: %s, reason: %s",
-                       format_ns(position), e)
-
-    def seekRelative(self, time):
-        time = int(time)
-        try:
-            self.emit('seek-relative', time)
-        except PipelineError:
-            self.error("Error while seeking %s relative", time)
-
-    def flush(self):
-        self.seekRelative(0)
-
-
 class SimplePipeline(GObject.Object, Loggable):
 
     """
@@ -117,6 +72,8 @@ class SimplePipeline(GObject.Object, Loggable):
      - C{position} : The current position of the pipeline changed.
      - C{eos} : The Pipeline has finished playing.
      - C{error} : An error happened.
+
+    @type _pipeline: L{Gst.Pipeline}
     """
 
     __gsignals__ = PIPELINE_SIGNALS
@@ -191,7 +148,7 @@ class SimplePipeline(GObject.Object, Loggable):
             return
 
         try:
-            self.seekRelative(0)
+            self.simple_seek(self.getPosition())
         except PipelineError as e:
             self.warning("Could not flush because: %s", e)
             pass
@@ -397,9 +354,13 @@ class SimplePipeline(GObject.Object, Loggable):
         # clamp between [0, duration]
         position = max(0, min(position, self.getDuration()))
 
-        res = self._pipeline.seek(1.0, Gst.Format.TIME, Gst.SeekFlags.FLUSH | Gst.SeekFlags.ACCURATE,
-                                  Gst.SeekType.SET, position,
-                                  Gst.SeekType.NONE, -1)
+        res = self._pipeline.seek(1.0,
+                                  Gst.Format.TIME,
+                                  Gst.SeekFlags.FLUSH | Gst.SeekFlags.ACCURATE,
+                                  Gst.SeekType.SET,
+                                  position,
+                                  Gst.SeekType.NONE,
+                                  -1)
         self._addWaitingForAsyncDoneTimeout()
 
         if not res:
@@ -411,7 +372,10 @@ class SimplePipeline(GObject.Object, Loggable):
         self.emit('position', position)
 
     def seekRelative(self, time_delta):
-        self.simple_seek(self.getPosition() + time_delta)
+        try:
+            self.simple_seek(self.getPosition() + int(time_delta))
+        except PipelineError:
+            self.error("Error while seeking %s relative", time_delta)
 
     # Private methods
 
@@ -568,12 +532,11 @@ class Pipeline(GES.Pipeline, SimplePipeline):
 
     """
     Helper to handle GES.Pipeline through the SimplePipeline API
-    and handle the Seeker properly
     """
 
     __gsignals__ = PIPELINE_SIGNALS
 
-    def __init__(self, app, pipeline=None):
+    def __init__(self, app):
         GES.Pipeline.__init__(self)
         SimplePipeline.__init__(self, self)
 
@@ -583,9 +546,6 @@ class Pipeline(GES.Pipeline, SimplePipeline):
         self._commit_wanted = False
 
         self._timeline = None
-        self._seeker = Seeker()
-        self._seeker.connect("seek", self._seekCb)
-        self._seeker.connect("seek-relative", self._seekRelativeCb)
 
         if "watchdog" in os.environ.get("PITIVI_UNSTABLE_FEATURES", ''):
             watchdog = Gst.ElementFactory.make("watchdog", None)
@@ -618,13 +578,8 @@ class Pipeline(GES.Pipeline, SimplePipeline):
 
         @postcondition: The L{Pipeline} will no longer be usable.
         """
-        self._seeker.disconnect_by_func(self._seekRelativeCb)
-        self._seeker.disconnect_by_func(self._seekCb)
         SimplePipeline.release(self)
 
-    def _seekRelativeCb(self, unused_seeker, time_delta):
-        self.seekRelative(time_delta)
-
     def stepFrame(self, framerate, frames_offset):
         """
         Seek backwards or forwards a certain amount of frames (frames_offset).
@@ -649,33 +604,27 @@ class Pipeline(GES.Pipeline, SimplePipeline):
                       new_pos / float(Gst.SECOND))
         self.simple_seek(new_pos)
 
-    def _seekCb(self, unused_seeker, position):
-        """
-        The app's main seek method used when the user seeks manually.
-
-        We clamp the seeker position so that it cannot go past 0 or the
-        end of the timeline.
-        """
-        self.simple_seek(position)
-
     def simple_seek(self, position):
         if self._timeline.is_empty():
+            # Nowhere to seek.
             return
 
         if self._rendering():
             raise PipelineError("Trying to seek while rendering")
 
         st = Gst.Structure.new_empty("seek")
-
         if self.getState() == Gst.State.PLAYING:
             st.set_value("playback_time", float(
                 self.getPosition()) / Gst.SECOND)
-
         st.set_value("start", float(position / Gst.SECOND))
         st.set_value("flags", "accurate+flush")
         self.app.write_action(st)
 
-        SimplePipeline.simple_seek(self, position)
+        try:
+            SimplePipeline.simple_seek(self, position)
+        except PipelineError as e:
+            self.error("Error while seeking to position: %s, reason: %s",
+                       format_ns(position), e)
 
     def _busMessageCb(self, bus, message):
         if message.type == Gst.MessageType.ASYNC_DONE:
diff --git a/pitivi/utils/widgets.py b/pitivi/utils/widgets.py
index 47e292b..f50d09c 100644
--- a/pitivi/utils/widgets.py
+++ b/pitivi/utils/widgets.py
@@ -316,7 +316,6 @@ class TimeWidget(TextWidget, DynamicWidget):
             # We were given a frame number. Convert from the project framerate.
             frame_no = int(timecode)
             nanosecs = frame_no / float(self._framerate) * Gst.SECOND
-        # The seeker won't like floating point nanoseconds!
         return int(nanosecs)
 
     def setWidgetValue(self, timeNanos, send_signal=True):
diff --git a/pitivi/viewer.py b/pitivi/viewer.py
index 1392bdc..26311f8 100644
--- a/pitivi/viewer.py
+++ b/pitivi/viewer.py
@@ -31,7 +31,7 @@ from time import time
 from pitivi.settings import GlobalSettings
 from pitivi.utils.loggable import Loggable
 from pitivi.utils.misc import format_ns
-from pitivi.utils.pipeline import AssetPipeline, Seeker
+from pitivi.utils.pipeline import AssetPipeline
 from pitivi.utils.ui import SPACING
 from pitivi.utils.widgets import TimeWidget
 
@@ -66,7 +66,10 @@ class ViewerContainer(Gtk.Box, Loggable):
 
     """
     A wiget holding a viewer and the controls.
+
+    @type pipeline: L{pitivi.utils.pipeline.SimplePipeline}
     """
+
     __gtype_name__ = 'ViewerContainer'
     __gsignals__ = {
         "activate-playback-controls": (GObject.SignalFlags.RUN_LAST,
@@ -87,7 +90,6 @@ class ViewerContainer(Gtk.Box, Loggable):
 
         self.pipeline = None
         self.docked = True
-        self.seeker = Seeker()
         self.target = None
         self._compactMode = False
 
@@ -123,7 +125,7 @@ class ViewerContainer(Gtk.Box, Loggable):
         self.debug("New pipeline: %r", pipeline)
         self.pipeline = pipeline
         if position:
-            self.seeker.seek(position)
+            self.pipeline.simple_seek(position)
 
         self.pipeline.connect("state-change", self._pipelineStateChangedCb)
         self.pipeline.connect("position", self._positionCb)
@@ -139,7 +141,7 @@ class ViewerContainer(Gtk.Box, Loggable):
         self.sink = self.pipeline.createSink()
         self.pipeline.setSink(self.sink)
 
-        self.target = ViewerWidget(self.sink, self.app)
+        self.target = ViewerWidget(self.pipeline, self.app)
 
         if self.docked:
             self.pack_start(self.target, True, True, 0)
@@ -296,7 +298,7 @@ class ViewerContainer(Gtk.Box, Loggable):
 
     def _entryActivateCb(self, unused_entry):
         nanoseconds = self.timecode_entry.getWidgetValue()
-        self.seeker.seek(nanoseconds)
+        self.app.project_manager.current_project.pipeline.simple_seek(nanoseconds)
         self.app.gui.timeline_ui.timeline.scrollToPlayhead(align=Gtk.Align.CENTER, when_not_in_view=True)
 
     # Active Timeline calllbacks
@@ -311,25 +313,25 @@ class ViewerContainer(Gtk.Box, Loggable):
         self.app.gui.focusTimeline()
 
     def _goToStartCb(self, unused_button):
-        self.seeker.seek(0)
+        self.app.project_manager.current_project.pipeline.simple_seek(0)
         self.app.gui.focusTimeline()
         self.app.gui.timeline_ui.timeline.scrollToPlayhead(align=Gtk.Align.START, when_not_in_view=True)
 
     def _backCb(self, unused_button):
         # Seek backwards one second
-        self.seeker.seekRelative(0 - Gst.SECOND)
+        self.app.project_manager.current_project.pipeline.seekRelative(0 - Gst.SECOND)
         self.app.gui.focusTimeline()
         self.app.gui.timeline_ui.timeline.scrollToPlayhead(align=Gtk.Align.END, when_not_in_view=True)
 
     def _forwardCb(self, unused_button):
         # Seek forward one second
-        self.seeker.seekRelative(Gst.SECOND)
+        self.app.project_manager.current_project.pipeline.seekRelative(Gst.SECOND)
         self.app.gui.focusTimeline()
         self.app.gui.timeline_ui.timeline.scrollToPlayhead(align=Gtk.Align.START, when_not_in_view=True)
 
     def _goToEndCb(self, unused_button):
         end = self.app.project_manager.current_project.pipeline.getDuration()
-        self.seeker.seek(end)
+        self.app.project_manager.current_project.pipeline.simple_seek(end)
         self.app.gui.focusTimeline()
         self.app.gui.timeline_ui.timeline.scrollToPlayhead(align=Gtk.Align.CENTER, when_not_in_view=True)
 
@@ -368,7 +370,7 @@ class ViewerContainer(Gtk.Box, Loggable):
             self.settings.viewerWidth, self.settings.viewerHeight)
         if self.pipeline:
             self.pipeline.pause()
-            self.seeker.seek(position)
+            self.pipeline.simple_seek(position)
 
     def dock(self):
         if self.docked:
@@ -393,7 +395,7 @@ class ViewerContainer(Gtk.Box, Loggable):
         self.external_window.hide()
         if position:
             self.pipeline.pause()
-            self.seeker.seek(position)
+            self.pipeline.simple_seek(position)
 
     def _toggleFullscreen(self, widget):
         if widget.get_active():
@@ -491,6 +493,8 @@ class TransformationBox(Gtk.EventBox, Loggable):
         self.app = app
         self.__editSource = None
         self.__startDraggingPosition = None
+        self.__startEditSourcePosition = None
+
         self.add_events(Gdk.EventMask.SCROLL_MASK)
 
     def __setupEditSource(self):
@@ -613,56 +617,42 @@ class ViewerWidget(Gtk.AspectFrame, Loggable):
     """
     Widget for displaying a GStreamer video sink.
 
-    @ivar settings: The settings of the application.
-    @type settings: L{GlobalSettings}
+    @type _pipeline: L{pitivi.utils.pipeline.SimplePipeline}
     """
 
     __gsignals__ = {}
 
-    def __init__(self, sink, app=None):
+    def __init__(self, pipeline, app=None):
         # Prevent black frames and flickering while resizing or changing focus:
         # The aspect ratio gets overridden by setDisplayAspectRatio.
         Gtk.AspectFrame.__init__(self, xalign=0.5, yalign=0.5,
                                  ratio=4.0 / 3.0, obey_child=False)
         Loggable.__init__(self)
-        self.__transformationBox = TransformationBox(app)
+
+        self._pipeline = pipeline
+
+        transformation_box = TransformationBox(app)
+        self.add(transformation_box)
 
         # We only work with a gtkglsink inside a glsinkbin
+        sink = pipeline.video_sink
         try:
             self.drawing_area = sink.props.sink.props.widget
         except AttributeError:
             self.drawing_area = sink.props.widget
+        self.drawing_area.show()
+        transformation_box.add(self.drawing_area)
 
         # We keep the ViewerWidget hidden initially, or the desktop wallpaper
         # would show through the non-double-buffered widget!
-        self.add(self.__transformationBox)
-        self.__transformationBox.add(self.drawing_area)
-
-        self.drawing_area.show()
-
-        self.seeker = Seeker()
-        if app:
-            self.settings = app.settings
-        self.app = app
-        self.box = None
-        self.stored = False
-        self.area = None
-        self.zoom = 1.0
-        self.sink = sink
-        self.transformation_properties = None
-        self._setting_ratio = False
-        self.__startDraggingPosition = None
-        self.__startEditSourcePosition = None
-        self.__editSource = None
 
     def setDisplayAspectRatio(self, ratio):
-        self._setting_ratio = True
         self.set_property("ratio", float(ratio))
 
     def _sizeCb(self, unused_widget, unused_area):
         # The transformation box is cleared when using regular rendering
         # so we need to flush the pipeline
-        self.seeker.flush()
+        self._pipeline.flushSeek()
 
     def do_get_preferred_width(self):
         # Do not let a chance for Gtk to choose video natural size


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]