[pitivi/ges: 60/287] Properly handle projects and seeking



commit 0e208608c6d5e0c163c75e28141f94755bc360e6
Author: Thibault Saunier <thibault saunier collabora com>
Date:   Sat Oct 8 15:00:10 2011 -0300

    Properly handle projects and seeking
    
    Avoid using receiver as much as possible.

 pitivi/application.py             |    1 -
 pitivi/project.py                 |   19 ++++++++-
 pitivi/projectmanager.py          |   47 +++++++++++-----------
 pitivi/sourcelist.py              |   11 +++++-
 pitivi/ui/effectsconfiguration.py |    1 -
 pitivi/ui/mainwindow.py           |   78 +++++++++++++++++++-----------------
 pitivi/ui/previewer.py            |    2 +-
 pitivi/ui/sourcelist.py           |   21 +++++++---
 pitivi/ui/timeline.py             |   78 +++++++++++++++++++++++--------------
 pitivi/ui/timelinecanvas.py       |   31 +++++++++------
 pitivi/ui/timelinecontrols.py     |   37 ++++++++++++------
 pitivi/ui/track.py                |    1 -
 pitivi/ui/trackobject.py          |    1 -
 pitivi/ui/viewer.py               |   25 +++--------
 14 files changed, 206 insertions(+), 147 deletions(-)
---
diff --git a/pitivi/application.py b/pitivi/application.py
index e45abe4..f989f37 100644
--- a/pitivi/application.py
+++ b/pitivi/application.py
@@ -372,7 +372,6 @@ class StartupWizardGuiPitivi(FullGuiPitivi):
     def __init__(self, debug=False):
         FullGuiPitivi.__init__(self, debug)
         self.projectManager.newBlankProject(False)
-        self.gui.viewer.setPipeline()
 
     def _createGui(self):
         self.wizard = StartUpWizard(self)
diff --git a/pitivi/project.py b/pitivi/project.py
index 18fc3c3..0d9cfa8 100644
--- a/pitivi/project.py
+++ b/pitivi/project.py
@@ -90,13 +90,17 @@ class Project(Signallable, Loggable):
         self.timeline.selected = []
         self.layer = ges.TimelineLayer()
         self.layer.set_property("auto-transition", True)
+
         self.timeline.add_layer(self.layer)
         self.back_layer = ges.TimelineLayer()
-        self.background = ges.TimelineTestSource()
+        self._background = ges.TimelineTestSource()
         self.back_layer.set_priority(BACKGROUND_PRIORITY)
+
         #FIXME THIS IS SO DIRTY GES port
-        self.background.set_property("duration", 313960000000)
-        self.back_layer.add_object(self.background)
+        for track in self.timeline.get_tracks():
+            track.connect("notify::duration", self._backgroundDurationCb)
+
+        self.back_layer.add_object(self._background)
         self.timeline.add_layer(self.back_layer)
 
         self.pipeline = ges.TimelinePipeline()
@@ -107,6 +111,9 @@ class Project(Signallable, Loggable):
         self.settings = ExportSettings()
         self._videocaps = self.settings.getVideoCaps()
 
+    def _backgroundDurationCb(self, track, unused):
+        self._background.props.duration = track.props.duration
+
     def release(self):
         self.pipeline = None
 
@@ -153,3 +160,9 @@ class Project(Signallable, Loggable):
         if self.pipeline.get_state() != gst.STATE_NULL:
             self.pipeline.set_state(gst.STATE_READY)
             self.pipeline.set_state(gst.STATE_PAUSED)
+
+    def loadSources(self):
+        for layer in self.timeline.get_layers():
+            if layer.props.priority < BACKGROUND_PRIORITY:
+                for obj in layer.get_objects():
+                    self.sources.addUri(obj.get_uri())
diff --git a/pitivi/projectmanager.py b/pitivi/projectmanager.py
index 2a0982d..b7ebdc7 100644
--- a/pitivi/projectmanager.py
+++ b/pitivi/projectmanager.py
@@ -19,17 +19,15 @@
 # Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
 # Boston, MA 02110-1301, USA.
 
-from gettext import gettext as _
 import gobject
 import os
-import gst
 import ges
 
+from gettext import gettext as _
 from urlparse import urlparse
 from pwd import getpwuid
 
 from pitivi.project import Project
-
 from pitivi.signalinterface import Signallable
 from pitivi.log.loggable import Loggable
 from pitivi.undo import UndoableAction
@@ -90,21 +88,23 @@ class ProjectManager(Signallable, Loggable):
         self.current = None
         self.backup_lock = 0
         self.avalaible_effects = avalaible_effects
