Re: [jokosher-devel] [PATCH] for ticket #26 (Moving instruments)



On 8/7/06, Laszlo Pandy <laszlok2 gmail com> wrote:
Jens Geiregat a écrit :
> On 8/7/06, Laszlo Pandy <laszlok2 gmail com> wrote:
> [...]
>> > - What to do with 'bad' file-uri's? (http:// in stead of file://,
>> > trying to import a .txt, ...)
>> >
>>
>> Just ignore them and tell the status bar to display "could not import
>> file(s): %s".
> The problem with this solution is that there isn't enough space in the
> statusbar to display 20 filenames. Even when displaying only the
> amount of bad uri's, there is no good time/event to remove that
> message from the statusbar.
>
> About http:// uri's: Jokosher can't handle these because it uses
> shutil.copy to copy the imported files to the project's audio folder.
> Maybe that code should try to use gnome-vfs, and fall back to shutil
> when it is not available?
> Like this:
> try:
>    import gnomevfs
>    # use a gnome-vfs copy
> except ImportError:
>    print "GnomeVFS not available, using shutil"
>    import shutil
>    try:
>        file = parse_uri_to_local_file(uri)
>    except URIError:
>        #Display an error message
>    try:
>        shutil.copy(file, dest)
>    except IOError:
>        ...
>
> It would be better if this was handled by some helper-class or
> function though...

The plan is to support gnomevfs before 0.2 if someone gets around to
implementing it. I was thinking that there should be one class that
makes a nice abstraction for us. Then you would just do:

import FileOperations
FileOperations.movefile(from_place, to_place)

With this, file operations could try to use gnomevfs and default to
regular python calls if that doesnt work.

Laszlo



New patch:
* Fixes some bugs in my previous patch: dragging an instrument and
dropping it where it originally was isn't undo-able anymore. And
dragging something from outside of Jokosher to the instrument heads
doesn't result in lots of exceptions in the background anymore.
* Added support for dragging 'text/uri-list'-items to an
EventLaneView. Only 'file://' uri's are processed, others are ignored.
Processed uri's are turned into events, after copying the file to the
project audio directory. Multiple uri's are handled with
'MoveButDoNotOverlap'.


Jens
Index: InstrumentViewer.py
===================================================================
--- InstrumentViewer.py	(revision 553)
+++ InstrumentViewer.py	(working copy)
@@ -120,7 +120,7 @@
 		self.instrument.isSelected = False
 		
 		# Begin Drag and Drop code
