[pitivi] Make project loading look async to Formatter clients.



commit c1acdd94c6dfc2f092c302517b8a7f7ee34e6f0f
Author: Alessandro Decina <alessandro d gmail com>
Date:   Tue Jun 2 17:37:20 2009 +0200

    Make project loading look async to Formatter clients.
---
 pitivi/application.py     |   84 +++++++++++++++++++++++++++++----------------
 pitivi/formatters/base.py |   22 ++++++++++--
 pitivi/ui/mainwindow.py   |    4 +-
 3 files changed, 74 insertions(+), 36 deletions(-)

diff --git a/pitivi/application.py b/pitivi/application.py
index 19d2cd2..226f72e 100644
--- a/pitivi/application.py
+++ b/pitivi/application.py
@@ -92,9 +92,9 @@ class Pitivi(Loggable, Signallable):
 
         "new-project-loading" : ["project"],
         "new-project-loaded" : ["project"],
+        "new-project-failed" : ["uri", "exception"],
         "closing-project" : ["project"],
         "project-closed" : ["project"],
-        "new-project-failed" : ["reason", "uri"],
         "missing-uri" : ["formatter", "uri"],
         "shutdown" : None
         }
@@ -166,50 +166,74 @@ class Pitivi(Loggable, Signallable):
 
     def loadProject(self, uri):
         """ Load the given project file"""
-        # is the given filepath a valid pitivi project
         formatter = get_formatter_for_uri(uri)
         if not formatter:
-            self.emit("new-project-failed",
-                    _("Not a valid project file."), uri)
+            self.emit("new-project-failed", uri,
+                    Exception(_("Not a valid project file.")))
             return
 
         if not self._closeRunningProject():
-            self.emit("new-project-failed",
-                    _("Couldn't close current project"), uri)
+            self.emit("new-project-failed", uri,
+                    Exception(_("Couldn't close current project")))
             return
 
         project = formatter.newProject()
-        formatter.connect("missing-uri", self._missingURICb)
+        self._connectToFormatter(formatter)
+        # start loading the project, from now on everything is async
+        formatter.loadProject(uri, project)
+
+    def _connectToFormatter(self, formatter):
+        formatter.connect("missing-uri", self._formatterMissingURICb)
+        formatter.connect("new-project-loading",
+                self._formatterNewProjectLoading)
+        formatter.connect("new-project-loaded",
+                self._formatterNewProjectLoaded)
+        formatter.connect("new-project-failed",
+                self._formatterNewProjectFailed)
+
+    def _disconnectFromFormatter(self, formatter):
+        formatter.disconnect_by_function(self._formatterMissingURICb)
+        formatter.disconnect_by_function(self._formatterNewProjectLoading)
+        formatter.disconnect_by_function(self._formatterNewProjectLoaded)
+        formatter.disconnect_by_function(self._formatterNewProjectFailed)
+
+    def _formatterNewProjectLoading(self, formatter, project):
         self.emit("new-project-loading", project)
-        self.info("Got a new project %r, calling loadProject", project)
-        try:
-            formatter.loadProject(uri, project)
-            self.current = project
-            self.emit("new-project-loaded", self.current)
-        except FormatterError, e:
-            self.handleException(e)
-            self.warning("error loading the project")
-            self.current = None
-            self.emit("new-project-failed",
-                _("There was an error loading the file."), uri)
-        finally:
-            formatter.disconnect_by_function(self._missingURICb)
-
-    def _missingURICb(self, formatter, uri):
+
+    def _formatterNewProjectLoaded(self, formatter, project):
+        self._disconnectFromFormatter(formatter)
+
+        self.current = project
+        self.emit("new-project-loaded", project)
+
+    def _formatterNewProjectFailed(self, formatter, uri, exception):
+        self._disconnectFromFormatter(formatter)
+
+        self.handleException(exception)
+        self.warning("error loading the project")
+        self.current = None
+        self.emit("new-project-failed", uri, exception)
+
+    def _formatterMissingURICb(self, formatter, uri):
         self.emit("missing-uri", formatter, uri)
 
     def _closeRunningProject(self):
         """ close the current project """
         self.info("closing running project")
