~ubuntu-branches/ubuntu/quantal/jokosher/quantal

« back to all changes in this revision

Viewing changes to Jokosher/RecordingView.py

  • Committer: Bazaar Package Importer
  • Author(s): Luca Falavigna, Luca Falavigna, Piotr Ożarowski
  • Date: 2009-05-12 00:37:15 UTC
  • mfrom: (1.3.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20090512003715-3hp2ycoqjlzwfnlv
Tags: 0.11.2-1
[ Luca Falavigna ]
* New upstream release (Closes: #517234).
  - Jokosher now appears under Sound & Video (Closes: #443788).
* New Maintainer (Closes: #523167).
* Add Python Applications Packaging Team to Uploaders.
* Add Vcs-* fields in source stanza.
* Adjust copyright informations:
  - Refresh upstream authors and copyright holders.
  - Link to /usr/share/common-licenses/GPL-2.
  - Adjust copyright holders for Debian packaging.
  - Replace (c) with ©.
* Apply changes from Ubuntu by Daniel Holbach (thanks!):
  - Drop scrollkeeper from Build-Depends.
  - Drop useless dependencies: python-alsaaudio, gstreamer0.10-gnomevfs,
    librsvg2-common, python-gnome2.
  - Bump gstreamer0.10-plugins-good requirement to >= 0.10.9.
  - Drop debian/jokosher.sh, useless.
  - Provide debian/watch file.
* Switch to debhelper 7.
* Install Jokosher module in private directory.
* Unpack egg files to let python-support handle them.
* Drop python-dev from Build-Depends, use python (>= 2.4) instead.
* Depend on python-gobject.
* Switch dependency from python-setuptools to python-pkg-resources
  because of package rename (Closes: #468728).
* debian/patches/10_update_mime_database.dpatch:
  - Refresh for new upstream release.
* debian/patches/20_LevelList_IOError.dpatch:
  - Fix IOError exception trying to add an audio file to a project.
* debian/patches/30_desktop_file.dpatch:
  - Adhere to Freedesktop.org standards by removing deprecated entries.
* debian/patches/50_CreateNewProject_return.dpatch:
  - Return class while creating a new project.
* Provide a simple man page for jokosher.
* Bump Standards-Version to 3.8.1:
  - Provide Homepage field in source stanza.
  - Provide debian/README.source to document dpatch usage.

[ Piotr Ożarowski ]
* Add 40_load_extensions_from_unpacked_eggs patch so that extensions in
  unzipped Eggs are recognized as well

Show diffs side-by-side

added added

removed removed

Lines of Context:
13
13
import InstrumentViewer
14
14
import TimeLineBar
15
15
import Globals
 
16
import ui.MessageArea as MessageArea
16
17
from gettext import gettext as _
17
18
import urllib
18
19
 
22
23
        """
23
24
        This class encapsulates a visual layout of a project comprising
24
25
        instrument tracks, timeline, and horizontal scrollbars.
25
 
        Despite its name, it also appears under the mixing view contained
26
 
        in a CompactMixView object, where it represents the same
27
 
        information with shorter instrument tracks.
28
26
        """
29
27
        
30
28
        """ GTK widget name """
31
29
        __gtype_name__ = 'RecordingView'
32
30
        
33
 
        """ Width, in pixel, for the instrument headers """
34
 
        INSTRUMENT_HEADER_WIDTH = 150
35
31
        """ How far in you are allowed to zoom. """
36
32
        ZOOM_MAX_SCALE = 100.0
37
33
        """ How for out you are allowed to zoom. 
48
44
                                                URI_DRAG_TYPE ),                # Use the custom number
49
45
                                                ("text/plain", 0, URI_DRAG_TYPE) # so drags from Firefox work
50
46
                                                ]
 
47
        
 
48
        """The number of seconds shown after the end of the last event"""
 
49
        EXTRA_SCROLL_TIME = 25
51
50
 
52
51
        #_____________________________________________________________________
53
52
 
54
 
        def __init__(self, project, mainview, mixView=None, small=False):
 
53
        def __init__(self, project, mainview, small=False):
55
54
                """
56
55
                Creates a new instance of RecordingView.
57
56
                
58
57
                Parameters:
59
58
                        project -- the currently active Project.
60
59
                        mainview -- the main Jokosher window (MainApp).
61
 
                        mixView -- the CompactMixView object that holds this instance of
62
 
                                                RecordingView, if the mixing view is the currently 
63
 
                                                active one.
64
 
                                                If the recording view is the active one, then this
65
 
                                                should be set to None.
66
60
                        small -- set to True if we want small edit views (i.e. for the mixing view).
67
61
                """
68
62
                gtk.Frame.__init__(self)
69
63
 
70
64
                self.project = project
71
65
                self.mainview = mainview
72
 
                self.mixView = mixView
73
66
                self.small = small
74
 
                self.timelinebar = TimeLineBar.TimeLineBar(self.project, self, mainview)
 
67
                self.timelinebar = TimeLineBar.TimeLineBar(self.project, mainview)
 
68
                
 
69
                self.errorMessageArea = None
 
70
                self.restoreMessageArea = None
75
71
                
76
72
                ## create darker workspace box
77
73
                self.eventBox = gtk.EventBox()
91
87
                self.instrumentWindow.child.set_shadow_type(gtk.SHADOW_NONE)
92
88
                self.views = [] 
93
89
                
 
90
                self.header_size_group = gtk.SizeGroup(gtk.SIZE_GROUP_HORIZONTAL)
 
91
                self.header_size_group.add_widget(self.timelinebar.GetHeaderWidget())
 
92
                
94
93
                self.hb = gtk.HBox()
95
94
                self.hb.set_spacing(6)
 
95
                self.hb.set_border_width(6)
96
96
                self.vbox.pack_end(self.hb, False, False)
97
 
                self.al = gtk.Alignment(0, 0, 1, 1)
 
97
                self.vbox.pack_end(gtk.HSeparator(), False, False)
 
98
                
 
99
                self.zoom_hb = gtk.HBox()
 
100
                self.zoom_hb.set_spacing(6)
 
101
                self.zoom_hb.set_border_width(0)
 
102
                self.header_size_group.add_widget(self.zoom_hb)
 
103
                
98
104
                self.scrollRange = gtk.Adjustment()
99
 
                sb = gtk.HScrollbar(self.scrollRange)
100
 
                self.al.add(sb)
101
 
                self.al.set_padding(0, 0, 0, 0)
102
 
                self.hb.pack_start(self.al)
 
105
                self.scrollBar = gtk.HScrollbar(self.scrollRange)
 
106
                
 
107
                self.hb.pack_start(self.zoom_hb, False, False)
 
108
                self.hb.pack_start(self.scrollBar, True, True)
103
109
                
104
110
                self.lastzoom = 0
105
111
                
106
 
                #recording view contains zoom buttons
107
 
                if not self.mixView:
108
 
                        self.zoomSlider = gtk.HScale()
109
 
                        self.zoomSlider.set_size_request(70, -1)
110
 
                        
111
 
                        self.zoomSlider.set_range(self.ZOOM_MIN_SCALE, self.ZOOM_MAX_SCALE)
112
 
                        self.zoomSlider.set_increments(0.2, 0.2)
113
 
                        self.zoomSlider.set_draw_value(False)
114
 
                        self.zoomSlider.set_value(self.project.viewScale)
115
 
                        self.zoomtip = gtk.Tooltips()
116
 
                        self.zoomtip.set_tip(self.zoomSlider, _("Zoom the timeline"),None)
117
 
                        
118
 
                        self.zoomSlider.connect("value-changed", self.OnZoom)
119
 
                        
120
 
                        inbutton = gtk.Button()
121
 
                        inimg = gtk.image_new_from_stock(gtk.STOCK_ZOOM_IN, gtk.ICON_SIZE_BUTTON)
122
 
                        inbutton.set_image(inimg)
123
 
                        inbutton.set_relief(gtk.RELIEF_NONE)
124
 
                        inbutton.connect("clicked", self.OnZoomIn)
125
 
                        
126
 
                        outbutton = gtk.Button()
127
 
                        outimg = gtk.image_new_from_stock(gtk.STOCK_ZOOM_OUT, gtk.ICON_SIZE_BUTTON)
128
 
                        outbutton.set_image(outimg)
129
 
                        outbutton.set_relief(gtk.RELIEF_NONE)
130
 
                        outbutton.connect("clicked", self.OnZoomOut)
 
112
                self.zoomSlider = gtk.HScale()
 
113
                self.zoomSlider.set_size_request(70, -1)
 
114
                
 
115
                self.zoomSlider.set_range(self.ZOOM_MIN_SCALE, self.ZOOM_MAX_SCALE)
 
116
                self.zoomSlider.set_increments(0.2, 0.2)
 
117
                self.zoomSlider.set_draw_value(False)
 
118
                self.zoomSlider.set_value(self.project.viewScale)
 
119
                self.zoomtip = gtk.Tooltips()
 
120
                self.zoomtip.set_tip(self.zoomSlider, _("Zoom the timeline - Right-Click to reset to the default level"), None)
 
121
                
 
122
                self.zoomSlider.connect("value-changed", self.OnZoom)
 
123
                self.zoomSlider.connect("button-press-event", self.OnZoomReset)
 
124
                
 
125
                self.inbutton = gtk.Button()
 
126
                inimg = gtk.image_new_from_stock(gtk.STOCK_ZOOM_IN, gtk.ICON_SIZE_BUTTON)
 
127
                self.inbutton.set_image(inimg)
 
128
                self.inbutton.set_relief(gtk.RELIEF_NONE)
 
129
                self.zoomtip.set_tip(self.inbutton, _("Zoom in timeline"), None)
 
130
                self.inbutton.connect("clicked", self.OnZoomIn)
 
131
                
 
132
                self.outbutton = gtk.Button()
 
133
                outimg = gtk.image_new_from_stock(gtk.STOCK_ZOOM_OUT, gtk.ICON_SIZE_BUTTON)
 
134
                self.outbutton.set_image(outimg)
 
135
                self.outbutton.set_relief(gtk.RELIEF_NONE)
 
136
                self.zoomtip.set_tip(self.outbutton, _("Zoom out timeline"), None)
 
137
                self.outbutton.connect("clicked", self.OnZoomOut)
131
138
 
132
 
                        self.hb.pack_start( outbutton, False, False)
133
 
                        self.hb.pack_start( self.zoomSlider, False, False)
134
 
                        self.hb.pack_start( inbutton, False, False)
 
139
                self.zoom_hb.pack_start( self.outbutton, False, False)
 
140
                self.zoom_hb.pack_start( self.zoomSlider, False, False)
 
141
                self.zoom_hb.pack_start( self.inbutton, False, False)
135
142
                
136
 
                self.extraScrollTime = 25
137
143
                self.centreViewOnPosition = False
138
144
                self.scrollRange.lower = 0
139
145
                self.scrollRange.upper = 100
140
146
                self.scrollRange.value = 0
141
147
                self.scrollRange.step_increment = 1
142
148
                
143
 
                sb.connect("value-changed", self.OnScroll)
 
149
                self.scrollBar.connect("value-changed", self.OnScroll)
144
150
                self.connect("expose-event", self.OnExpose)
145
151
                self.connect("button_release_event", self.OnExpose)
146
152
                self.connect("button_press_event", self.OnMouseDown)
147
 
                self.connect("size-allocate", self.OnAllocate)
 
153
                
 
154
                #connect to the project signals
 
155
                self.project.connect("gst-bus-error", self.OnProjectGstError)
 
156
                self.project.connect("incremental-save", self.OnProjectIncSave)
 
157
                self.project.connect("instrument::added", self.OnInstrumentAdded)
 
158
                self.project.connect("instrument::reordered", self.OnInstrumentReordered)
 
159
                self.project.connect("instrument::removed", self.OnInstrumentRemoved)
 
160
                self.project.connect("view-start", self.OnViewStartChanged)
148
161
                
149
162
                self.vbox.drag_dest_set(        gtk.DEST_DEFAULT_DROP,
150
163
                                                                        self.DRAG_TARGETS, 
152
165
                self.vbox.connect("drag_data_received", self.OnDragDataReceived)
153
166
                self.vbox.connect("drag_motion", self.OnDragMotion)
154
167
                
155
 
                self.Update()
 
168
                #add the instruments that were loaded from the project file already
 
169
                for instr in self.project.instruments:
 
170
                        self.OnInstrumentAdded(project, instr)
 
171
                        
 
172
                self.show_all()
 
173
                self.show_all()
 
174
                if self.small:
 
175
                        self.inbutton.hide()
 
176
                        self.outbutton.hide()
 
177
                        self.zoomSlider.hide()
 
178
                
 
179
                if self.project.CanDoIncrementalRestore():
 
180
                        message = _("Would you like to restore the current project?")
 
181
                        details = _("A crash was detected and changes to your project were not saved.\nIf you would like, you can attempt to recover these lost changes.")
 
182
                        
 
183
                        msg_area = MessageArea.MessageArea()
 
184
                        msg_area.add_button(gtk.STOCK_CLOSE, gtk.RESPONSE_CLOSE)
 
185
                        msg_area.add_stock_button_with_text(_("_Restore Project"), gtk.STOCK_APPLY, gtk.RESPONSE_OK)
 
186
                        msg_area.set_text_and_icon(gtk.STOCK_DIALOG_QUESTION, message, details)
 
187
                        
 
188
                        msg_area.connect("response", self.OnRestoreMessageAreaResponse, msg_area)
 
189
                        msg_area.connect("close", self.OnRestoreMessageAreaClose, msg_area)
 
190
                        
 
191
                        self.vbox.pack_end(msg_area, False, False)
 
192
                        msg_area.show()
 
193
                        self.restoreMessageArea = msg_area
 
194
                
156
195
        #_____________________________________________________________________
157
196
 
158
197
        def OnExpose(self, widget, event):
181
220
                ## use the new colormap
182
221
                self.eventBox.set_style(stcp)
183
222
                
184
 
                # calculate scrollable width - allow 4 pixels for borders
185
 
                self.scrollRange.page_size = (self.allocation.width - Globals.INSTRUMENT_HEADER_WIDTH - 4) / self.project.viewScale
 
223
                # calculate scrollable width (scroll bar should always be same width as viewable area)
 
224
                self.scrollRange.page_size = (self.scrollBar.allocation.width) / self.project.viewScale
186
225
                self.scrollRange.page_increment = self.scrollRange.page_size
187
226
                # add EXTRA_SCROLL_TIME extra seconds
188
 
                length = self.project.GetProjectLength() + self.extraScrollTime
 
227
                length = self.project.GetProjectLength() + self.EXTRA_SCROLL_TIME
189
228
                self.scrollRange.upper = length
190
229
                
191
230
                if self.centreViewOnPosition:  
192
231
                        self.centreViewOnPosition = False  
193
232
                        #set the view to be centred over the playhead  
194
233
                        start = self.project.transport.GetPosition() - (self.scrollRange.page_size / 2)
195
 
                        self.SetViewPosition(start)
 
234
                        self.project.SetViewStart(start)
196
235
                # Need to adjust project view start if we are zooming out
197
236
                # and the end of the project is now before the end of the page.
198
237
                # Project end will be at right edge unless the start is also on 
199
238
                # screen, in which case the start will be at the left.
200
239
                elif self.project.viewStart + self.scrollRange.page_size > length:
201
 
                        self.SetViewPosition(length - self.scrollRange.page_size)
202
 
                
203
 
                if not self.mixView:
204
 
                        #check the min zoom value (based on project length)
205
 
                        pixelSize = self.allocation.width - Globals.INSTRUMENT_HEADER_WIDTH - 4 # four pixels to account for borders
206
 
                        minScale = pixelSize / length
207
 
                        self.zoomSlider.set_range(minScale, self.ZOOM_MAX_SCALE)
208
 
                        if self.zoomSlider.get_value() < minScale:
209
 
                                self.zoomSlider.set_value(minScale)
210
 
                
211
 
        #_____________________________________________________________________
212
 
 
213
 
        def OnAllocate(self, widget, allocation):
214
 
                """
215
 
                Callback for "size-allocate" signal.
216
 
                
217
 
                Parameters:
218
 
                        widget -- reserved for GTK callbacks, don't use it explicitly.
219
 
                        allocation -- new allocation value to be set.
220
 
                """
221
 
                self.allocation = allocation
222
 
                
223
 
        #_____________________________________________________________________
224
 
        
225
 
 
226
 
        def Update(self):
227
 
                """
228
 
                Updates the GUI to reflect changes on the instruments, timeline and
229
 
                scrollbars.
230
 
                Called either directly from OnStateChanged(), or via the owning
231
 
                CompactMixView.update()(depending on which view we are in) when
232
 
                there is a change of state in an instrument being listened to.
233
 
                
234
 
                Considerations:
235
 
                        InstrumentViews MUST have the order that the instruments have in
236
 
                        Project.instruments, to keep the drag and drop of InstrumentViews
237
 
                        consistent.
238
 
                """
239
 
                children = self.instrumentBox.get_children()
240
 
                orderCounter = 0
241
 
                for instr in self.project.instruments:
242
 
                        #Find the InstrumentView that matches instr:
243
 
                        iv = None
244
 
                        for ident, instrV in self.views:
245
 
                                if instrV.instrument is instr:
246
 
                                        iv = instrV
247
 
                                        break
248
 
                        #If there is no InstrumentView for instr, create one:
249
 
                        if not iv:
250
 
                                iv = InstrumentViewer.InstrumentViewer(self.project, instr, self, self.mainview, self.small)
251
 
                                # if this is mix view then add parent (CompactMixView) as listener
252
 
                                # otherwise add self
253
 
                                if self.mixView:
254
 
                                        instr.AddListener(self.mixView)
255
 
                                else:
256
 
                                        instr.AddListener(self)
257
 
                                #Add it to the views
258
 
                                self.views.append((instr.id, iv))
259
 
                                iv.headerAlign.connect("size-allocate", self.UpdateSize)
260
 
                        
261
 
                        if iv not in children:
262
 
                                #Add the InstrumentView to the VBox
263
 
                                self.instrumentBox.pack_start(iv, False, False)
264
 
                        else:
265
 
                                #If the InstrumentView has already been added, just move it
266
 
                                self.instrumentBox.reorder_child(iv, orderCounter)
267
 
                                
268
 
                        #Make sure the InstrumentView is visible:
269
 
                        iv.show()
270
 
                        
271
 
                        orderCounter += 1
272
 
                
273
 
                removeList = []
274
 
                #self.views is up to date now
275
 
                for ident, iv in self.views:
276
 
                        #check if instrument has been deleted
277
 
                        if not iv.instrument in self.project.instruments:
278
 
                                if iv in children:
279
 
                                        self.instrumentBox.remove(iv)
280
 
                                iv.Destroy()
281
 
                                removeList.append((ident, iv))
282
 
                        else:
283
 
                                iv.Update() #Update non-deleted instruments
284
 
                
285
 
                #remove all the unused ones so the garbage collector can clean then up
286
 
                for tuple_ in removeList:
287
 
                        self.views.remove(tuple_)
288
 
                del removeList
289
 
                
290
 
                if len(self.views) > 0:
291
 
                        self.UpdateSize(None, self.views[0][1].headerAlign.get_allocation())
292
 
                else:
293
 
                        self.UpdateSize(None, None)
294
 
                self.show_all()
295
 
        
296
 
        #_____________________________________________________________________
297
 
                
298
 
        def UpdateSize(self, widget=None, size=None):
299
 
                """
300
 
                Called during update() to re-align the timeline and scrollbars
301
 
                with the start of the event lane since the instrument width may
302
 
                have been altered.
303
 
                """
304
 
                #find the width of the instrument headers (they should all be the same size)
305
 
                if size:
306
 
                        tempWidth = size.width
307
 
                else:
308
 
                        tempWidth = self.INSTRUMENT_HEADER_WIDTH
309
 
                
310
 
                #set it to the globals class
311
 
                Globals.INSTRUMENT_HEADER_WIDTH = tempWidth
312
 
                
313
 
                #align timeline and scrollbar
314
 
                self.timelinebar.Update()
315
 
                self.al.set_padding(0, 0, tempWidth, 0)
 
240
                        self.project.SetViewStart(length - self.scrollRange.page_size)
 
241
                
 
242
                #check the min zoom value (based on project length)
 
243
                # (scroll bar should always be same width as viewable area)
 
244
                pixelSize = self.scrollBar.allocation.width 
 
245
                minScale = pixelSize / length
 
246
                self.zoomSlider.set_range(minScale, self.ZOOM_MAX_SCALE)
 
247
                if self.zoomSlider.get_value() < minScale:
 
248
                        self.zoomSlider.set_value(minScale)
 
249
                
 
250
        #_____________________________________________________________________
 
251
        
 
252
        def OnInstrumentAdded(self, project, instrument):
 
253
                """
 
254
                Callback for when an instrument is added to the project.
 
255
                
 
256
                Parameters:
 
257
                        project -- The project that the instrument was added to.
 
258
                        instrument -- The instrument that was added.
 
259
                """
 
260
                instrViewer = InstrumentViewer.InstrumentViewer(project, instrument, self, self.mainview, self.small)
 
261
                
 
262
                #Add it to the views
 
263
                self.views.append((instrument.id, instrViewer))
 
264
                self.header_size_group.add_widget(instrViewer.GetHeaderWidget())
 
265
                
 
266
                self.instrumentBox.pack_start(instrViewer, False, False)
 
267
                instrViewer.show()
 
268
        
 
269
        #_____________________________________________________________________
 
270
        
 
271
        def OnInstrumentRemoved(self, project, instrument):
 
272
                """
 
273
                Callback for when an instrument is removed from the project.
 
274
                
 
275
                Parameters:
 
276
                        project -- The project that the instrument was removed from.
 
277
                        instrument -- The instrument that was removed.
 
278
                """
 
279
                for ID, instrViewer in self.views:
 
280
                        if ID == instrument.id:
 
281
                                if instrViewer.parent:
 
282
                                        self.instrumentBox.remove(instrViewer)
 
283
                                instrViewer.Destroy()
 
284
                                self.views.remove((ID, instrViewer))
 
285
                                break
 
286
        
 
287
        #_____________________________________________________________________
 
288
        
 
289
        def OnInstrumentReordered(self, project, instrument):
 
290
                """
 
291
                Callback for when an instrument's position in the project has changed.
 
292
                
 
293
                Parameters:
 
294
                        project -- The project that the instrument was changed on.
 
295
                        instrument -- The instrument that was reordered.
 
296
                """
 
297
                for ID, instrViewer in self.views:
 
298
                        if ID == instrument.id:
 
299
                                if instrViewer.parent:
 
300
                                        pos = self.project.instruments.index(instrument)
 
301
                                        self.instrumentBox.reorder_child(instrViewer, pos)
 
302
                                        instrViewer.show_all()
 
303
                                break
 
304
                
 
305
        
 
306
        #_____________________________________________________________________
 
307
        
 
308
        def OnProjectGstError(self, project, error, debug):
 
309
                """
 
310
                Callback for when the project sends a gstreamer error message
 
311
                from the pipeline.
 
312
                
 
313
                Parameters:
 
314
                        project -- The project instance that send the signal.
 
315
                        error -- The type of error that occurred as a string.
 
316
                        debug -- A string with more debug information about the error.
 
317
                """
 
318
                if not error:
 
319
                        error = _("A Gstreamer error has occurred")
 
320
                
 
321
                if not self.errorMessageArea:
 
322
                        msg_area = self.CreateDefaultErrorPane(error, debug)
 
323
                        self.vbox.pack_end(msg_area, False, False)
 
324
                        msg_area.show()
 
325
                        self.errorMessageArea = msg_area
 
326
        
 
327
        #_____________________________________________________________________
 
328
        
 
329
        def CreateDefaultErrorPane(self, error, details):
 
330
                message = _("A GStreamer error has occurred.")
 
331
                info = _("If this problem persists consider reporting a bug using the link in the help menu.")
 
332
                
 
333
                details = "\n".join((error, info))
 
334
                
 
335
                msg_area = MessageArea.MessageArea()
 
336
                msg_area.add_button(gtk.STOCK_CLOSE, gtk.RESPONSE_CLOSE)
 
337
                msg_area.set_text_and_icon(gtk.STOCK_DIALOG_ERROR, message, details)
 
338
                
 
339
                msg_area.connect("response", self.OnMessageAreaReponse, msg_area)
 
340
                msg_area.connect("close", self.OnMessageAreaClose, msg_area)
 
341
                
 
342
                return msg_area
 
343
                
 
344
        #_____________________________________________________________________
 
345
        
 
346
        def OnMessageAreaClose(self, widget, message_area):
 
347
                if self.errorMessageArea:
 
348
                        self.vbox.remove(self.errorMessageArea)
 
349
                        self.errorMessageArea = None
 
350
        
 
351
        #_____________________________________________________________________
 
352
        
 
353
        def OnMessageAreaReponse(self, widget, response_id, message_area):
 
354
                if response_id == gtk.RESPONSE_CLOSE:
 
355
                        self.OnMessageAreaClose(widget, message_area)
316
356
        
317
357
        #_____________________________________________________________________
318
358
        
358
398
                        widget -- reserved for GTK callbacks, don't use it explicitly.
359
399
                """
360
400
                tmp = self.project.viewScale * 4. / 5.
361
 
                #setting the value will trigger the gtk event and call OnZoom for us.
 
401
                #setting the value will trigger the "value-changed" signal and call OnZoom for us.
362
402
                self.zoomSlider.set_value(tmp)
363
403
                
364
404
        #_____________________________________________________________________
383
423
                        widget -- reserved for GTK callbacks, don't use it explicitly.
384
424
                """
385
425
                tmp = self.project.viewScale * 1.25
386
 
                #setting the value will trigger the gtk event and call OnZoom for us.
 
426
                #setting the value will trigger the "value-changed" signal and call OnZoom for us.
387
427
                self.zoomSlider.set_value(tmp)
388
 
                
389
 
        #_____________________________________________________________________
390
428
 
391
 
        def SetViewPosition(self, position):
392
 
                """
393
 
                Moves the view so that the given position is the leftmost side
394
 
                of the viewable area for scrolling, etc.
395
 
                
396
 
                Parameters:
397
 
                        position -- the new position to set.
398
 
                """
399
 
                length = self.project.GetProjectLength() + self.extraScrollTime 
400
 
                #check if its over the project length
401
 
                start = min(length - self.scrollRange.page_size, position)
402
 
                #check if its under zero (do this after checking the project length, because if the project length is 0 it will go under)
403
 
                start = max(0, start)
404
 
                self.scrollRange.value = start
405
 
                self.project.SetViewStart(start)
 
429
        #_____________________________________________________________________
 
430
                
 
431
        def OnZoomReset(self, widget, mouse):
 
432
                """
 
433
                Calls OnZoom when the user resets the zoom to the default by right-clicking.
 
434
                
 
435
                Parameters:
 
436
                        widget -- reserved for GTK callbacks, don't use it explicitly.
 
437
                        mouse -- reserved for GTK callbacks, don't use it explicitly.
 
438
                """
 
439
                if mouse.button == 3:
 
440
                        tmp = (self.ZOOM_MAX_SCALE - self.ZOOM_MIN_SCALE) / 2
 
441
                        #setting the value will trigger the "value-changed" signal and call OnZoom for us.
 
442
                        self.zoomSlider.set_value(tmp)
 
443
                        return True
 
444
                
 
445
        #_____________________________________________________________________
 
446
        
 
447
        def OnViewStartChanged(self, project):
 
448
                """
 
449
                Callback for when the project notifies that the
 
450
                viewable start position has changed.
 
451
                
 
452
                Parameters:
 
453
                        project -- The project instance that send the signal.
 
454
                """
 
455
                self.scrollRange.value = project.viewStart
406
456
        
407
457
        #_____________________________________________________________________
408
458
        
417
467
                """
418
468
                # If we're here then we're out of bounds of anything else
419
469
                # So we should clear any selected events
 
470
                if mouse.type == gtk.gdk._2BUTTON_PRESS or mouse.type == gtk.gdk._3BUTTON_PRESS:
 
471
                        return True
420
472
                self.project.ClearEventSelections()
421
473
                self.project.SelectInstrument(None)
422
 
                self.Update()
423
474
                
424
475
        #_____________________________________________________________________
425
476
        
438
489
                        
439
490
        #_____________________________________________________________________
440
491
        
441
 
        def OnStateChanged(self, obj, change=None, *extra):
442
 
                """
443
 
                Called when a change of state is signalled by any of the
444
 
                objects this view is 'listening' to.
445
 
                
446
 
                Parameters:
447
 
                        obj -- object changing state. *CHECK*
448
 
                        change -- the change which has occured.
449
 
                        extra -- extra parameters passed by the caller.
450
 
                """
451
 
                #don't update on volume change because it happens very often
452
 
                if change != "volume":
453
 
                        self.Update()
454
 
                
455
 
        #_____________________________________________________________________
456
 
        
457
492
        def OnDragDataReceived(self, widget, context, x, y, selection, targetType, time):
458
493
                """
459
494
                Called when the user releases MOUSE1, finishing a drag and drop
478
513
                self.project.AddInstrumentAndEvents(uris, True) # True: copy
479
514
                
480
515
                context.finish(True, False, time)
481
 
                self.Update()
482
516
                return True
483
517
        
484
518
        #_____________________________________________________________________
501
535
                return True
502
536
        
503
537
        #_____________________________________________________________________
 
538
        
 
539
        def ChangeSize(self, small):
 
540
                """
 
541
                Alters the size of the instrument lanes and removes the zoom buttons.
 
542
                
 
543
                Parameters:
 
544
                        small -- True if changing to small. Otherwise False.
 
545
                """
 
546
                #if the requested size has not changed then quit
 
547
                if small == self.small:
 
548
                        return
 
549
                self.small = small
 
550
                children = self.instrumentBox.get_children()
 
551
                for instrView in children:
 
552
                        instrView.ChangeSize(small)
 
553
                if self.small:
 
554
                        self.inbutton.hide()
 
555
                        self.outbutton.hide()
 
556
                        self.zoomSlider.hide()
 
557
                else:
 
558
                        self.inbutton.show()
 
559
                        self.outbutton.show()
 
560
                        self.zoomSlider.show()
 
561
                        
 
562
        #____________________________________________________________________   
 
563
        
 
564
        def OnRestoreMessageAreaClose(self, widget=None, msg_area=None):
 
565
                if self.restoreMessageArea:
 
566
                        self.vbox.remove(self.restoreMessageArea)
 
567
                        self.restoreMessageArea = None
 
568
        
 
569
        #____________________________________________________________________
 
570
        
 
571
        def OnRestoreMessageAreaResponse(self, widget, response_id, msg_area):
 
572
                if response_id == gtk.RESPONSE_OK:
 
573
                        self.project.DoIncrementalRestore()
 
574
                
 
575
                self.OnRestoreMessageAreaClose()
 
576
        
 
577
        #____________________________________________________________________
 
578
        
 
579
        def OnProjectIncSave(self, project):
 
580
                self.OnRestoreMessageAreaClose()
 
581
        
 
582
        #____________________________________________________________________
504
583
#=========================================================================