mirror of
https://github.com/rn10950/RetroZilla.git
synced 2024-11-14 11:40:13 +01:00
1483 lines
42 KiB
C++
1483 lines
42 KiB
C++
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
/* ***** BEGIN LICENSE BLOCK *****
|
|
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
|
*
|
|
* The contents of this file are subject to the Mozilla Public License Version
|
|
* 1.1 (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/MPL/
|
|
*
|
|
* 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 the Initial Developer are Copyright (C) 1998
|
|
* the Initial Developer. All Rights Reserved.
|
|
*
|
|
* Contributor(s):
|
|
* Samir Gehani <sgehani@netscape.com>
|
|
*
|
|
* Alternatively, the contents of this file may be used under the terms of
|
|
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
|
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
|
* in which case the provisions of the GPL or the LGPL are applicable instead
|
|
* of those above. If you wish to allow use of your version of this file only
|
|
* under the terms of either the GPL or the LGPL, and not to allow others to
|
|
* use your version of this file under the terms of the MPL, indicate your
|
|
* decision by deleting the provisions above and replace them with the notice
|
|
* and other provisions required by the GPL or the LGPL. If you do not delete
|
|
* the provisions above, a recipient may use your version of this file under
|
|
* the terms of any one of the MPL, the GPL or the LGPL.
|
|
*
|
|
* ***** END LICENSE BLOCK ***** */
|
|
|
|
#include "nsSocket.h"
|
|
#include "nsHTTPConn.h"
|
|
#include "nsInstallDlg.h"
|
|
#include "nsXInstaller.h"
|
|
#include "nsXIEngine.h"
|
|
#include <signal.h>
|
|
#include <sys/wait.h>
|
|
#include <gtk/gtk.h>
|
|
#include <errno.h>
|
|
|
|
#define NUM_PS_ENTRIES 4
|
|
|
|
typedef struct _DLProgress
|
|
{
|
|
// progress widgets
|
|
GtkWidget *vbox;
|
|
GtkWidget *compName;
|
|
GtkWidget *URL;
|
|
GtkWidget *localPath;
|
|
GtkWidget *status;
|
|
GtkWidget *progBar;
|
|
|
|
// progress info
|
|
int downloadedBytes;
|
|
int totalKB;
|
|
}
|
|
DLProgress;
|
|
|
|
static char *sXPInstallEngine;
|
|
static nsRunApp *sRunAppList = NULL;
|
|
static nsRunApp *sPostInstallRun = NULL;
|
|
static DLProgress sDLProgress;
|
|
|
|
static GtkWidget *sDLTable = NULL;
|
|
static GtkWidget *sMsg0Label;
|
|
static GtkWidget *sMajorLabel;
|
|
static GtkWidget *sMinorLabel;
|
|
static GtkWidget *sRateLabel;
|
|
static GtkWidget *sMajorProgBar;
|
|
static GtkWidget *sMinorProgBar;
|
|
static GtkWidget *sPSTextEntry[NUM_PS_ENTRIES];
|
|
|
|
static int bDownload = FALSE;
|
|
static struct timeval sDLStartTime;
|
|
static int bDLPause = FALSE;
|
|
static int bDLCancel = FALSE;
|
|
|
|
nsInstallDlg::nsInstallDlg() :
|
|
mMsg0(NULL)
|
|
{
|
|
}
|
|
|
|
nsInstallDlg::~nsInstallDlg()
|
|
{
|
|
XI_IF_FREE(mMsg0);
|
|
}
|
|
|
|
void
|
|
nsInstallDlg::Back(GtkWidget *aWidget, gpointer aData)
|
|
{
|
|
DUMP("Back");
|
|
if (aData != gCtx->idlg) return;
|
|
#ifdef MOZ_WIDGET_GTK
|
|
if (gCtx->bMoving)
|
|
{
|
|
gCtx->bMoving = FALSE;
|
|
return;
|
|
}
|
|
#endif
|
|
|
|
// hide this notebook page
|
|
gCtx->idlg->Hide();
|
|
|
|
// show the last dlg
|
|
if (gCtx->opt->mSetupType == (gCtx->sdlg->GetNumSetupTypes() - 1))
|
|
{
|
|
gCtx->cdlg->Show();
|
|
// only set bMoving for component dlg since setuptype has no "back"
|
|
#ifdef MOZ_WIDGET_GTK
|
|
gCtx->bMoving = TRUE;
|
|
#endif
|
|
}
|
|
else
|
|
{
|
|
gCtx->sdlg->Show();
|
|
}
|
|
}
|
|
|
|
void
|
|
nsInstallDlg::Next(GtkWidget *aWidget, gpointer aData)
|
|
{
|
|
DUMP("Next");
|
|
GtkWidget *pauseLabel, *resumeLabel;
|
|
|
|
if (aData != gCtx->idlg) return;
|
|
#ifdef MOZ_WIDGET_GTK
|
|
if (gCtx->bMoving)
|
|
{
|
|
gCtx->bMoving = FALSE;
|
|
DUMP("Moving done!");
|
|
return;
|
|
}
|
|
#endif
|
|
|
|
// initialize progress bar cleanly
|
|
if (gCtx->opt->mMode != nsXIOptions::MODE_SILENT) {
|
|
gtk_progress_set_activity_mode(GTK_PROGRESS(sMajorProgBar), FALSE);
|
|
gtk_progress_bar_update(GTK_PROGRESS_BAR(sMajorProgBar), (gfloat) 0);
|
|
gtk_label_set_text(GTK_LABEL(sMajorLabel), "");
|
|
|
|
if (bDownload)
|
|
{
|
|
InitDLProgress( TRUE );
|
|
|
|
pauseLabel = gtk_label_new(gCtx->Res("PAUSE"));
|
|
resumeLabel = gtk_label_new(gCtx->Res("RESUME"));
|
|
gtk_container_remove(GTK_CONTAINER(gCtx->back), gCtx->backLabel);
|
|
gtk_container_remove(GTK_CONTAINER(gCtx->next), gCtx->installLabel);
|
|
gtk_container_add(GTK_CONTAINER(gCtx->back), pauseLabel);
|
|
gtk_container_add(GTK_CONTAINER(gCtx->next), resumeLabel);
|
|
gtk_widget_show(pauseLabel);
|
|
gtk_widget_show(resumeLabel);
|
|
|
|
gtk_signal_disconnect(GTK_OBJECT(gCtx->back), gCtx->backID);
|
|
gtk_signal_disconnect(GTK_OBJECT(gCtx->next), gCtx->nextID);
|
|
gtk_signal_disconnect(GTK_OBJECT(gCtx->cancel), gCtx->cancelID);
|
|
|
|
// disable resume button
|
|
gtk_widget_set_sensitive(gCtx->next, FALSE);
|
|
|
|
XI_GTK_UPDATE_UI();
|
|
|
|
// hook up buttons with callbacks
|
|
gCtx->backID = gtk_signal_connect(GTK_OBJECT(gCtx->back), "clicked",
|
|
GTK_SIGNAL_FUNC(DLPause), NULL);
|
|
gCtx->nextID = gtk_signal_connect(GTK_OBJECT(gCtx->next), "clicked",
|
|
GTK_SIGNAL_FUNC(DLResume), NULL);
|
|
gCtx->cancelID = gtk_signal_connect(GTK_OBJECT(gCtx->cancel), "clicked",
|
|
GTK_SIGNAL_FUNC(DLCancel), NULL);
|
|
}
|
|
else
|
|
{
|
|
gtk_widget_show(sMajorLabel);
|
|
gtk_widget_show(sMajorProgBar);
|
|
|
|
gtk_widget_hide(gCtx->back);
|
|
gtk_widget_hide(gCtx->next);
|
|
gtk_widget_hide(gCtx->cancel);
|
|
}
|
|
|
|
gtk_widget_hide(sMsg0Label);
|
|
if (bDownload && sDLTable)
|
|
gtk_widget_hide(sDLTable);
|
|
XI_GTK_UPDATE_UI();
|
|
}
|
|
|
|
PerformInstall();
|
|
while (bDLPause) {
|
|
// event loop ends with resume or cancel
|
|
gtk_main();
|
|
if (!bDLCancel)
|
|
PerformInstall();
|
|
}
|
|
|
|
// mode auto has no call to gtk_main()
|
|
if (gCtx->opt->mMode == nsXIOptions::MODE_DEFAULT)
|
|
gtk_main_quit();
|
|
|
|
#ifdef MOZ_WIDGET_GTK
|
|
gCtx->bMoving = TRUE;
|
|
#endif
|
|
return;
|
|
}
|
|
|
|
int
|
|
nsInstallDlg::Parse(nsINIParser *aParser)
|
|
{
|
|
int err = OK;
|
|
int bufsize = 0;
|
|
char *showDlg = NULL;
|
|
char secName[64];
|
|
int i;
|
|
char *app = NULL, *args = NULL;
|
|
nsRunApp *newRunApp = NULL;
|
|
|
|
/* compulsory keys*/
|
|
XI_ERR_BAIL(aParser->GetStringAlloc(DLG_START_INSTALL,
|
|
XPINSTALL_ENGINE, &sXPInstallEngine, &bufsize));
|
|
if (bufsize == 0 || !sXPInstallEngine)
|
|
return E_INVALID_KEY;
|
|
|
|
/* optional keys */
|
|
bufsize = 0;
|
|
err = aParser->GetStringAlloc(DLG_START_INSTALL, MSG0, &mMsg0, &bufsize);
|
|
if (err != OK && err != nsINIParser::E_NO_KEY) goto BAIL; else err = OK;
|
|
|
|
bufsize = 5;
|
|
XI_ERR_BAIL(aParser->GetStringAlloc(DLG_START_INSTALL, SHOW_DLG,
|
|
&showDlg, &bufsize));
|
|
if (bufsize != 0 && showDlg)
|
|
{
|
|
if (0 == strncmp(showDlg, "TRUE", 4))
|
|
mShowDlg = nsXInstallerDlg::SHOW_DIALOG;
|
|
else if (0 == strncmp(showDlg, "FALSE", 5))
|
|
mShowDlg = nsXInstallerDlg::SKIP_DIALOG;
|
|
}
|
|
|
|
bufsize = 0;
|
|
XI_ERR_BAIL(aParser->GetStringAlloc(DLG_START_INSTALL, TITLE,
|
|
&mTitle, &bufsize));
|
|
if (bufsize == 0)
|
|
XI_IF_FREE(mTitle);
|
|
|
|
for (i = 0; err == OK; i++)
|
|
{
|
|
/* construct PostInstallRunX section name */
|
|
sprintf(secName, POSTINSTALLRUNd, i);
|
|
err = aParser->GetStringAlloc(secName, TARGET, &app, &bufsize);
|
|
if (err == OK && bufsize > 0)
|
|
{
|
|
/* "args" is optional: this may return E_NO_KEY which we ignore */
|
|
aParser->GetStringAlloc(secName, ARGS, &args, &bufsize);
|
|
newRunApp = new nsRunApp(app, args);
|
|
if (!newRunApp)
|
|
return E_MEM;
|
|
err = AppendRunApp(&sPostInstallRun, newRunApp);
|
|
}
|
|
}
|
|
err = OK; /* reset error since PostInstallRunX sections are optional
|
|
and we could have gotten a parse error (E_NO_SEC) */
|
|
|
|
for (i = 0; err == OK; i++)
|
|
{
|
|
/* construct RunAppX section name */
|
|
sprintf(secName, RUNAPPd, i);
|
|
err = aParser->GetStringAlloc(secName, TARGET, &app, &bufsize);
|
|
if (err == OK && bufsize > 0)
|
|
{
|
|
/* "args" is optional: this may return E_NO_KEY which we ignore */
|
|
aParser->GetStringAlloc(secName, ARGS, &args, &bufsize);
|
|
newRunApp = new nsRunApp(app, args);
|
|
if (!newRunApp)
|
|
return E_MEM;
|
|
err = AppendRunApp(&sRunAppList, newRunApp);
|
|
}
|
|
}
|
|
err = OK; /* reset error since RunAppX sections are optional
|
|
and we could have gotten a parse error (E_NO_SEC) */
|
|
|
|
BAIL:
|
|
return err;
|
|
}
|
|
|
|
int
|
|
nsInstallDlg::AppendRunApp(nsRunApp **aRunAppList, nsRunApp *aNewRunApp)
|
|
{
|
|
int err = OK;
|
|
nsRunApp *currRunApp = NULL, *nextRunApp = NULL;
|
|
|
|
/* param check */
|
|
if (!aNewRunApp)
|
|
return E_PARAM;
|
|
|
|
/* special case: list is empty */
|
|
if (!*aRunAppList)
|
|
{
|
|
*aRunAppList = aNewRunApp;
|
|
return OK;
|
|
}
|
|
|
|
/* list has at least one element */
|
|
currRunApp = *aRunAppList;
|
|
while (currRunApp)
|
|
{
|
|
if (!(nextRunApp = currRunApp->GetNext()))
|
|
{
|
|
currRunApp->SetNext(aNewRunApp);
|
|
break;
|
|
}
|
|
currRunApp = nextRunApp;
|
|
}
|
|
return err;
|
|
}
|
|
|
|
void
|
|
nsInstallDlg::FreeRunAppList(nsRunApp *aRunAppList)
|
|
{
|
|
nsRunApp *currRunApp = aRunAppList, *nextRunApp = NULL;
|
|
|
|
while (currRunApp)
|
|
{
|
|
nextRunApp = currRunApp->GetNext();
|
|
delete currRunApp;
|
|
currRunApp = nextRunApp;
|
|
}
|
|
}
|
|
|
|
void
|
|
nsInstallDlg::RunApps(nsRunApp *aRunAppList, int aSequential)
|
|
{
|
|
nsRunApp *currRunApp = aRunAppList;
|
|
char *argv[3], *dest;
|
|
char apppath[MAXPATHLEN];
|
|
extern NS_IMPORT_(char **) environ; /* globally available to all processes */
|
|
|
|
dest = gCtx->opt->mDestination;
|
|
if (chdir(dest) < 0)
|
|
fprintf(stderr,"chdir(%s): %s\n",dest,strerror(errno));
|
|
|
|
while (currRunApp)
|
|
{
|
|
/* run application with supplied args */
|
|
sprintf(apppath, "%s/%s", dest, currRunApp->GetApp());
|
|
|
|
argv[0] = apppath;
|
|
argv[1] = currRunApp->GetArgs();
|
|
argv[2] = NULL; /* null-terminate arg vector */
|
|
|
|
if (!fork())
|
|
{
|
|
/* child */
|
|
|
|
execve(apppath, argv, environ);
|
|
|
|
/* shouldn't reach this but in case execve fails we will */
|
|
_exit(0);
|
|
}
|
|
/* parent continues running to finish installation */
|
|
|
|
if (aSequential)
|
|
{
|
|
wait(NULL);
|
|
}
|
|
|
|
currRunApp = currRunApp->GetNext();
|
|
}
|
|
|
|
|
|
}
|
|
|
|
int
|
|
nsInstallDlg::Show()
|
|
{
|
|
int err = OK;
|
|
GtkWidget *hbox = NULL;
|
|
GtkWidget *vbox = NULL;
|
|
GtkWidget *dlFrame, *dlCheckbox, *dlProxyBtn;
|
|
int bCus;
|
|
nsComponentList *comps = NULL;
|
|
|
|
XI_VERIFY(gCtx);
|
|
XI_VERIFY(gCtx->notebook);
|
|
|
|
if (mWidgetsInit == FALSE)
|
|
{
|
|
// create a new table and add it as a page of the notebook
|
|
mTable = gtk_table_new(4, 1, FALSE);
|
|
gtk_notebook_append_page(GTK_NOTEBOOK(gCtx->notebook), mTable, NULL);
|
|
mPageNum = gtk_notebook_get_current_page(GTK_NOTEBOOK(gCtx->notebook));
|
|
gtk_widget_show(mTable);
|
|
|
|
// insert a static text widget in the first row
|
|
sMsg0Label = gtk_label_new(mMsg0);
|
|
hbox = gtk_hbox_new(FALSE, 0);
|
|
gtk_box_pack_start(GTK_BOX(hbox), sMsg0Label, FALSE, FALSE, 0);
|
|
gtk_widget_show(hbox);
|
|
gtk_table_attach(GTK_TABLE(mTable), hbox, 0, 1, 0, 1,
|
|
static_cast<GtkAttachOptions>(GTK_FILL | GTK_EXPAND),
|
|
GTK_FILL, 20, 20);
|
|
gtk_widget_show(sMsg0Label);
|
|
|
|
// Proxy Settings
|
|
// insert a [ x ] heterogenous table
|
|
sDLTable = gtk_table_new(2, 2, FALSE);
|
|
|
|
gtk_table_attach(GTK_TABLE(mTable), sDLTable, 0, 1, 1, 4,
|
|
static_cast<GtkAttachOptions>(GTK_FILL | GTK_EXPAND),
|
|
GTK_FILL, 20, 20);
|
|
|
|
// download settings groupbox
|
|
dlFrame = gtk_frame_new(gCtx->Res("DL_SETTINGS"));
|
|
gtk_table_attach_defaults(GTK_TABLE(sDLTable), dlFrame, 0, 2, 0, 2);
|
|
gtk_widget_show(dlFrame);
|
|
|
|
// save installer modules checkbox and label
|
|
dlCheckbox = gtk_check_button_new_with_label(
|
|
gCtx->Res("SAVE_MODULES"));
|
|
gtk_widget_show(dlCheckbox);
|
|
gtk_table_attach(GTK_TABLE(sDLTable), dlCheckbox, 0, 2, 0, 1,
|
|
GTK_FILL, GTK_FILL, 10, 20);
|
|
gtk_signal_connect(GTK_OBJECT(dlCheckbox), "toggled",
|
|
GTK_SIGNAL_FUNC(SaveModulesToggled), NULL);
|
|
|
|
// proxy settings button
|
|
dlProxyBtn = gtk_button_new_with_label(gCtx->Res("PROXY_SETTINGS"));
|
|
gtk_widget_show(dlProxyBtn);
|
|
gtk_table_attach(GTK_TABLE(sDLTable), dlProxyBtn, 0, 1, 1, 2,
|
|
GTK_FILL, GTK_FILL, 10, 10);
|
|
gtk_signal_connect(GTK_OBJECT(dlProxyBtn), "clicked",
|
|
GTK_SIGNAL_FUNC(ShowProxySettings), NULL);
|
|
|
|
// vbox with two widgets packed in: label0 / progmeter0 (major)
|
|
vbox = gtk_vbox_new(FALSE, 0);
|
|
hbox = gtk_hbox_new(FALSE, 0);
|
|
sMajorLabel = gtk_label_new("");
|
|
sRateLabel = gtk_label_new("");
|
|
gtk_box_pack_start(GTK_BOX(hbox), sMajorLabel, FALSE, FALSE, 0);
|
|
gtk_box_pack_start(GTK_BOX(hbox), sRateLabel, FALSE, FALSE, 0);
|
|
gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
|
|
gtk_widget_show(hbox);
|
|
gtk_widget_show(sMajorLabel);
|
|
gtk_widget_show(sRateLabel);
|
|
|
|
sMajorProgBar = gtk_progress_bar_new();
|
|
gtk_box_pack_start(GTK_BOX(vbox), sMajorProgBar, FALSE, FALSE, 0);
|
|
// gtk_widget_show(sMajorProgBar);
|
|
|
|
gtk_table_attach(GTK_TABLE(mTable), vbox, 0, 1, 2, 3,
|
|
static_cast<GtkAttachOptions>(GTK_FILL | GTK_EXPAND),
|
|
GTK_FILL, 20, 20);
|
|
gtk_widget_show(vbox);
|
|
|
|
// vbox with two widgets packed in: label1 / progmeter1 (minor)
|
|
vbox = gtk_vbox_new(FALSE, 0);
|
|
hbox = gtk_hbox_new(FALSE, 0);
|
|
sMinorLabel = gtk_label_new("");
|
|
gtk_box_pack_start(GTK_BOX(hbox), sMinorLabel, FALSE, FALSE, 0);
|
|
gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
|
|
gtk_widget_show(hbox);
|
|
gtk_widget_show(sMinorLabel);
|
|
|
|
sMinorProgBar = gtk_progress_bar_new();
|
|
gtk_box_pack_start(GTK_BOX(vbox), sMinorProgBar, FALSE, FALSE, 0);
|
|
// gtk_widget_show(sMinorProgBar);
|
|
|
|
gtk_table_attach(GTK_TABLE(mTable), vbox, 0, 1, 3, 4,
|
|
static_cast<GtkAttachOptions>(GTK_FILL | GTK_EXPAND),
|
|
GTK_FILL, 20, 20);
|
|
gtk_widget_show(vbox);
|
|
|
|
mWidgetsInit = TRUE;
|
|
}
|
|
else
|
|
{
|
|
gtk_notebook_set_page(GTK_NOTEBOOK(gCtx->notebook), mPageNum);
|
|
gtk_widget_show(mTable);
|
|
}
|
|
|
|
bCus = (gCtx->opt->mSetupType == (gCtx->sdlg->GetNumSetupTypes() - 1));
|
|
comps = gCtx->sdlg->GetSelectedSetupType()->GetComponents();
|
|
|
|
if (!nsXIEngine::ExistAllXPIs(bCus, comps))
|
|
{
|
|
bDownload = TRUE;
|
|
gtk_widget_show(sDLTable);
|
|
}
|
|
else
|
|
{
|
|
bDownload = FALSE;
|
|
}
|
|
|
|
// signal connect the buttons
|
|
gCtx->backID = gtk_signal_connect(GTK_OBJECT(gCtx->back), "clicked",
|
|
GTK_SIGNAL_FUNC(nsInstallDlg::Back), gCtx->idlg);
|
|
gCtx->nextID = gtk_signal_connect(GTK_OBJECT(gCtx->next), "clicked",
|
|
GTK_SIGNAL_FUNC(nsInstallDlg::Next), gCtx->idlg);
|
|
|
|
if (gCtx->opt->mSetupType != (gCtx->sdlg->GetNumSetupTypes() - 1))
|
|
{
|
|
// show back btn again after setup type dlg where we couldn't go back
|
|
gtk_widget_show(gCtx->back);
|
|
}
|
|
|
|
GTK_WIDGET_SET_FLAGS(gCtx->next, GTK_CAN_DEFAULT);
|
|
gtk_widget_grab_default(gCtx->next);
|
|
gtk_widget_grab_focus(gCtx->next);
|
|
|
|
// show back and next button, but make title of next button "Install"
|
|
gCtx->backLabel = gtk_label_new(gCtx->Res("BACK"));
|
|
gCtx->installLabel = gtk_label_new(gCtx->Res("INSTALL"));
|
|
gtk_container_add(GTK_CONTAINER(gCtx->back), gCtx->backLabel);
|
|
gtk_container_add(GTK_CONTAINER(gCtx->next), gCtx->installLabel);
|
|
gtk_widget_show(gCtx->backLabel);
|
|
gtk_widget_show(gCtx->installLabel);
|
|
gtk_widget_show(gCtx->back);
|
|
gtk_widget_show(gCtx->next);
|
|
|
|
if (!mShowDlg)
|
|
{
|
|
gCtx->bMoving = FALSE;
|
|
nsInstallDlg::Next((GtkWidget *)NULL, gCtx->idlg);
|
|
return err;
|
|
}
|
|
|
|
|
|
return err;
|
|
}
|
|
|
|
int
|
|
nsInstallDlg::Hide()
|
|
{
|
|
if (bDownload && sDLTable)
|
|
gtk_widget_hide(sDLTable);
|
|
|
|
gtk_widget_hide(mTable);
|
|
|
|
// disconnect and remove this dlg's nav btns
|
|
gtk_signal_disconnect(GTK_OBJECT(gCtx->back), gCtx->backID);
|
|
gtk_signal_disconnect(GTK_OBJECT(gCtx->next), gCtx->nextID);
|
|
|
|
gtk_container_remove(GTK_CONTAINER(gCtx->back), gCtx->backLabel);
|
|
gtk_container_remove(GTK_CONTAINER(gCtx->next), gCtx->installLabel);
|
|
|
|
gtk_widget_hide(gCtx->back);
|
|
gtk_widget_hide(gCtx->next);
|
|
|
|
return OK;
|
|
}
|
|
|
|
int
|
|
nsInstallDlg::ShowTable()
|
|
{
|
|
if (!mTable)
|
|
return E_PARAM;
|
|
|
|
gtk_widget_show(mTable);
|
|
|
|
return OK;
|
|
}
|
|
|
|
int
|
|
nsInstallDlg::HideTable()
|
|
{
|
|
if (!mTable)
|
|
return E_PARAM;
|
|
|
|
gtk_widget_hide(mTable);
|
|
|
|
return OK;
|
|
}
|
|
|
|
int
|
|
nsInstallDlg::SetMsg0(char *aMsg)
|
|
{
|
|
if (!aMsg)
|
|
return E_PARAM;
|
|
|
|
mMsg0 = aMsg;
|
|
|
|
return OK;
|
|
}
|
|
|
|
char *
|
|
nsInstallDlg::GetMsg0()
|
|
{
|
|
if (mMsg0)
|
|
return mMsg0;
|
|
|
|
return NULL;
|
|
}
|
|
|
|
int
|
|
nsInstallDlg::PerformInstall()
|
|
{
|
|
DUMP("PerformInstall");
|
|
|
|
int err = OK;
|
|
|
|
// perform the installation
|
|
nsXIEngine *engine = new nsXIEngine();
|
|
if (!engine)
|
|
{
|
|
ErrorHandler(E_MEM);
|
|
return E_MEM;
|
|
}
|
|
|
|
// get the component list for the current setup type
|
|
nsComponentList *comps = NULL;
|
|
nsComponent *xpiengine = NULL;
|
|
int bCus = (gCtx->opt->mSetupType == (gCtx->sdlg->GetNumSetupTypes() - 1));
|
|
comps = gCtx->sdlg->GetSelectedSetupType()->GetComponents();
|
|
|
|
if (!sXPInstallEngine) return E_PARAM;
|
|
xpiengine = comps->GetCompByArchive(sXPInstallEngine);
|
|
|
|
// 1> download
|
|
if (bDownload)
|
|
{
|
|
err = engine->Download(bCus, comps);
|
|
if (err == E_DL_DROP_CXN)
|
|
{
|
|
ShowCxnDroppedDlg();
|
|
if (gCtx->opt->mMode != nsXIOptions::MODE_SILENT)
|
|
DLPause(NULL, NULL);
|
|
return err;
|
|
}
|
|
else if (err == E_CRC_FAILED)
|
|
{
|
|
ErrorHandler(err);
|
|
goto BAIL;
|
|
}
|
|
else if (err == E_DL_PAUSE || err == E_DL_CANCEL)
|
|
{
|
|
DUMP("Pause or Cancel pressed");
|
|
goto BAIL;
|
|
}
|
|
else if (err != OK)
|
|
{
|
|
DUMP("dammit... hopped into the wrong hole!");
|
|
ErrorHandler(err);
|
|
goto BAIL;
|
|
}
|
|
}
|
|
|
|
// prepare install UI
|
|
if (gCtx->opt->mMode != nsXIOptions::MODE_SILENT)
|
|
{
|
|
InitInstallProgress();
|
|
HideNavButtons();
|
|
}
|
|
|
|
// 2> extract engine
|
|
XI_ERR_BAIL(engine->Extract(xpiengine));
|
|
|
|
// 3> install .xpis
|
|
XI_ERR_BAIL(engine->Install(bCus, comps, gCtx->opt->mDestination));
|
|
|
|
// delete xpis if user didn't request saving them
|
|
if (bDownload && !gCtx->opt->mSaveModules)
|
|
{
|
|
engine->DeleteXPIs(bCus, comps);
|
|
}
|
|
|
|
// destroy installer engine thread object
|
|
XI_IF_DELETE(engine);
|
|
|
|
// run post-install applications to complete installation
|
|
if (sPostInstallRun)
|
|
{
|
|
if (gCtx->opt->mMode != nsXIOptions::MODE_SILENT)
|
|
MajorProgressCB("", 1, 1, ACT_COMPLETE);
|
|
RunApps(sPostInstallRun, 1);
|
|
FreeRunAppList(sPostInstallRun);
|
|
}
|
|
|
|
// run all specified applications after installation
|
|
if (sRunAppList)
|
|
{
|
|
if (gCtx->opt->mShouldRunApps)
|
|
RunApps(sRunAppList, 0);
|
|
FreeRunAppList(sRunAppList);
|
|
}
|
|
|
|
return OK;
|
|
|
|
BAIL:
|
|
// destroy installer engine thread object
|
|
XI_IF_DELETE(engine);
|
|
|
|
return err;
|
|
}
|
|
|
|
void
|
|
nsInstallDlg::XPIProgressCB(const char *aMsg, int aVal, int aMax)
|
|
{
|
|
if (gCtx->opt->mMode == nsXIOptions::MODE_SILENT)
|
|
return;
|
|
// DUMP("XPIProgressCB");
|
|
|
|
if (!aMsg)
|
|
return;
|
|
|
|
static int updates = 0;
|
|
char msg[64];
|
|
const char *colon = NULL, *lastSlash = NULL;
|
|
|
|
if (aMax > 0)
|
|
{
|
|
// reset for next component
|
|
if (updates)
|
|
updates = 0;
|
|
|
|
gfloat percent = (gfloat)((gfloat)aVal/(gfloat)aMax);
|
|
#if 0
|
|
printf("progress percent: %f\taVal: %d\taMax: %d\n", percent, aVal, aMax);
|
|
#endif
|
|
gtk_progress_set_activity_mode(GTK_PROGRESS(sMinorProgBar), FALSE);
|
|
gtk_progress_bar_update(GTK_PROGRESS_BAR(sMinorProgBar), percent);
|
|
gtk_widget_show(sMinorProgBar);
|
|
|
|
sprintf(msg, gCtx->Res("PROCESSING_FILE"), aVal, aMax);
|
|
}
|
|
else
|
|
{
|
|
updates++;
|
|
if (updates > 5)
|
|
updates = 0;
|
|
gfloat percent = (gfloat)((gfloat)updates/(gfloat)5);
|
|
|
|
gtk_progress_set_activity_mode(GTK_PROGRESS(sMinorProgBar), TRUE);
|
|
gtk_progress_bar_update(GTK_PROGRESS_BAR(sMinorProgBar), percent);
|
|
gtk_widget_show(sMinorProgBar);
|
|
|
|
/* tack on XPInstall action */
|
|
memset(msg, 0, 64);
|
|
colon = strchr(aMsg, ':');
|
|
if (colon)
|
|
strncpy(msg, aMsg, colon - aMsg);
|
|
|
|
strncat(msg, " ", 1);
|
|
|
|
/* tack on leaf name */
|
|
lastSlash = strrchr(aMsg, '/');
|
|
if (lastSlash)
|
|
strncat(msg, lastSlash + 1, strlen(lastSlash) - 1);
|
|
|
|
strncat(msg, "\0", 1);
|
|
}
|
|
|
|
gtk_label_set_text(GTK_LABEL(sMinorLabel), msg);
|
|
gtk_widget_draw(sMinorLabel, NULL);
|
|
|
|
XI_GTK_UPDATE_UI();
|
|
}
|
|
|
|
void
|
|
nsInstallDlg::MajorProgressCB(char *aName, int aNum, int aTotal, int aActivity)
|
|
{
|
|
// DUMP("MajorProgressCB");
|
|
|
|
char msg[256];
|
|
|
|
if (!aName)
|
|
return;
|
|
|
|
#ifdef DEBUG
|
|
printf("%s %d: Name = %s\tNum = %d\tTotal = %d\tAct = %d\n",
|
|
__FILE__, __LINE__, aName, aNum, aTotal, aActivity);
|
|
#endif
|
|
|
|
switch (aActivity)
|
|
{
|
|
case ACT_DOWNLOAD:
|
|
if (!bDownload)
|
|
sprintf(msg, gCtx->Res("PREPARING"), aName);
|
|
break;
|
|
|
|
case ACT_EXTRACT:
|
|
sprintf(msg, gCtx->Res("EXTRACTING"), aName);
|
|
break;
|
|
|
|
case ACT_INSTALL:
|
|
sprintf(msg, gCtx->Res("INSTALLING_XPI"), aName);
|
|
break;
|
|
|
|
case ACT_COMPLETE:
|
|
sprintf(msg, gCtx->Res("COMPLETING_INSTALL"));
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
gtk_label_set_text(GTK_LABEL(sMajorLabel), msg);
|
|
gtk_widget_show(sMajorLabel);
|
|
|
|
if (aTotal <= 0)
|
|
{
|
|
XI_ASSERT(0, "aTotal was <= 0");
|
|
XI_GTK_UPDATE_UI();
|
|
return;
|
|
}
|
|
|
|
gfloat percent = (gfloat)((gfloat)aNum/(gfloat)aTotal);
|
|
gtk_progress_bar_update(GTK_PROGRESS_BAR(sMajorProgBar), percent);
|
|
gtk_widget_show(sMajorProgBar);
|
|
|
|
// reset minor progress ui
|
|
if (aActivity == ACT_INSTALL)
|
|
{
|
|
gtk_label_set_text(GTK_LABEL(sMinorLabel), "");
|
|
gtk_progress_bar_update(GTK_PROGRESS_BAR(sMinorProgBar), (gfloat)0);
|
|
gtk_widget_show(sMinorLabel);
|
|
gtk_widget_show(sMinorProgBar);
|
|
}
|
|
else if (aActivity == ACT_COMPLETE)
|
|
gtk_label_set_text(GTK_LABEL(sMinorLabel), "");
|
|
|
|
XI_GTK_UPDATE_UI();
|
|
}
|
|
|
|
const int kCharsInDLLabel = 50;
|
|
|
|
void
|
|
nsInstallDlg::SetDownloadComp(nsComponent *aComp, int aURLIndex,
|
|
int aNum, int aTotal)
|
|
{
|
|
static char xpiDir[MAXPATHLEN];
|
|
static int bHaveXPIDir = FALSE;
|
|
char label[MAXPATHLEN];
|
|
char localPath[MAXPATHLEN];
|
|
|
|
if (!aComp)
|
|
return;
|
|
|
|
if (!bHaveXPIDir)
|
|
{
|
|
getcwd(xpiDir, MAXPATHLEN);
|
|
strcat(xpiDir, "/xpi");
|
|
bHaveXPIDir = TRUE;
|
|
}
|
|
|
|
// update comp name
|
|
sprintf(label, "%s [%d/%d]", aComp->GetDescShort(), aNum, aTotal);
|
|
gtk_label_set_text(GTK_LABEL(sDLProgress.compName), label);
|
|
|
|
// update from URL
|
|
label[0] = 0;
|
|
CompressToFit(aComp->GetURL(aURLIndex), label, kCharsInDLLabel);
|
|
gtk_label_set_text(GTK_LABEL(sDLProgress.URL), label);
|
|
|
|
// to local path
|
|
label[0] = 0;
|
|
sprintf(localPath, "%s/%s", xpiDir, aComp->GetArchive());
|
|
CompressToFit(localPath, label, kCharsInDLLabel);
|
|
gtk_label_set_text(GTK_LABEL(sDLProgress.localPath), label);
|
|
|
|
gettimeofday(&sDLStartTime, NULL);
|
|
}
|
|
|
|
#define SHOW_EVERY_N_KB 16
|
|
int
|
|
nsInstallDlg::DownloadCB(int aBytesRd, int aTotal)
|
|
{
|
|
struct timeval now;
|
|
char label[64];
|
|
int rate;
|
|
gfloat percent = 0;
|
|
static int timesCalled = 0;
|
|
static int activityCount = 0;
|
|
int dlKB;
|
|
static int lastTotal = 0;
|
|
static int lastBytesRd = 0;
|
|
|
|
// new component being downloaded
|
|
if (lastTotal != aTotal)
|
|
{
|
|
lastBytesRd = 0; // reset
|
|
lastTotal = aTotal;
|
|
}
|
|
|
|
if ((aBytesRd - lastBytesRd) > 0)
|
|
{
|
|
sDLProgress.downloadedBytes += aBytesRd - lastBytesRd;
|
|
lastBytesRd = aBytesRd;
|
|
}
|
|
|
|
if (bDLPause || bDLCancel)
|
|
{
|
|
return nsHTTPConn::E_USER_CANCEL;
|
|
}
|
|
|
|
if (++timesCalled < SHOW_EVERY_N_KB)
|
|
return 0;
|
|
else
|
|
timesCalled = 0;
|
|
|
|
gettimeofday(&now, NULL);
|
|
rate = (int) nsSocket::CalcRate(&sDLStartTime, &now, aBytesRd);
|
|
|
|
// update the status -- bytes thus far, rate, percent in prog bar
|
|
dlKB = sDLProgress.downloadedBytes/1024;
|
|
sprintf(label, gCtx->Res("DL_STATUS_STR"), dlKB, sDLProgress.totalKB, rate);
|
|
gtk_label_set_text(GTK_LABEL(sDLProgress.status), label);
|
|
|
|
/*
|
|
// only update rate in major label line
|
|
XXX remove this: DLRATE no longer exists
|
|
sprintf(label, gCtx->Res("DLRATE"), rate);
|
|
gtk_label_set_text(GTK_LABEL(sRateLabel), label);
|
|
*/
|
|
|
|
if (sDLProgress.totalKB <= 0)
|
|
{
|
|
// show some activity
|
|
if (activityCount >= 5) activityCount = 0;
|
|
percent = (gfloat)( (gfloat)activityCount++/ (gfloat)5 );
|
|
gtk_progress_set_activity_mode(GTK_PROGRESS(sDLProgress.progBar), TRUE);
|
|
gtk_progress_bar_update(GTK_PROGRESS_BAR(sDLProgress.progBar), percent);
|
|
}
|
|
else
|
|
{
|
|
percent = (gfloat)dlKB/(gfloat)sDLProgress.totalKB;
|
|
#ifdef DEBUG
|
|
printf("DLProgress: %d of %d (%f percent) at %d KB/sec\n", dlKB,
|
|
sDLProgress.totalKB, percent, rate);
|
|
#endif
|
|
gtk_progress_set_activity_mode(GTK_PROGRESS(sDLProgress.progBar),
|
|
FALSE);
|
|
gtk_progress_bar_update(GTK_PROGRESS_BAR(sDLProgress.progBar), percent);
|
|
}
|
|
|
|
XI_GTK_UPDATE_UI();
|
|
return 0;
|
|
}
|
|
|
|
void
|
|
nsInstallDlg::ClearRateLabel()
|
|
{
|
|
gtk_label_set_text(GTK_LABEL(sRateLabel), "");
|
|
gtk_progress_set_activity_mode(GTK_PROGRESS(sMajorProgBar), FALSE);
|
|
XI_GTK_UPDATE_UI();
|
|
}
|
|
|
|
void
|
|
nsInstallDlg::SaveModulesToggled(GtkWidget *aWidget, gpointer aData)
|
|
{
|
|
if (GTK_TOGGLE_BUTTON(aWidget)->active)
|
|
{
|
|
DUMP("Save modules toggled on");
|
|
gCtx->opt->mSaveModules = TRUE;
|
|
}
|
|
else
|
|
{
|
|
DUMP("Save modules toggled off");
|
|
gCtx->opt->mSaveModules = FALSE;
|
|
}
|
|
}
|
|
|
|
void
|
|
nsInstallDlg::ShowProxySettings(GtkWidget *aWidget, gpointer aData)
|
|
{
|
|
GtkWidget *psDlg, *psTable;
|
|
GtkWidget *okButton, *cancelButton;
|
|
GtkWidget *psLabel[NUM_PS_ENTRIES];
|
|
int i;
|
|
char resName[16], *text = nsnull;
|
|
|
|
psDlg = gtk_dialog_new();
|
|
gtk_window_set_modal(GTK_WINDOW(psDlg), TRUE);
|
|
gtk_window_set_title(GTK_WINDOW(psDlg), gCtx->opt->mTitle);
|
|
gtk_window_set_position(GTK_WINDOW(psDlg), GTK_WIN_POS_CENTER);
|
|
|
|
psTable = gtk_table_new(5, 2, FALSE);
|
|
gtk_container_add(GTK_CONTAINER(GTK_DIALOG(psDlg)->vbox), psTable);
|
|
gtk_widget_show(psTable);
|
|
|
|
// create labels
|
|
for (i = 0; i < NUM_PS_ENTRIES; ++i)
|
|
{
|
|
sprintf(resName, "PS_LABEL%d", i);
|
|
psLabel[i] = gtk_label_new(gCtx->Res(resName));
|
|
gtk_widget_show(psLabel[i]);
|
|
|
|
gtk_misc_set_alignment(GTK_MISC(psLabel[i]), 1, 0.5);
|
|
|
|
gtk_table_attach(GTK_TABLE(psTable), psLabel[i], 0, 1, i, i + 1,
|
|
static_cast<GtkAttachOptions>(GTK_FILL | GTK_EXPAND),
|
|
static_cast<GtkAttachOptions>(GTK_FILL | GTK_EXPAND), 5, 5);
|
|
}
|
|
|
|
// create text entry fields
|
|
for (i = 0; i < NUM_PS_ENTRIES; ++i)
|
|
{
|
|
sPSTextEntry[i] = gtk_entry_new();
|
|
gtk_entry_set_editable(GTK_ENTRY(sPSTextEntry[i]), TRUE);
|
|
|
|
// reset text if we already opened this dlg before
|
|
if (i == 0) text = gCtx->opt->mProxyHost;
|
|
if (i == 1) text = gCtx->opt->mProxyPort;
|
|
if (i == 2) text = gCtx->opt->mProxyUser;
|
|
if (i == 3) text = gCtx->opt->mProxyPswd;
|
|
|
|
if (text)
|
|
gtk_entry_set_text(GTK_ENTRY(sPSTextEntry[i]), text);
|
|
|
|
// password field
|
|
if (i + 1 == NUM_PS_ENTRIES)
|
|
gtk_entry_set_visibility(GTK_ENTRY(sPSTextEntry[i]), FALSE);
|
|
|
|
gtk_widget_show(sPSTextEntry[i]);
|
|
|
|
gtk_table_attach(GTK_TABLE(psTable), sPSTextEntry[i],
|
|
1, 2, i, i + 1,
|
|
static_cast<GtkAttachOptions>(GTK_FILL | GTK_EXPAND),
|
|
static_cast<GtkAttachOptions>(GTK_FILL | GTK_EXPAND), 5, 5);
|
|
}
|
|
|
|
// pre-populate text entry fields if data already stored
|
|
okButton = gtk_button_new_with_label(gCtx->Res("OK_LABEL"));
|
|
gtk_container_add(GTK_CONTAINER(GTK_DIALOG(psDlg)->action_area),
|
|
okButton);
|
|
gtk_signal_connect(GTK_OBJECT(okButton), "clicked",
|
|
GTK_SIGNAL_FUNC(PSDlgOK), psDlg);
|
|
GTK_WIDGET_SET_FLAGS(okButton, GTK_CAN_DEFAULT);
|
|
gtk_widget_grab_default(okButton);
|
|
gtk_widget_show(okButton);
|
|
|
|
cancelButton = gtk_button_new_with_label(gCtx->Res("CANCEL_LABEL"));
|
|
gtk_container_add(GTK_CONTAINER(GTK_DIALOG(psDlg)->action_area),
|
|
cancelButton);
|
|
gtk_signal_connect(GTK_OBJECT(cancelButton), "clicked",
|
|
GTK_SIGNAL_FUNC(PSDlgCancel), psDlg);
|
|
gtk_widget_show(cancelButton);
|
|
|
|
gtk_widget_show(psDlg);
|
|
}
|
|
|
|
void
|
|
nsInstallDlg::PSDlgOK(GtkWidget *aWidget, gpointer aData)
|
|
{
|
|
GtkWidget *dlg = (GtkWidget *) aData;
|
|
char *text;
|
|
char *proxyHost=NULL, *proxyPort=NULL, *proxyUser=NULL, *proxyPswd=NULL;
|
|
|
|
// grab proxy host field
|
|
text = gtk_editable_get_chars(GTK_EDITABLE(sPSTextEntry[0]), 0, -1);
|
|
if (text && *text)
|
|
proxyHost = text;
|
|
else
|
|
XI_IF_FREE(text);
|
|
|
|
// grab proxy port field
|
|
text = gtk_editable_get_chars(GTK_EDITABLE(sPSTextEntry[1]), 0, -1);
|
|
if (text && *text)
|
|
proxyPort = text;
|
|
else
|
|
XI_IF_FREE(text);
|
|
|
|
// grab proxy user field
|
|
text = gtk_editable_get_chars(GTK_EDITABLE(sPSTextEntry[2]), 0, -1);
|
|
if (text && *text)
|
|
proxyUser = text;
|
|
else
|
|
XI_IF_FREE(text);
|
|
|
|
// grab proxy pswd field
|
|
text = gtk_editable_get_chars(GTK_EDITABLE(sPSTextEntry[3]), 0, -1);
|
|
if (text && *text)
|
|
proxyPswd = text;
|
|
else
|
|
XI_IF_FREE(text);
|
|
|
|
if ( (proxyHost || proxyPort || proxyUser || proxyPswd)
|
|
&& (!proxyHost || !proxyPort) )
|
|
{
|
|
XI_IF_FREE(proxyHost);
|
|
XI_IF_FREE(proxyPort);
|
|
XI_IF_FREE(proxyUser);
|
|
XI_IF_FREE(proxyPswd);
|
|
ErrorHandler(E_INVALID_PROXY);
|
|
}
|
|
else
|
|
{
|
|
XI_IF_FREE(gCtx->opt->mProxyHost);
|
|
XI_IF_FREE(gCtx->opt->mProxyPort);
|
|
XI_IF_FREE(gCtx->opt->mProxyUser);
|
|
XI_IF_FREE(gCtx->opt->mProxyPswd);
|
|
|
|
gCtx->opt->mProxyHost = proxyHost;
|
|
gCtx->opt->mProxyPort = proxyPort;
|
|
gCtx->opt->mProxyUser = proxyUser;
|
|
gCtx->opt->mProxyPswd = proxyPswd;
|
|
gtk_widget_destroy(dlg);
|
|
}
|
|
}
|
|
|
|
void
|
|
nsInstallDlg::PSDlgCancel(GtkWidget *aWidget, gpointer aData)
|
|
{
|
|
GtkWidget *dlg = (GtkWidget *) aData;
|
|
|
|
if (dlg)
|
|
gtk_widget_destroy(dlg);
|
|
}
|
|
|
|
void
|
|
nsInstallDlg::DLPause(GtkWidget *aWidget, gpointer aData)
|
|
{
|
|
DUMP("DLPause");
|
|
|
|
// set pause for download callback to return to libxpnet
|
|
bDLPause = TRUE;
|
|
|
|
// disbale pause button
|
|
gtk_widget_set_sensitive(gCtx->back, FALSE);
|
|
|
|
// enable resume button
|
|
gtk_widget_set_sensitive(gCtx->next, TRUE);
|
|
}
|
|
|
|
void
|
|
nsInstallDlg::DLResume(GtkWidget *aWidget, gpointer aData)
|
|
{
|
|
DUMP("DLResume");
|
|
|
|
if (!bDLPause)
|
|
{
|
|
DUMP("Not paused");
|
|
return;
|
|
}
|
|
|
|
DUMP("Unsetting bDLPause");
|
|
bDLPause = FALSE;
|
|
|
|
// disable resume button
|
|
gtk_widget_set_sensitive(gCtx->next, FALSE);
|
|
|
|
// enable pause button
|
|
gtk_widget_set_sensitive(gCtx->back, TRUE);
|
|
|
|
gtk_main_quit();
|
|
}
|
|
|
|
void
|
|
nsInstallDlg::DLCancel(GtkWidget *aWidget, gpointer aData)
|
|
{
|
|
DUMP("DLCancel");
|
|
|
|
// show cancellation confirm dialog
|
|
// XXX TO DO
|
|
|
|
// set cancel for download callback to return to libxpnet
|
|
bDLCancel = TRUE;
|
|
|
|
#ifdef DEBUG
|
|
printf("%s %d: bDLPause: %d\tbDLCancel: %d\n", __FILE__, __LINE__,
|
|
bDLPause, bDLCancel);
|
|
#endif
|
|
|
|
// already paused then take explicit action to quit
|
|
if (bDLPause)
|
|
{
|
|
bDLPause = FALSE;
|
|
gtk_main_quit();
|
|
}
|
|
}
|
|
|
|
int
|
|
nsInstallDlg::CancelOrPause()
|
|
{
|
|
int err = OK;
|
|
|
|
if (bDLPause)
|
|
{
|
|
err = E_DL_PAUSE;
|
|
}
|
|
else if (bDLCancel)
|
|
{
|
|
err = E_DL_CANCEL;
|
|
}
|
|
|
|
return err;
|
|
}
|
|
|
|
static GtkWidget *crcDlg = (GtkWidget *) NULL;
|
|
|
|
void
|
|
nsInstallDlg::ShowCRCDlg()
|
|
{
|
|
GtkWidget *label, *okButton;
|
|
|
|
if (gCtx->opt->mMode == nsXIOptions::MODE_SILENT) {
|
|
ErrorHandler(E_CRC_FAILED);
|
|
return;
|
|
}
|
|
|
|
if ( crcDlg == (GtkWidget *) NULL ) {
|
|
// throw up dialog informing user to press resume
|
|
// or to cancel out
|
|
crcDlg = gtk_dialog_new();
|
|
gtk_window_set_modal(GTK_WINDOW(crcDlg), TRUE);
|
|
label = gtk_label_new(gCtx->Res("CRC_CHECK"));
|
|
okButton = gtk_button_new_with_label(gCtx->Res("OK_LABEL"));
|
|
if (crcDlg && label && okButton )
|
|
{
|
|
gtk_misc_set_padding(GTK_MISC(label), 20, 20);
|
|
gtk_misc_set_alignment(GTK_MISC(label), 0.5, 1);
|
|
gtk_window_set_title(GTK_WINDOW(crcDlg), gCtx->opt->mTitle);
|
|
gtk_window_set_position(GTK_WINDOW(crcDlg), GTK_WIN_POS_CENTER);
|
|
gtk_container_add(GTK_CONTAINER(GTK_DIALOG(crcDlg)->vbox),
|
|
label);
|
|
gtk_container_add(GTK_CONTAINER(GTK_DIALOG(crcDlg)->action_area),
|
|
okButton);
|
|
gtk_signal_connect(GTK_OBJECT(okButton), "clicked",
|
|
GTK_SIGNAL_FUNC(CRCOKCb), crcDlg);
|
|
GTK_WIDGET_SET_FLAGS(okButton, GTK_CAN_DEFAULT);
|
|
gtk_widget_grab_default(okButton);
|
|
gtk_widget_show_all(crcDlg);
|
|
}
|
|
}
|
|
XI_GTK_UPDATE_UI();
|
|
}
|
|
|
|
int
|
|
nsInstallDlg::ShowCxnDroppedDlg()
|
|
{
|
|
GtkWidget *cxnDroppedDlg, *label, *okButton;
|
|
|
|
// throw up dialog informing user to press resume
|
|
// or to cancel out
|
|
if (gCtx->opt->mMode == nsXIOptions::MODE_SILENT) {
|
|
ErrorHandler(E_NO_DOWNLOAD);
|
|
return OK;
|
|
}
|
|
|
|
cxnDroppedDlg = gtk_dialog_new();
|
|
gtk_window_set_modal(GTK_WINDOW(cxnDroppedDlg), TRUE);
|
|
label = gtk_label_new(gCtx->Res("CXN_DROPPED"));
|
|
okButton = gtk_button_new_with_label(gCtx->Res("OK_LABEL"));
|
|
|
|
if (cxnDroppedDlg && label && okButton )
|
|
{
|
|
gtk_misc_set_padding(GTK_MISC(label), 20, 20);
|
|
gtk_misc_set_alignment(GTK_MISC(label), 0.5, 1);
|
|
gtk_window_set_modal(GTK_WINDOW(cxnDroppedDlg), TRUE);
|
|
gtk_window_set_title(GTK_WINDOW(cxnDroppedDlg), gCtx->opt->mTitle);
|
|
gtk_window_set_position(GTK_WINDOW(cxnDroppedDlg), GTK_WIN_POS_CENTER);
|
|
gtk_container_add(GTK_CONTAINER(GTK_DIALOG(cxnDroppedDlg)->vbox),
|
|
label);
|
|
gtk_container_add(GTK_CONTAINER(GTK_DIALOG(cxnDroppedDlg)->action_area),
|
|
okButton);
|
|
gtk_signal_connect(GTK_OBJECT(okButton), "clicked",
|
|
GTK_SIGNAL_FUNC(CxnDroppedOK), cxnDroppedDlg);
|
|
GTK_WIDGET_SET_FLAGS(okButton, GTK_CAN_DEFAULT);
|
|
gtk_widget_grab_default(okButton);
|
|
gtk_widget_show_all(cxnDroppedDlg);
|
|
}
|
|
XI_GTK_UPDATE_UI();
|
|
|
|
return OK;
|
|
}
|
|
|
|
void
|
|
nsInstallDlg::DestroyCRCDlg()
|
|
{
|
|
CRCOKCb( (GtkWidget *) NULL, (gpointer) NULL );
|
|
}
|
|
|
|
void
|
|
nsInstallDlg::CRCOKCb(GtkWidget *aWidget, gpointer aData)
|
|
{
|
|
if (crcDlg != (GtkWidget *) NULL)
|
|
gtk_widget_destroy(crcDlg);
|
|
crcDlg = (GtkWidget *) NULL;
|
|
|
|
return;
|
|
}
|
|
|
|
void
|
|
nsInstallDlg::CxnDroppedOK(GtkWidget *aWidget, gpointer aData)
|
|
{
|
|
GtkWidget *cxnDroppedDlg = (GtkWidget *) aData;
|
|
|
|
if (cxnDroppedDlg)
|
|
gtk_widget_destroy(cxnDroppedDlg);
|
|
|
|
return;
|
|
}
|
|
|
|
void
|
|
nsInstallDlg::HideNavButtons()
|
|
{
|
|
gtk_signal_disconnect(GTK_OBJECT(gCtx->back), gCtx->backID);
|
|
gtk_signal_disconnect(GTK_OBJECT(gCtx->next), gCtx->nextID);
|
|
gtk_signal_disconnect(GTK_OBJECT(gCtx->cancel), gCtx->cancelID);
|
|
|
|
gtk_widget_hide(gCtx->back);
|
|
gtk_widget_hide(gCtx->next);
|
|
gtk_widget_hide(gCtx->cancel);
|
|
}
|
|
|
|
void
|
|
nsInstallDlg::InitDLProgress( int isFirst )
|
|
{
|
|
GtkWidget *titles[4];
|
|
GtkWidget *hbox;
|
|
GtkWidget *table;
|
|
|
|
gCtx->idlg->HideTable();
|
|
|
|
if ( isFirst == TRUE ) {
|
|
sDLProgress.vbox = gtk_vbox_new(FALSE, 10);
|
|
gtk_notebook_append_page(GTK_NOTEBOOK(gCtx->notebook),
|
|
sDLProgress.vbox, NULL);
|
|
gtk_widget_show(sDLProgress.vbox);
|
|
|
|
table = gtk_table_new(5, 2, FALSE);
|
|
gtk_box_pack_start(GTK_BOX(sDLProgress.vbox), table, FALSE,
|
|
FALSE, 0);
|
|
gtk_widget_show(table);
|
|
|
|
// setup static title progress labels in table left column
|
|
titles[0] = gtk_label_new(gCtx->Res("DOWNLOADING"));
|
|
titles[1] = gtk_label_new(gCtx->Res("FROM"));
|
|
titles[2] = gtk_label_new(gCtx->Res("TO"));
|
|
titles[3] = gtk_label_new(gCtx->Res("STATUS"));
|
|
|
|
// setup dynamic progress labels in right column
|
|
sDLProgress.compName = gtk_label_new(gCtx->Res("UNKNOWN"));
|
|
sDLProgress.URL = gtk_label_new(gCtx->Res("UNKNOWN"));
|
|
sDLProgress.localPath = gtk_label_new(gCtx->Res("UNKNOWN"));
|
|
sDLProgress.status = gtk_label_new(gCtx->Res("UNKNOWN"));
|
|
|
|
// pack and show titles
|
|
for (int i = 0; i < 4; ++i)
|
|
{
|
|
hbox = gtk_hbox_new(FALSE, 10);
|
|
gtk_box_pack_end(GTK_BOX(hbox), titles[i], FALSE, FALSE, 0);
|
|
gtk_table_attach(GTK_TABLE(table), hbox,
|
|
0, 1, i, i + 1, GTK_FILL, GTK_FILL, 5, 5);
|
|
gtk_widget_show(titles[i]);
|
|
gtk_widget_show(hbox);
|
|
}
|
|
|
|
// pack and show dynamic labels
|
|
hbox = gtk_hbox_new(FALSE, 10);
|
|
gtk_box_pack_start(GTK_BOX(hbox), sDLProgress.compName, FALSE, FALSE, 0);
|
|
gtk_table_attach(GTK_TABLE(table), hbox, 1, 2, 0, 1,
|
|
GTK_FILL, GTK_FILL, 5, 5);
|
|
gtk_widget_show(sDLProgress.compName);
|
|
gtk_widget_show(hbox);
|
|
|
|
hbox = gtk_hbox_new(FALSE, 10);
|
|
gtk_box_pack_start(GTK_BOX(hbox), sDLProgress.URL, FALSE, FALSE, 0);
|
|
gtk_table_attach(GTK_TABLE(table), hbox, 1, 2, 1, 2,
|
|
GTK_FILL, GTK_FILL, 5, 5);
|
|
gtk_widget_show(sDLProgress.URL);
|
|
gtk_widget_show(hbox);
|
|
|
|
hbox = gtk_hbox_new(FALSE, 10);
|
|
gtk_box_pack_start(GTK_BOX(hbox), sDLProgress.localPath, FALSE,
|
|
FALSE, 0);
|
|
gtk_table_attach(GTK_TABLE(table), hbox, 1, 2, 2, 3,
|
|
GTK_FILL, GTK_FILL, 5, 5);
|
|
gtk_widget_show(sDLProgress.localPath);
|
|
gtk_widget_show(hbox);
|
|
|
|
hbox = gtk_hbox_new(FALSE, 10);
|
|
gtk_box_pack_start(GTK_BOX(hbox), sDLProgress.status, FALSE,
|
|
FALSE, 0);
|
|
gtk_table_attach(GTK_TABLE(table), hbox, 1, 2, 3, 4,
|
|
GTK_FILL, GTK_FILL, 5, 5);
|
|
gtk_widget_show(sDLProgress.status);
|
|
gtk_widget_show(hbox);
|
|
|
|
// init and show prog bar
|
|
sDLProgress.progBar = gtk_progress_bar_new();
|
|
|
|
// show prog bar
|
|
hbox = gtk_hbox_new(TRUE, 10);
|
|
gtk_box_pack_start(GTK_BOX(hbox), sDLProgress.progBar, FALSE,
|
|
TRUE, 0);
|
|
gtk_box_pack_start(GTK_BOX(sDLProgress.vbox), hbox, FALSE,
|
|
FALSE, 0);
|
|
gtk_widget_show(sDLProgress.progBar);
|
|
gtk_widget_show(hbox);
|
|
}
|
|
|
|
// set to non-activity mode and initialize
|
|
gtk_progress_set_activity_mode(GTK_PROGRESS(sDLProgress.progBar), FALSE);
|
|
gtk_progress_bar_update(GTK_PROGRESS_BAR(sDLProgress.progBar), (gfloat) 0);
|
|
|
|
// compute total download size
|
|
sDLProgress.downloadedBytes = 0;
|
|
sDLProgress.totalKB = TotalDLSize();
|
|
|
|
XI_GTK_UPDATE_UI();
|
|
}
|
|
|
|
void
|
|
nsInstallDlg::InitInstallProgress()
|
|
{
|
|
if ( sDLProgress.vbox )
|
|
gtk_widget_hide(sDLProgress.vbox);
|
|
gCtx->idlg->ShowTable();
|
|
}
|
|
|
|
int
|
|
nsInstallDlg::TotalDLSize()
|
|
{
|
|
int total = 0; // in KB
|
|
int bCustom;
|
|
nsComponentList *comps;
|
|
nsComponent *currComp;
|
|
int archiveSize, currentSize;
|
|
|
|
bCustom = (gCtx->opt->mSetupType == (gCtx->sdlg->GetNumSetupTypes() - 1));
|
|
comps = gCtx->sdlg->GetSelectedSetupType()->GetComponents();
|
|
currComp = comps->GetHead();
|
|
|
|
// loop through all components
|
|
while (currComp)
|
|
{
|
|
if ((bCustom && currComp->IsSelected()) || (!bCustom))
|
|
{
|
|
// if still have to download
|
|
if (!currComp->IsDownloaded())
|
|
{
|
|
// find archive size - amount downloaded already
|
|
archiveSize = currComp->GetArchiveSize();
|
|
currentSize = currComp->GetCurrentSize();
|
|
|
|
#ifdef DEBUG
|
|
printf("%s ar sz = %d cu sz = %d\n", currComp->GetArchive(),
|
|
archiveSize, currentSize);
|
|
#endif
|
|
|
|
total += (archiveSize - currentSize);
|
|
}
|
|
}
|
|
currComp = comps->GetNext();
|
|
}
|
|
|
|
return total;
|
|
}
|
|
|
|
void
|
|
nsInstallDlg::CompressToFit(char *aOrigStr, char *aOutStr, int aOutStrLen)
|
|
{
|
|
int origStrLen;
|
|
int halfOutStrLen;
|
|
char *lastPart; // last aOrigStr part start
|
|
|
|
if (!aOrigStr || !aOutStr || aOutStrLen <= 0)
|
|
return;
|
|
|
|
origStrLen = strlen(aOrigStr);
|
|
halfOutStrLen = (aOutStrLen/2) - 2; // minus 2 since ellipsis is 3 chars
|
|
lastPart = aOrigStr + origStrLen - halfOutStrLen;
|
|
|
|
strncpy(aOutStr, aOrigStr, halfOutStrLen);
|
|
*(aOutStr + halfOutStrLen) = 0;
|
|
strcat(aOutStr, "...");
|
|
strncat(aOutStr, lastPart, strlen(lastPart));
|
|
*(aOutStr + aOutStrLen + 1) = 0;
|
|
}
|
|
|
|
void
|
|
nsInstallDlg::ReInitUI( void )
|
|
{
|
|
InitDLProgress( FALSE );
|
|
}
|