Dragging files to other applications
    It seems that Gtk 1.x on windows allows you to receive drops from
    other windows programs, but not to drag outside the application. 
    This means you can use DnD inside your PHP-Gtk application, but
    use drop only when communicating with other programs.
   
   The good news: Unlike the drop problems, all tested programs (Konqueror,
   Kate, Firefox, Opera, Nautilus) seem to be able to handle correct URIs 
   dragged to them in the right way. Even Firefox accepts
   text/uri-list data.
  
   The first step is again to tell the widget that it has the ability
   to act as a source for drag data. Furthermore, we need to provide
   the data we want to drag, which can be done by connecting the widget
   to the "drag-data-get"
   signal.
  
Example 4.7. Setting up the drag source
//at the end of buildDialog()
$this->tree->drag_source_set(GDK_BUTTON1_MASK, $this->targets, GDK_ACTION_COPY);
$this->tree->connect('drag-data-get', array(&$this, 'dragDataGet'));
 | 
   We told the widget the following:
   
- 
     Act as a drag source when the user uses the first (mostly left) 
     mouse button
    
 - 
     Provide one format for the dragging data, namely 
     text/uri-list
 - 
     Require the drop target to copy the file, not to move it.
    
 - 
     When the target widget demands for the data, call the 
     dragDataGet function of our class.
    
 
 
  
   Next is to provide the data for the drop target in the 
   dragDataGet function:
  
Example 4.8. Setting the data to drag
function dragDataGet( $tree, $context, $selection_data, $info, $time) {
    if( count( $tree->selection) < 1) { return false; }
    $node = $tree->selection[0];
    $file = $tree->node_get_text( $node, 2);
    if( $file == '') { return false; }
    $selection_data->set($selection_data->target, 8, urlencode($this->getUriFromFile($file)) . "\r\n");
}
    
/**
*   converts a file name to a URI
*   useful to convert a file to the text/uri-list compatible format
*   @param  string  The file
*   @return string  The URI
*/
function getUriFromFile( $strFile) {
    if (strstr($strFile, '://')) {
        //real URL
        $strUri = $strFile;
    } else {
        //normal file
        if (substr($strFile, 1, 2) ==  ':\\') {
            //windows path c:\programs\bla\blu\file.bli
            $strUri = 'file://localhost/' . str_replace('\\', '/', $strFile);
        } else {
            //should be nice unix file
            //@fixme: convert relative names to absolute ones?
            $strUri = 'file://localhost' . realpath($strFile);
        }
    }
    return $strUri;
}
 | 
   The data are passed by overwriting the selection data via the 
   set()  method of the
   selection_data. As we want to follow the 
   standards, the file name has to be converted to a full-flagged 
   url-encoded URI, with the terminating \r\n at 
   the end of the line. When nothing is selected in the tree, we don't
   change the selection data.
  
   When trying to drag a file to your favorite application, you will
   note that nothing happens. Why? The URI passed to the program looks
   like that: file%3A%2F%2Flocalhost%2Fdata%2Fphp-gtk.
   Yes, urlencode doesn't take care of the character's
   meaning in the URI. Now it would cost some effort to make a function
   which does a correct encoding while taking care of special characters,
   as http URIs can contain slashes in a parameter which would have to be
   encoded, but slashes in the filename not. For that reason, only a
   simple back-translation of some chars is done after urlencoding the
   string:
  
Example 4.9. urlencode replacement
function pathurlencode($uri) {
    $uri = urlencode($uri);
    $uri = str_replace('%3A', ':', $uri);
    $uri = str_replace('%2F', '/', $uri);
    $uri = str_replace('%26', '&', $uri);
    $uri = str_replace('%40', '@', $uri);
    $uri = str_replace('%3A', ':', $uri);
    $uri = str_replace('%3F', '?', $uri);
    return $uri;
}
 | 
   With that, we can change our dragDataGet function:
   
$selection_data->set($selection_data->target, 8, $this->pathurlencode($this->getUriFromFile($file)) . "\r\n");
  |