[pitivi/ges: 186/287] project: Move projectmanager into project.py



commit 42853ac59845e7eaaff528ce26295c2bd485e427
Author: Thibault Saunier <thibault saunier collabora com>
Date:   Tue Jan 10 18:25:04 2012 -0300

    project: Move projectmanager into project.py

 pitivi/Makefile.am           |    1 -
 pitivi/application.py        |    2 +-
 pitivi/project.py            |  237 ++++++++++++++++++++++++++++++++++++++-
 pitivi/projectmanager.py     |  259 ------------------------------------------
 po/POTFILES.in               |    1 -
 tests/test_projectmanager.py |    2 +-
 6 files changed, 238 insertions(+), 264 deletions(-)
---
diff --git a/pitivi/Makefile.am b/pitivi/Makefile.am
index 9d3cd86..16364ee 100644
--- a/pitivi/Makefile.am
+++ b/pitivi/Makefile.am
@@ -15,7 +15,6 @@ pitivi_PYTHON = \
 	render.py	\
 	instance.py 	\
 	project.py 	\
-	projectmanager.py 	\
 	settings.py 	\
 	medialibrary.py 	\
 	thumbnailcache.py
diff --git a/pitivi/application.py b/pitivi/application.py
index 0cf30aa..207a336 100644
--- a/pitivi/application.py
+++ b/pitivi/application.py
@@ -47,7 +47,7 @@ from pitivi.utils.system import getSystem
 from pitivi.utils.loggable import Loggable
 import pitivi.utils.loggable as log
 from pitivi.ui.mainwindow import PitiviMainWindow
-from pitivi.projectmanager import ProjectManager, ProjectLogObserver
+from pitivi.project import ProjectManager, ProjectLogObserver
 from pitivi.undo.undo import UndoableActionLog, DebugActionLogObserver
 #FIXME GES port disabled it
 #from pitivi.undo.timeline import TimelineLogObserver
diff --git a/pitivi/project.py b/pitivi/project.py
index 9167e2f..e26a356 100644
--- a/pitivi/project.py
+++ b/pitivi/project.py
@@ -20,7 +20,7 @@
 # Boston, MA 02110-1301, USA.
 
 """
-Project class
+Project related classes
 """
 
 import ges
@@ -33,6 +33,241 @@ from pitivi.settings import MultimediaSettings
 from pitivi.utils.signal import Signallable
 from pitivi.utils.timeline import Selection
 
