* 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
+22 -2
View File
@@ -74,8 +74,10 @@ CopyEngine::MessageReceived(BMessage*msg)
{ {
status_t err = Start(fWindow->GetSourceMenu(), status_t err = Start(fWindow->GetSourceMenu(),
fWindow->GetTargetMenu()); fWindow->GetTargetMenu());
if (err != B_OK) if (err != B_OK) {
ERR("Start failed"); ERR("Start failed");
BMessenger(fWindow).SendMessage(RESET_INSTALL);
}
break; break;
} }
} }
@@ -123,6 +125,9 @@ status_t
CopyEngine::Start(BMenu *srcMenu, BMenu *targetMenu) CopyEngine::Start(BMenu *srcMenu, BMenu *targetMenu)
{ {
CALLED(); CALLED();
fControl->Reset();
status_t err = B_OK; status_t err = B_OK;
PartitionMenuItem *targetItem = (PartitionMenuItem *)targetMenu->FindMarked(); PartitionMenuItem *targetItem = (PartitionMenuItem *)targetMenu->FindMarked();
PartitionMenuItem *srcItem = (PartitionMenuItem *)srcMenu->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 " "Try choosing a different disk or choose to not install optional "
"items.", "Try installing anyway", "Cancel", 0, "items.", "Try installing anyway", "Cancel", 0,
B_WIDTH_AS_USUAL, B_STOP_ALERT))->Go() != 0)) { B_WIDTH_AS_USUAL, B_STOP_ALERT))->Go() != 0)) {
BMessenger(fWindow).SendMessage(RESET_INSTALL);
return B_OK; return B_OK;
} }
@@ -203,6 +209,7 @@ CopyEngine::Start(BMenu *srcMenu, BMenu *targetMenu)
if (strcmp(srcDirectory.Path(), targetDirectory.Path()) == 0) { if (strcmp(srcDirectory.Path(), targetDirectory.Path()) == 0) {
SetStatusMessage("You can't install the contents of a disk onto " SetStatusMessage("You can't install the contents of a disk onto "
"itself. Please choose a different disk."); "itself. Please choose a different disk.");
BMessenger(fWindow).SendMessage(RESET_INSTALL);
return B_OK; return B_OK;
} }
@@ -213,6 +220,7 @@ CopyEngine::Start(BMenu *srcMenu, BMenu *targetMenu)
"machine if you proceed.", "OK", "Cancel", 0, "machine if you proceed.", "OK", "Cancel", 0,
B_WIDTH_AS_USUAL, B_STOP_ALERT))->Go() != 0)) { B_WIDTH_AS_USUAL, B_STOP_ALERT))->Go() != 0)) {
SetStatusMessage("Installation stopped."); SetStatusMessage("Installation stopped.");
BMessenger(fWindow).SendMessage(RESET_INSTALL);
return B_OK; return B_OK;
} }
@@ -230,16 +238,20 @@ CopyEngine::Start(BMenu *srcMenu, BMenu *targetMenu)
BDirectory packageDir; BDirectory packageDir;
int32 count = fPackages->CountItems(); int32 count = fPackages->CountItems();
for (int32 i = 0; i < count; i++) { for (int32 i = 0; i < count; i++) {
if (fControl->CheckUserCanceled())
return B_OK;
Package *p = static_cast<Package*>(fPackages->ItemAt(i)); Package *p = static_cast<Package*>(fPackages->ItemAt(i));
packageDir.SetTo(&srcDir, p->Folder()); packageDir.SetTo(&srcDir, p->Folder());
CopyFolder(packageDir, targetDir); CopyFolder(packageDir, targetDir);
} }
} }
if (!fControl->CheckUserCanceled()) {
LaunchFinishScript(targetDirectory); LaunchFinishScript(targetDirectory);
BMessage msg(INSTALL_FINISHED); BMessage msg(INSTALL_FINISHED);
BMessenger(fWindow).SendMessage(&msg); BMessenger(fWindow).SendMessage(&msg);
}
return B_OK; return B_OK;
} }
@@ -250,7 +262,8 @@ CopyEngine::CopyFolder(BDirectory &srcDir, BDirectory &targetDir)
{ {
BEntry entry; BEntry entry;
status_t err; status_t err;
while (srcDir.GetNextEntry(&entry) == B_OK) { while (srcDir.GetNextEntry(&entry) == B_OK
&& !fControl->CheckUserCanceled()) {
StatStruct statbuf; StatStruct statbuf;
entry.GetStat(&statbuf); entry.GetStat(&statbuf);
@@ -299,6 +312,13 @@ CopyEngine::SetPackagesList(BList *list)
} }
bool
CopyEngine::Cancel()
{
return fControl->Cancel();
}
// #pragma mark - // #pragma mark -
+1
View File
@@ -28,6 +28,7 @@ class CopyEngine : public BLooper {
void ScanDisksPartitions(BMenu *srcMenu, BMenu *targetMenu); void ScanDisksPartitions(BMenu *srcMenu, BMenu *targetMenu);
void SetPackagesList(BList *list); void SetPackagesList(BList *list);
void SetSpaceRequired(off_t bytes) { fSpaceRequired = bytes; }; void SetSpaceRequired(off_t bytes) { fSpaceRequired = bytes; };
bool Cancel();
private: private:
void LaunchInitScript(BPath &path); void LaunchInitScript(BPath &path);
void LaunchFinishScript(BPath &path); void LaunchFinishScript(BPath &path);
@@ -9,7 +9,8 @@
InstallerCopyLoopControl::InstallerCopyLoopControl(InstallerWindow *window) InstallerCopyLoopControl::InstallerCopyLoopControl(InstallerWindow *window)
: fWindow(window), : fWindow(window),
fMessenger(window) fMessenger(window),
fUserCanceled(false)
{ {
} }
@@ -48,7 +49,7 @@ InstallerCopyLoopControl::UpdateStatus(const char *name, entry_ref ref, int32 co
bool bool
InstallerCopyLoopControl::CheckUserCanceled() InstallerCopyLoopControl::CheckUserCanceled()
{ {
return false; return fUserCanceled;
} }
@@ -97,3 +98,21 @@ InstallerCopyLoopControl::PreserveAttribute(const char *attributeName)
return false; 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;
}
@@ -35,10 +35,13 @@ class InstallerCopyLoopControl : public CopyLoopControl
virtual bool ChecksumFile(const entry_ref *); virtual bool ChecksumFile(const entry_ref *);
virtual bool SkipAttribute(const char *attributeName); virtual bool SkipAttribute(const char *attributeName);
virtual bool PreserveAttribute(const char *attributeName); virtual bool PreserveAttribute(const char *attributeName);
bool Cancel();
void Reset();
private: private:
InstallerWindow *fWindow; InstallerWindow *fWindow;
BMessenger fMessenger; BMessenger fMessenger;
bool fUserCanceled;
}; };
#endif #endif
+35 -4
View File
@@ -71,6 +71,7 @@ InstallerWindow::InstallerWindow(BRect frame_rect)
: BWindow(frame_rect, "Installer", B_TITLED_WINDOW, : BWindow(frame_rect, "Installer", B_TITLED_WINDOW,
B_NOT_ZOOMABLE | B_NOT_RESIZABLE), B_NOT_ZOOMABLE | B_NOT_RESIZABLE),
fDriveSetupLaunched(false), fDriveSetupLaunched(false),
fInstallStatus(kReadyForInstall),
fLastSrcItem(NULL), fLastSrcItem(NULL),
fLastTargetItem(NULL) fLastTargetItem(NULL)
{ {
@@ -110,6 +111,7 @@ InstallerWindow::InstallerWindow(BRect frame_rect)
"begin_button", "Begin", new BMessage(BEGIN_MESSAGE), "begin_button", "Begin", new BMessage(BEGIN_MESSAGE),
B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM); B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM);
fBeginButton->MakeDefault(true); fBeginButton->MakeDefault(true);
fBeginButton->SetEnabled(false);
fBackBox->AddChild(fBeginButton); fBackBox->AddChild(fBeginButton);
fSetupButton = new BButton(BRect(bounds.left + 11, bounds.bottom - 35, 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); fDestMenu = new BPopUpMenu("scanning" B_UTF8_ELLIPSIS, true, false);
fSrcMenu = 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); bounds.top + 90);
fSrcMenuField = new BMenuField(fieldRect, "srcMenuField", fSrcMenuField = new BMenuField(fieldRect, "srcMenuField",
"Install from: ", fSrcMenu); "Install from: ", fSrcMenu);
fSrcMenuField->SetDivider(bounds.right - 274); fSrcMenuField->SetDivider(bounds.right - 300);
fSrcMenuField->SetAlignment(B_ALIGN_RIGHT); fSrcMenuField->SetAlignment(B_ALIGN_RIGHT);
fBackBox->AddChild(fSrcMenuField); fBackBox->AddChild(fSrcMenuField);
fieldRect.OffsetBy(0, 23); fieldRect.OffsetBy(0, 23);
fDestMenuField = new BMenuField(fieldRect, "destMenuField", fDestMenuField = new BMenuField(fieldRect, "destMenuField",
"Onto: ", fDestMenu); "Onto: ", fDestMenu);
fDestMenuField->SetDivider(bounds.right - 274); fDestMenuField->SetDivider(bounds.right - 300);
fDestMenuField->SetAlignment(B_ALIGN_RIGHT); fDestMenuField->SetAlignment(B_ALIGN_RIGHT);
fBackBox->AddChild(fDestMenuField); fBackBox->AddChild(fDestMenuField);
@@ -182,10 +184,19 @@ void
InstallerWindow::MessageReceived(BMessage *msg) InstallerWindow::MessageReceived(BMessage *msg)
{ {
switch (msg->what) { switch (msg->what) {
case RESET_INSTALL:
fInstallStatus = kReadyForInstall;
fBeginButton->SetEnabled(true);
DisableInterface(false);
fBeginButton->SetLabel("Begin");
break;
case START_SCAN: case START_SCAN:
StartScan(); StartScan();
fBeginButton->SetEnabled(true);
break; break;
case BEGIN_MESSAGE: case BEGIN_MESSAGE:
switch (fInstallStatus) {
case kReadyForInstall:
{ {
BList *list = new BList(); BList *list = new BList();
int32 size = 0; int32 size = 0;
@@ -193,9 +204,25 @@ InstallerWindow::MessageReceived(BMessage *msg)
fCopyEngine->SetPackagesList(list); fCopyEngine->SetPackagesList(list);
fCopyEngine->SetSpaceRequired(size); fCopyEngine->SetSpaceRequired(size);
BMessenger(fCopyEngine).SendMessage(ENGINE_START); BMessenger(fCopyEngine).SendMessage(ENGINE_START);
fBeginButton->SetLabel("Stop");
DisableInterface(true); DisableInterface(true);
fInstallStatus = kInstalling;
break; 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: case SHOW_BOTTOM_MESSAGE:
ShowBottom(); ShowBottom();
break; break;
@@ -224,6 +251,8 @@ InstallerWindow::MessageReceived(BMessage *msg)
break; break;
} }
case STATUS_MESSAGE: { case STATUS_MESSAGE: {
if (fInstallStatus != kInstalling)
break;
const char *status; const char *status;
if (msg->FindString("status", &status) == B_OK) { if (msg->FindString("status", &status) == B_OK) {
fLastStatus = fStatusView->Text(); fLastStatus = fStatusView->Text();
@@ -233,6 +262,8 @@ InstallerWindow::MessageReceived(BMessage *msg)
break; break;
} }
case INSTALL_FINISHED: case INSTALL_FINISHED:
fBeginButton->SetLabel("Quit");
fInstallStatus = kFinished;
DisableInterface(false); DisableInterface(false);
break; break;
case B_SOME_APP_LAUNCHED: case B_SOME_APP_LAUNCHED:
@@ -242,6 +273,7 @@ InstallerWindow::MessageReceived(BMessage *msg)
if (msg->FindString("be:signature", &signature) == B_OK if (msg->FindString("be:signature", &signature) == B_OK
&& strcasecmp(signature, DRIVESETUP_SIG) == 0) { && strcasecmp(signature, DRIVESETUP_SIG) == 0) {
fDriveSetupLaunched = msg->what == B_SOME_APP_LAUNCHED; fDriveSetupLaunched = msg->what == B_SOME_APP_LAUNCHED;
fBeginButton->SetEnabled(!fDriveSetupLaunched);
DisableInterface(fDriveSetupLaunched); DisableInterface(fDriveSetupLaunched);
if (fDriveSetupLaunched) if (fDriveSetupLaunched)
SetStatusMessage("Running DriveSetup" B_UTF8_ELLIPSIS SetStatusMessage("Running DriveSetup" B_UTF8_ELLIPSIS
@@ -307,7 +339,6 @@ InstallerWindow::LaunchDriveSetup()
void void
InstallerWindow::DisableInterface(bool disable) InstallerWindow::DisableInterface(bool disable)
{ {
fBeginButton->SetEnabled(!disable);
fSetupButton->SetEnabled(!disable); fSetupButton->SetEnabled(!disable);
fSrcMenuField->SetEnabled(!disable); fSrcMenuField->SetEnabled(!disable);
fDestMenuField->SetEnabled(!disable); fDestMenuField->SetEnabled(!disable);
+9
View File
@@ -20,8 +20,16 @@
#define INSTALLER_RIGHT 402 #define INSTALLER_RIGHT 402
enum InstallStatus {
kReadyForInstall,
kInstalling,
kFinished,
kCancelled
};
const uint32 STATUS_MESSAGE = 'iSTM'; const uint32 STATUS_MESSAGE = 'iSTM';
const uint32 INSTALL_FINISHED = 'iIFN'; const uint32 INSTALL_FINISHED = 'iIFN';
const uint32 RESET_INSTALL = 'iRSI';
const char PACKAGES_DIRECTORY[] = "_packages_"; const char PACKAGES_DIRECTORY[] = "_packages_";
class InstallerWindow : public BWindow { class InstallerWindow : public BWindow {
@@ -46,6 +54,7 @@ class InstallerWindow : public BWindow {
BButton *fBeginButton, *fSetupButton; BButton *fBeginButton, *fSetupButton;
DrawButton *fDrawButton; DrawButton *fDrawButton;
bool fDriveSetupLaunched; bool fDriveSetupLaunched;
InstallStatus fInstallStatus;
BTextView *fStatusView; BTextView *fStatusView;
BMenu* fSrcMenu, *fDestMenu; BMenu* fSrcMenu, *fDestMenu;
BMenuField* fSrcMenuField, *fDestMenuField; BMenuField* fSrcMenuField, *fDestMenuField;