home *** CD-ROM | disk | FTP | other *** search
/ Chip 2003 January / 01_03.iso / software / ghostzilla_hit / files / ghostzilla-1.0-plus-install.exe / chrome / toolkit.jar / content / global / nsDragAndDrop.js < prev    next >
Encoding:
JavaScript  |  2002-04-09  |  9.5 KB  |  264 lines

  1. /* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
  2. /* ***** BEGIN LICENSE BLOCK *****
  3.  * Version: NPL 1.1/GPL 2.0/LGPL 2.1
  4.  *
  5.  * The contents of this file are subject to the Netscape Public License
  6.  * Version 1.1 (the "License"); you may not use this file except in
  7.  * compliance with the License. You may obtain a copy of the License at
  8.  * http://www.mozilla.org/NPL/
  9.  *
  10.  * Software distributed under the License is distributed on an "AS IS" basis,
  11.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  12.  * for the specific language governing rights and limitations under the
  13.  * License.
  14.  *
  15.  * The Original Code is mozilla.org code.
  16.  *
  17.  * The Initial Developer of the Original Code is 
  18.  * Netscape Communications Corporation.
  19.  * Portions created by the Initial Developer are Copyright (C) 1998
  20.  * the Initial Developer. All Rights Reserved.
  21.  *
  22.  * Contributor(s):
  23.  *   Ben Goodger <ben@netscape.com> (Original Author)
  24.  *
  25.  * Alternatively, the contents of this file may be used under the terms of
  26.  * either the GNU General Public License Version 2 or later (the "GPL"), or 
  27.  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  28.  * in which case the provisions of the GPL or the LGPL are applicable instead
  29.  * of those above. If you wish to allow use of your version of this file only
  30.  * under the terms of either the GPL or the LGPL, and not to allow others to
  31.  * use your version of this file under the terms of the NPL, indicate your
  32.  * decision by deleting the provisions above and replace them with the notice
  33.  * and other provisions required by the GPL or the LGPL. If you do not delete
  34.  * the provisions above, a recipient may use your version of this file under
  35.  * the terms of any one of the NPL, the GPL or the LGPL.
  36.  *
  37.  * ***** END LICENSE BLOCK ***** */
  38.  
  39. ////////////////////////////////////////////////////////////////////////////
  40. // XXX - WARNING - DRAG AND DROP API CHANGE ALERT - XXX
  41. // This file has been extensively modified in a checkin planned for Mozilla
  42. // 0.8, and the API has been modified. DO NOT MODIFY THIS FILE without 
  43. // approval from ben@netscape.com, otherwise your changes will be lost. 
  44.  
  45. /**
  46.  * XXX - until load is supported in chrome, you also need to include 
  47.  *       these files:
  48.  *       chrome://global/content/nsTransferable.js
  49.  **/
  50.  
  51.  
  52.  
  53. /**
  54.  * nsDragAndDrop - a convenience wrapper for nsTransferable, nsITransferable
  55.  *                 and nsIDragService/nsIDragSession. 
  56.  *
  57.  * USAGE INFORMATION: see 'README-nsDragAndDrop.html' in the same source directory
  58.  *                    as this file (typically xpfe/global/resources/content)
  59.  */
  60.  
  61. var nsDragAndDrop = {
  62.   
  63.   _mDS: null,
  64.   get mDragService()
  65.     {
  66.       if (!this._mDS) 
  67.         {
  68.           const kDSContractID = "@mozilla.org/widget/dragservice;1";
  69.           const kDSIID = Components.interfaces.nsIDragService;
  70.           this._mDS = Components.classes[kDSContractID].getService(kDSIID);
  71.         }
  72.       return this._mDS;
  73.     },
  74.  
  75.   /**
  76.    * void startDrag (DOMEvent aEvent, Object aDragDropObserver) ;
  77.    *
  78.    * called when a drag on an element is started.
  79.    *
  80.    * @param DOMEvent aEvent
  81.    *        the DOM event fired by the drag init
  82.    * @param Object aDragDropObserver
  83.    *        javascript object of format described above that specifies
  84.    *        the way in which the element responds to drag events.
  85.    **/  
  86.   startDrag: function (aEvent, aDragDropObserver)
  87.     {
  88.       if (!("onDragStart" in aDragDropObserver))
  89.         return;
  90.  
  91.       const kDSIID = Components.interfaces.nsIDragService;
  92.       var dragAction = { action: kDSIID.DRAGDROP_ACTION_COPY + kDSIID.DRAGDROP_ACTION_MOVE + kDSIID.DRAGDROP_ACTION_LINK };
  93.  
  94.       var transferData = { data: null };
  95.       try 
  96.         {
  97.           aDragDropObserver.onDragStart(aEvent, transferData, dragAction);
  98.         }
  99.       catch (e) 
  100.         {
  101.           return;  // not a draggable item, bail!
  102.         }
  103.  
  104.       if (!transferData.data) return;
  105.       transferData = transferData.data;
  106.       
  107.       var transArray = Components.classes["@mozilla.org/supports-array;1"]
  108.                                  .createInstance(Components.interfaces.nsISupportsArray);
  109.  
  110.       var region = null;
  111.       if (aEvent.originalTarget.localName == "treechildren") {
  112.         // let's build the drag region
  113.         var tree = aEvent.originalTarget.parentNode;
  114.         try {
  115.           region = Components.classes["@mozilla.org/gfx/region;1"].createInstance(Components.interfaces.nsIScriptableRegion);
  116.           region.init();
  117.           var obo = tree.treeBoxObject;
  118.           var bo = obo.treeBody.boxObject;
  119.           var obosel= obo.selection;
  120.  
  121.           var rowX = bo.x;
  122.           var rowY = bo.y;
  123.           var rowHeight = obo.rowHeight;
  124.           var rowWidth = bo.width;
  125.  
  126.           //add a rectangle for each visible selected row
  127.           for (var i = obo.getFirstVisibleRow(); i <= obo.getLastVisibleRow(); i ++)
  128.           {
  129.             if (obosel.isSelected(i))
  130.               region.unionRect(rowX, rowY, rowWidth, rowHeight);
  131.             rowY = rowY + rowHeight;
  132.           }
  133.       
  134.           //and finally, clip the result to be sure we don't spill over...
  135.           region.intersectRect(bo.x, bo.y, bo.width, bo.height);
  136.         } catch(ex) {
  137.           dump("Error while building selection region: " + ex + "\n");
  138.           region = null;
  139.         }
  140.       }
  141.  
  142.       var count = 0;
  143.       do 
  144.         {
  145.           var trans = nsTransferable.set(transferData._XferID == "TransferData" 
  146.                                          ? transferData 
  147.                                          : transferData.dataList[count++]);
  148.           transArray.AppendElement(trans.QueryInterface(Components.interfaces.nsISupports));
  149.         }
  150.       while (transferData._XferID == "TransferDataSet" && 
  151.              count < transferData.dataList.length);
  152.       
  153.       try {
  154.         this.mDragService.invokeDragSession(aEvent.target, transArray, region, dragAction.action);
  155.       }
  156.       catch(ex) {
  157.         // this could be because the user pressed escape to
  158.         // cancel the drag. even if it's not, there's not much
  159.         // we can do, so be silent.
  160.       }
  161.       aEvent.preventBubble();
  162.     },
  163.  
  164.   /** 
  165.    * void dragOver (DOMEvent aEvent, Object aDragDropObserver) ;
  166.    *
  167.    * called when a drag passes over this element
  168.    *
  169.    * @param DOMEvent aEvent
  170.    *        the DOM event fired by the drag init
  171.    * @param Object aDragDropObserver
  172.    *        javascript object of format described above that specifies
  173.    *        the way in which the element responds to drag events.
  174.    **/
  175.   dragOver: function (aEvent, aDragDropObserver)
  176.     { 
  177.       if (!("onDragOver" in aDragDropObserver)) 
  178.         return;
  179.       if (!this.mDragSession) 
  180.         this.mDragSession = this.mDragService.getCurrentSession();
  181.       if (this.mDragSession)
  182.         {
  183.           var flavourSet = aDragDropObserver.getSupportedFlavours();
  184.           for (var flavour in flavourSet.flavourTable)
  185.             {
  186.               if (this.mDragSession.isDataFlavorSupported(flavour))
  187.                 {
  188.                   this.mDragSession.canDrop = (this.mDragSession.sourceNode != aEvent.target);
  189.                   aDragDropObserver.onDragOver(aEvent, 
  190.                                                flavourSet.flavourTable[flavour], 
  191.                                                this.mDragSession);
  192.                   aEvent.preventBubble();
  193.                   break;
  194.                 }
  195.             }
  196.         }
  197.     },
  198.  
  199.   mDragSession: null,
  200.  
  201.   /** 
  202.    * void drop (DOMEvent aEvent, Object aDragDropObserver) ;
  203.    *
  204.    * called when the user drops on the element
  205.    *
  206.    * @param DOMEvent aEvent
  207.    *        the DOM event fired by the drag init
  208.    * @param Object aDragDropObserver
  209.    *        javascript object of format described above that specifies
  210.    *        the way in which the element responds to drag events.
  211.    **/
  212.   drop: function (aEvent, aDragDropObserver)
  213.     {
  214.       if (!("onDrop" in aDragDropObserver))
  215.         return;
  216.         
  217.       if (!this.mDragSession) 
  218.         this.mDragSession = this.mDragService.getCurrentSession();
  219.       if (this.mDragSession)
  220.         {
  221.           var flavourSet = aDragDropObserver.getSupportedFlavours();
  222.           var transferData = nsTransferable.get(flavourSet, this.getDragData, true);
  223.           aEvent.preventBubble();
  224.           // hand over to the client to respond to dropped data
  225.           var multiple = "canHandleMultipleItems" in aDragDropObserver && aDragDropObserver.canHandleMultipleItems;
  226.           var dropData = multiple ? transferData : transferData.first.first;
  227.           aDragDropObserver.onDrop(aEvent, dropData, this.mDragSession);
  228.         }
  229.     },
  230.  
  231.   dragExit: function (aEvent, aDragDropObserver)
  232.     {
  233.       if ("onDragExit" in aDragDropObserver)
  234.         aDragDropObserver.onDragExit(aEvent, this.mDragSession);
  235.     },  
  236.     
  237.   /** 
  238.    * nsISupportsArray getDragData (Object aFlavourList)
  239.    *
  240.    * Creates a nsISupportsArray of all droppable items for the given
  241.    * set of supported flavours.
  242.    * 
  243.    * @param FlavourSet aFlavourSet
  244.    *        formatted flavour list.
  245.    **/  
  246.   getDragData: function (aFlavourSet)
  247.     {
  248.       var supportsArray = Components.classes["@mozilla.org/supports-array;1"]
  249.                                     .createInstance(Components.interfaces.nsISupportsArray);
  250.  
  251.       for (var i = 0; i < nsDragAndDrop.mDragSession.numDropItems; ++i)
  252.         {
  253.           var trans = nsTransferable.createTransferable();
  254.           for (var j = 0; j < aFlavourSet.flavours.length; ++j)
  255.             trans.addDataFlavor(aFlavourSet.flavours[j].contentType);
  256.           nsDragAndDrop.mDragSession.getData(trans, i);
  257.           supportsArray.AppendElement(trans);
  258.         }
  259.       return supportsArray;
  260.     }
  261.  
  262. };
  263.  
  264.