Bug #329954 --> add a close button to thunderbird's new mail alert notification, and re-open the alert when you left click the biff icon in the system tray. sr=bienvenu

This commit is contained in:
scott%scott-macgregor.org 2006-03-14 21:52:50 +00:00
parent 4fdf8cf296
commit b71e9517cd
5 changed files with 177 additions and 80 deletions

View File

@ -44,16 +44,19 @@ var gOpenTime = 3000; // total time the alert should stay up once we are done an
var gAlertCookie = "";
var gAlertListener = null;
var gPendingPreviewFetchRequests = 0;
var gAnimateOnOpen = true;
function prefillAlertInfo()
{
// unwrap all the args....
// arguments[0] --> array of folders with new mail
// arguments[1] --> the observer to call back with notifications about the alert
// arguments[2] --> animation boolean. Set to true if we should animate the alert, false
// if we should open the alert and leave it open until the user closes it.
var foldersWithNewMail = window.arguments[0];
gAlertListener = window.arguments[1];
gAnimateOnOpen = window.arguments[2];
// walk the array of folders with new mail.
var foldersWithNewMail = window.arguments[0];
// for now just grab the first folder which should be a root folder
// for the account that has new mail.
var rootFolder = foldersWithNewMail.GetElementAt(0).QueryInterface(Components.interfaces.nsIWeakReference).QueryReferent(Components.interfaces.nsIMsgFolder);
@ -137,9 +140,19 @@ function showAlert()
{
resizeAlert();
if (document.getElementById('folderSummaryInfo').hasMessages)
setTimeout(animateAlert, gSlideTime);
{
if (gAnimateOnOpen)
setTimeout(animateOpen, gSlideTime);
else
{
// restore the alert to its full height so we can open it right away.
window.outerHeight = gFinalHeight;
// now move the alert back to a visible location...
window.moveTo( (screen.availLeft + screen.availWidth - window.outerWidth) - 10, screen.availTop + screen.availHeight - window.outerHeight);
}
}
else
closeAlert();
animateClose();
}
function resizeAlert()
@ -156,7 +169,7 @@ function resizeAlert()
var windowWidth = Math.max (document.getBoxObjectFor(document.getElementById('alertGroove')).width,
document.getBoxObjectFor(document.getElementById('folderSummaryInfo')).width);
resizeTo(windowWidth + document.getBoxObjectFor(document.getElementById('alertImageBox')).width + 30,
document.getBoxObjectFor(document.getElementById('alertBox')).height + 10);
document.getBoxObjectFor(document.getElementById('alertBox')).height + 10);
gFinalHeight = window.outerHeight;
window.outerHeight = 1;
@ -164,32 +177,35 @@ function resizeAlert()
window.moveTo( (screen.availLeft + screen.availWidth - window.outerWidth) - 10, screen.availTop + screen.availHeight - window.outerHeight);
}
function animateAlert()
function animateOpen()
{
if (window.outerHeight < gFinalHeight)
{
window.screenY -= gSlideIncrement;
window.outerHeight += gSlideIncrement;
setTimeout(animateAlert, gSlideTime);
setTimeout(animateOpen, gSlideTime);
}
else
setTimeout(closeAlert, gOpenTime);
setTimeout(animateClose, gOpenTime);
}
function closeAlert()
function animateClose()
{
if (window.outerHeight > 1)
{
window.screenY += gSlideIncrement;
window.outerHeight -= gSlideIncrement;
setTimeout(closeAlert, gSlideTime);
setTimeout(animateClose, gSlideTime);
}
else
{
if (gAlertListener)
gAlertListener.observe(null, "alertfinished", gAlertCookie);
window.close();
}
closeAlert();
}
function closeAlert()
{
if (gAlertListener)
gAlertListener.observe(null, "alertfinished", gAlertCookie);
window.close();
}
function onAlertClick()

View File

