diff --git a/mozilla/browser/base/content/browser-sets.inc b/mozilla/browser/base/content/browser-sets.inc index fcaa512c6ca..674932df668 100644 --- a/mozilla/browser/base/content/browser-sets.inc +++ b/mozilla/browser/base/content/browser-sets.inc @@ -76,8 +76,14 @@ - + + + +#ifdef XP_WIN + + +#endif + @@ -256,6 +262,8 @@ + + diff --git a/mozilla/browser/base/content/browser.js b/mozilla/browser/base/content/browser.js index 11d2b4a68ec..ceed592034b 100644 --- a/mozilla/browser/base/content/browser.js +++ b/mozilla/browser/base/content/browser.js @@ -1503,7 +1503,6 @@ function updateToolbarStates(toolbarMenuElt) function BrowserImport() { - // goats #ifdef XP_MACOSX var features = "centerscreen,chrome,resizable=no"; #else @@ -3207,14 +3206,14 @@ nsContextMenu.prototype = { saveURL( this.linkURL(), this.linkText(), null, true, true ); }, sendLink : function () { - sendLink( this.linkURL(), "" ); // we don't know the title of the link so pass in an empty string + MailIntegration.sendMessage( this.linkURL(), "" ); // we don't know the title of the link so pass in an empty string }, // Save URL of clicked-on image. saveImage : function () { saveURL( this.imageURL, null, "SaveImageTitle", false ); }, sendImage : function () { - sendLink(this.imageURL, ""); + MailIntegration.sendMessage(this.imageURL, ""); }, toggleImageBlocking : function (aBlock) { var nsIPermissionManager = Components.interfaces.nsIPermissionManager; @@ -3942,27 +3941,6 @@ function charsetLoadListener (event) } } -// a generic method which can be used to pass arbitrary urls to the operating system. -// aURL --> a nsIURI which represents the url to launch -function launchExternalUrl(aURL) -{ - var extProtocolSvc = Components.classes["@mozilla.org/uriloader/external-protocol-service;1"].getService(Components.interfaces.nsIExternalProtocolService); - if (extProtocolSvc) - extProtocolSvc.loadUrl(aURL); -} - -function sendLink(url, title) -{ - // generate a mailto url based on the url and the url's title - var mailtoUrl = url ? "mailto:?body=" + encodeURIComponent(url) + "&subject=" + encodeURIComponent(title) : "mailto:"; - - var ioService = Components.classes["@mozilla.org/network/io-service;1"].getService(Components.interfaces.nsIIOService); - var uri = ioService.newURI(mailtoUrl, null, null); - - // now pass this url to the operating system - launchExternalUrl(uri); -} - #ifdef XP_MACOSX const nsIWindowDataSource = Components.interfaces.nsIWindowDataSource; @@ -4317,3 +4295,61 @@ function WindowIsClosing() return reallyClose; } + +var MailIntegration = { + sendLinkForContent: function () + { + this.sendMessage(Components.lookupMethod(window._content, 'location').call(window._content).href, + Components.lookupMethod(window._content.document, 'title').call(window._content.document)); + }, + + sendMessage: function (aBody, aSubject) + { + // generate a mailto url based on the url and the url's title + var mailtoUrl = aBody ? "mailto:?body=" + encodeURIComponent(aBody) + "&subject=" + encodeURIComponent(aSubject) : "mailto:"; + + var ioService = Components.classes["@mozilla.org/network/io-service;1"].getService(Components.interfaces.nsIIOService); + var uri = ioService.newURI(mailtoUrl, null, null); + + // now pass this url to the operating system + this._launchExternalUrl(uri); + }, + + // a generic method which can be used to pass arbitrary urls to the operating system. + // aURL --> a nsIURI which represents the url to launch + _launchExternalUrl: function(aURL) + { + var extProtocolSvc = Components.classes["@mozilla.org/uriloader/external-protocol-service;1"].getService(Components.interfaces.nsIExternalProtocolService); + if (extProtocolSvc) + extProtocolSvc.loadUrl(aURL); +#ifdef XP_WIN + }, + + readMail: function () + { + var whs = Components.classes["@mozilla.org/winhooks;1"].getService(Components.interfaces.nsIWindowsHooks); + whs.openDefaultClient("Mail"); + }, + + readNews: function () + { + var whs = Components.classes["@mozilla.org/winhooks;1"].getService(Components.interfaces.nsIWindowsHooks); + whs.openDefaultClient("News"); + }, + + updateUnreadCount: function () + { + var whs = Components.classes["@mozilla.org/winhooks;1"].getService(Components.interfaces.nsIWindowsHooks); + var unreadCount = whs.unreadMailCount; + var message = gNavigatorBundle.getFormattedString("mailUnreadTooltip", [unreadCount]); + var element = document.getElementById("mail-button"); + element.setAttribute("tooltiptext", message); + + message = gNavigatorBundle.getFormattedString("mailUnreadMenuitem", [unreadCount]); + element = document.getElementById("readMailItem"); + element.setAttribute("label", message); + } +#else + } +#endif +}; \ No newline at end of file diff --git a/mozilla/browser/base/content/browser.xul b/mozilla/browser/base/content/browser.xul index 6cc95993fc6..ea94d1632ae 100644 --- a/mozilla/browser/base/content/browser.xul +++ b/mozilla/browser/base/content/browser.xul @@ -289,7 +289,31 @@ - + +#ifdef XP_WIN + + + + + + + + + +#endif + diff --git a/mozilla/browser/base/locale/browser.dtd b/mozilla/browser/base/locale/browser.dtd index 2e49d646c52..658b3e876e9 100644 --- a/mozilla/browser/base/locale/browser.dtd +++ b/mozilla/browser/base/locale/browser.dtd @@ -268,6 +268,18 @@ + + + + + + + + + + + + diff --git a/mozilla/browser/base/locale/browser.properties b/mozilla/browser/base/locale/browser.properties index e297ec3209b..fe2b477b29e 100644 --- a/mozilla/browser/base/locale/browser.properties +++ b/mozilla/browser/base/locale/browser.properties @@ -56,3 +56,6 @@ 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 tabs.closeWarningPromptMe=Warn me when closing multiple tabs + +mailUnreadTooltip=Read Mail and News (%S new messages) +mailUnreadMenuitem=Read Mail (%S new) diff --git a/mozilla/browser/base/skin/browser.css b/mozilla/browser/base/skin/browser.css index bddedda9f09..6c9556171cd 100644 --- a/mozilla/browser/base/skin/browser.css +++ b/mozilla/browser/base/skin/browser.css @@ -302,6 +302,17 @@ toolbar[mode="text"] .toolbarbutton-text { -moz-image-region: rect(64px 224px 96px 192px); } +#mail-button { + -moz-image-region: rect(0px 224px 32px 192px); +} +#mail-button:hover, +#mail-button[checked="true"] { + -moz-image-region: rect(32px 224px 64px 192px); +} +#mail-button[disabled="true"] { + -moz-image-region: rect(64px 224px 96px 192px); +} + #cut-button { -moz-image-region: rect(0px 384px 32px 352px); } @@ -453,6 +464,17 @@ toolbar[iconsize="small"] #history-button[disabled="true"] { -moz-image-region: rect(40px 140px 60px 120px) !important; } +toolbar[iconsize="small"] #mail-button { + -moz-image-region: rect(0px 140px 20px 120px); +} +toolbar[iconsize="small"] #mail-button:hover, +toolbar[iconsize="small"] #mail-button[checked="true"] { + -moz-image-region: rect(20px 140px 40px 120px); +} +toolbar[iconsize="small"] #mail-button[disabled="true"] { + -moz-image-region: rect(40px 140px 60px 120px) !important; +} + toolbar[iconsize="small"] #cut-button { -moz-image-region: rect(0px 240px 20px 220px); } diff --git a/mozilla/browser/components/winhooks/nsWindowsHooks.cpp b/mozilla/browser/components/winhooks/nsWindowsHooks.cpp index 989033baaee..d97693b0162 100755 --- a/mozilla/browser/components/winhooks/nsWindowsHooks.cpp +++ b/mozilla/browser/components/winhooks/nsWindowsHooks.cpp @@ -767,3 +767,125 @@ nsWindowsHooks::SetImageAsWallpaper(nsIDOMElement* aElement, PRBool aUseBackgrou return rv; } +NS_IMETHODIMP +nsWindowsHooks::OpenDefaultClient(const char* aClient) +{ + nsresult rv; + + // The Default Client section of the Windows Registry looks like this: + // + // Clients\aClient\ + // e.g. aClient = "Mail"... + // \Mail\(default) = Client Subkey Name + // \Client Subkey Name + // \Client Subkey Name\shell\open\command\ + // \Client Subkey Name\shell\open\command\(default) = path to exe + // + nsCAutoString clientKey(NS_LITERAL_CSTRING("SOFTWARE\\Clients\\")); + clientKey += aClient; + + nsXPIDLCString defaultClient; + rv = GetRegistryEntry(nsIWindowsRegistry::HKLM, clientKey.get(), "", + getter_Copies(defaultClient)); + if (NS_FAILED(rv) || defaultClient.IsEmpty()) + return rv; + + clientKey.Append("\\"); + clientKey.Append(defaultClient.get()); + clientKey.Append("\\shell\\open\\command"); + + nsXPIDLCString path; + rv = GetRegistryEntry(nsIWindowsRegistry::HKLM, clientKey.get(), "", + getter_Copies(path)); + if (NS_FAILED(rv) || path.IsEmpty()) + return rv; + + // Look for any embedded environment variables and substitute their + // values, as |::CreateProcess| is unable to do this. + PRInt32 end = path.Length(); + PRInt32 cursor = 0, temp = 0; + char buf[_MAX_PATH]; + do { + cursor = path.FindChar('%', cursor); + if (cursor < 0) + break; + + temp = path.FindChar('%', cursor + 1); + + ++cursor; + + ::ZeroMemory(&buf, sizeof(buf)); + ::GetEnvironmentVariable(nsCAutoString(Substring(path, cursor, temp - cursor)).get(), + buf, sizeof(buf)); + + // "+ 2" is to subtract the extra characters used to delimit the environment + // variable ('%'). + path.Replace((cursor - 1), temp - cursor + 2, nsDependentCString(buf)); + + ++cursor; + } + while (cursor < end); + + STARTUPINFO si; + PROCESS_INFORMATION pi; + + ::ZeroMemory(&si, sizeof(STARTUPINFO)); + ::ZeroMemory(&pi, sizeof(PROCESS_INFORMATION)); + + char* pathCStr = ToNewCString(path); + BOOL success = ::CreateProcess(NULL, pathCStr, NULL, NULL, FALSE, 0, NULL, + NULL, &si, &pi); + nsCRT::free(pathCStr); + if (!success) + return NS_ERROR_FAILURE; + + return NS_OK; +} + +NS_IMETHODIMP +nsWindowsHooks::GetUnreadMailCount(PRUint32* aResult) +{ + *aResult = 0; + + HKEY accountKey; + if (GetMailAccountKey(&accountKey)) { + DWORD type, length, unreadCount; + DWORD result = ::RegQueryValueEx(accountKey, "MessageCount", 0, &type, + (LPBYTE)&unreadCount, &length); + if (result == ERROR_SUCCESS) { + *aResult = unreadCount; + } + } + + return NS_OK; +} + +PRBool +nsWindowsHooks::GetMailAccountKey(HKEY* aResult) +{ + HKEY mailKey; + DWORD result = ::RegOpenKeyEx(HKEY_CURRENT_USER, + "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\UnreadMail\\", + 0, KEY_ENUMERATE_SUB_KEYS, &mailKey); + + PRInt32 i = 0; + do { + char subkeyName[_MAX_PATH]; + DWORD len = sizeof subkeyName; + result = ::RegEnumKeyEx(mailKey, i++, subkeyName, &len, 0, 0, 0, 0); + if (result == ERROR_SUCCESS) { + HKEY accountKey; + result = ::RegOpenKeyEx(mailKey, subkeyName, 0, KEY_READ, &accountKey); + if (result == ERROR_SUCCESS) { + *aResult = accountKey; + return PR_TRUE; + } + } + else + break; + } + while (1); + + return PR_FALSE; +} + diff --git a/mozilla/browser/components/winhooks/nsWindowsHooks.h b/mozilla/browser/components/winhooks/nsWindowsHooks.h index 70b9524483f..46e35b97785 100755 --- a/mozilla/browser/components/winhooks/nsWindowsHooks.h +++ b/mozilla/browser/components/winhooks/nsWindowsHooks.h @@ -42,6 +42,8 @@ #include "nscore.h" #include "nsIWindowsHooks.h" +#include + #ifndef MAX_BUF #define MAX_BUF 4096 #endif @@ -113,6 +115,8 @@ protected: // Internal flavor of GetPreferences. NS_IMETHOD GetSettings( nsWindowsHooksSettings ** ); + PRBool GetMailAccountKey(HKEY* aResult); + // Set registry according to settings. NS_IMETHOD SetRegistry(); char mShortcutPath[MAX_BUF]; diff --git a/mozilla/browser/components/winhooks/public/nsIWindowsHooks.idl b/mozilla/browser/components/winhooks/public/nsIWindowsHooks.idl index d87e95dc18d..459b30a947e 100755 --- a/mozilla/browser/components/winhooks/public/nsIWindowsHooks.idl +++ b/mozilla/browser/components/winhooks/public/nsIWindowsHooks.idl @@ -148,39 +148,70 @@ interface nsIWindowsHooksSettings : nsISupports { * by the nsIWindowsHooksPrefs attributes. */ [scriptable, uuid(19c9fbb0-06a3-11d4-8076-00600811a9c3)] -interface nsIWindowsHooks : nsISupports { - - // settings - // -------- - // Get/set this to query or modify them. The Windows - // registry is updated when you set this attribute. +interface nsIWindowsHooks : nsISupports +{ + /** + * See nsIWindowsHooksSettings; The Windows Registry is updated when + * this attribute is set. + */ attribute nsIWindowsHooksSettings settings; - // checkSettings - // ------------- - // Check that registry matches settings and if not, - // prompt user for whether to reset. This is - // controlled by the showDialog setting. This will - // perform the check only the first time the - // service is called. - // aParent - parent window for any dialogs that - // will appear - // Returns true if the windows integration dialog was shown - boolean checkSettings( in nsIDOMWindowInternal aParent ); + /** + * Check that registry matches settings and if not, prompt user for whether + * to reset. This is controlled by the showDialog setting. This will + * perform the check only the first time the service is called. + * + * @param aParent parent window for any dialogs that will appear. + * @return true if the windows integration dialog was shown, false if not. + */ + boolean checkSettings(in nsIDOMWindowInternal aParent); const PRInt32 WALLPAPER_TILE = 0; const PRInt32 WALLPAPER_STRETCH = 1; const PRInt32 WALLPAPER_CENTER = 2; /** - * Accepts an element, either an HTML img element or an element with - * a background image, serializes the image to a bitmap file - * in the windows directory, and sets it to be the desktop wallpaper. + * Sets the desktop background image using either the HTML + * element supplied or the background image of the element supplied. + * + * @param aImageElement Either a HTML element or an element with + * a background image from which to source the + * background image. + * @param useBackground Determines whether or not to interpret aImageElement + * as a HTML element or as another element whose + * background image should be used. + * @param position How to place the image on the desktop */ void setImageAsWallpaper(in nsIDOMElement aImageElement, in boolean useBackground, in PRInt32 position); + + /** + * Retrieves the current desktop background color. + */ PRUint32 getDesktopColor(); + + /** + * Sets the current desktop background color. + * + * @param color The color to use, in rgb format. + */ void setDesktopColor(in PRUint32 color); - + + /** + * Launches one of the Windows default clients. + * + * @param aClient The client type to open, as specified in the Windows Registry under: + * HKEY_LOCAL_MACHINE\Software\Clients\ + * Typical values include "Mail", "News", "Contacts" etc. + */ + void openDefaultClient(in string aClient); + + /** + * Retrieve the number of unread mail messages from the system for the current user. + * + * @return The number of unread (new) mail messages for the current user. + */ + readonly attribute unsigned long unreadMailCount; + }; /* nsIWindowsRegistry @@ -193,23 +224,31 @@ interface nsIWindowsHooks : nsISupports { [scriptable, uuid(e07e7430-8d11-417c-83ee-c994400c452f)] interface nsIWindowsRegistry : nsISupports { /** - * Returns a Win32 registry entry value. The returned string will be truncated - * at 4096 bytes. The constants define the set of valid starting keys. You - * pass in the subkey name and a value identifier (an empty string returns - * the "default" value for that subkey). + * Valid starting keys for the Windows Registry. */ const long HKCR = 0; // HKEY_CLASSES_ROOT const long HKCC = 1; // HKEY_CURRENT_CONFIG const long HKCU = 2; // HKEY_CURRENT_USER const long HKLM = 3; // HKEY_LOCAL_MACHINE const long HKU = 4; // HKEY_USERS - string getRegistryEntry( in long aHKeyConstant, in string aSubKeyName, in string aValueName ); + + /** + * Retrieves a Windows Registry entry value. + * + * @param aHKeyConstant The starting key, using the constants defined above. + * @param aSubKeyName The sub key to locate + * @param aValueName The value to locate in the sub key. The empty string + * returns the default value of the sub key. + * @return The value of the specified sub key/value, truncated to 4096 bytes. + */ + string getRegistryEntry(in long aHKeyConstant, in string aSubKeyName, in string aValueName); }; %{C++ -#define NS_IWINDOWSHOOKS_CONTRACTID "@mozilla.org/winhooks;1" +#define NS_IWINDOWSHOOKS_CONTRACTID "@mozilla.org/winhooks;1" #define NS_IWINDOWSHOOKS_CLASSNAME "Mozilla Windows Integration Hooks" +// XXXben - get rid of this // The key that is used to write the quick launch appname in the windows registry #define NS_QUICKLAUNCH_RUN_KEY "Mozilla Quick Launch" %} diff --git a/mozilla/toolkit/content/widgets/toolbarbutton.xml b/mozilla/toolkit/content/widgets/toolbarbutton.xml index 628b02ddfa1..752b6aac069 100644 --- a/mozilla/toolkit/content/widgets/toolbarbutton.xml +++ b/mozilla/toolkit/content/widgets/toolbarbutton.xml @@ -30,6 +30,21 @@ + + + + + + + + + + + + + diff --git a/mozilla/toolkit/content/xul.css b/mozilla/toolkit/content/xul.css index 59ee6336846..b4f33313f1a 100644 --- a/mozilla/toolkit/content/xul.css +++ b/mozilla/toolkit/content/xul.css @@ -123,6 +123,10 @@ toolbarbutton[type="menu"] { -moz-binding: url("chrome://global/content/bindings/toolbarbutton.xml#menu"); } +toolbarbutton[orient] { + -moz-binding: url("chrome://global/content/bindings/toolbarbutton.xml#menu-orient"); +} + toolbarbutton[type="menu-button"] { -moz-binding: url("chrome://global/content/bindings/toolbarbutton.xml#menu-button"); }