[pitivi/ges: 186/287] project: Move projectmanager into project.py
- From: Jean-FranÃois Fortin Tam <jfft src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [pitivi/ges: 186/287] project: Move projectmanager into project.py
- Date: Thu, 15 Mar 2012 16:41:28 +0000 (UTC)
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]