Added a progress bar

This commit is contained in:
dbragg%netscape.com 1999-06-09 20:16:59 +00:00
parent 93024ca674
commit 4524952ae6
9 changed files with 697 additions and 75 deletions

View File

@ -16,11 +16,16 @@
# Reserved.
DEPTH=..\..\..
MODULE=include
DEFINES=-D_IMPL_NS_DOM
EXPORTS= nsIPrefMigration.h \
nsPrefMigrationIIDs.h \
MODULE=prefm
XPIDLSRCS = .\nsIPrefMigrationProgress.idl
include <$(DEPTH)\config\rules.mak>

View File

@ -0,0 +1,28 @@
/* -*- Mode: IDL; 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 "nsISupports.idl"
[uuid(b7be6590-1ab8-11d3-bcfc-00805f0e1353)]
interface nsIPrefMigrationProgress : nsISupports
{
void CreateProfileProgressDialog();
void MigrationStarted([const] in string UIPackageName);
void IncrementProgressBar();
};

View File

@ -33,6 +33,7 @@ LCFLAGS = \
LINCS= \
-I..\..\base \
-I$(XPDIST)\public\prefm \
-I$(XPDIST)\public\rdf \
-I$(XPDIST)\public\js \
-I$(XPDIST)\public\netlib \
-I$(XPDIST)\public\network \
@ -43,6 +44,7 @@ LINCS= \
-I$(XPDIST)\public\pref \
-I$(XPDIST)\public\raptor \
-I$(XPDIST)\public\libreg \
-I$(XPDIST)\public\xpfe\components \
$(NULL)
LLIBS = \
@ -50,18 +52,20 @@ LLIBS = \
$(DIST)\lib\xpcom.lib \
$(DIST)\lib\plc3.lib \
$(DIST)\lib\xppref32.lib \
$(DIST)\lib\netlib.lib \
$(LIBNSPR) \
$(NULL)
OBJS = \
.\$(OBJDIR)\nsprefmigration.obj \
.\$(OBJDIR)\nsprefmigrationfactory.obj \
.\$(OBJDIR)\nsPrefMigrationProgressDialog.obj \
$(NULL)
include <$(DEPTH)\config\rules.mak>
install:: $(DLL)
$(MAKE_INSTALL) .\$(OBJDIR)\$(MODULE).dll $(DIST)\bin
$(MAKE_INSTALL) .\$(OBJDIR)\$(MODULE).dll $(DIST)\bin\components
$(MAKE_INSTALL) .\$(OBJDIR)\$(MODULE).lib $(DIST)\lib
clobber::

View File

@ -36,6 +36,7 @@
#include "net.h"
#include "nsPrefMigration.h"
#include "nsPrefMigrationProgressDialog.h"
/*-----------------------------------------------------------------
* Globals
@ -101,29 +102,18 @@ NS_IMPL_RELEASE(nsPrefMigration)
*
*-------------------------------------------------------------------------*/
NS_IMETHODIMP
nsPrefMigration::ProcessPrefs(char* profilePath, char* installPath50, nsresult *aResult)
nsPrefMigration::ProcessPrefs(char* profilePath, char* newProfilePath, nsresult *aResult)
{
/*
PRFileDesc *reg4file, *prefs4file;
*reg5file,
*prefs5file,
*cfg5file,
*cfg4file,
*cssfile;
*/
char *mailFileArray[200], *newsFileArray[200];
char *oldMailPath, *oldNewsPath;
char *newMailPath, *newNewsPath;
char *newProfilePath;
PRUint32 totalMailSize = 0, totalNewsSize = 0;
PRUint32 totalMailSize = 0, totalNewsSize = 0, numberOfMailFiles = 0, numberOfNewsFiles = 0;
PRInt32 oldDirLength = 0;
if((newProfilePath = (char*) PR_MALLOC(PL_strlen(profilePath) + 2)) == NULL)
{
PR_Free(newProfilePath);
*aResult = NS_ERROR_FAILURE;
return 0;
}
#if defined(NS_DEBUG)
printf("*Entered Actual Migration routine*\n");
#endif
if((newMailPath = (char*) PR_MALLOC(_MAX_PATH)) == NULL)
{
@ -182,8 +172,8 @@ nsPrefMigration::ProcessPrefs(char* profilePath, char* installPath50, nsresult *
}
/* Read the user's 4.x files from their profile */
success = Read4xFiles(oldMailPath, mailFileArray, &totalMailSize);
success = Read4xFiles(oldNewsPath, newsFileArray, &totalNewsSize);
success = Read4xFiles(oldMailPath, mailFileArray, &numberOfMailFiles, &totalMailSize);
success = Read4xFiles(oldNewsPath, newsFileArray, &numberOfNewsFiles, &totalNewsSize);
if(CheckForSpace(newMailPath, totalMailSize) != NS_OK)
return -1; /* Need error code for not enough space */
@ -217,52 +207,8 @@ nsPrefMigration::ProcessPrefs(char* profilePath, char* installPath50, nsresult *
nsresult
nsPrefMigration::CreateNewUser5Tree(char* oldProfilePath, char* newProfilePath)
{
char* users5Dir;
char* prefsFile;
int newDirLength = _MAX_PATH, i=0, j=0, len=0;
PRInt32 idx = 0, sbidx = 0;
if ((users5Dir = (char*) PR_MALLOC(PL_strlen(oldProfilePath) + 32)) == NULL)
{
PR_Free(users5Dir);
return -1;
}
#ifdef XP_PC
PL_strcpy(users5Dir, oldProfilePath);
len = strlen(users5Dir);
i = len;
while (users5Dir[i] != separator)
i--;
j = i;
users5Dir[i] = '5';
i++;
users5Dir[i] = eolnChar;
#endif /* XP_PC */
#ifdef DKB
#ifdef XP_MAC
nsSpecialSystemDirectory docDir = nsSpecialSystemDirectory::Mac_DocumentsDirectory;
docDir += ":netscape:users5";
users5Dir = docDir.mPath;
#endif /* XP_MAC */
#endif /* DKB */
/* Create 5.x profile directory tree */
if (!PR_OpenDir(users5Dir)) /* users5 directory doesn't exist */
PR_MkDir(users5Dir, PR_RDWR);
while ((oldProfilePath[j] != eolnChar) && (j <= len)) /* reassemble the user5 path */
{
users5Dir[i] = oldProfilePath[j];
i++;
j++;
}
users5Dir[i] = '\0';
PR_MkDir(users5Dir, PR_RDWR); /* Create the actual profile dir */
PL_strcpy(newProfilePath, users5Dir); /* set newProfilePath for reference parameter */
/* Copy the old prefs.js file to the new profile directory for modification and reading */
if ((prefsFile = (char*) PR_MALLOC(PL_strlen(oldProfilePath) + 32)) == NULL)
@ -270,15 +216,23 @@ nsPrefMigration::CreateNewUser5Tree(char* oldProfilePath, char* newProfilePath)
PR_Free(prefsFile);
return -1;
}
PL_strcpy(prefsFile, oldProfilePath);
PL_strcat(prefsFile, "\\prefs.js\0");
nsFileSpec oldPrefsFile(prefsFile);
nsFileSpec newPrefsFile(newProfilePath);
oldPrefsFile.Copy(newPrefsFile);
if (!newPrefsFile.Exists())
{
newPrefsFile.CreateDirectory();
}
PR_Free(users5Dir);
oldPrefsFile.Copy(newPrefsFile);
newPrefsFile += "prefs.js";
newPrefsFile.Rename("prefs50.js");
//PR_Free(users5Dir);
PR_Free(prefsFile);
return NS_OK;
@ -313,7 +267,7 @@ nsPrefMigration::GetDirFromPref(char* newProfilePath, char* pref, char* newPath,
if(PREF_Init(prefs_jsPath))
{
if(PREF_GetCharPref(pref, oldPath, &oldDirLength) > -1) /* found the pref */
if(PREF_GetCharPref(pref, oldPath, &oldDirLength) != 0) /* found the pref */
{
PL_strcpy(newPath, oldPath);
PL_strcat(newPath, "5");
@ -343,7 +297,8 @@ nsPrefMigration::GetDirFromPref(char* newProfilePath, char* pref, char* newPath,
* RETURNS: NS_OK if successful
*--------------------------------------------------------------------------------*/
nsresult
nsPrefMigration::Read4xFiles(char* ProfilePath, char* fileArray[], PRUint32* sizeTotal)
nsPrefMigration::Read4xFiles(char* ProfilePath, char* fileArray[],
PRUint32* fileTotal, PRUint32* sizeTotal)
{
char* fullFileName;
int i = 0;
@ -382,7 +337,7 @@ nsPrefMigration::Read4xFiles(char* ProfilePath, char* fileArray[], PRUint32* siz
fileSize = 0;
}
}
*fileTotal = i-1;
fileArray[i] = NULL; /* Put a Null in the array after the last file name */
PR_Free(fullFileName);
@ -422,10 +377,15 @@ nsPrefMigration::CheckForSpace(char* newProfilePath, PRFloat64 requiredSpace)
*
*--------------------------------------------------------------------------*/
nsresult
nsPrefMigration::DoTheCopy(char* oldPath, char* newPath, char* fileArray[])
nsPrefMigration::DoTheCopy(const char* oldPath, const char* newPath, char* fileArray[])
{
PRInt32 i = 0, succeeded = 0;
nsPrefMigrationProgressDialog* pProgressMeter = new nsPrefMigrationProgressDialog;
pProgressMeter->CreateProfileProgressDialog();
while ((fileArray[i] != NULL) && (i < 200))
{
nsFileSpec sourceFile(oldPath);
@ -436,9 +396,10 @@ nsPrefMigration::DoTheCopy(char* oldPath, char* newPath, char* fileArray[])
//targetFile.GetParent(parentofTargetFile);
succeeded = sourceFile.Copy(targetFile);
pProgressMeter->IncrementProgressBar();
i++;
}
pProgressMeter->KillProfileProgressDialog();
return NS_OK;
}

View File

@ -32,13 +32,14 @@ class nsPrefMigration: public nsIPrefMigration
nsresult Read4xFiles(char* ProfilePath,
char* fileArray[],
PRUint32* fileTotal,
PRUint32* sizeTotal);
nsresult CheckForSpace(char* newProfilePath,
PRFloat64 requiredSpace);
nsresult DoTheCopy(char* oldPath,
char* newPath,
nsresult DoTheCopy(const char* oldPath,
const char* newPath,
char* fileArray[]);
};

View File

@ -0,0 +1,359 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Communicator client code,
* released March 31, 1998.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*
* Contributors:
* Douglas Turner <dougt@netscape.com>
*/
//#include "nsIPrefMigrationProgress.h"
#include "nsPrefMigrationProgressDialog.h"
#include "nsIAppShellComponentImpl.h"
#include "nsIServiceManager.h"
#include "nsIDocumentViewer.h"
#include "nsIContent.h"
#include "nsINameSpaceManager.h"
#include "nsIContentViewer.h"
#include "nsIDOMElement.h"
#include "nsINetService.h"
#include "nsIWebShell.h"
#include "nsIWebShellWindow.h"
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
static NS_DEFINE_IID( kAppShellServiceCID, NS_APPSHELL_SERVICE_CID );
static NS_DEFINE_IID( kNetServiceCID, NS_NETSERVICE_CID );
// Utility to set element attribute.
static nsresult setAttribute( nsIDOMXULDocument *doc,
const char *id,
const char *name,
const nsString &value ) {
nsresult rv = NS_OK;
if ( doc ) {
// Find specified element.
nsCOMPtr<nsIDOMElement> elem;
rv = doc->GetElementById( id, getter_AddRefs( elem ) );
if ( elem ) {
// Set the text attribute.
rv = elem->SetAttribute( name, value );
if ( NS_SUCCEEDED( rv ) ) {
} else {
DEBUG_PRINTF( PR_STDOUT, "%s %d: SetAttribute failed, rv=0x%X\n",
__FILE__, (int)__LINE__, (int)rv );
}
} else {
DEBUG_PRINTF( PR_STDOUT, "%s %d: GetElementById failed, rv=0x%X\n",
__FILE__, (int)__LINE__, (int)rv );
}
} else {
rv = NS_ERROR_NULL_POINTER;
}
return rv;
}
// Utility to get element attribute.
static nsresult getAttribute( nsIDOMXULDocument *doc,
const char *id,
const char *name,
nsString &value ) {
nsresult rv = NS_OK;
if ( doc ) {
// Find specified element.
nsCOMPtr<nsIDOMElement> elem;
rv = doc->GetElementById( id, getter_AddRefs( elem ) );
if ( elem ) {
// Set the text attribute.
rv = elem->GetAttribute( name, value );
if ( NS_SUCCEEDED( rv ) ) {
} else {
DEBUG_PRINTF( PR_STDOUT, "%s %d: SetAttribute failed, rv=0x%X\n",
__FILE__, (int)__LINE__, (int)rv );
}
} else {
DEBUG_PRINTF( PR_STDOUT, "%s %d: GetElementById failed, rv=0x%X\n",
__FILE__, (int)__LINE__, (int)rv );
}
} else {
rv = NS_ERROR_NULL_POINTER;
}
return rv;
}
nsPrefMigrationProgressDialog::nsPrefMigrationProgressDialog()
{
NS_INIT_REFCNT();
mWindow = nsnull;
mDocument = nsnull;
}
nsPrefMigrationProgressDialog::~nsPrefMigrationProgressDialog()
{
}
NS_IMPL_ADDREF( nsPrefMigrationProgressDialog );
NS_IMPL_RELEASE( nsPrefMigrationProgressDialog );
NS_IMETHODIMP
nsPrefMigrationProgressDialog::QueryInterface(REFNSIID aIID,void** aInstancePtr)
{
if (aInstancePtr == NULL) {
return NS_ERROR_NULL_POINTER;
}
// Always NULL result, in case of failure
*aInstancePtr = NULL;
if (aIID.Equals(nsIPrefMigrationProgress::GetIID())) {
*aInstancePtr = (void*) ((nsIPrefMigrationProgress*)this);
NS_ADDREF_THIS();
return NS_OK;
}
if (aIID.Equals(nsIXULWindowCallbacks::GetIID())) {
*aInstancePtr = (void*) ((nsIXULWindowCallbacks*)this);
NS_ADDREF_THIS();
return NS_OK;
}
if (aIID.Equals(kISupportsIID)) {
*aInstancePtr = (void*) (nsISupports*)((nsIPrefMigrationProgress*)this);
NS_ADDREF_THIS();
return NS_OK;
}
return NS_ERROR_NO_INTERFACE;
}
NS_IMETHODIMP
nsPrefMigrationProgressDialog::CreateProfileProgressDialog()
{
nsresult rv = NS_OK;
// Get app shell service.
nsIAppShellService *appShell;
rv = nsServiceManager::GetService( kAppShellServiceCID,
nsIAppShellService::GetIID(),
(nsISupports**)&appShell );
if ( NS_SUCCEEDED( rv ) )
{
// Open "progress" dialog.
nsIURL *url;
rv = NS_NewURL( &url, "resource:/res/profile/progress_undetermined.xul" );
if ( NS_SUCCEEDED(rv) )
{
nsIWebShellWindow *newWindow;
rv = appShell->CreateTopLevelWindow( nsnull,
url,
PR_TRUE,
newWindow,
nsnull,
this, // callbacks??
0,
0 );
if ( NS_SUCCEEDED( rv ) )
{
mWindow = newWindow;
NS_RELEASE( newWindow );
if (mWindow != nsnull)
mWindow->Show(PR_TRUE);
}
else
{
DEBUG_PRINTF( PR_STDOUT, "Error creating progress dialog, rv=0x%X\n", (int)rv );
}
NS_RELEASE( url );
}
nsServiceManager::ReleaseService( kAppShellServiceCID, appShell );
}
else
{
DEBUG_PRINTF( PR_STDOUT, "Unable to get app shell service, rv=0x%X\n", (int)rv );
}
return NS_OK;
}
NS_IMETHODIMP
nsPrefMigrationProgressDialog::KillProfileProgressDialog()
{
nsresult rv = NS_OK;
nsIAppShellService *appShell;
rv = nsServiceManager::GetService( kAppShellServiceCID,
nsIAppShellService::GetIID(),
(nsISupports**)&appShell );
if ( NS_SUCCEEDED( rv ) )
{
rv = appShell->CloseTopLevelWindow( mWindow );
nsServiceManager::ReleaseService(kAppShellServiceCID, appShell);
}
else
{
DEBUG_PRINTF( PR_STDOUT, "Unable to get app shell service, rv=0x%X\n", (int)rv );
}
return NS_OK;
}
NS_IMETHODIMP
nsPrefMigrationProgressDialog::MigrationStarted(const char *UIPackageName)
{
setAttribute( mDocument, "progress.status", "value", nsString(UIPackageName) );
return NS_OK;
}
NS_IMETHODIMP
nsPrefMigrationProgressDialog::IncrementProgressBar()
{
nsString sTotalFiles;
/* Get the Total number of files processed so far */
getAttribute( mDocument, "progress.status", "value", sTotalFiles);
/* Goofy little conversion routine */
char *temp = sTotalFiles.ToNewCString(); /* convert nsString to char * */
int nTotalFiles = atoi(temp); /* convert char * to int */
delete[] temp;
nTotalFiles++; /* the reason for the above conversions */
char buf[8];
PR_snprintf( buf, sizeof buf, "%lu", nTotalFiles ); /* convert int back to char* */
setAttribute( mDocument, "progress.status", "value", buf);
return NS_OK;
}
/*
NS_IMETHODIMP
nsInstallProgressDialog::InstallFinalization(const char *message, PRInt32 itemNum, PRInt32 totNum)
{
PRInt32 maxChars = 40;
nsString theMessage(message);
PRInt32 len = theMessage.Length();
if (len > maxChars)
{
PRInt32 offset = (len/2) - ((len - maxChars)/2);
PRInt32 count = (len - maxChars);
theMessage.Cut(offset, count);
theMessage.Insert(nsString("..."), offset);
}
setAttribute( mDocument, "dialog.currentAction", "value", theMessage );
nsresult rv = NS_OK;
char buf[16];
PR_snprintf( buf, sizeof buf, "%lu", totNum );
setAttribute( mDocument, "dialog.progress", "max", buf );
if (totNum != 0)
{
PR_snprintf( buf, sizeof buf, "%lu", ((totNum-itemNum)/totNum) );
}
else
{
PR_snprintf( buf, sizeof buf, "%lu", 0 );
}
setAttribute( mDocument, "dialog.progress", "value", buf );
return NS_OK;
}
*/
/*
NS_IMETHODIMP
nsInstallProgressDialog::InstallAborted()
{
return NS_OK;
}
*/
// Do startup stuff from C++ side.
NS_IMETHODIMP
nsPrefMigrationProgressDialog::ConstructBeforeJavaScript(nsIWebShell *aWebShell)
{
nsresult rv = NS_OK;
// Get content viewer from the web shell.
nsCOMPtr<nsIContentViewer> contentViewer;
rv = aWebShell ? aWebShell->GetContentViewer(getter_AddRefs(contentViewer))
: NS_ERROR_NULL_POINTER;
if ( contentViewer ) {
// Up-cast to a document viewer.
nsCOMPtr<nsIDocumentViewer> docViewer( do_QueryInterface( contentViewer, &rv ) );
if ( docViewer ) {
// Get the document from the doc viewer.
nsCOMPtr<nsIDocument> document;
rv = docViewer->GetDocument(*getter_AddRefs(document));
if ( document ) {
// Upcast to XUL document.
mDocument = do_QueryInterface( document, &rv );
if ( ! mDocument )
{
DEBUG_PRINTF( PR_STDOUT, "%s %d: Upcast to nsIDOMXULDocument failed, rv=0x%X\n",
__FILE__, (int)__LINE__, (int)rv );
}
}
else
{
DEBUG_PRINTF( PR_STDOUT, "%s %d: GetDocument failed, rv=0x%X\n",
__FILE__, (int)__LINE__, (int)rv );
}
}
else
{
DEBUG_PRINTF( PR_STDOUT, "%s %d: Upcast to nsIDocumentViewer failed, rv=0x%X\n",
__FILE__, (int)__LINE__, (int)rv );
}
}
else
{
DEBUG_PRINTF( PR_STDOUT, "%s %d: GetContentViewer failed, rv=0x%X\n",
__FILE__, (int)__LINE__, (int)rv );
}
return rv;
}

View File

@ -0,0 +1,67 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Communicator client code,
* released March 31, 1998.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*
* Contributors:
* Douglas Turner <dougt@netscape.com>
*/
#ifndef __nsInstallProgressDialog_h__
#define __nsInstallProgressDialog_h__
#include "nsIPrefMigrationProgress.h"
#include "nsISupports.h"
#include "nsISupportsUtils.h"
#include "nsCOMPtr.h"
#include "nsIWebShell.h"
#include "nsIWebShellWindow.h"
#include "nsIXULWindowCallbacks.h"
#include "nsIDocument.h"
#include "nsIDOMXULDocument.h"
class nsPrefMigrationProgressDialog : public nsIPrefMigrationProgress, public nsIXULWindowCallbacks
{
public:
nsPrefMigrationProgressDialog();
virtual ~nsPrefMigrationProgressDialog();
NS_DECL_ISUPPORTS
NS_IMETHOD CreateProfileProgressDialog();
NS_IMETHOD KillProfileProgressDialog();
NS_IMETHOD MigrationStarted(const char *UIPackageName);
NS_IMETHOD IncrementProgressBar();
//NS_IMETHOD InstallFinalization(const char *message, PRInt32 itemNum, PRInt32 totNum);
//NS_IMETHOD InstallAborted();
// Declare implementations of nsIXULWindowCallbacks interface functions.
NS_IMETHOD ConstructBeforeJavaScript(nsIWebShell *aWebShell);
NS_IMETHOD ConstructAfterJavaScript(nsIWebShell *aWebShell) { return NS_OK; }
private:
nsCOMPtr<nsIDOMXULDocument> mDocument;
nsCOMPtr<nsIWebShellWindow> mWindow;
};
#endif

View File

@ -0,0 +1,3 @@
TD {
font: 10pt sans-serif;
}

View File

@ -0,0 +1,194 @@
<?xml version="1.0"?>
<?xml-stylesheet href="xul.css" type="text/css"?>
<?xml-stylesheet href="prefmProgress.css" type="text/css"?>
<!DOCTYPE window
[
<!ENTITY downloadWindow.title "Updating profile">
<!ENTITY location "Location">
<!ENTITY saving "Saving">
<!ENTITY status "Status:">
<!ENTITY dialogStatus.label "( nn.nK of mm.mK bytes )">
<!ENTITY timeLeft "Time Left:">
<!ENTITY dialogTimeLeft.label "?">
<!ENTITY dialogCancel.label "Cancel">
]
>
<window xmlns:html="http://www.w3.org/TR/REC-html40"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
title="Updating profile"
width="425"
height="225"
onload="onLoad()">
<data>
<broadcaster id="data.progress" type="progress" value="0" max="0" completed="false"/>
<broadcaster id="data.status" type="string" value=""/>
<broadcaster id="data.execute" command=""/>
</data>
<dialog>
<observes element="data.progress" attribute="value" onchange="onProgress()"/>
<observes element="data.progress" attribute="completed" onchange="onCompletion()"/>
<observes element="data.status" attribute="value" onchange="onStatus()"/>
</dialog>
<html:script>
var data;
var dialog;
function loadDialog() {
dialog.location.setAttribute( "value", data.location.getAttribute( "value" ) );
dialog.fileName.setAttribute( "value", data.fileName.getAttribute( "value" ) );
}
function onLoad() {
// Set global variables.
data = new Object;
data.progress = document.getElementById("data.progress");
data.status = document.getElementById("data.status");
data.execute = document.getElementById("data.execute");
dialog = new Object;
dialog.status = document.getElementById("dialog.status");
dialog.progress = document.getElementById("dialog.progress");
dialog.progressPercent = document.getElementById("dialog.progressPercent");
dialog.cancel = document.getElementById("dialog.cancel");
// Fill dialog.
loadDialog();
// Commence.
data.execute.setAttribute("command","start");
}
var started = false;
var completed = false;
var interval = 1000; // Update every 1000 milliseconds.
var lastUpdate = -interval; // Update initially.
function stop() {
if ( started &amp;&amp; !completed ) {
// Stop the download.
data.execute.setAttribute( "command", "stop" );
} else {
// Close the window.
data.execute.setAttribute( "command", "close" );
}
}
function onProgress() {
// Check for first time.
if ( !started ) {
// Initialize download start time.
started = true;
dialog.cancel.removeAttribute( "disabled" );
}
// Get stats.
var currentStatus = data.progress.getAttribute("value");
var max = data.progress.getAttribute("max");
// Determine if progress bar should update
// If a file isn't done copying, don't increment progress bar.
if ( currentStatus == lastUpdate ) {
return;
}
// Update with the current progress value.
lastUpdate = currentStatus;
// Update download rate.
var elapsed = now - startTime;
var rate; // bytes/sec
if ( elapsed ) {
rate = ( bytes * 1000 ) / elapsed;
} else {
rate = 0;
}
// Calculate percentage.
var percent = Math.round( (currentStatus*100)/max );
// Advance progress meter.
dialog.progress.setAttribute( "value", percent );
// Update percentage label on progress meter.
dialog.progressPercent.childNodes[0].nodeValue = percent + "%";
}
function onCompletion() {
if ( !completed ) {
completed = true;
data.execute.setAttribute( "command", "close" );
}
}
function onStatus() {
var txt = data.status.getAttribute( "value" );
dialog.status.childNodes[0].nodeValue = txt;
}
</html:script>
<html:table style="width:100%;">
<html:tr>
<html:td align="right">
&location;
</html:td>
<html:td align="left">
<html:input id="dialog.location" readonly="" style="background-color:lightgray;width:300px;"/>
</html:td>
</html:tr>
<html:tr>
<html:td align="right">
&saving;
</html:td>
<html:td align="left">
<html:input id="dialog.fileName" readonly="" value="" style="background-color:lightgray;width:300px;"/>
</html:td>
</html:tr>
<html:tr>
<html:td align="right">
&status;
</html:td>
<html:td align="left">
<html:span id="dialog.status">
&dialogStatus.label;
</html:span>
</html:td>
</html:tr>
<html:tr>
<html:td align="right">
&timeLeft;
</html:td>
<html:td align="left">
<html:span id="dialog.timeLeft">
&dialogTimeLeft.label;
</html:span>
</html:td>
</html:tr>
<html:tr>
<html:td align="center" height="40px" colspan="2">
<progressmeter id="dialog.progress" mode="normal" value="0"
style="width:300px;height:16px;"/>
<html:span id="dialog.progressPercent" style="border-left:5px solid lightgray;">
0%
</html:span>
</html:td>
</html:tr>
<html:tr>
<html:td align="center" colspan="2">
<html:button id="dialog.cancel" onclick="stop()">&dialogCancel.label;</html:button>
</html:td>
</html:tr>
</html:table>
</window>