mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-25 22:01:30 +00:00
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:
parent
64596972f0
commit
d606de2ade
BIN
themes/classic/global/filepicker/folder-new.gif
Normal file
BIN
themes/classic/global/filepicker/folder-new.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 487 B |
@ -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;
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
}
|
||||
|
BIN
themes/modern/global/filepicker/folder-new.gif
Normal file
BIN
themes/modern/global/filepicker/folder-new.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 586 B |
@ -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)
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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">
|
||||
|
@ -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">
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user