+        self.formatter = None
 
     def loadProject(self, uri):
 
         """ Load the given project file"""
         self.emit("new-project-loading", uri)
 
-        self.formatter = ges.PitiviFormatter()
+        self.current = Project(uri=uri)
 
-        pipeline = self.current.pipeline
-        pipeline.set_state(gst.STATE_NULL)
         self.timeline = self.current.timeline
-        for layer in self.timeline.get_layers():
-            self.timeline.remove_layer(layer)
-        self.formatter.load_from_uri(self.timeline, uri)
-        pipeline.set_state(gst.STATE_PAUSED)
+        self.formatter = ges.PitiviFormatter()
+
+        if self.formatter.load_from_uri(self.timeline, uri):
+            self.current.connect("project-changed", self._projectChangedCb)
+            self.emit("new-project-loaded", self.current)
+            #FIXME GES hack to make sure sources are added to the sourcelist
+            self.current.loadSources()
 
     def saveProject(self, project, uri=None, overwrite=False, formatter=None, backup=False):
         """
@@ -126,23 +126,24 @@ class ProjectManager(Signallable, Loggable):
 
         @see: L{Formatter.saveProject}
         """
-        if formatter is None:
-            if project.format:
-                formatter = project.format
-            else:
-                from pitivi.formatters.etree import ElementTreeFormatter
-                formatter = ElementTreeFormatter(self.avalaible_effects)
+        #if formatter is None:
+            #if project.format:
+                #formatter = project.format
+            #else:
+        formatter = ges.PitiviFormatter()
 
         if uri is None:
             if project.uri is None:
-                self.emit("save-project-failed", project, uri,
-                        FormatterSaveError(_("No URI specified.")))
+                self.emit("save-project-failed", project, uri)
+                        #FIXME GES port break
+                        #FormatterSaveError(_("No URI specified.")))
                 return
 
             uri = project.uri
 
-        self._connectToFormatter(formatter)
-        return formatter.saveProject(project, uri, overwrite, backup)
+        #FIXME Implement when avalaible in GES
+        #self._connectToFormatter(formatter)
+        return formatter.save_to_uri(project.timeline, uri)
 
     def closeRunningProject(self):
         """ close the current project """
@@ -251,9 +252,9 @@ class ProjectManager(Signallable, Loggable):
             return name + "~" + ext
         return None
 
