Bug 274374 - Landing Mac Shell Servie (default browser, set desktup backgorund and mail integration support). patches from ben and me. r=jhpedemonte/josh/mconnor, a=shaver.

This commit is contained in:
mozilla.mano%sent.com 2005-06-23 02:25:06 +00:00
Родитель a318dbaf73
Коммит ed0bc04db8
27 изменённых файлов: 884 добавлений и 75 удалений

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

@ -52,7 +52,7 @@ ifdef MOZ_USE_OFFICIAL_BRANDING
DEFINES += -DMOZ_USE_OFFICIAL_BRANDING
endif
ifneq (,$(filter windows gtk2, $(MOZ_WIDGET_TOOLKIT)))
ifneq (,$(filter windows gtk2 mac cocoa, $(MOZ_WIDGET_TOOLKIT)))
DEFINES += -DHAVE_SHELL_SERVICE=1
endif

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

@ -93,10 +93,10 @@
label="&sendImageCmd.label;"
accesskey="&sendImageCmd.accesskey;"
oncommand="gContextMenu.sendImage();"/>
<menuitem id="context-setWallpaper"
label="&setWallpaperCmd.label;"
accesskey="&setWallpaperCmd.accesskey;"
oncommand="gContextMenu.setWallpaper();"/>
<menuitem id="context-setDesktopBackground"
label="&setDesktopBackgroundCmd.label;"
accesskey="&setDesktopBackgroundCmd.accesskey;"
oncommand="gContextMenu.setDesktopBackground();"/>
<!--XXXBlake XUL sucks! We need autocheck for menuitems. -->
<menuitem id="context-blockimage" class="menuitem-iconic"

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

@ -383,7 +383,7 @@
>
<menuitem label="&search.label;" accesskey="&search.accesskey;"
key="key_search" command="Tools:Search"/>
#ifdef XP_WIN
#ifdef HAVE_SHELL_SERVICE
<menuseparator/>
<menuitem label="&mailButton.readMail.label;"
accesskey="&mailButton.readMail.accesskey;"

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

