зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
c8c42ead15
Коммит
bf3813bca3
|
@ -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")
|
||||
|
|
Загрузка…
Ссылка в новой задаче