art with code


Filezoo day 32: drag and drop handling

Added a handler for dealing with data dropped onto the Filezoo window. It copies or moves the source uri list (Konqueror, Nautilus, Firefox and others pass the DnD'd files as \r\n-separated strings of URIs) over to the drag target directory using Gnome-VFS. So now I can drag an image from Firefox onto a Filezoo directory and it'll be copied there.

The implementation was a wee bit challenging, since there was very little documentation for doing DragDrop event handling and perhaps even less for the Gnome.Vfs namespace. Here's what I used:

Handling data dropped on the widget, this is from the widget constructor:

TargetEntry[] target_table = new TargetEntry [] {
new TargetEntry ("text/uri-list", 0, 0),
new TargetEntry ("text/plain", 0, 1),
new TargetEntry ("STRING", 0, 1)

DragDataReceived += delegate (object sender, DragDataReceivedArgs e) {
string type = e.SelectionData.Type.Name;
Gdk.DragAction action = e.Context.SuggestedAction;
if (type == "text/uri-list" || (type == "text/plain" && IsURI(e.SelectionData.Text))) {
string data = new System.Text.ASCIIEncoding().GetString(e.SelectionData.Data);
string[] uris = data.Split(new char[] {'\r','\n','\0'},
string msg = action.ToString() + " " + String.join(", ", uris);
} else {
Console.WriteLine("Got {0}", e.SelectionData.Text);

Gtk.Drag.DestSet (this, DestDefaults.All, target_table,
| Gdk.DragAction.Copy
| Gdk.DragAction.Ask

Using Gnome-VFS XferUriList to do a copy or move:

public static void XferURIs
(Gnome.Vfs.Uri[] sources, Gnome.Vfs.Uri[] targets, bool removeSources)
XferURIs (sources, targets, removeSources, ConsoleXferProgressCallback);

public static void XferURIs
(Gnome.Vfs.Uri[] sources, Gnome.Vfs.Uri[] targets, bool removeSources,
Gnome.Vfs.XferProgressCallback callback)
Gnome.Vfs.Vfs.Initialize ();
Gnome.Vfs.XferOptions mode = Gnome.Vfs.XferOptions.Recursive;
if (removeSources) mode = mode | Gnome.Vfs.XferOptions.Removesource;
Gnome.Vfs.Xfer.XferUriList (
sources, targets, mode,

public static int ConsoleXferProgressCallback (Gnome.Vfs.XferProgressInfo info)
switch (info.Status) {
case Gnome.Vfs.XferProgressStatus.Vfserror:
Console.WriteLine("{0}: {1} in {2} -> {3}",
info.Status, info.VfsStatus, info.SourceName, info.TargetName);
return (int)Gnome.Vfs.XferErrorAction.Abort;
case Gnome.Vfs.XferProgressStatus.Overwrite:
Console.WriteLine("{0}: {1} in {2} -> {3}",
info.Status, info.VfsStatus, info.SourceName, info.TargetName);
return (int)Gnome.Vfs.XferOverwriteAction.Abort;
Console.WriteLine("{0} / {1} {2} -> {3}",
info.BytesCopied, info.BytesTotal, info.SourceName, info.TargetName);
return 1;

(Now I need a pimpin' progress indicator... maybe an arc to the dir with "incoming $STUFF -." or something with ambient notifications. Maybe just pop up a plain jane Gtk progress dialog :P)

Next features on this path would be dragging things around, navigating while dragging (think Finder's space-to-descend on steroids), and handling cut-copy-paste.
Post a Comment

Blog Archive

About Me

My photo

Built art installations, web sites, graphics libraries, web browsers, mobile apps, desktop apps, media player themes, many nutty prototypes