+import gobject
+import os
+import gio
+
+from gettext import gettext as _
+from urlparse import urlparse
+from pwd import getpwuid
+
+from pitivi.undo.undo import UndoableAction
+
+
+class ProjectSettingsChanged(UndoableAction):
+
+    def __init__(self, project, old, new):
+        self.project = project
+        self.oldsettings = old
+        self.newsettings = new
+
+    def do(self):
+        self.project.setSettings(self.newsettings)
+        self._done()
+
+    def undo(self):
+        self.project.setSettings(self.oldsettings)
+        self._undone()
+
+
+class ProjectLogObserver(UndoableAction):
+
+    def __init__(self, log):
+        self.log = log
+
+    def startObserving(self, project):
+        project.connect("settings-changed", self._settingsChangedCb)
+
+    def stopObserving(self, project):
+        project.disconnect_by_function(self._settingsChangedCb)
+
+    def _settingsChangedCb(self, project, old, new):
+        action = ProjectSettingsChanged(project, old, new)
+        self.log.begin("change project settings")
+        self.log.push(action)
+        self.log.commit()
+
+
+class ProjectManager(Signallable, Loggable):
+    __signals__ = {
+        "new-project-loading": ["uri"],
+        "new-project-created": ["project"],
+        "new-project-failed": ["uri", "exception"],
+        "new-project-loaded": ["project"],
+        "save-project-failed": ["project", "uri", "exception"],
+        "project-saved": ["project", "uri"],
+        "closing-project": ["project"],
+        "project-closed": ["project"],
+        "missing-uri": ["formatter", "uri", "factory"],
+        "reverting-to-saved": ["project"],
+    }
+
+    def __init__(self, avalaible_effects={}):
+        Signallable.__init__(self)
+        Loggable.__init__(self)
+
+        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.current = Project(uri=uri)
+
+        self.timeline = self.current.timeline
+        self.formatter = ges.PitiviFormatter()
+
+        self.formatter.connect("source-moved", self._formatterMissingURICb)
+        self.formatter.connect("loaded", self._projectLoadedCb)
+        if self.formatter.load_from_uri(self.timeline, uri):
+            self.current.connect("project-changed", self._projectChangedCb)
+
+    def saveProject(self, project, uri=None, overwrite=False, formatter=None, backup=False):
+        """
+        Save the L{Project} to the given location.
+
+        If specified, use the given formatter.
+
+        @type project: L{Project}
+        @param project: The L{Project} to save.
+        @type uri: L{str}
+        @param uri: The location to store the project to. Needs to
+        be an absolute URI.
+        @type formatter: L{Formatter}
+        @param formatter: The L{Formatter} to use to store the project if specified.
+        If it is not specified, then it will be saved at its original format.
+        @param overwrite: Whether to overwrite existing location.
+        @type overwrite: C{bool}
+        @raise FormatterSaveError: If the file couldn't be properly stored.
+
+        @see: L{Formatter.saveProject}
+        """
+        if formatter is None:
+            formatter = ges.PitiviFormatter()
+
+        if uri is None:
+            uri = project.uri
+
+        if uri is None or not ges.formatter_can_save_uri(uri):
+            self.emit("save-project-failed", project, uri)
+            return
+
+        # FIXME Using query_exist is not the best thing to do, but makes
+        # the trick for now
+        file = gio.File(uri)
+        if overwrite or not file.query_exist():
+            formatter.set_sources(project.sources.getSources())
+            return formatter.save_to_uri(project.timeline, uri)
+
+    def closeRunningProject(self):
+        """ close the current project """
+        self.info("closing running project")
+
+        if self.current is None:
+            return True
+
+        if not self.emit("closing-project", self.current):
+            return False
+
+        self.emit("project-closed", self.current)
+        self.current.disconnect_by_function(self._projectChangedCb)
+        self._cleanBackup(self.current.uri)
+        self.current.release()
+        self.current = None
+
+        return True
+
+    def newBlankProject(self, emission=True):
+        """ start up a new blank project """
+        # if there's a running project we must close it
+        if self.current is not None and not self.closeRunningProject():
+            return False
+
+        # we don't have an URI here, None means we're loading a new project
+        if emission:
+            self.emit("new-project-loading", None)
+        project = Project(_("New Project"))
+
+        # setting default values for project metadata
+        project.author = getpwuid(os.getuid()).pw_gecos.split(",")[0]
+
+        self.emit("new-project-created", project)
+        self.current = project
+
+        # Add default tracks to the timeline of the new project.
+        # The tracks of the timeline determine what tracks
+        # the rendered content will have. Pitivi currently supports
+        # projects with exactly one video track and one audio track.
+        settings = project.getSettings()
+        project.connect("project-changed", self._projectChangedCb)
+        if emission:
+            self.current.disconnect = False
+        else:
+            self.current.disconnect = True
+        self.emit("new-project-loaded", self.current)
+
+        return True
+
+    def revertToSavedProject(self):
+        """ discard all unsaved changes and reload current open project """
+        #no running project or
+        #project has not been modified
+        if self.current.uri is None \
+           or not self.current.hasUnsavedModifications():
+            return True
+
+        if not self.emit("reverting-to-saved", self.current):
+            return False
+        uri = self.current.uri
+        self.current.setModificationState(False)
+        self.closeRunningProject()
+        self.loadProject(uri)
+
+    def _projectChangedCb(self, project):
+        # The backup_lock is a timer, when a change in the project is done it is
+        # set to 10 seconds. If before those 10 seconds pass an other change is done
+        # 5 seconds are added in the timeout callback instead of saving the backup
+        # file. The limit is 60 seconds.
+        uri = project.uri
+        if uri is None:
+            return
+
+        if self.backup_lock == 0:
+            self.backup_lock = 10
+            gobject.timeout_add_seconds(self.backup_lock,
+                    self._saveBackupCb, project, uri)
+        else:
+            if self.backup_lock < 60:
+                self.backup_lock += 5
+
+    def _saveBackupCb(self, project, uri):
+        backup_uri = self._makeBackupURI(uri)
+
+        if self.backup_lock > 10:
+            self.backup_lock -= 5
+            return True
+        else:
+            self.saveProject(project, backup_uri, overwrite=True, backup=True)
+            self.backup_lock = 0
+        return False
+
+    def _cleanBackup(self, uri):
+        if uri is None:
+            return
+
+        location = self._makeBackupURI(uri)
+        path = urlparse(location).path
+        if os.path.exists(path):
+            os.remove(path)
+
+    def _makeBackupURI(self, uri):
+        name, ext = os.path.splitext(uri)
+        if ext == '.xptv':
+            return name + ext + "~"
+        return None
+
+    def _formatterMissingURICb(self, formatter, tfs):
+        return self.emit("missing-uri", formatter, tfs)
+
+    def _projectLoadedCb(self, formatter, timeline):
+        self.debug("Project Loaded")
+        self.emit("new-project-loaded", self.current)
+        self.current.sources.addUris(self.formatter.get_sources())
+
 
 class ProjectError(Exception):
     """Project error"""
diff --git a/po/POTFILES.in b/po/POTFILES.in
index ae0bb39..21b068f 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -16,7 +16,6 @@ pitivi/application.py
 pitivi/check.py
 pitivi/effects.py
 pitivi/render.py
-pitivi/projectmanager.py
 pitivi/project.py
 pitivi/settings.py
 pitivi/medialibrary.py
diff --git a/tests/test_projectmanager.py b/tests/test_projectmanager.py
index 489f4a6..b7f2ed4 100644
--- a/tests/test_projectmanager.py
+++ b/tests/test_projectmanager.py
@@ -28,7 +28,7 @@
 
 #from unittest import TestCase
 
-#from pitivi.projectmanager import ProjectManager
+#from pitivi.project import ProjectManager
 #from pitivi.formatters.base import Formatter, \
         #FormatterError, FormatterLoadError
 #import os



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