@ -50,19 +50,25 @@
<stringbundle id="bundle_messenger" src="chrome://messenger/locale/messenger.properties"/>
<script type="application/x-javascript" src="chrome://messenger/content/newmailalert.js"/>
<hbox id="alertBox">
<hbox id ="alertImageBox" align="center" valign="center">
<image id="alertImage"/>
<stack>
<hbox id="alertBox">
<hbox id ="alertImageBox" align="center" valign="center">
<image id="alertImage"/>
</hbox>
<vbox id="alertTextBox">
<label id="alertTitle"/>
<separator id="alertGroove" class="groove"/>
<folderSummary id="folderSummaryInfo"/>
</vbox>
</hbox>
<vbox id="alertTextBox">
<label id="alertTitle"/>
<separator id="alertGroove" class="groove"/>
<folderSummary id="folderSummaryInfo"/>
</vbox>
</hbox>
<hbox align="top">
<spacer flex="1"/>
<toolbarbutton id="closeButton" onclick="closeAlert();"/>
</hbox>
</stack>
<!-- This method is called inline because we want to make sure we establish the width
and height of the alert before we fire the onload handler. -->
<script type="application/x-javascript">prefillAlertInfo();</script>

View File

@ -63,6 +63,11 @@
#alertTitle {
font-weight: bold;
text-align: center;
/* this right margin keeps us from overlapping with the
close button. It's value should be related to the width
of the closeButtonImage
*/
margin-right: 16px;
}
#alertTextBox {
@ -87,3 +92,19 @@
color: grey;
padding-left: 5px;
}
#closeButton {
list-style-image: url("chrome://messenger/skin/icons/quick-search-clear.png");
-moz-image-region: rect(0px, 16px, 16px, 0px);
-moz-appearance: none;
border: none !important;
padding: 2px 2px 0px 0px;
}
#closeButton:hover {
-moz-image-region: rect(0px, 32px, 16px, 16px);
}
#closeButton:hover:active {
-moz-image-region: rect(0px, 48px, 16px, 32px);
}

View File

