home *** CD-ROM | disk | FTP | other *** search
/ Chip 2002 January / 01_02.iso / software / netscape62win / browser.xpi / bin / chrome / toolkit.jar / content / global / nsOutlinerController.js < prev    next >
Encoding:
Text File  |  2001-07-02  |  8.6 KB  |  293 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.  *   Blake Ross <blakeross@telocity.com> (Original Author)
  22.  */
  23.  
  24. // helper routines, for doing rdf-based cut/copy/paste/etc
  25. // this needs to be more generic!
  26.  
  27. const nsTransferable_contractid = "@mozilla.org/widget/transferable;1";
  28. const clipboard_contractid = "@mozilla.org/widget/clipboard;1";
  29. const rdf_contractid = "@mozilla.org/rdf/rdf-service;1";
  30. const supportswstring_contractid = "@mozilla.org/supports-wstring;1";
  31. const rdfc_contractid = "@mozilla.org/rdf/container;1";
  32.  
  33. const nsISupportsWString = Components.interfaces.nsISupportsWString;
  34. const nsIClipboard = Components.interfaces.nsIClipboard;
  35. const nsITransferable = Components.interfaces.nsITransferable;
  36. const nsIRDFLiteral = Components.interfaces.nsIRDFLiteral;
  37. const nsIRDFContainer = Components.interfaces.nsIRDFContainer;
  38.  
  39. var gClipboard;
  40. var gOutliner;
  41. var gOutlinerBody;
  42. var gRDFC;
  43. var gRDF;
  44.  
  45. function isContainer(outliner, index)
  46. {
  47.   return outliner.outlinerBoxObject.view.isContainer(index);
  48. }
  49.  
  50. function nsOutlinerController_SetTransferData(transferable, flavor, text)
  51. {
  52.   if (!text)
  53.     return;
  54.   var textData = Components.classes[supportswstring_contractid].createInstance(nsISupportsWString);
  55.   textData.data = text;
  56.  
  57.   transferable.addDataFlavor(flavor);
  58.   transferable.setTransferData(flavor, textData, text.length*2);
  59. }
  60.  
  61. function nsOutlinerController_copy()
  62. {
  63.   var rangeCount = this.getOutlinerSelection().getRangeCount();
  64.   if (rangeCount < 1)
  65.     return false;
  66.    
  67.   // Build a url that encodes all the select nodes 
  68.   // as well as their parent nodes
  69.   var url = "";
  70.   var text = "";
  71.   var html = "";
  72.   var min = new Object();
  73.   var max = new Object();
  74.  
  75.   for (var i = 0; i < rangeCount; ++i) {
  76.     this.getOutlinerSelection().getRangeAt(i, min, max);
  77.     for (var k = min.value; k <= max.value; ++k) {
  78.       // If one of the selected items is
  79.       // a container, ignore it.
  80.       if (isContainer(this.getOutliner(), k))
  81.         continue;
  82.       var pageUrl  = this.getOutlinerView().getCellText(k, "URL");        
  83.       var pageName = this.getOutlinerView().getCellText(k, "Name");
  84.  
  85.       url += "ID:{" + pageUrl + "};";
  86.       url += "NAME:{" + pageName + "};";
  87.  
  88.       text += pageUrl + "\r";
  89.       html += "<a href='" + pageUrl + "'>";
  90.       if (pageName) html += pageName;
  91.         html += "</a><p>";
  92.     } 
  93.   }
  94.  
  95.   if (!url)
  96.     return false;
  97.  
  98.   // get some useful components
  99.   var trans = Components.classes[nsTransferable_contractid].createInstance(nsITransferable);
  100.   
  101.   if (!gClipboard)
  102.     gClipboard = Components.classes[clipboard_contractid].getService(Components.interfaces.nsIClipboard);
  103.  
  104.   gClipboard.emptyClipboard(nsIClipboard.kGlobalClipboard);
  105.  
  106.   this.SetTransferData(trans, "text/unicode", text);
  107.   this.SetTransferData(trans, "moz/bookmarkclipboarditem", url);
  108.   this.SetTransferData(trans, "text/html", html);
  109.  
  110.   gClipboard.setData(trans, null, nsIClipboard.kGlobalClipboard);
  111.   return true;
  112. }
  113.  
  114. function nsOutlinerController_cut()
  115. {
  116.   if (this.copy()) {
  117.     this.doDelete();
  118.     return true;            // copy succeeded, don't care if delete failed
  119.   }
  120.   return false;             // copy failed, so did cut
  121. }
  122.  
  123. function nsOutlinerController_selectAll()
  124. {
  125.   this.getOutlinerSelection().selectAll();
  126. }
  127.  
  128. function nsOutlinerController_delete()
  129. {  
  130.   var rangeCount = this.getOutlinerSelection().getRangeCount();
  131.   if (rangeCount < 1)
  132.     return false;      
  133.  
  134.   if (!gRDFC)
  135.     gRDFC = Components.classes[rdfc_contractid].getService(nsIRDFContainer);
  136.  
  137.   var datasource = this.getOutlinerBody().database;
  138.   var min = new Object(); 
  139.   var max = new Object();
  140.   var dirty = false;
  141.  
  142.   for (var i = 0; i < rangeCount; ++i) {
  143.     this.getOutlinerSelection().getRangeAt(i, min, max);
  144.     for (var k = max.value; k >= min.value; --k) {
  145.       var url = this.getOutlinerView().getCellText(k, "URL");
  146.       if (!url)
  147.         continue;
  148.         
  149.       if (!gRDF)
  150.         gRDF = Components.classes[rdf_contractid].getService(Components.interfaces.nsIRDFService);
  151.  
  152.       var IDRes = gRDF.GetResource(url);
  153.       if (!IDRes)
  154.         continue;
  155.  
  156.       var root = this.getOutlinerBody().getAttribute('ref');
  157.       var parentIDRes = gRDF.GetResource(root);
  158.       if (!parentIDRes)
  159.         continue;
  160.       
  161.       // XXX - This should not be necessary
  162.       // Why doesn't the unassertion fan out to all of the datasources in
  163.       // the nsIRDFCompositeDataSource so they can handle it?
  164.       var dsEnum = datasource.GetDataSources();   
  165.       while (dsEnum.hasMoreElements()) {
  166.         var ds = dsEnum.getNext().QueryInterface(Components.interfaces.nsIRDFDataSource);
  167.  
  168.         try {
  169.           // try a container-based approach
  170.           gRDFC.Init(ds, parentIDRes);
  171.           gRDFC.RemoveElement(IDRes, true);
  172.         } catch (ex) {
  173.           // otherwise remove the parent/child assertion then
  174.           var containment = gRDF.GetResource("http://home.netscape.com/NC-rdf#child");
  175.           ds.Unassert(parentIDRes, containment, IDRes);
  176.         }
  177.         dirty = true;
  178.       }
  179.     }
  180.   }
  181.  
  182.   if (dirty) {    
  183.     try {
  184.       var remote = datasource.QueryInterface(Components.interfaces.nsIRDFRemoteDataSource);
  185.       remote.Flush();
  186.     } catch (ex) {
  187.     }
  188.   }
  189.   return true;
  190. }
  191.  
  192. function nsOutlinerController(outliner, outlinerBody)
  193. {
  194.   this.outlinerId = outliner.id;
  195.   this.outlinerBodyId = outlinerBody.id;
  196.   outliner.controllers.appendController(this);
  197. }
  198.  
  199. nsOutlinerController.prototype = 
  200. {
  201.   // store the outliner's ID, rather than the outliner,
  202.   // to avoid holding a strong ref
  203.   outlinerId: null,
  204.   outlinerBodyId: null,
  205.   getOutliner : function()
  206.   {
  207.     if (!gOutliner)
  208.       gOutliner = document.getElementById(this.outlinerId);
  209.     return gOutliner;
  210.   },
  211.   getOutlinerBoxObject : function()
  212.   {
  213.     return this.getOutliner().outlinerBoxObject;
  214.   },
  215.   getOutlinerView : function()
  216.   {
  217.     return this.getOutliner().outlinerBoxObject.view;
  218.   },
  219.   getOutlinerSelection : function()
  220.   {
  221.     return this.getOutliner().outlinerBoxObject.view.selection;
  222.   },
  223.   getOutlinerBody : function()
  224.   {
  225.     if (!gOutlinerBody)
  226.       gOutlinerBody = document.getElementById(this.outlinerBodyId);
  227.     return gOutlinerBody;
  228.   },
  229.   SetTransferData : nsOutlinerController_SetTransferData,
  230.  
  231.   supportsCommand: function(command)
  232.   {
  233.     switch(command)
  234.     {
  235.       case "cmd_cut":
  236.       case "cmd_copy":
  237.       case "cmd_delete":
  238.       case "cmd_selectAll":
  239.         return true;
  240.       default:
  241.         return false;
  242.     }
  243.   },
  244.  
  245.   isCommandEnabled: function(command)
  246.   {
  247.     var haveCommand;
  248.     switch (command)
  249.     {
  250.       // commands which do not require selection              
  251.       case "cmd_selectAll":
  252.         var outlinerView = this.getOutlinerView();
  253.         return (outlinerView.rowCount !=  outlinerView.selection.count);
  254.                 
  255.       // these commands require selection
  256.       case "cmd_cut":
  257.         haveCommand = (this.cut != undefined);
  258.         break;
  259.       case "cmd_copy":
  260.         haveCommand = (this.copy != undefined);
  261.         break;
  262.       case "cmd_delete":
  263.         haveCommand = (this.doDelete != undefined);
  264.         break;
  265.     }
  266.         
  267.     // if we get here, then we have a command that requires selection
  268.     var haveSelection = (this.getOutlinerSelection().count);
  269.     return (haveCommand && haveSelection);
  270.   },
  271.  
  272.   doCommand: function(command)
  273.   {
  274.     switch(command)
  275.     {
  276.       case "cmd_cut":
  277.         return this.cut();
  278.       case "cmd_copy":
  279.         return this.copy();
  280.       case "cmd_delete":
  281.         return this.doDelete();        
  282.       case "cmd_selectAll":
  283.         return this.selectAll();
  284.     }
  285.     return false;
  286.   },
  287.   copy: nsOutlinerController_copy,
  288.   cut: nsOutlinerController_cut,
  289.   doDelete: nsOutlinerController_delete,
  290.   selectAll: nsOutlinerController_selectAll
  291. }
  292.  
  293.