@ -3961,19 +3961,23 @@ nsContextMenu.prototype = {
this.showItem( "context-viewinfo", !( this.inDirList || this.onImage || this.isContentSelected || this.onLink || this.onTextInput ) );
this.showItem( "context-sep-properties", !( this.inDirList || this.isContentSelected || this.onTextInput ) );
// Set As Wallpaper depends on whether an image was clicked on, and only works if we have a shell service.
var haveSetWallpaper = false;
// Set as Desktop background depends on whether an image was clicked on,
// and only works if we have a shell service.
var haveSetDesktopBackground = false;
#ifdef HAVE_SHELL_SERVICE
// Only enable set as wallpaper if we can get the shell service.
// Only enable Set as Desktop Background if we can get the shell service.
var shell = getShellService();
if (shell)
haveSetWallpaper = true;
haveSetDesktopBackground = true;
#endif
this.showItem( "context-setWallpaper", haveSetWallpaper && this.onImage );
this.showItem( "context-setDesktopBackground", haveSetDesktopBackground && this.onImage );
if( haveSetWallpaper && this.onImage )
// Disable the Set As Wallpaper menu item if we're still trying to load the image
this.setItemAttr( "context-setWallpaper", "disabled", (("complete" in this.target) && !this.target.complete) ? "true" : null );
if( haveSetDesktopBackground && this.onImage )
// Disable the Set as Desktop Background menu item if we're still trying
// to load the image
this.setItemAttr( "context-setDesktopBackground", "disabled",
(("complete" in this.target) && !this.target.complete) ?
"true" : null );
// View Image depends on whether an image was clicked on.
this.showItem( "context-viewimage", this.onImage && !this.onStandaloneImage );
@ -4347,11 +4351,28 @@ nsContextMenu.prototype = {
urlSecurityCheck( this.bgImageURL, document )
openUILink( this.bgImageURL, e );
},
setWallpaper: function() {
setDesktopBackground: function() {
// Confirm since it's annoying if you hit this accidentally.
openDialog("chrome://browser/content/setWallpaper.xul", "",
const kDesktopBackgroundURL =
"chrome://browser/content/setDesktopBackground.xul";
#ifdef XP_MACOSX
var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
.getService(Components.interfaces.nsIWindowMediator);
var dbWin = wm.getMostRecentWindow("Shell:SetDesktopBackground");
if (dbWin) {
dbWin.gSetBackground.init(this.target);
dbWin.focus();
}
else {
openDialog(kDesktopBackgroundURL, "",
"centerscreen,chrome,dialog=no,dependent,resizable=no",
this.target);
}
#else
openDialog(kDesktopBackgroundURL, "",
"centerscreen,chrome,dialog,modal,dependent",
this.target);
#endif
},
// Save URL of clicked-on frame.
saveFrame : function () {
@ -5526,14 +5547,14 @@ var MailIntegration = {
{
var shell = getShellService();
if (shell)
shell.openPreferredApplication(Components.interfaces.nsIShellService.APPLICATION_MAIL);
shell.openApplication(Components.interfaces.nsIShellService.APPLICATION_MAIL);
},
readNews: function ()
{
var shell = getShellService();
if (shell)
shell.openPreferredApplication(Components.interfaces.nsIShellService.APPLICATION_NEWS);
shell.openApplication(Components.interfaces.nsIShellService.APPLICATION_NEWS);
},
updateUnreadCount: function ()

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

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

@ -366,7 +366,7 @@ function getShellService()
try {
shell = Components.classes["@mozilla.org/browser/shell-service;1"]
.getService(Components.interfaces.nsIShellService);
} catch (e) {}
} catch (e) {dump("*** e = " + e + "\n");}
return shell;
}

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

@ -28,7 +28,6 @@ browser.jar:
* content/browser/sanitize.xul (content/sanitize.xul)
* content/browser/search.xml (content/search.xml)
* content/browser/searchbarBindings.css (content/searchbarBindings.css)
* content/browser/setWallpaper.xul (content/setWallpaper.xul)
* content/browser/utilityOverlay.js (content/utilityOverlay.js)
* content/browser/web-panels.js (content/web-panels.js)
* content/browser/web-panels.xul (content/web-panels.xul)

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

@ -18,6 +18,8 @@ REQUIRES = \
string \
pref \
rdf \
uriloader \
webbrowserpersist \
intl \
necko \
nkcache \

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

@ -142,6 +142,11 @@ static const nsModuleComponentInfo components[] =
nsIEProfileMigratorConstructor },
#elif defined(XP_MACOSX)
{ "Browser Shell Service",
NS_SHELLSERVICE_CID,
NS_SHELLSERVICE_CONTRACTID,
nsMacShellServiceConstructor },
{ "Safari Profile Migrator",
NS_SAFARIPROFILEMIGRATOR_CID,
NS_BROWSERPROFILEMIGRATOR_CONTRACTID_PREFIX "safari",

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

@ -43,6 +43,6 @@ include $(DEPTH)/config/autoconf.mk
include $(topsrcdir)/config/rules.mk
ifneq (,$(filter windows gtk2, $(MOZ_WIDGET_TOOLKIT)))
ifneq (,$(filter windows gtk2 mac cocoa, $(MOZ_WIDGET_TOOLKIT)))
DEFINES += -DHAVE_SHELL_SERVICE=1
endif

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

@ -0,0 +1,236 @@
# ***** BEGIN LICENSE BLOCK *****
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
#
# The contents of this file are subject to the Mozilla Public License Version
# 1.1 (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
# http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
# for the specific language governing rights and limitations under the
# License.
#
# The Original Code is Mozilla Firebird about dialog.
#
# The Initial Developer of the Original Code is
# Blake Ross (blake@blakeross.com).
# Portions created by the Initial Developer are Copyright (C) 2002
# the Initial Developer. All Rights Reserved.
#
# Contributor(s):
# Blake Ross <blake@blakeross.com>
# Ben Goodger <ben@mozilla.org>
#
# 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
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
# in which case the provisions of the GPL or the LGPL are applicable instead
# of those above. If you wish to allow use of your version of this file only
# under the terms of either the GPL or the LGPL, and not to allow others to
# use your version of this file under the terms of the MPL, indicate your
# decision by deleting the provisions above and replace them with the notice
# and other provisions required by the LGPL or the GPL. If you do not delete
# the provisions above, a recipient may use your version of this file under
# the terms of any one of the MPL, the GPL or the LGPL.
#
# ***** END LICENSE BLOCK *****
const kXUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
const kIShellService = Components.interfaces.nsIShellService;
const kIMacShellService = Components.interfaces.nsIMacShellService;
var gSetBackground = {
_position : kIShellService.BACKGROUND_STRETCH,
_monitor : null,
_image : null,
_backgroundColor : 0,
#ifndef XP_MACOSX
// Converts a color string in the format "#RRGGBB" to an integer.
_hexStringToLong: function (aString)
{
return parseInt(aString.substring(1,3), 16) << 16 |
parseInt(aString.substring(3,5), 16) << 8 |
parseInt(aString.substring(5,7), 16);
},
_rgbToHex(aR, aG, aB)
{
var rHex = aR.toString(16).toUpperCase();
var gHex = aG.toString(16).toUpperCase();
var bHex = aB.toString(16).toUpperCase();
if (rHex.length == 1) rHex ='0' + rHex;
if (gHex.length == 1) gHex ='0' + gHex;
if (bHex.length == 1) bHex ='0' + bHex;
return '#' + rHex + gHex + bHex;
},
#endif
get _shell()
{
return Components.classes["@mozilla.org/browser/shell-service;1"]
.getService(Components.interfaces.nsIShellService);
},
load: function ()
{
this._monitor = document.getElementById("monitor");
#ifdef XP_MACOSX
document.documentElement.getButton("accept").hidden = true;
#endif
this.init(window.arguments[0]);
},
init: function (aImage)
{
this._image = aImage;
#ifndef XP_MACOSX
this._initColor();
var position = parseInt(document.getElementById("menuPosition").value);
#else
// Make sure to reset the button state in case the user has already
// set an image as their desktop background.
var setDesktopBackground = document.getElementById("setDesktopBackground");
setDesktopBackground.hidden = false;
var bundle = document.getElementById("backgroundBundle");
setDesktopBackground.label = bundle.getString("DesktopBackgroundSet");
setDesktopBackground.disabled = false;
var showDesktopPreferences = document.getElementById("showDesktopPreferences");
showDesktopPreferences.hidden = true;
var position = kIShellService.BACKGROUND_STRETCH;
#endif
this.updatePosition(position);
},
#ifndef XP_MACOSX
_initColor: function ()
{
var color = this._shell.desktopBackgroundColor;
const rMask = 4294901760;
const gMask = 65280;
const bMask = 255;
var r = (color & rMask) >> 16;
var g = (color & gMask) >> 8;
var b = (color & bMask);
this._backgroundColor = this._rgbToHex(r, g, b);
var colorpicker = document.getElementById("desktopColor");
colorpicker.color = this._rgbToHex(r, g, b);
},
#endif
observe: function (aSubject, aTopic, aData)
{
if (aTopic == "shell:desktop-background-changed") {
var setDesktopBackground = document.getElementById("setDesktopBackground");
setDesktopBackground.hidden = true;
var showDesktopPreferences = document.getElementById("showDesktopPreferences");
showDesktopPreferences.hidden = false;
var os = Components.classes["@mozilla.org/observer-service;1"]
.getService(Components.interfaces.nsIObserverService);
os.removeObserver(this, "shell:desktop-background-changed");
}
},
#ifdef XP_MACOSX
setDesktopBackground: function()
{
var os = Components.classes["@mozilla.org/observer-service;1"]
.getService(Components.interfaces.nsIObserverService);
os.addObserver(this, "shell:desktop-background-changed", false);
var bundle = document.getElementById("backgroundBundle");
var setDesktopBackground = document.getElementById("setDesktopBackground");
setDesktopBackground.disabled = true;
setDesktopBackground.label = bundle.getString("DesktopBackgroundDownloading");
this._shell.setDesktopBackground(this._image, this._position);
},
showDesktopPrefs: function()
{
this._shell.openApplication(kIMacShellService.APPLICATION_DESKTOP);
},
#else
setDesktopBackground: function ()
{
this._shell.setDesktopBackground(this._image, this._position);
this._shell.desktopBackgroundColor = this._hexStringToLong(this._backgroundColor);
document.persist("menuPosition", "value");
},
#endif
updateColor: function (color)
{
#ifndef XP_MACOSX
this._backgroundColor = color;
if (this._position != kIShellService.BACKGROUND_TILE)
this._monitor.style.backgroundColor = color;
#endif
},
updatePosition: function (aPosition)
{
if (this._monitor.childNodes.length)
this._monitor.removeChild(this._monitor.firstChild);
this._position = aPosition;
if (this._position == kIShellService.BACKGROUND_TILE)
this._tileImage();
else if (this._position == kIShellService.BACKGROUND_STRETCH)
this._stretchImage();
else
this._centerImage();
},
_createImage: function ()
{
var img = document.createElementNS(kXULNS, "image");
img.setAttribute("src", this._image.src);
return img;
},
_stretchImage: function ()
{
this.updateColor(this._backgroundColor);
var img = this._createImage();
img.width = parseInt(this._monitor.style.width);
img.height = parseInt(this._monitor.style.height);
this._monitor.appendChild(img);
},
_tileImage: function ()
{
var bundle = document.getElementById("backgroundBundle");
this._monitor.style.backgroundColor = "white";
var text = document.createElementNS(kXULNS, "label");
text.setAttribute("id", "noPreviewAvailable");
text.setAttribute("value", bundle.getString("DesktopBackgroundNoPreview"));
this._monitor.appendChild(text);
},
_centerImage: function ()
{
this.updateColor(this._backgroundColor);
var img = this._createImage();
var width = this._image.width * this._monitor.boxObject.width / screen.width;
var height = this._image.height * this._monitor.boxObject.height / screen.height;
img.width = Math.floor(width);
img.height = Math.floor(height);
this._monitor.appendChild(img);
}
};

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

@ -0,0 +1,122 @@
<?xml version="1.0"?> <!-- -*- Mode: HTML -*- -->
# ***** BEGIN LICENSE BLOCK *****
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
#
# The contents of this file are subject to the Mozilla Public License Version
# 1.1 (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
# http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
# for the specific language governing rights and limitations under the
# License.
#
# The Original Code is Mozilla Firebird about dialog.
#
# The Initial Developer of the Original Code is
# Blake Ross (blake@blakeross.com).
# Portions created by the Initial Developer are Copyright (C) 2002
# the Initial Developer. All Rights Reserved.
#
# Contributor(s):
# Blake Ross <blake@blakeross.com>
# Ben Goodger <ben@mozilla.org>
#
# 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
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
# in which case the provisions of the GPL or the LGPL are applicable instead
# of those above. If you wish to allow use of your version of this file only
# under the terms of either the GPL or the LGPL, and not to allow others to
# use your version of this file under the terms of the MPL, indicate your
# decision by deleting the provisions above and replace them with the notice
# and other provisions required by the LGPL or the GPL. If you do not delete
# the provisions above, a recipient may use your version of this file under
# the terms of any one of the MPL, the GPL or the LGPL.
#
# ***** END LICENSE BLOCK ***** -->
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<?xml-stylesheet href="chrome://browser/content/browser.css" type="text/css"?>
<!DOCTYPE dialog SYSTEM "chrome://browser/locale/setDesktopBackground.dtd">
#ifdef XP_MACOSX
<?xul-overlay href="chrome://browser/content/macBrowserOverlay.xul"?>
#endif
<dialog xmlns:html="http://www.w3.org/1999/xhtml"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
id="aboutDialog"
windowtype="Shell:SetDesktopBackground"
#ifndef XP_MACOSX
buttons="accept,cancel"
#else
buttons="accept"
#endif
buttonlabelaccept="&setDesktopBackground.title;"
onload="gSetBackground.load();"
ondialogaccept="gSetBackground.setDesktopBackground();"
title="&setDesktopBackground.title;"
style="width: 30em;">
<stringbundle id="backgroundBundle"
src="chrome://browser/locale/shellservice.properties"/>
<script type="application/x-javascript"
src="chrome://browser/content/utilityOverlay.js"/>
<script type="application/x-javascript"
src="chrome://browser/content/setDesktopBackground.js"/>
#ifndef XP_MACOSX
<hbox align="center" id="foo">
<label value="&position.label;"/>
<menulist id="menuPosition"
label="&position.label;"
oncommand="gSetBackground.updatePosition(parseInt(this.value));">
<menupopup>
<menuitem label="&center.label;" value="3"/>
<menuitem label="&tile.label;" value="1"/>
<menuitem label="&stretch.label;" value="2"/>
</menupopup>
</menulist>
<spacer flex="1"/>
<label value="&color.label;"/>
<colorpicker id="desktopColor"
type="button"
onchange="gSetBackground.updateColor(this.color);"/>
</hbox>
#endif
<groupbox align="center">
<caption label="&preview.label;"/>
<stack>
<vbox id="monitor" align="center" pack="center"
style="width: 153px !important; height: 114px !important; overflow: hidden;"
left="13" top="18"/>
<!-- XXXben - this needs to be skinable - on MacOSX we want to draw a
bucket, not a monitor -->
<image src="chrome://browser/content/monitor.png"/>
</stack>
</groupbox>
#ifdef XP_MACOSX
<separator/>
<hbox align="right">
<button id="setDesktopBackground"
label="&setDesktopBackground.title;"
oncommand="gSetBackground.setDesktopBackground();"/>
<button id="showDesktopPreferences"
label="&openDesktopPrefs.label;"
oncommand="gSetBackground.showDesktopPrefs();"
hidden="true"/>
</hbox>
#endif
#ifdef XP_MACOSX
#include ../../../base/content/browserMountPoints.inc
#endif
</dialog>

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

@ -1,2 +1,7 @@
toolkit.jar:
content/global/dummyWindow.xul (content/dummyWindow.xul)
browser.jar:
* content/browser/setDesktopBackground.xul (content/setDesktopBackground.xul)
* content/browser/setDesktopBackground.js (content/setDesktopBackground.js)

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

@ -51,4 +51,8 @@ ifeq ($(OS_ARCH),WINNT)
XPIDLSRCS += nsIWindowsShellService.idl
endif
ifneq (,$(filter mac cocoa,$(MOZ_WIDGET_TOOLKIT)))
XPIDLSRCS += nsIMacShellService.idl
endif
include $(topsrcdir)/config/rules.mk

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

@ -0,0 +1,47 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Shell Service.
*
* The Initial Developer of the Original Code is mozilla.org.
* Portions created by the Initial Developer are Copyright (C) 2005
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Ben Goodger <ben@mozilla.org> (Original Author)
*
* 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
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsIShellService.idl"
[scriptable, uuid(7f8ca08e-1df4-4735-86e9-50dedb48e5e8)]
interface nsIMacShellService : nsIShellService
{
const long APPLICATION_KEYCHAIN_ACCESS = 2;
const long APPLICATION_NETWORK = 3;
const long APPLICATION_DESKTOP = 4;
};

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

@ -39,7 +39,7 @@
interface nsIDOMElement;
[scriptable, uuid(7d8a7a34-f492-43c0-9657-ec7dbbeba236)]
[scriptable, uuid(d6f62053-3769-46f6-bd2b-0a1440d6c394)]
interface nsIShellService : nsISupports
{
/**
@ -76,9 +76,10 @@ interface nsIShellService : nsISupports
/**
* Flags for positioning/sizing of the Desktop Background image.
*/
const long BACKGROUND_TILE = 0x00;
const long BACKGROUND_STRETCH = 0x01;
const long BACKGROUND_CENTER = 0x02;
const long BACKGROUND_TILE = 1;
const long BACKGROUND_STRETCH = 2;
const long BACKGROUND_CENTER = 3;
const long BACKGROUND_FILL = 4;
/**
* Sets the desktop background image using either the HTML <IMG>
@ -92,16 +93,18 @@ interface nsIShellService : nsISupports
void setDesktopBackground(in nsIDOMElement aElement, in long aPosition);
/**
* Constants identifying preferred applications that can be opened with
* openPreferredApplication.
* Constants identifying applications that can be opened with
* openApplication.
*/
const long APPLICATION_MAIL = 0;
const long APPLICATION_NEWS = 1;
/**
* Opens the preferred application specified.
* Opens the application specified. If more than one application of the
* given type is available on the system, the default or "preferred"
* application is used.
*/
void openPreferredApplication(in long aApplication);
void openApplication(in long aApplication);
/**
* The desktop background color, visible when no background image is

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

@ -48,6 +48,8 @@ MOZILLA_INTERNAL_API = 1
REQUIRES = \
xpcom \
string \
uriloader \
webbrowserpersist \
dom \
intl \
necko \

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

@ -488,7 +488,7 @@ nsGNOMEShellService::SetDesktopBackgroundColor(PRUint32 aColor)
}
NS_IMETHODIMP
nsGNOMEShellService::OpenPreferredApplication(PRInt32 aApplication)
nsGNOMEShellService::OpenApplication(PRInt32 aApplication)
{
nsCAutoString scheme;
if (aApplication == APPLICATION_MAIL)

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

@ -14,11 +14,13 @@
*
* The Original Code is Shell Service.
*
* The Initial Developer of the Original Code is mozilla.org.
* The Initial Developer of the Original Code is Ben Goodger.
* Portions created by the Initial Developer are Copyright (C) 2004
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Ben Goodger <ben@mozilla.org> (Original Author)
* Asaf Romano <mozilla.mano@sent.com>
*
* 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
@ -34,23 +36,135 @@
*
* ***** END LICENSE BLOCK ***** */
#include "nsCOMPtr.h"
#include "nsDirectoryServiceDefs.h"
#include "nsIDOM3Node.h"
#include "nsIDOMElement.h"
#include "nsIDOMHTMLImageElement.h"
#include "nsIObserverService.h"
#include "nsIPrefService.h"
#include "nsIServiceManager.h"
#include "nsIStringBundle.h"
#include "nsIURL.h"
#include "nsIWebBrowserPersist.h"
#include "nsMacShellService.h"
#include "nsNetUtil.h"
#include "nsShellService.h"
#include "nsString.h"
NS_IMPL_ISUPPORTS1(nsMacShellService, nsIShellService)
#include <CoreFoundation/CoreFoundation.h>
#include <Carbon/Carbon.h>
#define NETWORK_PREFPANE NS_LITERAL_CSTRING("/System/Library/PreferencePanes/Network.prefPane")
#define DESKTOP_PREFPANE NS_LITERAL_CSTRING("/System/Library/PreferencePanes/DesktopScreenEffectsPref.prefPane")
// These Launch Services functions are undocumented. We're using them since they're
// the only way to set the default opener for URLs / file extensions.
extern "C" {
// Returns the CFURL for application currently set as the default opener for the
// given URL scheme. appURL must be released by the caller.
extern OSStatus _LSCopyDefaultSchemeHandlerURL(CFStringRef scheme, CFURLRef *appURL);
extern OSStatus _LSSetDefaultSchemeHandlerURL(CFStringRef scheme, CFURLRef appURL);
extern OSStatus _LSSaveAndRefresh(void);
// Callers should pass 0 as both inType and inCreator in order to set the default opener
// without modifing those.
extern OSStatus _LSSetWeakBindingForType(OSType inType,
OSType inCreator,
CFStringRef inExtension,
LSRolesMask inRoleMask,
const FSRef* inBindingRef);
}
NS_IMPL_ISUPPORTS3(nsMacShellService, nsIMacShellService, nsIShellService, nsIWebProgressListener)
NS_IMETHODIMP
nsMacShellService::IsDefaultBrowser(PRBool aStartupCheck, PRBool* aIsDefaultBrowser)
{
return NS_OK;
*aIsDefaultBrowser = PR_TRUE;
// Since neither Launch Services nor Internet Config actually differ between
// bundles which have the same bundle identifier (That is, if we set our
// bundle's URL as the default handler, Launch Service might return the
// URL of another firefox bundle as the defualt http handler), we are
// comparing the bundles' identifiers rather than their URLs.
CFStringRef firefoxID = ::CFBundleGetIdentifier(CFBundleGetMainBundle());
if (!firefoxID) {
// CFBundleGetIdentifier is expected to return NULL only if the specified
// bundle doesn't have a bundle identifier in its plist. In this case, that
// means a failure, since our bundle does have an identifier.
return NS_ERROR_FAILURE;
}
::CFRetain(firefoxID);
// Get the default http handler URL
CFURLRef defaultBrowserURL;
OSStatus err = ::_LSCopyDefaultSchemeHandlerURL(CFSTR("http"),
&defaultBrowserURL);
nsresult rv = NS_ERROR_FAILURE;
if (err == noErr) {
// Get a reference to the bundle (based on its URL)
CFBundleRef defaultBrowserBundle = ::CFBundleCreate(NULL,
defaultBrowserURL);
if (defaultBrowserBundle) {
CFStringRef defaultBrowserID = ::CFBundleGetIdentifier(defaultBrowserBundle);
if (defaultBrowserID) {
::CFRetain(defaultBrowserID);
// and compare it to our bundle identifier
*aIsDefaultBrowser = ::CFStringCompare(firefoxID, defaultBrowserID, 0)
== kCFCompareEqualTo;
::CFRelease(defaultBrowserID);
}
else {
// If the default browser bundle doesn't have an identifier in its plist,
// it's not our bundle
*aIsDefaultBrowser = PR_FALSE;
}
::CFRelease(defaultBrowserBundle);
rv = NS_OK;
}
::CFRelease(defaultBrowserURL);
}
// release the idetifiers strings
::CFRelease(firefoxID);
// If this is the first browser window, maintain internal state that we've
// checked this session (so that subsequent window opens don't show the
// default browser dialog).
if (aStartupCheck)
mCheckedThisSession = PR_TRUE;
return rv;
}
NS_IMETHODIMP
nsMacShellService::SetDefaultBrowser(PRBool aClaimAllTypes, PRBool aForAllUsers)
{
// Note: We don't support aForAllUsers on Mac OS X.
CFURLRef firefoxURL = ::CFBundleCopyBundleURL(CFBundleGetMainBundle());
::_LSSetDefaultSchemeHandlerURL(CFSTR("http"), firefoxURL);
::_LSSetDefaultSchemeHandlerURL(CFSTR("https"), firefoxURL);
if (aClaimAllTypes) {
::_LSSetDefaultSchemeHandlerURL(CFSTR("ftp"), firefoxURL);
FSRef firefoxFSRef;
// CFURLGetFSRef returns true if the conversion was successful
if (::CFURLGetFSRef(firefoxURL, &firefoxFSRef)); {
// Set the default opener for html/htm files
::_LSSetWeakBindingForType(0, 0, CFSTR("html"), kLSRolesAll, &firefoxFSRef);
::_LSSetWeakBindingForType(0, 0, CFSTR("htm"), kLSRolesAll, &firefoxFSRef);
}
}
::_LSSaveAndRefresh();
::CFRelease(firefoxURL);
return NS_OK;
}
@ -90,24 +204,249 @@ nsMacShellService::SetShouldCheckDefaultBrowser(PRBool aShouldCheck)
NS_IMETHODIMP
nsMacShellService::SetDesktopBackground(nsIDOMElement* aElement,
PRInt32 aPosition)
{
// Note: We don't support aPosition on OS X.
nsCOMPtr<nsIDOMHTMLImageElement> image(do_QueryInterface(aElement));
if (!image)
return NS_ERROR_INVALID_ARG;
// Get the image URL:
nsAutoString src;
image->GetSrc(src);
PRUint32 flags = nsIWebBrowserPersist::PERSIST_FLAGS_NO_CONVERSION |
nsIWebBrowserPersist::PERSIST_FLAGS_REPLACE_EXISTING_FILES |
nsIWebBrowserPersist::PERSIST_FLAGS_FROM_CACHE;
nsCOMPtr<nsIWebBrowserPersist> wbp
(do_CreateInstance("@mozilla.org/embedding/browser/nsWebBrowserPersist;1"));
if (!wbp)
return NS_ERROR_OUT_OF_MEMORY;
wbp->SetPersistFlags(flags);
nsAutoString baseURI;
nsCOMPtr<nsIDOM3Node> node(do_QueryInterface(aElement));
node->GetBaseURI(baseURI);
nsCOMPtr<nsIURI> imageURI, docURI;
NS_NewURI(getter_AddRefs(imageURI), src);
NS_NewURI(getter_AddRefs(docURI), baseURI);
if (!imageURI || !docURI)
return NS_ERROR_OUT_OF_MEMORY;
nsCOMPtr<nsIURL> imageURL(do_QueryInterface(imageURI));
nsCAutoString fileName;
imageURL->GetFileName(fileName);
nsresult rv;
nsCOMPtr<nsIProperties> fileLocator(do_GetService("@mozilla.org/file/directory_service;1",
&rv));
if (NS_FAILED(rv))
return rv;
// Get the current user's "Pictures" folder (That's ~/Pictures):
fileLocator->Get(NS_OSX_PICTURE_DOCUMENTS_DIR, NS_GET_IID(nsILocalFile),
getter_AddRefs(mBackgroundFile));
if (!mBackgroundFile)
return NS_ERROR_OUT_OF_MEMORY;
nsAutoString fileNameUnicode;
CopyUTF8toUTF16(fileName, fileNameUnicode);
// and add the imgage file name itself:
mBackgroundFile->Append(fileNameUnicode);
wbp->SetProgressListener(this);
// Download the image; the desktop background will be set in OnStateChange()
return wbp->SaveURI(imageURI, nsnull, docURI, nsnull, nsnull, mBackgroundFile);
}
NS_IMETHODIMP
nsMacShellService::OnProgressChange(nsIWebProgress* aWebProgress,
nsIRequest* aRequest,
PRInt32 aCurSelfProgress,
PRInt32 aMaxSelfProgress,
PRInt32 aCurTotalProgress,
PRInt32 aMaxTotalProgress)
{
return NS_OK;
}
NS_IMETHODIMP
nsMacShellService::OpenPreferredApplication(PRInt32 aApplication)
nsMacShellService::OnLocationChange(nsIWebProgress* aWebProgress,
nsIRequest* aRequest,
nsIURI* aLocation)
{
return NS_OK;
}
NS_IMETHODIMP
nsMacShellService::OnStatusChange(nsIWebProgress* aWebProgress,
nsIRequest* aRequest,
nsresult aStatus,
const PRUnichar* aMessage)
{
return NS_OK;
}
NS_IMETHODIMP
nsMacShellService::OnSecurityChange(nsIWebProgress* aWebProgress,
nsIRequest* aRequest,
PRUint32 aState)
{
return NS_OK;
}
NS_IMETHODIMP
nsMacShellService::OnStateChange(nsIWebProgress* aWebProgress,
nsIRequest* aRequest,
PRUint32 aStateFlags,
nsresult aStatus)
{
if (aStateFlags & STATE_STOP) {
nsCOMPtr<nsIObserverService> os(do_GetService("@mozilla.org/observer-service;1"));
if (os)
os->NotifyObservers(nsnull, "shell:desktop-background-changed", nsnull);
PRBool exists = PR_FALSE;
mBackgroundFile->Exists(&exists);
if (!exists)
return NS_OK;
nsCAutoString nativePath;
mBackgroundFile->GetNativePath(nativePath);
AEDesc tAEDesc = { typeNull, nil };
OSErr err = noErr;
AliasHandle aliasHandle = nil;
FSRef pictureRef;
OSStatus status;
// Convert the path into a FSRef
status = ::FSPathMakeRef((const UInt8*)nativePath.get(), &pictureRef, NULL);
if (status == noErr) {
err = ::FSNewAlias(nil, &pictureRef, &aliasHandle);
if (err == noErr && aliasHandle == nil)
err = paramErr;
if (err == noErr) {
// We need the descriptor (based on the picture file reference)
// for the 'Set Desktop Picture' apple event.
char handleState = ::HGetState((Handle)aliasHandle);
::HLock((Handle)aliasHandle);
err = ::AECreateDesc(typeAlias, *aliasHandle,
GetHandleSize((Handle)aliasHandle), &tAEDesc);
// unlock the alias handler
::HSetState((Handle)aliasHandle, handleState);
::DisposeHandle((Handle)aliasHandle);
}
if (err == noErr) {
AppleEvent tAppleEvent;
OSType sig = 'MACS';
AEBuildError tAEBuildError;
// Create a 'Set Desktop Pictue' Apple Event
err = ::AEBuildAppleEvent(kAECoreSuite, kAESetData, typeApplSignature,
&sig, sizeof(OSType), kAutoGenerateReturnID,
kAnyTransactionID, &tAppleEvent, &tAEBuildError,
"'----':'obj '{want:type (prop),form:prop" \
",seld:type('dpic'),from:'null'()},data:(@)",
&tAEDesc);
if (err == noErr) {
AppleEvent reply = { typeNull, nil };
// Sent the event we built, the reply event isn't necessary
err = ::AESend(&tAppleEvent, &reply, kAENoReply, kAENormalPriority,
kNoTimeOut, nil, nil);
::AEDisposeDesc(&tAppleEvent);
}
}
}
}
return NS_OK;
}
NS_IMETHODIMP
nsMacShellService::OpenApplication(PRInt32 aApplication)
{
nsresult rv = NS_OK;
CFURLRef appURL = nil;
OSStatus err = noErr;
switch (aApplication) {
case nsIShellService::APPLICATION_MAIL:
{
CFURLRef tempURL = ::CFURLCreateWithString(kCFAllocatorDefault,
CFSTR("mailto:"), NULL);
err = ::LSGetApplicationForURL(tempURL, kLSRolesAll, NULL, &appURL);
::CFRelease(tempURL);
}
break;
case nsIShellService::APPLICATION_NEWS:
{
CFURLRef tempURL = ::CFURLCreateWithString(kCFAllocatorDefault,
CFSTR("news:"), NULL);
err = ::LSGetApplicationForURL(tempURL, kLSRolesAll, NULL, &appURL);
::CFRelease(tempURL);
}
break;
case nsIMacShellService::APPLICATION_KEYCHAIN_ACCESS:
err = ::LSGetApplicationForInfo('APPL', 'kcmr', NULL, kLSRolesAll, NULL,
&appURL);
break;
case nsIMacShellService::APPLICATION_NETWORK:
{
nsCOMPtr<nsILocalFile> lf;
rv = NS_NewNativeLocalFile(NETWORK_PREFPANE, PR_TRUE, getter_AddRefs(lf));
NS_ENSURE_SUCCESS(rv, rv);
PRBool exists;
lf->Exists(&exists);
if (!exists)
return NS_ERROR_FILE_NOT_FOUND;
return lf->Launch();
}
break;
case nsIMacShellService::APPLICATION_DESKTOP:
{
nsCOMPtr<nsILocalFile> lf;
rv = NS_NewNativeLocalFile(DESKTOP_PREFPANE, PR_TRUE, getter_AddRefs(lf));
NS_ENSURE_SUCCESS(rv, rv);
PRBool exists;
lf->Exists(&exists);
if (!exists)
return NS_ERROR_FILE_NOT_FOUND;
return lf->Launch();
}
break;
}
if (appURL && err == noErr) {
err = ::LSOpenCFURLRef(appURL, NULL);
rv = err != noErr ? NS_ERROR_FAILURE : NS_OK;
::CFRelease(appURL);
}
return rv;
}
NS_IMETHODIMP
nsMacShellService::GetDesktopBackgroundColor(PRUint32 *aColor)
{
return NS_OK;
// This method and |SetDesktopBackgroundColor| has no meaning on Mac OS X.
// The mac desktop preferences UI uses pictures for the few solid colors it
// supports.
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsMacShellService::SetDesktopBackgroundColor(PRUint32 aColor)
{
return NS_OK;
// This method and |GetDesktopBackgroundColor| has no meaning on Mac OS X.
// The mac desktop preferences UI uses pictures for the few solid colors it
// supports.
return NS_ERROR_NOT_IMPLEMENTED;
}

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

@ -38,9 +38,12 @@
#ifndef nsmacshellservice_h____
#define nsmacshellservice_h____
#include "nsIShellService.h"
#include "nsIMacShellService.h"
#include "nsIWebProgressListener.h"
#include "nsILocalFile.h"
class nsMacShellService : public nsIShellService
class nsMacShellService : public nsIMacShellService,
public nsIWebProgressListener
{
public:
nsMacShellService() : mCheckedThisSession(PR_FALSE) {};
@ -48,10 +51,14 @@ public:
NS_DECL_ISUPPORTS
NS_DECL_NSISHELLSERVICE
NS_DECL_NSIMACSHELLSERVICE
NS_DECL_NSIWEBPROGRESSLISTENER
protected:
private:
nsCOMPtr<nsILocalFile> mBackgroundFile;
PRBool mCheckedThisSession;
};

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

@ -19,10 +19,10 @@
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Ben Goodger <ben@mozilla.org> (Clients, Mail, New Default Browser)
* Joe Hewitt <hewitt@netscape.com> (Set Background)
* Blake Ross <blake@cs.stanford.edu (Desktop Color, DDE support)
* Jungshik Shin <jshin@mailaps.org> (I18N)
* Ben Goodger <ben@mozilla.org> (Clients, Mail, New Default Browser)
* Joe Hewitt <hewitt@netscape.com> (Set Background)
* Blake Ross <blake@cs.stanford.edu (Desktop Color, DDE support)
* Jungshik Shin <jshin@mailaps.org> (I18N)
*
* 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
@ -46,7 +46,6 @@
#include "nsIDOMElement.h"
#include "nsIDOMHTMLImageElement.h"
#include "nsIImageLoadingContent.h"
#include "nsIOutputStream.h"
#include "nsIPrefService.h"
#include "nsIPrefLocalizedString.h"
#include "nsIServiceManager.h"
@ -436,9 +435,14 @@ nsWindowsShellService::SetDefaultBrowser(PRBool aClaimAllTypes, PRBool aForAllUs
backupKey, aClaimAllTypes, aForAllUsers);
nsCOMPtr<nsIStringBundleService> bundleService(do_GetService("@mozilla.org/intl/stringbundle;1"));
if (!bundleService)
return NS_ERROR_FAILURE;
nsCOMPtr<nsIStringBundle> bundle, brandBundle;
bundleService->CreateBundle(SHELLSERVICE_PROPERTIES, getter_AddRefs(bundle));
bundleService->CreateBundle(BRAND_PROPERTIES, getter_AddRefs(brandBundle));
rv = bundleService->CreateBundle(SHELLSERVICE_PROPERTIES, getter_AddRefs(bundle));
NS_ENSURE_SUCCESS(rv, rv);
rv = bundleService->CreateBundle(BRAND_PROPERTIES, getter_AddRefs(brandBundle));
NS_ENSURE_SUCCESS(rv, rv);
// Set the Start Menu item subtitle
nsXPIDLString brandFullName;
@ -635,7 +639,7 @@ nsWindowsShellService::SetShouldCheckDefaultBrowser(PRBool aShouldCheck)
return NS_OK;
}
nsresult
static nsresult
WriteBitmap(nsString& aPath, gfxIImageFrame* aImage)
{
PRInt32 width, height;
@ -743,25 +747,31 @@ nsWindowsShellService::SetDesktopBackground(nsIDOMElement* aElement,
nsAutoString winPath;
NS_CopyNativeToUnicode(nsDependentCString(winDir), winPath);
// get the product brand name from localized strings
nsXPIDLString brandName;
nsCID bundleCID = NS_STRINGBUNDLESERVICE_CID;
nsCOMPtr<nsIStringBundleService> bundleService(do_GetService(bundleCID));
if (bundleService) {
nsCOMPtr<nsIStringBundle> brandBundle;
rv = bundleService->CreateBundle("chrome://branding/locale/brand.properties",
getter_AddRefs(brandBundle));
if (NS_SUCCEEDED(rv) && brandBundle) {
if (NS_FAILED(rv = brandBundle->GetStringFromName(NS_LITERAL_STRING("brandShortName").get(),
getter_Copies(brandName))))
return rv;
}
}
// build the file name
winPath.Append(NS_LITERAL_STRING("\\").get());
winPath.Append(brandName);
winPath.Append(NS_LITERAL_STRING(" Wallpaper.bmp").get());
// get the product brand name from localized strings
nsCID bundleCID = NS_STRINGBUNDLESERVICE_CID;
nsCOMPtr<nsIStringBundleService> bundleService(do_GetService(bundleCID));
if (!bundleService)
return NS_ERROR_FAILURE;
nsCOMPtr<nsIStringBundle> brandBundle, shellBundle;
rv = bundleService->CreateBundle("chrome://global/locale/brand.properties",
getter_AddRefs(brandBundle));
NS_ENSURE_SUCCESS(rv, rv);
rv = bundleService->CreateBundle("chrome://browser/locale/shellservice.properties",
getter_AddRefs(shellBundle));
NS_ENSURE_SUCCESS(rv, rv);
nsXPIDLString brandShortName;
brandBundle->GetStringFromName(NS_LITERAL_STRING("brandShortName").get(),
getter_Copies(brandShortName));
const PRUnichar* brandNameStrings[] = { brandShortName.get() };
nsXPIDLString backgroundFileName;
shellBundle->FormatStringFromName(NS_LITERAL_STRING("desktopBackgroundFileNameWin").get(),
brandNameStrings, 1, getter_Copies(backgroundFileName));
winPath.Append(backgroundFileName);
// write the bitmap to a file in the windows dir
rv = WriteBitmap(winPath, gfxFrame);
@ -814,7 +824,7 @@ nsWindowsShellService::SetDesktopBackground(nsIDOMElement* aElement,
}
NS_IMETHODIMP
nsWindowsShellService::OpenPreferredApplication(PRInt32 aApplication)
nsWindowsShellService::OpenApplication(PRInt32 aApplication)
{
nsCAutoString application;
switch (aApplication) {

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

@ -245,8 +245,8 @@
<!ENTITY viewImageCmd.accesskey "I">
<!ENTITY viewBGImageCmd.label "View Background Image">
<!ENTITY viewBGImageCmd.accesskey "w">
<!ENTITY setWallpaperCmd.label "Set As Wallpaper...">
<!ENTITY setWallpaperCmd.accesskey "S">
<!ENTITY setDesktopBackgroundCmd.label "Set As Desktop Background...">
<!ENTITY setDesktopBackgroundCmd.accesskey "S">
<!ENTITY bookmarkPageCmd.label "Bookmark This Page...">
<!ENTITY bookmarkPageCmd.accesskey "m">
<!ENTITY bookmarkLinkCmd.label "Bookmark This Link...">

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

@ -52,10 +52,6 @@ saveLinkErrorTitle=Save Link
# Default name for the Web Panels sidebar
webPanels=Web Panels
# setWallpaper confirmation dialog
wallpaperConfirmTitle = Set Wallpaper
wallpaperConfirmMsg = Do you want to set this image as your desktop wallpaper?
tabs.closeWarningTitle=Confirm close
tabs.closeWarning=This Browser window has %S tabs open. Do you want to close it and all its tabs?
tabs.closeButton=Close all tabs
@ -84,8 +80,6 @@ livemarkHasLivemarksTooltip=Add Live Bookmark for this page's feed
livemarkNoLivemarksTooltip=Page has no feeds for Live Bookmark
livemarkSubscribeTo=Subscribe to '%S'...
WallpaperNoPreview=(no preview available)
saveFormInformationMessage=%S can save information that you enter in web forms to make filling them out faster in the future. Would you like to save form information from now on?
saveFormInformationYes=Save Form Information
saveFormInformationNo=Don't Save

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

@ -0,0 +1,9 @@
<!ENTITY position.label "Position:">
<!ENTITY tile.label "Tile">
<!ENTITY center.label "Center">
<!ENTITY stretch.label "Stretch">
<!ENTITY preview.label "Preview">
<!ENTITY color.label "Color:">
<!ENTITY setDesktopBackground.title "Set Desktop Background">
<!ENTITY openDesktopPrefs.label "Open Desktop Preferences">
<!ENTITY closeWindow.key "w">

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

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

@ -2,4 +2,8 @@ optionsLabel=%S &Options
setDefaultBrowserTitle=Default Browser
setDefaultBrowserMessage=%S is not currently set as your default browser. Would you like to make it your default browser?
setDefaultBrowserDontAsk=Always perform this check when starting %S.
alreadyDefaultBrowser=%S is already set as your default browser.
alreadyDefaultBrowser=%S is already set as your default browser.
desktopBackgroundFileNameWin=%S Background.bmp
DesktopBackgroundNoPreview=(no preview available)
DesktopBackgroundDownloading=Saving Picture...
DesktopBackgroundSet=Set Desktop Background

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

@ -18,7 +18,7 @@
locale/browser/pageReportFirstTime.dtd (%chrome/browser/pageReportFirstTime.dtd)
locale/browser/sanitize.dtd (%chrome/browser/sanitize.dtd)
locale/browser/searchbar.properties (%chrome/browser/searchbar.properties)
locale/browser/setWallpaper.dtd (%chrome/browser/setWallpaper.dtd)
locale/browser/setDesktopBackground.dtd (%chrome/browser/setDesktopBackground.dtd)
locale/browser/shellservice.properties (%chrome/browser/shellservice.properties)
* locale/browser/bookmarks/bookmarks.dtd (%chrome/browser/bookmarks/bookmarks.dtd)
* locale/browser/bookmarks/addBookmark.dtd (%chrome/browser/bookmarks/addBookmark.dtd)