Back to index

lightning-sunbird  0.9+nobinonly
nsMsgSendReport.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is mozilla.org code.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 1998
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *   Jean-Francois Ducarroz <ducarroz@netscape.com>
00024  *
00025  * Alternatively, the contents of this file may be used under the terms of
00026  * either of the GNU General Public License Version 2 or later (the "GPL"),
00027  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00028  * in which case the provisions of the GPL or the LGPL are applicable instead
00029  * of those above. If you wish to allow use of your version of this file only
00030  * under the terms of either the GPL or the LGPL, and not to allow others to
00031  * use your version of this file under the terms of the MPL, indicate your
00032  * decision by deleting the provisions above and replace them with the notice
00033  * and other provisions required by the GPL or the LGPL. If you do not delete
00034  * the provisions above, a recipient may use your version of this file under
00035  * the terms of any one of the MPL, the GPL or the LGPL.
00036  *
00037  * ***** END LICENSE BLOCK ***** */
00038 
00039 #include "nsMsgSendReport.h"
00040 
00041 #include "msgCore.h"
00042 #include "nsIMsgCompose.h"
00043 #include "nsMsgComposeStringBundle.h"
00044 #include "nsMsgCompCID.h"
00045 #include "nsMsgPrompts.h"
00046 #include "nsReadableUtils.h"
00047 #include "nsNetError.h"
00048 
00049 NS_IMPL_ISUPPORTS1(nsMsgProcessReport, nsIMsgProcessReport)
00050 
00051 nsMsgProcessReport::nsMsgProcessReport()
00052 {
00053   Reset();
00054 }
00055 
00056 nsMsgProcessReport::~nsMsgProcessReport()
00057 {
00058 }
00059 
00060 /* attribute boolean proceeded; */
00061 NS_IMETHODIMP nsMsgProcessReport::GetProceeded(PRBool *aProceeded)
00062 {
00063   NS_ENSURE_ARG_POINTER(aProceeded);
00064   *aProceeded = mProceeded;
00065   return NS_OK;
00066 }
00067 NS_IMETHODIMP nsMsgProcessReport::SetProceeded(PRBool aProceeded)
00068 {
00069   mProceeded = aProceeded;
00070   return NS_OK;
00071 }
00072 
00073 /* attribute nsresult error; */
00074 NS_IMETHODIMP nsMsgProcessReport::GetError(nsresult *aError)
00075 {
00076   NS_ENSURE_ARG_POINTER(aError);
00077   *aError = mError;
00078   return NS_OK;
00079 }
00080 NS_IMETHODIMP nsMsgProcessReport::SetError(nsresult aError)
00081 {
00082   mError = aError;
00083   return NS_OK;
00084 }
00085 
00086 /* attribute wstring message; */
00087 NS_IMETHODIMP nsMsgProcessReport::GetMessage(PRUnichar * *aMessage)
00088 {
00089   NS_ENSURE_ARG_POINTER(aMessage);
00090   *aMessage = ToNewUnicode(mMessage);
00091   return NS_OK;
00092 }
00093 NS_IMETHODIMP nsMsgProcessReport::SetMessage(const PRUnichar * aMessage)
00094 {
00095   mMessage = aMessage;
00096   return NS_OK;
00097 }
00098 
00099 /* void Reset (); */
00100 NS_IMETHODIMP nsMsgProcessReport::Reset()
00101 {
00102   mProceeded = PR_FALSE;
00103   mError = NS_OK;
00104   mMessage.Truncate();
00105 
00106   return NS_OK;
00107 }
00108 
00109 
00110 NS_IMPL_ISUPPORTS1(nsMsgSendReport, nsIMsgSendReport)
00111 
00112 nsMsgSendReport::nsMsgSendReport()
00113 {
00114   PRUint32 i;
00115   for (i = 0; i <= SEND_LAST_PROCESS; i ++)
00116     NS_NEWXPCOM(mProcessReport[i], nsMsgProcessReport);
00117 
00118   Reset(); 
00119 }
00120 
00121 nsMsgSendReport::~nsMsgSendReport()
00122 {
00123   PRUint32 i;
00124   for (i = 0; i <= SEND_LAST_PROCESS; i ++)
00125     mProcessReport[i] = nsnull;
00126 }
00127 
00128 /* attribute long currentProcess; */
00129 NS_IMETHODIMP nsMsgSendReport::GetCurrentProcess(PRInt32 *aCurrentProcess)
00130 {
00131   NS_ENSURE_ARG_POINTER(aCurrentProcess);
00132   *aCurrentProcess = mCurrentProcess;
00133   return NS_OK;
00134 }
00135 NS_IMETHODIMP nsMsgSendReport::SetCurrentProcess(PRInt32 aCurrentProcess)
00136 {
00137   if (aCurrentProcess < 0 || aCurrentProcess > SEND_LAST_PROCESS)
00138     return NS_ERROR_ILLEGAL_VALUE;
00139 
00140   mCurrentProcess = aCurrentProcess;
00141   if (mProcessReport[mCurrentProcess])
00142     mProcessReport[mCurrentProcess]->SetProceeded(PR_TRUE);
00143   
00144   return NS_OK;
00145 }
00146 
00147 /* attribute long deliveryMode; */
00148 NS_IMETHODIMP nsMsgSendReport::GetDeliveryMode(PRInt32 *aDeliveryMode)
00149 {
00150   NS_ENSURE_ARG_POINTER(aDeliveryMode);
00151   *aDeliveryMode = mDeliveryMode;
00152   return NS_OK;
00153 }
00154 NS_IMETHODIMP nsMsgSendReport::SetDeliveryMode(PRInt32 aDeliveryMode)
00155 {
00156   mDeliveryMode = aDeliveryMode;
00157   return NS_OK;
00158 }
00159 
00160 /* void Reset (); */
00161 NS_IMETHODIMP nsMsgSendReport::Reset()
00162 {
00163   PRUint32 i;
00164   for (i = 0; i <= SEND_LAST_PROCESS; i ++)
00165     if (mProcessReport[i])
00166       mProcessReport[i]->Reset();
00167 
00168   mCurrentProcess = 0;
00169   mDeliveryMode = 0;
00170   mAlreadyDisplayReport = PR_FALSE;
00171 
00172   return NS_OK;
00173 }
00174 
00175 /* void setProceeded (in long process, in boolean proceeded); */
00176 NS_IMETHODIMP nsMsgSendReport::SetProceeded(PRInt32 process, PRBool proceeded)
00177 {
00178   if (process < process_Current || process > SEND_LAST_PROCESS)
00179     return NS_ERROR_ILLEGAL_VALUE;
00180     
00181   if (process == process_Current)
00182     process = mCurrentProcess;
00183     
00184   if (!mProcessReport[process])
00185     return NS_ERROR_NOT_INITIALIZED;
00186 
00187   return mProcessReport[process]->SetProceeded(proceeded);
00188 }
00189 
00190 /* void setError (in long process, in nsresult error, in boolean overwriteError); */
00191 NS_IMETHODIMP nsMsgSendReport::SetError(PRInt32 process, nsresult newError, PRBool overwriteError)
00192 {
00193   if (process < process_Current || process > SEND_LAST_PROCESS)
00194     return NS_ERROR_ILLEGAL_VALUE;
00195   
00196   if (process == process_Current)
00197     process = mCurrentProcess;
00198     
00199   if (!mProcessReport[process])
00200     return NS_ERROR_NOT_INITIALIZED;
00201 
00202   nsresult currError = NS_OK;
00203   mProcessReport[process]->GetError(&currError);
00204   if (overwriteError || currError == NS_OK)
00205     return mProcessReport[process]->SetError(newError);
00206   else
00207     return NS_OK;
00208 }
00209 
00210 /* void setMessage (in long process, in wstring message, in boolean overwriteMessage); */
00211 NS_IMETHODIMP nsMsgSendReport::SetMessage(PRInt32 process, const PRUnichar *message, PRBool overwriteMessage)
00212 {
00213   if (process < process_Current || process > SEND_LAST_PROCESS)
00214     return NS_ERROR_ILLEGAL_VALUE;
00215     
00216   if (process == process_Current)
00217     process = mCurrentProcess;
00218     
00219   if (!mProcessReport[process])
00220     return NS_ERROR_NOT_INITIALIZED;
00221 
00222   nsXPIDLString currMessage;
00223   mProcessReport[process]->GetMessage(getter_Copies(currMessage));
00224   if (overwriteMessage || (!currMessage) || (const char *)currMessage[0] == 0)
00225     return mProcessReport[process]->SetMessage(message);
00226   else
00227     return NS_OK;
00228 }
00229 
00230 /* nsIMsgProcessReport getProcessReport (in long process); */
00231 NS_IMETHODIMP nsMsgSendReport::GetProcessReport(PRInt32 process, nsIMsgProcessReport **_retval)
00232 {
00233   NS_ENSURE_ARG_POINTER(_retval);
00234   if (process < process_Current || process > SEND_LAST_PROCESS)
00235     return NS_ERROR_ILLEGAL_VALUE;
00236 
00237   if (process == process_Current)
00238     process = mCurrentProcess;
00239     
00240   *_retval = mProcessReport[process];
00241   NS_IF_ADDREF(*_retval);
00242   return NS_OK;
00243 }
00244 
00245 /* nsresult displayReport (in nsIPrompt prompt, in boolean showErrorOnly, in boolean dontShowReportTwice); */
00246 NS_IMETHODIMP nsMsgSendReport::DisplayReport(nsIPrompt *prompt, PRBool showErrorOnly, PRBool dontShowReportTwice, nsresult *_retval)
00247 {
00248   NS_ENSURE_ARG_POINTER(_retval);
00249 
00250   nsresult currError = NS_OK;
00251   mProcessReport[mCurrentProcess]->GetError(&currError);
00252   *_retval = currError;
00253   
00254   if (dontShowReportTwice && mAlreadyDisplayReport)
00255     return NS_OK;
00256   
00257   if (showErrorOnly && NS_SUCCEEDED(currError))
00258     return NS_OK;
00259   
00260   nsXPIDLString currMessage;
00261   mProcessReport[mCurrentProcess]->GetMessage(getter_Copies(currMessage));
00262 
00263 
00264   nsCOMPtr<nsIMsgStringService> composebundle (do_GetService(NS_MSG_COMPOSESTRINGSERVICE_CONTRACTID));
00265   if (!composebundle)
00266   {
00267     //TODO need to display a generic hardcoded message
00268     mAlreadyDisplayReport = PR_TRUE;
00269     return NS_OK;
00270   }
00271 
00272   nsXPIDLString dialogTitle;
00273   nsXPIDLString dialogMessage;
00274 
00275   if (NS_SUCCEEDED(currError))
00276   {
00277     //TODO display a success error message
00278     return NS_OK;
00279   }
00280   
00281   //Do we have an explanation of the error? if no, try to build one...
00282   if (currMessage.IsEmpty())
00283   {
00284       switch (currError)
00285       {
00286         case NS_BINDING_ABORTED:
00287         case NS_ERROR_SEND_FAILED:
00288         case NS_ERROR_SEND_FAILED_BUT_NNTP_OK:
00289         case NS_MSG_FAILED_COPY_OPERATION:
00290         case NS_MSG_UNABLE_TO_SEND_LATER:
00291         case NS_MSG_UNABLE_TO_SAVE_DRAFT:
00292         case NS_MSG_UNABLE_TO_SAVE_TEMPLATE:
00293           //Ignore, don't need to repeat ourself.
00294           break;
00295         case NS_ERROR_MSG_MULTILINGUAL_SEND:
00296           // already displayed an alert, no additional message is needed
00297           // return to the compose window
00298           mAlreadyDisplayReport = PR_TRUE;
00299           return NS_OK;
00300         default:
00301           nsAutoString errorMsg;
00302           nsMsgBuildErrorMessageByID(currError, errorMsg);
00303 
00304           if (! errorMsg.IsEmpty())
00305             currMessage.Assign(errorMsg);
00306           break;
00307       }
00308   }
00309   
00310   if (mDeliveryMode == nsIMsgCompDeliverMode::Now || mDeliveryMode == nsIMsgCompDeliverMode::SendUnsent)
00311   {
00312     // SMTP is taking care of it's own error message and will return NS_ERROR_BUT_DONT_SHOW_ALERT as error code.
00313     // In that case, we must not show an alert ourself.
00314     if (currError == NS_ERROR_BUT_DONT_SHOW_ALERT)
00315     {
00316       mAlreadyDisplayReport = PR_TRUE;
00317       return NS_OK;
00318     }
00319   
00320     composebundle->GetStringByID(NS_MSG_SEND_ERROR_TITLE, getter_Copies(dialogTitle));
00321 
00322     PRInt32 preStrId = NS_ERROR_SEND_FAILED;
00323     PRBool askToGoBackToCompose = PR_FALSE;
00324     switch (mCurrentProcess)
00325     {
00326       case process_BuildMessage :
00327         preStrId = NS_ERROR_SEND_FAILED;
00328         askToGoBackToCompose = PR_FALSE;
00329         break;
00330       case process_NNTP :
00331         preStrId = NS_ERROR_SEND_FAILED;
00332         askToGoBackToCompose = PR_FALSE;
00333         break;
00334       case process_SMTP :
00335         PRBool nntpProceeded;
00336         mProcessReport[process_NNTP]->GetProceeded(&nntpProceeded);
00337         if (nntpProceeded)
00338           preStrId = NS_ERROR_SEND_FAILED_BUT_NNTP_OK;
00339         else
00340           preStrId = NS_ERROR_SEND_FAILED;
00341         askToGoBackToCompose = PR_FALSE;
00342         break;
00343       case process_Copy:
00344         preStrId = NS_MSG_FAILED_COPY_OPERATION;
00345         askToGoBackToCompose = (mDeliveryMode == nsIMsgCompDeliverMode::Now);
00346         break;
00347       case process_FCC:
00348         preStrId = NS_MSG_FAILED_COPY_OPERATION;
00349         askToGoBackToCompose = (mDeliveryMode == nsIMsgCompDeliverMode::Now);
00350         break;
00351     }
00352     composebundle->GetStringByID(preStrId, getter_Copies(dialogMessage));
00353 
00354     //Do we already have an error message?
00355     if (!askToGoBackToCompose && currMessage.IsEmpty())
00356     {
00357       //we don't have an error description but we can put a generic explanation
00358       composebundle->GetStringByID(NS_MSG_GENERIC_FAILURE_EXPLANATION, getter_Copies(currMessage));
00359     }
00360     
00361     if (!currMessage.IsEmpty())
00362     {
00363       nsAutoString temp((const PRUnichar *)dialogMessage);  // Because of bug 74726, we cannot use directly an XPIDLString
00364 
00365       //Don't need to repeat ourself!
00366       if (! currMessage.Equals(temp))
00367       {
00368         if (! dialogMessage.IsEmpty())
00369           temp.AppendLiteral("\n");
00370         temp.Append(currMessage);
00371         dialogMessage.Assign(temp);
00372       }
00373     }
00374       
00375     if (askToGoBackToCompose)
00376     {
00377       PRBool oopsGiveMeBackTheComposeWindow = PR_TRUE;
00378       nsXPIDLString text1;
00379       composebundle->GetStringByID(NS_MSG_ASK_TO_COMEBACK_TO_COMPOSE, getter_Copies(text1));
00380       nsAutoString temp((const PRUnichar *)dialogMessage);  // Because of bug 74726, we cannot use directly an XPIDLString
00381       if (! dialogMessage.IsEmpty())
00382         temp.AppendLiteral("\n");
00383       temp.Append(text1);
00384       dialogMessage.Assign(temp);
00385       nsMsgAskBooleanQuestionByString(prompt, dialogMessage, &oopsGiveMeBackTheComposeWindow, dialogTitle);
00386       if (!oopsGiveMeBackTheComposeWindow)
00387         *_retval = NS_OK;
00388     }
00389     else
00390       nsMsgDisplayMessageByString(prompt, dialogMessage, dialogTitle);
00391   }
00392   else
00393   {
00394     PRInt32 titleID;
00395     PRInt32 preStrId;
00396 
00397     switch (mDeliveryMode)
00398     {
00399       case nsIMsgCompDeliverMode::Later:
00400         titleID = NS_MSG_SENDLATER_ERROR_TITLE;
00401         preStrId = NS_MSG_UNABLE_TO_SEND_LATER;
00402         break;
00403 
00404       case nsIMsgCompDeliverMode::AutoSaveAsDraft:
00405       case nsIMsgCompDeliverMode::SaveAsDraft:
00406         titleID = NS_MSG_SAVE_DRAFT_TITLE;
00407         preStrId = NS_MSG_UNABLE_TO_SAVE_DRAFT;
00408         break;
00409 
00410       case nsIMsgCompDeliverMode::SaveAsTemplate:
00411         titleID = NS_MSG_SAVE_TEMPLATE_TITLE;
00412         preStrId = NS_MSG_UNABLE_TO_SAVE_TEMPLATE;
00413         break;
00414 
00415       default:
00416         /* This should never happend! */
00417         titleID = NS_MSG_SEND_ERROR_TITLE;
00418         preStrId = NS_ERROR_SEND_FAILED;
00419         break;
00420     }
00421 
00422     composebundle->GetStringByID(titleID, getter_Copies(dialogTitle));
00423     composebundle->GetStringByID(preStrId, getter_Copies(dialogMessage));
00424 
00425     //Do we have an error message...
00426     if (currMessage.IsEmpty())
00427     {
00428       //we don't have an error description but we can put a generic explanation
00429       composebundle->GetStringByID(NS_MSG_GENERIC_FAILURE_EXPLANATION, getter_Copies(currMessage));
00430     }
00431 
00432     if (!currMessage.IsEmpty())
00433     {
00434       nsAutoString temp((const PRUnichar *)dialogMessage);  // Because of bug 74726, we cannot use directly an XPIDLString
00435       if (! dialogMessage.IsEmpty())
00436         temp.AppendLiteral("\n");
00437       temp.Append(currMessage);
00438       dialogMessage.Assign(temp);
00439     }
00440 
00441     nsMsgDisplayMessageByString(prompt, dialogMessage, dialogTitle);
00442   }
00443   
00444   mAlreadyDisplayReport = PR_TRUE;
00445   return NS_OK;
00446 }
00447