[haiku-commits] r36482 - haiku/trunk/src/apps/installer

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;


Other related posts: