--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -1109,16 +1109,35 @@ function delayedStartup()
try {
ContentPrefSink.init();
TextZoom.init();
}
catch(ex) {
Components.utils.reportError("Failed to init content pref service:\n" + ex);
}
+#ifdef XP_WIN
+ // For Vista, flip the default download folder pref once from Desktop to Downloads
+ // on new profiles.
+ try {
+ var sysInfo = Cc["@mozilla.org/system-info;1"].
+ getService(Ci.nsIPropertyBag2);
+ if (parseFloat(sysInfo.getProperty("version")) >= 6 &&
+ !gPrefService.getPrefType("browser.download.dir") &&
+ gPrefService.getIntPref("browser.download.folderList") == 0) {
+ var dnldMgr = Cc["@mozilla.org/download-manager;1"]
+ .getService(Ci.nsIDownloadManager);
+ gPrefService.setCharPref("browser.download.dir",
+ dnldMgr.defaultDownloadsDirectory.path);
+ gPrefService.setIntPref("browser.download.folderList", 1);
+ }
+ } catch (ex) {
+ }
+#endif
+
// initialize the session-restore service (in case it's not already running)
if (document.documentElement.getAttribute("windowtype") == "navigator:browser") {
try {
var ss = Cc["@mozilla.org/browser/sessionstore;1"].
getService(Ci.nsISessionStore);
ss.init(window);
} catch(ex) {
dump("nsSessionStore could not be initialized: " + ex + "\n");
--- a/browser/components/migration/src/nsOperaProfileMigrator.cpp
+++ b/browser/components/migration/src/nsOperaProfileMigrator.cpp
@@ -309,17 +309,17 @@ nsOperaProfileMigrator::GetSourceHomePag
return NS_OK;
}
#define _OPM(type) nsOperaProfileMigrator::type
static
nsOperaProfileMigrator::PrefTransform gTransforms[] = {
- { "User Prefs", "Download Directory", _OPM(STRING), "browser.download.defaultFolder", _OPM(SetFile), PR_FALSE, -1 },
+ { "User Prefs", "Download Directory", _OPM(STRING), "browser.download.dir", _OPM(SetFile), PR_FALSE, -1 },
{ nsnull, "Enable Cookies", _OPM(INT), "network.cookie.cookieBehavior", _OPM(SetCookieBehavior), PR_FALSE, -1 },
{ nsnull, "Accept Cookies Session Only", _OPM(BOOL), "network.cookie.enableForCurrentSessionOnly", _OPM(SetBool), PR_FALSE, -1 },
{ nsnull, "Allow script to resize window", _OPM(BOOL), "dom.disable_window_move_resize", _OPM(SetBool), PR_FALSE, -1 },
{ nsnull, "Allow script to move window", _OPM(BOOL), "dom.disable_window_move_resize", _OPM(SetBool), PR_FALSE, -1 },
{ nsnull, "Allow script to raise window", _OPM(BOOL), "dom.disable_window_flip", _OPM(SetBool), PR_FALSE, -1 },
{ nsnull, "Allow script to change status", _OPM(BOOL), "dom.disable_window_status_change", _OPM(SetBool), PR_FALSE, -1 },
{ nsnull, "Ignore Unrequested Popups", _OPM(BOOL), "dom.disable_open_during_load", _OPM(SetBool), PR_FALSE, -1 },
{ nsnull, "Load Figures", _OPM(BOOL), "permissions.default.image", _OPM(SetImageBehavior), PR_FALSE, -1 },
--- a/browser/components/migration/src/nsSafariProfileMigrator.cpp
+++ b/browser/components/migration/src/nsSafariProfileMigrator.cpp
@@ -511,17 +511,17 @@ nsSafariProfileMigrator::SetDownloadFold
nsCOMPtr<nsIProperties> fileLocator(do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID));
nsCOMPtr<nsILocalFile> desktopFolder;
fileLocator->Get(NS_OSX_USER_DESKTOP_DIR, NS_GET_IID(nsILocalFile),
getter_AddRefs(desktopFolder));
PRBool equals;
downloadFolder->Equals(desktopFolder, &equals);
aBranch->SetIntPref("browser.download.folderList", equals ? 0 : 2);
- aBranch->SetComplexValue("browser.download.defaultFolder",
+ aBranch->SetComplexValue("browser.download.dir",
NS_GET_IID(nsILocalFile), downloadFolder);
return NS_OK;
}
nsresult
nsSafariProfileMigrator::SetDownloadHandlers(void* aTransform, nsIPrefBranch* aBranch)
{
--- a/browser/components/preferences/main.js
+++ b/browser/components/preferences/main.js
@@ -166,36 +166,45 @@ var gMainPane = {
homePage.value = homePage.defaultValue;
},
// DOWNLOADS
/*
* Preferences:
*
- * browser.download.showWhenStarting
- * true if the Download Manager should be opened when a download is started,
- * false if it shouldn't be opened
- * browser.download.closeWhenDone
- * true if the Download Manager should be closed when all downloads
- * complete, false if it shouldn't be closed
- * browser.download.useDownloadDir
- * true if downloads are saved to a default location with no UI shown, false
- * if the user should always be asked where to save files
- * browser.download.dir
- * the last directory to which a download was saved
+ * browser.download.showWhenStarting - bool
+ * True if the Download Manager should be opened when a download is
+ * started, false if it shouldn't be opened.
+ * browser.download.closeWhenDone - bool
+ * True if the Download Manager should be closed when all downloads
+ * complete, false if it should be left open.
+ * browser.download.useDownloadDir - bool
+ * True if downloads are saved with no save-as UI shown, false if
+ * the user should always be asked where to save a file.
+ * browser.download.dir - str path
+ * A local path the user may have selected for downloaded files to be
+ * saved. Migration of other browser settings may also set this path.
+ * This path is enabled when folderList is equals 2.
+ * browser.download.lastDir - str path
+ * May contain the last folder path accessed when the user browsed
+ * via the file save-as dialog. (see contentAreaUtils.js)
+ * browser.download.folderList - int
+ * Indicates the location users wish to save downloaded files too.
+ * It is also used to display special file labels when the default
+ * download location is either the Desktop or the Downloads folder.
+ * Values:
+ * 0 - The desktop is the default download location.
+ * 1 - The system's downloads folder is the default download location.
+ * 2 - The default download location is elsewhere as specified in
+ * browser.download.dir.
* browser.download.downloadDir
- * the current default download location
- * browser.download.folderList
- * 0 if the desktop is the default download location,
- * 1 if the downloads folder is the default download location,
- * 2 if the default download location is elsewhere;
- * used to display special UI when the default location is the Desktop or
- * the Downloads folder in Download Manager UI and in the file field in
- * preferences
+ * depreciated.
+ * browser.download.defaultFolder
+ * depreciated.
*/
/**
* Updates preferences which depend upon the value of the preference which
* determines whether the Downloads manager is opened at the start of a
* download.
*/
readShowDownloadsWhenStarting: function ()
@@ -227,78 +236,159 @@ var gMainPane = {
var chooseFolder = document.getElementById("chooseFolder");
var preference = document.getElementById("browser.download.useDownloadDir");
downloadFolder.disabled = !preference.value;
chooseFolder.disabled = !preference.value;
// don't override the preference's value in UI
return undefined;
},
-
+
/**
* Displays a file picker in which the user can choose the location where
* downloads are automatically saved, updating preferences and UI in
* response to the choice, if one is made.
*/
chooseFolder: function ()
{
const nsIFilePicker = Components.interfaces.nsIFilePicker;
+ const nsILocalFile = Components.interfaces.nsILocalFile;
+
var fp = Components.classes["@mozilla.org/filepicker;1"]
.createInstance(nsIFilePicker);
var bundlePreferences = document.getElementById("bundlePreferences");
var title = bundlePreferences.getString("chooseDownloadFolderTitle");
fp.init(window, title, nsIFilePicker.modeGetFolder);
+ fp.appendFilters(nsIFilePicker.filterAll);
- const nsILocalFile = Components.interfaces.nsILocalFile;
- var customDirPref = document.getElementById("browser.download.dir");
- if (customDirPref.value)
- fp.displayDirectory = customDirPref.value;
- fp.appendFilters(nsIFilePicker.filterAll);
+ var folderListPref = document.getElementById("browser.download.folderList");
+ var currentDirPref = this._indexToFolder(folderListPref.value); // file
+ var defDownloads = this._indexToFolder(1); // file
+
+ // First try to open what's currently configured
+ if (currentDirPref && currentDirPref.exists()) {
+ fp.displayDirectory = currentDirPref;
+ } // Try the system's download dir
+ else if (defDownloads && defDownloads.exists()) {
+ fp.displayDirectory = defDownloads;
+ } // Fall back to Desktop
+ else {
+ fp.displayDirectory = this._indexToFolder(0);
+ }
+
if (fp.show() == nsIFilePicker.returnOK) {
var file = fp.file.QueryInterface(nsILocalFile);
- var currentDirPref = document.getElementById("browser.download.downloadDir");
- customDirPref.value = currentDirPref.value = file;
+ var currentDirPref = document.getElementById("browser.download.dir");
+ currentDirPref.value = file;
var folderListPref = document.getElementById("browser.download.folderList");
folderListPref.value = this._folderToIndex(file);
+ // Note, the real prefs will not be updated yet, so dnld manager's
+ // userDownloadsDirectory may not return the right folder after
+ // this code executes. displayDownloadDirPref will be called on
+ // the assignment above to update the UI.
}
},
/**
- * Initializes the download folder widget based on the folder as stored in
+ * Initializes the download folder display settings based on the user's
* preferences.
*/
- readDownloadDirPref: function ()
+ displayDownloadDirPref: function ()
{
var folderListPref = document.getElementById("browser.download.folderList");
var bundlePreferences = document.getElementById("bundlePreferences");
var downloadFolder = document.getElementById("downloadFolder");
+ var currentDirPref = document.getElementById("browser.download.dir");
- var customDirPref = document.getElementById("browser.download.dir");
- var customIndex = customDirPref.value ? this._folderToIndex(customDirPref.value) : 0;
- if (folderListPref.value == 0 || customIndex == 0)
- downloadFolder.label = bundlePreferences.getString("desktopFolderName");
- else if (folderListPref.value == 1 || customIndex == 1)
- downloadFolder.label = bundlePreferences.getString("myDownloadsFolderName");
- else
- downloadFolder.label = this._getDisplayNameOfFile(customDirPref.value);
+ // The user's download folder is based on the preferences listed above.
+ // However, if the system does not support a download folder, the
+ // actual path returned will be the system's desktop or home folder.
+ // If this is the case, skip off displaying the Download label and
+ // display Desktop, even though folderList might be 1.
+ var fileLocator = Components.classes["@mozilla.org/file/directory_service;1"]
+ .getService(Components.interfaces.nsIProperties);
+ var desk = fileLocator.get("Desk", Components.interfaces.nsILocalFile);
+ var dnldMgr = Components.classes["@mozilla.org/download-manager;1"]
+ .getService(Components.interfaces.nsIDownloadManager);
+ var supportDownloadLabel = !dnldMgr.defaultDownloadsDirectory.equals(desk);
+ // Used in defining the correct path to the folder icon.
var ios = Components.classes["@mozilla.org/network/io-service;1"]
.getService(Components.interfaces.nsIIOService);
var fph = ios.getProtocolHandler("file")
.QueryInterface(Components.interfaces.nsIFileProtocolHandler);
- var currentDirPref = document.getElementById("browser.download.downloadDir");
- var downloadDir = currentDirPref.value || this._indexToFolder(folderListPref.value);
- var urlspec = fph.getURLSpecFromFile(downloadDir);
- downloadFolder.image = "moz-icon://" + urlspec + "?size=16";
-
+ var iconUrlSpec;
+
+ // Display a 'pretty' label or the path in the UI.
+ if (folderListPref.value == 2) {
+ // Custom path selected and is configured
+ downloadFolder.label = this._getDisplayNameOfFile(currentDirPref.value);
+ iconUrlSpec = fph.getURLSpecFromFile(currentDirPref.value);
+ } else if (folderListPref.value == 1 && supportDownloadLabel) {
+ // 'Downloads'
+ // In 1.5, this pointed to a folder we created called 'My Downloads'
+ // and was available as an option in the 1.5 drop down. On XP this
+ // was in My Documents, on OSX it was in User Docs. In 2.0, we did
+ // away with the drop down option, although the special label was
+ // still supported for the folder if it existed. Because it was
+ // not exposed it was rarely used.
+ // With 3.0, a new desktop folder - 'Downloads' was introduced for
+ // platforms and versions that don't support a default system downloads
+ // folder. See nsDownloadManager for details.
+ downloadFolder.label = bundlePreferences.getString("downloadsFolderName");
+ iconUrlSpec = fph.getURLSpecFromFile(this._indexToFolder(1));
+ } else {
+ // 'Desktop'
+ downloadFolder.label = bundlePreferences.getString("desktopFolderName");
+ iconUrlSpec = fph.getURLSpecFromFile(desk);
+ }
+ downloadFolder.image = "moz-icon://" + iconUrlSpec + "?size=16";
+
// don't override the preference's value in UI
return undefined;
},
/**
+ * Returns the textual path of a folder in readable form.
+ */
+ _getDisplayNameOfFile: function (aFolder)
+ {
+ // TODO: would like to add support for 'Downloads on Macintosh HD'
+ // for OS X users.
+ return aFolder ? aFolder.path : "";
+ },
+
+ /**
+ * Returns the Downloads folder. If aFolder is "Desktop", then the Downloads
+ * folder returned is the desktop folder; otherwise, it is a folder whose name
+ * indicates that it is a download folder and whose path is as determined by
+ * the XPCOM directory service via the download manager's attribute
+ * defaultDownloadsDirectory.
+ *
+ * @throws if aFolder is not "Desktop" or "Downloads"
+ */
+ _getDownloadsFolder: function (aFolder)
+ {
+ switch(aFolder)
+ {
+ case "Desktop":
+ var fileLoc = Components.classes["@mozilla.org/file/directory_service;1"]
+ .getService(Components.interfaces.nsIProperties);
+ return fileLoc.get("Desk", Components.interfaces.nsILocalFile);
+ break;
+ case "Downloads":
+ var dnldMgr = Components.classes["@mozilla.org/download-manager;1"]
+ .getService(Components.interfaces.nsIDownloadManager);
+ return dnldMgr.defaultDownloadsDirectory;
+ break;
+ }
+ throw "ASSERTION FAILED: folder type should be 'Desktop' or 'Downloads'";
+ },
+
+ /**
* Determines the type of the given folder.
*
* @param aFolder
* the folder whose type is to be determined
* @returns integer
* 0 if aFolder is the Desktop or is unspecified,
* 1 if aFolder is the Downloads folder,
* 2 otherwise
@@ -308,103 +398,57 @@ var gMainPane = {
if (!aFolder || aFolder.equals(this._getDownloadsFolder("Desktop")))
return 0;
else if (aFolder.equals(this._getDownloadsFolder("Downloads")))
return 1;
return 2;
},
/**
- * Returns the Downloads folder. If aFolder is "Desktop", then the Downloads
- * folder returned is the desktop folder; otherwise, it is a folder whose name
- * indicates that it is a download folder and whose path is as determined by
- * the XPCOM directory service from aFolder.
- *
- * @throws if aFolder is not "Desktop" or "Downloads"
- */
- _getDownloadsFolder: function (aFolder)
- {
- var fileLocator = Components.classes["@mozilla.org/file/directory_service;1"]
- .getService(Components.interfaces.nsIProperties);
- var dir = fileLocator.get(this._getSpecialFolderKey(aFolder),
- Components.interfaces.nsILocalFile);
- if (aFolder != "Desktop")
- dir.append("My Downloads"); // XXX l12y!
-
- return dir;
- },
-
- /**
- * Gets the platform-specific key to be fed to the directory service for the
- * given special folder.
- *
- * @param aFolder
- * either of the strings "Desktop" or "Downloads"
- * @returns the platform-specific key for the location, which may be used with
- * the XPCOM directory service
- */
- _getSpecialFolderKey: function (aFolderType)
- {
- if (aFolderType == "Desktop")
- return "Desk";
-
- if (aFolderType == "Downloads")
-#ifdef XP_WIN
- return "Pers";
-#else
-#ifdef XP_MACOSX
- return "UsrDocs";
-#else
- return "Home";
-#endif
-#endif
-
- throw "ASSERTION FAILED: folder type should be 'Desktop' or 'Downloads'";
- },
-
- /**
- * Returns the textual path of a folder in readable form.
- */
- _getDisplayNameOfFile: function (aFolder)
- {
- // TODO: would like to add support for 'Downloads on Macintosh HD'
- // for OS X users.
- return aFolder ? aFolder.path : "";
- },
-
- /**
* Converts an integer into the corresponding folder.
*
* @param aIndex
* an integer
* @returns the Desktop folder if aIndex == 0,
* the Downloads folder if aIndex == 1,
- * the folder stored in browser.download.dir otherwise
+ * the folder stored in browser.download.dir
*/
_indexToFolder: function (aIndex)
{
switch (aIndex) {
case 0:
return this._getDownloadsFolder("Desktop");
case 1:
return this._getDownloadsFolder("Downloads");
}
-
- var customDirPref = document.getElementById("browser.download.dir");
- return customDirPref.value;
+ var currentDirPref = document.getElementById("browser.download.dir");
+ return currentDirPref.value;
},
/**
- * Returns the value for the browser.download.folderList preference determined
- * from the current value of browser.download.downloadDir.
+ * Returns the value for the browser.download.folderList preference.
*/
- writeFolderList: function ()
+ getFolderListPref: function ()
{
- var currentDirPref = document.getElementById("browser.download.downloadDir");
- return this._folderToIndex(currentDirPref.value);
+ var folderListPref = document.getElementById("browser.download.folderList");
+ switch(folderListPref.value) {
+ case 0: // Desktop
+ case 1: // Downloads
+ return folderListPref.value;
+ break;
+ case 2: // Custom
+ var currentDirPref = document.getElementById("browser.download.dir");
+ if (currentDirPref.value) {
+ // Resolve to a known location if possible. We are writing out
+ // to prefs on this call, so now would be a good time to do it.
+ return this._folderToIndex(currentDirPref.value);
+ }
+ return 0;
+ break;
+ }
}
#ifdef HAVE_SHELL_SERVICE
,
// SYSTEM DEFAULTS
/*
--- a/browser/components/preferences/main.xul
+++ b/browser/components/preferences/main.xul
@@ -86,17 +86,16 @@
type="bool"/>
<preference id="browser.download.useDownloadDir"
name="browser.download.useDownloadDir"
type="bool"/>
<preference id="browser.download.dir"
name="browser.download.dir"
type="file"
onchange="gMainPane.readDownloadDirPref();"/>
- <preference id="browser.download.downloadDir" name="browser.download.downloadDir" type="file"/>
<preference id="browser.download.folderList" name="browser.download.folderList" type="int"/>
<!-- SYSTEM DEFAULTS -->
<preference id="browser.shell.checkDefaultBrowser"
name="browser.shell.checkDefaultBrowser"
type="bool"/>
<preference id="pref.general.disable_button.default_browser"
@@ -172,28 +171,28 @@
<radio id="saveTo" value="true"
label="&saveTo.label;"
accesskey="&saveTo.accesskey;"
xmlns:aaa="http://www.w3.org/2005/07/aaa"
aaa:labelledby="saveTo downloadFolder"/>
<filefield id="downloadFolder" flex="1"
preference="browser.download.folderList"
preference-editable="true"
- onsyncfrompreference="return gMainPane.readDownloadDirPref();"
- onsynctopreference="return gMainPane.writeFolderList()"/>
+ onsyncfrompreference="return gMainPane.displayDownloadDirPref();"
+ onsynctopreference="return gMainPane.getFolderListPref()"/>
<button id="chooseFolder" oncommand="gMainPane.chooseFolder();"
#ifdef XP_MACOSX
accesskey="&chooseFolderMac.accesskey;"
label="&chooseFolderMac.label;"
#else
accesskey="&chooseFolderWin.accesskey;"
label="&chooseFolderWin.label;"
#endif
preference="browser.download.folderList"
- onsynctopreference="return gMainPane.writeFolderList();"/>
+ onsynctopreference="return gMainPane.getFolderListPref();"/>
</hbox>
<radio id="alwaysAsk" value="false"
label="&alwaysAsk.label;"
accesskey="&alwaysAsk.accesskey;"/>
</radiogroup>
</groupbox>
#ifdef HAVE_SHELL_SERVICE
--- a/browser/locales/en-US/chrome/browser/preferences/preferences.properties
+++ b/browser/locales/en-US/chrome/browser/preferences/preferences.properties
@@ -35,17 +35,17 @@ pw_change_failed_title=Password Change F
# %1$S = language name, %2$S = region name, %3$S = language-region code
languageRegionCodeFormat=%1$S/%2$S [%3$S]
# %1$S = language name, %2$S = language-region code
languageCodeFormat=%1$S [%2$S]
#### Downloads
desktopFolderName=Desktop
-myDownloadsFolderName=My Downloads
+downloadsFolderName=Downloads
chooseDownloadFolderTitle=Choose Download Folder:
#### Download Actions
extensionNone=(NONE)
removeButtonSingle=Remove Action
removeButtonMultiple=Remove Actions
removeTitleSingle=Remove Action
--- a/toolkit/components/downloads/public/nsIDownloadManager.idl
+++ b/toolkit/components/downloads/public/nsIDownloadManager.idl
@@ -46,17 +46,17 @@ interface nsIURI;
interface nsILocalFile;
interface nsIDownload;
interface nsICancelable;
interface nsIMIMEInfo;
interface nsIDownloadProgressListener;
interface nsISimpleEnumerator;
interface mozIStorageConnection;
-[scriptable, uuid(a44925cb-186a-4e57-846e-8f9504b9f675)]
+[scriptable, uuid(b23d291f-2893-48ea-abda-ba9c9fe69c95)]
interface nsIDownloadManager : nsISupports {
// Download States
const short DOWNLOAD_NOTSTARTED = -1;
const short DOWNLOAD_QUEUED = 5;
const short DOWNLOAD_DOWNLOADING = 0;
const short DOWNLOAD_FINISHED = 1;
const short DOWNLOAD_FAILED = 2;
const short DOWNLOAD_CANCELED = 3;
@@ -205,11 +205,38 @@ interface nsIDownloadManager : nsISuppor
* Adds a listener from the download manager.
*/
void addListener(in nsIDownloadProgressListener aListener);
/**
* Removes a listener from the download manager.
*/
void removeListener(in nsIDownloadProgressListener aListener);
+
+ /**
+ * Returns the platform default downloads directory.
+ */
+ readonly attribute nsILocalFile defaultDownloadsDirectory;
+
+ /**
+ * Returns the user configured downloads directory.
+ * The path is dependent on two user configurable prefs
+ * set in preferences:
+ *
+ * browser.download.folderList
+ * Indicates the location users wish to save downloaded
+ * files too.
+ * Values:
+ * 0 - The desktop is the default download location.
+ * 1 - The system's downloads folder is the default download location.
+ * 2 - The default download location is elsewhere as specified in
+ * browser.download.dir. If invalid, userDownloadsDirectory
+ * will fallback on defaultDownloadsDirectory.
+ *
+ * browser.download.dir -
+ * A local path the user may have selected at some point
+ * where downloaded files are saved. The use of which is
+ * enabled when folderList equals 2.
+ */
+ readonly attribute nsILocalFile userDownloadsDirectory;
};
--- a/toolkit/components/downloads/src/nsDownloadManager.cpp
+++ b/toolkit/components/downloads/src/nsDownloadManager.cpp
@@ -47,32 +47,33 @@
#include "nsNetUtil.h"
#include "nsIURL.h"
#include "nsIDOMChromeWindow.h"
#include "nsIDOMWindow.h"
#include "nsIDOMWindowInternal.h"
#include "nsIDOMEvent.h"
#include "nsIDOMEventTarget.h"
#include "nsAppDirectoryServiceDefs.h"
+#include "nsDirectoryServiceDefs.h"
#include "nsIWindowWatcher.h"
#include "nsIWindowMediator.h"
#include "nsIPromptService.h"
#include "nsIPrefBranch.h"
#include "nsIPrefService.h"
#include "nsVoidArray.h"
#include "nsEnumeratorUtils.h"
#include "nsIFileURL.h"
#include "nsEmbedCID.h"
#include "mozStorageCID.h"
#include "mozIStorageService.h"
#include "mozStorageHelper.h"
#include "nsIMutableArray.h"
#include "nsIAlertsService.h"
+#include "nsIPropertyBag2.h"
#include "nsIHttpChannel.h"
-#include "nsIPropertyBag2.h"
#ifdef XP_WIN
#include <shlobj.h>
#endif
static PRBool gStoppingDownloads = PR_FALSE;
#define DOWNLOAD_MANAGER_FE_URL "chrome://mozapps/content/downloads/downloads.xul"
@@ -703,16 +704,190 @@ nsDownloadManager::GetActiveDownloadCoun
NS_IMETHODIMP
nsDownloadManager::GetActiveDownloads(nsISimpleEnumerator **aResult)
{
return NS_NewArrayEnumerator(aResult, mCurrentDownloads);
}
NS_IMETHODIMP
+nsDownloadManager::GetDefaultDownloadsDirectory(nsILocalFile **aResult)
+{
+ nsCOMPtr<nsILocalFile> downloadDir;
+
+ nsresult rv;
+ nsCOMPtr<nsIProperties> dirService =
+ do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID, &rv);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ // OSX:
+ // Safari download folder or Desktop/Downloads
+ // Vista:
+ // Downloads
+ // XP/2K:
+ // Desktop/Downloads
+ // Linux:
+ // Home/Downloads
+
+ nsXPIDLString folderName;
+ mBundle->GetStringFromName(NS_LITERAL_STRING("downloadsFolder").get(),
+ getter_Copies(folderName));
+
+#if defined (XP_MACOSX)
+ nsCOMPtr<nsILocalFile> desktopDir;
+ rv = dirService->Get(NS_OSX_DEFAULT_DOWNLOAD_DIR,
+ NS_GET_IID(nsILocalFile),
+ getter_AddRefs(downloadDir));
+ NS_ENSURE_SUCCESS(rv, rv);
+ rv = dirService->Get(NS_OSX_USER_DESKTOP_DIR,
+ NS_GET_IID(nsILocalFile),
+ getter_AddRefs(desktopDir));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ // Check to see if we have the desktop or the Safari downloads folder
+ PRBool equals;
+ rv = downloadDir->Equals(desktopDir, &equals);
+ NS_ENSURE_SUCCESS(rv, rv);
+ if (equals) {
+ rv = downloadDir->Append(folderName);
+ NS_ENSURE_SUCCESS(rv, rv);
+ }
+#elif defined (XP_WIN)
+ rv = dirService->Get(NS_WIN_DEFAULT_DOWNLOAD_DIR,
+ NS_GET_IID(nsILocalFile),
+ getter_AddRefs(downloadDir));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ // Check the os version
+ #define NS_SYSTEMINFO_CONTRACTID "@mozilla.org/system-info;1"
+ nsCOMPtr<nsIPropertyBag2> infoService =
+ do_GetService(NS_SYSTEMINFO_CONTRACTID, &rv);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ PRInt32 version;
+ NS_NAMED_LITERAL_STRING(osVersion, "version");
+ rv = infoService->GetPropertyAsInt32(osVersion, &version);
+ if (version < 6) { // XP/2K
+ rv = downloadDir->Append(folderName);
+ NS_ENSURE_SUCCESS(rv, rv);
+ }
+#else
+ rv = dirService->Get(NS_OS_HOME_DIR,
+ NS_GET_IID(nsILocalFile),
+ getter_AddRefs(downloadDir));
+ NS_ENSURE_SUCCESS(rv, rv);
+ rv = downloadDir->Append(folderName);
+ NS_ENSURE_SUCCESS(rv, rv);
+#endif
+
+ NS_ADDREF(*aResult = downloadDir);
+
+ return NS_OK;
+}
+
+#define NS_BRANCH_DOWNLOAD "browser.download."
+#define NS_PREF_FOLDERLIST "folderList"
+#define NS_PREF_DIR "dir"
+
+NS_IMETHODIMP
+nsDownloadManager::GetUserDownloadsDirectory(nsILocalFile **aResult)
+{
+ nsresult rv;
+ nsCOMPtr<nsIProperties> dirService =
+ do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID, &rv);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ nsCOMPtr<nsIPrefService> prefService =
+ do_GetService(NS_PREFSERVICE_CONTRACTID, &rv);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ nsCOMPtr<nsIPrefBranch> prefBranch;
+ rv = prefService->GetBranch(NS_BRANCH_DOWNLOAD,
+ getter_AddRefs(prefBranch));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ PRInt32 val;
+ rv = prefBranch->GetIntPref(NS_PREF_FOLDERLIST,
+ &val);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ PRBool bRes = PR_FALSE;
+
+ switch(val) {
+ case 0: // Desktop
+ {
+ nsCOMPtr<nsILocalFile> downloadDir;
+ nsCOMPtr<nsIProperties> dirService =
+ do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID, &rv);
+ NS_ENSURE_SUCCESS(rv, rv);
+ rv = dirService->Get(NS_OS_DESKTOP_DIR,
+ NS_GET_IID(nsILocalFile),
+ getter_AddRefs(downloadDir));
+ NS_ENSURE_SUCCESS(rv, rv);
+ NS_ADDREF(*aResult = downloadDir);
+ return NS_OK;
+ }
+ break;
+ case 1: // Downloads
+ {
+ rv = GetDefaultDownloadsDirectory(aResult); // refup
+ NS_ENSURE_SUCCESS(rv, rv);
+ (*aResult)->Exists(&bRes);
+ if (!bRes) {
+ rv = (*aResult)->Create(nsIFile::DIRECTORY_TYPE, 755);
+ NS_ENSURE_SUCCESS(rv, rv);
+ }
+ return NS_OK;
+ }
+ break;
+ case 2: // Custom
+ {
+ nsCOMPtr<nsISupportsString> customDirectory;
+ prefBranch->GetComplexValue(NS_PREF_DIR,
+ NS_GET_IID(nsISupportsString),
+ getter_AddRefs(customDirectory));
+ if (customDirectory) {
+ nsCOMPtr<nsILocalFile> aFile =
+ do_CreateInstance("@mozilla.org/file/local;1", &rv);
+ NS_ENSURE_SUCCESS(rv, rv);
+ nsAutoString dir;
+ customDirectory->GetData(dir);
+ rv = aFile->InitWithNativePath(NS_ConvertUTF16toUTF8(dir));
+ NS_ENSURE_SUCCESS(rv, rv);
+ aFile->Exists(&bRes);
+ if (bRes) {
+ NS_ADDREF(*aResult = aFile);
+ return NS_OK;
+ }
+ rv = aFile->Create(nsIFile::DIRECTORY_TYPE, 755);
+ NS_ENSURE_SUCCESS(rv, rv);
+ if (bRes) {
+ NS_ADDREF(*aResult = aFile);
+ return NS_OK;
+ }
+ }
+ rv = GetDefaultDownloadsDirectory(aResult); // refup
+ NS_ENSURE_SUCCESS(rv, rv);
+ (*aResult)->Exists(&bRes);
+ if (!bRes) {
+ rv = (*aResult)->Create(nsIFile::DIRECTORY_TYPE, 755);
+ NS_ENSURE_SUCCESS(rv, rv);
+ // Update dir pref
+ prefBranch->SetComplexValue(NS_PREF_DIR,
+ NS_GET_IID(nsILocalFile),
+ *aResult);
+ }
+ return NS_OK;
+ }
+ break;
+ }
+ return NS_ERROR_INVALID_ARG;
+}
+
+NS_IMETHODIMP
nsDownloadManager::AddDownload(DownloadType aDownloadType,
nsIURI* aSource,
nsIURI* aTarget,
const nsAString& aDisplayName,
nsIMIMEInfo *aMIMEInfo,
PRTime aStartTime,
nsILocalFile* aTempFile,
nsICancelable* aCancelable,
--- a/toolkit/content/contentAreaUtils.js
+++ b/toolkit/content/contentAreaUtils.js
@@ -446,89 +446,45 @@ function getTargetFile(aFpP, aSkipPrompt
{
const prefSvcContractID = "@mozilla.org/preferences-service;1";
const prefSvcIID = Components.interfaces.nsIPrefService;
var prefs = Components.classes[prefSvcContractID]
.getService(prefSvcIID).getBranch("browser.download.");
const nsILocalFile = Components.interfaces.nsILocalFile;
- // ben 07/31/2003:
- // |browser.download.defaultFolder| holds the default download folder for
- // all files when the user has elected to have all files automatically
- // download to a folder. The values of |defaultFolder| can be either their
- // desktop, their downloads folder (My Documents\My Downloads) or some other
- // location of their choosing (which is mapped to |browser.download.dir|
- // This pref is _unset_ when the user has elected to be asked about where
- // to place every download - this will force the prompt to ask the user
- // where to put saved files.
- var dir = null;
- var useDownloadDir = prefs.getBoolPref("useDownloadDir");
-
- function getSpecialFolderKey(aFolderType)
- {
- if (aFolderType == "Desktop")
- return "Desk";
-
- if (aFolderType != "Downloads")
- throw "ASSERTION FAILED: folder type should be 'Desktop' or 'Downloads'";
-
-#ifdef XP_WIN
- return "Pers";
-#else
-#ifdef XP_MACOSX
- return "UsrDocs";
-#else
- return "Home";
-#endif
-#endif
- }
+ // For information on download folder preferences, see
+ // mozilla/browser/components/preferences/main.js
- function getDownloadsFolder(aFolder)
- {
- var fileLocator = Components.classes["@mozilla.org/file/directory_service;1"]
- .getService(Components.interfaces.nsIProperties);
-
- var dir = fileLocator.get(getSpecialFolderKey(aFolder), Components.interfaces.nsILocalFile);
-
- var bundle = Components.classes["@mozilla.org/intl/stringbundle;1"]
- .getService(Components.interfaces.nsIStringBundleService);
- bundle = bundle.createBundle("chrome://mozapps/locale/downloads/unknownContentType.properties");
-
- var description = bundle.GetStringFromName("myDownloads");
- if (aFolder != "Desktop")
- dir.append(description);
-
- return dir;
+ var useDownloadDir = prefs.getBoolPref("useDownloadDir");
+ var dir = null;
+
+ try {
+ // On prompt operations, default to lastDir, on direct to folder
+ // downloads, default to the user's configured download folder.
+ // (right-click save image vs. drag-and-drop into download manager)
+ var lastDir = prefs.getComplexValue("lastDir", nsILocalFile);
+ var dnldMgr = Components.classes["@mozilla.org/download-manager;1"]
+ .getService(Components.interfaces.nsIDownloadManager);
+ if (!aSkipPrompt) {
+ dir = lastDir;
+ } else {
+ dir = dnldMgr.userDownloadsDirectory;
+ }
+ } catch (ex) {
}
-
- switch (prefs.getIntPref("folderList")) {
- case 0:
- dir = getDownloadsFolder("Desktop")
- break;
- case 1:
- dir = getDownloadsFolder("Downloads");
- break;
- case 2:
- dir = prefs.getComplexValue("dir", nsILocalFile);
- break;
- }
-
- if (!aSkipPrompt || !useDownloadDir || !dir) {
+
+ if (!aSkipPrompt || !useDownloadDir || !dir || (dir && !dir.exists())) {
// If we're asking the user where to save the file, root the Save As...
- // dialog on they place they last picked.
- try {
- dir = prefs.getComplexValue("lastDir", nsILocalFile);
- }
- catch (e) {
- // No default download location. Default to desktop.
+ // dialog on the place they last picked.
+ if (!dir || (dir && !dir.exists())) {
+ // Default to desktop.
var fileLocator = Components.classes["@mozilla.org/file/directory_service;1"]
.getService(Components.interfaces.nsIProperties);
-
- dir = fileLocator.get(getSpecialFolderKey("Desktop"), nsILocalFile);
+ dir = fileLocator.get("Desk", nsILocalFile);
}
var fp = makeFilePicker();
var titleKey = aFpP.fpTitleKey || "SaveLinkTitle";
var bundle = getStringBundle();
fp.init(window, bundle.GetStringFromName(titleKey),
Components.interfaces.nsIFilePicker.modeSave);
@@ -543,17 +499,17 @@ function getTargetFile(aFpP, aSkipPrompt
if (aFpP.isDocument) {
try {
fp.filterIndex = prefs.getIntPref("save_converter_index");
}
catch (e) {
}
}
-
+
if (fp.show() == Components.interfaces.nsIFilePicker.returnCancel || !fp.file)
return false;
var directory = fp.file.parent.QueryInterface(nsILocalFile);
prefs.setComplexValue("lastDir", nsILocalFile, directory);
fp.file.leafName = validateFileName(fp.file.leafName);
aFpP.saveAsType = fp.filterIndex;
--- a/toolkit/locales/en-US/chrome/mozapps/downloads/downloads.properties
+++ b/toolkit/locales/en-US/chrome/mozapps/downloads/downloads.properties
@@ -55,8 +55,11 @@ chooseAppFilePickerTitle=Open With...
downloadsTitle=%S%% of 1 file - Downloads
downloadsTitleMultiple=%S%% of %S files - Downloads
fileExecutableSecurityWarning="%S" is an executable file. Executable files may contain viruses or other malicious code that could harm your computer. Use caution when opening this file. Are you sure you want to launch "%S"?
fileExecutableSecurityWarningTitle=Open Executable File?
fileExecutableSecurityWarningDontAsk=Don't ask me this again
displayNameDesktop=Desktop
+
+# Desktop folder name for downloaded files
+downloadsFolder=Downloads
--- a/toolkit/locales/en-US/chrome/mozapps/downloads/unknownContentType.properties
+++ b/toolkit/locales/en-US/chrome/mozapps/downloads/unknownContentType.properties
@@ -38,12 +38,11 @@
title=Opening %S
saveDialogTitle=Enter name of file to save to...
defaultApp=%S (default)
chooseAppFilePickerTitle=Choose Helper Application
badApp=The application you chose ("%S") could not be found. Check the file name or choose another application.
badApp.title=Application not found
selectDownloadDir=Select Download Folder
-myDownloads=My Downloads
unknownAccept.label=Save File
unknownCancel.label=Cancel
fileType=%S file
--- a/toolkit/mozapps/downloads/src/nsHelperAppDlg.js.in
+++ b/toolkit/mozapps/downloads/src/nsHelperAppDlg.js.in
@@ -116,144 +116,96 @@ nsUnknownContentTypeDialog.prototype = {
//
// Alternatively, if the user has selected to have all
// files download to a specific location, return that
// location and don't ask via the dialog.
//
// Note - this function is called without a dialog, so it cannot access any part
// of the dialog XUL as other functions on this object do.
promptForSaveToFile: function(aLauncher, aContext, aDefaultFile, aSuggestedFileExtension) {
- var result = "";
+ var result = null;
this.mLauncher = aLauncher;
- // If the user is always downloading to the same location, the default download
- // folder is stored in preferences. If a value is found stored, use that
- // automatically and don't ask via a dialog.
+ // Check to see if the user wishes to auto save to the default download
+ // folder without prompting.
var prefs = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch);
var autodownload = prefs.getBoolPref("browser.download.useDownloadDir");
+
if (autodownload) {
- function getSpecialFolderKey(aFolderType)
- {
- if (aFolderType == "Desktop")
- return "Desk";
-
- if (aFolderType != "Downloads")
- throw "ASSERTION FAILED: folder type should be 'Desktop' or 'Downloads'";
-
-#ifdef XP_WIN
- return "Pers";
-#else
-#ifdef XP_MACOSX
- return "UsrDocs";
-#else
- return "Home";
-#endif
-#endif
- }
-
- function getDownloadsFolder(aFolder)
- {
- var fileLocator = Components.classes["@mozilla.org/file/directory_service;1"].getService(Components.interfaces.nsIProperties);
-
- var dir = fileLocator.get(getSpecialFolderKey(aFolder), Components.interfaces.nsILocalFile);
-
- var bundle = Components.classes["@mozilla.org/intl/stringbundle;1"].getService(Components.interfaces.nsIStringBundleService);
- bundle = bundle.createBundle("chrome://mozapps/locale/downloads/unknownContentType.properties");
-
- var description = bundle.GetStringFromName("myDownloads");
- if (aFolder != "Desktop")
- dir.append(description);
-
- return dir;
- }
-
- var defaultFolder = null;
- switch (prefs.getIntPref("browser.download.folderList")) {
- case 0:
- defaultFolder = getDownloadsFolder("Desktop");
- break;
- case 1:
- defaultFolder = getDownloadsFolder("Downloads");
- break;
- case 2:
- defaultFolder = prefs.getComplexValue("browser.download.dir", Components.interfaces.nsILocalFile);
- break;
- }
-
+ // Retrieve the user's default download directory
+ var dnldMgr = Components.classes["@mozilla.org/download-manager;1"]
+ .getService(Components.interfaces.nsIDownloadManager);
+ var defaultFolder = dnldMgr.userDownloadsDirectory;
result = this.validateLeafName(defaultFolder, aDefaultFile, aSuggestedFileExtension);
}
- if (!result) {
- // Use file picker to show dialog.
- var nsIFilePicker = Components.interfaces.nsIFilePicker;
- var picker = Components.classes["@mozilla.org/filepicker;1"].createInstance(nsIFilePicker);
+ // Check to make sure we have a valid directory, otherwise, prompt
+ if (result)
+ return result;
+
+ // Use file picker to show dialog.
+ var nsIFilePicker = Components.interfaces.nsIFilePicker;
+ var picker = Components.classes["@mozilla.org/filepicker;1"].createInstance(nsIFilePicker);
- var bundle = Components.classes["@mozilla.org/intl/stringbundle;1"].getService(Components.interfaces.nsIStringBundleService);
- bundle = bundle.createBundle("chrome://mozapps/locale/downloads/unknownContentType.properties");
-
- var windowTitle = bundle.GetStringFromName("saveDialogTitle");
- var parent = aContext.QueryInterface(Components.interfaces.nsIInterfaceRequestor).getInterface(Components.interfaces.nsIDOMWindowInternal);
- picker.init(parent, windowTitle, nsIFilePicker.modeSave);
- picker.defaultString = aDefaultFile;
+ var bundle = Components.classes["@mozilla.org/intl/stringbundle;1"].getService(Components.interfaces.nsIStringBundleService);
+ bundle = bundle.createBundle("chrome://mozapps/locale/downloads/unknownContentType.properties");
- if (aSuggestedFileExtension) {
- // aSuggestedFileExtension includes the period, so strip it
- picker.defaultExtension = aSuggestedFileExtension.substring(1);
+ var windowTitle = bundle.GetStringFromName("saveDialogTitle");
+ var parent = aContext.QueryInterface(Components.interfaces.nsIInterfaceRequestor).getInterface(Components.interfaces.nsIDOMWindowInternal);
+ picker.init(parent, windowTitle, nsIFilePicker.modeSave);
+ picker.defaultString = aDefaultFile;
+
+ if (aSuggestedFileExtension) {
+ // aSuggestedFileExtension includes the period, so strip it
+ picker.defaultExtension = aSuggestedFileExtension.substring(1);
+ }
+ else {
+ try {
+ picker.defaultExtension = this.mLauncher.MIMEInfo.primaryExtension;
}
- else {
- try {
- picker.defaultExtension = this.mLauncher.MIMEInfo.primaryExtension;
- }
- catch (ex) { }
- }
-
- var wildCardExtension = "*";
- if (aSuggestedFileExtension) {
- wildCardExtension += aSuggestedFileExtension;
- picker.appendFilter(this.mLauncher.MIMEInfo.description, wildCardExtension);
- }
-
- picker.appendFilters( nsIFilePicker.filterAll );
+ catch (ex) { }
+ }
- // Pull in the user's preferences and get the default download directory.
- var prefs = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch);
- try {
- var startDir = prefs.getComplexValue("browser.download.dir", Components.interfaces.nsILocalFile);
- if (startDir.exists()) {
- picker.displayDirectory = startDir;
- }
- }
- catch(exception) { }
+ var wildCardExtension = "*";
+ if (aSuggestedFileExtension) {
+ wildCardExtension += aSuggestedFileExtension;
+ picker.appendFilter(this.mLauncher.MIMEInfo.description, wildCardExtension);
+ }
- var dlgResult = picker.show();
+ picker.appendFilters( nsIFilePicker.filterAll );
- if (dlgResult == nsIFilePicker.returnCancel) {
- // null result means user cancelled.
- return null;
- }
-
+ // Get the default download directory from download manager
+ var dnldMgr = Components.classes["@mozilla.org/download-manager;1"]
+ .getService(Components.interfaces.nsIDownloadManager);
+ var startDir = dnldMgr.defaultDownloadsDirectory;
+ picker.displayDirectory = startDir;
- // Be sure to save the directory the user chose through the Save As...
- // dialog as the new browser.download.dir
- result = picker.file;
+ if (picker.show() == nsIFilePicker.returnCancel) {
+ // null result means user cancelled.
+ return null;
+ }
+
+ // Be sure to save the directory the user chose through the Save As...
+ // dialog as the new browser.download.dir since the old one
+ // didn't exist.
+ result = picker.file;
- if (result) {
- try {
- // Remove the file so that it's not there when we ensure non-existence later;
- // this is safe because for the file to exist, the user would have had to
- // confirm that he wanted the file overwritten.
- if (result.exists())
- result.remove(false);
- }
- catch (e) { }
- var newDir = result.parent;
- prefs.setComplexValue("browser.download.dir", Components.interfaces.nsILocalFile, newDir);
- result = this.validateLeafName(newDir, result.leafName, null);
+ if (result) {
+ try {
+ // Remove the file so that it's not there when we ensure non-existence later;
+ // this is safe because for the file to exist, the user would have had to
+ // confirm that he wanted the file overwritten.
+ if (result.exists())
+ result.remove(false);
}
+ catch (e) { }
+ var newDir = result.parent;
+ prefs.setComplexValue("browser.download.dir", Components.interfaces.nsILocalFile, newDir);
+ result = this.validateLeafName(newDir, result.leafName, null);
}
return result;
},
/**
* Ensures that a local folder/file combination does not already exist in
* the file system (or finds such a combination with a reasonably similar
* leaf name), creates the corresponding file, and returns it.
--- a/xpcom/io/SpecialSystemDirectory.cpp
+++ b/xpcom/io/SpecialSystemDirectory.cpp
@@ -445,22 +445,30 @@ GetSpecialSystemDirectory(SystemDirector
{
return GetWindowsFolder(CSIDL_DESKTOP, aFile);
}
case Win_Programs:
{
return GetWindowsFolder(CSIDL_PROGRAMS, aFile);
}
- case Win_Downloads:
- {
- // Defined in KnownFolders.h.
- GUID folderid_downloads = {0x374de290, 0x123f, 0x4565, {0x91, 0x64, 0x39, 0xc4, 0x92, 0x5e, 0x46, 0x7b}};
- return GetKnownFolder(&folderid_downloads, aFile);
- }
+ case Win_Downloads:
+ {
+ // Defined in KnownFolders.h.
+ GUID folderid_downloads = {0x374de290, 0x123f, 0x4565, {0x91, 0x64,
+ 0x39, 0xc4, 0x92, 0x5e, 0x46, 0x7b}};
+ nsresult rv = GetKnownFolder(&folderid_downloads, aFile);
+ // On WinXP and 2k, there is no downloads folder, default
+ // to 'Desktop'.
+ if(NS_ERROR_FAILURE == rv)
+ {
+ rv = GetWindowsFolder(CSIDL_DESKTOP, aFile);
+ }
+ return rv;
+ }
case Win_Controls:
{
return GetWindowsFolder(CSIDL_CONTROLS, aFile);
}
case Win_Printers:
{
return GetWindowsFolder(CSIDL_PRINTERS, aFile);