Author: stippi Date: 2010-04-26 12:09:14 +0200 (Mon, 26 Apr 2010) New Revision: 36482 Changeset: http://dev.haiku-os.org/changeset/36482/haiku Ticket: http://dev.haiku-os.org/ticket/4425 Modified: haiku/trunk/src/apps/installer/InstallerWindow.cpp haiku/trunk/src/apps/installer/InstallerWindow.h Log: 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. Modified: haiku/trunk/src/apps/installer/InstallerWindow.cpp =================================================================== --- haiku/trunk/src/apps/installer/InstallerWindow.cpp 2010-04-26 10:00:59 UTC (rev 36481) +++ haiku/trunk/src/apps/installer/InstallerWindow.cpp 2010-04-26 10:09:14 UTC (rev 36482) @@ -1,5 +1,5 @@ /* - * Copyright 2009, Stephan Aßmus <superstippi@xxxxxx> + * Copyright 2009-2010, Stephan Aßmus <superstippi@xxxxxx> * Copyright 2005-2008, Jérôme DUVAL * All rights reserved. Distributed under the terms of the MIT License. */ @@ -48,10 +48,12 @@ #define TR_CONTEXT "InstallerWindow" #define DRIVESETUP_SIG "application/x-vnd.Haiku-DriveSetup" +#define BOOTMAN_SIG "application/x-vnd.Haiku-Bootman" const uint32 BEGIN_MESSAGE = 'iBGN'; 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 PACKAGE_CHECKBOX = 'iPCB'; const uint32 ENCOURAGE_DRIVESETUP = 'iENC'; @@ -151,6 +153,7 @@ B_TITLED_WINDOW, B_NOT_ZOOMABLE | B_AUTO_UPDATE_SIZE_LIMITS), fEncouragedToSetupPartitions(false), fDriveSetupLaunched(false), + fBootmanLaunched(false), fInstallStatus(kReadyForInstall), fWorkerThread(new WorkerThread(this)), fCopyEngineCancelSemaphore(-1) @@ -206,9 +209,14 @@ fBeginButton->MakeDefault(true); fBeginButton->SetEnabled(false); - fSetupButton = new BButton("setup_button", - TR("Set up partitions" B_UTF8_ELLIPSIS), new BMessage(SETUP_MESSAGE)); + fLaunchDriveSetupButton = new BButton("setup_button", + 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", TR("Write boot sector"), new BMessage(MSG_WRITE_BOOT_SECTOR)); fMakeBootableButton->SetEnabled(false); @@ -236,7 +244,8 @@ ) .Add(BGroupLayoutBuilder(B_HORIZONTAL, 10) - .Add(fSetupButton) + .Add(fLaunchDriveSetupButton) + .Add(fLaunchBootmanButton) .Add(fMakeBootableButton) .AddGlue() .Add(fBeginButton) @@ -256,12 +265,17 @@ fProgressLayoutItem->SetVisible(false); // Setup tool tips for the non-obvious features - fSetupButton->SetToolTip( + fLaunchDriveSetupButton->SetToolTip( TR("Launch the DriveSetup utility to partition\n" "available hard drives and other media.\n" "Partitions can be initialized with the\n" "Be File System needed for a Haiku boot\n" "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( TR("Writes the Haiku boot code to the partition start\n" "sector. This step is automatically performed by\n" @@ -276,15 +290,18 @@ CenterOnScreen(); 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); + fBootmanLaunched = be_roster->IsRunning(BOOTMAN_SIG); if (Lock()) { - fSetupButton->SetEnabled(!fDriveSetupLaunched); + fLaunchDriveSetupButton->SetEnabled(!fDriveSetupLaunched); + fLaunchBootmanButton->SetEnabled(!fBootmanLaunched); Unlock(); } - be_roster->StartWatching(this); - PostMessage(START_SCAN); } @@ -372,9 +389,12 @@ case TARGET_PARTITION: _UpdateControls(); break; - case SETUP_MESSAGE: + case LAUNCH_DRIVE_SETUP: _LaunchDriveSetup(); break; + case LAUNCH_BOOTMAN: + _LaunchBootman(); + break; case PACKAGE_CHECKBOX: { char buffer[15]; @@ -468,17 +488,46 @@ case B_SOME_APP_QUIT: { const char *signature; - 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) + if (msg->FindString("be:signature", &signature) != B_OK) + break; + bool isDriveSetup = strcasecmp(signature, DRIVESETUP_SIG) == 0; + bool isBootman = strcasecmp(signature, BOOTMAN_SIG) == 0; + if (isDriveSetup || isBootman) { + 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 "\n\nClose DriveSetup to continue with the " "installation.")); - else - _ScanPartitions(); + } else if (fBootmanLaunched) { + _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; } @@ -496,11 +545,21 @@ bool InstallerWindow::QuitRequested() { - if (fDriveSetupLaunched) { - (new BAlert("driveSetup", + if (fDriveSetupLaunched && fBootmanLaunched) { + (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 " "Installer window."), TR("OK")))->Go(); 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) { @@ -559,9 +618,37 @@ 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 InstallerWindow::_DisableInterface(bool disable) { - fSetupButton->SetEnabled(!disable); + fLaunchDriveSetupButton->SetEnabled(!disable); + fLaunchBootmanButton->SetEnabled(!disable); fMakeBootableButton->SetEnabled(!disable); fSrcMenuField->SetEnabled(!disable); fDestMenuField->SetEnabled(!disable); @@ -581,9 +668,9 @@ fWorkerThread->ScanDisksPartitions(fSrcMenu, fDestMenu); - if (fSrcMenu->ItemAt(0)) { + if (fSrcMenu->ItemAt(0) != NULL) _PublishPackages(); - } + _UpdateControls(); } @@ -632,15 +719,15 @@ } fDestMenuField->MenuItem()->SetLabel(label.String()); - if (srcItem && dstItem) { + if (srcItem != NULL && dstItem != NULL) { char message[255]; sprintf(message, TR("Press the Begin button to install from '%1s' " "onto '%2s'."), srcItem->Name(), dstItem->Name()); _SetStatusMessage(message); - } else if (srcItem) { + } else if (srcItem != NULL) { _SetStatusMessage(TR("Choose the disk you want to install onto from " "the pop-up menu. Then click \"Begin\".")); - } else if (dstItem) { + } else if (dstItem != NULL) { _SetStatusMessage(TR("Choose the source disk from the " "pop-up menu. Then click \"Begin\".")); } else { @@ -652,16 +739,17 @@ fBeginButton->SetLabel(TR("Begin")); fBeginButton->SetEnabled(srcItem && dstItem); - // adjust "Write Boot Sector" button - if (dstItem) { + // adjust "Write Boot Sector" and "Set up boot menu" buttons + if (dstItem != NULL) { char buffer[256]; snprintf(buffer, sizeof(buffer), TR("Write boot sector to '%s'"), dstItem->Name()); label = buffer; } else label = TR("Write boot sector"); - fMakeBootableButton->SetEnabled(dstItem); + fMakeBootableButton->SetEnabled(dstItem != NULL); fMakeBootableButton->SetLabel(label.String()); + fLaunchBootmanButton->SetEnabled(dstItem != NULL); if (!fEncouragedToSetupPartitions && !foundOneSuitableTarget) { // Focus the users attention on the DriveSetup button @@ -676,7 +764,7 @@ { fPackagesView->Clean(); PartitionMenuItem *item = (PartitionMenuItem *)fSrcMenu->FindMarked(); - if (!item) + if (item == NULL) return; BPath directory; Modified: haiku/trunk/src/apps/installer/InstallerWindow.h =================================================================== --- haiku/trunk/src/apps/installer/InstallerWindow.h 2010-04-26 10:00:59 UTC (rev 36481) +++ haiku/trunk/src/apps/installer/InstallerWindow.h 2010-04-26 10:09:14 UTC (rev 36482) @@ -1,5 +1,5 @@ /* - * Copyright 2009, Stephan Aßmus <superstippi@xxxxxx> + * Copyright 2009-2010, Stephan Aßmus <superstippi@xxxxxx> * Copyright 2005, Jérôme DUVAL * All rights reserved. Distributed under the terms of the MIT License. */ @@ -53,6 +53,7 @@ private: void _ShowOptionalPackages(); void _LaunchDriveSetup(); + void _LaunchBootman(); void _DisableInterface(bool disable); void _ScanPartitions(); void _UpdateControls(); @@ -84,12 +85,14 @@ BLayoutItem* fProgressLayoutItem; BButton* fBeginButton; - BButton* fSetupButton; + BButton* fLaunchDriveSetupButton; + BButton* fLaunchBootmanButton; BButton* fMakeBootableButton; bool fEncouragedToSetupPartitions; bool fDriveSetupLaunched; + bool fBootmanLaunched; InstallStatus fInstallStatus; WorkerThread* fWorkerThread;