You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

263 lines
6.5 KiB
C++

#include "config.h"
#include <nsIFactory.h>
#include <nsIFile.h>
#include <nsIFileURL.h>
#include <nsServiceManagerUtils.h>
#include <nsIMIMEService.h>
#include "sugar-download-manager.h"
#include "GeckoDownload.h"
#define APPLICATION_OCTET_STREAM "application/octet-stream"
class GeckoDownload : public nsITransfer
{
public:
GeckoDownload();
virtual ~GeckoDownload();
NS_DECL_ISUPPORTS
NS_DECL_NSIWEBPROGRESSLISTENER
NS_DECL_NSIWEBPROGRESSLISTENER2
NS_DECL_NSITRANSFER
protected:
nsIURI *mSource;
nsCString mTargetFileName;
nsIMIMEInfo *mMIMEInfo;
nsILocalFile *mTempFile;
};
GeckoDownload::GeckoDownload ()
{
}
GeckoDownload::~GeckoDownload ()
{
}
NS_IMPL_ISUPPORTS3 (GeckoDownload,
nsIWebProgressListener,
nsIWebProgressListener2,
nsITransfer)
NS_IMETHODIMP
GeckoDownload::Init (nsIURI *aSource,
nsIURI *aTarget,
const nsAString &aDisplayName,
nsIMIMEInfo *aMIMEInfo,
PRTime aStartTime,
nsILocalFile *aTempFile,
nsICancelable *aCancelable)
{
mSource = aSource;
mMIMEInfo = aMIMEInfo;
mTempFile = aTempFile;
nsresult rv;
nsCOMPtr<nsIFileURL> fileURL = do_QueryInterface(aTarget);
NS_ENSURE_TRUE(fileURL, NS_ERROR_FAILURE);
nsCOMPtr<nsIFile> file;
rv = fileURL->GetFile(getter_AddRefs(file));
NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
file->GetNativePath (mTargetFileName);
return NS_OK;
}
NS_IMETHODIMP
GeckoDownload::OnStateChange(nsIWebProgress *aWebProgress,
nsIRequest *aRequest,
PRUint32 aStateFlags,
nsresult aStatus)
{
SugarDownloadManager *download_manager = sugar_get_download_manager();
if(aStateFlags == STATE_START) {
nsCString url;
nsCString mimeType;
mMIMEInfo->GetMIMEType(mimeType);
mSource->GetSpec(url);
/* If the file is application/octet-stream, look up a better mime type
from the extension. */
if(mimeType.Equals(APPLICATION_OCTET_STREAM)) {
nsresult rv;
nsCOMPtr<nsIMIMEService> mimeService(
do_GetService("@mozilla.org/mime;1", &rv));
NS_ENSURE_SUCCESS(rv, rv);
const char *fileExt = strrchr(mTargetFileName.get(), '.');
if(fileExt) {
nsCString contentType;
mimeService->GetTypeFromExtension(nsCString(fileExt),
contentType);
if(!contentType.IsEmpty()) {
mimeType = contentType;
}
}
}
sugar_download_manager_download_started(download_manager,
url.get(),
mimeType.get(),
mTargetFileName.get());
} else if(aStateFlags == STATE_STOP) {
if(NS_SUCCEEDED(aStatus)) {
sugar_download_manager_download_completed(download_manager,
mTargetFileName.get());
} else {
sugar_download_manager_download_cancelled(download_manager,
mTargetFileName.get());
}
}
return NS_OK;
}
NS_IMETHODIMP
GeckoDownload::OnProgressChange (nsIWebProgress *aWebProgress,
nsIRequest *aRequest,
PRInt32 aCurSelfProgress,
PRInt32 aMaxSelfProgress,
PRInt32 aCurTotalProgress,
PRInt32 aMaxTotalProgress)
{
return OnProgressChange64 (aWebProgress,
aRequest,
aCurSelfProgress,
aMaxSelfProgress,
aCurTotalProgress,
aMaxTotalProgress);
}
NS_IMETHODIMP
GeckoDownload::OnProgressChange64 (nsIWebProgress *aWebProgress,
nsIRequest *aRequest,
PRInt64 aCurSelfProgress,
PRInt64 aMaxSelfProgress,
PRInt64 aCurTotalProgress,
PRInt64 aMaxTotalProgress)
{
SugarDownloadManager *download_manager = sugar_get_download_manager ();
PRInt32 percentComplete =
(PRInt32)(((float)aCurSelfProgress / (float)aMaxSelfProgress) * 100.0);
sugar_download_manager_update_progress (download_manager,
mTargetFileName.get (),
percentComplete);
return NS_OK;
}
NS_IMETHODIMP
GeckoDownload::OnLocationChange (nsIWebProgress *aWebProgress,
nsIRequest *aRequest,
nsIURI *location)
{
return NS_OK;
}
NS_IMETHODIMP
GeckoDownload::OnStatusChange (nsIWebProgress *aWebProgress,
nsIRequest *aRequest,
nsresult aStatus,
const PRUnichar *aMessage)
{
return NS_OK;
}
NS_IMETHODIMP
GeckoDownload::OnSecurityChange (nsIWebProgress *aWebProgress,
nsIRequest *aRequest,
PRUint32 state)
{
return NS_OK;
}
NS_IMETHODIMP
GeckoDownload::OnRefreshAttempted (nsIWebProgress *aWebProgress,
nsIURI *aRefreshURI,
PRInt32 aMillis,
PRBool aSameURI,
PRBool *_retval)
{
return NS_OK;
}
//*****************************************************************************
// GeckoDownloadFactory
//*****************************************************************************
class GeckoDownloadFactory : public nsIFactory {
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIFACTORY
GeckoDownloadFactory();
virtual ~GeckoDownloadFactory();
};
//*****************************************************************************
NS_IMPL_ISUPPORTS1(GeckoDownloadFactory, nsIFactory)
GeckoDownloadFactory::GeckoDownloadFactory() {
}
GeckoDownloadFactory::~GeckoDownloadFactory() {
}
NS_IMETHODIMP
GeckoDownloadFactory::CreateInstance(nsISupports *aOuter, const nsIID & aIID, void **aResult)
{
NS_ENSURE_ARG_POINTER(aResult);
*aResult = NULL;
GeckoDownload *inst = new GeckoDownload;
if (!inst)
return NS_ERROR_OUT_OF_MEMORY;
nsresult rv = inst->QueryInterface(aIID, aResult);
if (rv != NS_OK) {
// We didn't get the right interface, so clean up
delete inst;
}
return rv;
}
NS_IMETHODIMP
GeckoDownloadFactory::LockFactory(PRBool lock)
{
return NS_OK;
}
//*****************************************************************************
nsresult
NS_NewGeckoDownloadFactory(nsIFactory** aFactory)
{
NS_ENSURE_ARG_POINTER(aFactory);
*aFactory = nsnull;
GeckoDownloadFactory *result = new GeckoDownloadFactory;
if (!result)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(result);
*aFactory = result;
return NS_OK;
}