Bug 1031527 - Remove dup fd from ParamTraits<MagicGrallocBufferHandle>::Read(). r...
[gecko.git] / browser / components / preferences / main.js
blobd851c4816ac0abf06f4ad68dc2997a48acc1e7a7
1 /* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3  * License, v. 2.0. If a copy of the MPL was not distributed with this
4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
7 XPCOMUtils.defineLazyModuleGetter(this, "DownloadsCommon",
8                                   "resource:///modules/DownloadsCommon.jsm");
10 var gMainPane = {
11   _pane: null,
13   /**
14    * Initialization of this.
15    */
16   init: function ()
17   {
18     this._pane = document.getElementById("paneMain");
20     // set up the "use current page" label-changing listener
21     this._updateUseCurrentButton();
22     window.addEventListener("focus", this._updateUseCurrentButton.bind(this), false);
24     this.updateBrowserStartupLastSession();
26     // Notify observers that the UI is now ready
27     Components.classes["@mozilla.org/observer-service;1"]
28               .getService(Components.interfaces.nsIObserverService)
29               .notifyObservers(window, "main-pane-loaded", null);
30   },
32   // HOME PAGE
34   /*
35    * Preferences:
36    *
37    * browser.startup.homepage
38    * - the user's home page, as a string; if the home page is a set of tabs,
39    *   this will be those URLs separated by the pipe character "|"
40    * browser.startup.page
41    * - what page(s) to show when the user starts the application, as an integer:
42    *
43    *     0: a blank page
44    *     1: the home page (as set by the browser.startup.homepage pref)
45    *     2: the last page the user visited (DEPRECATED)
46    *     3: windows and tabs from the last session (a.k.a. session restore)
47    *
48    *   The deprecated option is not exposed in UI; however, if the user has it
49    *   selected and doesn't change the UI for this preference, the deprecated
50    *   option is preserved.
51    */
53   syncFromHomePref: function ()
54   {
55     let homePref = document.getElementById("browser.startup.homepage");
57     // If the pref is set to about:home, set the value to "" to show the
58     // placeholder text (about:home title).
59     if (homePref.value.toLowerCase() == "about:home")
60       return "";
62     // If the pref is actually "", show about:blank.  The actual home page
63     // loading code treats them the same, and we don't want the placeholder text
64     // to be shown.
65     if (homePref.value == "")
66       return "about:blank";
68     // Otherwise, show the actual pref value.
69     return undefined;
70   },
72   syncToHomePref: function (value)
73   {
74     // If the value is "", use about:home.
75     if (value == "")
76       return "about:home";
78     // Otherwise, use the actual textbox value.
79     return undefined;
80   },
82   /**
83    * Sets the home page to the current displayed page (or frontmost tab, if the
84    * most recent browser window contains multiple tabs), updating preference
85    * window UI to reflect this.
86    */
87   setHomePageToCurrent: function ()
88   {
89     let homePage = document.getElementById("browser.startup.homepage");
90     let tabs = this._getTabsForHomePage();
91     function getTabURI(t) t.linkedBrowser.currentURI.spec;
93     // FIXME Bug 244192: using dangerous "|" joiner!
94     if (tabs.length)
95       homePage.value = tabs.map(getTabURI).join("|");
96   },
98   /**
99    * Displays a dialog in which the user can select a bookmark to use as home
100    * page.  If the user selects a bookmark, that bookmark's name is displayed in
101    * UI and the bookmark's address is stored to the home page preference.
102    */
103   setHomePageToBookmark: function ()
104   {
105     var rv = { urls: null, names: null };
106     document.documentElement.openSubDialog("chrome://browser/content/preferences/selectBookmark.xul",
107                                            "resizable", rv);  
108     if (rv.urls && rv.names) {
109       var homePage = document.getElementById("browser.startup.homepage");
111       // XXX still using dangerous "|" joiner!
112       homePage.value = rv.urls.join("|");
113     }
114   },
116   /**
117    * Switches the "Use Current Page" button between its singular and plural
118    * forms.
119    */
120   _updateUseCurrentButton: function () {
121     let useCurrent = document.getElementById("useCurrent");
123     let tabs = this._getTabsForHomePage();
124     if (tabs.length > 1)
125       useCurrent.label = useCurrent.getAttribute("label2");
126     else
127       useCurrent.label = useCurrent.getAttribute("label1");
129     // In this case, the button's disabled state is set by preferences.xml.
130     if (document.getElementById
131         ("pref.browser.homepage.disable_button.current_page").locked)
132       return;
134     useCurrent.disabled = !tabs.length
135   },
137   _getTabsForHomePage: function ()
138   {
139     var win;
140     var tabs = [];
141     if (document.documentElement.instantApply) {
142       const Cc = Components.classes, Ci = Components.interfaces;
143       // If we're in instant-apply mode, use the most recent browser window
144       var wm = Cc["@mozilla.org/appshell/window-mediator;1"]
145                  .getService(Ci.nsIWindowMediator);
146       win = wm.getMostRecentWindow("navigator:browser");
147     }
148     else {
149       win = window.opener;
150     }
152     if (win && win.document.documentElement
153                   .getAttribute("windowtype") == "navigator:browser") {
154       // We should only include visible & non-pinned tabs
155       tabs = win.gBrowser.visibleTabs.slice(win.gBrowser._numPinnedTabs);
156     }
158     return tabs;
159   },
161   /**
162    * Restores the default home page as the user's home page.
163    */
164   restoreDefaultHomePage: function ()
165   {
166     var homePage = document.getElementById("browser.startup.homepage");
167     homePage.value = homePage.defaultValue;
168   },
170   // DOWNLOADS
172   /*
173    * Preferences:
174    * 
175    * browser.download.useDownloadDir - bool
176    *   True - Save files directly to the folder configured via the
177    *   browser.download.folderList preference.
178    *   False - Always ask the user where to save a file and default to 
179    *   browser.download.lastDir when displaying a folder picker dialog.
180    * browser.download.dir - local file handle
181    *   A local folder the user may have selected for downloaded files to be
182    *   saved. Migration of other browser settings may also set this path.
183    *   This folder is enabled when folderList equals 2.
184    * browser.download.lastDir - local file handle
185    *   May contain the last folder path accessed when the user browsed
186    *   via the file save-as dialog. (see contentAreaUtils.js)
187    * browser.download.folderList - int
188    *   Indicates the location users wish to save downloaded files too.
189    *   It is also used to display special file labels when the default
190    *   download location is either the Desktop or the Downloads folder.
191    *   Values:
192    *     0 - The desktop is the default download location.
193    *     1 - The system's downloads folder is the default download location.
194    *     2 - The default download location is elsewhere as specified in
195    *         browser.download.dir.
196    * browser.download.downloadDir
197    *   deprecated.
198    * browser.download.defaultFolder
199    *   deprecated.
200    */
202   /**
203    * Enables/disables the folder field and Browse button based on whether a
204    * default download directory is being used.
205    */
206   readUseDownloadDir: function ()
207   {
208     var downloadFolder = document.getElementById("downloadFolder");
209     var chooseFolder = document.getElementById("chooseFolder");
210     var preference = document.getElementById("browser.download.useDownloadDir");
211     downloadFolder.disabled = !preference.value;
212     chooseFolder.disabled = !preference.value;
214     // don't override the preference's value in UI
215     return undefined;
216   },
217   
218   /**
219    * Displays a file picker in which the user can choose the location where
220    * downloads are automatically saved, updating preferences and UI in
221    * response to the choice, if one is made.
222    */
223   chooseFolder: function ()
224   {
225     const nsIFilePicker = Components.interfaces.nsIFilePicker;
226     const nsILocalFile = Components.interfaces.nsILocalFile;
228     let bundlePreferences = document.getElementById("bundlePreferences");
229     let title = bundlePreferences.getString("chooseDownloadFolderTitle");
230     let folderListPref = document.getElementById("browser.download.folderList");
231     let currentDirPref = this._indexToFolder(folderListPref.value); // file
232     let defDownloads = this._indexToFolder(1); // file
233     let fp = Components.classes["@mozilla.org/filepicker;1"].
234              createInstance(nsIFilePicker);
235     let fpCallback = function fpCallback_done(aResult) {
236       if (aResult == nsIFilePicker.returnOK) {
237         let file = fp.file.QueryInterface(nsILocalFile);
238         let downloadDirPref = document.getElementById("browser.download.dir");
240         downloadDirPref.value = file;
241         folderListPref.value = this._folderToIndex(file);
242         // Note, the real prefs will not be updated yet, so dnld manager's
243         // userDownloadsDirectory may not return the right folder after
244         // this code executes. displayDownloadDirPref will be called on
245         // the assignment above to update the UI.
246       }
247     }.bind(this);
249     fp.init(window, title, nsIFilePicker.modeGetFolder);
250     fp.appendFilters(nsIFilePicker.filterAll);
251     // First try to open what's currently configured
252     if (currentDirPref && currentDirPref.exists()) {
253       fp.displayDirectory = currentDirPref;
254     } // Try the system's download dir
255     else if (defDownloads && defDownloads.exists()) {
256       fp.displayDirectory = defDownloads;
257     } // Fall back to Desktop
258     else {
259       fp.displayDirectory = this._indexToFolder(0);
260     }
261     fp.open(fpCallback);
262   },
264   /**
265    * Initializes the download folder display settings based on the user's 
266    * preferences.
267    */
268   displayDownloadDirPref: function ()
269   {
270     var folderListPref = document.getElementById("browser.download.folderList");
271     var bundlePreferences = document.getElementById("bundlePreferences");
272     var downloadFolder = document.getElementById("downloadFolder");
273     var currentDirPref = document.getElementById("browser.download.dir");
275     // Used in defining the correct path to the folder icon.
276     var ios = Components.classes["@mozilla.org/network/io-service;1"]
277                         .getService(Components.interfaces.nsIIOService);
278     var fph = ios.getProtocolHandler("file")
279                  .QueryInterface(Components.interfaces.nsIFileProtocolHandler);
280     var iconUrlSpec;
281       
282     // Display a 'pretty' label or the path in the UI.
283     if (folderListPref.value == 2) {
284       // Custom path selected and is configured
285       downloadFolder.label = this._getDisplayNameOfFile(currentDirPref.value);
286       iconUrlSpec = fph.getURLSpecFromFile(currentDirPref.value);
287     } else if (folderListPref.value == 1) {
288       // 'Downloads'
289       // In 1.5, this pointed to a folder we created called 'My Downloads'
290       // and was available as an option in the 1.5 drop down. On XP this
291       // was in My Documents, on OSX it was in User Docs. In 2.0, we did
292       // away with the drop down option, although the special label was
293       // still supported for the folder if it existed. Because it was
294       // not exposed it was rarely used.
295       // With 3.0, a new desktop folder - 'Downloads' was introduced for
296       // platforms and versions that don't support a default system downloads
297       // folder. See nsDownloadManager for details. 
298       downloadFolder.label = bundlePreferences.getString("downloadsFolderName");
299       iconUrlSpec = fph.getURLSpecFromFile(this._indexToFolder(1));
300     } else {
301       // 'Desktop'
302       downloadFolder.label = bundlePreferences.getString("desktopFolderName");
303       iconUrlSpec = fph.getURLSpecFromFile(this._getDownloadsFolder("Desktop"));
304     }
305     downloadFolder.image = "moz-icon://" + iconUrlSpec + "?size=16";
306     
307     // don't override the preference's value in UI
308     return undefined;
309   },
311   /**
312    * Returns the textual path of a folder in readable form.
313    */
314   _getDisplayNameOfFile: function (aFolder)
315   {
316     // TODO: would like to add support for 'Downloads on Macintosh HD'
317     //       for OS X users.
318     return aFolder ? aFolder.path : "";
319   },
321   /**
322    * Returns the Downloads folder.  If aFolder is "Desktop", then the Downloads
323    * folder returned is the desktop folder; otherwise, it is a folder whose name
324    * indicates that it is a download folder and whose path is as determined by
325    * the XPCOM directory service via the download manager's attribute 
326    * defaultDownloadsDirectory.
327    *
328    * @throws if aFolder is not "Desktop" or "Downloads"
329    */
330   _getDownloadsFolder: function (aFolder)
331   {
332     switch (aFolder) {
333       case "Desktop":
334         var fileLoc = Components.classes["@mozilla.org/file/directory_service;1"]
335                                     .getService(Components.interfaces.nsIProperties);
336         return fileLoc.get("Desk", Components.interfaces.nsILocalFile);
337       break;
338       case "Downloads":
339         var dnldMgr = Components.classes["@mozilla.org/download-manager;1"]
340                                 .getService(Components.interfaces.nsIDownloadManager);
341         return dnldMgr.defaultDownloadsDirectory;
342       break;
343     }
344     throw "ASSERTION FAILED: folder type should be 'Desktop' or 'Downloads'";
345   },
347   /**
348    * Determines the type of the given folder.
349    *
350    * @param   aFolder
351    *          the folder whose type is to be determined
352    * @returns integer
353    *          0 if aFolder is the Desktop or is unspecified,
354    *          1 if aFolder is the Downloads folder,
355    *          2 otherwise
356    */
357   _folderToIndex: function (aFolder)
358   {
359     if (!aFolder || aFolder.equals(this._getDownloadsFolder("Desktop")))
360       return 0;
361     else if (aFolder.equals(this._getDownloadsFolder("Downloads")))
362       return 1;
363     return 2;
364   },
366   /**
367    * Converts an integer into the corresponding folder.
368    *
369    * @param   aIndex
370    *          an integer
371    * @returns the Desktop folder if aIndex == 0,
372    *          the Downloads folder if aIndex == 1,
373    *          the folder stored in browser.download.dir
374    */
375   _indexToFolder: function (aIndex)
376   {
377     switch (aIndex) {
378       case 0:
379         return this._getDownloadsFolder("Desktop");
380       case 1:
381         return this._getDownloadsFolder("Downloads");
382     }
383     var currentDirPref = document.getElementById("browser.download.dir");
384     return currentDirPref.value;
385   },
387   /**
388    * Returns the value for the browser.download.folderList preference.
389    */
390   getFolderListPref: function ()
391   {
392     var folderListPref = document.getElementById("browser.download.folderList");
393     switch (folderListPref.value) {
394       case 0: // Desktop
395       case 1: // Downloads
396         return folderListPref.value;
397       break;
398       case 2: // Custom
399         var currentDirPref = document.getElementById("browser.download.dir");
400         if (currentDirPref.value) {
401           // Resolve to a known location if possible. We are writing out
402           // to prefs on this call, so now would be a good time to do it.
403           return this._folderToIndex(currentDirPref.value);
404         }
405         return 0;
406       break;
407     }
408   },
410   /**
411    * Hide/show the "Show my windows and tabs from last time" option based
412    * on the value of the browser.privatebrowsing.autostart pref.
413    */
414   updateBrowserStartupLastSession: function()
415   {
416     let pbAutoStartPref = document.getElementById("browser.privatebrowsing.autostart");
417     let startupPref = document.getElementById("browser.startup.page");
418     let menu = document.getElementById("browserStartupPage");
419     let option = document.getElementById("browserStartupLastSession");
420     if (pbAutoStartPref.value) {
421       option.setAttribute("disabled", "true");
422       if (option.selected) {
423         menu.selectedItem = document.getElementById("browserStartupHomePage");
424       }
425     } else {
426       option.removeAttribute("disabled");
427       startupPref.updateElements(); // select the correct index in the startup menulist
428     }
429   }