-        if self.current:
-            if self.current.hasUnsavedModifications():
-                if not self.current.save():
-                    return False
-            if self.emit("closing-project", self.current) == False:
+        if not self.current:
+            return True
+
+        if self.current.hasUnsavedModifications():
+            if not self.current.save():
                 return False
-            self.emit("project-closed", self.current)
-            self.current.release()
-            self.current = None
+
+        if self.emit("closing-project", self.current) == False:
+            return False
+
+        self.emit("project-closed", self.current)
+        self.current.release()
+        self.current = None
+
         return True
 
     def newBlankProject(self):
diff --git a/pitivi/formatters/base.py b/pitivi/formatters/base.py
index 73e5529..c02ab5b 100644
--- a/pitivi/formatters/base.py
+++ b/pitivi/formatters/base.py
@@ -63,6 +63,9 @@ class Formatter(Signallable, Loggable):
     """
 
     __signals__ = {
+        "new-project-loading": ["project"],
+        "new-project-loaded": ["project"],
+        "new-project-failed": ["uri", "exception"],
         "missing-uri" : ["uri"]
         }
 
@@ -84,6 +87,12 @@ class Formatter(Signallable, Loggable):
         return self.ProjectClass()
 
     def loadProject(self, location, project=None):
+        try:
+            self._loadProjectUnchecked(location, project)
+        except FormatterError, e:
+            self.emit("new-project-failed", location, e)
+
+    def _loadProjectUnchecked(self, location, project=None):
         """
         Loads the project from the given location.
 
@@ -96,7 +105,14 @@ class Formatter(Signallable, Loggable):
         @return: The L{Project}
         @raise FormatterLoadError: If the file couldn't be properly loaded.
         """
+        if not project:
+            project = self.newProject()
+
+        project.uri = location
+
         self.log("location:%s, project:%r", location, project)
+        self.emit("new-project-loading", project)
+
         # check if the location is
         # .. a uri
         # .. a valid uri
@@ -109,9 +125,6 @@ class Formatter(Signallable, Loggable):
         # FIXME : maybe have a convenience method for opening a location
         self._parse(location, project)
 
-        if not project:
-            project = self.newProject()
-
         self.debug("About to get used sources")
         # ask for all sources being used
         uris = []
@@ -151,8 +164,9 @@ class Formatter(Signallable, Loggable):
             self.project.loaded = False
             self.project.sources.addUris(uris)
 
+        self.emit("new-project-loaded", self.project)
+
         # finally return the project.
-        self.project.uri = location
         return self.project
 
     def saveProject(self, project, location, overwrite=False):
diff --git a/pitivi/ui/mainwindow.py b/pitivi/ui/mainwindow.py
index aa5992b..9f2527a 100644
--- a/pitivi/ui/mainwindow.py
+++ b/pitivi/ui/mainwindow.py
@@ -673,7 +673,7 @@ class PitiviMainWindow(gtk.Window, Loggable):
         return False
 
     @handler(app, "new-project-failed")
-    def _notProjectCb(self, unused_pitivi, reason, uri):
+    def _notProjectCb(self, unused_pitivi, uri, exception):
         # ungrey UI
         dialog = gtk.MessageDialog(self,
             gtk.DIALOG_MODAL,
@@ -682,7 +682,7 @@ class PitiviMainWindow(gtk.Window, Loggable):
             _("PiTiVi is unable to load file \"%s\"") %
                 uri)
         dialog.set_title(_("Error Loading File"))
-        dialog.set_property("secondary-text", reason)
+        dialog.set_property("secondary-text", str(exception))
         dialog.run()
         dialog.destroy()
         self.set_sensitive(True)



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