Gtk
[ class tree: Gtk ] [ index: Gtk ] [ all elements ]

Source for file FileDrop.php

Documentation is available at FileDrop.php

  1. <?php
  2. /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
  3. // +----------------------------------------------------------------------+
  4. // | PHP version 4                                                        |
  5. // +----------------------------------------------------------------------+
  6. // | Copyright (c) 1997-2004 The PHP Group                                |
  7. // +----------------------------------------------------------------------+
  8. // | This source file is subject to version 3.0 of the PHP license,       |
  9. // | that is bundled with this package in the file LICENSE, and is        |
  10. // | available through the world-wide-web at the following url:           |
  11. // | http://www.php.net/license/3_0.txt.                                  |
  12. // | If you did not receive a copy of the PHP license and are unable to   |
  13. // | obtain it through the world-wide-web, please send a note to          |
  14. // | license@php.net so we can mail you a copy immediately.               |
  15. // +----------------------------------------------------------------------+
  16. // | Authors: Christian Weiske <cweiske@php.net>                          |
  17. // +----------------------------------------------------------------------+
  18. //
  19. // $Id: FileDrop.php 304748 2010-10-25 09:44:01Z clockwerx $
  20.  
  21. require_once('MIME/Type.php');
  22. require_once('PEAR.php');
  23.  
  24. /**
  25.  * A FileDrop error code.
  26.  * @const GTK_FILEDROP_WIDGET_NOT_SUPPORTED
  27.  */
  28. define('GTK_FILEDROP_WIDGET_NOT_SUPPORTED'1);
  29.  
  30. /**
  31. *   A class which makes it easy to
  32. *   make a GtkWidget accept the dropping
  33. *   of files or folders
  34. *   @author Christian Weiske <cweiske@cweiske.de>
  35. *   @package Gtk
  36. *
  37. *   @date 2004-10-21 13:12
  38. *   @license PHP
  39. *
  40. *   @todo
  41. *    - reject files when moving the dragging mouse over the widget, just like opera does
  42. *        how does this work? I don't know, but I suppose I should
  43. *
  44. *   @example
  45. *    Usage:
  46. *    Simply change the text of a widget
  47. *    (accept files with MIME-Types text/plain and text/html and files with .sgml extension):
  48. *        Gtk_FileDrop::attach($entry, array('text/plain', 'text/html', '.sgml'));
  49. *    Call a callback, and don't change the text (accept directories only):
  50. *        Gtk_FileDrop::attach($entry, array( 'inode/directory'), array( &$this, 'callback'), false);
  51. */
  52. {
  53.     /**
  54.     *   prepares a widget to accept file drops
  55.     *   @static
  56.     *   @param GtkWidget    The widget which shall accept files
  57.     *   @param array        List of MIME-Types to accept OR extensions, beginning with a dot "."
  58.     *   @param mixed        Callback to call when a drop with valid files happened
  59.     *   @param boolean      If the widget's text/label/content shall be changed automatically
  60.     *
  61.     *   @return boolean     If all was ok
  62.     */
  63.     function attach($widget$arTypes$objCallback = null$bSetText = true)
  64.     {
  65.         $widget->drag_dest_set(GTK_DEST_DEFAULT_ALLarray(array('text/uri-list'00))GDK_ACTION_COPY | GDK_ACTION_MOVE);
  66.         
  67.         $fd = new Gtk_FileDrop$arTypes$objCallback$bSetText);
  68.         $widget->connect('drag-data-received'array&$fd'dragDataReceived'));
  69.         
  70.         return true;
  71.     }
  72.     
  73.  
  74.     
  75.     /**
  76.     *   constructor
  77.     *   Use attach() instead!
  78.     *
  79.     *   @access private
  80.     */
  81.     function Gtk_FileDrop$arTypes$objCallback = null$bSetText = true
  82.     {
  83.         $this->arTypes     $arTypes;
  84.         $this->objCallback $objCallback;
  85.         $this->bSetText    $bSetText;
  86.     }
  87.     
  88.     
  89.     
  90.     /**
  91.     *   prepares a widget to accept directories only
  92.     *   Just a shortcut for the exhausted programmer
  93.     *   @static
  94.     *   @param GtkWidget    The widget which shall accept directories
  95.     *
  96.     *   @return boolean     If all was ok
  97.     */
  98.     function attachDirectory($widget)
  99.     {
  100.         return Gtk_FileDrop::attach($widgetarray('inode/directory'));
  101.     }
  102.  
  103.     
  104.     
  105.     /**
  106.     *   Data have been dropped over the widget
  107.     *   @param GtkWidget      The widget on which the data have been dropped
  108.     *   @param GdkDragContext The context of the drop
  109.     *   @param int            X position
  110.     *   @param int            Y position
  111.     *   @param int            Info parameter (0 in our case)
  112.     *   @param int            The time on which the event happened
  113.     */
  114.     function dragDataReceived($widget$context $x$y$data $info$time)
  115.     {
  116.         $arData     explode("\n"$data->data);
  117.         $arAccepted = array();
  118.         $arRejected = array();
  119.         $bDirectories = false;
  120.         foreach ($arData as $strLine{
  121.             $strLine trim($strLine);
  122.             if ($strLine == ''
  123.                 continue; 
  124.             }
  125.             $strFile     Gtk_FileDrop::getPathFromUrilistEntry($strLine);
  126.             $strFileMime Gtk_FileDrop::getMimeType($strFile);
  127.             $bAccepted   = false;
  128.             foreach ($this->arTypes as $strType{
  129.                 if ($strType == 'inode/directory'
  130.                     $bDirectories = true; 
  131.                 }
  132.                 if (($strType[0== '.' && Gtk_FileDrop::getFileExtension($strFile== $strType)
  133.                  || $strType == $strFileMime || MIME_Type::wildcardMatch($strType$strFileMime)) {
  134.                     $arAccepted[$strFile;
  135.                     $bAccepted    = true;
  136.                     break;
  137.                 }
  138.             }//foreach type
  139.             if (!$bAccepted{
  140.                 $arRejected[$strFile;
  141.             }
  142.         }//foreach line
  143.         
  144.         //make directories from the files if dirs are accepted
  145.         //this is done here to give native directories first places on the list
  146.         if ($bDirectories && count($arRejected> 0{
  147.             foreach ($arRejected as $strFile{
  148.                 $arAccepted[dirname$strFile);
  149.             }
  150.         }
  151.         
  152.         if (count($arAccepted== 0{
  153.             //no matching files
  154.             return;
  155.         }
  156.         
  157.         if ($this->bSetText{
  158.             $strClass get_class($widget);
  159.             switch ($strClass{
  160.             case 'GtkEntry':
  161.             case 'GtkLabel':
  162.                 $widget->set_text($arAccepted[0]);
  163.                 break;
  164.             case 'GtkButton':
  165.             case 'GtkToggleButton':
  166.             case 'GtkCheckButton':
  167.             case 'GtkRadioButton':
  168.                 $childs $widget->children();
  169.                 $child $childs[0];
  170.                 if (get_class($child== 'GtkLabel'{
  171.                     $child->set_text($arAccepted[0]);
  172.                 else {
  173.                     trigger_error('No label found on widget.');
  174.                 }
  175.                 break;
  176.             case 'GtkCombo':
  177.                 $entry $widget->entry;
  178.                 $entry->set_text($arAccepted[0]);
  179.                 break;
  180.             case 'GtkFileSelection':
  181.                 $widget->set_filename($arAccepted[0]);
  182.                 break;
  183.             case 'GtkList':
  184.                 foreach ($arAccepted as $strFile{
  185.                     $items[=new GtkListItem($strFile);
  186.                 }
  187.                 $widget->append_items($items);
  188.                 $widget->show_all();
  189.                 break;
  190.             default:
  191.                 PEAR::raiseError'Widget class "' $strClass '" is not supported'GTK_FILEDROP_WIDGET_NOT_SUPPORTEDPEAR_ERROR_TRIGGERE_USER_WARNING);
  192.                 break;
  193.             }
  194.         }//if bSetText
  195.         
  196.         if ($this->objCallback !== null{
  197.             call_user_func$this->objCallback$widget$arAccepted);
  198.         }//objCallback !== null
  199.     }
  200.     
  201.     
  202.     
  203.     /**
  204.     *   converts a file path gotten from a text/uri-list
  205.     *   drop to a usable local filepath
  206.     *
  207.     *   Php functions like parse_url can't be used as it is
  208.     *   likely that the dropped URI is no real URI but a
  209.     *   strange thing which tries to look like one
  210.     *   See the explanation at:
  211.     *   http://gtk.php.net/manual/en/tutorials.filednd.urilist.php
  212.     *
  213.     *   @static
  214.     *   @param  string  The line from the uri-list
  215.     *   @return string  The usable local filepath
  216.     */
  217.     function getPathFromUrilistEntry($strUriFile)
  218.     {
  219.         $strUriFile urldecode($strUriFile);//should be URL-encoded
  220.         $bUrl = false;
  221.         if (substr($strUriFile05== 'file:'{
  222.             //(maybe buggy) file protocol
  223.             if (substr($strUriFile017== 'file://localhost/'{
  224.                 //correct implementation
  225.                 $strFile substr($strUriFile16);
  226.             else if (substr($strUriFile08== 'file:///'{
  227.                 //no hostname, but three slashes - nearly correct
  228.                 $strFile substr($strUriFile7);
  229.             else if ($strUriFile[5== '/'{
  230.                 //theoretically, the hostname should be the first
  231.                 //but no one implements it
  232.                 $strUriFile substr($strUriFile5);
  233.                 for$n = 1; $n < 5; $n++{
  234.                     if ($strUriFile[$n!= '/'
  235.                         break; 
  236.                     }
  237.                 }
  238.                 $strUriFile substr($strUriFile$n - 1);
  239.                 if (!file_exists($strUriFile)) {
  240.                     //perhaps a correct implementation with hostname???
  241.                     $strUriFileNoHost strstr(substr($strUriFile1)'/');
  242.                     if (file_exists($strUriFileNoHost)) {
  243.                         //seems so
  244.                         $strUriFile $strUriFileNoHost;
  245.                     }
  246.                 }
  247.                 $strFile $strUriFile;
  248.             else {
  249.                 //NO slash after "file:" - what is that for a crappy program?
  250.                 $strFile substr ($strUriFile5);
  251.             }
  252.         else if (strstr($strUriFile'://')) {
  253.             //real protocol, but not file
  254.             $strFile $strUriFile;
  255.             $bUrl    = true;
  256.         else {
  257.             //local file?
  258.             $strFile $strUriFile;
  259.         }
  260.         if (!$bUrl && $strFile[2== ':' && $strFile[0== '/'{
  261.             //windows file path
  262.             $strFile str_replace('/''\\'substr($strFile1));
  263.         }
  264.         return $strFile;
  265.     }
  266.     
  267.     
  268.     
  269.     /**
  270.     *   returns the extension if a filename
  271.     *   including the leading dot
  272.     *   @static
  273.     *   @param  string  The filename
  274.     *   @return string  The extension with a leading dot
  275.     */
  276.     function getFileExtension($strFile)
  277.     {
  278.         $strExt strrchr($strFile'.');
  279.         if ($strExt == false
  280.             return ''
  281.         }
  282.         $strExt str_replace('\\''/'$strExt);
  283.         if (strpos($strExt'/'!== false{
  284.             return ''
  285.         }
  286.         return $strExt;
  287.     }
  288.     
  289.     
  290.     
  291.     /**
  292.     *   determines the mime-type for the given file
  293.     *   @static
  294.     *   @param  string  The file name
  295.     *   @return string  The MIME type or FALSE in the case of an error
  296.     */
  297.     function getMimeType($strFile)
  298.     {
  299.         //MIME_Type doesn't return the right type for directories
  300.         //The underlying functions MIME_Type used don't return it right, 
  301.         //so there is no chance to fix MIME_Type itself
  302.         if ((file_exists($strFile&& is_dir($strFile))
  303.           || substr($strFile-1== '/'{
  304.             return 'inode/directory';
  305.         }
  306.         $strMime = MIME_Type::autoDetect($strFile);
  307.         if (!PEAR::isError($strMime)) {
  308.             return $strMime;
  309.         }
  310.         
  311.         //determine by extension | as MIME_TYPE doesn't support this, I have to do this myself
  312.         $strExtension Gtk_FileDrop::getFileExtension($strFile);
  313.         switch ($strExtension{
  314.             case '.txt' 
  315.                 $strType 'text/plain'
  316.                 break;
  317.             case '.gif' 
  318.                 $strType 'image/gif'
  319.                 break;
  320.             case '.jpg' :
  321.             case '.jpeg'
  322.                 $strType 'image/jpg'
  323.                 break;
  324.             case '.png' 
  325.                 $strType 'image/png'
  326.                 break;
  327.             case '.xml' 
  328.                 $strType 'text/xml';
  329.                 break;
  330.             case '.htm' :
  331.             case '.html'
  332.                 $strType 'text/html'
  333.                 break;
  334.             default:     
  335.                 $strType = false; 
  336.                 break;
  337.         }
  338.         return $strType;
  339.     }
  340.     
  341. }
  342. ?>

Documentation generated on Mon, 11 Mar 2019 15:40:33 -0400 by phpDocumentor 1.4.4. PEAR Logo Copyright © PHP Group 2004.