home *** CD-ROM | disk | FTP | other *** search
/ InterCD 2001 November / november_2001.iso / Browsers / Netscape 6.1 / browser.xpi / bin / chrome / toolkit.jar / content / global / filepicker.js < prev    next >
Encoding:
Text File  |  2001-06-21  |  13.3 KB  |  452 lines

  1. /* -*- Mode: Java; tab-width: 2; 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 nsIFilePicker       = Components.interfaces.nsIFilePicker;
  28. const nsIDirectoryServiceProvider = Components.interfaces.nsIDirectoryServiceProvider;
  29. const nsIDirectoryServiceProvider_CONTRACTID = "@mozilla.org/file/directory_service;1";
  30. const nsIOutlinerBoxObject = Components.interfaces.nsIOutlinerBoxObject;
  31.  
  32. var sfile = Components.classes[nsLocalFile_CONTRACTID].createInstance(nsILocalFile);
  33. var retvals;
  34. var filePickerMode;
  35. var homeDir;
  36. var outlinerView;
  37.  
  38. var textInput;
  39. var okButton;
  40.  
  41. var gFilePickerBundle;
  42.  
  43. function filepickerLoad() {
  44.   gFilePickerBundle = document.getElementById("bundle_filepicker");
  45.  
  46.   textInput = document.getElementById("textInput");
  47.   okButton = document.getElementById("ok");
  48.   outlinerView = new nsFileView();
  49.   outlinerView.selectionCallback = onSelect;
  50.  
  51.   if (window.arguments) {
  52.     var o = window.arguments[0];
  53.     retvals = o.retvals; /* set this to a global var so we can set return values */
  54.     const title = o.title;
  55.     filePickerMode = o.mode;
  56.     if (o.displayDirectory) {
  57.       const directory = o.displayDirectory.unicodePath;
  58.     }
  59.     const initialText = o.defaultString;
  60.     const filterTitles = o.filters.titles;
  61.     const filterTypes = o.filters.types;
  62.     const numFilters = filterTitles.length;
  63.  
  64.     window.title = title;
  65.  
  66.     if (initialText) {
  67.       textInput.value = initialText;
  68.     }
  69.   }
  70.  
  71.   if ((filePickerMode == nsIFilePicker.modeOpen) ||
  72.       (filePickerMode == nsIFilePicker.modeSave)) {
  73.  
  74.     window.setCursor("wait");
  75.     outlinerView.setFilter(filterTypes[0]);
  76.     window.setCursor("auto");
  77.  
  78.     /* build filter popup */
  79.     var filterPopup = document.createElement("menupopup");
  80.  
  81.     for (var i = 0; i < numFilters; i++) {
  82.       var menuItem = document.createElement("menuitem");
  83.       menuItem.setAttribute("label", filterTitles[i] + " (" + filterTypes[i] + ")");
  84.       menuItem.setAttribute("filters", filterTypes[i]);
  85.       filterPopup.appendChild(menuItem);
  86.     }
  87.  
  88.     var filterMenuList = document.getElementById("filterMenuList");
  89.     filterMenuList.appendChild(filterPopup);
  90.     if (numFilters > 0)
  91.       filterMenuList.selectedIndex = 0;
  92.     var filterBox = document.getElementById("filterBox");
  93.     filterBox.removeAttribute("hidden");
  94.   } else if (filePickerMode == nsIFilePicker.modeGetFolder) {
  95.     outlinerView.showOnlyDirectories = true;
  96.   }
  97.  
  98.   // start out with a filename sort
  99.   handleColumnClick("FilenameColumn");
  100.  
  101.   try {
  102.     var buttonLabel;
  103.     switch (filePickerMode) {
  104.       case nsIFilePicker.modeOpen:
  105.         buttonLabel = gFilePickerBundle.getString("openButtonLabel");
  106.         break;
  107.       case nsIFilePicker.modeSave:
  108.         buttonLabel = gFilePickerBundle.getString("saveButtonLabel");
  109.         break;
  110.       case nsIFilePicker.modeGetFolder:
  111.         buttonLabel = gFilePickerBundle.getString("selectFolderButtonLabel");
  112.         break;
  113.     }
  114.  
  115.     if (buttonLabel) {
  116.       okButton.setAttribute("label", buttonLabel);
  117.     }
  118.   } catch (exception) {
  119.     // keep it set to "OK"
  120.   }
  121.  
  122.   // setup the dialogOverlay.xul button handlers
  123.   doSetOKCancel(onOK, onCancel);
  124.  
  125.   // get the home dir
  126.   var dirServiceProvider = Components.classes[nsIDirectoryServiceProvider_CONTRACTID]
  127.                                      .getService(nsIDirectoryServiceProvider);
  128.   var persistent = new Object();
  129.   homeDir = dirServiceProvider.getFile("Home", persistent);
  130.  
  131.   if (directory) {
  132.     sfile.initWithUnicodePath(directory);
  133.   }
  134.   if (!directory || !(sfile.exists() && sfile.isDirectory())) {
  135.     // Start in the user's home directory
  136.     sfile.initWithUnicodePath(homeDir.unicodePath);
  137.   }
  138.  
  139.   retvals.buttonStatus = nsIFilePicker.returnCancel;
  140.  
  141.   gotoDirectory(sfile);
  142.   var outliner = document.getElementById("directoryOutliner");
  143.   outliner.outlinerBoxObject.view = outlinerView;
  144.  
  145.   doEnabling();
  146.   textInput.focus();
  147. }
  148.  
  149. function onFilterChanged(target)
  150. {
  151.   var filterTypes = target.getAttribute("filters");
  152.   window.setCursor("wait");
  153.   outlinerView.setFilter(filterTypes);
  154.   window.setCursor("auto");
  155. }
  156.  
  157. function onOK()
  158. {
  159.   var errorTitle, errorMessage, promptService;
  160.   var ret = nsIFilePicker.returnCancel;
  161.  
  162.   var isDir = false;
  163.   var isFile = false;
  164.  
  165.   var input = textInput.value;
  166.   if (input[0] == '~') // XXX XP?
  167.     input  = homeDir.unicodePath + input.substring(1);
  168.  
  169.   var file = sfile.clone().QueryInterface(nsILocalFile);
  170.   if (!file)
  171.     return false;
  172.  
  173.   /* XXX we need an XP way to test for an absolute path! */
  174.   if (input[0] == '/')   /* an absolute path was entered */
  175.     file.initWithUnicodePath(input);
  176.   else {
  177.     try {
  178.       file.appendRelativeUnicodePath(input);
  179.     } catch (e) {
  180.       dump("Can't append relative path '"+input+"':\n");
  181.       return false;
  182.     }
  183.   }
  184.  
  185.   if (!file.exists() && (filePickerMode != nsIFilePicker.modeSave)) {
  186.     errorTitle = gFilePickerBundle.getFormattedString("errorOpenFileDoesntExistTitle",
  187.                                                       [file.unicodePath]);
  188.     errorMessage = gFilePickerBundle.getFormattedString("errorOpenFileDoesntExistMessage",
  189.                                                         [file.unicodePath]);
  190.     promptService = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
  191.                               .getService(Components.interfaces.nsIPromptService);
  192.     promptService.alert(window, errorTitle, errorMessage);
  193.     return false;
  194.   }
  195.  
  196.   if (file.exists()) {
  197.     isDir = file.isDirectory();
  198.     isFile = file.isFile();
  199.   }
  200.  
  201.   switch(filePickerMode) {
  202.   case nsIFilePicker.modeOpen:
  203.     if (isFile) {
  204.       retvals.directory = file.parent.unicodePath;
  205.       ret = nsIFilePicker.returnOK;
  206.     } else if (isDir) {
  207.       if (!sfile.equals(file)) {
  208.         gotoDirectory(file);
  209.       }
  210.       textInput.value = "";
  211.       doEnabling();
  212.       ret = nsIFilePicker.returnCancel;
  213.     }
  214.     break;
  215.   case nsIFilePicker.modeSave:
  216.     if (isFile) { // can only be true if file.exists()
  217.       // we need to pop up a dialog asking if you want to save
  218.       var message = gFilePickerBundle.getFormattedString("confirmFileReplacing",
  219.                                                          [file.unicodePath]);
  220.       var rv = window.confirm(message);
  221.       if (rv) {
  222.         ret = nsIFilePicker.returnReplace;
  223.         retvals.directory = file.parent.unicodePath;
  224.       } else {
  225.         ret = nsIFilePicker.returnCancel;
  226.       }
  227.     } else if (isDir) {
  228.       if (!sfile.equals(file)) {
  229.         gotoDirectory(file);
  230.       }
  231.       textInput.value = "";
  232.       doEnabling();
  233.       ret = nsIFilePicker.returnCancel;
  234.     } else {
  235.       var parent = file.parent;
  236.       if (parent.exists() && parent.isDirectory()) {
  237.         ret = nsIFilePicker.returnOK;
  238.         retvals.directory = parent.unicodePath;
  239.       } else {
  240.         var oldParent = parent;
  241.         while (!parent.exists()) {
  242.           oldParent = parent;
  243.           parent = parent.parent;
  244.         }
  245.         errorTitle = gFilePickerBundle.getFormattedString("errorSavingFileTitle",
  246.                                                           [file.unicodePath]);
  247.         if (parent.isFile()) {
  248.           errorMessage = gFilePickerBundle.getFormattedString("saveParentIsFileMessage",
  249.                                                               [parent.unicodePath, file.unicodePath]);
  250.         } else {
  251.           errorMessage = gFilePickerBundle.getFormattedString("saveParentDoesntExistMessage",
  252.                                                               [oldParent.unicodePath, file.unicodePath]);
  253.         }
  254.         promptService = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
  255.                                   .getService(Components.interfaces.nsIPromptService);
  256.         promptService.alert(window, errorTitle, errorMessage);
  257.         ret = nsIFilePicker.returnCancel;
  258.       }
  259.     }
  260.     break;
  261.   case nsIFilePicker.modeGetFolder:
  262.     if (isDir) {
  263.       retvals.directory = file.parent.unicodePath;
  264.     } else { // if nothing selected, the current directory will be fine
  265.       retvals.directory = sfile.unicodePath;
  266.     }
  267.     ret = nsIFilePicker.returnOK;
  268.     break;
  269.   }
  270.  
  271.   retvals.file = file;
  272.   retvals.buttonStatus = ret;
  273.  
  274.   if (ret == nsIFilePicker.returnCancel)
  275.     return false;
  276.   else
  277.     return true;
  278. }
  279.  
  280. function onCancel()
  281. {
  282.   // Close the window.
  283.   retvals.buttonStatus = nsIFilePicker.returnCancel;
  284.   retvals.file = null;
  285.   return true;
  286. }
  287.  
  288. function onDblClick(e) {
  289.   var t = e.originalTarget;
  290.   if (t.localName != "outlinerbody")
  291.     return;
  292.  
  293.   var file = outlinerView.getSelectedFile();
  294.   if (!file)
  295.     return;
  296.  
  297.   if (file.isSymlink()) {
  298.     var targetFile = Components.classes[nsLocalFile_CONTRACTID].createInstance(nsILocalFile);
  299.     targetFile.initWithUnicodePath(file.unicodeTarget);
  300.     file = targetFile;
  301.   }
  302.  
  303.   if (file.isDirectory()) {
  304.     gotoDirectory(file);
  305.   }
  306.   else if (file.isFile()) {
  307.     doOKButton();
  308.   }
  309. }
  310.  
  311. function onClick(e) {
  312.   var t = e.originalTarget;
  313.   if (t.localName == "outlinercol")
  314.     handleColumnClick(t.id);
  315. }
  316.  
  317. function convertColumnIDtoSortType(columnID) {
  318.   var sortKey;
  319.   
  320.   switch (columnID) {
  321.   case "FilenameColumn":
  322.     sortKey = nsFileView.SORTTYPE_NAME;
  323.     break;
  324.   case "FileSizeColumn":
  325.     sortKey = nsFileView.SORTTYPE_SIZE;
  326.     break;
  327.   case "LastModifiedColumn":
  328.     sortKey = nsFileView.SORTTYPE_DATE;
  329.     break;
  330.   default:
  331.     dump("unsupported sort column: " + columnID + "\n");
  332.     sortKey = 0;
  333.     break;
  334.   }
  335.   
  336.   return sortKey;
  337. }
  338.  
  339. function handleColumnClick(columnID) {
  340.   var sortType = convertColumnIDtoSortType(columnID);
  341.   var sortOrder = (outlinerView.sortType == sortType) ? !outlinerView.reverseSort : false;
  342.   outlinerView.sort(sortType, sortOrder, false);
  343.   
  344.   // set the sort indicator on the column we are sorted by
  345.   var sortedColumn = document.getElementById(columnID);
  346.   if (outlinerView.reverseSort) {
  347.     sortedColumn.setAttribute("sortDirection", "descending");
  348.   } else {
  349.     sortedColumn.setAttribute("sortDirection", "ascending");
  350.   }
  351.   
  352.   // remove the sort indicator from the rest of the columns
  353.   var currCol = document.getElementById("directoryOutliner").firstChild;
  354.   while (currCol) {
  355.     while (currCol && currCol.localName != "outlinercol")
  356.       currCol = currCol.nextSibling;
  357.     if (currCol) {
  358.       if (currCol != sortedColumn) {
  359.         currCol.removeAttribute("sortDirection");
  360.       }
  361.       currCol = currCol.nextSibling;
  362.     }
  363.   }
  364. }
  365.  
  366. function doSort(sortType) {
  367.   outlinerView.sort(sortType, false);
  368. }
  369.  
  370. function onKeypress(e) {
  371.   if (e.keyCode == 8) /* backspace */
  372.     goUp();
  373. }
  374.  
  375. function doEnabling() {
  376.   // Maybe add check if textInput.value would resolve to an existing
  377.   // file or directory in .modeOpen. Too costly I think.
  378.   var enable = (textInput.value != "");
  379.  
  380.   okButton.disabled = !enable;
  381. }
  382.  
  383. function onSelect(file) {
  384.   var path = file.unicodeLeafName;
  385.  
  386.   if (path) {
  387.     if ((filePickerMode == nsIFilePicker.modeGetFolder) || file.isFile()) {
  388.       textInput.value = path;
  389.       doEnabling();
  390.     }
  391.   }
  392. }
  393.  
  394. function onDirectoryChanged(target)
  395. {
  396.   var path = target.getAttribute("label");
  397.  
  398.   var file = Components.classes[nsLocalFile_CONTRACTID].createInstance(nsILocalFile);
  399.   file.initWithUnicodePath(path);
  400.  
  401.   if (!sfile.equals(file)) {
  402.     gotoDirectory(file);
  403.   }
  404. }
  405.  
  406. function addToHistory(directoryName) {
  407.   var menu = document.getElementById("lookInMenu");
  408.   var children = menu.childNodes;
  409.  
  410.   var i = 0;
  411.   while (i < children.length) {
  412.     if (children[i].getAttribute("label") == directoryName)
  413.       break;
  414.  
  415.     ++i;
  416.   }
  417.  
  418.   if (i < children.length) {
  419.     if (i != 0) {
  420.       var node = children[i];
  421.       menu.removeChild(node);
  422.       menu.insertBefore(node, children[0]);
  423.     }
  424.   } else {
  425.     var menuItem = document.createElement("menuitem");
  426.     menuItem.setAttribute("label", directoryName);
  427.     menu.insertBefore(menuItem, children[0]);
  428.   }
  429.  
  430.   var menuList = document.getElementById("lookInMenuList");
  431.   menuList.selectedIndex = 0;
  432. }
  433.  
  434. function goUp() {
  435.   try {
  436.     var parent = sfile.parent;
  437.   } catch(ex) { dump("can't get parent directory\n"); }
  438.  
  439.   if (parent) {
  440.     gotoDirectory(parent);
  441.   }
  442. }
  443.  
  444. function gotoDirectory(directory) {
  445.   addToHistory(directory.unicodePath);
  446.   window.setCursor("wait");
  447.   outlinerView.setDirectory(directory.unicodePath);
  448.   window.setCursor("auto");
  449.   sfile = directory;
  450. }
  451.  
  452.