зеркало из https://github.com/mozilla/gecko-dev.git
Touch down progress bar changes from PROGRESS_19981006_BRANCH.
This commit is contained in:
Родитель
1dfaa4ce03
Коммит
c36d1640ce
|
@ -3,3 +3,6 @@
|
||||||
#
|
#
|
||||||
|
|
||||||
pw_public.h
|
pw_public.h
|
||||||
|
nsITransferListener.h
|
||||||
|
nsProgressManager.h
|
||||||
|
progress.h
|
||||||
|
|
|
@ -21,4 +21,12 @@ MODULE = progress
|
||||||
|
|
||||||
EXPORTS = pw_public.h
|
EXPORTS = pw_public.h
|
||||||
|
|
||||||
|
ifdef MOZ_SMOOTH_PROGRESS
|
||||||
|
EXPORTS += \
|
||||||
|
nsITransferListener.h \
|
||||||
|
nsProgressManager.h \
|
||||||
|
progress.h \
|
||||||
|
$(NULL)
|
||||||
|
endif
|
||||||
|
|
||||||
include $(DEPTH)/config/rules.mk
|
include $(DEPTH)/config/rules.mk
|
||||||
|
|
|
@ -20,7 +20,15 @@ IGNORE_MANIFEST=1
|
||||||
|
|
||||||
MODULE=progress
|
MODULE=progress
|
||||||
DEPTH=..\..\..
|
DEPTH=..\..\..
|
||||||
EXPORTS=pw_public.h
|
|
||||||
|
EXPORTS=\
|
||||||
|
!ifdef MOZ_SMOOTH_PROGRESS
|
||||||
|
nsITransferListener.h \
|
||||||
|
nsProgressManager.h \
|
||||||
|
progress.h \
|
||||||
|
!endif
|
||||||
|
pw_public.h \
|
||||||
|
$(NULL)
|
||||||
|
|
||||||
include <$(DEPTH)/config/rules.mak>
|
include <$(DEPTH)/config/rules.mak>
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,20 @@ LIBRARY_NAME = prgrss
|
||||||
|
|
||||||
REQUIRES = progress nspr dbm img layer util
|
REQUIRES = progress nspr dbm img layer util
|
||||||
|
|
||||||
|
ifdef MOZ_SMOOTH_PROGRESS
|
||||||
|
REQUIRES += raptor xpcom
|
||||||
|
endif
|
||||||
|
|
||||||
# all code is platform specific right now
|
# all code is platform specific right now
|
||||||
CPPSRCS = pw_win.cpp pw_unix.cpp pwcommon.cpp
|
CPPSRCS = pw_win.cpp pw_unix.cpp pwcommon.cpp
|
||||||
|
|
||||||
|
ifdef MOZ_SMOOTH_PROGRESS
|
||||||
|
CPPSRCS += nsProgressManager.cpp \
|
||||||
|
nsTopProgressManager.cpp \
|
||||||
|
nsSubProgressManager.cpp \
|
||||||
|
nsTransfer.cpp \
|
||||||
|
progress.cpp \
|
||||||
|
$(NULL)
|
||||||
|
endif
|
||||||
|
|
||||||
include $(DEPTH)/config/rules.mk
|
include $(DEPTH)/config/rules.mk
|
||||||
|
|
|
@ -26,28 +26,63 @@ MAKE_OBJ_TYPE=EXE
|
||||||
|
|
||||||
|
|
||||||
MODULE=progress
|
MODULE=progress
|
||||||
REQUIRES=progress nspr dbm img layer util
|
REQUIRES=progress nspr dbm img layer util xpcom
|
||||||
LIBRARY_NAME=prgrss
|
LIBRARY_NAME=prgrss
|
||||||
DEPTH=..\..\..
|
DEPTH=..\..\..
|
||||||
CPPSRCS=pw_win.cpp pw_unix.cpp pwcommon.cpp
|
|
||||||
CPP_OBJS=.\$(OBJDIR)\pw_win.obj .\$(OBJDIR)\pw_unix.obj \
|
CPPSRCS=\
|
||||||
.\$(OBJDIR)\pwcommon.obj
|
pw_win.cpp \
|
||||||
|
pw_unix.cpp \
|
||||||
|
pwcommon.cpp \
|
||||||
|
!ifdef MOZ_SMOOTH_PROGRESS
|
||||||
|
nsProgressManager.cpp \
|
||||||
|
nsSubProgressManager.cpp \
|
||||||
|
nsTopProgressManager.cpp \
|
||||||
|
nsTransfer.cpp \
|
||||||
|
progress.cpp \
|
||||||
|
!endif
|
||||||
|
$(NULL)
|
||||||
|
|
||||||
|
|
||||||
|
CPP_OBJS=\
|
||||||
|
.\$(OBJDIR)\pw_win.obj \
|
||||||
|
.\$(OBJDIR)\pw_unix.obj \
|
||||||
|
.\$(OBJDIR)\pwcommon.obj \
|
||||||
|
!ifdef MOZ_SMOOTH_PROGRESS
|
||||||
|
.\$(OBJDIR)\nsProgressManager.obj \
|
||||||
|
.\$(OBJDIR)\nsTopProgressManager.obj \
|
||||||
|
.\$(OBJDIR)\nsSubProgressManager.obj \
|
||||||
|
.\$(OBJDIR)\nsTransfer.obj \
|
||||||
|
.\$(OBJDIR)\progress.obj \
|
||||||
|
!endif
|
||||||
|
$(NULL)
|
||||||
|
|
||||||
!if "$(MOZ_BITS)" != "16"
|
!if "$(MOZ_BITS)" != "16"
|
||||||
LINCS=-I$(XPDIST)\public\progress -I$(XPDIST)\public\nspr \
|
LINCS=\
|
||||||
-I$(XPDIST)\public\dbm -I$(XPDIST)\public\img \
|
-I$(XPDIST)\public\progress \
|
||||||
-I$(XPDIST)\public\layer -I$(XPDIST)\public\util
|
-I$(XPDIST)\public\nspr \
|
||||||
|
-I$(XPDIST)\public\dbm \
|
||||||
|
-I$(XPDIST)\public\img \
|
||||||
|
-I$(XPDIST)\public\layer \
|
||||||
|
-I$(XPDIST)\public\util \
|
||||||
|
!ifdef MOZ_SMOOTH_PROGRESS
|
||||||
|
-I$(XPDIST)\public\network \
|
||||||
|
-I$(XPDIST)\public\raptor \
|
||||||
|
-I$(XPDIST)\public\xpcom \
|
||||||
|
!endif
|
||||||
|
$(NULL)
|
||||||
!endif
|
!endif
|
||||||
|
|
||||||
include <$(DEPTH)\config\rules.mak>
|
include <$(DEPTH)\config\rules.mak>
|
||||||
|
|
||||||
# XXX this should not be required, but mantomake doesnt grok J?I yet
|
# XXX this should not be required, but mantomake doesnt grok J?I yet
|
||||||
# also, -I..\public should be -I$(PUBLIC)\progress
|
# also, -I..\public should be -I$(PUBLIC)\progress
|
||||||
LINCS= $(LINCS) \
|
LINCS=$(LINCS) \
|
||||||
-I$(DEPTH)/cmd/winfe \
|
-I$(DEPTH)/cmd/winfe \
|
||||||
-I..\public
|
-I..\public
|
||||||
|
|
||||||
libs:: $(LIBRARY)
|
libs:: $(LIBRARY)
|
||||||
$(MAKE_INSTALL) $(LIBRARY) $(DIST)\lib
|
$(MAKE_INSTALL) $(LIBRARY) $(DIST)\lib
|
||||||
|
|
||||||
clobber::
|
clobber::
|
||||||
$(RM) $(DIST)\lib\$(LIBRARY)
|
$(RM) $(DIST)\lib\$(LIBRARY)
|
||||||
|
|
|
@ -0,0 +1,123 @@
|
||||||
|
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||||
|
*
|
||||||
|
* The contents of this file are subject to the Netscape Public License
|
||||||
|
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||||
|
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||||
|
* http://www.mozilla.org/NPL/
|
||||||
|
*
|
||||||
|
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||||
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||||
|
* for the specific language governing rights and limitations under the
|
||||||
|
* NPL.
|
||||||
|
*
|
||||||
|
* The Initial Developer of this code under the NPL is Netscape
|
||||||
|
* Communications Corporation. Portions created by Netscape are
|
||||||
|
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||||
|
* Reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "nsSubProgressManager.h"
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
nsSubProgressManager::nsSubProgressManager(MWContext* context)
|
||||||
|
: nsProgressManager(context)
|
||||||
|
{
|
||||||
|
// Grab a reference to the parent context's progress manager
|
||||||
|
nsITransferListener* pm = fContext->grid_parent->progressManager;
|
||||||
|
PR_ASSERT(pm);
|
||||||
|
if (pm)
|
||||||
|
pm->AddRef();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
nsSubProgressManager::~nsSubProgressManager(void)
|
||||||
|
{
|
||||||
|
// Release the reference on the parent context's progress manager
|
||||||
|
nsITransferListener* pm = fContext->grid_parent->progressManager;
|
||||||
|
if (pm)
|
||||||
|
pm->Release();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsSubProgressManager::OnStartBinding(const URL_Struct* url)
|
||||||
|
{
|
||||||
|
nsITransferListener* pm = fContext->grid_parent->progressManager;
|
||||||
|
PR_ASSERT(pm);
|
||||||
|
if (! pm)
|
||||||
|
return NS_ERROR_NULL_POINTER;
|
||||||
|
|
||||||
|
return pm->OnStartBinding(url);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsSubProgressManager::OnProgress(const URL_Struct* url,
|
||||||
|
PRUint32 bytesReceived,
|
||||||
|
PRUint32 contentLength)
|
||||||
|
{
|
||||||
|
nsITransferListener* pm = fContext->grid_parent->progressManager;
|
||||||
|
PR_ASSERT(pm);
|
||||||
|
if (! pm)
|
||||||
|
return NS_ERROR_NULL_POINTER;
|
||||||
|
|
||||||
|
return pm->OnProgress(url, bytesReceived, contentLength);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsSubProgressManager::OnStatus(const URL_Struct* url, const char* message)
|
||||||
|
{
|
||||||
|
nsITransferListener* pm = fContext->grid_parent->progressManager;
|
||||||
|
PR_ASSERT(pm);
|
||||||
|
if (! pm)
|
||||||
|
return NS_ERROR_NULL_POINTER;
|
||||||
|
|
||||||
|
return pm->OnStatus(url, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsSubProgressManager::OnSuspend(const URL_Struct* url)
|
||||||
|
{
|
||||||
|
nsITransferListener* pm = fContext->grid_parent->progressManager;
|
||||||
|
PR_ASSERT(pm);
|
||||||
|
if (! pm)
|
||||||
|
return NS_ERROR_NULL_POINTER;
|
||||||
|
|
||||||
|
return pm->OnSuspend(url);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsSubProgressManager::OnResume(const URL_Struct* url)
|
||||||
|
{
|
||||||
|
nsITransferListener* pm = fContext->grid_parent->progressManager;
|
||||||
|
PR_ASSERT(pm);
|
||||||
|
if (! pm)
|
||||||
|
return NS_ERROR_NULL_POINTER;
|
||||||
|
|
||||||
|
return pm->OnResume(url);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsSubProgressManager::OnStopBinding(const URL_Struct* url,
|
||||||
|
PRInt32 status,
|
||||||
|
const char* message)
|
||||||
|
{
|
||||||
|
nsITransferListener* pm = fContext->grid_parent->progressManager;
|
||||||
|
PR_ASSERT(pm);
|
||||||
|
if (! pm)
|
||||||
|
return NS_ERROR_NULL_POINTER;
|
||||||
|
|
||||||
|
return pm->OnStopBinding(url, status, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,59 @@
|
||||||
|
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||||
|
*
|
||||||
|
* The contents of this file are subject to the Netscape Public License
|
||||||
|
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||||
|
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||||
|
* http://www.mozilla.org/NPL/
|
||||||
|
*
|
||||||
|
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||||
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||||
|
* for the specific language governing rights and limitations under the
|
||||||
|
* NPL.
|
||||||
|
*
|
||||||
|
* The Initial Developer of this code under the NPL is Netscape
|
||||||
|
* Communications Corporation. Portions created by Netscape are
|
||||||
|
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||||
|
* Reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef nsSubProgressManager_h__
|
||||||
|
#define nsSubProgressManager_h__
|
||||||
|
|
||||||
|
#include "nsProgressManager.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The <b>nsSubProgressManager</b> is a progress manager that gets created
|
||||||
|
* in a grid (frame cell) context. It simply delegates all of the operations
|
||||||
|
* in the <b>nsITransferListener</b> interface to it's grid parent's
|
||||||
|
* progress manager.
|
||||||
|
*/
|
||||||
|
class nsSubProgressManager : public nsProgressManager
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
nsSubProgressManager(MWContext* context);
|
||||||
|
virtual ~nsSubProgressManager(void);
|
||||||
|
|
||||||
|
NS_IMETHOD
|
||||||
|
OnStartBinding(const URL_Struct* url);
|
||||||
|
|
||||||
|
NS_IMETHOD
|
||||||
|
OnProgress(const URL_Struct* url, PRUint32 bytesReceived, PRUint32 contentLength);
|
||||||
|
|
||||||
|
NS_IMETHOD
|
||||||
|
OnStatus(const URL_Struct* url, const char* message);
|
||||||
|
|
||||||
|
NS_IMETHOD
|
||||||
|
OnSuspend(const URL_Struct* url);
|
||||||
|
|
||||||
|
NS_IMETHOD
|
||||||
|
OnResume(const URL_Struct* url);
|
||||||
|
|
||||||
|
NS_IMETHOD
|
||||||
|
OnStopBinding(const URL_Struct* url, PRInt32 status, const char* message);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif // nsSubProgressManager_h__
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,691 @@
|
||||||
|
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||||
|
*
|
||||||
|
* The contents of this file are subject to the Netscape Public License
|
||||||
|
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||||
|
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||||
|
* http://www.mozilla.org/NPL/
|
||||||
|
*
|
||||||
|
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||||
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||||
|
* for the specific language governing rights and limitations under the
|
||||||
|
* NPL.
|
||||||
|
*
|
||||||
|
* The Initial Developer of this code under the NPL is Netscape
|
||||||
|
* Communications Corporation. Portions created by Netscape are
|
||||||
|
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||||
|
* Reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "nsTopProgressManager.h"
|
||||||
|
#include "nsTransfer.h"
|
||||||
|
#include "xp.h" // for FE_* callbacks
|
||||||
|
#include "xpgetstr.h"
|
||||||
|
#include "prprf.h"
|
||||||
|
#include "prmem.h"
|
||||||
|
#include "plstr.h"
|
||||||
|
|
||||||
|
#define OBJECT_TABLE_INIT_SIZE 32
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Debugging garbage
|
||||||
|
//
|
||||||
|
//
|
||||||
|
|
||||||
|
#if 0 /* defined(DEBUG) */
|
||||||
|
#define TRACE_PROGRESS(args) pm_TraceProgress args
|
||||||
|
|
||||||
|
static void
|
||||||
|
pm_TraceProgress(const char* fmtstr, ...)
|
||||||
|
{
|
||||||
|
char buf[256];
|
||||||
|
va_list ap;
|
||||||
|
va_start(ap, fmtstr);
|
||||||
|
PR_vsnprintf(buf, sizeof(buf), fmtstr, ap);
|
||||||
|
va_end(ap);
|
||||||
|
|
||||||
|
#if defined(XP_WIN)
|
||||||
|
OutputDebugString(buf);
|
||||||
|
#elif defined(XP_UNIX)
|
||||||
|
#elif defined(XP_MAC)
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#else /* defined(DEBUG) */
|
||||||
|
#define TRACE_PROGRESS(args)
|
||||||
|
#endif /* defined(DEBUG) */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Hash table allocation routines
|
||||||
|
//
|
||||||
|
//
|
||||||
|
|
||||||
|
static PR_CALLBACK void*
|
||||||
|
AllocTable(void* pool, PRSize size)
|
||||||
|
{
|
||||||
|
return PR_MALLOC(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
static PR_CALLBACK void
|
||||||
|
FreeTable(void* pool, void* item)
|
||||||
|
{
|
||||||
|
PR_DELETE(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
static PR_CALLBACK PLHashEntry*
|
||||||
|
AllocEntry(void* pool, const void* key)
|
||||||
|
{
|
||||||
|
return PR_NEW(PLHashEntry);
|
||||||
|
}
|
||||||
|
|
||||||
|
static PR_CALLBACK void
|
||||||
|
FreeEntry(void* pool, PLHashEntry* he, PRUintn flag)
|
||||||
|
{
|
||||||
|
if (flag == HT_FREE_VALUE) {
|
||||||
|
if (he->value) {
|
||||||
|
nsTransfer* obj = (nsTransfer*) he->value;
|
||||||
|
obj->Release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (flag == HT_FREE_ENTRY) {
|
||||||
|
// we don't own the key, so leave it alone...
|
||||||
|
|
||||||
|
if (he->value) {
|
||||||
|
nsTransfer* obj = (nsTransfer*) he->value;
|
||||||
|
obj->Release();
|
||||||
|
}
|
||||||
|
PR_DELETE(he);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static PLHashAllocOps AllocOps = {
|
||||||
|
AllocTable,
|
||||||
|
FreeTable,
|
||||||
|
AllocEntry,
|
||||||
|
FreeEntry
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static PLHashNumber
|
||||||
|
pm_HashURL(const void* key)
|
||||||
|
{
|
||||||
|
return (PLHashNumber) key;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
pm_CompareURLs(const void* v1, const void* v2)
|
||||||
|
{
|
||||||
|
return v1 == v2;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Hash table iterators
|
||||||
|
//
|
||||||
|
//
|
||||||
|
|
||||||
|
static PRIntn
|
||||||
|
pm_AggregateTransferInfo(PLHashEntry* he, PRIntn i, void* closure)
|
||||||
|
{
|
||||||
|
AggregateTransferInfo* info = (AggregateTransferInfo*) closure;
|
||||||
|
|
||||||
|
++(info->ObjectCount);
|
||||||
|
if (he->value) {
|
||||||
|
nsTransfer* transfer = (nsTransfer*) he->value;
|
||||||
|
|
||||||
|
if (transfer->IsComplete())
|
||||||
|
++(info->CompleteCount);
|
||||||
|
|
||||||
|
if (transfer->IsSuspended())
|
||||||
|
++(info->SuspendedCount);
|
||||||
|
|
||||||
|
info->MSecRemaining += transfer->GetMSecRemaining();
|
||||||
|
info->BytesReceived += transfer->GetBytesReceived();
|
||||||
|
info->ContentLength += transfer->GetContentLength();
|
||||||
|
|
||||||
|
if (! transfer->IsComplete() &&
|
||||||
|
transfer->GetContentLength() == transfer->GetBytesReceived())
|
||||||
|
++(info->UnknownLengthCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
return HT_ENUMERATE_NEXT;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// nsTopProgressManager
|
||||||
|
//
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
nsTopProgressManager::nsTopProgressManager(MWContext* context)
|
||||||
|
: nsProgressManager(context),
|
||||||
|
fActualStart(PR_Now()),
|
||||||
|
fProgressBarStart(PR_Now()),
|
||||||
|
fDefaultStatus(NULL)
|
||||||
|
{
|
||||||
|
fURLs = PL_NewHashTable(OBJECT_TABLE_INIT_SIZE,
|
||||||
|
pm_HashURL,
|
||||||
|
pm_CompareURLs,
|
||||||
|
PL_CompareValues,
|
||||||
|
&AllocOps,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
// Start the progress manager
|
||||||
|
fTimeout = FE_SetTimeout(nsTopProgressManager::TimeoutCallback, (void*) this, 500);
|
||||||
|
PR_ASSERT(fTimeout);
|
||||||
|
|
||||||
|
// to avoid "strobe" mode...
|
||||||
|
fProgress = 1;
|
||||||
|
FE_SetProgressBarPercent(fContext, fProgress);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
nsTopProgressManager::~nsTopProgressManager(void)
|
||||||
|
{
|
||||||
|
if (fDefaultStatus) {
|
||||||
|
PL_strfree(fDefaultStatus);
|
||||||
|
fDefaultStatus = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fURLs) {
|
||||||
|
PL_HashTableDestroy(fURLs);
|
||||||
|
fURLs = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fTimeout) {
|
||||||
|
FE_ClearTimeout(fTimeout);
|
||||||
|
fTimeout = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// XXX Needs to go to allxpstr.h
|
||||||
|
FE_Progress(fContext, "Done.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsTopProgressManager::OnStartBinding(const URL_Struct* url)
|
||||||
|
{
|
||||||
|
PR_ASSERT(url);
|
||||||
|
if (! url)
|
||||||
|
return NS_ERROR_NULL_POINTER;
|
||||||
|
|
||||||
|
PR_ASSERT(fURLs);
|
||||||
|
if (! fURLs)
|
||||||
|
return NS_ERROR_NULL_POINTER;
|
||||||
|
|
||||||
|
TRACE_PROGRESS(("OnStartBinding(%s)\n", url->address));
|
||||||
|
|
||||||
|
PL_HashTableAdd(fURLs, url, new nsTransfer(url));
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsTopProgressManager::OnProgress(const URL_Struct* url,
|
||||||
|
PRUint32 bytesReceived,
|
||||||
|
PRUint32 contentLength)
|
||||||
|
{
|
||||||
|
// Some sanity checks...
|
||||||
|
PR_ASSERT(url);
|
||||||
|
if (! url)
|
||||||
|
return NS_ERROR_NULL_POINTER;
|
||||||
|
|
||||||
|
TRACE_PROGRESS(("OnProgress(%s, %ld, %ld)\n", url->address, bytesReceived, contentLength));
|
||||||
|
|
||||||
|
PR_ASSERT(fURLs);
|
||||||
|
if (! fURLs)
|
||||||
|
return NS_ERROR_NULL_POINTER;
|
||||||
|
|
||||||
|
nsTransfer* transfer = (nsTransfer*) PL_HashTableLookup(fURLs, url);
|
||||||
|
|
||||||
|
PR_ASSERT(transfer);
|
||||||
|
if (!transfer)
|
||||||
|
return NS_ERROR_NULL_POINTER;
|
||||||
|
|
||||||
|
transfer->SetProgress(bytesReceived, contentLength);
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsTopProgressManager::OnStatus(const URL_Struct* url, const char* message)
|
||||||
|
{
|
||||||
|
TRACE_PROGRESS(("OnStatus(%s, %s)\n", (url ? url->address : NULL), message));
|
||||||
|
|
||||||
|
// There are cases when transfer may be null, and that's ok.
|
||||||
|
if (url) {
|
||||||
|
PR_ASSERT(fURLs);
|
||||||
|
if (! fURLs)
|
||||||
|
return NS_ERROR_NULL_POINTER;
|
||||||
|
|
||||||
|
nsTransfer* transfer = (nsTransfer*) PL_HashTableLookup(fURLs, url);
|
||||||
|
|
||||||
|
PR_ASSERT(transfer);
|
||||||
|
if (transfer)
|
||||||
|
transfer->SetStatus(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fDefaultStatus)
|
||||||
|
PL_strfree(fDefaultStatus);
|
||||||
|
|
||||||
|
fDefaultStatus = PL_strdup(message);
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsTopProgressManager::OnSuspend(const URL_Struct* url)
|
||||||
|
{
|
||||||
|
PR_ASSERT(url);
|
||||||
|
if (! url)
|
||||||
|
return NS_ERROR_NULL_POINTER;
|
||||||
|
|
||||||
|
TRACE_PROGRESS(("OnSuspend(%s)\n", url->address));
|
||||||
|
|
||||||
|
PR_ASSERT(fURLs);
|
||||||
|
if (! fURLs)
|
||||||
|
return NS_ERROR_NULL_POINTER;
|
||||||
|
|
||||||
|
nsTransfer* transfer = (nsTransfer*) PL_HashTableLookup(fURLs, url);
|
||||||
|
|
||||||
|
PR_ASSERT(transfer);
|
||||||
|
if (!transfer)
|
||||||
|
return NS_ERROR_NULL_POINTER;
|
||||||
|
|
||||||
|
transfer->Suspend();
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsTopProgressManager::OnResume(const URL_Struct* url)
|
||||||
|
{
|
||||||
|
PR_ASSERT(url);
|
||||||
|
if (! url)
|
||||||
|
return NS_ERROR_NULL_POINTER;
|
||||||
|
|
||||||
|
TRACE_PROGRESS(("OnResume(%s)\n", url->address));
|
||||||
|
|
||||||
|
PR_ASSERT(fURLs);
|
||||||
|
if (! fURLs)
|
||||||
|
return NS_ERROR_NULL_POINTER;
|
||||||
|
|
||||||
|
nsTransfer* transfer = (nsTransfer*) PL_HashTableLookup(fURLs, url);
|
||||||
|
|
||||||
|
PR_ASSERT(transfer);
|
||||||
|
if (!transfer)
|
||||||
|
return NS_ERROR_NULL_POINTER;
|
||||||
|
|
||||||
|
transfer->Resume();
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsTopProgressManager::OnStopBinding(const URL_Struct* url,
|
||||||
|
PRInt32 status,
|
||||||
|
const char* message)
|
||||||
|
{
|
||||||
|
PR_ASSERT(url);
|
||||||
|
if (! url)
|
||||||
|
return NS_ERROR_NULL_POINTER;
|
||||||
|
|
||||||
|
TRACE_PROGRESS(("OnStatus(%s, %d, %s)\n", url->address, status, message));
|
||||||
|
|
||||||
|
PR_ASSERT(fURLs);
|
||||||
|
if (! fURLs)
|
||||||
|
return NS_ERROR_NULL_POINTER;
|
||||||
|
|
||||||
|
nsTransfer* transfer = (nsTransfer*) PL_HashTableLookup(fURLs, url);
|
||||||
|
|
||||||
|
PR_ASSERT(transfer);
|
||||||
|
if (!transfer)
|
||||||
|
return NS_ERROR_NULL_POINTER;
|
||||||
|
|
||||||
|
transfer->MarkComplete(status);
|
||||||
|
transfer->SetStatus(message);
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void
|
||||||
|
nsTopProgressManager::TimeoutCallback(void* closure)
|
||||||
|
{
|
||||||
|
nsTopProgressManager* self = (nsTopProgressManager*) closure;
|
||||||
|
self->Tick();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsTopProgressManager::Tick(void)
|
||||||
|
{
|
||||||
|
TRACE_PROGRESS(("nsProgressManager.Tick: aggregating information for active objects\n"));
|
||||||
|
|
||||||
|
AggregateTransferInfo info = { 0, 0, 0, 0, 0, 0, 0 };
|
||||||
|
PL_HashTableEnumerateEntries(fURLs, pm_AggregateTransferInfo, (void*) &info);
|
||||||
|
|
||||||
|
TRACE_PROGRESS(("nsProgressManager.Tick: %ld of %ld objects complete, "
|
||||||
|
"%ldms left, "
|
||||||
|
"%ld of %ld bytes xferred\n",
|
||||||
|
info.CompleteCount, info.ObjectCount,
|
||||||
|
info.MSecRemaining,
|
||||||
|
info.BytesReceived, info.ContentLength));
|
||||||
|
|
||||||
|
PR_ASSERT(info.ObjectCount > 0);
|
||||||
|
if (info.ObjectCount == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
UpdateProgressBar(info);
|
||||||
|
UpdateStatusMessage(info);
|
||||||
|
|
||||||
|
// Check to see if we're done.
|
||||||
|
if (info.CompleteCount == info.ObjectCount) {
|
||||||
|
TRACE_PROGRESS(("Complete: %ld/%ld objects loaded\n",
|
||||||
|
info.CompleteCount,
|
||||||
|
info.ObjectCount));
|
||||||
|
|
||||||
|
// XXX needs to go to allxpstr.h
|
||||||
|
FE_Progress(fContext, " ");
|
||||||
|
|
||||||
|
PL_HashTableDestroy(fURLs);
|
||||||
|
fURLs = NULL;
|
||||||
|
|
||||||
|
fTimeout = NULL;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Reset the timeout to fire again...
|
||||||
|
fTimeout = FE_SetTimeout(nsTopProgressManager::TimeoutCallback,
|
||||||
|
(void*) this, 500);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
nsTopProgressManager::UpdateProgressBar(AggregateTransferInfo& info)
|
||||||
|
{
|
||||||
|
if (info.MSecRemaining == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (info.SuspendedCount > 0) {
|
||||||
|
// turn on the strobe...
|
||||||
|
FE_SetProgressBarPercent(fContext, 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsInt64 dt = nsTime(PR_Now()) - fProgressBarStart;
|
||||||
|
PRUint32 elapsed = dt / nsInt64((PRUint32) PR_USEC_PER_MSEC);
|
||||||
|
|
||||||
|
// Compute the percent complete, that is, elapsed / (elapsed + remaining)
|
||||||
|
double p = ((double) elapsed) / ((double) (elapsed + info.MSecRemaining));
|
||||||
|
PRUint32 pctComplete = (PRUint32) (100.0 * p);
|
||||||
|
|
||||||
|
#define MONOTONIC_PROGRESS_BAR
|
||||||
|
#if defined(MONOTONIC_PROGRESS_BAR)
|
||||||
|
// This hackery is a kludge to make the progress bar
|
||||||
|
// monotonically increase rather than slipping backwards as we
|
||||||
|
// discover that there's more content to download. It works by
|
||||||
|
// adjusting the progress manager's start time backwards to
|
||||||
|
// make the elapsed time (time we've waited so far) seem
|
||||||
|
// larger in proportion to the amount of time that appears to
|
||||||
|
// be left.
|
||||||
|
if (pctComplete < fProgress) {
|
||||||
|
PRUint32 newElapsed =
|
||||||
|
(PRUint32) ((p * ((double) info.MSecRemaining))
|
||||||
|
/ (1.0 - p));
|
||||||
|
|
||||||
|
PRInt32 dMSec = newElapsed - elapsed;
|
||||||
|
if (dMSec > 0)
|
||||||
|
fProgressBarStart -= nsInt64(dMSec * ((PRUint32) PR_USEC_PER_MSEC));
|
||||||
|
|
||||||
|
// Progress bar hasn't changed -- don't bother updating it.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
fProgress = pctComplete;
|
||||||
|
FE_SetProgressBarPercent(fContext, fProgress);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// The bulk of the following code was pulled over from lib/xp/xp_thermo.c
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifdef XP_MAC
|
||||||
|
#include "allxpstr.h"
|
||||||
|
#else
|
||||||
|
|
||||||
|
PR_BEGIN_EXTERN_C
|
||||||
|
extern int XP_THERMO_BYTE_FORMAT;
|
||||||
|
extern int XP_THERMO_KBYTE_FORMAT;
|
||||||
|
extern int XP_THERMO_HOURS_FORMAT;
|
||||||
|
extern int XP_THERMO_MINUTES_FORMAT;
|
||||||
|
extern int XP_THERMO_SECONDS_FORMAT;
|
||||||
|
extern int XP_THERMO_SINGULAR_FORMAT;
|
||||||
|
extern int XP_THERMO_PLURAL_FORMAT;
|
||||||
|
extern int XP_THERMO_PERCENTAGE_FORMAT;
|
||||||
|
extern int XP_THERMO_UH;
|
||||||
|
extern int XP_THERMO_PERCENT_FORM;
|
||||||
|
extern int XP_THERMO_PERCENT_RATE_FORM;
|
||||||
|
extern int XP_THERMO_RAW_COUNT_FORM;
|
||||||
|
extern int XP_THERMO_BYTE_RATE_FORMAT;
|
||||||
|
extern int XP_THERMO_K_RATE_FORMAT;
|
||||||
|
extern int XP_THERMO_M_RATE_FORMAT;
|
||||||
|
extern int XP_THERMO_STALLED_FORMAT;
|
||||||
|
extern int XP_THERMO_RATE_REMAINING_FORM;
|
||||||
|
extern int XP_THERMO_RATE_FORM;
|
||||||
|
PR_END_EXTERN_C
|
||||||
|
|
||||||
|
#endif // XP_MAC
|
||||||
|
|
||||||
|
#define KILOBYTE (1024L)
|
||||||
|
#define MINUTE (60L)
|
||||||
|
#define HOUR (MINUTE * MINUTE)
|
||||||
|
|
||||||
|
#define IS_PLURAL(x) (((x) == 1) ? "" : XP_GetString(XP_THERMO_PLURAL_FORMAT)) /* L10N? */
|
||||||
|
|
||||||
|
#define ENOUGH_TIME_TO_GUESS 10 /* in seconds */
|
||||||
|
#define TIME_UNTIL_DETAILS 5
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
static void
|
||||||
|
formatRate(char* buf, PRUint32 len, double bytes_per_sec)
|
||||||
|
{
|
||||||
|
if (bytes_per_sec > 0) {
|
||||||
|
if (bytes_per_sec < KILOBYTE)
|
||||||
|
PR_snprintf(buf, len, XP_GetString(XP_THERMO_BYTE_RATE_FORMAT),
|
||||||
|
(PRUint32) bytes_per_sec);
|
||||||
|
else
|
||||||
|
PR_snprintf(buf, len, XP_GetString(XP_THERMO_K_RATE_FORMAT),
|
||||||
|
(bytes_per_sec / ((double) KILOBYTE)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
formatKnownContentLength(char* buf,
|
||||||
|
PRUint32 len,
|
||||||
|
PRUint32 bytesReceived,
|
||||||
|
PRUint32 contentLength,
|
||||||
|
PRUint32 elapsed)
|
||||||
|
{
|
||||||
|
char rate[32];
|
||||||
|
*rate = 0;
|
||||||
|
|
||||||
|
// the transfer rate
|
||||||
|
double bytes_per_sec = 0;
|
||||||
|
if (elapsed > 0)
|
||||||
|
bytes_per_sec = ((double) bytesReceived) / ((double) elapsed);
|
||||||
|
|
||||||
|
formatRate(rate, sizeof(rate), bytes_per_sec);
|
||||||
|
|
||||||
|
|
||||||
|
// format the content length
|
||||||
|
char length[32];
|
||||||
|
*length = 0;
|
||||||
|
|
||||||
|
if (contentLength < KILOBYTE)
|
||||||
|
PR_snprintf(length, sizeof(length), XP_GetString(XP_THERMO_BYTE_FORMAT), contentLength);
|
||||||
|
else
|
||||||
|
PR_snprintf(length, sizeof(length), XP_GetString(XP_THERMO_KBYTE_FORMAT), contentLength / KILOBYTE);
|
||||||
|
|
||||||
|
|
||||||
|
// the percentage complete
|
||||||
|
char percent[32];
|
||||||
|
|
||||||
|
PRUint32 p = (bytesReceived * 100) / contentLength;
|
||||||
|
if (p >= 100 && bytesReceived != contentLength)
|
||||||
|
p = 99;
|
||||||
|
|
||||||
|
PR_snprintf(percent, sizeof(percent), XP_GetString(XP_THERMO_PERCENTAGE_FORMAT), p);
|
||||||
|
|
||||||
|
// the amount of time remaining
|
||||||
|
char tleft[32];
|
||||||
|
*tleft = 0;
|
||||||
|
|
||||||
|
if (bytes_per_sec >= KILOBYTE && elapsed >= ENOUGH_TIME_TO_GUESS) {
|
||||||
|
PRUint32 secs_left =
|
||||||
|
(PRUint32) (((double) (contentLength - bytesReceived)) / bytes_per_sec);
|
||||||
|
|
||||||
|
if (secs_left >= HOUR) {
|
||||||
|
PR_snprintf(tleft, sizeof(tleft),
|
||||||
|
XP_GetString(XP_THERMO_HOURS_FORMAT),
|
||||||
|
secs_left / HOUR,
|
||||||
|
(secs_left / MINUTE) % MINUTE,
|
||||||
|
secs_left % MINUTE);
|
||||||
|
}
|
||||||
|
else if (secs_left >= MINUTE) {
|
||||||
|
PR_snprintf(tleft, sizeof(tleft),
|
||||||
|
XP_GetString(XP_THERMO_MINUTES_FORMAT),
|
||||||
|
secs_left / MINUTE,
|
||||||
|
secs_left % MINUTE);
|
||||||
|
}
|
||||||
|
else if (secs_left > 0) {
|
||||||
|
PR_snprintf(tleft, sizeof(tleft),
|
||||||
|
XP_GetString(XP_THERMO_SECONDS_FORMAT),
|
||||||
|
secs_left,
|
||||||
|
IS_PLURAL(secs_left));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*tleft) {
|
||||||
|
/* "%s of %s (at %s, %s remaining)" */
|
||||||
|
PR_snprintf(buf, len,
|
||||||
|
XP_GetString(XP_THERMO_RATE_REMAINING_FORM),
|
||||||
|
percent, length, rate, tleft);
|
||||||
|
}
|
||||||
|
else if (*rate) {
|
||||||
|
/* "%s of %s (at %s)" */
|
||||||
|
PR_snprintf(buf, len,
|
||||||
|
XP_GetString(XP_THERMO_RATE_FORM),
|
||||||
|
percent, length, rate);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* "%s of %s" */
|
||||||
|
PR_snprintf(buf, len,
|
||||||
|
XP_GetString(XP_THERMO_PERCENT_FORM),
|
||||||
|
percent, length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
formatUnknownContentLength(char* buf, PRUint32 len, PRUint32 bytesReceived, PRUint32 elapsed)
|
||||||
|
{
|
||||||
|
char rate[32];
|
||||||
|
*rate = 0;
|
||||||
|
|
||||||
|
// the transfer rate
|
||||||
|
double bytes_per_sec = 0;
|
||||||
|
if (elapsed > 0)
|
||||||
|
bytes_per_sec = ((double) bytesReceived) / ((double) elapsed);
|
||||||
|
|
||||||
|
formatRate(rate, sizeof(rate), bytes_per_sec);
|
||||||
|
|
||||||
|
// the number of bytes received
|
||||||
|
char bytes_received[32];
|
||||||
|
|
||||||
|
if (bytesReceived < KILOBYTE)
|
||||||
|
PR_snprintf(bytes_received, sizeof(bytes_received),
|
||||||
|
XP_GetString(XP_THERMO_UH),
|
||||||
|
bytesReceived, IS_PLURAL(bytesReceived));
|
||||||
|
else
|
||||||
|
PR_snprintf(bytes_received, sizeof(bytes_received),
|
||||||
|
XP_GetString(XP_THERMO_KBYTE_FORMAT),
|
||||||
|
bytesReceived / KILOBYTE);
|
||||||
|
|
||||||
|
if (*rate) {
|
||||||
|
/* "%s read (at %s)" */
|
||||||
|
PR_snprintf(buf, len, XP_GetString(XP_THERMO_PERCENT_RATE_FORM), bytes_received, rate);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
PR_snprintf(buf, len, XP_GetString(XP_THERMO_RAW_COUNT_FORM), bytes_received);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
nsTopProgressManager::UpdateStatusMessage(AggregateTransferInfo& info)
|
||||||
|
{
|
||||||
|
// Compute how much time has elapsed
|
||||||
|
nsInt64 dt = nsTime(PR_Now()) - fActualStart;
|
||||||
|
PRUint32 elapsed = dt / nsInt64((PRUint32) PR_USEC_PER_SEC);
|
||||||
|
|
||||||
|
char buf[256];
|
||||||
|
*buf = 0;
|
||||||
|
|
||||||
|
if (info.ObjectCount == 1 || info.CompleteCount == 0) {
|
||||||
|
// If we only have one object that we're transferring, or if
|
||||||
|
// nothing has completed yet, show the default status message
|
||||||
|
PL_strncpy(buf, fDefaultStatus, sizeof(buf));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (elapsed > TIME_UNTIL_DETAILS) {
|
||||||
|
char details[256];
|
||||||
|
*details = 0;
|
||||||
|
|
||||||
|
if (!info.UnknownLengthCount && info.ContentLength > 0) {
|
||||||
|
formatKnownContentLength(details, sizeof(details),
|
||||||
|
info.BytesReceived,
|
||||||
|
info.ContentLength,
|
||||||
|
elapsed);
|
||||||
|
}
|
||||||
|
else if (info.BytesReceived > 0) {
|
||||||
|
formatUnknownContentLength(details, sizeof(details),
|
||||||
|
info.BytesReceived,
|
||||||
|
elapsed);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*details) {
|
||||||
|
// XXX needs to go to allxpstr.h
|
||||||
|
if (*buf)
|
||||||
|
PL_strcatn(buf, sizeof(buf), ", ");
|
||||||
|
|
||||||
|
PL_strcatn(buf, sizeof(buf), details);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FE_Progress(fContext, buf);
|
||||||
|
}
|
|
@ -0,0 +1,130 @@
|
||||||
|
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||||
|
*
|
||||||
|
* The contents of this file are subject to the Netscape Public License
|
||||||
|
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||||
|
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||||
|
* http://www.mozilla.org/NPL/
|
||||||
|
*
|
||||||
|
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||||
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||||
|
* for the specific language governing rights and limitations under the
|
||||||
|
* NPL.
|
||||||
|
*
|
||||||
|
* The Initial Developer of this code under the NPL is Netscape
|
||||||
|
* Communications Corporation. Portions created by Netscape are
|
||||||
|
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||||
|
* Reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef nsTopProgressManager_h__
|
||||||
|
#define nsTopProgressManager_h__
|
||||||
|
|
||||||
|
#include "nsProgressManager.h"
|
||||||
|
#include "nsTime.h"
|
||||||
|
|
||||||
|
struct AggregateTransferInfo {
|
||||||
|
PRUint32 ObjectCount;
|
||||||
|
PRUint32 CompleteCount;
|
||||||
|
PRUint32 SuspendedCount;
|
||||||
|
PRUint32 MSecRemaining;
|
||||||
|
PRUint32 BytesReceived;
|
||||||
|
PRUint32 ContentLength;
|
||||||
|
PRUint32 UnknownLengthCount;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An <b>nsTopProgressManager</b> is a progress manager that is associated
|
||||||
|
* with a top-level window context. It does the dirty work of managing the
|
||||||
|
* progress bar and the status text.
|
||||||
|
*/
|
||||||
|
class nsTopProgressManager : public nsProgressManager
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
/**
|
||||||
|
* A table of URLs that we are monitoring progress for. The table is
|
||||||
|
* keyed by <b>URL_Structs</b>, the values are <b>nsTransfer</b>
|
||||||
|
* objects.
|
||||||
|
*/
|
||||||
|
PLHashTable* fURLs;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The time at which the progress manager was created.
|
||||||
|
*/
|
||||||
|
nsTime fActualStart;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The time at which the progress bar thinks we were created. This is used
|
||||||
|
* with to make progress seem "monotonic": it is "slipped" backwards
|
||||||
|
* when a transfer stalls so that the percentage complete stays constant.
|
||||||
|
*/
|
||||||
|
nsTime fProgressBarStart;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The current amount of progress shown on the chrome's progress bar
|
||||||
|
*/
|
||||||
|
PRUint16 fProgress;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The default status message to display if nothing more appropriate
|
||||||
|
* is around.
|
||||||
|
*/
|
||||||
|
char* fDefaultStatus;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An FE timeout object that is used to periodically update the
|
||||||
|
* status bar.
|
||||||
|
*/
|
||||||
|
void* fTimeout;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The FE timeout callback.
|
||||||
|
*/
|
||||||
|
static void TimeoutCallback(void* self);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called to update the status bar.
|
||||||
|
*/
|
||||||
|
virtual void Tick(void);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the progress bar
|
||||||
|
*/
|
||||||
|
virtual void UpdateProgressBar(AggregateTransferInfo& info);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the status message
|
||||||
|
*/
|
||||||
|
virtual void UpdateStatusMessage(AggregateTransferInfo& info);
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
nsTopProgressManager(MWContext* context);
|
||||||
|
virtual ~nsTopProgressManager(void);
|
||||||
|
|
||||||
|
NS_IMETHOD
|
||||||
|
OnStartBinding(const URL_Struct* url);
|
||||||
|
|
||||||
|
NS_IMETHOD
|
||||||
|
OnProgress(const URL_Struct* url, PRUint32 bytesReceived, PRUint32 contentLength);
|
||||||
|
|
||||||
|
NS_IMETHOD
|
||||||
|
OnStatus(const URL_Struct* url, const char* message);
|
||||||
|
|
||||||
|
NS_IMETHOD
|
||||||
|
OnSuspend(const URL_Struct* url);
|
||||||
|
|
||||||
|
NS_IMETHOD
|
||||||
|
OnResume(const URL_Struct* url);
|
||||||
|
|
||||||
|
NS_IMETHOD
|
||||||
|
OnStopBinding(const URL_Struct* url, PRInt32 status, const char* message);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif // nsTopProgressManager_h__
|
||||||
|
|
|
@ -0,0 +1,192 @@
|
||||||
|
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||||
|
*
|
||||||
|
* The contents of this file are subject to the Netscape Public License
|
||||||
|
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||||
|
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||||
|
* http://www.mozilla.org/NPL/
|
||||||
|
*
|
||||||
|
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||||
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||||
|
* for the specific language governing rights and limitations under the
|
||||||
|
* NPL.
|
||||||
|
*
|
||||||
|
* The Initial Developer of this code under the NPL is Netscape
|
||||||
|
* Communications Corporation. Portions created by Netscape are
|
||||||
|
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||||
|
* Reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "nsTransfer.h"
|
||||||
|
#include "plstr.h"
|
||||||
|
#include "prtime.h"
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
PRUint32 nsTransfer::DefaultMSecRemaining = 1000;
|
||||||
|
|
||||||
|
nsTransfer::nsTransfer(const URL_Struct* url)
|
||||||
|
: fURL(url),
|
||||||
|
fBytesReceived(0),
|
||||||
|
fContentLength(0),
|
||||||
|
fStart(PR_Now()),
|
||||||
|
fIsSuspended(PR_FALSE),
|
||||||
|
fStatus(NULL),
|
||||||
|
fComplete(PR_FALSE),
|
||||||
|
fResultCode(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
nsTransfer::~nsTransfer(void)
|
||||||
|
{
|
||||||
|
if (fStatus) {
|
||||||
|
PL_strfree(fStatus);
|
||||||
|
fStatus = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
NS_IMPL_ISUPPORTS(nsTransfer, kISupportsIID);
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
nsTransfer::SetProgress(PRUint32 bytesReceived, PRUint32 contentLength)
|
||||||
|
{
|
||||||
|
fBytesReceived = bytesReceived;
|
||||||
|
fContentLength = contentLength;
|
||||||
|
if (fContentLength < fBytesReceived)
|
||||||
|
fContentLength = fBytesReceived;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PRUint32
|
||||||
|
nsTransfer::GetBytesReceived(void)
|
||||||
|
{
|
||||||
|
return fBytesReceived;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PRUint32
|
||||||
|
nsTransfer::GetContentLength(void)
|
||||||
|
{
|
||||||
|
return fContentLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
double
|
||||||
|
nsTransfer::GetTransferRate(void)
|
||||||
|
{
|
||||||
|
if (fContentLength == 0 || fBytesReceived == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
nsInt64 dt = nsTime(PR_Now()) - fStart;
|
||||||
|
PRUint32 dtMSec = dt / nsInt64((PRUint32) PR_USEC_PER_MSEC);
|
||||||
|
|
||||||
|
if (dtMSec == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return ((double) fBytesReceived) / ((double) dtMSec);
|
||||||
|
}
|
||||||
|
|
||||||
|
PRUint32
|
||||||
|
nsTransfer::GetMSecRemaining(void)
|
||||||
|
{
|
||||||
|
if (IsComplete())
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (fContentLength == 0 || fBytesReceived == 0)
|
||||||
|
// no content length and/or no bytes received
|
||||||
|
return DefaultMSecRemaining;
|
||||||
|
|
||||||
|
PRUint32 cbRemaining = fContentLength - fBytesReceived;
|
||||||
|
if (cbRemaining == 0)
|
||||||
|
// not complete, but content length == bytes received.
|
||||||
|
return DefaultMSecRemaining;
|
||||||
|
|
||||||
|
double bytesPerMSec = GetTransferRate();
|
||||||
|
if (bytesPerMSec == 0)
|
||||||
|
return DefaultMSecRemaining;
|
||||||
|
|
||||||
|
PRUint32 msecRemaining = (PRUint32) (((double) cbRemaining) / bytesPerMSec);
|
||||||
|
|
||||||
|
return msecRemaining;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
nsTransfer::SetStatus(const char* message)
|
||||||
|
{
|
||||||
|
if (fStatus)
|
||||||
|
PL_strfree(fStatus);
|
||||||
|
|
||||||
|
fStatus = PL_strdup(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const char*
|
||||||
|
nsTransfer::GetStatus(void)
|
||||||
|
{
|
||||||
|
return fStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
nsTransfer::Suspend(void)
|
||||||
|
{
|
||||||
|
if (fIsSuspended)
|
||||||
|
return;
|
||||||
|
|
||||||
|
fSuspendStart = PR_Now();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
nsTransfer::Resume(void)
|
||||||
|
{
|
||||||
|
if (! fIsSuspended)
|
||||||
|
return;
|
||||||
|
|
||||||
|
nsInt64 dt = nsTime(PR_Now()) - fSuspendStart;
|
||||||
|
fStart += dt;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PRBool
|
||||||
|
nsTransfer::IsSuspended(void)
|
||||||
|
{
|
||||||
|
return fIsSuspended;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
nsTransfer::MarkComplete(PRInt32 resultCode)
|
||||||
|
{
|
||||||
|
fComplete = PR_TRUE;
|
||||||
|
fResultCode = resultCode;
|
||||||
|
|
||||||
|
if (fResultCode >= 0) {
|
||||||
|
nsInt64 elapsed = nsTime(PR_Now()) - fStart;
|
||||||
|
PRUint32 elapsedMSec= (PRUint32) (elapsed / nsInt64((PRUint32) PR_USEC_PER_MSEC));
|
||||||
|
UpdateDefaultMSecRemaining(elapsedMSec);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PRBool
|
||||||
|
nsTransfer::IsComplete(void)
|
||||||
|
{
|
||||||
|
return fComplete;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
nsTransfer::UpdateDefaultMSecRemaining(PRUint32 msec)
|
||||||
|
{
|
||||||
|
// very simple. just maintain a rolling average.
|
||||||
|
DefaultMSecRemaining += msec;
|
||||||
|
DefaultMSecRemaining /= 2;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,71 @@
|
||||||
|
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||||
|
*
|
||||||
|
* The contents of this file are subject to the Netscape Public License
|
||||||
|
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||||
|
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||||
|
* http://www.mozilla.org/NPL/
|
||||||
|
*
|
||||||
|
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||||
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||||
|
* for the specific language governing rights and limitations under the
|
||||||
|
* NPL.
|
||||||
|
*
|
||||||
|
* The Initial Developer of this code under the NPL is Netscape
|
||||||
|
* Communications Corporation. Portions created by Netscape are
|
||||||
|
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||||
|
* Reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef nsTransfer_h__
|
||||||
|
#define nsTransfer_h__
|
||||||
|
|
||||||
|
#include "prtypes.h"
|
||||||
|
#include "structs.h"
|
||||||
|
#include "nsISupports.h"
|
||||||
|
#include "nsTime.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class encapsulates the transfer state for each stream that will
|
||||||
|
* be transferring data, is currently transferring data, or has previously
|
||||||
|
* transferred data in the current context.
|
||||||
|
*/
|
||||||
|
class nsTransfer
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
const URL_Struct* fURL;
|
||||||
|
PRUint32 fBytesReceived;
|
||||||
|
PRUint32 fContentLength;
|
||||||
|
nsTime fStart;
|
||||||
|
nsTime fSuspendStart;
|
||||||
|
PRBool fIsSuspended;
|
||||||
|
char* fStatus;
|
||||||
|
PRBool fComplete;
|
||||||
|
PRInt32 fResultCode;
|
||||||
|
|
||||||
|
static PRUint32 DefaultMSecRemaining;
|
||||||
|
static void UpdateDefaultMSecRemaining(PRUint32 time);
|
||||||
|
|
||||||
|
public:
|
||||||
|
nsTransfer(const URL_Struct* url);
|
||||||
|
virtual ~nsTransfer(void);
|
||||||
|
|
||||||
|
NS_DECL_ISUPPORTS
|
||||||
|
|
||||||
|
void SetProgress(PRUint32 bytesReceived, PRUint32 contentLength);
|
||||||
|
PRUint32 GetBytesReceived(void);
|
||||||
|
PRUint32 GetContentLength(void);
|
||||||
|
double GetTransferRate(void);
|
||||||
|
PRUint32 GetMSecRemaining(void);
|
||||||
|
void SetStatus(const char* message);
|
||||||
|
const char* GetStatus(void);
|
||||||
|
void Suspend(void);
|
||||||
|
void Resume(void);
|
||||||
|
PRBool IsSuspended(void);
|
||||||
|
void MarkComplete(PRInt32 resultCode);
|
||||||
|
PRBool IsComplete(void);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif // nsTransfer_h__
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче