Add a "new directory" button to the XP filepicker. Bug 58311, patch by

johann@ai.univie.ac.at, r=bzbarsky, sr=jag
This commit is contained in:
bzbarsky%mit.edu 2002-05-15 20:19:12 +00:00
parent 64596972f0
commit d606de2ade
10 changed files with 182 additions and 42 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 487 B

View File

@ -69,3 +69,8 @@ treechildren:-moz-tree-image(FilenameColumn, file) {
list-style-image: url("chrome://global/skin/filepicker/folder-home.gif");
max-width: 36px;
}
.new-dir-button {
list-style-image: url("chrome://global/skin/filepicker/folder-new.gif");
max-width: 36px;
}

View File

@ -117,6 +117,7 @@ classic.jar:
skin/classic/global/filepicker/dir-open.gif (global/filepicker/dir-open.gif)
skin/classic/global/filepicker/folder-up.gif (global/filepicker/folder-up.gif)
skin/classic/global/filepicker/folder-home.gif (global/filepicker/folder-home.gif)
skin/classic/global/filepicker/folder-new.gif (global/filepicker/folder-new.gif)
skin/classic/global/arrow/arrow-dn-dis.gif (global/arrow/arrow-dn-dis.gif)
skin/classic/global/arrow/arrow-dn-hov.gif (global/arrow/arrow-dn-hov.gif)
skin/classic/global/arrow/arrow-dn-sharp.gif (global/arrow/arrow-dn-sharp.gif)

View File

