1
# PiTiVi , Non-linear video editor
3
# pitivi/projectmanager.py
5
# Copyright (c) 2009, Alessandro Decina <alessandro.d@gmail.com>
7
# This program is free software; you can redistribute it and/or
8
# modify it under the terms of the GNU Lesser General Public
9
# License as published by the Free Software Foundation; either
10
# version 2.1 of the License, or (at your option) any later version.
12
# This program is distributed in the hope that it will be useful,
13
# but WITHOUT ANY WARRANTY; without even the implied warranty of
14
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15
# Lesser General Public License for more details.
17
# You should have received a copy of the GNU Lesser General Public
18
# License along with this program; if not, write to the
19
# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20
# Boston, MA 02111-1307, USA.
22
from gettext import gettext as _
24
gobject.threads_init()
27
from pitivi.project import Project
28
from pitivi.formatters.format import get_formatter_for_uri
29
from pitivi.formatters.base import FormatterLoadError, FormatterSaveError
31
from pitivi.signalinterface import Signallable
32
from pitivi.log.loggable import Loggable
33
from pitivi.stream import AudioStream, VideoStream
34
from pitivi.timeline.track import Track
36
class ProjectManager(Signallable, Loggable):
38
"new-project-loading": ["uri"],
39
"new-project-created": ["project"],
40
"new-project-failed": ["uri", "exception"],
41
"new-project-loaded": ["project"],
42
"save-project-failed": ["project", "uri", "exception"],
43
"project-saved": ["project", "uri"],
44
"closing-project": ["project"],
45
"project-closed": ["project"],
46
"missing-uri": ["formatter", "uri"],
50
Signallable.__init__(self)
51
Loggable.__init__(self)
55
def loadProject(self, uri):
56
""" Load the given project file"""
57
self.emit("new-project-loading", uri)
59
formatter = self._getFormatterForUri(uri)
61
self.emit("new-project-failed", uri,
62
FormatterLoadError(_("Not a valid project file.")))
65
if not self.closeRunningProject():
66
self.emit("new-project-failed", uri,
67
FormatterLoadError(_("Couldn't close current project")))
70
self._connectToFormatter(formatter)
71
# start loading the project, from now on everything is async
72
formatter.loadProject(uri)
74
def saveProject(self, project, uri=None, overwrite=False, formatter=None):
76
Save the L{Project} to the given location.
78
If specified, use the given formatter.
80
@type project: L{Project}
81
@param project: The L{Project} to save.
83
@param uri: The location to store the project to. Needs to
85
@type formatter: L{Formatter}
86
@param formatter: The L{Formatter} to use to store the project if specified.
87
If it is not specified, then it will be saved at its original format.
88
@param overwrite: Whether to overwrite existing location.
89
@type overwrite: C{bool}
90
@raise FormatterSaveError: If the file couldn't be properly stored.
92
@see: L{Formatter.saveProject}
96
formatter == project.format
98
from pitivi.formatters.etree import ElementTreeFormatter
99
formatter = ElementTreeFormatter()
102
if project.uri is None:
103
self.emit("save-project-failed", project, uri,
104
FormatterSaveError(_("No URI specified.")))
109
self._connectToFormatter(formatter)
110
return formatter.saveProject(project, uri, overwrite)
112
def closeRunningProject(self):
113
""" close the current project """
114
self.info("closing running project")
116
if self.current is None:
119
if self.emit("closing-project", self.current) == False:
122
self.emit("project-closed", self.current)
123
self.current.release()
128
def newBlankProject(self):
129
""" start up a new blank project """
130
# if there's a running project we must close it
131
if self.current is not None and not self.closeRunningProject():
134
# we don't have an URI here, None means we're loading a new project
135
self.emit("new-project-loading", None)
136
project = Project(_("New Project"))
137
self.emit("new-project-created", project)
138
self.current = project
140
# FIXME: this should not be hard-coded
141
# add default tracks for a new project
142
video = VideoStream(gst.Caps('video/x-raw-rgb; video/x-raw-yuv'))
144
project.timeline.addTrack(track)
145
audio = AudioStream(gst.Caps('audio/x-raw-int; audio/x-raw-float'))
147
project.timeline.addTrack(track)
149
self.emit("new-project-loaded", self.current)
154
def _getFormatterForUri(self, uri):
155
return get_formatter_for_uri(uri)
157
def _connectToFormatter(self, formatter):
158
formatter.connect("missing-uri", self._formatterMissingURICb)
159
formatter.connect("new-project-created",
160
self._formatterNewProjectCreated)
161
formatter.connect("new-project-loaded",
162
self._formatterNewProjectLoaded)
163
formatter.connect("new-project-failed",
164
self._formatterNewProjectFailed)
165
formatter.connect("save-project-failed",
166
self._formatterSaveProjectFailed)
167
formatter.connect("project-saved",
168
self._formatterProjectSaved)
170
def _disconnectFromFormatter(self, formatter):
171
formatter.disconnect_by_function(self._formatterMissingURICb)
172
formatter.disconnect_by_function(self._formatterNewProjectCreated)
173
formatter.disconnect_by_function(self._formatterNewProjectLoaded)
174
formatter.disconnect_by_function(self._formatterNewProjectFailed)
175
formatter.disconnect_by_function(self._formatterSaveProjectFailed)
176
formatter.disconnect_by_function(self._formatterProjectSaved)
178
def _formatterNewProjectCreated(self, formatter, project):
179
self.emit("new-project-created", project)
181
def _formatterNewProjectLoaded(self, formatter, project):
182
self._disconnectFromFormatter(formatter)
184
self.current = project
185
self.emit("new-project-loaded", project)
187
def _formatterNewProjectFailed(self, formatter, uri, exception):
188
self._disconnectFromFormatter(formatter)
190
self.emit("new-project-failed", uri, exception)
192
def _formatterMissingURICb(self, formatter, uri):
193
return self.emit("missing-uri", formatter, uri)
195
def _formatterSaveProjectFailed(self, formatter, project, uri, exception):
196
self._disconnectFromFormatter(formatter)
197
self.emit("save-project-failed", project, uri, exception)
199
def _formatterProjectSaved(self, formatter, project, uri):
200
self._disconnectFromFormatter(formatter)
201
self.emit("project-saved", project, uri)