* Patch from Christian Fasshauer: provides a cancel button

* fixed a few things: one couldn't restart the install process when cancelled, use B_QUIT_REQUESTED instead of QuitRequested().


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@25466 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Jérôme Duval 2008-05-12 11:38:10 +00:00
parent e5812e917b
commit 739dbdfae4
6 changed files with 103 additions and 20 deletions

View File

@ -74,8 +74,10 @@ CopyEngine::MessageReceived(BMessage*msg)
{
status_t err = Start(fWindow->GetSourceMenu(),
fWindow->GetTargetMenu());
if (err != B_OK)
if (err != B_OK) {
ERR("Start failed");
BMessenger(fWindow).SendMessage(RESET_INSTALL);
}
break;
}
}
@ -123,6 +125,9 @@ status_t
CopyEngine::Start(BMenu *srcMenu, BMenu *targetMenu)
{
CALLED();
fControl->Reset();
status_t err = B_OK;
PartitionMenuItem *targetItem = (PartitionMenuItem *)targetMenu->FindMarked();
PartitionMenuItem *srcItem = (PartitionMenuItem *)srcMenu->FindMarked();
@ -182,6 +187,7 @@ CopyEngine::Start(BMenu *srcMenu, BMenu *targetMenu)
"Try choosing a different disk or choose to not install optional "
"items.", "Try installing anyway", "Cancel", 0,
B_WIDTH_AS_USUAL, B_STOP_ALERT))->Go() != 0)) {
BMessenger(fWindow).SendMessage(RESET_INSTALL);
return B_OK;
}
@ -203,6 +209,7 @@ CopyEngine::Start(BMenu *srcMenu, BMenu *targetMenu)
if (strcmp(srcDirectory.Path(), targetDirectory.Path()) == 0) {
SetStatusMessage("You can't install the contents of a disk onto "
"itself. Please choose a different disk.");
BMessenger(fWindow).SendMessage(RESET_INSTALL);
return B_OK;
}
@ -213,6 +220,7 @@ CopyEngine::Start(BMenu *srcMenu, BMenu *targetMenu)
"machine if you proceed.", "OK", "Cancel", 0,
B_WIDTH_AS_USUAL, B_STOP_ALERT))->Go() != 0)) {
SetStatusMessage("Installation stopped.");
BMessenger(fWindow).SendMessage(RESET_INSTALL);
return B_OK;
}
@ -230,16 +238,20 @@ CopyEngine::Start(BMenu *srcMenu, BMenu *targetMenu)
BDirectory packageDir;
int32 count = fPackages->CountItems();
for (int32 i = 0; i < count; i++) {
if (fControl->CheckUserCanceled())
return B_OK;
Package *p = static_cast<Package*>(fPackages->ItemAt(i));
packageDir.SetTo(&srcDir, p->Folder());
CopyFolder(packageDir, targetDir);
}
}
if (!fControl->CheckUserCanceled()) {
LaunchFinishScript(targetDirectory);
BMessage msg(INSTALL_FINISHED);
BMessenger(fWindow).SendMessage(&msg);
}
return B_OK;
}
@ -250,7 +262,8 @@ CopyEngine::CopyFolder(BDirectory &srcDir, BDirectory &targetDir)
{
BEntry entry;
status_t err;
while (srcDir.GetNextEntry(&entry) == B_OK) {
while (srcDir.GetNextEntry(&entry) == B_OK
&& !fControl->CheckUserCanceled()) {
StatStruct statbuf;
entry.GetStat(&statbuf);
@ -299,6 +312,13 @@ CopyEngine::SetPackagesList(BList *list)
}
bool
CopyEngine::Cancel()
{
return fControl->Cancel();
}
// #pragma mark -

View File

@ -28,6 +28,7 @@ class CopyEngine : public BLooper {
void ScanDisksPartitions(BMenu *srcMenu, BMenu *targetMenu);
void SetPackagesList(BList *list);
void SetSpaceRequired(off_t bytes) { fSpaceRequired = bytes; };
bool Cancel();
private:
void LaunchInitScript(BPath &path);
void LaunchFinishScript(BPath &path);

View File

@ -9,7 +9,8 @@
InstallerCopyLoopControl::InstallerCopyLoopControl(InstallerWindow *window)
: fWindow(window),
fMessenger(window)
fMessenger(window),
fUserCanceled(false)
{
}
@ -48,7 +49,7 @@ InstallerCopyLoopControl::UpdateStatus(const char *name, entry_ref ref, int32 co
bool
InstallerCopyLoopControl::CheckUserCanceled()
{
return false;
return fUserCanceled;
}
@ -97,3 +98,21 @@ InstallerCopyLoopControl::PreserveAttribute(const char *attributeName)
return false;
}
bool
InstallerCopyLoopControl::Cancel()
{
fUserCanceled = (new BAlert("",
"Are you sure you want to to stop the installation?",
"Continue", "Stop", 0,
B_WIDTH_AS_USUAL, B_STOP_ALERT))->Go() != 0;
return fUserCanceled;
}
void
InstallerCopyLoopControl::Reset()
{
fUserCanceled = false;
}

View File

@ -35,10 +35,13 @@ class InstallerCopyLoopControl : public CopyLoopControl
virtual bool ChecksumFile(const entry_ref *);
virtual bool SkipAttribute(const char *attributeName);
virtual bool PreserveAttribute(const char *attributeName);
bool Cancel();
void Reset();
private:
InstallerWindow *fWindow;
BMessenger fMessenger;
bool fUserCanceled;
};
#endif

View File

@ -71,6 +71,7 @@ InstallerWindow::InstallerWindow(BRect frame_rect)
: BWindow(frame_rect, "Installer", B_TITLED_WINDOW,
B_NOT_ZOOMABLE | B_NOT_RESIZABLE),
fDriveSetupLaunched(false),
fInstallStatus(kReadyForInstall),
fLastSrcItem(NULL),
fLastTargetItem(NULL)
{
@ -110,6 +111,7 @@ InstallerWindow::InstallerWindow(BRect frame_rect)
"begin_button", "Begin", new BMessage(BEGIN_MESSAGE),
B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM);
fBeginButton->MakeDefault(true);
fBeginButton->SetEnabled(false);
fBackBox->AddChild(fBeginButton);
fSetupButton = new BButton(BRect(bounds.left + 11, bounds.bottom - 35,
@ -135,18 +137,18 @@ InstallerWindow::InstallerWindow(BRect frame_rect)
fDestMenu = new BPopUpMenu("scanning" B_UTF8_ELLIPSIS, true, false);
fSrcMenu = new BPopUpMenu("scanning" B_UTF8_ELLIPSIS, true, false);
BRect fieldRect(bounds.left + 50, bounds.top + 70, bounds.right - 13,
BRect fieldRect(bounds.left + 13, bounds.top + 70, bounds.right - 13,
bounds.top + 90);
fSrcMenuField = new BMenuField(fieldRect, "srcMenuField",
"Install from: ", fSrcMenu);
fSrcMenuField->SetDivider(bounds.right - 274);
fSrcMenuField->SetDivider(bounds.right - 300);
fSrcMenuField->SetAlignment(B_ALIGN_RIGHT);
fBackBox->AddChild(fSrcMenuField);
fieldRect.OffsetBy(0, 23);
fDestMenuField = new BMenuField(fieldRect, "destMenuField",
"Onto: ", fDestMenu);
fDestMenuField->SetDivider(bounds.right - 274);
fDestMenuField->SetDivider(bounds.right - 300);
fDestMenuField->SetAlignment(B_ALIGN_RIGHT);
fBackBox->AddChild(fDestMenuField);
@ -182,10 +184,19 @@ void
InstallerWindow::MessageReceived(BMessage *msg)
{
switch (msg->what) {
case RESET_INSTALL:
fInstallStatus = kReadyForInstall;
fBeginButton->SetEnabled(true);
DisableInterface(false);
fBeginButton->SetLabel("Begin");
break;
case START_SCAN:
StartScan();
fBeginButton->SetEnabled(true);
break;
case BEGIN_MESSAGE:
switch (fInstallStatus) {
case kReadyForInstall:
{
BList *list = new BList();
int32 size = 0;
@ -193,9 +204,25 @@ InstallerWindow::MessageReceived(BMessage *msg)
fCopyEngine->SetPackagesList(list);
fCopyEngine->SetSpaceRequired(size);
BMessenger(fCopyEngine).SendMessage(ENGINE_START);
fBeginButton->SetLabel("Stop");
DisableInterface(true);
fInstallStatus = kInstalling;
break;
}
case kInstalling:
if (fCopyEngine->Cancel()) {
fInstallStatus = kCancelled;
SetStatusMessage("Installation cancelled.");
PostMessage(RESET_INSTALL);
}
break;
case kFinished:
PostMessage(B_QUIT_REQUESTED);
break;
case kCancelled:
break;
}
break;
case SHOW_BOTTOM_MESSAGE:
ShowBottom();
break;
@ -224,6 +251,8 @@ InstallerWindow::MessageReceived(BMessage *msg)
break;
}
case STATUS_MESSAGE: {
if (fInstallStatus != kInstalling)
break;
const char *status;
if (msg->FindString("status", &status) == B_OK) {
fLastStatus = fStatusView->Text();
@ -233,6 +262,8 @@ InstallerWindow::MessageReceived(BMessage *msg)
break;
}
case INSTALL_FINISHED:
fBeginButton->SetLabel("Quit");
fInstallStatus = kFinished;
DisableInterface(false);
break;
case B_SOME_APP_LAUNCHED:
@ -242,6 +273,7 @@ InstallerWindow::MessageReceived(BMessage *msg)
if (msg->FindString("be:signature", &signature) == B_OK
&& strcasecmp(signature, DRIVESETUP_SIG) == 0) {
fDriveSetupLaunched = msg->what == B_SOME_APP_LAUNCHED;
fBeginButton->SetEnabled(!fDriveSetupLaunched);
DisableInterface(fDriveSetupLaunched);
if (fDriveSetupLaunched)
SetStatusMessage("Running DriveSetup" B_UTF8_ELLIPSIS
@ -307,7 +339,6 @@ InstallerWindow::LaunchDriveSetup()
void
InstallerWindow::DisableInterface(bool disable)
{
fBeginButton->SetEnabled(!disable);
fSetupButton->SetEnabled(!disable);
fSrcMenuField->SetEnabled(!disable);
fDestMenuField->SetEnabled(!disable);

View File

@ -20,8 +20,16 @@
#define INSTALLER_RIGHT 402
enum InstallStatus {
kReadyForInstall,
kInstalling,
kFinished,
kCancelled
};
const uint32 STATUS_MESSAGE = 'iSTM';
const uint32 INSTALL_FINISHED = 'iIFN';
const uint32 RESET_INSTALL = 'iRSI';
const char PACKAGES_DIRECTORY[] = "_packages_";
class InstallerWindow : public BWindow {
@ -46,6 +54,7 @@ class InstallerWindow : public BWindow {
BButton *fBeginButton, *fSetupButton;
DrawButton *fDrawButton;
bool fDriveSetupLaunched;
InstallStatus fInstallStatus;
BTextView *fStatusView;
BMenu* fSrcMenu, *fDestMenu;
BMenuField* fSrcMenuField, *fDestMenuField;