1
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
3
* The contents of this file are subject to the Netscape Public
4
* License Version 1.1 (the "License"); you may not use this file
5
* except in compliance with the License. You may obtain a copy of
6
* the License at http://www.mozilla.org/NPL/
8
* Software distributed under the License is distributed on an "AS
9
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
10
* implied. See the License for the specific language governing
11
* rights and limitations under the License.
13
* The Original Code is Mozilla Communicator client code,
14
* released March 31, 1998.
16
* The Initial Developer of the Original Code is Netscape Communications
17
* Corporation. Portions created by Netscape are
18
* Copyright (C) 1998 Netscape Communications Corporation. All
22
* Samir Gehani <sgehani@netscape.com>
26
#include "nsSetupTypeDlg.h"
27
#include "nsXInstaller.h"
29
#include <sys/types.h>
32
// need these for statfs
34
#ifdef HAVE_SYS_STATVFS_H
35
#include <sys/statvfs.h>
38
#ifdef HAVE_SYS_STATFS_H
39
#include <sys/statfs.h>
43
#define STATFS statvfs
49
static GtkWidget *sBrowseBtn;
50
static gint sBrowseBtnID;
51
static GtkWidget *sFolder;
52
static GSList *sGroup;
53
static GtkWidget *sCreateDestDlg;
54
static GtkWidget *sDelInstDlg;
55
static int sFilePickerUp = FALSE;
56
static int sConfirmCreateUp = FALSE;
57
static int sDelInstUp = FALSE;
58
static nsLegacyCheck *sLegacyChecks = NULL;
59
static nsObjectIgnore *sObjectsToIgnore = NULL;
61
nsSetupTypeDlg::nsSetupTypeDlg() :
67
nsSetupTypeDlg::~nsSetupTypeDlg()
76
nsSetupTypeDlg::Back(GtkWidget *aWidget, gpointer aData)
79
if (aData != gCtx->sdlg) return;
82
gCtx->bMoving = FALSE;
86
// hide this notebook page
87
gCtx->sdlg->Hide(nsXInstallerDlg::BACKWARD_MOVE);
89
// disconnect this dlg's nav btn signal handlers
90
gtk_signal_disconnect(GTK_OBJECT(gCtx->back), gCtx->backID);
91
gtk_signal_disconnect(GTK_OBJECT(gCtx->next), gCtx->nextID);
92
gtk_signal_disconnect(GTK_OBJECT(sBrowseBtn), sBrowseBtnID);
95
gCtx->ldlg->Show(nsXInstallerDlg::BACKWARD_MOVE);
100
nsSetupTypeDlg::Next(GtkWidget *aWidget, gpointer aData)
103
if (aData != gCtx->sdlg) return;
106
gCtx->bMoving = FALSE;
110
// creation confirmation dlg still up
111
if (sConfirmCreateUp || sDelInstUp)
114
// verify selected destination directory exists
115
if (OK != nsSetupTypeDlg::VerifyDestination())
118
// old installation may exist: delete it
119
if (OK != nsSetupTypeDlg::DeleteOldInst())
122
// make sure destination directory is empty
123
if (OK != nsSetupTypeDlg::CheckDestEmpty())
126
// if not custom setup type verify disk space
127
if (gCtx->opt->mSetupType != (gCtx->sdlg->GetNumSetupTypes() - 1))
129
if (OK != nsSetupTypeDlg::VerifyDiskSpace())
133
// hide this notebook page
134
gCtx->sdlg->Hide(nsXInstallerDlg::FORWARD_MOVE);
136
// disconnect this dlg's nav btn signal handlers
137
gtk_signal_disconnect(GTK_OBJECT(gCtx->back), gCtx->backID);
138
gtk_signal_disconnect(GTK_OBJECT(gCtx->next), gCtx->nextID);
139
gtk_signal_disconnect(GTK_OBJECT(sBrowseBtn), sBrowseBtnID);
142
if (gCtx->opt->mSetupType == (gCtx->sdlg->GetNumSetupTypes() - 1))
143
gCtx->cdlg->Show(nsXInstallerDlg::FORWARD_MOVE);
145
gCtx->idlg->Show(nsXInstallerDlg::FORWARD_MOVE);
146
gCtx->bMoving = TRUE;
150
nsSetupTypeDlg::Parse(nsINIParser *aParser)
154
char *showDlg = NULL;
156
char *currSec = (char *) malloc(strlen(SETUP_TYPEd) + 1); // e.g. SetupType12
157
if (!currSec) return E_MEM;
158
char *currKey = (char *) malloc(1 + 3); // e.g. C0, C1, C12
159
if (!currKey) return E_MEM;
160
char *currOIKey = (char *) malloc(strlen(OBJECT_IGNOREd) + 1);
161
if (!currOIKey) return E_MEM;
162
char *currLCSec = (char *) malloc(strlen(LEGACY_CHECKd) + 1);
163
if (!currLCSec) return E_MEM;
164
char *currVal = NULL;
165
nsLegacyCheck *currLC = NULL, *lastLC = NULL, *nextLC = NULL;
166
nsObjectIgnore *currOI = NULL, *lastOI = NULL, *nextOI = NULL;
167
nsComponent *currComp = NULL;
168
nsComponent *currCompDup = NULL;
170
int currNumComps = 0;
172
nsComponentList *compList = gCtx->cdlg->GetCompList();
173
DUMP("Pre-verification of comp list")
175
DUMP("Post-verification of comp list")
177
nsSetupType *currST = NULL;
178
char *currDescShort = NULL;
179
char *currDescLong = NULL;
184
err = aParser->GetStringAlloc(DLG_SETUP_TYPE, MSG0, &mMsg0, &bufsize);
185
if (err != OK && err != nsINIParser::E_NO_KEY) goto BAIL; else err = OK;
188
err = aParser->GetStringAlloc(DLG_SETUP_TYPE, SHOW_DLG, &showDlg, &bufsize);
189
if (err != OK && err != nsINIParser::E_NO_KEY) goto BAIL; else err = OK;
190
if (bufsize != 0 && showDlg)
192
if (0 == strncmp(showDlg, "TRUE", 4))
193
mShowDlg = nsXInstallerDlg::SHOW_DIALOG;
194
else if (0 == strncmp(showDlg, "FALSE", 5))
195
mShowDlg = nsXInstallerDlg::SKIP_DIALOG;
199
err = aParser->GetStringAlloc(DLG_SETUP_TYPE, TITLE, &mTitle, &bufsize);
200
if (err != OK && err != nsINIParser::E_NO_KEY) goto BAIL; else err = OK;
204
/* Objects to Ignore */
205
sObjectsToIgnore = new nsObjectIgnore();
206
currOI = sObjectsToIgnore;
207
for (i = 0; i < MAX_LEGACY_CHECKS; i++)
209
// construct key name based on index
210
memset(currOIKey, 0, (strlen(OBJECT_IGNOREd) + 1));
211
sprintf(currOIKey, OBJECT_IGNOREd, i);
213
// get ObjectToIgnore key
215
err = aParser->GetStringAlloc(CLEAN_UPGRADE, currOIKey, &currVal, &bufsize);
218
if (err != nsINIParser::E_NO_SEC &&
219
err != nsINIParser::E_NO_KEY) goto BAIL;
223
XI_IF_DELETE(currOI);
229
currOI->SetFilename(currVal);
231
nextOI = new nsObjectIgnore();
232
currOI->SetNext(nextOI);
236
if (i == 0) // none found
237
sObjectsToIgnore = NULL;
240
sLegacyChecks = new nsLegacyCheck();
241
currLC = sLegacyChecks;
242
for (i = 0; i < MAX_LEGACY_CHECKS; i++)
244
// construct section name based on index
245
memset(currLCSec, 0, (strlen(LEGACY_CHECKd) + 1));
246
sprintf(currLCSec, LEGACY_CHECKd, i);
248
// get "Filename" and "Message" keys
250
err = aParser->GetStringAlloc(currLCSec, FILENAME, &currVal, &bufsize);
253
if (err != nsINIParser::E_NO_SEC &&
254
err != nsINIParser::E_NO_KEY) goto BAIL;
258
XI_IF_DELETE(currLC);
264
currLC->SetFilename(currVal);
267
err = aParser->GetStringAlloc(currLCSec, MSG, &currVal, &bufsize);
270
if (err != nsINIParser::E_NO_SEC &&
271
err != nsINIParser::E_NO_KEY) goto BAIL;
275
XI_IF_DELETE(currLC);
281
currLC->SetMessage(currVal);
283
nextLC = new nsLegacyCheck();
284
currLC->SetNext(nextLC);
288
if (i == 0) // none found
289
sLegacyChecks = NULL;
292
for (i=0; i<MAX_SETUP_TYPES; i++)
294
sprintf(currSec, SETUP_TYPEd, i);
297
err = aParser->GetStringAlloc(currSec, DESC_SHORT, &currDescShort,
299
if (err != OK && err != nsINIParser::E_NO_SEC) goto fin_iter;
300
if (bufsize == 0 || err == nsINIParser::E_NO_SEC) // no more setup types
307
err = aParser->GetStringAlloc(currSec, DESC_LONG, &currDescLong,
309
if (err != OK || bufsize == 0) goto fin_iter;
311
currST = new nsSetupType();
312
if (!currST) goto fin_iter;
314
currST->SetDescShort(currDescShort);
315
currST->SetDescLong(currDescLong);
318
for (j=0; j<MAX_COMPONENTS; j++)
320
sprintf(currKey, Cd, j);
323
err = aParser->GetStringAlloc(currSec, currKey, &currVal,
325
if (err != OK && err != nsINIParser::E_NO_KEY) continue;
326
if (bufsize == 0 || err == nsINIParser::E_NO_KEY)
333
currIndex = atoi(currVal + strlen(COMPONENT));
334
currComp = compList->GetCompByIndex(currIndex);
338
currCompDup = currComp->Duplicate();
339
currST->SetComponent(currCompDup);
343
if (currNumComps > 0)
345
AddSetupType(currST);
350
XI_IF_DELETE(currST);
358
XI_IF_FREE(currOIKey);
359
XI_IF_FREE(currLCSec);
365
nsSetupTypeDlg::Show(int aDirection)
368
int numSetupTypes = 0;
370
GtkWidget *stTable = NULL;
371
GtkWidget *radbtns[MAX_SETUP_TYPES];
372
GtkWidget *desc[MAX_SETUP_TYPES];
373
nsSetupType *currST = NULL;
374
GtkWidget *destTable = NULL;
375
GtkWidget *frame = NULL;
376
GtkWidget *hbox = NULL;
379
XI_VERIFY(gCtx->notebook);
381
if (mWidgetsInit == FALSE)
383
// create a new table and add it as a page of the notebook
384
mTable = gtk_table_new(4, 1, FALSE);
385
gtk_notebook_append_page(GTK_NOTEBOOK(gCtx->notebook), mTable, NULL);
386
mPageNum = gtk_notebook_get_current_page(GTK_NOTEBOOK(gCtx->notebook));
387
gtk_widget_show(mTable);
389
// insert a static text widget in the first row
390
GtkWidget *msg0 = gtk_label_new(mMsg0);
391
hbox = gtk_hbox_new(FALSE, 0);
392
gtk_box_pack_start(GTK_BOX(hbox), msg0, FALSE, FALSE, 0);
393
gtk_widget_show(hbox);
394
gtk_table_attach(GTK_TABLE(mTable), hbox, 0, 1, 1, 2,
395
static_cast<GtkAttachOptions>(GTK_FILL | GTK_EXPAND),
397
gtk_widget_show(msg0);
399
// insert a [n x 2] heterogeneous table in the second row
400
// where n = numSetupTypes
401
numSetupTypes = GetNumSetupTypes();
402
stTable = gtk_table_new(numSetupTypes, 4, FALSE);
403
gtk_widget_show(stTable);
404
gtk_table_attach(GTK_TABLE(mTable), stTable, 0, 1, 2, 3,
405
static_cast<GtkAttachOptions>(GTK_EXPAND | GTK_FILL),
406
static_cast<GtkAttachOptions>(GTK_EXPAND | GTK_FILL),
409
currST = GetSetupTypeList();
410
if (!currST) return E_NO_SETUPTYPES;
412
// first radio button
413
gCtx->opt->mSetupType = 0;
414
radbtns[0] = gtk_radio_button_new_with_label(NULL,
415
currST->GetDescShort());
416
sGroup = gtk_radio_button_group(GTK_RADIO_BUTTON(radbtns[0]));
417
gtk_table_attach(GTK_TABLE(stTable), radbtns[0], 0, 1, 0, 1,
418
static_cast<GtkAttachOptions>(GTK_FILL | GTK_EXPAND),
419
static_cast<GtkAttachOptions>(GTK_FILL | GTK_EXPAND),
421
gtk_signal_connect(GTK_OBJECT(radbtns[0]), "toggled",
422
GTK_SIGNAL_FUNC(RadBtnToggled), 0);
423
gtk_widget_show(radbtns[0]);
425
desc[0] = gtk_label_new(currST->GetDescLong());
426
gtk_label_set_justify(GTK_LABEL(desc[0]), GTK_JUSTIFY_LEFT);
427
gtk_label_set_line_wrap(GTK_LABEL(desc[0]), TRUE);
428
hbox = gtk_hbox_new(FALSE, 0);
429
gtk_box_pack_start(GTK_BOX(hbox), desc[0], FALSE, FALSE, 0);
430
gtk_widget_show(hbox);
431
gtk_table_attach_defaults(GTK_TABLE(stTable), hbox, 1, 2, 0, 1);
432
gtk_widget_show(desc[0]);
434
// remaining radio buttons
435
for (i = 1; i < numSetupTypes; i++)
437
currST = currST->GetNext();
440
radbtns[i] = gtk_radio_button_new_with_label(sGroup,
441
currST->GetDescShort());
442
sGroup = gtk_radio_button_group(GTK_RADIO_BUTTON(radbtns[i]));
443
gtk_table_attach(GTK_TABLE(stTable), radbtns[i], 0, 1, i, i+1,
444
static_cast<GtkAttachOptions>(GTK_FILL | GTK_EXPAND),
445
static_cast<GtkAttachOptions>(GTK_FILL | GTK_EXPAND), 0, 0);
446
gtk_signal_connect(GTK_OBJECT(radbtns[i]), "toggled",
447
GTK_SIGNAL_FUNC(RadBtnToggled),
448
reinterpret_cast<void *>(i));
449
gtk_widget_show(radbtns[i]);
451
desc[i] = gtk_label_new(currST->GetDescLong());
452
gtk_label_set_justify(GTK_LABEL(desc[i]), GTK_JUSTIFY_LEFT);
453
gtk_label_set_line_wrap(GTK_LABEL(desc[i]), TRUE);
454
hbox = gtk_hbox_new(FALSE, 0);
455
gtk_box_pack_start(GTK_BOX(hbox), desc[i], FALSE, FALSE, 0);
456
gtk_widget_show(hbox);
457
gtk_table_attach_defaults(GTK_TABLE(stTable), hbox, 1, 2, i, i+1);
458
gtk_widget_show(desc[i]);
461
// insert a [1 x 2] heterogeneous table in the third row
462
destTable = gtk_table_new(1, 2, FALSE);
463
gtk_widget_show(destTable);
465
gtk_table_attach(GTK_TABLE(mTable), destTable, 0, 1, 3, 4,
466
static_cast<GtkAttachOptions>(GTK_EXPAND | GTK_FILL),
467
static_cast<GtkAttachOptions>(GTK_EXPAND | GTK_FILL),
469
frame = gtk_frame_new(gCtx->Res("DEST_DIR"));
470
gtk_table_attach_defaults(GTK_TABLE(destTable), frame, 0, 2, 0, 1);
471
gtk_widget_show(frame);
473
if (!gCtx->opt->mDestination)
475
gCtx->opt->mDestination = (char*)malloc(MAXPATHLEN * sizeof(char));
476
getcwd(gCtx->opt->mDestination, MAXPATHLEN);
478
sFolder = gtk_label_new(gCtx->opt->mDestination);
479
gtk_label_set_line_wrap(GTK_LABEL(sFolder), TRUE);
480
gtk_widget_show(sFolder);
481
gtk_table_attach_defaults(GTK_TABLE(destTable), sFolder, 0, 1, 0, 1);
483
sBrowseBtn = gtk_button_new_with_label(gCtx->Res("BROWSE"));
484
gtk_widget_show(sBrowseBtn);
485
gtk_table_attach(GTK_TABLE(destTable), sBrowseBtn, 1, 2, 0, 1,
486
static_cast<GtkAttachOptions>(GTK_EXPAND | GTK_FILL),
493
gtk_notebook_set_page(GTK_NOTEBOOK(gCtx->notebook), mPageNum);
494
gtk_widget_show(mTable);
497
// signal connect the buttons
498
// NOTE: back button disfunctional in this dlg since user accepted license
499
gCtx->backID = gtk_signal_connect(GTK_OBJECT(gCtx->back), "clicked",
500
GTK_SIGNAL_FUNC(nsSetupTypeDlg::Back), gCtx->sdlg);
501
gCtx->nextID = gtk_signal_connect(GTK_OBJECT(gCtx->next), "clicked",
502
GTK_SIGNAL_FUNC(nsSetupTypeDlg::Next), gCtx->sdlg);
503
sBrowseBtnID = gtk_signal_connect(GTK_OBJECT(sBrowseBtn), "clicked",
504
GTK_SIGNAL_FUNC(nsSetupTypeDlg::SelectFolder), NULL);
506
if (aDirection == nsXInstallerDlg::FORWARD_MOVE)
508
// change the button titles back to Back/Next
509
gtk_container_remove(GTK_CONTAINER(gCtx->next), gCtx->acceptLabel);
510
gtk_container_remove(GTK_CONTAINER(gCtx->back), gCtx->declineLabel);
511
gCtx->nextLabel = gtk_label_new(gCtx->Res("NEXT"));
512
gCtx->backLabel = gtk_label_new(gCtx->Res("BACK"));
513
gtk_widget_show(gCtx->nextLabel);
514
gtk_widget_show(gCtx->backLabel);
515
gtk_container_add(GTK_CONTAINER(gCtx->next), gCtx->nextLabel);
516
gtk_container_add(GTK_CONTAINER(gCtx->back), gCtx->backLabel);
517
gtk_widget_show(gCtx->next);
518
gtk_widget_show(gCtx->back);
521
if (aDirection == nsXInstallerDlg::BACKWARD_MOVE &&
522
// not custom setup type
523
gCtx->opt->mSetupType != (gCtx->sdlg->GetNumSetupTypes() - 1))
525
DUMP("Back from Install to Setup Type");
526
gtk_container_remove(GTK_CONTAINER(gCtx->next), gCtx->installLabel);
527
gCtx->nextLabel = gtk_label_new(gCtx->Res("NEXT"));
528
gtk_container_add(GTK_CONTAINER(gCtx->next), gCtx->nextLabel);
529
gtk_widget_show(gCtx->nextLabel);
530
gtk_widget_show(gCtx->next);
533
gtk_widget_hide(gCtx->back);
539
nsSetupTypeDlg::Hide(int aDirection)
541
gtk_widget_hide(mTable);
547
nsSetupTypeDlg::SetMsg0(char *aMsg)
558
nsSetupTypeDlg::GetMsg0()
567
nsSetupTypeDlg::AddSetupType(nsSetupType *aSetupType)
574
mSetupTypeList = aSetupType;
578
nsSetupType *curr = mSetupTypeList;
583
next = curr->GetNext();
587
return curr->SetNext(aSetupType);
597
nsSetupTypeDlg::GetSetupTypeList()
600
return mSetupTypeList;
606
nsSetupTypeDlg::GetNumSetupTypes()
609
nsSetupType *curr = NULL;
614
curr = mSetupTypeList;
618
curr = curr->GetNext();
625
nsSetupTypeDlg::GetSelectedSetupType()
627
nsSetupType *curr = NULL;
628
int numSetupTypes = GetNumSetupTypes();
629
int setupTypeCount = 0;
631
curr = GetSetupTypeList();
632
while (curr && setupTypeCount < numSetupTypes) // paranoia!
634
if (setupTypeCount == gCtx->opt->mSetupType)
638
curr = curr->GetNext();
645
nsSetupTypeDlg::FreeSetupTypeList()
647
nsSetupType *curr = mSetupTypeList;
653
curr = curr->GetNext();
660
nsSetupTypeDlg::FreeLegacyChecks()
662
nsLegacyCheck *curr = NULL;
663
nsLegacyCheck *last = NULL;
667
curr = sLegacyChecks;
672
curr = last->GetNext();
680
nsSetupTypeDlg::SelectFolder(GtkWidget *aWidget, gpointer aData)
682
DUMP("SelectFolder");
687
GtkWidget *fileSel = NULL;
688
char *selDir = gCtx->opt->mDestination;
690
fileSel = gtk_file_selection_new(gCtx->Res("SELECT_DIR"));
691
gtk_file_selection_set_filename(GTK_FILE_SELECTION(fileSel), selDir);
692
gtk_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(fileSel)->ok_button),
693
"clicked", (GtkSignalFunc) SelectFolderOK, fileSel);
694
gtk_signal_connect_object(GTK_OBJECT(
695
GTK_FILE_SELECTION(fileSel)->cancel_button),
696
"clicked", (GtkSignalFunc) SelectFolderCancel,
697
GTK_OBJECT(fileSel));
698
gtk_widget_show(fileSel);
699
sFilePickerUp = TRUE;
703
nsSetupTypeDlg::SelectFolderOK(GtkWidget *aWidget, GtkFileSelection *aFileSel)
705
DUMP("SelectFolderOK");
707
struct stat destStat;
708
char *selDir = gtk_file_selection_get_filename(
709
GTK_FILE_SELECTION(aFileSel));
711
// put the candidate file name in the global variable, then verify it
713
strcpy(gCtx->opt->mDestination, selDir);
715
if (0 == stat(selDir, &destStat))
716
if (!S_ISDIR(destStat.st_mode) || VerifyDestination() != OK ) /* not a directory, or we don't have access permissions, so don't tear down */
719
// update folder path displayed
720
gtk_label_set_text(GTK_LABEL(sFolder), gCtx->opt->mDestination);
721
gtk_widget_show(sFolder);
723
// tear down file sel dlg
724
gtk_object_destroy(GTK_OBJECT(aFileSel));
725
sFilePickerUp = FALSE;
729
nsSetupTypeDlg::SelectFolderCancel(GtkWidget *aWidget,
730
GtkFileSelection *aFileSel)
732
// tear down file sel dlg
733
gtk_object_destroy(GTK_OBJECT(aWidget));
734
gtk_object_destroy(GTK_OBJECT(aFileSel));
735
sFilePickerUp = FALSE;
739
nsSetupTypeDlg::RadBtnToggled(GtkWidget *aWidget, gpointer aData)
741
DUMP("RadBtnToggled");
743
gCtx->opt->mSetupType = NS_PTR_TO_INT32(aData);
747
nsSetupTypeDlg::VerifyDestination()
752
GtkWidget *yesButton, *noButton, *label;
753
GtkWidget *noPermsDlg, *okButton;
754
char message[MAXPATHLEN];
756
stat_err = stat(gCtx->opt->mDestination, &stbuf);
759
if (access(gCtx->opt->mDestination, R_OK | W_OK | X_OK ) != 0)
761
sprintf(message, gCtx->Res("NO_PERMS"), gCtx->opt->mDestination);
763
noPermsDlg = gtk_dialog_new();
764
label = gtk_label_new(message);
765
okButton = gtk_button_new_with_label(gCtx->Res("OK_LABEL"));
767
if (noPermsDlg && label && okButton)
769
gtk_window_set_title(GTK_WINDOW(noPermsDlg), gCtx->opt->mTitle);
770
gtk_window_set_position(GTK_WINDOW(noPermsDlg),
772
gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
773
gtk_box_pack_start(GTK_BOX(
774
GTK_DIALOG(noPermsDlg)->action_area), okButton, FALSE, FALSE, 10);
775
gtk_signal_connect(GTK_OBJECT(okButton), "clicked",
776
GTK_SIGNAL_FUNC(NoPermsOK), noPermsDlg);
777
gtk_box_pack_start(GTK_BOX(
778
GTK_DIALOG(noPermsDlg)->vbox), label, FALSE, FALSE, 10);
780
gtk_widget_show_all(noPermsDlg);
787
// perms OK, we can proceed
792
// destination doesn't exist so ask user if we should create it
793
sprintf(message, gCtx->Res("DOESNT_EXIST"), gCtx->opt->mDestination);
795
sCreateDestDlg = gtk_dialog_new();
796
label = gtk_label_new(message);
797
yesButton = gtk_button_new_with_label(gCtx->Res("YES_LABEL"));
798
noButton = gtk_button_new_with_label(gCtx->Res("NO_LABEL"));
800
gtk_window_set_title(GTK_WINDOW(sCreateDestDlg), gCtx->opt->mTitle);
801
gtk_window_set_position(GTK_WINDOW(sCreateDestDlg), GTK_WIN_POS_CENTER);
802
gtk_container_add(GTK_CONTAINER(GTK_DIALOG(sCreateDestDlg)->action_area),
804
gtk_container_add(GTK_CONTAINER(GTK_DIALOG(sCreateDestDlg)->action_area),
806
gtk_signal_connect(GTK_OBJECT(yesButton), "clicked",
807
GTK_SIGNAL_FUNC(CreateDestYes), sCreateDestDlg);
808
gtk_signal_connect(GTK_OBJECT(noButton), "clicked",
809
GTK_SIGNAL_FUNC(CreateDestNo), sCreateDestDlg);
811
gtk_container_add(GTK_CONTAINER(GTK_DIALOG(sCreateDestDlg)->vbox), label);
813
gtk_widget_show_all(sCreateDestDlg);
814
sConfirmCreateUp = TRUE;
820
nsSetupTypeDlg::NoPermsOK(GtkWidget *aWidget, gpointer aData)
822
GtkWidget *noPermsDlg = (GtkWidget *) aData;
827
gtk_widget_destroy(noPermsDlg);
831
nsSetupTypeDlg::CreateDestYes(GtkWidget *aWidget, gpointer aData)
833
DUMP("CreateDestYes");
835
char path[PATH_MAX + 1];
836
int pathLen = strlen(gCtx->opt->mDestination);
838
if (pathLen > PATH_MAX)
840
memcpy(path, gCtx->opt->mDestination, pathLen);
841
path[pathLen] = '/'; // for uniform handling
844
mode_t oldPerms = umask(022);
846
for (int i = 1; !err && i <= pathLen; i++)
851
if (stat(path, &buf) != 0)
853
err = mkdir(path, (0777 & ~oldPerms));
859
umask(oldPerms); // restore original umask
861
gtk_widget_destroy(sCreateDestDlg);
862
sConfirmCreateUp = FALSE;
866
ErrorHandler(E_MKDIR_FAIL);
870
// hide this notebook page
871
gCtx->sdlg->Hide(nsXInstallerDlg::FORWARD_MOVE);
873
// disconnect this dlg's nav btn signal handlers
874
gtk_signal_disconnect(GTK_OBJECT(gCtx->back), gCtx->backID);
875
gtk_signal_disconnect(GTK_OBJECT(gCtx->next), gCtx->nextID);
876
gtk_signal_disconnect(GTK_OBJECT(sBrowseBtn), sBrowseBtnID);
878
// show the final dlg
879
if (gCtx->opt->mSetupType == (gCtx->sdlg->GetNumSetupTypes() - 1))
880
gCtx->cdlg->Show(nsXInstallerDlg::FORWARD_MOVE);
882
gCtx->idlg->Show(nsXInstallerDlg::FORWARD_MOVE);
886
nsSetupTypeDlg::CreateDestNo(GtkWidget *aWidget, gpointer aData)
888
DUMP("CreateDestNo");
890
gtk_widget_destroy(sCreateDestDlg);
891
sConfirmCreateUp = FALSE;
895
nsSetupTypeDlg::DeleteOldInst()
897
DUMP("DeleteOldInst");
899
const int MAXCHARS = 64; // Maximum chars per line in Delete Dialog
900
const int MAXLINES = 20; // Maximum lines in Delete Dialog
903
char path[MAXPATHLEN];
904
GtkWidget *label = NULL;
905
GtkWidget *deleteBtn = NULL; /* delete button */
906
GtkWidget *cancelBtn = NULL; /* cancel button */
907
char *msgPtr = NULL, *msgChunkPtr = NULL, *msgEndPtr = NULL;
908
char msgChunk[MAXCHARS+1];
909
char msg[MAXPATHLEN+512];
910
nsLegacyCheck *currLC = NULL;
912
currLC = sLegacyChecks;
915
memset(path, 0, MAXPATHLEN);
916
ConstructPath(path, gCtx->opt->mDestination, currLC->GetFilename());
919
// check if old installation exists
920
if (0 == stat(path, &dummy))
922
// throw up delete dialog
923
sDelInstDlg = gtk_dialog_new();
924
gtk_window_set_title(GTK_WINDOW(sDelInstDlg), gCtx->opt->mTitle);
925
gtk_window_set_position(GTK_WINDOW(sDelInstDlg), GTK_WIN_POS_CENTER);
927
deleteBtn = gtk_button_new_with_label(gCtx->Res("DELETE_LABEL"));
928
cancelBtn = gtk_button_new_with_label(gCtx->Res("CANCEL_LABEL"));
930
gtk_container_add(GTK_CONTAINER(GTK_DIALOG(sDelInstDlg)->action_area),
932
gtk_container_add(GTK_CONTAINER(GTK_DIALOG(sDelInstDlg)->action_area),
934
gtk_signal_connect(GTK_OBJECT(deleteBtn), "clicked",
935
GTK_SIGNAL_FUNC(DeleteInstDelete), sDelInstDlg);
936
gtk_signal_connect(GTK_OBJECT(cancelBtn), "clicked",
937
GTK_SIGNAL_FUNC(DeleteInstCancel), sDelInstDlg);
939
snprintf(msg, sizeof(msg), currLC->GetMessage(), gCtx->opt->mDestination);
941
msgEndPtr = msg + strlen(msg);
942
// wrap message at MAXCHARS colums (or last space inside MAXCHARS)
943
// stop at MAXLINES rows or stop after last char is reached
944
for (int i = 0; i < MAXLINES && msgPtr < msgEndPtr; i++)
946
// get the next MAXCHARS chars
947
memset(msgChunk, 0, MAXCHARS+1);
948
strncpy(msgChunk, msgPtr, MAXCHARS);
951
msgChunkPtr = strrchr(msgChunk, ' ');
955
msgPtr += (msgChunkPtr - msgChunk + 1);
961
label = gtk_label_new(msgChunk);
962
gtk_box_pack_start(GTK_BOX(GTK_DIALOG(sDelInstDlg)->vbox), label,
965
gtk_widget_show_all(sDelInstDlg);
971
currLC = currLC->GetNext();
978
nsSetupTypeDlg::DeleteInstDelete(GtkWidget *aWidget, gpointer aData)
980
DUMP("DeleteInstDelete");
982
char cwd[MAXPATHLEN];
986
getcwd(cwd, MAXPATHLEN);
987
chdir(gCtx->opt->mDestination);
991
// hide this notebook page
992
gCtx->sdlg->Hide(nsXInstallerDlg::FORWARD_MOVE);
994
// disconnect this dlg's nav btn signal handlers
995
gtk_signal_disconnect(GTK_OBJECT(gCtx->back), gCtx->backID);
996
gtk_signal_disconnect(GTK_OBJECT(gCtx->next), gCtx->nextID);
997
gtk_signal_disconnect(GTK_OBJECT(sBrowseBtn), sBrowseBtnID);
999
// show the final dlg
1000
if (gCtx->opt->mSetupType == (gCtx->sdlg->GetNumSetupTypes() - 1))
1001
gCtx->cdlg->Show(nsXInstallerDlg::FORWARD_MOVE);
1003
gCtx->idlg->Show(nsXInstallerDlg::FORWARD_MOVE);
1005
gtk_widget_destroy(sDelInstDlg);
1009
nsSetupTypeDlg::DeleteInstCancel(GtkWidget *aWidget, gpointer aData)
1011
DUMP("DeleteInstCancel");
1014
gtk_widget_destroy(sDelInstDlg);
1018
nsSetupTypeDlg::ConstructPath(char *aDest, char *aTrunk, char *aLeaf)
1022
char *lastSlash = NULL;
1024
if (!aDest || !aTrunk || !aLeaf)
1027
trunkLen = strlen(aTrunk);
1028
lastSlash = strrchr(aTrunk, '/');
1030
strcpy(aDest, aTrunk);
1031
if (lastSlash != aTrunk + (trunkLen - 1))
1033
// need to tack on a slash
1036
strcat(aDest, aLeaf);
1042
nsSetupTypeDlg::CheckDestEmpty()
1044
DUMP("DeleteOldInst");
1048
nsObjectIgnore *currOI = NULL;
1050
/* check if the destination directory is empty */
1051
destDirD = opendir(gCtx->opt->mDestination);
1052
while (de = readdir(destDirD))
1054
if (strcmp(de->d_name, ".") && strcmp(de->d_name, ".."))
1056
currOI = sObjectsToIgnore;
1059
// check if this is an Object To Ignore
1060
if (!strcmp(currOI->GetFilename(),de->d_name))
1063
currOI = currOI->GetNext();
1068
ErrorHandler(E_DIR_NOT_EMPTY);
1069
return E_DIR_NOT_EMPTY;
1079
nsSetupTypeDlg::VerifyDiskSpace(void)
1082
int dsAvail, dsReqd;
1083
char dsAvailStr[128], dsReqdStr[128];
1085
GtkWidget *noDSDlg, *label, *okButton, *packer;
1087
// find disk space available at destination
1088
dsAvail = DSAvailable();
1090
return OK; // optimistic when statfs failed
1091
// or we don't have statfs
1093
// get disk space required
1094
dsReqd = DSRequired();
1096
if (dsReqd > dsAvail)
1098
// throw up not enough ds dlg
1099
sprintf(dsAvailStr, gCtx->Res("DS_AVAIL"), dsAvail);
1100
sprintf(dsReqdStr, gCtx->Res("DS_REQD"), dsReqd);
1101
sprintf(message, "%s\n%s\n\n%s", dsAvailStr, dsReqdStr,
1102
gCtx->Res("NO_DISK_SPACE"));
1104
noDSDlg = gtk_dialog_new();
1105
label = gtk_label_new(message);
1106
okButton = gtk_button_new_with_label(gCtx->Res("OK_LABEL"));
1107
packer = gtk_packer_new();
1109
if (noDSDlg && label && okButton && packer)
1111
gtk_window_set_title(GTK_WINDOW(noDSDlg), gCtx->opt->mTitle);
1112
gtk_window_set_position(GTK_WINDOW(noDSDlg),
1113
GTK_WIN_POS_CENTER);
1114
gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
1115
gtk_packer_set_default_border_width(GTK_PACKER(packer), 20);
1116
gtk_packer_add_defaults(GTK_PACKER(packer), label, GTK_SIDE_BOTTOM,
1117
GTK_ANCHOR_CENTER, GTK_FILL_X);
1118
gtk_box_pack_start(GTK_BOX(
1119
GTK_DIALOG(noDSDlg)->action_area), okButton,
1121
gtk_signal_connect(GTK_OBJECT(okButton), "clicked",
1122
GTK_SIGNAL_FUNC(NoDiskSpaceOK), noDSDlg);
1123
gtk_box_pack_start(GTK_BOX(
1124
GTK_DIALOG(noDSDlg)->vbox), packer, FALSE, FALSE, 10);
1126
gtk_widget_show_all(noDSDlg);
1129
err = E_NO_DISK_SPACE;
1136
nsSetupTypeDlg::DSAvailable(void)
1138
// returns disk space available in kilobytes
1142
#if defined(HAVE_SYS_STATVFS_H) || defined(HAVE_SYS_STATFS_H)
1146
if (gCtx->opt->mDestination)
1148
rv = STATFS(gCtx->opt->mDestination, &buf);
1151
if (buf.f_bsize > 1024 && (buf.f_bsize%1024 == 0))
1153
// normally the block size is >= 1024 and a multiple
1154
// so we can shave off the last three digits before
1155
// finding the product of the block size and num blocks
1156
// which is important for large disks
1158
dsAvail = (buf.f_bsize/1024) * (buf.f_bavail);
1162
// attempt to stuff into a 32 bit int even though
1163
// we convert from bytes -> kilobytes later
1164
// (may fail to compute on very large disks whose
1165
// block size is not a multiple of 1024 -- highly
1168
dsAvail = (buf.f_bsize * buf.f_bavail)/1024;
1172
#endif // HAVE_SYS_STATVFS_H -or- HAVE_SYS_STATFS_H
1178
nsSetupTypeDlg::DSRequired(void)
1180
// returns disk space required in kilobytes
1183
nsComponentList *comps;
1186
// find setup type's component list
1187
bCus = (gCtx->opt->mSetupType == (gCtx->sdlg->GetNumSetupTypes() - 1));
1188
comps = gCtx->sdlg->GetSelectedSetupType()->GetComponents();
1190
// loop through all components
1191
nsComponent *currComp = comps->GetHead();
1194
if ( (bCus == TRUE && currComp->IsSelected()) || (bCus == FALSE) )
1196
// add to disk space required
1197
dsReqd += currComp->GetInstallSize();
1198
dsReqd += currComp->GetArchiveSize();
1201
currComp = currComp->GetNext();
1208
nsSetupTypeDlg::NoDiskSpaceOK(GtkWidget *aWidget, gpointer aData)
1210
GtkWidget *noDSDlg = (GtkWidget *) aData;
1215
gtk_widget_destroy(noDSDlg);