~ubuntu-branches/ubuntu/trusty/pitivi/trusty

« back to all changes in this revision

Viewing changes to pitivi/projectmanager.py

* New upstream pre-release:
  + debian/control:
    - Update dependencies.
* debian/control:
  + Update Standards-Version to 3.8.2.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# PiTiVi , Non-linear video editor
 
2
#
 
3
#       pitivi/projectmanager.py
 
4
#
 
5
# Copyright (c) 2009, Alessandro Decina <alessandro.d@gmail.com>
 
6
#
 
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.
 
11
#
 
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.
 
16
#
 
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.
 
21
 
 
22
from gettext import gettext as _
 
23
import gobject
 
24
gobject.threads_init()
 
25
import gst
 
26
 
 
27
from pitivi.project import Project
 
28
from pitivi.formatters.format import get_formatter_for_uri
 
29
from pitivi.formatters.base import FormatterLoadError, FormatterSaveError
 
30
 
 
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
 
35
 
 
36
class ProjectManager(Signallable, Loggable):
 
37
    __signals__ = {
 
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"],
 
47
    }
 
48
 
 
49
    def __init__(self):
 
50
        Signallable.__init__(self)
 
51
        Loggable.__init__(self)
 
52
 
 
53
        self.current = None
 
54
 
 
55
    def loadProject(self, uri):
 
56
        """ Load the given project file"""
 
57
        self.emit("new-project-loading", uri)
 
58
 
 
59
        formatter = self._getFormatterForUri(uri)
 
60
        if not formatter:
 
61
            self.emit("new-project-failed", uri,
 
62
                    FormatterLoadError(_("Not a valid project file.")))
 
63
            return
 
64
 
 
65
        if not self.closeRunningProject():
 
66
            self.emit("new-project-failed", uri,
 
67
                    FormatterLoadError(_("Couldn't close current project")))
 
68
            return
 
69
 
 
70
        self._connectToFormatter(formatter)
 
71
        # start loading the project, from now on everything is async
 
72
        formatter.loadProject(uri)
 
73
 
 
74
    def saveProject(self, project, uri=None, overwrite=False, formatter=None):
 
75
        """
 
76
        Save the L{Project} to the given location.
 
77
 
 
78
        If specified, use the given formatter.
 
79
 
 
80
        @type project: L{Project}
 
81
        @param project: The L{Project} to save.
 
82
        @type uri: L{str}
 
83
        @param uri: The location to store the project to. Needs to
 
84
        be an absolute URI.
 
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.
 
91
 
 
92
        @see: L{Formatter.saveProject}
 
93
        """
 
94
        if formatter is None:
 
95
            if project.format:
 
96
                formatter == project.format
 
97
            else:
 
98
                from pitivi.formatters.etree import ElementTreeFormatter
 
99
                formatter = ElementTreeFormatter()
 
100
 
 
101
        if uri is None:
 
102
            if project.uri is None:
 
103
                self.emit("save-project-failed", project, uri,
 
104
                        FormatterSaveError(_("No URI specified.")))
 
105
                return
 
106
 
 
107
            uri = project.uri
 
108
 
 
109
        self._connectToFormatter(formatter)
 
110
        return formatter.saveProject(project, uri, overwrite)
 
111
 
 
112
    def closeRunningProject(self):
 
113
        """ close the current project """
 
114
        self.info("closing running project")
 
115
 
 
116
        if self.current is None:
 
117
            return True
 
118
 
 
119
        if self.emit("closing-project", self.current) == False:
 
120
            return False
 
121
 
 
122
        self.emit("project-closed", self.current)
 
123
        self.current.release()
 
124
        self.current = None
 
125
 
 
126
        return True
 
127
 
 
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():
 
132
            return False
 
133
 
 
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
 
139
 
 
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'))
 
143
        track = Track(video)
 
144
        project.timeline.addTrack(track)
 
145
        audio = AudioStream(gst.Caps('audio/x-raw-int; audio/x-raw-float'))
 
146
        track = Track(audio)
 
147
        project.timeline.addTrack(track)
 
148
 
 
149
        self.emit("new-project-loaded", self.current)
 
150
 
 
151
        return True
 
152
 
 
153
 
 
154
    def _getFormatterForUri(self, uri):
 
155
        return get_formatter_for_uri(uri)
 
156
 
 
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)
 
169
 
 
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)
 
177
 
 
178
    def _formatterNewProjectCreated(self, formatter, project):
 
179
        self.emit("new-project-created", project)
 
180
 
 
181
    def _formatterNewProjectLoaded(self, formatter, project):
 
182
        self._disconnectFromFormatter(formatter)
 
183
 
 
184
        self.current = project
 
185
        self.emit("new-project-loaded", project)
 
186
 
 
187
    def _formatterNewProjectFailed(self, formatter, uri, exception):
 
188
        self._disconnectFromFormatter(formatter)
 
189
        self.current = None
 
190
        self.emit("new-project-failed", uri, exception)
 
191
 
 
192
    def _formatterMissingURICb(self, formatter, uri):
 
193
        return self.emit("missing-uri", formatter, uri)
 
194
 
 
195
    def _formatterSaveProjectFailed(self, formatter, project, uri, exception):
 
196
        self._disconnectFromFormatter(formatter)
 
197
        self.emit("save-project-failed", project, uri, exception)
 
198
 
 
199
    def _formatterProjectSaved(self, formatter, project, uri):
 
200
        self._disconnectFromFormatter(formatter)
 
201
        self.emit("project-saved", project, uri)