Back to index

lightning-sunbird  0.9+nobinonly
nsInstallDlg.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is Mozilla Communicator client code, released
00016  * March 31, 1998.
00017  *
00018  * The Initial Developer of the Original Code is
00019  * Netscape Communications Corporation.
00020  * Portions created by the Initial Developer are Copyright (C) 1998
00021  * the Initial Developer. All Rights Reserved.
00022  *
00023  * Contributor(s):
00024  *   Samir Gehani <sgehani@netscape.com>
00025  *
00026  * Alternatively, the contents of this file may be used under the terms of
00027  * either of the GNU General Public License Version 2 or later (the "GPL"),
00028  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00029  * in which case the provisions of the GPL or the LGPL are applicable instead
00030  * of those above. If you wish to allow use of your version of this file only
00031  * under the terms of either the GPL or the LGPL, and not to allow others to
00032  * use your version of this file under the terms of the MPL, indicate your
00033  * decision by deleting the provisions above and replace them with the notice
00034  * and other provisions required by the GPL or the LGPL. If you do not delete
00035  * the provisions above, a recipient may use your version of this file under
00036  * the terms of any one of the MPL, the GPL or the LGPL.
00037  *
00038  * ***** END LICENSE BLOCK ***** */
00039 
00040 #include "nsSocket.h"
00041 #include "nsHTTPConn.h"
00042 #include "nsInstallDlg.h"
00043 #include "nsXInstaller.h"
00044 #include "nsXIEngine.h"
00045 #include <signal.h>
00046 #include <sys/wait.h>
00047 #include <gtk/gtk.h>
00048 #include <errno.h>
00049 
00050 #define NUM_PS_ENTRIES 4
00051 
00052 typedef struct _DLProgress 
00053 {
00054     // progress widgets
00055     GtkWidget *vbox;
00056     GtkWidget *compName;
00057     GtkWidget *URL;
00058     GtkWidget *localPath;
00059     GtkWidget *status;
00060     GtkWidget *progBar;
00061 
00062     // progress info
00063     int       downloadedBytes;
00064     int       totalKB;
00065 } 
00066 DLProgress;
00067 
00068 static char             *sXPInstallEngine;
00069 static nsRunApp         *sRunAppList = NULL;
00070 static nsRunApp         *sPostInstallRun = NULL;
00071 static DLProgress       sDLProgress;
00072 
00073 static GtkWidget        *sDLTable = NULL;
00074 static GtkWidget        *sMsg0Label;
00075 static GtkWidget        *sMajorLabel;
00076 static GtkWidget        *sMinorLabel;
00077 static GtkWidget        *sRateLabel;
00078 static GtkWidget        *sMajorProgBar;
00079 static GtkWidget        *sMinorProgBar;
00080 static GtkWidget        *sPSTextEntry[NUM_PS_ENTRIES];
00081 
00082 static int              bDownload = FALSE;
00083 static struct timeval   sDLStartTime;
00084 static int              bDLPause = FALSE;
00085 static int              bDLCancel = FALSE;
00086 
00087 nsInstallDlg::nsInstallDlg() :
00088     mMsg0(NULL)
00089 {
00090 }
00091 
00092 nsInstallDlg::~nsInstallDlg()
00093 {
00094     XI_IF_FREE(mMsg0);  
00095 }
00096 
00097 void
00098 nsInstallDlg::Back(GtkWidget *aWidget, gpointer aData)
00099 {
00100     DUMP("Back");
00101     if (aData != gCtx->idlg) return;
00102 #ifdef MOZ_WIDGET_GTK
00103     if (gCtx->bMoving)
00104     {
00105         gCtx->bMoving = FALSE;
00106         return;
00107     }
00108 #endif
00109 
00110     // hide this notebook page
00111     gCtx->idlg->Hide();
00112 
00113     // show the last dlg
00114     if (gCtx->opt->mSetupType == (gCtx->sdlg->GetNumSetupTypes() - 1))
00115     {
00116         gCtx->cdlg->Show();
00117         // only set bMoving for component dlg since setuptype has no "back"
00118 #ifdef MOZ_WIDGET_GTK
00119         gCtx->bMoving = TRUE;
00120 #endif
00121     }
00122     else
00123     {
00124         gCtx->sdlg->Show();
00125     }
00126 }
00127 
00128 void
00129 nsInstallDlg::Next(GtkWidget *aWidget, gpointer aData)
00130 {
00131     DUMP("Next");
00132     GtkWidget *pauseLabel, *resumeLabel;
00133 
00134     if (aData != gCtx->idlg) return;
00135 #ifdef MOZ_WIDGET_GTK
00136     if (gCtx->bMoving)
00137     {
00138         gCtx->bMoving = FALSE;
00139         DUMP("Moving done!");
00140         return;
00141     }
00142 #endif
00143 
00144     // initialize progress bar cleanly
00145     if (gCtx->opt->mMode != nsXIOptions::MODE_SILENT) {
00146         gtk_progress_set_activity_mode(GTK_PROGRESS(sMajorProgBar), FALSE);
00147         gtk_progress_bar_update(GTK_PROGRESS_BAR(sMajorProgBar), (gfloat) 0);
00148         gtk_label_set_text(GTK_LABEL(sMajorLabel), "");
00149 
00150         if (bDownload)
00151         {
00152             InitDLProgress( TRUE );
00153 
00154             pauseLabel = gtk_label_new(gCtx->Res("PAUSE"));
00155             resumeLabel = gtk_label_new(gCtx->Res("RESUME"));
00156             gtk_container_remove(GTK_CONTAINER(gCtx->back), gCtx->backLabel); 
00157             gtk_container_remove(GTK_CONTAINER(gCtx->next), gCtx->installLabel); 
00158             gtk_container_add(GTK_CONTAINER(gCtx->back), pauseLabel);
00159             gtk_container_add(GTK_CONTAINER(gCtx->next), resumeLabel);
00160             gtk_widget_show(pauseLabel);
00161             gtk_widget_show(resumeLabel);
00162 
00163             gtk_signal_disconnect(GTK_OBJECT(gCtx->back), gCtx->backID);
00164             gtk_signal_disconnect(GTK_OBJECT(gCtx->next), gCtx->nextID);
00165             gtk_signal_disconnect(GTK_OBJECT(gCtx->cancel), gCtx->cancelID);
00166 
00167             // disable resume button
00168             gtk_widget_set_sensitive(gCtx->next, FALSE);
00169 
00170             XI_GTK_UPDATE_UI();
00171 
00172             // hook up buttons with callbacks
00173             gCtx->backID = gtk_signal_connect(GTK_OBJECT(gCtx->back), "clicked",
00174                 GTK_SIGNAL_FUNC(DLPause), NULL);
00175             gCtx->nextID = gtk_signal_connect(GTK_OBJECT(gCtx->next), "clicked",
00176                 GTK_SIGNAL_FUNC(DLResume), NULL);
00177             gCtx->cancelID = gtk_signal_connect(GTK_OBJECT(gCtx->cancel), "clicked",
00178                 GTK_SIGNAL_FUNC(DLCancel), NULL);
00179         }
00180         else
00181         {
00182             gtk_widget_show(sMajorLabel);
00183             gtk_widget_show(sMajorProgBar);
00184 
00185             gtk_widget_hide(gCtx->back);
00186             gtk_widget_hide(gCtx->next);
00187             gtk_widget_hide(gCtx->cancel);
00188         }
00189 
00190         gtk_widget_hide(sMsg0Label);
00191         if (bDownload && sDLTable)
00192             gtk_widget_hide(sDLTable);
00193         XI_GTK_UPDATE_UI();
00194     }
00195 
00196     PerformInstall();
00197     while (bDLPause) {
00198         // event loop ends with resume or cancel
00199         gtk_main();
00200         if (!bDLCancel)
00201             PerformInstall();
00202     }
00203 
00204     // mode auto has no call to gtk_main()
00205     if (gCtx->opt->mMode == nsXIOptions::MODE_DEFAULT)
00206         gtk_main_quit();
00207     
00208 #ifdef MOZ_WIDGET_GTK
00209     gCtx->bMoving = TRUE;
00210 #endif
00211     return;
00212 }
00213 
00214 int
00215 nsInstallDlg::Parse(nsINIParser *aParser)
00216 {
00217     int err = OK;
00218     int bufsize = 0;
00219     char *showDlg = NULL;
00220     char secName[64];
00221     int i;
00222     char *app = NULL, *args = NULL;
00223     nsRunApp *newRunApp = NULL;
00224     
00225     /* compulsory keys*/
00226     XI_ERR_BAIL(aParser->GetStringAlloc(DLG_START_INSTALL, 
00227                 XPINSTALL_ENGINE, &sXPInstallEngine, &bufsize));
00228     if (bufsize == 0 || !sXPInstallEngine)
00229         return E_INVALID_KEY;
00230 
00231     /* optional keys */
00232     bufsize = 0;
00233     err = aParser->GetStringAlloc(DLG_START_INSTALL, MSG0, &mMsg0, &bufsize);
00234     if (err != OK && err != nsINIParser::E_NO_KEY) goto BAIL; else err = OK;
00235 
00236     bufsize = 5;
00237     XI_ERR_BAIL(aParser->GetStringAlloc(DLG_START_INSTALL, SHOW_DLG, 
00238                 &showDlg, &bufsize));
00239     if (bufsize != 0 && showDlg)
00240     {
00241         if (0 == strncmp(showDlg, "TRUE", 4))
00242             mShowDlg = nsXInstallerDlg::SHOW_DIALOG;
00243         else if (0 == strncmp(showDlg, "FALSE", 5))
00244             mShowDlg = nsXInstallerDlg::SKIP_DIALOG;
00245     }
00246 
00247     bufsize = 0;
00248     XI_ERR_BAIL(aParser->GetStringAlloc(DLG_START_INSTALL, TITLE, 
00249                 &mTitle, &bufsize));
00250     if (bufsize == 0)
00251         XI_IF_FREE(mTitle); 
00252 
00253     for (i = 0; err == OK; i++)
00254     {
00255         /* construct PostInstallRunX section name */
00256         sprintf(secName, POSTINSTALLRUNd, i);
00257         err = aParser->GetStringAlloc(secName, TARGET, &app, &bufsize);
00258         if (err == OK && bufsize > 0)
00259         {
00260             /* "args" is optional: this may return E_NO_KEY which we ignore */
00261             aParser->GetStringAlloc(secName, ARGS, &args, &bufsize);
00262             newRunApp = new nsRunApp(app, args);
00263             if (!newRunApp)
00264                 return E_MEM;
00265             err = AppendRunApp(&sPostInstallRun, newRunApp);
00266         }
00267     }
00268     err = OK; /* reset error since PostInstallRunX sections are optional
00269                  and we could have gotten a parse error (E_NO_SEC) */
00270 
00271     for (i = 0; err == OK; i++)
00272     {
00273         /* construct RunAppX section name */
00274         sprintf(secName, RUNAPPd, i);
00275         err = aParser->GetStringAlloc(secName, TARGET, &app, &bufsize);
00276         if (err == OK && bufsize > 0)
00277         {
00278             /* "args" is optional: this may return E_NO_KEY which we ignore */
00279             aParser->GetStringAlloc(secName, ARGS, &args, &bufsize);
00280             newRunApp = new nsRunApp(app, args);
00281             if (!newRunApp)
00282                 return E_MEM;
00283             err = AppendRunApp(&sRunAppList, newRunApp);
00284         }
00285     }
00286     err = OK; /* reset error since RunAppX sections are optional
00287                  and we could have gotten a parse error (E_NO_SEC) */
00288 
00289 BAIL:
00290     return err;
00291 }
00292 
00293 int 
00294 nsInstallDlg::AppendRunApp(nsRunApp **aRunAppList, nsRunApp *aNewRunApp)
00295 {
00296     int err = OK;
00297     nsRunApp *currRunApp = NULL, *nextRunApp = NULL;
00298 
00299     /* param check */
00300     if (!aNewRunApp)
00301         return E_PARAM;
00302 
00303     /* special case: list is empty */
00304     if (!*aRunAppList)
00305     {
00306         *aRunAppList = aNewRunApp;
00307         return OK;
00308     }
00309 
00310     /* list has at least one element */
00311     currRunApp = *aRunAppList;
00312     while (currRunApp)
00313     {
00314         if (!(nextRunApp = currRunApp->GetNext()))
00315         {
00316             currRunApp->SetNext(aNewRunApp);
00317             break;
00318         }
00319         currRunApp = nextRunApp;
00320     }
00321     return err;
00322 }
00323 
00324 void
00325 nsInstallDlg::FreeRunAppList(nsRunApp *aRunAppList)
00326 {
00327     nsRunApp *currRunApp = aRunAppList, *nextRunApp = NULL;
00328 
00329     while (currRunApp)
00330     {
00331         nextRunApp = currRunApp->GetNext();
00332         delete currRunApp;
00333         currRunApp = nextRunApp;
00334     }
00335 }
00336 
00337 void
00338 nsInstallDlg::RunApps(nsRunApp *aRunAppList, int aSequential)
00339 {
00340     nsRunApp *currRunApp = aRunAppList;
00341     char *argv[3], *dest;
00342     char apppath[MAXPATHLEN];
00343     extern NS_IMPORT_(char **) environ; /* globally available to all processes */
00344 
00345     dest = gCtx->opt->mDestination;
00346     if (chdir(dest) < 0) 
00347         fprintf(stderr,"chdir(%s): %s\n",dest,strerror(errno));
00348 
00349     while (currRunApp)
00350     {
00351         /* run application with supplied args */
00352         sprintf(apppath, "%s/%s", dest, currRunApp->GetApp());
00353 
00354         argv[0] = apppath;
00355         argv[1] = currRunApp->GetArgs();
00356         argv[2] = NULL; /* null-terminate arg vector */
00357 
00358         if (!fork())
00359         {
00360             /* child */
00361 
00362             execve(apppath, argv, environ);
00363 
00364             /* shouldn't reach this but in case execve fails we will */
00365             _exit(0);
00366         }
00367         /* parent continues running to finish installation */
00368 
00369         if (aSequential)
00370         {
00371            wait(NULL);
00372         }
00373 
00374         currRunApp = currRunApp->GetNext();
00375     }
00376 
00377 
00378 }
00379 
00380 int
00381 nsInstallDlg::Show()
00382 {
00383     int err = OK;
00384     GtkWidget *hbox = NULL;
00385     GtkWidget *vbox = NULL;
00386     GtkWidget *dlFrame, *dlCheckbox, *dlProxyBtn;
00387     int bCus;
00388     nsComponentList *comps = NULL;
00389 
00390     XI_VERIFY(gCtx);
00391     XI_VERIFY(gCtx->notebook);
00392 
00393     if (mWidgetsInit == FALSE)
00394     {
00395         // create a new table and add it as a page of the notebook
00396         mTable = gtk_table_new(4, 1, FALSE);
00397         gtk_notebook_append_page(GTK_NOTEBOOK(gCtx->notebook), mTable, NULL);
00398         mPageNum = gtk_notebook_get_current_page(GTK_NOTEBOOK(gCtx->notebook));
00399         gtk_widget_show(mTable);
00400 
00401         // insert a static text widget in the first row
00402         sMsg0Label = gtk_label_new(mMsg0);
00403         hbox = gtk_hbox_new(FALSE, 0);
00404         gtk_box_pack_start(GTK_BOX(hbox), sMsg0Label, FALSE, FALSE, 0);
00405         gtk_widget_show(hbox);
00406         gtk_table_attach(GTK_TABLE(mTable), hbox, 0, 1, 0, 1,
00407             static_cast<GtkAttachOptions>(GTK_FILL | GTK_EXPAND),
00408                      GTK_FILL, 20, 20);
00409         gtk_widget_show(sMsg0Label);
00410 
00411         // Proxy Settings
00412         // insert a [ x ] heterogenous table
00413         sDLTable = gtk_table_new(2, 2, FALSE);
00414 
00415         gtk_table_attach(GTK_TABLE(mTable), sDLTable, 0, 1, 1, 4, 
00416             static_cast<GtkAttachOptions>(GTK_FILL | GTK_EXPAND),
00417             GTK_FILL, 20, 20);
00418             
00419         // download settings groupbox
00420         dlFrame = gtk_frame_new(gCtx->Res("DL_SETTINGS"));
00421         gtk_table_attach_defaults(GTK_TABLE(sDLTable), dlFrame, 0, 2, 0, 2);
00422         gtk_widget_show(dlFrame);
00423     
00424         // save installer modules checkbox and label
00425         dlCheckbox = gtk_check_button_new_with_label(
00426                         gCtx->Res("SAVE_MODULES"));
00427         gtk_widget_show(dlCheckbox);
00428         gtk_table_attach(GTK_TABLE(sDLTable), dlCheckbox, 0, 2, 0, 1,
00429             GTK_FILL, GTK_FILL, 10, 20);
00430         gtk_signal_connect(GTK_OBJECT(dlCheckbox), "toggled",
00431             GTK_SIGNAL_FUNC(SaveModulesToggled), NULL);
00432 
00433         // proxy settings button
00434         dlProxyBtn = gtk_button_new_with_label(gCtx->Res("PROXY_SETTINGS"));
00435         gtk_widget_show(dlProxyBtn);
00436         gtk_table_attach(GTK_TABLE(sDLTable), dlProxyBtn, 0, 1, 1, 2,
00437             GTK_FILL, GTK_FILL, 10, 10);
00438         gtk_signal_connect(GTK_OBJECT(dlProxyBtn), "clicked",
00439             GTK_SIGNAL_FUNC(ShowProxySettings), NULL);
00440 
00441         // vbox with two widgets packed in: label0 / progmeter0 (major)
00442         vbox = gtk_vbox_new(FALSE, 0);
00443         hbox = gtk_hbox_new(FALSE, 0);
00444         sMajorLabel = gtk_label_new("");
00445         sRateLabel = gtk_label_new("");
00446         gtk_box_pack_start(GTK_BOX(hbox), sMajorLabel, FALSE, FALSE, 0);
00447         gtk_box_pack_start(GTK_BOX(hbox), sRateLabel, FALSE, FALSE, 0);
00448         gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
00449         gtk_widget_show(hbox);
00450         gtk_widget_show(sMajorLabel);
00451         gtk_widget_show(sRateLabel);
00452 
00453         sMajorProgBar = gtk_progress_bar_new();
00454         gtk_box_pack_start(GTK_BOX(vbox), sMajorProgBar, FALSE, FALSE, 0);
00455         // gtk_widget_show(sMajorProgBar);
00456 
00457         gtk_table_attach(GTK_TABLE(mTable), vbox, 0, 1, 2, 3, 
00458             static_cast<GtkAttachOptions>(GTK_FILL | GTK_EXPAND),
00459                      GTK_FILL, 20, 20);
00460         gtk_widget_show(vbox); 
00461 
00462         // vbox with two widgets packed in: label1 / progmeter1 (minor)
00463         vbox = gtk_vbox_new(FALSE, 0);
00464         hbox = gtk_hbox_new(FALSE, 0);
00465         sMinorLabel = gtk_label_new("");
00466         gtk_box_pack_start(GTK_BOX(hbox), sMinorLabel, FALSE, FALSE, 0);
00467         gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
00468         gtk_widget_show(hbox);
00469         gtk_widget_show(sMinorLabel);
00470 
00471         sMinorProgBar = gtk_progress_bar_new();
00472         gtk_box_pack_start(GTK_BOX(vbox), sMinorProgBar, FALSE, FALSE, 0);
00473         // gtk_widget_show(sMinorProgBar); 
00474 
00475         gtk_table_attach(GTK_TABLE(mTable), vbox, 0, 1, 3, 4, 
00476             static_cast<GtkAttachOptions>(GTK_FILL | GTK_EXPAND),
00477                      GTK_FILL, 20, 20);
00478         gtk_widget_show(vbox); 
00479         
00480         mWidgetsInit = TRUE;
00481     }
00482     else
00483     {
00484         gtk_notebook_set_page(GTK_NOTEBOOK(gCtx->notebook), mPageNum);
00485         gtk_widget_show(mTable);
00486     }
00487 
00488     bCus = (gCtx->opt->mSetupType == (gCtx->sdlg->GetNumSetupTypes() - 1));
00489     comps = gCtx->sdlg->GetSelectedSetupType()->GetComponents();
00490 
00491     if (!nsXIEngine::ExistAllXPIs(bCus, comps))
00492     {
00493         bDownload = TRUE;
00494         gtk_widget_show(sDLTable);
00495     }
00496     else
00497     {
00498         bDownload = FALSE;
00499     }
00500 
00501     // signal connect the buttons
00502     gCtx->backID = gtk_signal_connect(GTK_OBJECT(gCtx->back), "clicked",
00503                    GTK_SIGNAL_FUNC(nsInstallDlg::Back), gCtx->idlg);
00504     gCtx->nextID = gtk_signal_connect(GTK_OBJECT(gCtx->next), "clicked",
00505                    GTK_SIGNAL_FUNC(nsInstallDlg::Next), gCtx->idlg);
00506 
00507     if (gCtx->opt->mSetupType != (gCtx->sdlg->GetNumSetupTypes() - 1))
00508     {
00509         // show back btn again after setup type dlg where we couldn't go back
00510         gtk_widget_show(gCtx->back);
00511     }
00512 
00513     GTK_WIDGET_SET_FLAGS(gCtx->next, GTK_CAN_DEFAULT);
00514     gtk_widget_grab_default(gCtx->next);
00515     gtk_widget_grab_focus(gCtx->next);
00516 
00517     // show back and next button, but make title of next button "Install"
00518     gCtx->backLabel = gtk_label_new(gCtx->Res("BACK"));
00519     gCtx->installLabel = gtk_label_new(gCtx->Res("INSTALL"));
00520     gtk_container_add(GTK_CONTAINER(gCtx->back), gCtx->backLabel);
00521     gtk_container_add(GTK_CONTAINER(gCtx->next), gCtx->installLabel);
00522     gtk_widget_show(gCtx->backLabel);
00523     gtk_widget_show(gCtx->installLabel);
00524     gtk_widget_show(gCtx->back);
00525     gtk_widget_show(gCtx->next);
00526 
00527     if (!mShowDlg)
00528     {
00529        gCtx->bMoving = FALSE;
00530        nsInstallDlg::Next((GtkWidget *)NULL, gCtx->idlg);
00531        return err;
00532     }
00533    
00534 
00535     return err;
00536 }
00537 
00538 int
00539 nsInstallDlg::Hide()
00540 {
00541     if (bDownload && sDLTable)
00542         gtk_widget_hide(sDLTable);
00543 
00544     gtk_widget_hide(mTable);
00545 
00546     // disconnect and remove this dlg's nav btns
00547     gtk_signal_disconnect(GTK_OBJECT(gCtx->back), gCtx->backID);
00548     gtk_signal_disconnect(GTK_OBJECT(gCtx->next), gCtx->nextID);
00549 
00550     gtk_container_remove(GTK_CONTAINER(gCtx->back), gCtx->backLabel); 
00551     gtk_container_remove(GTK_CONTAINER(gCtx->next), gCtx->installLabel); 
00552 
00553     gtk_widget_hide(gCtx->back);
00554     gtk_widget_hide(gCtx->next);
00555 
00556     return OK;
00557 }
00558 
00559 int
00560 nsInstallDlg::ShowTable()
00561 {
00562     if (!mTable)
00563         return E_PARAM;
00564 
00565     gtk_widget_show(mTable);
00566 
00567     return OK;
00568 }
00569 
00570 int
00571 nsInstallDlg::HideTable()
00572 {
00573     if (!mTable)
00574         return E_PARAM;
00575 
00576     gtk_widget_hide(mTable);
00577 
00578     return OK;
00579 }
00580 
00581 int
00582 nsInstallDlg::SetMsg0(char *aMsg)
00583 {
00584     if (!aMsg)
00585         return E_PARAM;
00586 
00587     mMsg0 = aMsg;
00588 
00589     return OK;
00590 }
00591 
00592 char *
00593 nsInstallDlg::GetMsg0()
00594 {
00595     if (mMsg0)
00596         return mMsg0;
00597 
00598     return NULL;
00599 }
00600 
00601 int
00602 nsInstallDlg::PerformInstall()
00603 {
00604     DUMP("PerformInstall");
00605 
00606     int err = OK;
00607 
00608     // perform the installation
00609     nsXIEngine *engine = new nsXIEngine();
00610     if (!engine)
00611     {
00612         ErrorHandler(E_MEM);
00613         return E_MEM;
00614     }
00615 
00616     // get the component list for the current setup type
00617     nsComponentList *comps = NULL;
00618     nsComponent *xpiengine = NULL;
00619     int bCus = (gCtx->opt->mSetupType == (gCtx->sdlg->GetNumSetupTypes() - 1));
00620     comps = gCtx->sdlg->GetSelectedSetupType()->GetComponents();
00621     
00622     if (!sXPInstallEngine) return E_PARAM;
00623     xpiengine = comps->GetCompByArchive(sXPInstallEngine);
00624 
00625     // 1> download
00626     if (bDownload)
00627     {
00628         err = engine->Download(bCus, comps);
00629         if (err == E_DL_DROP_CXN)
00630         {
00631             ShowCxnDroppedDlg();
00632             if (gCtx->opt->mMode != nsXIOptions::MODE_SILENT)
00633                 DLPause(NULL, NULL);
00634             return err;
00635         }
00636         else if (err == E_CRC_FAILED)
00637         {
00638             ErrorHandler(err);
00639             goto BAIL;
00640         }
00641         else if (err == E_DL_PAUSE || err == E_DL_CANCEL)
00642         {
00643             DUMP("Pause or Cancel pressed");
00644             goto BAIL;
00645         }
00646         else if (err != OK)
00647         {
00648             DUMP("dammit... hopped into the wrong hole!");
00649             ErrorHandler(err);
00650             goto BAIL;
00651         }
00652     }
00653 
00654     // prepare install UI
00655     if (gCtx->opt->mMode != nsXIOptions::MODE_SILENT)
00656     {
00657         InitInstallProgress();
00658         HideNavButtons();
00659     }
00660 
00661     // 2> extract engine
00662     XI_ERR_BAIL(engine->Extract(xpiengine));
00663     
00664     // 3> install .xpis
00665     XI_ERR_BAIL(engine->Install(bCus, comps, gCtx->opt->mDestination));
00666 
00667     // delete xpis if user didn't request saving them
00668     if (bDownload && !gCtx->opt->mSaveModules)
00669     {
00670         engine->DeleteXPIs(bCus, comps);
00671     }
00672 
00673     // destroy installer engine thread object
00674     XI_IF_DELETE(engine);
00675 
00676     // run post-install applications to complete installation
00677     if (sPostInstallRun)
00678     {
00679         if (gCtx->opt->mMode != nsXIOptions::MODE_SILENT)
00680             MajorProgressCB("", 1, 1, ACT_COMPLETE);
00681         RunApps(sPostInstallRun, 1);
00682         FreeRunAppList(sPostInstallRun);
00683     }
00684 
00685     // run all specified applications after installation
00686     if (sRunAppList)
00687     {
00688         if (gCtx->opt->mShouldRunApps)
00689             RunApps(sRunAppList, 0);
00690         FreeRunAppList(sRunAppList);
00691     }
00692 
00693     return OK;
00694 
00695 BAIL:
00696     // destroy installer engine thread object
00697     XI_IF_DELETE(engine);
00698 
00699     return err;
00700 }
00701 
00702 void
00703 nsInstallDlg::XPIProgressCB(const char *aMsg, int aVal, int aMax)
00704 {
00705     if (gCtx->opt->mMode == nsXIOptions::MODE_SILENT)
00706        return;
00707     // DUMP("XPIProgressCB");
00708 
00709     if (!aMsg)
00710         return;
00711 
00712     static int updates = 0;
00713     char msg[64];
00714     const char *colon = NULL, *lastSlash = NULL;
00715 
00716     if (aMax > 0)
00717     {
00718         // reset for next component
00719         if (updates)
00720             updates = 0;
00721 
00722         gfloat percent = (gfloat)((gfloat)aVal/(gfloat)aMax);
00723 #if 0
00724     printf("progress percent: %f\taVal: %d\taMax: %d\n", percent, aVal, aMax);
00725 #endif
00726         gtk_progress_set_activity_mode(GTK_PROGRESS(sMinorProgBar), FALSE);
00727         gtk_progress_bar_update(GTK_PROGRESS_BAR(sMinorProgBar), percent);
00728         gtk_widget_show(sMinorProgBar);
00729 
00730         sprintf(msg, gCtx->Res("PROCESSING_FILE"), aVal, aMax);
00731     }
00732     else
00733     {
00734         updates++;
00735         if (updates > 5)
00736             updates = 0;
00737         gfloat percent = (gfloat)((gfloat)updates/(gfloat)5);
00738 
00739         gtk_progress_set_activity_mode(GTK_PROGRESS(sMinorProgBar), TRUE);
00740         gtk_progress_bar_update(GTK_PROGRESS_BAR(sMinorProgBar), percent);
00741         gtk_widget_show(sMinorProgBar);
00742 
00743         /* tack on XPInstall action */
00744         memset(msg, 0, 64);
00745         colon = strchr(aMsg, ':');
00746         if (colon)
00747             strncpy(msg, aMsg, colon - aMsg);
00748 
00749         strncat(msg, " ", 1);
00750 
00751         /* tack on leaf name */
00752         lastSlash = strrchr(aMsg, '/');
00753         if (lastSlash)
00754             strncat(msg, lastSlash + 1, strlen(lastSlash) - 1);
00755 
00756         strncat(msg, "\0", 1);
00757     }
00758 
00759     gtk_label_set_text(GTK_LABEL(sMinorLabel), msg);
00760     gtk_widget_draw(sMinorLabel, NULL);
00761 
00762     XI_GTK_UPDATE_UI();
00763 }
00764 
00765 void
00766 nsInstallDlg::MajorProgressCB(char *aName, int aNum, int aTotal, int aActivity)
00767 {
00768     // DUMP("MajorProgressCB");
00769 
00770     char msg[256];
00771 
00772     if (!aName)
00773        return;
00774 
00775 #ifdef DEBUG
00776     printf("%s %d: Name = %s\tNum = %d\tTotal = %d\tAct = %d\n", 
00777     __FILE__, __LINE__, aName, aNum, aTotal, aActivity);
00778 #endif
00779 
00780     switch (aActivity)
00781     {
00782         case ACT_DOWNLOAD:
00783             if (!bDownload)
00784                 sprintf(msg, gCtx->Res("PREPARING"), aName);
00785             break;
00786 
00787         case ACT_EXTRACT:
00788             sprintf(msg, gCtx->Res("EXTRACTING"), aName);
00789             break;
00790 
00791         case ACT_INSTALL:
00792             sprintf(msg, gCtx->Res("INSTALLING_XPI"), aName);
00793             break;
00794 
00795         case ACT_COMPLETE:
00796             sprintf(msg, gCtx->Res("COMPLETING_INSTALL"));
00797             break;
00798 
00799         default:
00800             break;
00801     }
00802 
00803     gtk_label_set_text(GTK_LABEL(sMajorLabel), msg);
00804     gtk_widget_show(sMajorLabel);
00805 
00806     if (aTotal <= 0)
00807     {
00808         XI_ASSERT(0, "aTotal was <= 0");
00809         XI_GTK_UPDATE_UI();
00810         return;
00811     }
00812 
00813     gfloat percent = (gfloat)((gfloat)aNum/(gfloat)aTotal);
00814     gtk_progress_bar_update(GTK_PROGRESS_BAR(sMajorProgBar), percent);
00815     gtk_widget_show(sMajorProgBar);
00816 
00817     // reset minor progress ui
00818     if (aActivity == ACT_INSTALL)
00819     {
00820         gtk_label_set_text(GTK_LABEL(sMinorLabel), "");
00821         gtk_progress_bar_update(GTK_PROGRESS_BAR(sMinorProgBar), (gfloat)0);
00822         gtk_widget_show(sMinorLabel);
00823         gtk_widget_show(sMinorProgBar);
00824     }
00825     else if (aActivity == ACT_COMPLETE)
00826         gtk_label_set_text(GTK_LABEL(sMinorLabel), "");
00827 
00828     XI_GTK_UPDATE_UI();
00829 }
00830 
00831 const int kCharsInDLLabel = 50;
00832 
00833 void
00834 nsInstallDlg::SetDownloadComp(nsComponent *aComp, int aURLIndex, 
00835                               int aNum, int aTotal)
00836 {
00837     static char xpiDir[MAXPATHLEN];
00838     static int bHaveXPIDir = FALSE;
00839     char label[MAXPATHLEN];
00840     char localPath[MAXPATHLEN];
00841     
00842     if (!aComp)
00843        return;
00844 
00845     if (!bHaveXPIDir)
00846     {
00847         getcwd(xpiDir, MAXPATHLEN);
00848         strcat(xpiDir, "/xpi");
00849         bHaveXPIDir = TRUE;
00850     }
00851 
00852     // update comp name 
00853     sprintf(label, "%s [%d/%d]", aComp->GetDescShort(), aNum, aTotal);
00854     gtk_label_set_text(GTK_LABEL(sDLProgress.compName), label);
00855 
00856     // update from URL 
00857     label[0] = 0;
00858     CompressToFit(aComp->GetURL(aURLIndex), label, kCharsInDLLabel);
00859     gtk_label_set_text(GTK_LABEL(sDLProgress.URL), label);
00860 
00861     // to local path 
00862     label[0] = 0;
00863     sprintf(localPath, "%s/%s", xpiDir, aComp->GetArchive());
00864     CompressToFit(localPath, label, kCharsInDLLabel);
00865     gtk_label_set_text(GTK_LABEL(sDLProgress.localPath), label);
00866     
00867     gettimeofday(&sDLStartTime, NULL);
00868 }
00869 
00870 #define SHOW_EVERY_N_KB 16
00871 int
00872 nsInstallDlg::DownloadCB(int aBytesRd, int aTotal)
00873 {
00874     struct timeval now;
00875     char label[64];
00876     int rate;
00877     gfloat percent = 0;
00878     static int timesCalled = 0;
00879     static int activityCount = 0;
00880     int dlKB;
00881     static int lastTotal = 0;
00882     static int lastBytesRd = 0;
00883 
00884     // new component being downloaded
00885     if (lastTotal != aTotal)
00886     {
00887         lastBytesRd = 0; // reset
00888         lastTotal = aTotal;
00889     }
00890     
00891     if ((aBytesRd - lastBytesRd) > 0)
00892     {
00893         sDLProgress.downloadedBytes += aBytesRd - lastBytesRd;
00894         lastBytesRd = aBytesRd;
00895     }
00896 
00897     if (bDLPause || bDLCancel)
00898     {
00899         return nsHTTPConn::E_USER_CANCEL;
00900     }
00901 
00902     if (++timesCalled < SHOW_EVERY_N_KB)
00903         return 0; 
00904     else
00905         timesCalled = 0;
00906 
00907     gettimeofday(&now, NULL);
00908     rate = (int) nsSocket::CalcRate(&sDLStartTime, &now, aBytesRd);
00909 
00910     // update the status -- bytes thus far, rate, percent in prog bar
00911     dlKB = sDLProgress.downloadedBytes/1024;
00912     sprintf(label, gCtx->Res("DL_STATUS_STR"), dlKB, sDLProgress.totalKB, rate);
00913     gtk_label_set_text(GTK_LABEL(sDLProgress.status), label);
00914 
00915 /*
00916     // only update rate in major label line
00917     XXX remove this: DLRATE no longer exists
00918     sprintf(label, gCtx->Res("DLRATE"), rate);
00919     gtk_label_set_text(GTK_LABEL(sRateLabel), label);
00920 */
00921 
00922     if (sDLProgress.totalKB <= 0) 
00923     {
00924         // show some activity
00925         if (activityCount >= 5) activityCount = 0;
00926         percent = (gfloat)( (gfloat)activityCount++/ (gfloat)5 ); 
00927         gtk_progress_set_activity_mode(GTK_PROGRESS(sDLProgress.progBar), TRUE);
00928         gtk_progress_bar_update(GTK_PROGRESS_BAR(sDLProgress.progBar), percent);
00929     }
00930     else
00931     {
00932         percent = (gfloat)dlKB/(gfloat)sDLProgress.totalKB;
00933 #ifdef DEBUG
00934     printf("DLProgress: %d of %d (%f percent) at %d KB/sec\n", dlKB,
00935             sDLProgress.totalKB, percent, rate);
00936 #endif
00937         gtk_progress_set_activity_mode(GTK_PROGRESS(sDLProgress.progBar), 
00938             FALSE); 
00939         gtk_progress_bar_update(GTK_PROGRESS_BAR(sDLProgress.progBar), percent);
00940     }
00941 
00942     XI_GTK_UPDATE_UI();
00943     return 0;
00944 }
00945 
00946 void
00947 nsInstallDlg::ClearRateLabel()
00948 {
00949     gtk_label_set_text(GTK_LABEL(sRateLabel), "");
00950     gtk_progress_set_activity_mode(GTK_PROGRESS(sMajorProgBar), FALSE); 
00951     XI_GTK_UPDATE_UI();
00952 }
00953 
00954 void
00955 nsInstallDlg::SaveModulesToggled(GtkWidget *aWidget, gpointer aData)
00956 {
00957     if (GTK_TOGGLE_BUTTON(aWidget)->active)
00958     {
00959         DUMP("Save modules toggled on");
00960         gCtx->opt->mSaveModules = TRUE;
00961     }
00962     else
00963     {
00964         DUMP("Save modules toggled off");
00965         gCtx->opt->mSaveModules = FALSE;
00966     }
00967 }
00968 
00969 void
00970 nsInstallDlg::ShowProxySettings(GtkWidget *aWidget, gpointer aData)
00971 {
00972     GtkWidget *psDlg, *psTable;
00973     GtkWidget *okButton, *cancelButton;
00974     GtkWidget *psLabel[NUM_PS_ENTRIES];
00975     int i;
00976     char resName[16], *text = nsnull;
00977 
00978     psDlg = gtk_dialog_new();
00979     gtk_window_set_modal(GTK_WINDOW(psDlg), TRUE);
00980     gtk_window_set_title(GTK_WINDOW(psDlg), gCtx->opt->mTitle);
00981     gtk_window_set_position(GTK_WINDOW(psDlg), GTK_WIN_POS_CENTER);
00982 
00983     psTable = gtk_table_new(5, 2, FALSE);
00984     gtk_container_add(GTK_CONTAINER(GTK_DIALOG(psDlg)->vbox), psTable);
00985     gtk_widget_show(psTable);
00986 
00987     // create labels
00988     for (i = 0; i < NUM_PS_ENTRIES; ++i) 
00989     {
00990         sprintf(resName, "PS_LABEL%d", i);
00991         psLabel[i] = gtk_label_new(gCtx->Res(resName));
00992         gtk_widget_show(psLabel[i]);
00993 
00994         gtk_misc_set_alignment(GTK_MISC(psLabel[i]), 1, 0.5);
00995 
00996         gtk_table_attach(GTK_TABLE(psTable), psLabel[i], 0, 1, i, i + 1,
00997             static_cast<GtkAttachOptions>(GTK_FILL | GTK_EXPAND),
00998             static_cast<GtkAttachOptions>(GTK_FILL | GTK_EXPAND), 5, 5);
00999     }
01000     
01001     // create text entry fields
01002     for (i = 0; i < NUM_PS_ENTRIES; ++i)
01003     {
01004         sPSTextEntry[i] = gtk_entry_new();
01005         gtk_entry_set_editable(GTK_ENTRY(sPSTextEntry[i]), TRUE);
01006 
01007         // reset text if we already opened this dlg before
01008         if (i == 0) text = gCtx->opt->mProxyHost;
01009         if (i == 1) text = gCtx->opt->mProxyPort;
01010         if (i == 2) text = gCtx->opt->mProxyUser;
01011         if (i == 3) text = gCtx->opt->mProxyPswd;
01012 
01013         if (text)
01014             gtk_entry_set_text(GTK_ENTRY(sPSTextEntry[i]), text);
01015 
01016         // password field
01017         if (i + 1 == NUM_PS_ENTRIES)
01018             gtk_entry_set_visibility(GTK_ENTRY(sPSTextEntry[i]), FALSE); 
01019 
01020         gtk_widget_show(sPSTextEntry[i]);
01021 
01022         gtk_table_attach(GTK_TABLE(psTable), sPSTextEntry[i], 
01023             1, 2, i, i + 1,
01024             static_cast<GtkAttachOptions>(GTK_FILL | GTK_EXPAND),
01025             static_cast<GtkAttachOptions>(GTK_FILL | GTK_EXPAND), 5, 5);
01026     }
01027 
01028     // pre-populate text entry fields if data already stored
01029     okButton = gtk_button_new_with_label(gCtx->Res("OK_LABEL"));
01030     gtk_container_add(GTK_CONTAINER(GTK_DIALOG(psDlg)->action_area),
01031         okButton);
01032     gtk_signal_connect(GTK_OBJECT(okButton), "clicked",
01033                    GTK_SIGNAL_FUNC(PSDlgOK), psDlg);
01034     GTK_WIDGET_SET_FLAGS(okButton, GTK_CAN_DEFAULT);
01035     gtk_widget_grab_default(okButton);
01036     gtk_widget_show(okButton);
01037 
01038     cancelButton = gtk_button_new_with_label(gCtx->Res("CANCEL_LABEL"));
01039     gtk_container_add(GTK_CONTAINER(GTK_DIALOG(psDlg)->action_area),
01040         cancelButton);
01041     gtk_signal_connect(GTK_OBJECT(cancelButton), "clicked",
01042                    GTK_SIGNAL_FUNC(PSDlgCancel), psDlg);
01043     gtk_widget_show(cancelButton);
01044 
01045     gtk_widget_show(psDlg);
01046 }
01047 
01048 void
01049 nsInstallDlg::PSDlgOK(GtkWidget *aWidget, gpointer aData)
01050 {
01051     GtkWidget *dlg = (GtkWidget *) aData;
01052     char *text;
01053     char *proxyHost=NULL, *proxyPort=NULL, *proxyUser=NULL, *proxyPswd=NULL;
01054 
01055     // grab proxy host field
01056     text = gtk_editable_get_chars(GTK_EDITABLE(sPSTextEntry[0]), 0, -1);
01057     if (text && *text)
01058         proxyHost = text;
01059     else
01060         XI_IF_FREE(text);
01061 
01062     // grab proxy port field
01063     text = gtk_editable_get_chars(GTK_EDITABLE(sPSTextEntry[1]), 0, -1);
01064     if (text && *text)
01065         proxyPort = text;
01066     else
01067         XI_IF_FREE(text);
01068 
01069     // grab proxy user field
01070     text = gtk_editable_get_chars(GTK_EDITABLE(sPSTextEntry[2]), 0, -1);
01071     if (text && *text)
01072         proxyUser = text;
01073     else
01074         XI_IF_FREE(text);
01075 
01076     // grab proxy pswd field
01077     text = gtk_editable_get_chars(GTK_EDITABLE(sPSTextEntry[3]), 0, -1);
01078     if (text && *text)
01079         proxyPswd = text;
01080     else
01081         XI_IF_FREE(text);
01082 
01083     if ( (proxyHost || proxyPort || proxyUser || proxyPswd)
01084           && (!proxyHost || !proxyPort) )
01085     {
01086         XI_IF_FREE(proxyHost);
01087         XI_IF_FREE(proxyPort);
01088         XI_IF_FREE(proxyUser);
01089         XI_IF_FREE(proxyPswd);
01090         ErrorHandler(E_INVALID_PROXY);
01091     }
01092     else
01093     {
01094         XI_IF_FREE(gCtx->opt->mProxyHost);
01095         XI_IF_FREE(gCtx->opt->mProxyPort);
01096         XI_IF_FREE(gCtx->opt->mProxyUser);
01097         XI_IF_FREE(gCtx->opt->mProxyPswd);
01098 
01099         gCtx->opt->mProxyHost = proxyHost;
01100         gCtx->opt->mProxyPort = proxyPort;
01101         gCtx->opt->mProxyUser = proxyUser;
01102         gCtx->opt->mProxyPswd = proxyPswd;
01103         gtk_widget_destroy(dlg);
01104     }
01105 }
01106 
01107 void
01108 nsInstallDlg::PSDlgCancel(GtkWidget *aWidget, gpointer aData)
01109 {
01110     GtkWidget *dlg = (GtkWidget *) aData;
01111 
01112     if (dlg)
01113         gtk_widget_destroy(dlg);
01114 }
01115 
01116 void
01117 nsInstallDlg::DLPause(GtkWidget *aWidget, gpointer aData)
01118 {
01119     DUMP("DLPause");
01120 
01121     // set pause for download callback to return to libxpnet
01122     bDLPause = TRUE;
01123 
01124     // disbale pause button
01125     gtk_widget_set_sensitive(gCtx->back, FALSE);
01126 
01127     // enable resume button
01128     gtk_widget_set_sensitive(gCtx->next, TRUE);
01129 }
01130 
01131 void
01132 nsInstallDlg::DLResume(GtkWidget *aWidget, gpointer aData)
01133 {
01134     DUMP("DLResume");
01135 
01136     if (!bDLPause)
01137     {
01138         DUMP("Not paused");
01139         return;
01140     }
01141 
01142     DUMP("Unsetting bDLPause");
01143     bDLPause = FALSE;
01144 
01145     // disable resume button
01146     gtk_widget_set_sensitive(gCtx->next, FALSE);
01147 
01148     // enable pause button
01149     gtk_widget_set_sensitive(gCtx->back, TRUE);
01150 
01151     gtk_main_quit();
01152 }
01153 
01154 void
01155 nsInstallDlg::DLCancel(GtkWidget *aWidget, gpointer aData)
01156 {
01157     DUMP("DLCancel");
01158 
01159     // show cancellation confirm dialog
01160     // XXX    TO DO
01161 
01162     // set cancel for download callback to return to libxpnet
01163     bDLCancel = TRUE;
01164 
01165 #ifdef DEBUG
01166     printf("%s %d: bDLPause: %d\tbDLCancel: %d\n", __FILE__, __LINE__, 
01167                    bDLPause, bDLCancel);
01168 #endif
01169 
01170     // already paused then take explicit action to quit
01171     if (bDLPause)
01172     {
01173         bDLPause = FALSE;
01174         gtk_main_quit();
01175     }
01176 }
01177 
01178 int
01179 nsInstallDlg::CancelOrPause()
01180 {
01181     int err = OK;
01182 
01183     if (bDLPause)
01184     {
01185         err = E_DL_PAUSE;
01186     }
01187     else if (bDLCancel)
01188     {
01189         err = E_DL_CANCEL;
01190     }
01191     
01192     return err;
01193 }
01194 
01195 static GtkWidget *crcDlg = (GtkWidget *) NULL;
01196 
01197 void
01198 nsInstallDlg::ShowCRCDlg()
01199 {
01200     GtkWidget *label, *okButton;
01201 
01202     if (gCtx->opt->mMode == nsXIOptions::MODE_SILENT) {
01203        ErrorHandler(E_CRC_FAILED);
01204        return;
01205     }
01206 
01207     if ( crcDlg == (GtkWidget *) NULL ) {
01208        // throw up dialog informing user to press resume
01209        // or to cancel out
01210        crcDlg = gtk_dialog_new();
01211        gtk_window_set_modal(GTK_WINDOW(crcDlg), TRUE);
01212        label = gtk_label_new(gCtx->Res("CRC_CHECK"));
01213        okButton = gtk_button_new_with_label(gCtx->Res("OK_LABEL"));
01214        if (crcDlg && label && okButton )
01215        {
01216            gtk_misc_set_padding(GTK_MISC(label), 20, 20);
01217            gtk_misc_set_alignment(GTK_MISC(label), 0.5, 1);
01218            gtk_window_set_title(GTK_WINDOW(crcDlg), gCtx->opt->mTitle);
01219            gtk_window_set_position(GTK_WINDOW(crcDlg), GTK_WIN_POS_CENTER);
01220            gtk_container_add(GTK_CONTAINER(GTK_DIALOG(crcDlg)->vbox), 
01221                              label);
01222            gtk_container_add(GTK_CONTAINER(GTK_DIALOG(crcDlg)->action_area),
01223                              okButton);
01224            gtk_signal_connect(GTK_OBJECT(okButton), "clicked",
01225                               GTK_SIGNAL_FUNC(CRCOKCb), crcDlg);
01226            GTK_WIDGET_SET_FLAGS(okButton, GTK_CAN_DEFAULT);
01227            gtk_widget_grab_default(okButton);
01228            gtk_widget_show_all(crcDlg);
01229        }
01230     }
01231     XI_GTK_UPDATE_UI();
01232 }
01233 
01234 int
01235 nsInstallDlg::ShowCxnDroppedDlg()
01236 {
01237     GtkWidget *cxnDroppedDlg, *label, *okButton;
01238 
01239     // throw up dialog informing user to press resume
01240     // or to cancel out
01241     if (gCtx->opt->mMode == nsXIOptions::MODE_SILENT) {
01242        ErrorHandler(E_NO_DOWNLOAD);
01243        return OK;
01244     }
01245     
01246     cxnDroppedDlg = gtk_dialog_new();
01247     gtk_window_set_modal(GTK_WINDOW(cxnDroppedDlg), TRUE);
01248     label = gtk_label_new(gCtx->Res("CXN_DROPPED"));
01249     okButton = gtk_button_new_with_label(gCtx->Res("OK_LABEL"));
01250 
01251     if (cxnDroppedDlg && label && okButton )
01252     {
01253         gtk_misc_set_padding(GTK_MISC(label), 20, 20);
01254         gtk_misc_set_alignment(GTK_MISC(label), 0.5, 1);
01255         gtk_window_set_modal(GTK_WINDOW(cxnDroppedDlg), TRUE);
01256         gtk_window_set_title(GTK_WINDOW(cxnDroppedDlg), gCtx->opt->mTitle);
01257         gtk_window_set_position(GTK_WINDOW(cxnDroppedDlg), GTK_WIN_POS_CENTER);
01258         gtk_container_add(GTK_CONTAINER(GTK_DIALOG(cxnDroppedDlg)->vbox), 
01259                           label);
01260         gtk_container_add(GTK_CONTAINER(GTK_DIALOG(cxnDroppedDlg)->action_area),
01261                           okButton);
01262         gtk_signal_connect(GTK_OBJECT(okButton), "clicked",
01263                            GTK_SIGNAL_FUNC(CxnDroppedOK), cxnDroppedDlg);
01264         GTK_WIDGET_SET_FLAGS(okButton, GTK_CAN_DEFAULT);
01265         gtk_widget_grab_default(okButton);
01266         gtk_widget_show_all(cxnDroppedDlg);
01267     }
01268     XI_GTK_UPDATE_UI();
01269 
01270     return OK;
01271 }
01272 
01273 void
01274 nsInstallDlg::DestroyCRCDlg()
01275 {
01276   CRCOKCb( (GtkWidget *) NULL, (gpointer) NULL );
01277 }
01278 
01279 void
01280 nsInstallDlg::CRCOKCb(GtkWidget *aWidget, gpointer aData)
01281 {
01282     if (crcDlg != (GtkWidget *) NULL)
01283         gtk_widget_destroy(crcDlg);
01284     crcDlg = (GtkWidget *) NULL;
01285 
01286     return;
01287 }
01288 
01289 void
01290 nsInstallDlg::CxnDroppedOK(GtkWidget *aWidget, gpointer aData)
01291 {
01292     GtkWidget *cxnDroppedDlg = (GtkWidget *) aData;
01293     
01294     if (cxnDroppedDlg)
01295         gtk_widget_destroy(cxnDroppedDlg);
01296 
01297     return;
01298 }
01299 
01300 void
01301 nsInstallDlg::HideNavButtons()
01302 {
01303     gtk_signal_disconnect(GTK_OBJECT(gCtx->back), gCtx->backID);
01304     gtk_signal_disconnect(GTK_OBJECT(gCtx->next), gCtx->nextID);
01305     gtk_signal_disconnect(GTK_OBJECT(gCtx->cancel), gCtx->cancelID);
01306 
01307     gtk_widget_hide(gCtx->back);
01308     gtk_widget_hide(gCtx->next);
01309     gtk_widget_hide(gCtx->cancel);
01310 }
01311 
01312 void
01313 nsInstallDlg::InitDLProgress( int isFirst )
01314 {
01315     GtkWidget *titles[4];
01316     GtkWidget *hbox;
01317     GtkWidget *table;
01318 
01319     gCtx->idlg->HideTable();
01320 
01321     if ( isFirst == TRUE ) {
01322             sDLProgress.vbox = gtk_vbox_new(FALSE, 10);
01323             gtk_notebook_append_page(GTK_NOTEBOOK(gCtx->notebook), 
01324                 sDLProgress.vbox, NULL);
01325             gtk_widget_show(sDLProgress.vbox);
01326                     
01327             table = gtk_table_new(5, 2, FALSE);
01328             gtk_box_pack_start(GTK_BOX(sDLProgress.vbox), table, FALSE, 
01329                 FALSE, 0);
01330             gtk_widget_show(table);
01331 
01332             // setup static title progress labels in table left column
01333             titles[0] = gtk_label_new(gCtx->Res("DOWNLOADING"));
01334             titles[1] = gtk_label_new(gCtx->Res("FROM"));
01335             titles[2] = gtk_label_new(gCtx->Res("TO"));
01336             titles[3] = gtk_label_new(gCtx->Res("STATUS"));
01337 
01338             // setup dynamic progress labels in right column
01339             sDLProgress.compName = gtk_label_new(gCtx->Res("UNKNOWN"));
01340             sDLProgress.URL = gtk_label_new(gCtx->Res("UNKNOWN"));
01341             sDLProgress.localPath = gtk_label_new(gCtx->Res("UNKNOWN"));
01342             sDLProgress.status = gtk_label_new(gCtx->Res("UNKNOWN"));
01343 
01344             // pack and show titles
01345             for (int i = 0; i < 4; ++i)
01346             {
01347                 hbox = gtk_hbox_new(FALSE, 10);
01348                 gtk_box_pack_end(GTK_BOX(hbox), titles[i], FALSE, FALSE, 0);
01349                 gtk_table_attach(GTK_TABLE(table), hbox, 
01350                     0, 1, i, i + 1, GTK_FILL, GTK_FILL, 5, 5);
01351                 gtk_widget_show(titles[i]);
01352                 gtk_widget_show(hbox);
01353             }
01354 
01355             // pack and show dynamic labels 
01356             hbox = gtk_hbox_new(FALSE, 10);
01357             gtk_box_pack_start(GTK_BOX(hbox), sDLProgress.compName, FALSE, FALSE, 0);
01358             gtk_table_attach(GTK_TABLE(table), hbox, 1, 2, 0, 1,
01359                 GTK_FILL, GTK_FILL, 5, 5);
01360             gtk_widget_show(sDLProgress.compName);
01361             gtk_widget_show(hbox);
01362 
01363             hbox = gtk_hbox_new(FALSE, 10);
01364             gtk_box_pack_start(GTK_BOX(hbox), sDLProgress.URL, FALSE, FALSE, 0);
01365             gtk_table_attach(GTK_TABLE(table), hbox, 1, 2, 1, 2,
01366                 GTK_FILL, GTK_FILL, 5, 5);
01367             gtk_widget_show(sDLProgress.URL);
01368             gtk_widget_show(hbox);
01369 
01370             hbox = gtk_hbox_new(FALSE, 10);
01371             gtk_box_pack_start(GTK_BOX(hbox), sDLProgress.localPath, FALSE, 
01372                 FALSE, 0);
01373             gtk_table_attach(GTK_TABLE(table), hbox, 1, 2, 2, 3,
01374                 GTK_FILL, GTK_FILL, 5, 5);
01375             gtk_widget_show(sDLProgress.localPath);
01376             gtk_widget_show(hbox);
01377 
01378             hbox = gtk_hbox_new(FALSE, 10);
01379             gtk_box_pack_start(GTK_BOX(hbox), sDLProgress.status, FALSE, 
01380                 FALSE, 0);
01381             gtk_table_attach(GTK_TABLE(table), hbox, 1, 2, 3, 4,
01382                 GTK_FILL, GTK_FILL, 5, 5);
01383             gtk_widget_show(sDLProgress.status);
01384             gtk_widget_show(hbox);
01385 
01386             // init and show prog bar
01387             sDLProgress.progBar = gtk_progress_bar_new();
01388 
01389             // show prog bar
01390             hbox = gtk_hbox_new(TRUE, 10);
01391             gtk_box_pack_start(GTK_BOX(hbox), sDLProgress.progBar, FALSE, 
01392               TRUE, 0);
01393             gtk_box_pack_start(GTK_BOX(sDLProgress.vbox), hbox, FALSE, 
01394               FALSE, 0);
01395             gtk_widget_show(sDLProgress.progBar);
01396             gtk_widget_show(hbox);
01397     }
01398 
01399     // set to non-activity mode and initialize 
01400     gtk_progress_set_activity_mode(GTK_PROGRESS(sDLProgress.progBar), FALSE);
01401     gtk_progress_bar_update(GTK_PROGRESS_BAR(sDLProgress.progBar), (gfloat) 0);
01402 
01403     // compute total download size
01404     sDLProgress.downloadedBytes = 0;
01405     sDLProgress.totalKB = TotalDLSize();
01406 
01407     XI_GTK_UPDATE_UI();
01408 }
01409 
01410 void
01411 nsInstallDlg::InitInstallProgress()
01412 {
01413     if ( sDLProgress.vbox )
01414             gtk_widget_hide(sDLProgress.vbox);
01415     gCtx->idlg->ShowTable();
01416 }
01417 
01418 int
01419 nsInstallDlg::TotalDLSize()
01420 {
01421     int total = 0; // in KB
01422     int bCustom;
01423     nsComponentList *comps;
01424     nsComponent *currComp;
01425     int archiveSize, currentSize;
01426 
01427     bCustom = (gCtx->opt->mSetupType == (gCtx->sdlg->GetNumSetupTypes() - 1));
01428     comps = gCtx->sdlg->GetSelectedSetupType()->GetComponents();
01429     currComp = comps->GetHead();
01430     
01431     // loop through all components
01432     while (currComp)
01433     {
01434         if ((bCustom && currComp->IsSelected()) || (!bCustom))
01435         {
01436             // if still have to download 
01437             if (!currComp->IsDownloaded())
01438             {
01439                 // find archive size - amount downloaded already
01440                 archiveSize = currComp->GetArchiveSize();
01441                 currentSize = currComp->GetCurrentSize();
01442 
01443 #ifdef DEBUG
01444                 printf("%s ar sz = %d cu sz = %d\n", currComp->GetArchive(), 
01445                         archiveSize, currentSize);
01446 #endif
01447 
01448                 total += (archiveSize - currentSize);
01449             }
01450         }
01451         currComp = comps->GetNext();
01452     }
01453 
01454     return total;
01455 }
01456 
01457 void
01458 nsInstallDlg::CompressToFit(char *aOrigStr, char *aOutStr, int aOutStrLen)
01459 {
01460     int origStrLen;
01461     int halfOutStrLen;
01462     char *lastPart; // last aOrigStr part start
01463 
01464     if (!aOrigStr || !aOutStr || aOutStrLen <= 0)
01465         return;
01466 
01467     origStrLen = strlen(aOrigStr);
01468     halfOutStrLen = (aOutStrLen/2) - 2; // minus 2 since ellipsis is 3 chars
01469     lastPart = aOrigStr + origStrLen - halfOutStrLen;
01470 
01471     strncpy(aOutStr, aOrigStr, halfOutStrLen);
01472     *(aOutStr + halfOutStrLen) = 0;
01473     strcat(aOutStr, "...");
01474     strncat(aOutStr, lastPart, strlen(lastPart));
01475     *(aOutStr + aOutStrLen + 1) = 0;
01476 }
01477 
01478 void
01479 nsInstallDlg::ReInitUI( void )
01480 {
01481   InitDLProgress( FALSE );
01482 }