-    def _getFormatterForUri(self, uri):
-        return get_formatter_for_uri(uri, self.avalaible_effects)
-
+    ###
+    #FIXME reimplement with GES
+    ###
     def _connectToFormatter(self, formatter):
         formatter.connect("missing-uri", self._formatterMissingURICb)
         formatter.connect("new-project-created",
diff --git a/pitivi/sourcelist.py b/pitivi/sourcelist.py
index 35a0afc..a866a31 100644
--- a/pitivi/sourcelist.py
+++ b/pitivi/sourcelist.py
@@ -25,9 +25,12 @@ Handles the list of source for a project
 """
 
 import urllib
+import gst
+
 from pitivi.signalinterface import Signallable
 from pitivi.log.loggable import Loggable
-import gst
+
+from pitivi.ui.timeline import BACKGROUND_PRIORITY
 
 
 class SourceListError(Exception):
@@ -123,6 +126,12 @@ class SourceList(Signallable, Loggable):
             assert info is None
         self.emit("source-removed", uri, info)
 
+    def _newProjectLoadedCb(self, unused_pitivi, project):
+        for layer in project.timeline.get_layers():
+            if layer.props.priority < BACKGROUND_PRIORITY:
+                for obj in layer.get_objects():
+                    self.addUri(obj.get_uri())
+
     def getUri(self, uri):
         """
         Get the source corresponding to C{uri}.
diff --git a/pitivi/ui/effectsconfiguration.py b/pitivi/ui/effectsconfiguration.py
index 166726b..b9ecb3b 100644
--- a/pitivi/ui/effectsconfiguration.py
+++ b/pitivi/ui/effectsconfiguration.py
@@ -60,7 +60,6 @@ class EffectsPropertiesHandling:
 
         self._current_effect_setting_ui = effect_set_ui
         element = self._current_effect_setting_ui.element
-        print element.list_children_properties(), "zobii !"
         for prop in element.list_children_properties():
             self._current_element_values[prop.name] = element.get_child_property(prop.name)
 
diff --git a/pitivi/ui/mainwindow.py b/pitivi/ui/mainwindow.py
index 23ccb68..07eb1d0 100644
--- a/pitivi/ui/mainwindow.py
+++ b/pitivi/ui/mainwindow.py
@@ -29,6 +29,7 @@ import gtk
 import gst
 from urllib import unquote
 import webbrowser
+import gobject
 import ges
 
 from gettext import gettext as _
@@ -43,7 +44,6 @@ from pitivi.configure import pitivi_version, APPNAME, APPURL, \
      get_pixmap_dir, get_ui_dir
 from pitivi.ui import dnd
 from pitivi.settings import GlobalSettings
-from pitivi.receiver import receiver, handler
 from pitivi.sourcelist import SourceListError
 from pitivi.ui.sourcelist import SourceList
 from pitivi.ui.effectlist import EffectList
@@ -542,10 +542,10 @@ class PitiviMainWindow(gtk.Window, Loggable):
 
     def _saveProjectAsCb(self, unused_action):
         uri = self._showSaveAsDialog(self.app.current)
-        formatter = ges.PitiviFormatter()
-        formatter.save_to_uri(self.project.timeline, uri)
+        if uri is not None:
+            return self.app.projectManager.saveProject(self.project, uri, overwrite=True)
 
-        return True
+        return False
 
     def _revertToSavedProjectCb(self, unused_action):
         return self.app.projectManager.revertToSavedProject()
@@ -680,26 +680,24 @@ class PitiviMainWindow(gtk.Window, Loggable):
 
     def _projectManagerNewProjectLoadedCb(self, projectManager, project):
         self.log("A NEW project is loaded, update the UI!")
-        self.project = project
-        self.timeline.project = self.project
-        self.clipconfig.project = self.project
+        self._setProject(project)
+
         #FIXME we should reanable it when possible with GES
         #self._connectToProjectSources(project.sources)
-        duration = 0
-        can_render = duration > 0
-        self._syncDoUndo(self.app.action_log)
+        #self._syncDoUndo(self.app.action_log)
 
+        #FIXME GES reimplement me
         if self._missingUriOnLoading:
             self.app.current.setModificationState(True)
             self.actiongroup.get_action("SaveProject").set_sensitive(True)
             self._missingUriOnLoading = False
 
-        if duration != 0:
+        if self.timeline.duration != 0:
             self.setBestZoomRatio()
         else:
             self._zoom_duration_changed = True
 
-        #self.project.seeker.connect("seek", self._timelineSeekCb)
+        self.project.seeker.connect("seek", self._timelineSeekCb)
 
         # preliminary seek to ensure the project pipeline is configured
         self.project.seeker.seek(0)
@@ -940,14 +938,16 @@ class PitiviMainWindow(gtk.Window, Loggable):
 
 ## PiTiVi current project callbacks
 
-    def _setProject(self):
+    def _setProject(self, project):
+        self.project = project
         if self.project:
             self.project_pipeline = self.project.pipeline
             self.project_timeline = self.project.timeline
+            self.viewer.setPipeline(project.pipeline)
             if self.timeline:
-                self.timeline.project = self.project
+                self.timeline.setProject(self.project)
                 self.clipconfig.project = self.project
-                self.app.timelineLogObserver.pipeline = self.project.pipeline
+                #self.app.timelineLogObserver.pipeline = self.project.pipeline
 
     def _sourceListMissingPluginsCb(self, project, uri, factory,
             details, descriptions, missingPluginsCallback):
@@ -956,32 +956,35 @@ class PitiviMainWindow(gtk.Window, Loggable):
 
 ## Current Project Pipeline
 
-    def _setProjectPipeline(self):
-        if self.project_pipeline:
+    def setProjectPipeline(self, pipeline):
+        self._project_pipeline = pipeline
+        if self._project_pipeline:
             # connect to timeline
-            self.project_pipeline.activatePositionListener()
-            self._timelinePipelinePositionChangedCb(self.project_pipeline, 0)
+            #self.project_pipeline.activatePositionListener()
+            gobject.timeout_add(300, self._timelinePipelinePositionChangedCb)
 
-    project_pipeline = receiver()
+    def getProjectPipeline(self):
+        return self._project_pipeline
 
-    @handler(project_pipeline, "error")
+    project_pipeline = property(getProjectPipeline, setProjectPipeline, None, "The Gst.Pipeline of the project")
+
+    # handler(project_pipeline, "error")
     def _pipelineErrorCb(self, unused_pipeline, error, detail):
         pass
 
-    @handler(project_pipeline, "position")
     def _timelinePipelinePositionChangedCb(self, pipeline, position):
         self.timeline.timelinePositionChanged(position)
         self.timelinepos = position
 
-    @handler(project_pipeline, "state-changed")
+    # handler(project_pipeline, "state-changed")
     def _timelinePipelineStateChangedCb(self, pipeline, state):
         self.timeline.stateChanged(state)
 
 ## Project Timeline (not to be confused with UI timeline)
 
-    project_timeline = receiver()
+    #project_timeline = receiver()
 
-    @handler(project_timeline, "duration-changed")
+    # handler(project_timeline, "duration-changed")
     def _timelineDurationChangedCb(self, timeline, duration):
         if duration > 0:
             sensitive = True
@@ -1066,18 +1069,19 @@ class PitiviMainWindow(gtk.Window, Loggable):
         #GES crazyness... Implement
         pass
 
-    #FIXME GES port, check where the seeking should be done
-    #def _timelineSeekCb(self, ruler, position, format):
-        #self.debug("position:%s", gst.TIME_ARGS(position))
-        #if self.viewer.action != self.project.view_action:
-            #sett = self.project.getSettings()
-            #self.viewer.setDisplayAspectRatio(float(sett.videopar * sett.videowidth) / float(sett.videoheight))
-        ## everything above only needs to be done if the viewer isn't already
-        ## set to the pipeline.
-        #try:
-            #self.project.pipeline.seek(position, format)
-        #except:
-            #self.debug("Seeking failed")
+    def _timelineSeekCb(self, ruler, position, format):
+        try:
+            self.project_pipeline.seek(1.0, format, gst.SEEK_FLAG_FLUSH,
+                                  gst.SEEK_TYPE_SET, position,
+                                  gst.SEEK_TYPE_NONE, -1)
+            if position < 0:
+                position = 0
+            elif position >= self.timeline.getDuration():
+                position = self.timeline.getDuration()
+            self.timeline.timelinePositionChanged(position)
+
+        except Exception, e:
+            self.error("seek failed %s %s %s", gst.TIME_ARGS(position), format, e)
 
     def updateTitle(self):
         name = touched = ""
diff --git a/pitivi/ui/previewer.py b/pitivi/ui/previewer.py
index d421e95..1d7a9c1 100644
--- a/pitivi/ui/previewer.py
+++ b/pitivi/ui/previewer.py
@@ -475,7 +475,7 @@ class RandomAccessAudioPreviewer(RandomAccessPreviewer):
 
     def _busMessageErrorCb(self, bus, message):
         error, debug = message.parse_error()
-        print "Event bus error:", str(error), str(debug)
+        self.error("Event bus error: %s: %s", str(error), str(debug))
 
         return gst.BUS_PASS
 
diff --git a/pitivi/ui/sourcelist.py b/pitivi/ui/sourcelist.py
index 488e7f0..32a91a8 100644
--- a/pitivi/ui/sourcelist.py
+++ b/pitivi/ui/sourcelist.py
@@ -30,13 +30,13 @@ from urllib import unquote
 from gettext import gettext as _
 
 import pitivi.ui.dnd as dnd
-from pitivi.ui.pathwalker import PathWalker, quote_uri
-from pitivi.ui.filelisterrordialog import FileListErrorDialog
 from pitivi.configure import get_pixmap_dir
 from pitivi.signalgroup import SignalGroup
-
 from pitivi.settings import GlobalSettings
 from pitivi.utils import beautify_length
+
+from pitivi.ui.pathwalker import PathWalker, quote_uri
+from pitivi.ui.filelisterrordialog import FileListErrorDialog
 from pitivi.ui.common import beautify_info, info_name, \
     SPACING, PADDING
 from pitivi.log.loggable import Loggable
@@ -116,6 +116,7 @@ class SourceList(gtk.VBox, Loggable):
         self.app = instance
         self.settings = instance.settings
         self._errors = []
+        self._project = None
 
         # Store
         # icon, infotext, objectfactory, uri, length
@@ -991,16 +992,22 @@ class SourceList(gtk.VBox, Loggable):
         return False
 
     def _newProjectCreatedCb(self, app, project):
-        self._resetErrorList()
-        self.storemodel.clear()
-        self._connectToProject(project)
+        if not self._project is project:
+            self._project = project
+            self._resetErrorList()
+            self.storemodel.clear()
+            self._connectToProject(project)
 
     def _newProjectLoadedCb(self, unused_pitivi, project):
-        pass
+        if not self._project is project:
+            self._project = project
+            self.storemodel.clear()
+            self._connectToProject(project)
 
     def _newProjectFailedCb(self, unused_pitivi, unused_reason, unused_uri):
         self.storemodel.clear()
         self.project_signals.disconnectAll()
+        self._project = None
 
     ## Drag and Drop
     def _dndDataReceivedCb(self, unused_widget, unused_context, unused_x,
diff --git a/pitivi/ui/timeline.py b/pitivi/ui/timeline.py
index 8abd7cc..8290f02 100644
--- a/pitivi/ui/timeline.py
+++ b/pitivi/ui/timeline.py
@@ -35,9 +35,8 @@ import ges
 from gettext import gettext as _
 from timelinecanvas import TimelineCanvas
 from timelinecontrols import TimelineControls
-from pitivi.receiver import receiver, handler
 from zoominterface import Zoomable
-from pitivi.ui.common import LAYER_HEIGHT_EXPANDED, LAYER_SPACING, TRACK_SPACING
+from pitivi.ui.common import LAYER_HEIGHT_EXPANDED, LAYER_SPACING
 from pitivi.timeline.timeline import MoveContext, SELECT
 from pitivi.ui.filelisterrordialog import FileListErrorDialog
 from pitivi.ui.common import SPACING
@@ -69,7 +68,7 @@ SELECT_BEFORE = ("Select all sources before selected")
 SELECT_AFTER = ("Select all after selected")
 
 #FIXME We should not use a background when gaps are properly handled in GES
-BACKGROUND_PRIORITY = 500
+BACKGROUND_PRIORITY = 99
 
 ui = '''
 <ui>
@@ -190,7 +189,6 @@ class Timeline(gtk.Table, Loggable, Zoomable):
         self.log("Creating Timeline")
 
         self._updateZoom = True
-        self.project = None
         self.ui_manager = ui_manager
         self.app = instance
         self._temp_objects = None
@@ -201,6 +199,9 @@ class Timeline(gtk.Table, Loggable, Zoomable):
         self._createUI()
         self._prev_duration = 0
         self.rate = gst.Fraction(1, 1)
+        self._project = None
+        self._timeline = None
+        self._duration = 0
 
         self._temp_objects = []
 
@@ -366,8 +367,8 @@ class Timeline(gtk.Table, Loggable, Zoomable):
         mod = event.get_state()
         try:
             if mod & gtk.gdk.CONTROL_MASK:
-                now = self.project.pipeline.getPosition()
-                ltime, rtime = self.project.timeline.edges.closest(now)
+                now = self._project.pipeline.getPosition()
+                ltime, rtime = self._project.timeline.edges.closest(now)
 
             if kv == gtk.keysyms.Left:
                 if mod & gtk.gdk.SHIFT_MASK:
@@ -387,7 +388,7 @@ class Timeline(gtk.Table, Loggable, Zoomable):
             return True
 
     def _seekRelative(self, time):
-        pipeline = self.project.pipeline
+        pipeline = self._project.pipeline
         seekvalue = max(0, min(pipeline.getPosition() + time,
             pipeline.getDuration()))
         self._seeker.seek(seekvalue)
@@ -417,7 +418,7 @@ class Timeline(gtk.Table, Loggable, Zoomable):
         self.app.projectManager.current.timeline.enable_update(True)
 
     def _dragDropCb(self, widget, context, x, y, timestamp):
-            #FIXME GES break, reimplement me
+        #FIXME GES break, reimplement me
         if  context.targets not in DND_EFFECT_LIST:
             self.app.action_log.begin("add clip")
             self.app.action_log.commit()
@@ -443,6 +444,21 @@ class Timeline(gtk.Table, Loggable, Zoomable):
 
         return False
 
+    def setDuration(self, unused1=None, unused2=None):
+        self._duration = 0
+
+        for track in self._timeline.get_tracks():
+            if track.props.duration > self._duration:
+                self._duration = track.props.duration
+
+        self.debug("Duration changed %s", self._duration)
+        return self._duration
+
+    def getDuration(self):
+        return self._duration
+
+    duration = property(getDuration, setDuration, None, "The duration property")
+
     def _dragDataReceivedCb(self, unused_layout, context, x, y,
         selection, targetType, timestamp):
         self.app.projectManager.current.timeline.enable_update(False)
@@ -463,7 +479,7 @@ class Timeline(gtk.Table, Loggable, Zoomable):
 
         if targetType == dnd.TYPE_PITIVI_FILESOURCE:
             uris = selection.data.split("\n")
-            self._factories = [self.project.sources.getUri(uri) for uri in uris]
+            self._factories = [self._project.sources.getUri(uri) for uri in uris]
         else:
             if not self.timeline.timeline_objects:
                 return False
@@ -632,22 +648,22 @@ class Timeline(gtk.Table, Loggable, Zoomable):
 
 ## Project callbacks
 
-    def _setProject(self):
-        if self.project:
-            self.timeline = self.project.timeline
-            self._controls.timeline = self.timeline
-            self._canvas.timeline = self.timeline
-            self._canvas.set_timeline()
+    def setProject(self, project):
+        self.debug("Setting project %s", project)
+        if self._project:
+            self._project.disconnect_by_function(self._settingsChangedCb)
+
+        self._project = project
+        if self._project:
+            self.setTimeline(project.timeline)
+            self._canvas.setTimeline(project.timeline)
             self._canvas.zoomChanged()
-            self.ruler.setProjectFrameRate(self.project.getSettings().videorate)
+            self.ruler.setProjectFrameRate(self._project.getSettings().videorate)
             self.ruler.zoomChanged()
-            self._settingsChangedCb(self.project, None, self.project.getSettings())
-            self._seeker = self.project.seeker
-
-    #FIXME GES port
-    project = receiver(_setProject)
+            self._settingsChangedCb(self._project, None, self._project.getSettings())
+            self._seeker = self._project.seeker
+            self._project.connect("settings-changed", self._settingsChangedCb)
 
-    @handler(project, "settings-changed")
     def _settingsChangedCb(self, project, old, new):
         rate = new.videorate
         self.rate = float(1 / rate)
@@ -655,13 +671,18 @@ class Timeline(gtk.Table, Loggable, Zoomable):
 
 ## Timeline callbacks
 
-    def _setTimeline(self):
-        if self.timeline:
-            self._timelineSelectionChanged(self.timeline)
-            self._timelineStartDurationChanged(self.timeline,
-                self.timeline.duration)
+    def setTimeline(self, timeline):
+        self.debug("Setting timeline %s", timeline)
+        self._controls.timeline = self._timeline
+
+        self._timeline = timeline
+        for track in self._timeline.get_tracks():
+            track.connect("notify::duration", self.setDuration)
+
+    def getTimeline(self):
+        return self._timeline
 
-        self._controls.timeline = self.timeline
+    timeline = property(getTimeline, setTimeline, None, "The GESTimeline")
 
     def _updateScrollAdjustments(self):
         a = self.get_allocation()
@@ -698,7 +719,6 @@ class Timeline(gtk.Table, Loggable, Zoomable):
                 if remove:
                     lyr = obj.get_layer()
                     lyr.remove_object(obj)
-                    print "removed"
             self.app.action_log.commit()
         self.app.projectManager.current.pipeline.set_state(gst.STATE_PAUSED)
 
diff --git a/pitivi/ui/timelinecanvas.py b/pitivi/ui/timelinecanvas.py
index 2e0f9ee..31a5165 100644
--- a/pitivi/ui/timelinecanvas.py
+++ b/pitivi/ui/timelinecanvas.py
@@ -95,7 +95,7 @@ class TimelineCanvas(goocanvas.Canvas, Zoomable, Loggable):
         self.get_root_item().set_simple_transform(0, 2.0, 1.0, 0)
 
         self._createUI()
-        self.timeline = timeline
+        self._timeline = timeline
         self.settings = instance.settings
 
     def _createUI(self):
@@ -243,7 +243,7 @@ class TimelineCanvas(goocanvas.Canvas, Zoomable, Loggable):
         self._selecting = False
         self._marquee.props.visibility = goocanvas.ITEM_INVISIBLE
         if not self._got_motion_notify:
-            #self.timeline.setSelectionTo(set(), 0)
+            #self._timeline.setSelectionTo(set(), 0)
             seeker.seek(Zoomable.pixelToNs(event.x))
         else:
             self._got_motion_notify = False
@@ -254,7 +254,7 @@ class TimelineCanvas(goocanvas.Canvas, Zoomable, Loggable):
                 mode = 2
             selected = self._objectsUnderMarquee()
             self.app.projectManager.current.emit("selected-changed", selected)
-            #self.timeline.setSelectionTo(self._objectsUnderMarquee(), mode)
+            #self._timeline.setSelectionTo(self._objectsUnderMarquee(), mode)
         return True
 
     def _objectsUnderMarquee(self):
@@ -289,10 +289,10 @@ class TimelineCanvas(goocanvas.Canvas, Zoomable, Loggable):
 
     def zoomChanged(self):
         self.queue_draw()
-        if self.timeline:
-            self.timeline.dead_band = self.pixelToNs(
+        if self._timeline:
+            self._timeline.dead_band = self.pixelToNs(
                 self.settings.edgeSnapDeadband)
-            self.timelinePositionChanged(self.position)
+            #self._timelinePositionChanged(self.position)
 
 ## settings callbacks
 
@@ -307,18 +307,25 @@ class TimelineCanvas(goocanvas.Canvas, Zoomable, Loggable):
 
 ## Timeline callbacks
 
-    def set_timeline(self):
+    def setTimeline(self, timeline):
         while self._tracks:
             self._trackRemoved(None, 0)
-        if self.timeline:
-            for track in self.timeline.get_tracks():
+
+        self._timeline = timeline
+        if self._timeline:
+            for track in self._timeline.get_tracks():
                 self._trackAdded(None, track)
-            self.timeline.connect ("track-added", self._trackAdded)
-            self.timeline.connect ("track-removed", self._trackRemoved)
+            self._timeline.connect("track-added", self._trackAdded)
+            self._timeline.connect("track-removed", self._trackRemoved)
         self.zoomChanged()
 
+    def getTimeline(self):
+        return self._timeline
+
+    timeline = property(getTimeline, setTimeline, None, "The timeline property")
+
     def _trackAdded(self, timeline, track):
-        track = Track(self.app, track, self.timeline)
+        track = Track(self.app, track, self._timeline)
         self._tracks.append(track)
         track.set_canvas(self)
         self.tracks.add_child(track)
diff --git a/pitivi/ui/timelinecontrols.py b/pitivi/ui/timelinecontrols.py
index 7e14647..37ebcdc 100644
--- a/pitivi/ui/timelinecontrols.py
+++ b/pitivi/ui/timelinecontrols.py
@@ -2,11 +2,12 @@ import gtk
 from pitivi.receiver import receiver, handler
 from gettext import gettext as _
 from common import LAYER_HEIGHT_EXPANDED, LAYER_SPACING
+from pitivi.log.loggable import Loggable
 
 TRACK_CONTROL_WIDTH = 75
 
 
-class TrackControls(gtk.Label):
+class TrackControls(gtk.Label, Loggable):
     """Contains a timeline track name.
 
     @ivar track: The track for which to display the name.
@@ -17,6 +18,7 @@ class TrackControls(gtk.Label):
 
     def __init__(self, track):
         gtk.Label.__init__(self)
+        Loggable.__init__(self)
         # Center the label horizontally.
         self.set_alignment(0.5, 0)
         # The value below is arbitrarily chosen so the text appears
@@ -56,35 +58,46 @@ class TrackControls(gtk.Label):
         return "<b>%s</b>" % track_name
 
 
-class TimelineControls(gtk.VBox):
+class TimelineControls(gtk.VBox, Loggable):
     """Contains the timeline track names."""
 
     def __init__(self):
         gtk.VBox.__init__(self)
+        Loggable.__init__(self)
         self._tracks = []
+        self._timeline = None
         self.set_spacing(LAYER_SPACING)
         self.set_size_request(TRACK_CONTROL_WIDTH, -1)
 
 ## Timeline callbacks
 
-    def _set_timeline(self):
+    def getTimeline(self):
+        return self._timeline
+
+    def setTimeline(self, timeline):
+        self.debug("Setting timeline %s", timeline)
+
         while self._tracks:
-            self._trackRemoved(None, 0)
-        if self.timeline:
-            for track in self.timeline.get_tracks():
-                self._trackAdded(None, track)
+            self._trackRemovedCb(None, 0)
+
+        if self._timeline:
+            for track in self._timeline.get_tracks():
+                self._trackAddedCb(None, track)
+
+            self._timeline.connect("track-added", self._trackAddedCb)
+            self._timeline.connect("track-removed", self._trackRemovedCb)
 
-    timeline = receiver(_set_timeline)
+    timeline = property(getTimeline, setTimeline, None, "The timeline property")
 
-    @handler(timeline, "track-added")
-    def _trackAdded(self, timeline, track):
+    def _trackAddedCb(self, timeline, track):
         track = TrackControls(track)
         self._tracks.append(track)
         self.pack_start(track, False, False)
         track.show()
 
-    @handler(timeline, "track-removed")
-    def _trackRemoved(self, unused_timeline, position):
+    def _trackRemovedCb(self, unused_timeline, position):
+        self.timeline.disconnect_by_function(self._trackAddedCb)
+        self.timeline.disconnect_by_function(self._trackRemovedCb)
         track = self._tracks[position]
         del self._tracks[position]
         self.remove(track)
diff --git a/pitivi/ui/track.py b/pitivi/ui/track.py
index bab0003..1dccb26 100644
--- a/pitivi/ui/track.py
+++ b/pitivi/ui/track.py
@@ -135,7 +135,6 @@ class Track(goocanvas.Group, Zoomable):
     def check(self, tr_obj):
         if tr_obj.get_timeline_object():
             w = TrackObject(self.app, tr_obj, self.track, self.timeline, self)
-            self.app.current.sources.addUri(tr_obj.get_timeline_object().get_uri())
             self.widgets[tr_obj] = w
             self.add_child(w)
             self.app.gui.setBestZoomRatio()
diff --git a/pitivi/ui/trackobject.py b/pitivi/ui/trackobject.py
index 1d71ec7..840a245 100644
--- a/pitivi/ui/trackobject.py
+++ b/pitivi/ui/trackobject.py
@@ -503,7 +503,6 @@ class TrackObject(View, goocanvas.Group, Zoomable):
         try:
             x = self.nsToPixel(self.element.get_start())
         except Exception, e:
-            print self.element.get_start()
             raise Exception(e)
         priority = (self.element.get_priority()) / 10
         if priority < 0:
diff --git a/pitivi/ui/viewer.py b/pitivi/ui/viewer.py
index 4e3ec8e..110e158 100644
--- a/pitivi/ui/viewer.py
+++ b/pitivi/ui/viewer.py
@@ -26,11 +26,10 @@ from gtk import gdk
 import gst
 from math import pi
 import cairo
-import ges
 
 from gettext import gettext as _
 
-from pitivi.utils import time_to_string, Seeker
+from pitivi.utils import time_to_string
 from pitivi.log.loggable import Loggable
 from pitivi.ui.common import SPACING, hex_to_rgb
 from pitivi.settings import GlobalSettings
@@ -105,8 +104,6 @@ class PitiviViewer(gtk.VBox, Loggable):
         self.action = action
         self.pipeline = None
 
-        self.formatter = ges.PitiviFormatter()
-
         self.sink = None
         self.docked = True
 
@@ -127,7 +124,7 @@ class PitiviViewer(gtk.VBox, Loggable):
             if not self.settings.viewerDocked:
                 self.undock()
 
-    def setPipeline(self):
+    def setPipeline(self, pipeline):
         """
         Set the Viewer to the given Pipeline.
 
@@ -138,7 +135,10 @@ class PitiviViewer(gtk.VBox, Loggable):
         """
         self.debug("self.pipeline:%r", self.pipeline)
 
-        self.pipeline = self.app.projectManager.current.pipeline
+        if (self.pipeline):
+            self.pipeline.set_state(gst.STATE_NULL)
+
+        self.pipeline = pipeline
         if self.pipeline != None:
             bus = self.pipeline.get_bus()
             bus.add_signal_watch()
@@ -148,7 +148,6 @@ class PitiviViewer(gtk.VBox, Loggable):
             self.currentState = gst.STATE_PAUSED
         self._setUiActive()
         self.seeker = self.app.projectManager.current.seeker
-        self.seeker.connect('seek', self._seekerSeekCb)
 
     def setAction(self, action):
         """
@@ -173,7 +172,7 @@ class PitiviViewer(gtk.VBox, Loggable):
 
     def _busMessageCb(self, unused_bus, message):
         if message.type == gst.MESSAGE_EOS:
-            print "eos"
+            self.warning("eos")
         elif message.type == gst.MESSAGE_STATE_CHANGED:
             prev, new, pending = message.parse_state_changed()
 
@@ -443,15 +442,6 @@ class PitiviViewer(gtk.VBox, Loggable):
         except:
             self.warning("seek failed")
 
-    def _seekerSeekCb(self, seeker, position, format):
-        try:
-            self.pipeline.seek(1.0, format, gst.SEEK_FLAG_FLUSH,
-                                  gst.SEEK_TYPE_SET, position,
-                                  gst.SEEK_TYPE_NONE, -1)
-            self.app.gui.timeline.timelinePositionChanged(position)
-        except PipelineError:
-            self.error("seek failed %s %s", gst.TIME_ARGS(position), format)
-
     def _newTime(self, value, frame=-1):
         self.info("value:%s, frame:%d", gst.TIME_ARGS(value), frame)
         self.current_time = value
@@ -506,7 +496,6 @@ class PitiviViewer(gtk.VBox, Loggable):
         if playing:
             self.playing = True
             self.pipeline.set_state(gst.STATE_PLAYING)
-            gobject.timeout_add(300, self._posCb)
         else:
             self.playing = False
             self.pipeline.set_state(gst.STATE_PAUSED)



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