Relanding bug 402252 - application details should be accessible from prefs UI. Original patch: r=Mano, ui-r=beltzner (over IRC), a1.9=damons; additionnal parts (strings): r+ui-r+a1.9=beltzner.

This commit is contained in:
florian@queze.net 2008-01-29 12:06:37 -08:00
Родитель c8c42ead15
Коммит bf3813bca3
4 изменённых файлов: 141 добавлений и 46 удалений

Просмотреть файл

@ -25,6 +25,7 @@
# Jeff Walden <jwalden+code@mit.edu>
# Asaf Romano <mozilla.mano@sent.com>
# Myk Melez <myk@mozilla.org>
# Florian Queze <florian@queze.net>
#
# Alternatively, the contents of this file may be used under the terms of
# either the GNU General Public License Version 2 or later (the "GPL"), or
@ -272,6 +273,25 @@ HandlerInfoWrapper.prototype = {
this.possibleApplicationHandlers.appendElement(aNewHandler, false);
},
removePossibleApplicationHandler: function(aHandler) {
var defaultApp = this.preferredApplicationHandler;
if (defaultApp && aHandler.equals(defaultApp)) {
// If the app we remove was the default app, we must make sure
// it won't be used anymore
this.alwaysAskBeforeHandling = true;
this.preferredApplicationHandler = null;
}
var handlers = this.possibleApplicationHandlers;
for (var i = 0; i < handlers.length; ++i) {
var handler = handlers.queryElementAt(i, Ci.nsIHandlerApp);
if (handler.equals(aHandler)) {
handlers.removeElementAt(i);
break;
}
}
},
get hasDefaultHandler() {
return this.wrappedHandlerInfo.hasDefaultHandler;
},
@ -566,6 +586,7 @@ var feedHandlerInfo = {
// methods its callers invoke, namely appendElement and nsIArray::enumerate.
this._possibleApplicationHandlers = {
_inner: [],
_removed: [],
QueryInterface: function(aIID) {
if (aIID.equals(Ci.nsIMutableArray) ||
@ -576,12 +597,25 @@ var feedHandlerInfo = {
throw Cr.NS_ERROR_NO_INTERFACE;
},
get length() {
return this._inner.length;
},
enumerate: function() {
return new ArrayEnumerator(this._inner);
},
appendElement: function(aHandlerApp, aWeak) {
this._inner.push(aHandlerApp);
},
removeElementAt: function(aIndex) {
this._removed.push(this._inner[aIndex]);
this._inner.splice(aIndex, 1);
},
queryElementAt: function(aIndex, aInterface) {
return this._inner[aIndex].QueryInterface(aInterface);
}
};
@ -748,11 +782,28 @@ var feedHandlerInfo = {
// Storage
// Changes to the preferred action and handler take effect immediately
// (we write them out to the preferences right as they happen), so we don't
// need to do anything when the controller calls store() after modifying
// the handler.
// (we write them out to the preferences right as they happen),
// so we when the controller calls store() after modifying the handlers,
// the only thing we need to store is the removal of possible handlers
// XXX Should we hold off on making the changes until this method gets called?
store: function() {},
store: function() {
for each (let app in this._possibleApplicationHandlers._removed) {
if (app instanceof Ci.nsILocalHandlerApp) {
let pref = this.element(PREF_FEED_SELECTED_APP);
var preferredAppFile = pref.value;
if (preferredAppFile) {
let preferredApp = getLocalHandlerApp(preferredAppFile);
if (app.equals(preferredApp))
pref.reset();
}
}
else {
app.QueryInterface(Ci.nsIWebContentHandlerInfo);
this._converterSvc.removeContentHandler(app.contentType, app.uri);
}
}
this._possibleApplicationHandlers._removed = [];
},
//**************************************************************************//
@ -1137,15 +1188,17 @@ var gApplicationsPane = {
case Ci.nsIHandlerInfo.useHelperApp:
var preferredApp = aHandlerInfo.preferredApplicationHandler;
var name;
if (preferredApp instanceof Ci.nsILocalHandlerApp)
return getDisplayNameForFile(preferredApp.executable);
name = getDisplayNameForFile(preferredApp.executable);
else
return preferredApp.name;
name = preferredApp.name;
return this._prefsBundle.getFormattedString("useApp", [name]);
case Ci.nsIHandlerInfo.handleInternally:
// For the feed type, handleInternally means live bookmarks.
if (aHandlerInfo.type == TYPE_MAYBE_FEED)
return this._prefsBundle.getFormattedString("liveBookmarksInApp",
return this._prefsBundle.getFormattedString("addLiveBookmarksInApp",
[this._brandShortName]);
// For other types, handleInternally looks like either useHelperApp
@ -1162,10 +1215,11 @@ var gApplicationsPane = {
// in the first place?
case Ci.nsIHandlerInfo.useSystemDefault:
return aHandlerInfo.defaultDescription;
return this._prefsBundle.getFormattedString("useDefault",
[aHandlerInfo.defaultDescription]);
case kActionUsePlugin:
return this._prefsBundle.getFormattedString("pluginName",
return this._prefsBundle.getFormattedString("usePluginIn",
[aHandlerInfo.plugin.name,
this._brandShortName]);
}
@ -1247,7 +1301,7 @@ var gApplicationsPane = {
menuPopup.removeChild(menuPopup.lastChild);
{
var askMenuItem = document.createElementNS(kXULNS, "menuitem");
var askMenuItem = document.createElement("menuitem");
askMenuItem.setAttribute("alwaysAsk", "true");
let label;
if (handlerInfo.type == TYPE_MAYBE_FEED)
@ -1261,28 +1315,45 @@ var gApplicationsPane = {
menuPopup.appendChild(askMenuItem);
}
// Create a menu item for saving to disk.
// Note: this option isn't available to protocol types, since we don't know
// what it means to save a URL having a certain scheme to disk, nor is it
// available to feeds, since the feed code doesn't implement the capability.
if ((handlerInfo.wrappedHandlerInfo instanceof Ci.nsIMIMEInfo) &&
handlerInfo.type != TYPE_MAYBE_FEED) {
var saveMenuItem = document.createElement("menuitem");
saveMenuItem.setAttribute("action", Ci.nsIHandlerInfo.saveToDisk);
let label = this._prefsBundle.getString("saveFile");
saveMenuItem.setAttribute("label", label);
saveMenuItem.setAttribute("tooltiptext", label);
saveMenuItem.setAttribute(APP_ICON_ATTR_NAME, "save");
menuPopup.appendChild(saveMenuItem);
}
// If this is the feed type, add a Live Bookmarks item.
if (handlerInfo.type == TYPE_MAYBE_FEED) {
var internalMenuItem = document.createElementNS(kXULNS, "menuitem");
var internalMenuItem = document.createElement("menuitem");
internalMenuItem.setAttribute("action", Ci.nsIHandlerInfo.handleInternally);
let label = this._prefsBundle.getFormattedString("liveBookmarksInApp",
let label = this._prefsBundle.getFormattedString("addLiveBookmarksInApp",
[this._brandShortName]);
internalMenuItem.setAttribute("label", label);
internalMenuItem.setAttribute("tooltiptext", label);
internalMenuItem.setAttribute(APP_ICON_ATTR_NAME, "feed");
menuPopup.appendChild(internalMenuItem);
// Add a separator to distinguish these items from the helper app items
// that follow them.
let menuItem = document.createElementNS(kXULNS, "menuseparator");
menuPopup.appendChild(menuItem);
}
// Add a separator to distinguish these items from the helper app items
// that follow them.
let menuItem = document.createElement("menuseparator");
menuPopup.appendChild(menuItem);
// Create a menu item for the OS default application, if any.
if (handlerInfo.hasDefaultHandler) {
var defaultMenuItem = document.createElementNS(kXULNS, "menuitem");
var defaultMenuItem = document.createElement("menuitem");
defaultMenuItem.setAttribute("action", Ci.nsIHandlerInfo.useSystemDefault);
defaultMenuItem.setAttribute("label", handlerInfo.defaultDescription);
let label = this._prefsBundle.getFormattedString("useDefault",
[handlerInfo.defaultDescription]);
defaultMenuItem.setAttribute("label", label);
defaultMenuItem.setAttribute("tooltiptext", handlerInfo.defaultDescription);
defaultMenuItem.setAttribute("image", this._getIconURLForSystemDefault(handlerInfo));
@ -1298,13 +1369,14 @@ var gApplicationsPane = {
if (!this.isValidHandlerApp(possibleApp))
continue;
let menuItem = document.createElementNS(kXULNS, "menuitem");
let menuItem = document.createElement("menuitem");
menuItem.setAttribute("action", Ci.nsIHandlerInfo.useHelperApp);
let label;
if (possibleApp instanceof Ci.nsILocalHandlerApp)
label = getDisplayNameForFile(possibleApp.executable);
else
label = possibleApp.name;
label = this._prefsBundle.getFormattedString("useApp", [label]);
menuItem.setAttribute("label", label);
menuItem.setAttribute("tooltiptext", label);
menuItem.setAttribute("image", this._getIconURLForHandlerApp(possibleApp));
@ -1319,9 +1391,9 @@ var gApplicationsPane = {
// Create a menu item for the plugin.
if (handlerInfo.plugin) {
var pluginMenuItem = document.createElementNS(kXULNS, "menuitem");
var pluginMenuItem = document.createElement("menuitem");
pluginMenuItem.setAttribute("action", kActionUsePlugin);
let label = this._prefsBundle.getFormattedString("pluginName",
let label = this._prefsBundle.getFormattedString("usePluginIn",
[handlerInfo.plugin.name,
this._brandShortName]);
pluginMenuItem.setAttribute("label", label);
@ -1339,27 +1411,22 @@ var gApplicationsPane = {
if (handlerInfo.type != executableType)
#endif
{
let menuItem = document.createElementNS(kXULNS, "menuitem");
let menuItem = document.createElement("menuitem");
menuItem.setAttribute("oncommand", "gApplicationsPane.chooseApp(event)");
let label = this._prefsBundle.getString("chooseApp");
let label = this._prefsBundle.getString("useOtherApp");
menuItem.setAttribute("label", label);
menuItem.setAttribute("tooltiptext", label);
menuPopup.appendChild(menuItem);
}
// Create a menu item for saving to disk.
// Note: this option isn't available to protocol types, since we don't know
// what it means to save a URL having a certain scheme to disk, nor is it
// available to feeds, since the feed code doesn't implement the capability.
if ((handlerInfo.wrappedHandlerInfo instanceof Ci.nsIMIMEInfo) &&
handlerInfo.type != TYPE_MAYBE_FEED) {
var saveMenuItem = document.createElementNS(kXULNS, "menuitem");
saveMenuItem.setAttribute("action", Ci.nsIHandlerInfo.saveToDisk);
let label = this._prefsBundle.getString("saveFile");
saveMenuItem.setAttribute("label", label);
saveMenuItem.setAttribute("tooltiptext", label);
saveMenuItem.setAttribute(APP_ICON_ATTR_NAME, "save");
menuPopup.appendChild(saveMenuItem);
// Create a menu item for managing applications.
if (possibleAppMenuItems.length) {
let menuItem = document.createElement("menuseparator");
menuPopup.appendChild(menuItem);
menuItem = document.createElement("menuitem");
menuItem.setAttribute("oncommand", "gApplicationsPane.manageApp(event)");
menuItem.setAttribute("label", this._prefsBundle.getString("manageApp"));
menuPopup.appendChild(menuItem);
}
// Select the item corresponding to the preferred action. If the always
@ -1553,6 +1620,28 @@ var gApplicationsPane = {
}
},
manageApp: function(aEvent) {
// Don't let the normal "on select action" handler get this event,
// as we handle it specially ourselves.
aEvent.stopPropagation();
var typeItem = this._list.selectedItem;
var handlerInfo = this._handledTypes[typeItem.type];
document.documentElement.openSubDialog("chrome://browser/content/preferences/applicationManager.xul",
"", handlerInfo);
// Rebuild the actions menu so that we revert to the previous selection,
// or "Always ask" if the previous default application has been removed
this.rebuildActionsMenu();
// update the richlistitem too. Will be visible when selecting another row
typeItem.setAttribute("actionDescription",
this._describePreferredAction(handlerInfo));
typeItem.setAttribute("actionIcon",
this._getIconURLForPreferredAction(handlerInfo));
},
chooseApp: function(aEvent) {
// Don't let the normal "on select action" handler get this event,
// as we handle it specially ourselves.

Просмотреть файл

@ -99,8 +99,8 @@
accesskey="&typeColumn.accesskey;" persist="sortDirection"
flex="1" onclick="gApplicationsPane.sort(event);"
sortDirection="ascending"/>
<treecol id="actionColumn" label="&actionColumn.label;" value="action"
accesskey="&actionColumn.accesskey;" persist="sortDirection"
<treecol id="actionColumn" label="&actionColumn2.label;" value="action"
accesskey="&actionColumn2.accesskey;" persist="sortDirection"
flex="1" onclick="gApplicationsPane.sort(event);"/>
</listheader>
</richlistbox>

Просмотреть файл

@ -1,8 +1,8 @@
<!ENTITY typeColumn.label "Content Type">
<!ENTITY typeColumn.accesskey "T">
<!ENTITY actionColumn.label "Application">
<!ENTITY actionColumn.accesskey "A">
<!ENTITY actionColumn2.label "Action">
<!ENTITY actionColumn2.accesskey "A">
<!ENTITY focusSearch1.key "f">
<!ENTITY focusSearch2.key "k">

Просмотреть файл

@ -47,21 +47,27 @@ chooseDownloadFolderTitle=Choose Download Folder:
fileEnding=%S file
saveFile=Save File
chooseApp=Choose application…
# LOCALIZATION NOTE (useApp, useDefault): %S = Application name
useApp=Use %S
useDefault=Use %S (default)
useOtherApp=Use other…
fpTitleChooseApp=Select Helper Application
manageApp=Application Details…
webFeed=Web Feed
videoPodcastFeed=Video Podcast
audioPodcastFeed=Podcast
alwaysAsk=Always ask
# LOCALIZATION NOTE (pluginName):
# LOCALIZATION NOTE (usePluginIn):
# %1$S = plugin name (for example "QuickTime Plugin-in 7.2")
# %2$S = brandShortName from brand.properties (for example "Minefield")
pluginName=%S (in %S)
usePluginIn=Use %S (in %S)
# LOCALIZATION NOTE (previewInApp, liveBookmarksInApp): %S = brandShortName
# LOCALIZATION NOTE (previewInApp, addLiveBookmarksInApp): %S = brandShortName
previewInApp=Preview in %S
liveBookmarksInApp=Live Bookmarks in %S
addLiveBookmarksInApp=Add Live Bookmarks in %S
# LOCALIZATION NOTE (typeDescriptionWithType):
# %1$S = type description (for example "Portable Document Format")