In the spirit of giving exposure to as many Haiku features as possible,
integrate the Boot Manager into Installer. There was a patch for this in ticket #4425, but I have implemented this myself, since the patch didn't implement the interaction with running and quitting DriveSetup and Bootman correctly. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@36482 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2009, Stephan Aßmus <[email protected]>
|
* Copyright 2009-2010, Stephan Aßmus <[email protected]>
|
||||||
* Copyright 2005-2008, Jérôme DUVAL
|
* Copyright 2005-2008, Jérôme DUVAL
|
||||||
* All rights reserved. Distributed under the terms of the MIT License.
|
* All rights reserved. Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
@@ -48,10 +48,12 @@
|
|||||||
#define TR_CONTEXT "InstallerWindow"
|
#define TR_CONTEXT "InstallerWindow"
|
||||||
|
|
||||||
#define DRIVESETUP_SIG "application/x-vnd.Haiku-DriveSetup"
|
#define DRIVESETUP_SIG "application/x-vnd.Haiku-DriveSetup"
|
||||||
|
#define BOOTMAN_SIG "application/x-vnd.Haiku-Bootman"
|
||||||
|
|
||||||
const uint32 BEGIN_MESSAGE = 'iBGN';
|
const uint32 BEGIN_MESSAGE = 'iBGN';
|
||||||
const uint32 SHOW_BOTTOM_MESSAGE = 'iSBT';
|
const uint32 SHOW_BOTTOM_MESSAGE = 'iSBT';
|
||||||
const uint32 SETUP_MESSAGE = 'iSEP';
|
const uint32 LAUNCH_DRIVE_SETUP = 'iSEP';
|
||||||
|
const uint32 LAUNCH_BOOTMAN = 'iWBM';
|
||||||
const uint32 START_SCAN = 'iSSC';
|
const uint32 START_SCAN = 'iSSC';
|
||||||
const uint32 PACKAGE_CHECKBOX = 'iPCB';
|
const uint32 PACKAGE_CHECKBOX = 'iPCB';
|
||||||
const uint32 ENCOURAGE_DRIVESETUP = 'iENC';
|
const uint32 ENCOURAGE_DRIVESETUP = 'iENC';
|
||||||
@@ -151,6 +153,7 @@ InstallerWindow::InstallerWindow()
|
|||||||
B_TITLED_WINDOW, B_NOT_ZOOMABLE | B_AUTO_UPDATE_SIZE_LIMITS),
|
B_TITLED_WINDOW, B_NOT_ZOOMABLE | B_AUTO_UPDATE_SIZE_LIMITS),
|
||||||
fEncouragedToSetupPartitions(false),
|
fEncouragedToSetupPartitions(false),
|
||||||
fDriveSetupLaunched(false),
|
fDriveSetupLaunched(false),
|
||||||
|
fBootmanLaunched(false),
|
||||||
fInstallStatus(kReadyForInstall),
|
fInstallStatus(kReadyForInstall),
|
||||||
fWorkerThread(new WorkerThread(this)),
|
fWorkerThread(new WorkerThread(this)),
|
||||||
fCopyEngineCancelSemaphore(-1)
|
fCopyEngineCancelSemaphore(-1)
|
||||||
@@ -206,8 +209,13 @@ InstallerWindow::InstallerWindow()
|
|||||||
fBeginButton->MakeDefault(true);
|
fBeginButton->MakeDefault(true);
|
||||||
fBeginButton->SetEnabled(false);
|
fBeginButton->SetEnabled(false);
|
||||||
|
|
||||||
fSetupButton = new BButton("setup_button",
|
fLaunchDriveSetupButton = new BButton("setup_button",
|
||||||
TR("Set up partitions" B_UTF8_ELLIPSIS), new BMessage(SETUP_MESSAGE));
|
TR("Set up partitions" B_UTF8_ELLIPSIS),
|
||||||
|
new BMessage(LAUNCH_DRIVE_SETUP));
|
||||||
|
|
||||||
|
fLaunchBootmanButton = new BButton("bootman_button",
|
||||||
|
TR("Set up boot menu"), new BMessage(LAUNCH_BOOTMAN));
|
||||||
|
fLaunchBootmanButton->SetEnabled(false);
|
||||||
|
|
||||||
fMakeBootableButton = new BButton("makebootable_button",
|
fMakeBootableButton = new BButton("makebootable_button",
|
||||||
TR("Write boot sector"), new BMessage(MSG_WRITE_BOOT_SECTOR));
|
TR("Write boot sector"), new BMessage(MSG_WRITE_BOOT_SECTOR));
|
||||||
@@ -236,7 +244,8 @@ InstallerWindow::InstallerWindow()
|
|||||||
)
|
)
|
||||||
|
|
||||||
.Add(BGroupLayoutBuilder(B_HORIZONTAL, 10)
|
.Add(BGroupLayoutBuilder(B_HORIZONTAL, 10)
|
||||||
.Add(fSetupButton)
|
.Add(fLaunchDriveSetupButton)
|
||||||
|
.Add(fLaunchBootmanButton)
|
||||||
.Add(fMakeBootableButton)
|
.Add(fMakeBootableButton)
|
||||||
.AddGlue()
|
.AddGlue()
|
||||||
.Add(fBeginButton)
|
.Add(fBeginButton)
|
||||||
@@ -256,12 +265,17 @@ InstallerWindow::InstallerWindow()
|
|||||||
fProgressLayoutItem->SetVisible(false);
|
fProgressLayoutItem->SetVisible(false);
|
||||||
|
|
||||||
// Setup tool tips for the non-obvious features
|
// Setup tool tips for the non-obvious features
|
||||||
fSetupButton->SetToolTip(
|
fLaunchDriveSetupButton->SetToolTip(
|
||||||
TR("Launch the DriveSetup utility to partition\n"
|
TR("Launch the DriveSetup utility to partition\n"
|
||||||
"available hard drives and other media.\n"
|
"available hard drives and other media.\n"
|
||||||
"Partitions can be initialized with the\n"
|
"Partitions can be initialized with the\n"
|
||||||
"Be File System needed for a Haiku boot\n"
|
"Be File System needed for a Haiku boot\n"
|
||||||
"partition."));
|
"partition."));
|
||||||
|
fLaunchBootmanButton->SetToolTip(
|
||||||
|
TR("Install or uninstall the Haiku boot menu, which allows to "
|
||||||
|
"choose an operating system to boot when the computer starts.\n"
|
||||||
|
"If this computer already has a boot manager such as GRUB installed, "
|
||||||
|
"it is better to add Haiku to that menu than to overwrite it."));
|
||||||
fMakeBootableButton->SetToolTip(
|
fMakeBootableButton->SetToolTip(
|
||||||
TR("Writes the Haiku boot code to the partition start\n"
|
TR("Writes the Haiku boot code to the partition start\n"
|
||||||
"sector. This step is automatically performed by\n"
|
"sector. This step is automatically performed by\n"
|
||||||
@@ -276,15 +290,18 @@ InstallerWindow::InstallerWindow()
|
|||||||
CenterOnScreen();
|
CenterOnScreen();
|
||||||
Show();
|
Show();
|
||||||
|
|
||||||
|
// Register to receive notifications when apps launch or quit...
|
||||||
|
be_roster->StartWatching(this);
|
||||||
|
// ... and check the two we are interested in.
|
||||||
fDriveSetupLaunched = be_roster->IsRunning(DRIVESETUP_SIG);
|
fDriveSetupLaunched = be_roster->IsRunning(DRIVESETUP_SIG);
|
||||||
|
fBootmanLaunched = be_roster->IsRunning(BOOTMAN_SIG);
|
||||||
|
|
||||||
if (Lock()) {
|
if (Lock()) {
|
||||||
fSetupButton->SetEnabled(!fDriveSetupLaunched);
|
fLaunchDriveSetupButton->SetEnabled(!fDriveSetupLaunched);
|
||||||
|
fLaunchBootmanButton->SetEnabled(!fBootmanLaunched);
|
||||||
Unlock();
|
Unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
be_roster->StartWatching(this);
|
|
||||||
|
|
||||||
PostMessage(START_SCAN);
|
PostMessage(START_SCAN);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -372,9 +389,12 @@ InstallerWindow::MessageReceived(BMessage *msg)
|
|||||||
case TARGET_PARTITION:
|
case TARGET_PARTITION:
|
||||||
_UpdateControls();
|
_UpdateControls();
|
||||||
break;
|
break;
|
||||||
case SETUP_MESSAGE:
|
case LAUNCH_DRIVE_SETUP:
|
||||||
_LaunchDriveSetup();
|
_LaunchDriveSetup();
|
||||||
break;
|
break;
|
||||||
|
case LAUNCH_BOOTMAN:
|
||||||
|
_LaunchBootman();
|
||||||
|
break;
|
||||||
case PACKAGE_CHECKBOX:
|
case PACKAGE_CHECKBOX:
|
||||||
{
|
{
|
||||||
char buffer[15];
|
char buffer[15];
|
||||||
@@ -468,17 +488,46 @@ InstallerWindow::MessageReceived(BMessage *msg)
|
|||||||
case B_SOME_APP_QUIT:
|
case B_SOME_APP_QUIT:
|
||||||
{
|
{
|
||||||
const char *signature;
|
const char *signature;
|
||||||
if (msg->FindString("be:signature", &signature) == B_OK
|
if (msg->FindString("be:signature", &signature) != B_OK)
|
||||||
&& strcasecmp(signature, DRIVESETUP_SIG) == 0) {
|
break;
|
||||||
fDriveSetupLaunched = msg->what == B_SOME_APP_LAUNCHED;
|
bool isDriveSetup = strcasecmp(signature, DRIVESETUP_SIG) == 0;
|
||||||
fBeginButton->SetEnabled(!fDriveSetupLaunched);
|
bool isBootman = strcasecmp(signature, BOOTMAN_SIG) == 0;
|
||||||
_DisableInterface(fDriveSetupLaunched);
|
if (isDriveSetup || isBootman) {
|
||||||
if (fDriveSetupLaunched)
|
bool scanPartitions = false;
|
||||||
|
if (isDriveSetup) {
|
||||||
|
bool launched = msg->what == B_SOME_APP_LAUNCHED;
|
||||||
|
// We need to scan partitions if DriveSetup has quit.
|
||||||
|
scanPartitions = fDriveSetupLaunched && !launched;
|
||||||
|
fDriveSetupLaunched = launched;
|
||||||
|
}
|
||||||
|
if (isBootman)
|
||||||
|
fBootmanLaunched = msg->what == B_SOME_APP_LAUNCHED;
|
||||||
|
|
||||||
|
fBeginButton->SetEnabled(
|
||||||
|
!fDriveSetupLaunched && !fBootmanLaunched);
|
||||||
|
_DisableInterface(fDriveSetupLaunched || fBootmanLaunched);
|
||||||
|
if (fDriveSetupLaunched && fBootmanLaunched) {
|
||||||
|
_SetStatusMessage(TR("Running Boot Manager and "
|
||||||
|
"DriveSetup" B_UTF8_ELLIPSIS
|
||||||
|
"\n\nClose both applications to continue with the "
|
||||||
|
"installation."));
|
||||||
|
} else if (fDriveSetupLaunched) {
|
||||||
_SetStatusMessage(TR("Running DriveSetup" B_UTF8_ELLIPSIS
|
_SetStatusMessage(TR("Running DriveSetup" B_UTF8_ELLIPSIS
|
||||||
"\n\nClose DriveSetup to continue with the "
|
"\n\nClose DriveSetup to continue with the "
|
||||||
"installation."));
|
"installation."));
|
||||||
else
|
} else if (fBootmanLaunched) {
|
||||||
_ScanPartitions();
|
_SetStatusMessage(TR("Running Boot Manager" B_UTF8_ELLIPSIS
|
||||||
|
"\n\nClose Boot Manager to continue with the "
|
||||||
|
"installation."));
|
||||||
|
} else {
|
||||||
|
// If neither DriveSetup nor Bootman is running, we need
|
||||||
|
// to scan partitions in case DriveSetup has quit, or
|
||||||
|
// we need to update the guidance message.
|
||||||
|
if (scanPartitions)
|
||||||
|
_ScanPartitions();
|
||||||
|
else
|
||||||
|
_UpdateControls();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -496,11 +545,21 @@ InstallerWindow::MessageReceived(BMessage *msg)
|
|||||||
bool
|
bool
|
||||||
InstallerWindow::QuitRequested()
|
InstallerWindow::QuitRequested()
|
||||||
{
|
{
|
||||||
if (fDriveSetupLaunched) {
|
if (fDriveSetupLaunched && fBootmanLaunched) {
|
||||||
(new BAlert("driveSetup",
|
(new BAlert(TR("Quit Boot Manager and DriveSetup"),
|
||||||
|
TR("Please close the Boot Manager and DriveSetup windows before "
|
||||||
|
"closing the Installer window."), TR("OK")))->Go();
|
||||||
|
return false;
|
||||||
|
} else if (fDriveSetupLaunched) {
|
||||||
|
(new BAlert(TR("Quit DriveSetup"),
|
||||||
TR("Please close the DriveSetup window before closing the "
|
TR("Please close the DriveSetup window before closing the "
|
||||||
"Installer window."), TR("OK")))->Go();
|
"Installer window."), TR("OK")))->Go();
|
||||||
return false;
|
return false;
|
||||||
|
} else if (fBootmanLaunched) {
|
||||||
|
(new BAlert(TR("Quit Boot Manager"),
|
||||||
|
TR("Please close the Boot Manager window before closing the "
|
||||||
|
"Installer window."), TR("OK")))->Go();
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fInstallStatus != kFinished && (Flags() & B_NOT_MINIMIZABLE) != 0) {
|
if (fInstallStatus != kFinished && (Flags() & B_NOT_MINIMIZABLE) != 0) {
|
||||||
@@ -558,10 +617,38 @@ InstallerWindow::_LaunchDriveSetup()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
InstallerWindow::_LaunchBootman()
|
||||||
|
{
|
||||||
|
// TODO: Currently bootman always tries to install to the "first" harddisk.
|
||||||
|
// If/when it later supports being installed to a certain harddisk, we
|
||||||
|
// would have to pass it the disk that contains the target partition here.
|
||||||
|
if (be_roster->Launch(BOOTMAN_SIG) != B_OK) {
|
||||||
|
// Try really hard to launch it. It's very likely that this fails,
|
||||||
|
// when we run from the CD and there is only an incomplete mime
|
||||||
|
// database for example...
|
||||||
|
BPath path;
|
||||||
|
if (find_directory(B_SYSTEM_BIN_DIRECTORY, &path) != B_OK
|
||||||
|
|| path.Append("bootman") != B_OK) {
|
||||||
|
path.SetTo("/boot/system/bin/bootman");
|
||||||
|
}
|
||||||
|
BEntry entry(path.Path());
|
||||||
|
entry_ref ref;
|
||||||
|
if (entry.GetRef(&ref) != B_OK || be_roster->Launch(&ref) != B_OK) {
|
||||||
|
BAlert* alert = new BAlert("error", TR("Bootman, the "
|
||||||
|
"application to configure the Haiku boot menu, could not be "
|
||||||
|
"launched."), TR("OK"));
|
||||||
|
alert->Go();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
InstallerWindow::_DisableInterface(bool disable)
|
InstallerWindow::_DisableInterface(bool disable)
|
||||||
{
|
{
|
||||||
fSetupButton->SetEnabled(!disable);
|
fLaunchDriveSetupButton->SetEnabled(!disable);
|
||||||
|
fLaunchBootmanButton->SetEnabled(!disable);
|
||||||
fMakeBootableButton->SetEnabled(!disable);
|
fMakeBootableButton->SetEnabled(!disable);
|
||||||
fSrcMenuField->SetEnabled(!disable);
|
fSrcMenuField->SetEnabled(!disable);
|
||||||
fDestMenuField->SetEnabled(!disable);
|
fDestMenuField->SetEnabled(!disable);
|
||||||
@@ -581,9 +668,9 @@ InstallerWindow::_ScanPartitions()
|
|||||||
|
|
||||||
fWorkerThread->ScanDisksPartitions(fSrcMenu, fDestMenu);
|
fWorkerThread->ScanDisksPartitions(fSrcMenu, fDestMenu);
|
||||||
|
|
||||||
if (fSrcMenu->ItemAt(0)) {
|
if (fSrcMenu->ItemAt(0) != NULL)
|
||||||
_PublishPackages();
|
_PublishPackages();
|
||||||
}
|
|
||||||
_UpdateControls();
|
_UpdateControls();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -632,15 +719,15 @@ InstallerWindow::_UpdateControls()
|
|||||||
}
|
}
|
||||||
fDestMenuField->MenuItem()->SetLabel(label.String());
|
fDestMenuField->MenuItem()->SetLabel(label.String());
|
||||||
|
|
||||||
if (srcItem && dstItem) {
|
if (srcItem != NULL && dstItem != NULL) {
|
||||||
char message[255];
|
char message[255];
|
||||||
sprintf(message, TR("Press the Begin button to install from '%1s' "
|
sprintf(message, TR("Press the Begin button to install from '%1s' "
|
||||||
"onto '%2s'."), srcItem->Name(), dstItem->Name());
|
"onto '%2s'."), srcItem->Name(), dstItem->Name());
|
||||||
_SetStatusMessage(message);
|
_SetStatusMessage(message);
|
||||||
} else if (srcItem) {
|
} else if (srcItem != NULL) {
|
||||||
_SetStatusMessage(TR("Choose the disk you want to install onto from "
|
_SetStatusMessage(TR("Choose the disk you want to install onto from "
|
||||||
"the pop-up menu. Then click \"Begin\"."));
|
"the pop-up menu. Then click \"Begin\"."));
|
||||||
} else if (dstItem) {
|
} else if (dstItem != NULL) {
|
||||||
_SetStatusMessage(TR("Choose the source disk from the "
|
_SetStatusMessage(TR("Choose the source disk from the "
|
||||||
"pop-up menu. Then click \"Begin\"."));
|
"pop-up menu. Then click \"Begin\"."));
|
||||||
} else {
|
} else {
|
||||||
@@ -652,16 +739,17 @@ InstallerWindow::_UpdateControls()
|
|||||||
fBeginButton->SetLabel(TR("Begin"));
|
fBeginButton->SetLabel(TR("Begin"));
|
||||||
fBeginButton->SetEnabled(srcItem && dstItem);
|
fBeginButton->SetEnabled(srcItem && dstItem);
|
||||||
|
|
||||||
// adjust "Write Boot Sector" button
|
// adjust "Write Boot Sector" and "Set up boot menu" buttons
|
||||||
if (dstItem) {
|
if (dstItem != NULL) {
|
||||||
char buffer[256];
|
char buffer[256];
|
||||||
snprintf(buffer, sizeof(buffer), TR("Write boot sector to '%s'"),
|
snprintf(buffer, sizeof(buffer), TR("Write boot sector to '%s'"),
|
||||||
dstItem->Name());
|
dstItem->Name());
|
||||||
label = buffer;
|
label = buffer;
|
||||||
} else
|
} else
|
||||||
label = TR("Write boot sector");
|
label = TR("Write boot sector");
|
||||||
fMakeBootableButton->SetEnabled(dstItem);
|
fMakeBootableButton->SetEnabled(dstItem != NULL);
|
||||||
fMakeBootableButton->SetLabel(label.String());
|
fMakeBootableButton->SetLabel(label.String());
|
||||||
|
fLaunchBootmanButton->SetEnabled(dstItem != NULL);
|
||||||
|
|
||||||
if (!fEncouragedToSetupPartitions && !foundOneSuitableTarget) {
|
if (!fEncouragedToSetupPartitions && !foundOneSuitableTarget) {
|
||||||
// Focus the users attention on the DriveSetup button
|
// Focus the users attention on the DriveSetup button
|
||||||
@@ -676,7 +764,7 @@ InstallerWindow::_PublishPackages()
|
|||||||
{
|
{
|
||||||
fPackagesView->Clean();
|
fPackagesView->Clean();
|
||||||
PartitionMenuItem *item = (PartitionMenuItem *)fSrcMenu->FindMarked();
|
PartitionMenuItem *item = (PartitionMenuItem *)fSrcMenu->FindMarked();
|
||||||
if (!item)
|
if (item == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
BPath directory;
|
BPath directory;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2009, Stephan Aßmus <[email protected]>
|
* Copyright 2009-2010, Stephan Aßmus <[email protected]>
|
||||||
* Copyright 2005, Jérôme DUVAL
|
* Copyright 2005, Jérôme DUVAL
|
||||||
* All rights reserved. Distributed under the terms of the MIT License.
|
* All rights reserved. Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
@@ -53,6 +53,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
void _ShowOptionalPackages();
|
void _ShowOptionalPackages();
|
||||||
void _LaunchDriveSetup();
|
void _LaunchDriveSetup();
|
||||||
|
void _LaunchBootman();
|
||||||
void _DisableInterface(bool disable);
|
void _DisableInterface(bool disable);
|
||||||
void _ScanPartitions();
|
void _ScanPartitions();
|
||||||
void _UpdateControls();
|
void _UpdateControls();
|
||||||
@@ -84,12 +85,14 @@ private:
|
|||||||
BLayoutItem* fProgressLayoutItem;
|
BLayoutItem* fProgressLayoutItem;
|
||||||
|
|
||||||
BButton* fBeginButton;
|
BButton* fBeginButton;
|
||||||
BButton* fSetupButton;
|
BButton* fLaunchDriveSetupButton;
|
||||||
|
BButton* fLaunchBootmanButton;
|
||||||
BButton* fMakeBootableButton;
|
BButton* fMakeBootableButton;
|
||||||
|
|
||||||
bool fEncouragedToSetupPartitions;
|
bool fEncouragedToSetupPartitions;
|
||||||
|
|
||||||
bool fDriveSetupLaunched;
|
bool fDriveSetupLaunched;
|
||||||
|
bool fBootmanLaunched;
|
||||||
InstallStatus fInstallStatus;
|
InstallStatus fInstallStatus;
|
||||||
|
|
||||||
WorkerThread* fWorkerThread;
|
WorkerThread* fWorkerThread;
|
||||||
|
|||||||
Reference in New Issue
Block a user