зеркало из https://github.com/mozilla/pjs.git
bug 380786 - clean up xpfe/ after suite moving to toolkit, cvs remove filepicker frontend, r=Neil (after verifying that all fixes have been ported to toolkit)
This commit is contained in:
Родитель
bcd37ee20a
Коммит
2f544543b6
|
@ -1,852 +0,0 @@
|
|||
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2000
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Stuart Parmenter <pavlov@netscape.com>
|
||||
* Brian Ryner <bryner@brianryner.com>
|
||||
* Jan Varga <varga@ku.sk>
|
||||
* Peter Annema <disttsc@bart.nl>
|
||||
* Johann Petrak <johann@ai.univie.ac.at>
|
||||
* Akkana Peck <akkana@netscape.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
const nsIFilePicker = Components.interfaces.nsIFilePicker;
|
||||
const nsIProperties = Components.interfaces.nsIProperties;
|
||||
const NS_DIRECTORYSERVICE_CONTRACTID = "@mozilla.org/file/directory_service;1";
|
||||
const nsITreeBoxObject = Components.interfaces.nsITreeBoxObject;
|
||||
const nsIFileView = Components.interfaces.nsIFileView;
|
||||
const NS_FILEVIEW_CONTRACTID = "@mozilla.org/filepicker/fileview;1";
|
||||
const nsITreeView = Components.interfaces.nsITreeView;
|
||||
const nsILocalFile = Components.interfaces.nsILocalFile;
|
||||
const nsIFile = Components.interfaces.nsIFile;
|
||||
const NS_LOCAL_FILE_CONTRACTID = "@mozilla.org/file/local;1";
|
||||
const NS_PROMPTSERVICE_CONTRACTID = "@mozilla.org/embedcomp/prompt-service;1";
|
||||
|
||||
var sfile = Components.classes[NS_LOCAL_FILE_CONTRACTID].createInstance(nsILocalFile);
|
||||
var retvals;
|
||||
var filePickerMode;
|
||||
var homeDir;
|
||||
var treeView;
|
||||
|
||||
var textInput;
|
||||
var okButton;
|
||||
|
||||
var gFilePickerBundle;
|
||||
|
||||
// name of new directory entered by the user to be remembered
|
||||
// for next call of newDir() in case something goes wrong with creation
|
||||
var gNewDirName = { value: "" };
|
||||
|
||||
function filepickerLoad() {
|
||||
gFilePickerBundle = document.getElementById("bundle_filepicker");
|
||||
|
||||
textInput = document.getElementById("textInput");
|
||||
okButton = document.documentElement.getButton("accept");
|
||||
treeView = Components.classes[NS_FILEVIEW_CONTRACTID].createInstance(nsIFileView);
|
||||
|
||||
if (window.arguments) {
|
||||
var o = window.arguments[0];
|
||||
retvals = o.retvals; /* set this to a global var so we can set return values */
|
||||
const title = o.title;
|
||||
filePickerMode = o.mode;
|
||||
if (o.displayDirectory) {
|
||||
const directory = o.displayDirectory.path;
|
||||
}
|
||||
const initialText = o.defaultString;
|
||||
const filterTitles = o.filters.titles;
|
||||
const filterTypes = o.filters.types;
|
||||
const numFilters = filterTitles.length;
|
||||
|
||||
document.title = title;
|
||||
|
||||
if (initialText) {
|
||||
textInput.value = initialText;
|
||||
}
|
||||
}
|
||||
|
||||
if (filePickerMode != nsIFilePicker.modeOpen && filePickerMode != nsIFilePicker.modeOpenMultiple) {
|
||||
var newDirButton = document.getElementById("newDirButton");
|
||||
newDirButton.removeAttribute("hidden");
|
||||
}
|
||||
|
||||
if (filePickerMode == nsIFilePicker.modeGetFolder) {
|
||||
var textInputLabel = document.getElementById("textInputLabel");
|
||||
textInputLabel.value = gFilePickerBundle.getString("dirTextInputLabel");
|
||||
textInputLabel.accessKey = gFilePickerBundle.getString("dirTextInputAccesskey");
|
||||
}
|
||||
|
||||
if ((filePickerMode == nsIFilePicker.modeOpen) ||
|
||||
(filePickerMode == nsIFilePicker.modeOpenMultiple) ||
|
||||
(filePickerMode == nsIFilePicker.modeSave)) {
|
||||
|
||||
/* build filter popup */
|
||||
var filterPopup = document.createElement("menupopup");
|
||||
|
||||
for (var i = 0; i < numFilters; i++) {
|
||||
var menuItem = document.createElement("menuitem");
|
||||
if (filterTypes[i] == "..apps")
|
||||
menuItem.setAttribute("label", filterTitles[i]);
|
||||
else
|
||||
menuItem.setAttribute("label", filterTitles[i] + " (" + filterTypes[i] + ")");
|
||||
menuItem.setAttribute("filters", filterTypes[i]);
|
||||
filterPopup.appendChild(menuItem);
|
||||
}
|
||||
|
||||
var filterMenuList = document.getElementById("filterMenuList");
|
||||
filterMenuList.appendChild(filterPopup);
|
||||
if (numFilters > 0)
|
||||
filterMenuList.selectedIndex = 0;
|
||||
var filterBox = document.getElementById("filterBox");
|
||||
filterBox.removeAttribute("hidden");
|
||||
|
||||
filterMenuList.selectedIndex = o.filterIndex;
|
||||
|
||||
treeView.setFilter(filterTypes[o.filterIndex]);
|
||||
|
||||
} else if (filePickerMode == nsIFilePicker.modeGetFolder) {
|
||||
treeView.showOnlyDirectories = true;
|
||||
}
|
||||
|
||||
// start out with a filename sort
|
||||
handleColumnClick("FilenameColumn");
|
||||
|
||||
try {
|
||||
var buttonLabel = getOKAction();
|
||||
okButton.setAttribute("label", buttonLabel);
|
||||
} catch (exception) {
|
||||
// keep it set to "OK"
|
||||
}
|
||||
|
||||
// setup the dialogOverlay.xul button handlers
|
||||
retvals.buttonStatus = nsIFilePicker.returnCancel;
|
||||
|
||||
var tree = document.getElementById("directoryTree");
|
||||
if (filePickerMode == nsIFilePicker.modeOpenMultiple)
|
||||
tree.removeAttribute("seltype");
|
||||
|
||||
tree.treeBoxObject.view = treeView;
|
||||
|
||||
// Start out with the ok button disabled since nothing will be
|
||||
// selected and nothing will be in the text field.
|
||||
okButton.disabled = filePickerMode != nsIFilePicker.modeGetFolder;
|
||||
|
||||
// This allows the window to show onscreen before we begin
|
||||
// loading the file list
|
||||
|
||||
setTimeout(setInitialDirectory, 0, directory);
|
||||
}
|
||||
|
||||
function setInitialDirectory(directory)
|
||||
{
|
||||
// Start in the user's home directory
|
||||
var dirService = Components.classes[NS_DIRECTORYSERVICE_CONTRACTID]
|
||||
.getService(nsIProperties);
|
||||
homeDir = dirService.get("Home", Components.interfaces.nsIFile);
|
||||
|
||||
if (directory) {
|
||||
sfile.initWithPath(directory);
|
||||
if (!sfile.exists() || !sfile.isDirectory())
|
||||
directory = false;
|
||||
}
|
||||
if (!directory) {
|
||||
sfile.initWithPath(homeDir.path);
|
||||
}
|
||||
|
||||
gotoDirectory(sfile);
|
||||
}
|
||||
|
||||
function onFilterChanged(target)
|
||||
{
|
||||
// Do this on a timeout callback so the filter list can roll up
|
||||
// and we don't keep the mouse grabbed while we are refiltering.
|
||||
|
||||
setTimeout(changeFilter, 0, target.getAttribute("filters"));
|
||||
}
|
||||
|
||||
function changeFilter(filterTypes)
|
||||
{
|
||||
window.setCursor("wait");
|
||||
treeView.setFilter(filterTypes);
|
||||
window.setCursor("auto");
|
||||
}
|
||||
|
||||
function showErrorDialog(titleStrName, messageStrName, file)
|
||||
{
|
||||
var errorTitle =
|
||||
gFilePickerBundle.getFormattedString(titleStrName, [file.path]);
|
||||
var errorMessage =
|
||||
gFilePickerBundle.getFormattedString(messageStrName, [file.path]);
|
||||
var promptService =
|
||||
Components.classes[NS_PROMPTSERVICE_CONTRACTID].getService(Components.interfaces.nsIPromptService);
|
||||
|
||||
promptService.alert(window, errorTitle, errorMessage);
|
||||
}
|
||||
|
||||
function openOnOK()
|
||||
{
|
||||
var dir = treeView.selectedFiles.queryElementAt(0, nsIFile);
|
||||
if (dir)
|
||||
gotoDirectory(dir);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function selectOnOK()
|
||||
{
|
||||
var errorTitle, errorMessage, promptService;
|
||||
var ret = nsIFilePicker.returnOK;
|
||||
|
||||
var isDir = false;
|
||||
var isFile = false;
|
||||
|
||||
var fileList = processPath(textInput.value);
|
||||
|
||||
if (!fileList) { // generic error message, should probably never happen
|
||||
showErrorDialog("errorPathProblemTitle",
|
||||
"errorPathProblemMessage",
|
||||
textInput.value);
|
||||
return false;
|
||||
}
|
||||
|
||||
var curFileIndex;
|
||||
for (curFileIndex = 0; curFileIndex < fileList.length &&
|
||||
ret != nsIFilePicker.returnCancel; ++curFileIndex) {
|
||||
var file = fileList[curFileIndex].QueryInterface(nsIFile);
|
||||
|
||||
// try to normalize - if this fails we will ignore the error
|
||||
// because we will notice the
|
||||
// error later and show a fitting error alert.
|
||||
try{
|
||||
file.normalize();
|
||||
} catch(e) {
|
||||
//promptService.alert(window, "Problem", "normalize failed, continuing");
|
||||
}
|
||||
|
||||
var fileExists = file.exists();
|
||||
|
||||
if (!fileExists && (filePickerMode == nsIFilePicker.modeOpen ||
|
||||
filePickerMode == nsIFilePicker.modeOpenMultiple)) {
|
||||
showErrorDialog("errorOpenFileDoesntExistTitle",
|
||||
"errorOpenFileDoesntExistMessage",
|
||||
file);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!fileExists && filePickerMode == nsIFilePicker.modeGetFolder) {
|
||||
showErrorDialog("errorDirDoesntExistTitle",
|
||||
"errorDirDoesntExistMessage",
|
||||
file);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (fileExists) {
|
||||
isDir = file.isDirectory();
|
||||
isFile = file.isFile();
|
||||
}
|
||||
|
||||
switch(filePickerMode) {
|
||||
case nsIFilePicker.modeOpen:
|
||||
case nsIFilePicker.modeOpenMultiple:
|
||||
if (isFile) {
|
||||
if (file.isReadable()) {
|
||||
retvals.directory = file.parent.path;
|
||||
} else {
|
||||
showErrorDialog("errorOpeningFileTitle",
|
||||
"openWithoutPermissionMessage_file",
|
||||
file);
|
||||
ret = nsIFilePicker.returnCancel;
|
||||
}
|
||||
} else if (isDir) {
|
||||
if (!sfile.equals(file)) {
|
||||
gotoDirectory(file);
|
||||
}
|
||||
textInput.value = "";
|
||||
doEnabling();
|
||||
ret = nsIFilePicker.returnCancel;
|
||||
}
|
||||
break;
|
||||
case nsIFilePicker.modeSave:
|
||||
if (isFile) { // can only be true if file.exists()
|
||||
if (!file.isWritable()) {
|
||||
showErrorDialog("errorSavingFileTitle",
|
||||
"saveWithoutPermissionMessage_file",
|
||||
file);
|
||||
ret = nsIFilePicker.returnCancel;
|
||||
} else {
|
||||
// we need to pop up a dialog asking if you want to save
|
||||
var confirmTitle = gFilePickerBundle.getString("confirmTitle");
|
||||
var message =
|
||||
gFilePickerBundle.getFormattedString("confirmFileReplacing",
|
||||
[file.path]);
|
||||
|
||||
promptService = Components.classes[NS_PROMPTSERVICE_CONTRACTID].getService(Components.interfaces.nsIPromptService);
|
||||
var rv = promptService.confirm(window, confirmTitle, message);
|
||||
if (rv) {
|
||||
ret = nsIFilePicker.returnReplace;
|
||||
retvals.directory = file.parent.path;
|
||||
} else {
|
||||
ret = nsIFilePicker.returnCancel;
|
||||
}
|
||||
}
|
||||
} else if (isDir) {
|
||||
if (!sfile.equals(file)) {
|
||||
gotoDirectory(file);
|
||||
}
|
||||
textInput.value = "";
|
||||
doEnabling();
|
||||
ret = nsIFilePicker.returnCancel;
|
||||
} else {
|
||||
var parent = file.parent;
|
||||
if (parent.exists() && parent.isDirectory() && parent.isWritable()) {
|
||||
retvals.directory = parent.path;
|
||||
} else {
|
||||
var oldParent = parent;
|
||||
while (!parent.exists()) {
|
||||
oldParent = parent;
|
||||
parent = parent.parent;
|
||||
}
|
||||
errorTitle =
|
||||
gFilePickerBundle.getFormattedString("errorSavingFileTitle",
|
||||
[file.path]);
|
||||
if (parent.isFile()) {
|
||||
errorMessage =
|
||||
gFilePickerBundle.getFormattedString("saveParentIsFileMessage",
|
||||
[parent.path, file.path]);
|
||||
} else {
|
||||
errorMessage =
|
||||
gFilePickerBundle.getFormattedString("saveParentDoesntExistMessage",
|
||||
[oldParent.path, file.path]);
|
||||
}
|
||||
if (!parent.isWritable()) {
|
||||
errorMessage =
|
||||
gFilePickerBundle.getFormattedString("saveWithoutPermissionMessage_dir", [parent.path]);
|
||||
}
|
||||
promptService = Components.classes[NS_PROMPTSERVICE_CONTRACTID].getService(Components.interfaces.nsIPromptService);
|
||||
promptService.alert(window, errorTitle, errorMessage);
|
||||
ret = nsIFilePicker.returnCancel;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case nsIFilePicker.modeGetFolder:
|
||||
if (isDir) {
|
||||
retvals.directory = file.parent.path;
|
||||
} else { // if nothing selected, the current directory will be fine
|
||||
retvals.directory = sfile.path;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
gFilesEnumerator.mFiles = fileList;
|
||||
|
||||
retvals.files = gFilesEnumerator;
|
||||
retvals.buttonStatus = ret;
|
||||
|
||||
var filterMenuList = document.getElementById("filterMenuList");
|
||||
retvals.filterIndex = filterMenuList.selectedIndex;
|
||||
|
||||
return (ret != nsIFilePicker.returnCancel);
|
||||
}
|
||||
|
||||
var gFilesEnumerator = {
|
||||
mFiles: null,
|
||||
mIndex: 0,
|
||||
|
||||
hasMoreElements: function()
|
||||
{
|
||||
return (this.mIndex < this.mFiles.length);
|
||||
},
|
||||
getNext: function()
|
||||
{
|
||||
if (this.mIndex >= this.mFiles.length)
|
||||
throw Components.results.NS_ERROR_FAILURE;
|
||||
return this.mFiles[this.mIndex++];
|
||||
}
|
||||
};
|
||||
|
||||
function onCancel()
|
||||
{
|
||||
// Close the window.
|
||||
retvals.buttonStatus = nsIFilePicker.returnCancel;
|
||||
retvals.file = null;
|
||||
retvals.files = null;
|
||||
return true;
|
||||
}
|
||||
|
||||
function onDblClick(e) {
|
||||
// we only care about button 0 (left click) events
|
||||
if (e.button != 0) return;
|
||||
|
||||
var t = e.originalTarget;
|
||||
if (t.localName != "treechildren")
|
||||
return;
|
||||
|
||||
openSelectedFile();
|
||||
}
|
||||
|
||||
function openSelectedFile() {
|
||||
var fileList = treeView.selectedFiles;
|
||||
if (fileList.length == 0)
|
||||
return;
|
||||
|
||||
var file = fileList.queryElementAt(0, nsIFile);
|
||||
if (file.isDirectory())
|
||||
gotoDirectory(file);
|
||||
else if (file.isFile())
|
||||
document.documentElement.acceptDialog();
|
||||
}
|
||||
|
||||
function onClick(e) {
|
||||
var t = e.originalTarget;
|
||||
if (t.localName == "treecol")
|
||||
handleColumnClick(t.id);
|
||||
}
|
||||
|
||||
function convertColumnIDtoSortType(columnID) {
|
||||
var sortKey;
|
||||
|
||||
switch (columnID) {
|
||||
case "FilenameColumn":
|
||||
sortKey = nsIFileView.sortName;
|
||||
break;
|
||||
case "FileSizeColumn":
|
||||
sortKey = nsIFileView.sortSize;
|
||||
break;
|
||||
case "LastModifiedColumn":
|
||||
sortKey = nsIFileView.sortDate;
|
||||
break;
|
||||
default:
|
||||
dump("unsupported sort column: " + columnID + "\n");
|
||||
sortKey = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
return sortKey;
|
||||
}
|
||||
|
||||
function handleColumnClick(columnID) {
|
||||
var sortType = convertColumnIDtoSortType(columnID);
|
||||
var sortOrder = (treeView.sortType == sortType) ? !treeView.reverseSort : false;
|
||||
treeView.sort(sortType, sortOrder);
|
||||
|
||||
// set the sort indicator on the column we are sorted by
|
||||
var sortedColumn = document.getElementById(columnID);
|
||||
if (treeView.reverseSort) {
|
||||
sortedColumn.setAttribute("sortDirection", "descending");
|
||||
} else {
|
||||
sortedColumn.setAttribute("sortDirection", "ascending");
|
||||
}
|
||||
|
||||
// remove the sort indicator from the rest of the columns
|
||||
var currCol = sortedColumn.parentNode.firstChild;
|
||||
while (currCol) {
|
||||
if (currCol != sortedColumn && currCol.localName == "treecol")
|
||||
currCol.removeAttribute("sortDirection");
|
||||
currCol = currCol.nextSibling;
|
||||
}
|
||||
}
|
||||
|
||||
function onKeypress(e) {
|
||||
if (e.keyCode == 8) /* backspace */
|
||||
goUp();
|
||||
|
||||
/* enter is handled by the ondialogaccept handler */
|
||||
}
|
||||
|
||||
function doEnabling() {
|
||||
if (filePickerMode != nsIFilePicker.modeGetFolder)
|
||||
// Maybe add check if textInput.value would resolve to an existing
|
||||
// file or directory in .modeOpen. Too costly I think.
|
||||
okButton.disabled = (textInput.value == "")
|
||||
}
|
||||
|
||||
function onTreeFocus(event) {
|
||||
// Reset the button label and enabled/disabled state.
|
||||
onFileSelected(treeView.selectedFiles);
|
||||
}
|
||||
|
||||
function getOKAction(file) {
|
||||
var buttonLabel;
|
||||
|
||||
if (file && file.isDirectory()) {
|
||||
document.documentElement.setAttribute("ondialogaccept", "return openOnOK();");
|
||||
buttonLabel = gFilePickerBundle.getString("openButtonLabel");
|
||||
}
|
||||
else {
|
||||
document.documentElement.setAttribute("ondialogaccept", "return selectOnOK();");
|
||||
switch(filePickerMode) {
|
||||
case nsIFilePicker.modeGetFolder:
|
||||
buttonLabel = gFilePickerBundle.getString("selectFolderButtonLabel");
|
||||
break;
|
||||
case nsIFilePicker.modeOpen:
|
||||
case nsIFilePicker.modeOpenMultiple:
|
||||
buttonLabel = gFilePickerBundle.getString("openButtonLabel");
|
||||
break;
|
||||
case nsIFilePicker.modeSave:
|
||||
buttonLabel = gFilePickerBundle.getString("saveButtonLabel");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return buttonLabel;
|
||||
}
|
||||
|
||||
function onSelect(event) {
|
||||
onFileSelected(treeView.selectedFiles);
|
||||
}
|
||||
|
||||
function onFileSelected(/* nsIArray */ selectedFileList) {
|
||||
var validFileSelected = false;
|
||||
var invalidSelection = false;
|
||||
var file;
|
||||
var fileCount = selectedFileList.length;
|
||||
|
||||
for (var index = 0; index < fileCount; ++index) {
|
||||
file = selectedFileList.queryElementAt(index, nsIFile);
|
||||
if (file) {
|
||||
var path = file.leafName;
|
||||
|
||||
if (path) {
|
||||
var isDir = file.isDirectory();
|
||||
if ((filePickerMode == nsIFilePicker.modeGetFolder) || !isDir) {
|
||||
if (!validFileSelected)
|
||||
textInput.value = "";
|
||||
addToTextFieldValue(path);
|
||||
}
|
||||
|
||||
if (isDir && fileCount > 1) {
|
||||
// The user has selected multiple items, and one of them is
|
||||
// a directory. This is not a valid state, so we'll disable
|
||||
// the ok button.
|
||||
invalidSelection = true;
|
||||
}
|
||||
|
||||
validFileSelected = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (validFileSelected) {
|
||||
var buttonLabel = getOKAction(file);
|
||||
okButton.setAttribute("label", buttonLabel);
|
||||
okButton.disabled = invalidSelection;
|
||||
} else if (filePickerMode != nsIFilePicker.modeGetFolder)
|
||||
okButton.disabled = (textInput.value == "");
|
||||
}
|
||||
|
||||
function addToTextFieldValue(path)
|
||||
{
|
||||
var newValue = "";
|
||||
|
||||
if (textInput.value == "")
|
||||
newValue = path.replace(/\"/g, "\\\"");
|
||||
else {
|
||||
// Quote the existing text if needed,
|
||||
// then append the new filename (quoted and escaped)
|
||||
if (textInput.value[0] != '"')
|
||||
newValue = '"' + textInput.value.replace(/\"/g, "\\\"") + '"';
|
||||
else
|
||||
newValue = textInput.value;
|
||||
|
||||
newValue = newValue + ' "' + path.replace(/\"/g, "\\\"") + '"';
|
||||
}
|
||||
|
||||
textInput.value = newValue;
|
||||
}
|
||||
|
||||
function onTextFieldFocus() {
|
||||
var buttonLabel = getOKAction(null);
|
||||
okButton.setAttribute("label", buttonLabel);
|
||||
doEnabling();
|
||||
}
|
||||
|
||||
function onDirectoryChanged(target)
|
||||
{
|
||||
var path = target.getAttribute("label");
|
||||
|
||||
var file = Components.classes[NS_LOCAL_FILE_CONTRACTID].createInstance(nsILocalFile);
|
||||
file.initWithPath(path);
|
||||
|
||||
if (!sfile.equals(file)) {
|
||||
// Do this on a timeout callback so the directory list can roll up
|
||||
// and we don't keep the mouse grabbed while we are loading.
|
||||
|
||||
setTimeout(gotoDirectory, 0, file);
|
||||
}
|
||||
}
|
||||
|
||||
function populateAncestorList(directory) {
|
||||
var menu = document.getElementById("lookInMenu");
|
||||
|
||||
while (menu.hasChildNodes()) {
|
||||
menu.removeChild(menu.firstChild);
|
||||
}
|
||||
|
||||
var menuItem = document.createElement("menuitem");
|
||||
menuItem.setAttribute("label", directory.path);
|
||||
menuItem.setAttribute("crop", "start");
|
||||
menu.appendChild(menuItem);
|
||||
|
||||
// .parent is _sometimes_ null, see bug 121489. Do a dance around that.
|
||||
var parent = directory.parent;
|
||||
while (parent && !parent.equals(directory)) {
|
||||
menuItem = document.createElement("menuitem");
|
||||
menuItem.setAttribute("label", parent.path);
|
||||
menuItem.setAttribute("crop", "start");
|
||||
menu.appendChild(menuItem);
|
||||
directory = parent;
|
||||
parent = directory.parent;
|
||||
}
|
||||
|
||||
var menuList = document.getElementById("lookInMenuList");
|
||||
menuList.selectedIndex = 0;
|
||||
}
|
||||
|
||||
function goUp() {
|
||||
try {
|
||||
var parent = sfile.parent;
|
||||
} catch(ex) { dump("can't get parent directory\n"); }
|
||||
|
||||
if (parent) {
|
||||
gotoDirectory(parent);
|
||||
}
|
||||
}
|
||||
|
||||
function goHome() {
|
||||
gotoDirectory(homeDir);
|
||||
}
|
||||
|
||||
function newDir() {
|
||||
var file;
|
||||
var promptService =
|
||||
Components.classes[NS_PROMPTSERVICE_CONTRACTID].getService(Components.interfaces.nsIPromptService);
|
||||
var dialogTitle =
|
||||
gFilePickerBundle.getString("promptNewDirTitle");
|
||||
var dialogMsg =
|
||||
gFilePickerBundle.getString("promptNewDirMessage");
|
||||
var ret = promptService.prompt(window, dialogTitle, dialogMsg, gNewDirName, null, {value:0});
|
||||
|
||||
if (ret) {
|
||||
file = processPath(gNewDirName.value);
|
||||
if (!file) {
|
||||
showErrorDialog("errorCreateNewDirTitle",
|
||||
"errorCreateNewDirMessage",
|
||||
file);
|
||||
return false;
|
||||
}
|
||||
|
||||
file = file[0].QueryInterface(nsIFile);
|
||||
if (file.exists()) {
|
||||
showErrorDialog("errorNewDirDoesExistTitle",
|
||||
"errorNewDirDoesExistMessage",
|
||||
file);
|
||||
return false;
|
||||
}
|
||||
|
||||
var parent = file.parent;
|
||||
if (!(parent.exists() && parent.isDirectory() && parent.isWritable())) {
|
||||
var oldParent = parent;
|
||||
while (!parent.exists()) {
|
||||
oldParent = parent;
|
||||
parent = parent.parent;
|
||||
}
|
||||
if (parent.isFile()) {
|
||||
showErrorDialog("errorCreateNewDirTitle",
|
||||
"errorCreateNewDirIsFileMessage",
|
||||
parent);
|
||||
return false;
|
||||
}
|
||||
if (!parent.isWritable()) {
|
||||
showErrorDialog("errorCreateNewDirTitle",
|
||||
"errorCreateNewDirPermissionMessage",
|
||||
parent);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
file.create(nsIFile.DIRECTORY_TYPE, 0755);
|
||||
} catch (e) {
|
||||
showErrorDialog("errorCreateNewDirTitle",
|
||||
"errorCreateNewDirMessage",
|
||||
file);
|
||||
return false;
|
||||
}
|
||||
file.normalize(); // ... in case ".." was used in the path
|
||||
gotoDirectory(file);
|
||||
// we remember and reshow a dirname if something goes wrong
|
||||
// so that errors can be corrected more easily. If all went well,
|
||||
// reset the default value to blank
|
||||
gNewDirName = { value: "" };
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function gotoDirectory(directory) {
|
||||
window.setCursor("wait");
|
||||
try {
|
||||
populateAncestorList(directory);
|
||||
treeView.setDirectory(directory);
|
||||
document.getElementById("errorShower").selectedIndex = 0;
|
||||
} catch(ex) {
|
||||
document.getElementById("errorShower").selectedIndex = 1;
|
||||
}
|
||||
|
||||
window.setCursor("auto");
|
||||
|
||||
if (filePickerMode == nsIFilePicker.modeGetFolder) {
|
||||
textInput.value = "";
|
||||
}
|
||||
textInput.focus();
|
||||
textInput.setAttribute("autocompletesearchparam", directory.path);
|
||||
sfile = directory;
|
||||
}
|
||||
|
||||
function toggleShowHidden(event) {
|
||||
treeView.showHiddenFiles = !treeView.showHiddenFiles;
|
||||
}
|
||||
|
||||
// from the current directory and whatever was entered
|
||||
// in the entry field, try to make a new path. This
|
||||
// uses "/" as the directory separator, "~" as a shortcut
|
||||
// for the home directory (but only when seen at the start
|
||||
// of a path), and ".." to denote the parent directory.
|
||||
// returns an array of the files listed,
|
||||
// or false if an error occurred.
|
||||
function processPath(path)
|
||||
{
|
||||
var fileArray = new Array();
|
||||
var strLength = path.length;
|
||||
|
||||
if (path[0] == '"' && filePickerMode == nsIFilePicker.modeOpenMultiple &&
|
||||
strLength > 1) {
|
||||
// we have a quoted list of filenames, separated by spaces.
|
||||
// iterate the list and process each file.
|
||||
|
||||
var curFileStart = 1;
|
||||
|
||||
while (1) {
|
||||
var nextQuote;
|
||||
|
||||
// Look for an unescaped quote
|
||||
var quoteSearchStart = curFileStart + 1;
|
||||
do {
|
||||
nextQuote = path.indexOf('"', quoteSearchStart);
|
||||
quoteSearchStart = nextQuote + 1;
|
||||
} while (nextQuote != -1 && path[nextQuote - 1] == '\\');
|
||||
|
||||
if (nextQuote == -1) {
|
||||
// we have a filename with no trailing quote.
|
||||
// just assume that the filename ends at the end of the string.
|
||||
|
||||
if (!processPathEntry(path.substring(curFileStart), fileArray))
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!processPathEntry(path.substring(curFileStart, nextQuote), fileArray))
|
||||
return false;
|
||||
|
||||
curFileStart = path.indexOf('"', nextQuote + 1);
|
||||
if (curFileStart == -1) {
|
||||
// no more quotes, but if we're not at the end of the string,
|
||||
// go ahead and process the remaining text.
|
||||
|
||||
if (nextQuote < strLength - 1)
|
||||
if (!processPathEntry(path.substring(nextQuote + 1), fileArray))
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
++curFileStart;
|
||||
}
|
||||
} else {
|
||||
// If we didn't start with a quote, assume we just have a single file.
|
||||
if (!processPathEntry(path, fileArray))
|
||||
return false;
|
||||
}
|
||||
|
||||
return fileArray;
|
||||
}
|
||||
|
||||
function processPathEntry(path, fileArray)
|
||||
{
|
||||
var filePath;
|
||||
var file;
|
||||
|
||||
try {
|
||||
file = sfile.clone().QueryInterface(nsILocalFile);
|
||||
} catch(e) {
|
||||
dump("Couldn't clone\n"+e);
|
||||
return false;
|
||||
}
|
||||
|
||||
var tilde_file = file.clone();
|
||||
tilde_file.append("~");
|
||||
if (path[0] == '~' && // Expand ~ to $HOME, except:
|
||||
!(path == "~" && tilde_file.exists()) && // If ~ was entered and such a file exists, don't expand
|
||||
(path.length == 1 || path[1] == "/")) // We don't want to expand ~file to ${HOME}file
|
||||
filePath = homeDir.path + path.substring(1);
|
||||
else
|
||||
filePath = path;
|
||||
|
||||
// Unescape quotes
|
||||
filePath = filePath.replace(/\\\"/g, "\"");
|
||||
|
||||
if (filePath[0] == '/') /* an absolute path was entered */
|
||||
file.initWithPath(filePath);
|
||||
else if ((filePath.indexOf("/../") > 0) ||
|
||||
(filePath.substr(-3) == "/..") ||
|
||||
(filePath.substr(0,3) == "../") ||
|
||||
(filePath == "..")) {
|
||||
/* appendRelativePath doesn't allow .. */
|
||||
try{
|
||||
file.initWithPath(file.path + "/" + filePath);
|
||||
} catch (e) {
|
||||
dump("Couldn't init path\n"+e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
try {
|
||||
file.appendRelativePath(filePath);
|
||||
} catch (e) {
|
||||
dump("Couldn't append path\n"+e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
fileArray[fileArray.length] = file;
|
||||
return true;
|
||||
}
|
|
@ -1,120 +0,0 @@
|
|||
<?xml version="1.0"?> <!-- -*- Mode: HTML -*- -->
|
||||
|
||||
<!-- ***** BEGIN LICENSE BLOCK *****
|
||||
- Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
-
|
||||
- The contents of this file are subject to the Mozilla Public License Version
|
||||
- 1.1 (the "License"); you may not use this file except in compliance with
|
||||
- the License. You may obtain a copy of the License at
|
||||
- http://www.mozilla.org/MPL/
|
||||
-
|
||||
- Software distributed under the License is distributed on an "AS IS" basis,
|
||||
- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
- for the specific language governing rights and limitations under the
|
||||
- License.
|
||||
-
|
||||
- The Original Code is mozilla.org code.
|
||||
-
|
||||
- The Initial Developer of the Original Code is
|
||||
- Netscape Communications Corporation.
|
||||
- Portions created by the Initial Developer are Copyright (C) 2000
|
||||
- the Initial Developer. All Rights Reserved.
|
||||
-
|
||||
- Contributor(s):
|
||||
- Stuart Parmenter <pavlov@netscape.com>
|
||||
- Brian Ryner <bryner@brianryner.com>
|
||||
- Jan Varga <varga@ku.sk>
|
||||
- Peter Annema <disttsc@bart.nl>
|
||||
- Johann Petrak <johann@ai.univie.ac.at>
|
||||
-
|
||||
- Alternatively, the contents of this file may be used under the terms of
|
||||
- either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
- or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
- in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
- of those above. If you wish to allow use of your version of this file only
|
||||
- under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
- use your version of this file under the terms of the MPL, indicate your
|
||||
- decision by deleting the provisions above and replace them with the notice
|
||||
- and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
- the provisions above, a recipient may use your version of this file under
|
||||
- the terms of any one of the MPL, the GPL or the LGPL.
|
||||
-
|
||||
- ***** END LICENSE BLOCK ***** -->
|
||||
|
||||
<?xml-stylesheet href="chrome://global/skin/filepicker.css" type="text/css"?>
|
||||
|
||||
<!DOCTYPE dialog SYSTEM "chrome://global/locale/filepicker.dtd" >
|
||||
|
||||
<dialog id="main-window"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:nc="http://home.netscape.com/NC-rdf#"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
onload="filepickerLoad();"
|
||||
width="426" height="300"
|
||||
ondialogaccept="return selectOnOK();"
|
||||
ondialogcancel="return onCancel();"
|
||||
persist="screenX screenY width height">
|
||||
|
||||
<stringbundle id="bundle_filepicker" src="chrome://global/locale/filepicker.properties"/>
|
||||
<script type="application/x-javascript" src="chrome://global/content/filepicker.js"/>
|
||||
|
||||
<hbox align="center">
|
||||
<label value="&lookInMenuList.label;" control="lookInMenuList" accesskey="&lookInMenuList.accesskey;"/>
|
||||
<menulist id="lookInMenuList" flex="1" oncommand="onDirectoryChanged(event.target);" crop="start">
|
||||
<menupopup id="lookInMenu"/>
|
||||
</menulist>
|
||||
<button id="folderUpButton" class="up-button" tooltiptext="&folderUp.tooltiptext;" oncommand="goUp();"/>
|
||||
<button id="homeButton" class="home-button" tooltiptext="&folderHome.tooltiptext;" oncommand="goHome();"/>
|
||||
<button id="newDirButton" hidden="true" class="new-dir-button" tooltiptext="&folderNew.tooltiptext;" oncommand="newDir();"/>
|
||||
</hbox>
|
||||
|
||||
<hbox flex="1">
|
||||
<deck id="errorShower" flex="1">
|
||||
<tree id="directoryTree" flex="1" class="focusring" seltype="single"
|
||||
onclick="onClick(event);"
|
||||
ondblclick="onDblClick(event);"
|
||||
onkeypress="onKeypress(event);"
|
||||
onfocus="onTreeFocus(event);"
|
||||
onselect="onSelect(event);">
|
||||
<treecols>
|
||||
<treecol id="FilenameColumn" label="&name.label;" flex="1"
|
||||
class="sortDirectionIndicator"/>
|
||||
<splitter class="tree-splitter"/>
|
||||
<treecol id="FileSizeColumn" label="&size.label;" flex="1"
|
||||
class="sortDirectionIndicator"/>
|
||||
<splitter class="tree-splitter"/>
|
||||
<treecol id="LastModifiedColumn" label="&lastModified.label;" flex="1"
|
||||
class="sortDirectionIndicator"/>
|
||||
</treecols>
|
||||
<treechildren/>
|
||||
</tree>
|
||||
<label>&noPermissionError.label;</label>
|
||||
</deck>
|
||||
</hbox>
|
||||
|
||||
<grid style="margin-top: 5px">
|
||||
<columns>
|
||||
<column/>
|
||||
<column flex="1"/>
|
||||
</columns>
|
||||
|
||||
<rows>
|
||||
<row align="center">
|
||||
<label value="&textInput.label;" id="textInputLabel" control="textInput" accesskey="&textInput.accesskey;"/>
|
||||
<textbox id="textInput" flex="1" oninput="doEnabling()"
|
||||
type="autocomplete" autocompletesearch="file"
|
||||
onfocus="onTextFieldFocus();"/>
|
||||
</row>
|
||||
<row id="filterBox" hidden="true" align="center">
|
||||
<label value="&filterMenuList.label;" control="filterMenuList" accesskey="&filterMenuList.accesskey;"/>
|
||||
<menulist id="filterMenuList" flex="1" oncommand="onFilterChanged(event.target);"/>
|
||||
</row>
|
||||
</rows>
|
||||
</grid>
|
||||
<hbox class="dialog-button-box" align="center">
|
||||
<checkbox label="&showHiddenFiles.label;" oncommand="toggleShowHidden();"
|
||||
flex="1" align="left" accesskey="&showHiddenFiles.accesskey;"/>
|
||||
<button dlgtype="accept" class="dialog-button"/>
|
||||
<button dlgtype="cancel" class="dialog-button"/>
|
||||
</hbox>
|
||||
</dialog>
|
|
@ -1,17 +0,0 @@
|
|||
<!ENTITY lookInMenuList.label "Look in:">
|
||||
<!ENTITY lookInMenuList.accesskey "L">
|
||||
<!ENTITY textInput.label "File name:">
|
||||
<!ENTITY textInput.accesskey "n">
|
||||
<!ENTITY filterMenuList.label "Files of type:">
|
||||
<!ENTITY filterMenuList.accesskey "t">
|
||||
<!ENTITY name.label "Name">
|
||||
<!ENTITY size.label "Size">
|
||||
<!ENTITY lastModified.label "Last Modified">
|
||||
<!ENTITY showHiddenFiles.label "Show hidden files and directories">
|
||||
<!ENTITY showHiddenFiles.accesskey "S">
|
||||
|
||||
<!ENTITY noPermissionError.label "You do not have the permissions necessary to view this directory.">
|
||||
|
||||
<!ENTITY folderUp.tooltiptext "Go up a level">
|
||||
<!ENTITY folderHome.tooltiptext "Go to home">
|
||||
<!ENTITY folderNew.tooltiptext "Create new directory">
|
|
@ -1,54 +0,0 @@
|
|||
# LOCALIZATION NOTE FILE
|
||||
# --do not localize the extensions, only the titles
|
||||
allTitle=All Files
|
||||
allFilter=*
|
||||
htmlTitle=HTML Files
|
||||
htmlFilter=*.html; *.htm; *.shtml; *.xhtml
|
||||
textTitle=Text Files
|
||||
textFilter=*.txt; *.text
|
||||
imageTitle=Image Files
|
||||
imageFilter=*.jpg; *.jpeg; *.gif; *.png; *.bmp; *.xbm; *.ico
|
||||
xmlTitle=XML Files
|
||||
xmlFilter=*.xml
|
||||
xulTitle=XUL Files
|
||||
xulFilter=*.xul
|
||||
appsTitle=Applications
|
||||
|
||||
dirTextInputLabel=Directory name:
|
||||
dirTextInputAccesskey=n
|
||||
|
||||
confirmTitle=Confirm
|
||||
confirmFileReplacing=%S already exists.\nDo you want to replace it?
|
||||
openButtonLabel=Open
|
||||
saveButtonLabel=Save
|
||||
selectFolderButtonLabel=Select
|
||||
noButtonLabel=No
|
||||
|
||||
errorOpenFileDoesntExistTitle=Error opening %S
|
||||
errorOpenFileDoesntExistMessage=File %S doesn't exist
|
||||
errorDirDoesntExistTitle=Error accessing %S
|
||||
errorDirDoesntExistMessage=Directory %S doesn't exist
|
||||
|
||||
errorOpeningFileTitle=Error opening %S
|
||||
openWithoutPermissionMessage_file=File %S is not readable
|
||||
|
||||
errorSavingFileTitle=Error saving %S
|
||||
saveParentIsFileMessage=%S is a file, can't save %S
|
||||
saveParentDoesntExistMessage=Path %S doesn't exist, can't save %S
|
||||
|
||||
saveWithoutPermissionMessage_file=File %S is not writable.
|
||||
saveWithoutPermissionMessage_dir=Cannot create file. Directory %S is not writable.
|
||||
|
||||
errorNewDirDoesExistTitle=Error creating %S
|
||||
errorNewDirDoesExistMessage=A file named %S already exists, directory cannot be created.
|
||||
|
||||
errorCreateNewDirTitle=Error creating %S
|
||||
errorCreateNewDirMessage=Directory %S could not be created
|
||||
errorCreateNewDirIsFileMessage=Directory cannot be created, %S is a file
|
||||
errorCreateNewDirPermissionMessage=Directory cannot be created, %S not writable
|
||||
|
||||
promptNewDirTitle=Create new directory
|
||||
promptNewDirMessage=Directory name:
|
||||
|
||||
errorPathProblemTitle=Unknown Error
|
||||
errorPathProblemMessage=An unknown error occured (path %S)
|
Загрузка…
Ссылка в новой задаче