-		self.headerEventBox.drag_dest_set(gtk.DEST_DEFAULT_DROP,
+		self.headerEventBox.drag_dest_set(gtk.DEST_DEFAULT_MOTION,
 										  self.DRAG_TARGETS, 
 										  gtk.gdk.ACTION_MOVE)
 		self.headerEventBox.connect('drag_motion', self.OnDragMotion)
@@ -278,13 +278,13 @@
 			source instrument in the GUI. Swapping of the Instrument objects
 			in self.project.instruments happens in OnDragDrop().
 		'''
-		source_header = context.get_source_widget() 	# Will return an EventBox (self.headerEventBox)
-		if widget != source_header: 					# Dont swap with self
+		source = context.get_source_widget() 	# Will return an EventBox (self.headerEventBox)
+		if widget != source:					# Dont swap with self
 			box = self.GetInstrumentViewVBox()
 			iv_array = box.get_children()				# InstrumentView array
 			index_iv = iv_array.index(self)
 			
-			source_iv = [iv for iv in iv_array if iv.headerEventBox == source_header][0]
+			source_iv = [iv for iv in iv_array if iv.headerEventBox == source][0]
 			index_source_iv = iv_array.index(source_iv)
 			
 			box.reorder_child(source_iv, index_iv)		# Immediate visual feedback
@@ -315,7 +315,10 @@
 		id = self.instrument.id
 		box = self.GetInstrumentViewVBox()
 		position = box.get_children().index(self)
-		self.project.MoveInstrument(id, position)
+		instr_position = self.project.instruments.index(self.instrument)
+		if position != instr_position:
+			self.project.MoveInstrument(id, position)
+		context.finish(True, False, time)
 	
 	#______________________________________________________________________
 
Index: EventLaneViewer.py
===================================================================
--- EventLaneViewer.py	(revision 553)
+++ EventLaneViewer.py	(working copy)
@@ -5,12 +5,19 @@
 import Monitored
 import os.path
 import gettext
+import urlparse # To split up URI's
+import urllib # To decode URI's
 _ = gettext.gettext
 
 #=========================================================================
 
 class EventLaneViewer(gtk.EventBox):
-
+	
+	URI_DRAG_TYPE = 84			# Number only to be used inside Jokosher
+	DRAG_TARGETS = [ ( "text/uri-list", 	# Accept uri-lists
+					   0,					# From everywhere
+					   URI_DRAG_TYPE )]		# Use the custom number
+	
 	#_____________________________________________________________________
 
 	def __init__(self, project, instrument, instrumentviewer, mainview, small = False):
@@ -55,6 +62,12 @@
 		self.connect("button-press-event", self.OnMouseDown)
 		self.connect("motion_notify_event", self.OnMouseMove)
 		self.connect("leave_notify_event", self.OnMouseLeave)
+		self.fixed.drag_dest_set(	gtk.DEST_DEFAULT_DROP,
+									self.DRAG_TARGETS, 
+									gtk.gdk.ACTION_COPY)
+		self.fixed.connect("drag_data_received", self.OnDragDataReceived)
+		self.fixed.connect("drag_motion", self.OnDragMotion)
+		self.fixed.connect("drag_leave", self.OnDragLeave)
 		self.fixed.connect("expose-event", self.OnDraw)
 		
 		self.messageID = None
@@ -172,7 +185,7 @@
 	#_____________________________________________________________________
 		
 	def OnMouseLeave(self, widget, mouse):
-		if self.messageID:   #clesr status bar if not already clear
+		if self.messageID:   #clear status bar if not already clear
 			self.mainview.ClearStatusBar(self.messageID)
 			self.messageID = None
 		if not self.popupIsActive:
@@ -239,5 +252,42 @@
 		
 	#_____________________________________________________________________
 	
-
+	def OnDragDataReceived(self, widget, context, x, y, selection, targetType, time):
+		'''
+			Called when the drop succeeds. Adds an event for each "file://"-uri
+			in the uri-list to the instrument, one after the other. The files
+			will be copied to the project audio directory.
+		'''
+		start = (x/self.project.viewScale) + self.project.viewStart
+		# Splitlines to separate the uri's, unquote to decode the uri-encoding ('%20' -> ' ')
+		for uri in [urllib.unquote(uri) for uri in selection.data.splitlines()]:
+			# Parse the uri, and continue only if it is pointing to a local file
+			(scheme, domain, file, params, query, fragment) = urlparse.urlparse(uri, "file")
+			if scheme == "file":
+				event = self.instrument.addEventFromFile(start, file, True) # True: copy
+				event.MoveButDoNotOverlap(event.start)
+				start = event.start # Should improve performance with very large file-lists
+		context.finish(True, False, time)
+		return True
+	
+	#_____________________________________________________________________
+	
+	def OnDragMotion(self, widget, context, x, y, time):
+		'''
+			Draws a cursor on the EventLane while dragging something over it.
+		'''
+		context.drag_status(gtk.gdk.ACTION_COPY, time)
+		self.highlightCursor = x
+		self.queue_draw()
+		return True
+	
+	#_____________________________________________________________________
+	
+	def OnDragLeave(self, widget, drag_context, timestamp):
+		'''
+			Removes the cursor when dragging out of the EventLane.
+		'''
+		self.highlightCursor = None
+		self.queue_draw()
+	
 #=========================================================================
Index: Instrument.py
===================================================================
--- Instrument.py	(revision 553)
+++ Instrument.py	(working copy)
@@ -318,11 +318,13 @@
 		
 		self.StateChanged()
 		
+		return e
+		
 	#_____________________________________________________________________
 	
 	def addEventFromEvent(self, start, event):
 		"""Creates a new event instance identical to the event parameter 
-		   and adds it to this instrument to this instrument (for paste functionality).
+		   and adds it to this instrument (for paste functionality).
 		      start - The offset time in seconds
 		      event - The event to be recreated on this instrument
 		      


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