Back to index

lightning-sunbird  0.9+nobinonly
nsDownloadListener.mm
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) 2002
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *   Simon Fraser <sfraser@netscape.com>
00024  *
00025  * Alternatively, the contents of this file may be used under the terms of
00026  * either the GNU General Public License Version 2 or later (the "GPL"), or
00027  * 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 #import "NSString+Utils.h"
00040 
00041 #include "nsDownloadListener.h"
00042 
00043 #include "nsIWebProgress.h"
00044 #include "nsIRequest.h"
00045 #include "nsIURL.h"
00046 #include "netCore.h"
00047 
00048 nsDownloadListener::nsDownloadListener(DownloadControllerFactory* inControllerFactory)
00049 : CHDownloader(inControllerFactory)
00050 , mBypassCache(PR_FALSE)
00051 , mNetworkTransfer(PR_FALSE)
00052 , mGotFirstStateChange(PR_FALSE)
00053 , mUserCanceled(PR_FALSE)
00054 {
00055 }
00056 
00057 nsDownloadListener::~nsDownloadListener()
00058 {
00059 }
00060 
00061 NS_IMPL_ISUPPORTS_INHERITED4(nsDownloadListener, CHDownloader, nsIDownload,
00062                              nsITransfer, nsIWebProgressListener,
00063                              nsIWebProgressListener2)
00064 
00065 #pragma mark -
00066 
00067 /* void init (in nsIURI aSource, in nsILocalFile aTarget, in AString aDisplayName, in wstring openingWith, in long long startTime, in nsILocalFile aTempFile, in nsICancelable aCancelable); */
00068 NS_IMETHODIMP
00069 nsDownloadListener::Init(nsIURI *aSource, nsILocalFile *aTarget, const nsAString &aDisplayName,
00070         nsIMIMEInfo *aMIMEInfo, PRInt64 startTime, nsILocalFile* aTempFile,
00071         nsICancelable* aCancelable)
00072 { 
00073   CreateDownloadDisplay(); // call the base class to make the download UI
00074 
00075   // Note: This forms a cycle, which will be broken in DownloadDone
00076   mCancelable = aCancelable;
00077 
00078   // This is a file save if the cancelable object is a webbrowserpersist
00079   nsCOMPtr<nsIWebBrowserPersist> persist(do_QueryInterface(aCancelable));
00080   SetIsFileSave(persist != NULL);
00081   
00082   mDestination = aTarget;
00083   mURI = aSource;
00084   mStartTime = startTime;
00085 
00086   InitDialog();
00087   return NS_OK;
00088 }
00089 
00090 /* readonly attribute nsIURI source; */
00091 NS_IMETHODIMP
00092 nsDownloadListener::GetSource(nsIURI * *aSource)
00093 {
00094   NS_ENSURE_ARG_POINTER(aSource);
00095   NS_IF_ADDREF(*aSource = mURI);
00096   return NS_OK;
00097 }
00098 
00099 /* readonly attribute nsILocalFile target; */
00100 NS_IMETHODIMP
00101 nsDownloadListener::GetTarget(nsILocalFile * *aTarget)
00102 {
00103   NS_ENSURE_ARG_POINTER(aTarget);
00104   NS_IF_ADDREF(*aTarget = mDestination);
00105   return NS_OK;
00106 }
00107 
00108 /* readonly attribute nsICancelable cancelable; */
00109 NS_IMETHODIMP
00110 nsDownloadListener::GetCancelable(nsICancelable * *aCancelable)
00111 {
00112   NS_ENSURE_ARG_POINTER(aCancelable);
00113   NS_IF_ADDREF(*aCancelable = mCancelable);
00114   return NS_OK;
00115 }
00116 
00117 /* readonly attribute PRInt32 percentComplete; */
00118 NS_IMETHODIMP
00119 nsDownloadListener::GetPercentComplete(PRInt32 *aPercentComplete)
00120 {
00121   return NS_ERROR_NOT_IMPLEMENTED;
00122 }
00123 
00124 /* readonly attribute PRUint64 amountTransferred; */
00125 NS_IMETHODIMP
00126 nsDownloadListener::GetAmountTransferred(PRUint64 *aAmountTransferred)
00127 {
00128   return NS_ERROR_NOT_IMPLEMENTED;
00129 }
00130 
00131 /* readonly attribute PRUint64 size; */
00132 NS_IMETHODIMP
00133 nsDownloadListener::GetSize(PRUint64 *aSize)
00134 {
00135   return NS_ERROR_NOT_IMPLEMENTED;
00136 }
00137 
00138 /* attribute wstring displayName; */
00139 NS_IMETHODIMP
00140 nsDownloadListener::GetDisplayName(PRUnichar * *aDisplayName)
00141 {
00142   return NS_ERROR_NOT_IMPLEMENTED;
00143 }
00144 
00145 /* readonly attribute long long startTime; */
00146 NS_IMETHODIMP
00147 nsDownloadListener::GetStartTime(PRInt64 *aStartTime)
00148 {
00149   NS_ENSURE_ARG(aStartTime);
00150   *aStartTime = mStartTime;
00151   return NS_OK;
00152 }
00153 
00154 /* readonly attribute nsIMIMEInfo MIMEInfo; */
00155 NS_IMETHODIMP
00156 nsDownloadListener::GetMIMEInfo(nsIMIMEInfo * *aMIMEInfo)
00157 {
00158   return NS_ERROR_NOT_IMPLEMENTED;
00159 }
00160 
00161 /* attribute nsIWebProgressListener listener; */
00162 NS_IMETHODIMP
00163 nsDownloadListener::GetListener(nsIWebProgressListener * *aListener)
00164 {
00165   NS_ENSURE_ARG_POINTER(aListener);
00166   NS_IF_ADDREF(*aListener = (nsIWebProgressListener *)this);
00167   return NS_OK;
00168 }
00169 
00170 NS_IMETHODIMP
00171 nsDownloadListener::SetListener(nsIWebProgressListener * aListener)
00172 {
00173   return NS_ERROR_NOT_IMPLEMENTED;
00174 }
00175 
00176 #pragma mark -
00177 
00178 /* void onProgressChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in long aCurSelfProgress, in long aMaxSelfProgress, in long aCurTotalProgress, in long aMaxTotalProgress); */
00179 NS_IMETHODIMP 
00180 nsDownloadListener::OnProgressChange(nsIWebProgress *aWebProgress, 
00181                                       nsIRequest *aRequest, 
00182                                       PRInt32 aCurSelfProgress, 
00183                                       PRInt32 aMaxSelfProgress, 
00184                                       PRInt32 aCurTotalProgress, 
00185                                       PRInt32 aMaxTotalProgress)
00186 {
00187   if (mUserCanceled)
00188   {
00189     if (aRequest)
00190       aRequest->Cancel(NS_BINDING_ABORTED);
00191       
00192     mUserCanceled = false;
00193   }
00194   
00195   [mDownloadDisplay setProgressTo:aCurTotalProgress ofMax:aMaxTotalProgress];
00196   return NS_OK;
00197 }
00198 
00199 /* void onProgressChange64 (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in long long aCurSelfProgress, in long long aMaxSelfProgress, in long long aCurTotalProgress, in long long aMaxTotalProgress); */
00200 NS_IMETHODIMP 
00201 nsDownloadListener::OnProgressChange64(nsIWebProgress *aWebProgress, 
00202                                        nsIRequest *aRequest, 
00203                                        PRInt64 aCurSelfProgress, 
00204                                        PRInt64 aMaxSelfProgress, 
00205                                        PRInt64 aCurTotalProgress, 
00206                                        PRInt64 aMaxTotalProgress)
00207 {
00208   // XXX truncates 64-bit to 32-bit
00209   return OnProgressChange(aProgress, aRequest,
00210                           PRInt32(curSelfProgress), PRInt32(maxSelfProgress),
00211                           PRInt32(curTotalProgress), PRInt32(maxTotalProgress));
00212 
00213 }
00214 
00215 
00216 /* void onLocationChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in nsIURI location); */
00217 NS_IMETHODIMP 
00218 nsDownloadListener::OnLocationChange(nsIWebProgress *aWebProgress, 
00219            nsIRequest *aRequest, 
00220            nsIURI *location)
00221 {
00222   return NS_OK;
00223 }
00224 
00225 /* void onStatusChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in nsresult aStatus, in wstring aMessage); */
00226 NS_IMETHODIMP 
00227 nsDownloadListener::OnStatusChange(nsIWebProgress *aWebProgress, 
00228                nsIRequest *aRequest, 
00229                nsresult aStatus, 
00230                const PRUnichar *aMessage)
00231 {
00232   return NS_OK;
00233 }
00234 
00235 /* void onSecurityChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in unsigned long state); */
00236 NS_IMETHODIMP 
00237 nsDownloadListener::OnSecurityChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, PRUint32 state)
00238 {
00239   return NS_OK;
00240 }
00241 
00242 // Implementation of nsIWebProgressListener
00243 /* void onStateChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in unsigned long aStateFlags, in unsigned long aStatus); */
00244 NS_IMETHODIMP 
00245 nsDownloadListener::OnStateChange(nsIWebProgress *aWebProgress,  nsIRequest *aRequest,  PRUint32 aStateFlags, 
00246                                     PRUint32 aStatus)
00247 {
00248   NSLog(@"State changed: state %u, status %u", aStateFlags, aStatus);  
00249 
00250   if (!mGotFirstStateChange) {
00251     mNetworkTransfer = ((aStateFlags & STATE_IS_NETWORK) != 0);
00252     mGotFirstStateChange = PR_TRUE;
00253   }
00254   
00255   // when the entire download finishes, stop the progress timer and clean up
00256   // the window and controller. We will get this even in the event of a cancel,
00257   // so this is the only place in the listener where we should kill the download.
00258   if ((aStateFlags & STATE_STOP) && (!mNetworkTransfer || (aStateFlags & STATE_IS_NETWORK))) {
00259     DownloadDone();
00260   }
00261   return NS_OK; 
00262 }
00263 
00264 #pragma mark -
00265 
00266 void
00267 nsDownloadListener::InitDialog()
00268 {
00269   // dialog has to be shown before the outlets get hooked up
00270   [mDownloadDisplay onStartDownload:(BOOL)IsFileSave()];
00271 
00272   if (mURI)
00273   {
00274     nsCAutoString spec;
00275     mURI->GetSpec(spec);
00276     [mDownloadDisplay setSourceURL: [NSString stringWithUTF8String:spec.get()]];
00277   }
00278 
00279   nsAutoString pathStr;
00280   mDestination->GetPath(pathStr);
00281   [mDownloadDisplay setDestinationPath: [NSString stringWith_nsAString:pathStr]];
00282 }
00283 
00284 void
00285 nsDownloadListener::PauseDownload()
00286 {
00287   // write me
00288 }
00289 
00290 void
00291 nsDownloadListener::ResumeDownload()
00292 {
00293   // write me
00294 }
00295 
00296 void
00297 nsDownloadListener::CancelDownload()
00298 {
00299   mUserCanceled = PR_TRUE;
00300 
00301   if (mWebPersist)
00302   {
00303     mWebPersist->CancelSave();
00304     mUserCanceled = PR_FALSE;
00305   }
00306   
00307   // delete any files we've created...
00308   
00309   
00310 }
00311 
00312 void
00313 nsDownloadListener::DownloadDone()
00314 {
00315   // break the reference cycle by removing ourselves as a listener
00316   if (mWebPersist)
00317   {
00318     mWebPersist->SetProgressListener(nsnull);
00319     mWebPersist = nsnull;
00320   }
00321 
00322   [mDownloadDisplay onEndDownload];
00323 }
00324 
00325 //
00326 // DetachDownloadDisplay
00327 //
00328 // there are times when the download dislpay UI goes away before the
00329 // listener (quit, for example). This alerts us that we should forget all
00330 // about having any UI.
00331 //
00332 void
00333 nsDownloadListener::DetachDownloadDisplay()
00334 {
00335   mDownloadDisplay = nil;
00336 }
00337 
00338 #pragma mark -