home *** CD-ROM | disk | FTP | other *** search
/ Chip 2002 January / 01_02.iso / software / netscape62win / mail.xpi / bin / chrome / messenger.jar / content / messenger / messengerdnd.js < prev    next >
Text File  |  2001-08-15  |  15KB  |  425 lines

  1. /* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  2.  *
  3.  * The contents of this file are subject to the Netscape Public
  4.  * License Version 1.1 (the "License"); you may not use this file
  5.  * except in compliance with the License. You may obtain a copy of
  6.  * the License at http://www.mozilla.org/NPL/
  7.  *
  8.  * Software distributed under the License is distributed on an "AS
  9.  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
  10.  * implied. See the License for the specific language governing
  11.  * rights and limitations under the License.
  12.  *
  13.  * The Original Code is mozilla.org code.
  14.  *
  15.  * The Initial Developer of the Original Code is Netscape
  16.  * Communications Corporation.  Portions created by Netscape are
  17.  * Copyright (C) 1998 Netscape Communications Corporation. All
  18.  * Rights Reserved.
  19.  *
  20.  * Contributor(s): 
  21.  *   disttsc@bart.nl
  22.  *   jarrod.k.gray@rose-hulman.edu
  23.  *   Jan Varga <varga@utcru.sk>
  24.  */
  25.  
  26. // cache these services
  27. var RDF = Components.classes["@mozilla.org/rdf/rdf-service;1"].getService().QueryInterface(Components.interfaces.nsIRDFService);
  28. var dragService = Components.classes["@mozilla.org/widget/dragservice;1"].getService().QueryInterface(Components.interfaces.nsIDragService);
  29. var nsIDragService = Components.interfaces.nsIDragService;
  30.  
  31. function debugDump(msg)
  32. {
  33.   // uncomment for noise
  34.   //dump(msg+"\n");
  35. }
  36.  
  37. function CanDropOnFolderOutliner(index)
  38. {
  39.     var dragSession = null;
  40.     var dragFolder = false;
  41.     var flavor = false;
  42.  
  43.     dragSession = dragService.getCurrentSession();
  44.     if (! dragSession)
  45.         return false;
  46.  
  47.     if (dragSession.isDataFlavorSupported("text/nsmessageOrfolder"))
  48.         flavor = true;
  49.  
  50.     var trans = Components.classes["@mozilla.org/widget/transferable;1"].createInstance(Components.interfaces.nsITransferable);
  51.     if (! trans)
  52.         return false;
  53.  
  54.     var folderOutliner = GetFolderOutliner();
  55.     var targetResource = GetFolderResource(folderOutliner, index);
  56.     var targetUri = targetResource.Value;
  57.     var targetFolder = targetResource.QueryInterface(Components.interfaces.nsIMsgFolder);
  58.     var targetServer = targetFolder.server;
  59.     var sourceServer;
  60.  
  61.     trans.addDataFlavor("text/nsmessageOrfolder");
  62.    
  63.     for (var i = 0; i < dragSession.numDropItems; i++)
  64.     {
  65.         dragSession.getData (trans, i);
  66.         var dataObj = new Object();
  67.         var bestFlavor = new Object();
  68.         var len = new Object();
  69.         try
  70.         {
  71.             trans.getAnyTransferData ( bestFlavor, dataObj, len );
  72.         }
  73.         catch (ex)
  74.         {
  75.             continue;   //no data so continue;
  76.         }
  77.         if (dataObj)
  78.             dataObj = dataObj.value.QueryInterface(Components.interfaces.nsISupportsWString);
  79.         if (! dataObj)
  80.             continue;
  81.  
  82.         // pull the URL out of the data object
  83.         var sourceUri = dataObj.data.substring(0, len.value);
  84.         if (! sourceUri)
  85.             continue;
  86.  
  87.         var sourceResource;
  88.         try
  89.         {
  90.             sourceResource = RDF.GetResource(sourceUri, true);
  91.             var folder = sourceResource.QueryInterface(Components.interfaces.nsIFolder);
  92.             if (folder)
  93.                 dragFolder = true;
  94.         }
  95.         catch(ex)
  96.         {
  97.             sourceResource = null;
  98.             var isServer = GetFolderAttribute(folderOutliner, targetResource, "IsServer");
  99.             if (isServer == "true")
  100.             {
  101.                 debugDump("***isServer == true\n");
  102.                 return false;
  103.             }
  104.             var canFileMessages = GetFolderAttribute(folderOutliner, targetResource, "CanFileMessages");
  105.             if (canFileMessages != "true")
  106.             {
  107.                 debugDump("***canFileMessages == false\n");
  108.                 return false;
  109.             }
  110.             var noSelect = GetFolderAttribute(folderOutliner, targetResource, "NoSelect");
  111.             if (noSelect == "true")
  112.             {
  113.                 debugDump("***NoSelect == true\n");
  114.                 return false;
  115.             } 
  116.             var hdr = messenger.messageServiceFromURI(sourceUri).messageURIToMsgHdr(sourceUri);
  117.             if (hdr.folder == targetFolder)
  118.                 return false;
  119.             break;
  120.         }
  121.  
  122.         // we should only get here if we are dragging and dropping folders
  123.         var sourceResource = folder.QueryInterface(Components.interfaces.nsIRDFResource);
  124.         var sourceFolder = sourceResource.QueryInterface(Components.interfaces.nsIMsgFolder);
  125.         sourceServer = sourceFolder.server;
  126.  
  127.         if (targetUri == sourceUri)    
  128.             return false;
  129.  
  130.         //don't allow drop on different imap servers.
  131.         if (sourceServer != targetServer && targetServer.type == "imap")
  132.             return false;
  133.  
  134.         //don't allow immediate child to be dropped to it's parent
  135.         if (targetFolder.URI == sourceFolder.parent.URI)
  136.         {
  137.             debugDump(targetFolder.URI + "\n");
  138.             debugDump(sourceFolder.parent.URI + "\n");     
  139.             return false;
  140.         }
  141.  
  142.         var isAncestor = sourceFolder.isAncestorOf(targetFolder);
  143.         // don't allow parent to be dropped on its ancestors
  144.         if (isAncestor)
  145.             return false;
  146.     }
  147.  
  148.     if (dragFolder)
  149.     {
  150.         //first check these conditions then proceed further
  151.         debugDump("***isFolderFlavor == true \n");
  152.  
  153.         // no copy for folder drag
  154.         if (dragSession.dragAction == nsIDragService.DRAGDROP_ACTION_COPY)
  155.             return false;
  156.  
  157.         var canCreateSubfolders = GetFolderAttribute(folderOutliner, targetResource, "CanCreateSubfolders");
  158.         // if cannot create subfolders then a folder cannot be dropped here     
  159.         if (canCreateSubfolders == "false")
  160.         {
  161.             debugDump("***canCreateSubfolders == false \n");
  162.             return false;
  163.         }
  164.         var serverType = GetFolderAttribute(folderOutliner, targetResource, "ServerType");
  165.  
  166.         // if we've got a folder that can't be renamed
  167.         // allow us to drop it if we plan on dropping it on "Local Folders"
  168.         // (but not within the same server, to prevent renaming folders on "Local Folders" that
  169.         // should not be renamed)
  170.         var srcCanRename = GetFolderAttribute(folderOutliner, sourceResource, "CanRename");
  171.         if (srcCanRename == "false") {
  172.             if (sourceServer == targetServer)
  173.                 return false;
  174.             if (serverType != "none")
  175.                 return false;
  176.         }
  177.     }
  178.  
  179.     //message or folder
  180.     if (flavor)
  181.     {
  182.         dragSession.canDrop = true;
  183.         return true;
  184.     }
  185.     
  186.     return false;
  187. }
  188.  
  189. function CanDropBeforeAfterFolderOutliner(index, before)
  190. {
  191.     return false;
  192. }
  193.  
  194. function DropOnFolderOutliner(row, orientation)
  195. {
  196.     if (orientation != Components.interfaces.nsIOutlinerView.inDropOn)
  197.         return;
  198.  
  199.     var folderOutliner = GetFolderOutliner();
  200.     var targetResource = GetFolderResource(folderOutliner, row);
  201.  
  202.     var targetUri = targetResource.Value;
  203.     debugDump("***targetUri = " + targetUri + "\n");
  204.  
  205.     var dragSession = dragService.getCurrentSession();
  206.     if (! dragSession )
  207.         return;
  208.  
  209.     var trans = Components.classes["@mozilla.org/widget/transferable;1"].createInstance(Components.interfaces.nsITransferable);
  210.     trans.addDataFlavor("text/nsmessageOrfolder");
  211.  
  212.     var list = Components.classes["@mozilla.org/supports-array;1"].createInstance(Components.interfaces.nsISupportsArray);
  213.  
  214.     var dropMessage = true;       
  215.     var sourceUri;
  216.     var sourceResource;
  217.     var sourceFolder;
  218.     var sourceServer;
  219.     
  220.     for (var i = 0; i < dragSession.numDropItems; i++)
  221.     {
  222.         dragSession.getData (trans, i);
  223.         var dataObj = new Object();
  224.         var bestFlavor = new Object();
  225.         var len = new Object();
  226.         trans.getAnyTransferData(bestFlavor, dataObj, len);
  227.         if (dataObj)
  228.             dataObj = dataObj.value.QueryInterface(Components.interfaces.nsISupportsWString);
  229.         if (! dataObj)
  230.             continue;
  231.  
  232.         // pull the URL out of the data object
  233.         sourceUri = dataObj.data.substring(0, len.value);
  234.         if (! sourceUri)
  235.             continue;
  236.  
  237.         debugDump("    Node #" + i + ": drop " + sourceUri + " to " + targetUri + "\n");
  238.  
  239.         sourceResource = RDF.GetResource(sourceUri, true);
  240.         // only do this for the first object, either they are all messages or they are all folders
  241.         if (i == 0) {
  242.             try {
  243.                 sourceFolder = sourceResource.QueryInterface(Components.interfaces.nsIMsgFolder);
  244.                 if (sourceFolder) {
  245.                     // we are dropping a folder
  246.                     dropMessage = false;
  247.                 }
  248.                 else {
  249.                     dropMessage = true;
  250.                 }
  251.             }
  252.             catch (ex) {
  253.                 dropMessage = true;
  254.             }
  255.         }
  256.         else {
  257.             if (! dropMessage)
  258.                 dump("drag and drop of multiple folders isn't supported\n");
  259.         }
  260.  
  261.         if (dropMessage) {
  262.             // from the message uri, get the appropriate messenger service
  263.             // and then from that service, get the msgDbHdr
  264.             list.AppendElement(messenger.messageServiceFromURI(sourceUri).messageURIToMsgHdr(sourceUri));
  265.         }
  266.         else {
  267.             // Prevent dropping of a node before, after, or on itself
  268.             if (sourceResource == targetResource)    
  269.                 continue;
  270.  
  271.             list.AppendElement(sourceResource);
  272.         }
  273.     }
  274.  
  275.     if (list.Count() < 1)
  276.        return false;
  277.  
  278.     var isSourceNews = false;
  279.     isSourceNews = isNewsURI(sourceUri);
  280.     
  281.     var targetFolder = targetResource.QueryInterface(Components.interfaces.nsIMsgFolder);
  282.     var targetServer = targetFolder.server;
  283.  
  284.     if (dropMessage) {
  285.         // fix this, to get the folder from the sourceUri.  this won't work with multiple 3 panes
  286.         sourceFolder = GetThreadPaneFolder();
  287.         sourceServer = sourceFolder.server;
  288.  
  289.         try {
  290.             if (isSourceNews) {
  291.                 // news to pop or imap is always a copy
  292.                 messenger.CopyMessages(sourceFolder, targetFolder, list, false);
  293.             }
  294.             else {
  295.                 // fix this, will not work for multiple 3 panes
  296.                 if (dragSession.dragAction == nsIDragService.DRAGDROP_ACTION_MOVE)
  297.                     SetNextMessageAfterDelete();
  298.                 var dragAction = dragSession.dragAction;
  299.                 if (dragAction == nsIDragService.DRAGDROP_ACTION_COPY)
  300.                     messenger.CopyMessages(sourceFolder, targetFolder, list, false);
  301.                 else if (dragAction == nsIDragService.DRAGDROP_ACTION_MOVE)
  302.                     messenger.CopyMessages(sourceFolder, targetFolder, list, true);
  303.             }
  304.         }
  305.         catch (ex) {
  306.             dump("failed to copy messages: " + ex + "\n");
  307.         }
  308.     }
  309.     else {
  310.         sourceServer = sourceFolder.server;
  311.         try 
  312.         {
  313.             messenger.CopyFolders(GetFolderDatasource(), targetResource, list, (sourceServer == targetServer));
  314.         }
  315.         catch(ex)
  316.         {
  317.             dump ("Exception : CopyFolders " + ex + "\n");
  318.         }
  319.     }
  320. }
  321.  
  322. function BeginDragFolderOutliner(event)
  323. {
  324.     debugDump("BeginDragFolderOutliner\n");
  325.  
  326.     var folderOutliner = GetFolderOutliner();
  327.     var row = {};
  328.     var col = {};
  329.     var elt = {};
  330.     folderOutliner.outlinerBoxObject.getCellAt(event.clientX, event.clientY, row, col, elt);
  331.     var folderResource = GetFolderResource(folderOutliner, row.value);
  332.  
  333.     if (GetFolderAttribute(folderOutliner, folderResource, "IsServer") == "true")
  334.     {
  335.       debugDump("***IsServer == true\n");
  336.       return false;
  337.     }
  338.  
  339.     // do not allow the drag when news is the source
  340.     if (GetFolderAttribute(folderOutliner, folderResource, "ServerType") == "nntp") 
  341.     {
  342.       debugDump("***ServerType == nntp\n");
  343.       return false;
  344.     }
  345.  
  346.     var selectedFolders = GetSelectedFolders();
  347.     return BeginDragOutliner(event, folderOutliner, selectedFolders, "text/nsmessageOrfolder");
  348. }
  349.  
  350. function BeginDragThreadPane(event)
  351. {
  352.     debugDump("BeginDragThreadPane\n");
  353.  
  354.     var threadOutliner = GetThreadOutliner();
  355.     var selectedMessages = GetSelectedMessages();
  356.     return BeginDragOutliner(event, threadOutliner, selectedMessages, "text/nsmessageOrfolder");
  357. }
  358.  
  359. function BeginDragOutliner(event, outliner, selArray, flavor)
  360. {
  361.     var dragStarted = false;
  362.  
  363.     var transArray = Components.classes["@mozilla.org/supports-array;1"].createInstance(Components.interfaces.nsISupportsArray);
  364.     if ( !transArray ) return(false);
  365.  
  366.     // let's build the drag region
  367.     var region = null;
  368.     try {
  369.       region = Components.classesByID["{da5b130a-1dd1-11b2-ad47-f455b1814a78}"].createInstance(Components.interfaces.nsIScriptableRegion);
  370.       region.init();
  371.       var obo = outliner.outlinerBoxObject;
  372.       var bo = obo.outlinerBody.boxObject;
  373.       var obosel= obo.selection;
  374.  
  375.       var rowX = bo.x;
  376.       var rowY = bo.y;
  377.       var rowHeight = obo.rowHeight;
  378.       var rowWidth = bo.width;
  379.  
  380.       //add a rectangle for each visible selected row
  381.       for (var i = obo.getFirstVisibleRow(); i <= obo.getLastVisibleRow(); i ++)
  382.       {
  383.         if (obosel.isSelected(i))
  384.           region.unionRect(rowX, rowY, rowWidth, rowHeight);
  385.         rowY = rowY + rowHeight;
  386.       }
  387.       
  388.       //and finally, clip the result to be sure we don't spill over...
  389.       region.intersectRect(bo.x, bo.y, bo.width, bo.height);
  390.     } catch(ex) {
  391.       dump("Error while building selection region: " + ex + "\n");
  392.       region = null;
  393.     }
  394.     
  395.     var count = selArray.length;
  396.     debugDump("selArray.length = " + count + "\n");
  397.     for (i = 0; i < count; ++i ) {
  398.         var trans = Components.classes["@mozilla.org/widget/transferable;1"].createInstance(Components.interfaces.nsITransferable);
  399.         if (!trans) return(false);
  400.  
  401.         var genTextData = Components.classes["@mozilla.org/supports-wstring;1"].createInstance(Components.interfaces.nsISupportsWString);
  402.         if (!genTextData) return(false);
  403.  
  404.         trans.addDataFlavor(flavor);
  405.  
  406.         // get id (url)
  407.         var id = selArray[i];
  408.         genTextData.data = id;
  409.         debugDump("    ID #" + i + " = " + id + "\n");
  410.  
  411.         trans.setTransferData ( flavor, genTextData, id.length * 2 );  // doublebyte byte data
  412.  
  413.         // put it into the transferable as an |nsISupports|
  414.         var genTrans = trans.QueryInterface(Components.interfaces.nsISupports);
  415.         transArray.AppendElement(genTrans);
  416.     }
  417.  
  418.     dragService.invokeDragSession ( event.target, transArray, region, nsIDragService.DRAGDROP_ACTION_COPY +
  419.     nsIDragService.DRAGDROP_ACTION_MOVE );
  420.  
  421.     dragStarted = true;
  422.  
  423.     return(!dragStarted);  // don't propagate the event if a drag has begun
  424. }
  425.