@ -88,3 +88,8 @@ treechildren:-moz-tree-image(FilenameColumn, file) {
list-style-image: url("chrome://global/skin/filepicker/folder-home.gif");
max-width: 36px;
}
.new-dir-button {
list-style-image: url("chrome://global/skin/filepicker/folder-new.gif");
max-width: 36px;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 586 B

View File

@ -190,6 +190,7 @@ modern.jar:
skin/modern/global/filepicker/dir-open.gif (global/filepicker/dir-open.gif)
skin/modern/global/filepicker/folder-up.gif (global/filepicker/folder-up.gif)
skin/modern/global/filepicker/folder-home.gif (global/filepicker/folder-home.gif)
skin/modern/global/filepicker/folder-new.gif (global/filepicker/folder-new.gif)
skin/modern/global/icons/alert-error.gif (global/icons/alert-error.gif)
skin/modern/global/icons/alert-exclam.gif (global/icons/alert-exclam.gif)
skin/modern/global/icons/alert-message.gif (global/icons/alert-message.gif)

View File

@ -22,6 +22,7 @@
* Brian Ryner <bryner@netscape.com>
* Jan Varga <varga@utcru.sk>
* Peter Annema <disttsc@bart.nl>
* Johann Petrak <johann@ai.univie.ac.at>
*/
const nsIFilePicker = Components.interfaces.nsIFilePicker;
@ -33,6 +34,7 @@ const nsFileView_CONTRACTID = "@mozilla.org/filepicker/fileview;1";
const nsITreeView = Components.interfaces.nsITreeView;
const nsILocalFile = Components.interfaces.nsILocalFile;
const nsLocalFile_CONTRACTID = "@mozilla.org/file/local;1";
const nsIPromptService_CONTRACTID = "@mozilla.org/embedcomp/prompt-service;1";
var sfile = Components.classes[nsLocalFile_CONTRACTID].createInstance(nsILocalFile);
var retvals;
@ -45,6 +47,10 @@ 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");
@ -72,6 +78,11 @@ function filepickerLoad() {
}
}
if (filePickerMode != nsIFilePicker.modeOpen) {
var newDirButton = document.getElementById("newDirButton");
newDirButton.removeAttribute("hidden");
}
if ((filePickerMode == nsIFilePicker.modeOpen) ||
(filePickerMode == nsIFilePicker.modeSave)) {
@ -161,25 +172,25 @@ function changeFilter(filterTypes)
window.setCursor("auto");
}
function showFilePermissionsErrorDialog(titleStrName, messageStrName, file)
function showErrorDialog(titleStrName, messageStrName, file)
{
var errorTitle =
gFilePickerBundle.getFormattedString(titleStrName, [file.path]);
var errorMessage =
gFilePickerBundle.getFormattedString(messageStrName, [file.path]);
var promptService =
Components.classes["@mozilla.org/embedcomp/prompt-service;1"].getService(Components.interfaces.nsIPromptService);
Components.classes[nsIPromptService_CONTRACTID].getService(Components.interfaces.nsIPromptService);
promptService.alert(window, errorTitle, errorMessage)
promptService.alert(window, errorTitle, errorMessage);
}
function openOnOK()
{
var dir = treeView.getSelectedFile();
if (!dir.isReadable()) {
showFilePermissionsErrorDialog("errorOpenFileDoesntExistTitle",
"errorDirNotReadableMessage",
dir);
showErrorDialog("errorOpenFileDoesntExistTitle",
"errorDirNotReadableMessage",
dir);
return false;
}
@ -202,38 +213,28 @@ function selectOnOK()
var isDir = false;
var isFile = false;
var input = textInput.value;
if (input[0] == '~') // XXX XP?
input = homeDir.path + input.substring(1);
var file = processPath(textInput.value);
var file = sfile.clone().QueryInterface(nsILocalFile);
if (!file)
if (!file) { // generic error message, should probably never happen
showErrorDialog("errorPathProblemTitle",
"errorPathProblemMessage",
textInput.value);
return false;
/* XXX we need an XP way to test for an absolute path! */
if (input[0] == '/') /* an absolute path was entered */
file.initWithPath(input);
else if ((input.indexOf("/../") > 0) ||
(input.substr(-3) == "/..") ||
(input.substr(0,3) == "../") ||
(input == "..")) {
/* appendRelativePath doesn't allow .. */
file.initWithPath(file.path + "/" + input);
file.normalize();
}
else {
try {
file.appendRelativePath(input);
} catch (e) {
dump("Can't append relative path '"+input+"':\n");
return false;
}
// 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");
}
if (!file.exists() && (filePickerMode != nsIFilePicker.modeSave)) {
showFilePermissionsErrorDialog("errorOpenFileDoesntExistTitle",
"errorOpenFileDoesntExistMessage",
file);
showErrorDialog("errorOpenFileDoesntExistTitle",
"errorOpenFileDoesntExistMessage",
file);
return false;
}
@ -249,9 +250,9 @@ function selectOnOK()
retvals.directory = file.parent.path;
ret = nsIFilePicker.returnOK;
} else {
showFilePermissionsErrorDialog("errorOpeningFileTitle",
"openWithoutPermissionMessage_file",
file);
showErrorDialog("errorOpeningFileTitle",
"openWithoutPermissionMessage_file",
file);
ret = nsIFilePicker.returnCancel;
}
} else if (isDir) {
@ -266,9 +267,9 @@ function selectOnOK()
case nsIFilePicker.modeSave:
if (isFile) { // can only be true if file.exists()
if (!file.isWritable()) {
showFilePermissionsErrorDialog("errorSavingFileTitle",
"saveWithoutPermissionMessage_file",
file);
showErrorDialog("errorSavingFileTitle",
"saveWithoutPermissionMessage_file",
file);
ret = nsIFilePicker.returnCancel;
} else {
// we need to pop up a dialog asking if you want to save
@ -318,8 +319,7 @@ function selectOnOK()
errorMessage =
gFilePickerBundle.getFormattedString("saveWithoutPermissionMessage_dir", [parent.path]);
}
promptService = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
.getService(Components.interfaces.nsIPromptService);
promptService = Components.classes[nsIPromptService_CONTRACTID].getService(Components.interfaces.nsIPromptService);
promptService.alert(window, errorTitle, errorMessage);
ret = nsIFilePicker.returnCancel;
}
@ -491,7 +491,6 @@ function onFileSelected(file) {
return;
}
}
okButton.disabled = (textInput.value == "");
}
@ -557,6 +556,71 @@ function goHome() {
gotoDirectory(homeDir);
}
function newDir() {
var file;
var promptService =
Components.classes[nsIPromptService_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;
}
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(Components.interfaces.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 {
@ -570,6 +634,9 @@ function gotoDirectory(directory) {
window.setCursor("auto");
treeView.QueryInterface(nsITreeView).selection.clearSelection();
if (filePickerMode == nsIFilePicker.modeGetFolder) {
textInput.value = "";
}
textInput.focus();
sfile = directory;
}
@ -577,3 +644,47 @@ function gotoDirectory(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 seperator, "~" as a shortcut
// for the home directory (but only when seen at the start
// of a path), and ".." to denote the parent directory.
// returns the path or false if an error occurred.
function processPath(path)
{
var file;
if (path[0] == '~')
path = homeDir.path + path.substring(1);
try{
file = sfile.clone().QueryInterface(nsILocalFile);
} catch(e) {
dump("Couldn't clone\n"+e);
return false;
}
if (path[0] == '/') /* an absolute path was entered */
file.initWithPath(path);
else if ((path.indexOf("/../") > 0) ||
(path.substr(-3) == "/..") ||
(path.substr(0,3) == "../") ||
(path == "..")) {
/* appendRelativePath doesn't allow .. */
try{
file.initWithPath(file.path + "/" + path);
} catch (e) {
dump("Couldn't init path\n"+e);
return false;
}
}
else {
try {
file.appendRelativePath(path);
} catch (e) {
dump("Couldn't append path\n"+e);
return false;
}
}
return file;
}

View File

@ -23,6 +23,7 @@
- Brian Ryner <bryner@netscape.com>
- Jan Varga <varga@utcru.sk>
- Peter Annema <disttsc@bart.nl>
- Johann Petrak <johann@ai.univie.ac.at>
-->
<?xml-stylesheet href="chrome://global/skin/filepicker.css" type="text/css"?>
@ -49,6 +50,7 @@
</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">

View File

@ -10,4 +10,5 @@
<!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 folderHome.tooltiptext "Go to home">
<!ENTITY folderNew.tooltiptext "Create new directory">

View File

@ -32,3 +32,17 @@ 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)