home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 35 Internet / 35-Internet.zip / mozil06.zip / bin / chrome / toolkit.jar / content / global / filepicker.js < prev    next >
Text File  |  2001-02-14  |  12KB  |  406 lines

  1. /* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  2.  *
  3.  * The contents of this file are subject to the Mozilla 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/MPL/
  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 Communications
  16.  * Corporation.  Portions created by Netscape are
  17.  * Copyright (C) 2000 Netscape Communications Corporation. All
  18.  * Rights Reserved.
  19.  *
  20.  * Contributor(s): 
  21.  *  Stuart Parmenter <pavlov@netscape.com>
  22.  *  Brian Ryner <bryner@netscape.com>
  23.  *  Jan Varga <varga@utcru.sk>
  24.  *  Peter Annema <disttsc@bart.nl>
  25.  */
  26.  
  27. const nsILocalFile        = Components.interfaces.nsILocalFile;
  28. const nsILocalFile_CONTRACTID = "@mozilla.org/file/local;1";
  29. const nsIFilePicker       = Components.interfaces.nsIFilePicker;
  30. const nsIDirectoryServiceProvider = Components.interfaces.nsIDirectoryServiceProvider;
  31. const nsIDirectoryServiceProvider_CONTRACTID = "@mozilla.org/file/directory_service;1";
  32. const nsStdURL_CONTRACTID     = "@mozilla.org/network/standard-url;1";
  33. const nsIFileURL          = Components.interfaces.nsIFileURL;
  34. const NC_NAMESPACE_URI = "http://home.netscape.com/NC-rdf#";
  35.  
  36. var sfile = Components.classes[nsILocalFile_CONTRACTID].createInstance(nsILocalFile);
  37. var retvals;
  38. var filePickerMode;
  39. var currentFilter;
  40. var dirHistory;
  41. var homeDir;
  42.  
  43. var directoryTree;
  44. var textInput;
  45.  
  46. var bundle = srGetStrBundle("chrome://global/locale/filepicker.properties");   
  47.  
  48. function onLoad() {
  49.   dirHistory = new Array();
  50.  
  51.   directoryTree = document.getElementById("directoryTree");
  52.   textInput = document.getElementById("textInput");
  53.  
  54.   if (window.arguments) {
  55.     var o = window.arguments[0];
  56.     retvals = o.retvals; /* set this to a global var so we can set return values */
  57.     const title = o.title;
  58.     filePickerMode = o.mode;
  59.     if (o.displayDirectory)
  60.       const directory = o.displayDirectory.path;
  61.     const initialText = o.defaultString;
  62.     const filterTitles = o.filters.titles;
  63.     const filterTypes = o.filters.types;
  64.     const numFilters = filterTitles.length;
  65.  
  66.     window.title = title;
  67.  
  68.     if (initialText) {
  69.       textInput.value = initialText;
  70.     }
  71.   }
  72.  
  73.   if ((filePickerMode == nsIFilePicker.modeOpen) ||
  74.       (filePickerMode == nsIFilePicker.modeSave)) {
  75.  
  76.     currentFilter = filterTypes[0];
  77.     applyFilter();
  78.  
  79.     /* build filter popup */
  80.     var filterPopup = document.createElement("menupopup");
  81.  
  82.     for (var i = 0; i < numFilters; i++) {
  83.       var menuItem = document.createElement("menuitem");
  84.       menuItem.setAttribute("value", filterTitles[i] + " (" + filterTypes[i] + ")");
  85.       menuItem.setAttribute("filters", filterTypes[i]);
  86.       filterPopup.appendChild(menuItem);
  87.     }
  88.  
  89.     var filterMenuList = document.getElementById("filterMenuList");
  90.     filterMenuList.appendChild(filterPopup);
  91.     var filterBox = document.getElementById("filterBox");
  92.     filterBox.removeAttribute("hidden");
  93.   } else if (filePickerMode == nsIFilePicker.modeGetFolder) {
  94.      // This applies a special filter to only show directories
  95.      applyDirectoryFilter();
  96.   }
  97.  
  98.   try {
  99.     var buttonLabel;
  100.     switch (filePickerMode) {
  101.       case nsIFilePicker.modeOpen:
  102.         buttonLabel = bundle.GetStringFromName("openButtonLabel");
  103.         break;
  104.       case nsIFilePicker.modeSave:
  105.         buttonLabel = bundle.GetStringFromName("saveButtonLabel");
  106.         break;
  107.       case nsIFilePicker.modeGetFolder:
  108.         buttonLabel = bundle.GetStringFromName("selectFolderButtonLabel");
  109.         break;
  110.     }
  111.  
  112.     if (buttonLabel) {
  113.       var okButton = document.getElementById("ok");
  114.       okButton.setAttribute("value", buttonLabel);
  115.     }
  116.   } catch (exception) {
  117.     // keep it set to "OK"
  118.   }
  119.  
  120.   // setup the dialogOverlay.xul button handlers
  121.   doSetOKCancel(onOK, onCancel);
  122.  
  123.   // get the home dir
  124.   var dirServiceProvider = Components.classes[nsIDirectoryServiceProvider_CONTRACTID].getService().QueryInterface(nsIDirectoryServiceProvider);
  125.   var persistent = new Object();
  126.   homeDir = dirServiceProvider.getFile("Home", persistent);
  127.  
  128.   if (directory)
  129.     sfile.initWithPath(directory);
  130.   if (!directory || !(sfile.exists() && sfile.isDirectory())) {
  131.     // Start in the user's home directory
  132.     sfile.initWithPath(homeDir.path);
  133.   }
  134.  
  135.   retvals.buttonStatus = nsIFilePicker.returnCancel;
  136.  
  137.   gotoDirectory(sfile);
  138.   textInput.focus();
  139. }
  140.  
  141. function onFilterChanged(target)
  142. {
  143.   var filterTypes = target.getAttribute("filters");
  144.   currentFilter = filterTypes;
  145.   applyFilter();
  146. }
  147.  
  148. function applyFilter()
  149. {
  150.   /* This is where we manipulate the DOM to create new <rule>s */
  151.   var splitFilters = currentFilter.split("; ");
  152.   var matchAllFiles = false;
  153.  
  154.   /* get just the extensions for each of the filters */
  155.   var extensions = new Array(splitFilters.length);
  156.   for (var j = 0; j < splitFilters.length; j++) {
  157.     var tmpStr = splitFilters[j];
  158.     if (tmpStr == "*") {
  159.       matchAllFiles = true;
  160.       break;
  161.     } else
  162.       extensions[j] = tmpStr.substring(1); /* chop off the '*' */
  163.   }
  164.  
  165.   /* delete all rules except the first one */
  166.   for (var j = 1;; j++) {
  167.     var ruleNode = document.getElementById("matchRule."+j);
  168.     if (ruleNode) {
  169.       ruleNode.parentNode.removeChild(ruleNode);
  170.     } else {
  171.       break;
  172.     }
  173.   }
  174.  
  175.   /* if we are matching all files, just clear the extension attribute
  176.      on the first match rule and we're done */
  177.   var rule0 = document.getElementById("matchRule.0");
  178.   if (matchAllFiles) {
  179.     rule0.removeAttributeNS(NC_NAMESPACE_URI, "extension");
  180.     directoryTree.builder.rebuild();
  181.     return;
  182.   }
  183.  
  184.   /* rule 0 is special */
  185.   rule0.setAttributeNS(NC_NAMESPACE_URI, "extension" , extensions[0]);
  186.  
  187.   /* iterate through the remaining extensions, creating new rules */
  188.   var ruleNode = document.getElementById("fileFilter");
  189.  
  190.   for (var k=1; k < extensions.length; k++) {
  191.     var newRule = rule0.cloneNode(true);
  192.     newRule.setAttribute("id", "matchRule."+k);
  193.     newRule.setAttributeNS(NC_NAMESPACE_URI, "extension", extensions[k]);
  194.     ruleNode.appendChild(newRule);
  195.   }
  196.  
  197.   directoryTree.builder.rebuild();
  198. }
  199.  
  200. function onOK()
  201. {
  202.   var ret = nsIFilePicker.returnCancel;
  203.  
  204.   var isDir = false;
  205.   var isFile = false;
  206.  
  207.   var input = textInput.value;
  208.   if (input[0] == '~') // XXX XP?
  209.     input  = homeDir.pathá+ input.substring(1);
  210.  
  211.   var file = sfile.clone().QueryInterface(nsILocalFile);
  212.   if (!file)
  213.     return false;
  214.  
  215.   /* XXX we need an XP way to test for an absolute path! */
  216.   if (input[0] == '/')   /* an absolute path was entered */
  217.     file.initWithPath(input);
  218.   else {
  219.     try {
  220.       file.appendRelativePath(input);
  221.     } catch (e) {
  222.       dump("Can't append relative path '"+input+"':\n");
  223.       return false;
  224.     }
  225.   }
  226.  
  227.   if (!file.exists() && (filePickerMode != nsIFilePicker.modeSave)) {
  228.     return false;
  229.   }
  230.  
  231.   if (file.exists()) {
  232.     isDir = file.isDirectory();
  233.     isFile = file.isFile();
  234.   }
  235.  
  236.   switch(filePickerMode) {
  237.   case nsIFilePicker.modeOpen:
  238.     if (isFile) {
  239.       retvals.directory = file.parent.path;
  240.       ret = nsIFilePicker.returnOK;
  241.     } else if (isDir) {
  242.       if (!sfile.equals(file)) {
  243.         gotoDirectory(file);
  244.       }
  245.       textInput.value = "";
  246.       ret = nsIFilePicker.returnCancel;
  247.     }
  248.     break;
  249.   case nsIFilePicker.modeSave:
  250.     if (isFile) {
  251.       // we need to pop up a dialog asking if you want to save
  252.       rv = window.confirm(file.path + " " + bundle.GetStringFromName("confirmFileReplacing"));
  253.       if (rv)
  254.         ret = nsIFilePicker.returnReplace;
  255.       else
  256.         ret = nsIFilePicker.returnCancel;
  257.       retvals.directory = file.parent.path;
  258.     } else if (!file.exists()) {
  259.       ret = nsIFilePicker.returnOK;
  260.       retvals.directory = file.parent.path;
  261.     }
  262.     break;
  263.   case nsIFilePicker.modeGetFolder:
  264.     if (isDir) {
  265.       retvals.directory = file.parent.path;
  266.     } else { // if nothing selected, the current directory will be fine
  267.       retvals.directory = sfile.path;
  268.     }
  269.     ret = nsIFilePicker.returnOK;
  270.     break;
  271.   }
  272.  
  273.   retvals.file = file;
  274.   retvals.buttonStatus = ret;
  275.  
  276.   if (ret == nsIFilePicker.returnCancel)
  277.     return false;
  278.   else
  279.     return true;
  280. }
  281.  
  282. function onCancel()
  283. {
  284.   // Close the window.
  285.   retvals.buttonStatus = nsIFilePicker.returnCancel;
  286.   retvals.file = null;
  287.   return true;
  288. }
  289.  
  290. function onClick(e) {
  291.   if ( e.detail == 2 ) {
  292.     var file = URLpathToFile(e.target.parentNode.getAttribute("path"));
  293.  
  294.     if (file.isDirectory()) {
  295.       gotoDirectory(file);
  296.     }
  297.     else if (file.isFile()) {
  298.       /* what about symlinks? what if they symlink to a directory? */
  299.       return doOKButton();
  300.     }
  301.   }
  302. }
  303.  
  304. function onKeypress(e) {
  305.   if (e.keyCode == 8) /* backspace */
  306.     goUp();
  307. }
  308.  
  309. function onSelect(e) {
  310.   if (e.target.selectedItems.length != 1)
  311.     return;
  312.   var file = URLpathToFile(e.target.selectedItems[0].firstChild.getAttribute("path"));
  313.  
  314.   if (file.isFile() || (filePickerMode == nsIFilePicker.modeGetFolder)) {
  315.     /* Note, if we're in GetFolder mode, everything in the display list
  316.        will be a directory, so we don't need an extra check */
  317.     textInput.value = file.leafName;
  318.   }
  319. }
  320.  
  321. function onDirectoryChanged(target)
  322. {
  323.   var path = target.getAttribute("value");
  324.  
  325.   var file = Components.classes[nsILocalFile_CONTRACTID].createInstance(nsILocalFile);
  326.   file.initWithPath(path);
  327.  
  328.   gotoDirectory(file);
  329. }
  330.  
  331. function addToHistory(directoryName) {
  332.   var found = false;
  333.   var i = 0;
  334.   while (!found && i<dirHistory.length) {
  335.     if (dirHistory[i] == directoryName)
  336.       found = true;
  337.     else
  338.       i++;
  339.   }
  340.  
  341.   if (found) {
  342.     if (i!=0) {
  343.       dirHistory.splice(i, 1);
  344.       dirHistory.splice(0, 0, directoryName);
  345.     }
  346.   } else {
  347.     dirHistory.splice(0, 0, directoryName);
  348.   }
  349.  
  350.   var menu = document.getElementById("lookInMenu");
  351.  
  352.   var children = menu.childNodes;
  353.   for (var i=0; i < children.length; i++)
  354.     menu.removeChild(children[i]);
  355.  
  356.   for (var i=0; i < dirHistory.length; i++) {
  357.     var menuItem = document.createElement("menuitem");
  358.     menuItem.setAttribute("value", dirHistory[i]);
  359.     menu.appendChild(menuItem);
  360.   }
  361.  
  362.   var menuList = document.getElementById("lookInMenuList");
  363.   menuList.selectedIndex = 0;
  364. }
  365.  
  366. function goUp() {
  367.   try {
  368.     var parent = sfile.parent;
  369.   } catch(ex) { dump("can't get parent directory\n"); }
  370.  
  371.   if (parent) {
  372.     gotoDirectory(parent);
  373.   }
  374. }
  375.  
  376. function gotoDirectory(directory) {
  377.   var newURL = fileToURL(directory);
  378.   addToHistory(directory.path);
  379.   directoryTree.setAttribute("ref", fileToURL(directory).spec);
  380.   sfile = directory;
  381. }
  382.  
  383. function fileToURL(aFile) {
  384.   var newDirectoryURL = Components.classes[nsStdURL_CONTRACTID].createInstance().QueryInterface(nsIFileURL);
  385.   newDirectoryURL.file = aFile;
  386.   return newDirectoryURL;
  387. }
  388.  
  389. function URLpathToFile(aURLstr) {
  390.   var fileURL = Components.classes[nsStdURL_CONTRACTID].createInstance().QueryInterface(nsIFileURL);
  391.   fileURL.spec = aURLstr;
  392.   return fileURL.file;
  393. }
  394.  
  395. function applyDirectoryFilter() {
  396.   var ruleNode = document.getElementById("matchRule.0");
  397.  
  398.   // A file can never have an extension of ".", because the extension is
  399.   // by definition everything after the last dot.  So, this rule will
  400.   // cause only directories to show up.
  401.   ruleNode.setAttributeNS(NC_NAMESPACE_URI, "extension", ".");
  402.  
  403.   directoryTree.builder.rebuild();
  404. }
  405.  
  406.