@ -173,15 +173,45 @@ static void openMailWindow(const PRUnichar * aMailWindowName, const char * aFold
}
}
static void CALLBACK delayedSingleClick(HWND msgWindow, UINT msg, INT_PTR idEvent, DWORD dwTime)
{
::KillTimer(msgWindow, idEvent);
#ifdef MOZ_THUNDERBIRD
// single clicks on the biff icon should re-open the alert notification
nsresult rv = NS_OK;
nsCOMPtr<nsIMessengerOSIntegration> integrationService =
do_GetService(NS_MESSENGEROSINTEGRATION_CONTRACTID, &rv);
if (NS_SUCCEEDED(rv))
{
// we know we are dealing with the windows integration object
nsMessengerWinIntegration * winIntegrationService = NS_STATIC_CAST(nsMessengerWinIntegration*,
NS_STATIC_CAST(nsIMessengerOSIntegration*, integrationService.get()));
winIntegrationService->ShowNewAlertNotification(PR_FALSE);
}
#endif
}
// Window proc.
static long CALLBACK MessageWindowProc( HWND msgWindow, UINT msg, WPARAM wp, LPARAM lp )
{
if (msg == WM_USER && lp == WM_LBUTTONDBLCLK)
if (msg == WM_USER)
{
NS_NAMED_LITERAL_STRING(mailName, "mail:3pane");
openMailWindow(mailName.get(), nsnull);
if (lp == WM_LBUTTONDOWN)
{
// the only way to tell a single left click
// from a double left click is to fire a timer which gets cleared if we end up getting
// a WM_LBUTTONDBLK event.
::SetTimer(msgWindow, 1, GetDoubleClickTime(), (TIMERPROC) delayedSingleClick);
}
else if (lp == WM_LBUTTONDBLCLK)
{
::KillTimer(msgWindow, 1);
NS_NAMED_LITERAL_STRING(mailName, "mail:3pane");
openMailWindow(mailName.get(), nsnull);
}
}
return TRUE;
}
@ -449,6 +479,7 @@ nsresult nsMessengerWinIntegration::GetStringBundle(nsIStringBundle **aBundle)
return rv;
}
#ifndef MOZ_THUNDERBIRD
nsresult nsMessengerWinIntegration::ShowAlertMessage(const PRUnichar * aAlertTitle, const PRUnichar * aAlertText, const char * aFolderURI)
{
nsresult rv;
@ -465,54 +496,6 @@ nsresult nsMessengerWinIntegration::ShowAlertMessage(const PRUnichar * aAlertTit
if (showAlert)
{
#ifdef MOZ_THUNDERBIRD
// Since the new mail notification alert isn't ready for primetype yet,
// tie it to the showPreviewText pref so testers can try it out
// in their builds...
PRBool useNewAlert = PR_FALSE;
if (prefBranch)
prefBranch->GetBoolPref("mail.showPreviewText", &useNewAlert);
if (useNewAlert)
{
nsCOMPtr<nsISupportsArray> argsArray;
rv = NS_NewISupportsArray(getter_AddRefs(argsArray));
NS_ENSURE_SUCCESS(rv, rv);
// pass in the array of folders with unread messages
nsCOMPtr<nsISupportsInterfacePointer> ifptr = do_CreateInstance(NS_SUPPORTS_INTERFACE_POINTER_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
ifptr->SetData(mFoldersWithNewMail);
ifptr->SetDataIID(&NS_GET_IID(nsISupportsArray));
argsArray->AppendElement(ifptr);
ifptr = do_CreateInstance(NS_SUPPORTS_INTERFACE_POINTER_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr <nsISupports> supports = do_QueryInterface(NS_STATIC_CAST(nsIMessengerOSIntegration*, this));
ifptr->SetData(supports);
ifptr->SetDataIID(&NS_GET_IID(nsIObserver));
argsArray->AppendElement(ifptr);
nsCOMPtr<nsIWindowWatcher> wwatch(do_GetService(NS_WINDOWWATCHER_CONTRACTID));
nsCOMPtr<nsIDOMWindow> newWindow;
rv = wwatch->OpenWindow(0, ALERT_CHROME_URL, "_blank",
"chrome,dialog=yes,titlebar=no,popup=yes", argsArray,
getter_AddRefs(newWindow));
mAlertInProgress = PR_TRUE;
}
else
{
// this code will go away when the new alert service is ready to be turned on...
nsCOMPtr<nsIAlertsService> alertsService (do_GetService(NS_ALERTSERVICE_CONTRACTID, &rv));
if (NS_SUCCEEDED(rv))
{
rv = alertsService->ShowAlertNotification(NS_LITERAL_STRING(NEW_MAIL_ALERT_ICON), nsDependentString(aAlertTitle),
nsDependentString(aAlertText), PR_TRUE,
NS_ConvertASCIItoUTF16(aFolderURI), this);
mAlertInProgress = PR_TRUE;
}
}
#else
nsCOMPtr<nsIAlertsService> alertsService (do_GetService(NS_ALERTSERVICE_CONTRACTID, &rv));
if (NS_SUCCEEDED(rv))
{
@ -521,7 +504,6 @@ nsresult nsMessengerWinIntegration::ShowAlertMessage(const PRUnichar * aAlertTit
NS_ConvertASCIItoUTF16(aFolderURI), this);
mAlertInProgress = PR_TRUE;
}
#endif
}
if (!showAlert || NS_FAILED(rv)) // go straight to showing the system tray icon.
@ -529,6 +511,68 @@ nsresult nsMessengerWinIntegration::ShowAlertMessage(const PRUnichar * aAlertTit
return rv;
}
#else
// Opening Thunderbird's new mail alert notification window
// aUseAnimation --> true if the window should be opened with animation, false if we want to
// just open the window and leave it open until the user closes it.
nsresult nsMessengerWinIntegration::ShowNewAlertNotification(PRBool aUseAnimation)
{
nsresult rv;
// if we are already in the process of showing an alert, don't try to show another....
if (mAlertInProgress)
return NS_OK;
nsCOMPtr<nsIPrefBranch> prefBranch(do_GetService(NS_PREFSERVICE_CONTRACTID, &rv));
PRBool showAlert = PR_TRUE;
if (prefBranch)
prefBranch->GetBoolPref(SHOW_ALERT_PREF, &showAlert);
if (showAlert)
{
nsCOMPtr<nsISupportsArray> argsArray;
rv = NS_NewISupportsArray(getter_AddRefs(argsArray));
NS_ENSURE_SUCCESS(rv, rv);
// pass in the array of folders with unread messages
nsCOMPtr<nsISupportsInterfacePointer> ifptr = do_CreateInstance(NS_SUPPORTS_INTERFACE_POINTER_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
ifptr->SetData(mFoldersWithNewMail);
ifptr->SetDataIID(&NS_GET_IID(nsISupportsArray));
argsArray->AppendElement(ifptr);
// pass in the observer
ifptr = do_CreateInstance(NS_SUPPORTS_INTERFACE_POINTER_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr <nsISupports> supports = do_QueryInterface(NS_STATIC_CAST(nsIMessengerOSIntegration*, this));
ifptr->SetData(supports);
ifptr->SetDataIID(&NS_GET_IID(nsIObserver));
argsArray->AppendElement(ifptr);
// pass in the animation flag
nsCOMPtr<nsISupportsPRBool> scriptableUseAnimation (do_CreateInstance(NS_SUPPORTS_PRBOOL_CONTRACTID, &rv));
NS_ENSURE_SUCCESS(rv, rv);
scriptableUseAnimation->SetData(aUseAnimation);
argsArray->AppendElement(scriptableUseAnimation);
nsCOMPtr<nsIWindowWatcher> wwatch(do_GetService(NS_WINDOWWATCHER_CONTRACTID));
nsCOMPtr<nsIDOMWindow> newWindow;
rv = wwatch->OpenWindow(0, ALERT_CHROME_URL, "_blank",
"chrome,dialog=yes,titlebar=no,popup=yes", argsArray,
getter_AddRefs(newWindow));
mAlertInProgress = PR_TRUE;
}
// if the user has turned off the mail alert, or openWindow generated an error,
// then go straight to the system tray.
if (!showAlert || NS_FAILED(rv))
AlertFinished();
return rv;
}
#endif
nsresult nsMessengerWinIntegration::AlertFinished()
{
@ -634,7 +678,11 @@ void nsMessengerWinIntegration::FillToolTipInfo()
if (!mBiffIconVisible)
{
#ifndef MOZ_THUNDERBIRD
ShowAlertMessage(accountName, animatedAlertText.get(), "");
#else
ShowNewAlertNotification(PR_TRUE);
#endif
}
else
GenericShellNotify( NIM_MODIFY);

View File

@ -85,6 +85,10 @@ public:
NS_DECL_NSIFOLDERLISTENER
NS_DECL_NSIOBSERVER
#ifdef MOZ_THUNDERBIRD
nsresult ShowNewAlertNotification(PRBool aAnimateAlert);
#endif
private:
nsresult AlertFinished();
nsresult AlertClicked();
@ -100,7 +104,9 @@ private:
void RevertToNonUnicodeShellAPI();
PRUint32 GetToolTipSize(); // available space for the tooltip string
#ifndef MOZ_THUNDERBIRD
nsresult ShowAlertMessage(const PRUnichar * aAlertTitle, const PRUnichar * aAlertText, const char * aFolderURI);
#endif
nsresult GetFirstFolderWithNewMail(char ** aFolderURI);
nsresult GetStringBundle(nsIStringBundle **aBundle);