16ffb6a6eSJérôme Duval/*
22061b030SStephan Aßmus * Copyright 2009-2010, Stephan A��mus <superstippi@gmx.de>
3803d0234SStephan Aßmus * Copyright 2005-2008, J��r��me DUVAL
47ff74a7bSStephan Aßmus * All rights reserved. Distributed under the terms of the MIT License.
56ffb6a6eSJérôme Duval */
66ffb6a6eSJérôme Duval
710dfe897SAxel Dörfler
81e855c37SIngo Weinhold#include "InstallerWindow.h"
93e3d7acbSStephan Aßmus
101e855c37SIngo Weinhold#include <stdio.h>
113aeed660SJérôme Duval#include <strings.h>
123e3d7acbSStephan Aßmus
1335d3acb2SJérôme Duval#include <Alert.h>
146ffb6a6eSJérôme Duval#include <Application.h>
15633dee06SJérôme Duval#include <Autolock.h>
166ffb6a6eSJérôme Duval#include <Box.h>
17803d0234SStephan Aßmus#include <Button.h>
184a2da425SStephan Aßmus#include <Catalog.h>
19c89c29e7SStephan Aßmus#include <ControlLook.h>
205b9ea6c3SJérôme Duval#include <Directory.h>
21b4afa663SStephan Aßmus#include <FindDirectory.h>
225dcd3cd1SHannah Boneß#include <LayoutBuilder.h>
237ff74a7bSStephan Aßmus#include <LayoutUtils.h>
244a2da425SStephan Aßmus#include <Locale.h>
257ff74a7bSStephan Aßmus#include <MenuBar.h>
26803d0234SStephan Aßmus#include <MenuField.h>
275b9ea6c3SJérôme Duval#include <Path.h>
2835d3acb2SJérôme Duval#include <PopUpMenu.h>
2935d3acb2SJérôme Duval#include <Roster.h>
307ff74a7bSStephan Aßmus#include <Screen.h>
31803d0234SStephan Aßmus#include <ScrollView.h>
32c4bd44f3SStephan Aßmus#include <SeparatorView.h>
337ff74a7bSStephan Aßmus#include <SpaceLayoutItem.h>
34803d0234SStephan Aßmus#include <StatusBar.h>
358d71ca3eSJérôme Duval#include <String.h>
36803d0234SStephan Aßmus#include <TextView.h>
37b461fb1dSJérôme Duval#include <TranslationUtils.h>
38ed7081f7SStephan Aßmus#include <TranslatorFormats.h>
393e3d7acbSStephan Aßmus
407ff74a7bSStephan Aßmus#include "tracker_private.h"
417ff74a7bSStephan Aßmus
423e3d7acbSStephan Aßmus#include "DialogPane.h"
43fb5f0bb1SIngo Weinhold#include "InstallerDefs.h"
44803d0234SStephan Aßmus#include "PackageViews.h"
455b9ea6c3SJérôme Duval#include "PartitionMenuItem.h"
46b4afa663SStephan Aßmus#include "WorkerThread.h"
476ffb6a6eSJérôme Duval
483e3d7acbSStephan Aßmus
49546208a5SOliver Tappe#undef B_TRANSLATION_CONTEXT
50546208a5SOliver Tappe#define B_TRANSLATION_CONTEXT "InstallerWindow"
514a2da425SStephan Aßmus
52b76ca311SAxel Dörfler
533feabba6SAxel Dörflerstatic const char* kDriveSetupSignature = "application/x-vnd.Haiku-DriveSetup";
543feabba6SAxel Dörflerstatic const char* kBootManagerSignature
553feabba6SAxel Dörfler	= "application/x-vnd.Haiku-BootManager";
5635d3acb2SJérôme Duval
5735d3acb2SJérôme Duvalconst uint32 BEGIN_MESSAGE = 'iBGN';
5835d3acb2SJérôme Duvalconst uint32 SHOW_BOTTOM_MESSAGE = 'iSBT';
592061b030SStephan Aßmusconst uint32 LAUNCH_DRIVE_SETUP = 'iSEP';
602061b030SStephan Aßmusconst uint32 LAUNCH_BOOTMAN = 'iWBM';
615b9ea6c3SJérôme Duvalconst uint32 START_SCAN = 'iSSC';
6261b3e949SJérôme Duvalconst uint32 PACKAGE_CHECKBOX = 'iPCB';
630da53e3dSPhilippe Saint-Pierreconst uint32 ENCOURAGE_DRIVESETUP = 'iENC';
64d98ceebbSJérôme Duval
65b76ca311SAxel Dörfler
662384ec28SStephan Aßmusclass LogoView : public BView {
672384ec28SStephan Aßmuspublic:
682384ec28SStephan Aßmus								LogoView(const BRect& frame);
692384ec28SStephan Aßmus								LogoView();
702384ec28SStephan Aßmus	virtual						~LogoView();
712384ec28SStephan Aßmus
722384ec28SStephan Aßmus	virtual	void				Draw(BRect update);
732384ec28SStephan Aßmus
74e904ecc9SMatt Madia	virtual	void				GetPreferredSize(float* _width,
75e904ecc9SMatt Madia									float* _height);
762384ec28SStephan Aßmus
772384ec28SStephan Aßmusprivate:
782384ec28SStephan Aßmus			void				_Init();
792384ec28SStephan Aßmus
802384ec28SStephan Aßmus			BBitmap*			fLogo;
81b461fb1dSJérôme Duval};
82b461fb1dSJérôme Duval
83b461fb1dSJérôme Duval
842384ec28SStephan AßmusLogoView::LogoView(const BRect& frame)
852384ec28SStephan Aßmus	:
867ff74a7bSStephan Aßmus	BView(frame, "logoview", B_FOLLOW_LEFT | B_FOLLOW_TOP,
877ff74a7bSStephan Aßmus		B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE)
88b461fb1dSJérôme Duval{
892384ec28SStephan Aßmus	_Init();
902384ec28SStephan Aßmus}
912384ec28SStephan Aßmus
922384ec28SStephan Aßmus
932384ec28SStephan AßmusLogoView::LogoView()
942384ec28SStephan Aßmus	:
957ff74a7bSStephan Aßmus	BView("logoview", B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE)
962384ec28SStephan Aßmus{
972384ec28SStephan Aßmus	_Init();
98b461fb1dSJérôme Duval}
99b461fb1dSJérôme Duval
100b461fb1dSJérôme Duval
101b461fb1dSJérôme DuvalLogoView::~LogoView(void)
102b461fb1dSJérôme Duval{
103b461fb1dSJérôme Duval	delete fLogo;
104b461fb1dSJérôme Duval}
105b461fb1dSJérôme Duval
106b461fb1dSJérôme Duval
107b461fb1dSJérôme Duvalvoid
108b461fb1dSJérôme DuvalLogoView::Draw(BRect update)
109b461fb1dSJérôme Duval{
1102384ec28SStephan Aßmus	if (fLogo == NULL)
1112384ec28SStephan Aßmus		return;
1122384ec28SStephan Aßmus
1132384ec28SStephan Aßmus	BRect bounds(Bounds());
1142384ec28SStephan Aßmus	BPoint placement;
1152384ec28SStephan Aßmus	placement.x = (bounds.left + bounds.right - fLogo->Bounds().Width()) / 2;
1162384ec28SStephan Aßmus	placement.y = (bounds.top + bounds.bottom - fLogo->Bounds().Height()) / 2;
1172384ec28SStephan Aßmus
1182384ec28SStephan Aßmus	DrawBitmap(fLogo, placement);
1192384ec28SStephan Aßmus}
1202384ec28SStephan Aßmus
1212384ec28SStephan Aßmus
1222384ec28SStephan Aßmusvoid
1232384ec28SStephan AßmusLogoView::GetPreferredSize(float* _width, float* _height)
1242384ec28SStephan Aßmus{
1252384ec28SStephan Aßmus	float width = 0.0;
1262384ec28SStephan Aßmus	float height = 0.0;
1272384ec28SStephan Aßmus	if (fLogo) {
1282384ec28SStephan Aßmus		width = fLogo->Bounds().Width();
1292384ec28SStephan Aßmus		height = fLogo->Bounds().Height();
1302384ec28SStephan Aßmus	}
1312384ec28SStephan Aßmus	if (_width)
1322384ec28SStephan Aßmus		*_width = width;
1332384ec28SStephan Aßmus	if (_height)
1342384ec28SStephan Aßmus		*_height = height;
1352384ec28SStephan Aßmus}
1362384ec28SStephan Aßmus
1372384ec28SStephan Aßmus
1382384ec28SStephan Aßmusvoid
1392384ec28SStephan AßmusLogoView::_Init()
1402384ec28SStephan Aßmus{
1412873f50aSMatt Madia	fLogo = BTranslationUtils::GetBitmap(B_PNG_FORMAT, "logo.png");
142b461fb1dSJérôme Duval}
143b461fb1dSJérôme Duval
144b461fb1dSJérôme Duval
145ed7081f7SStephan Aßmus// #pragma mark -
146ed7081f7SStephan Aßmus
147ed7081f7SStephan Aßmus
148803d0234SStephan Aßmusstatic BLayoutItem*
149803d0234SStephan Aßmuslayout_item_for(BView* view)
150803d0234SStephan Aßmus{
151803d0234SStephan Aßmus	BLayout* layout = view->Parent()->GetLayout();
152803d0234SStephan Aßmus	int32 index = layout->IndexOfView(view);
153803d0234SStephan Aßmus	return layout->ItemAt(index);
154803d0234SStephan Aßmus}
155803d0234SStephan Aßmus
156803d0234SStephan Aßmus
1577ff74a7bSStephan AßmusInstallerWindow::InstallerWindow()
158825c2d76SJonas Sundström	:
159825c2d76SJonas Sundström	BWindow(BRect(-2000, -2000, -1800, -1800),
160560ff447SJonas Sundström		B_TRANSLATE_SYSTEM_NAME("Installer"), B_TITLED_WINDOW,
1611565964aSMatt Madia		B_NOT_ZOOMABLE | B_AUTO_UPDATE_SIZE_LIMITS),
1622e6fb5f2SStephan Aßmus	fEncouragedToSetupPartitions(false),
1638b357f8aSJérôme Duval	fDriveSetupLaunched(false),
1643feabba6SAxel Dörfler	fBootManagerLaunched(false),
165739dbdfaSJérôme Duval	fInstallStatus(kReadyForInstall),
166b4afa663SStephan Aßmus	fWorkerThread(new WorkerThread(this)),
167d7737cc8SStephan Aßmus	fCopyEngineCancelSemaphore(-1)
1686ffb6a6eSJérôme Duval{
1691565964aSMatt Madia	if (!be_roster->IsRunning(kTrackerSignature))
1701565964aSMatt Madia		SetWorkspaces(B_ALL_WORKSPACES);
1711565964aSMatt Madia
1727ff74a7bSStephan Aßmus	LogoView* logoView = new LogoView();
1737ff74a7bSStephan Aßmus
174e904ecc9SMatt Madia	fStatusView = new BTextView("statusView", be_plain_font, NULL,
175e904ecc9SMatt Madia		B_WILL_DRAW);
176fa19dd44Slooncraz	fStatusView->SetViewColor(255, 255, 255, 255);
177d0ac6099SHumdinger	fStatusView->SetInsets(10, 0, 10, 0);
17835d3acb2SJérôme Duval	fStatusView->MakeEditable(false);
17935d3acb2SJérôme Duval	fStatusView->MakeSelectable(false);
18035d3acb2SJérôme Duval
1817ff74a7bSStephan Aßmus	BSize logoSize = logoView->MinSize();
1829b4593e3SStephan Aßmus	logoView->SetExplicitMaxSize(logoSize);
183693eccccSRyan Leavengood	fStatusView->SetExplicitMinSize(BSize(logoSize.width * 0.8,
184a3e22cdaSAugustin Cavalier		logoSize.height));
1859f3d8cb6SJérôme Duval
186693eccccSRyan Leavengood	// Explicitly create group view to set the background white in case
187693eccccSRyan Leavengood	// height resizing is needed for the status view
188a3e22cdaSAugustin Cavalier	fLogoGroup = new BGroupView(B_HORIZONTAL, 0);
189a3e22cdaSAugustin Cavalier	fLogoGroup->SetViewColor(255, 255, 255);
190a3e22cdaSAugustin Cavalier	fLogoGroup->GroupLayout()->AddView(logoView);
191a3e22cdaSAugustin Cavalier	fLogoGroup->GroupLayout()->AddView(fStatusView);
192693eccccSRyan Leavengood
193e904ecc9SMatt Madia	fDestMenu = new BPopUpMenu(B_TRANSLATE("scanning" B_UTF8_ELLIPSIS),
194e904ecc9SMatt Madia		true, false);
195e904ecc9SMatt Madia	fSrcMenu = new BPopUpMenu(B_TRANSLATE("scanning" B_UTF8_ELLIPSIS),
196e904ecc9SMatt Madia		true, false);
19735d3acb2SJérôme Duval
198e904ecc9SMatt Madia	fSrcMenuField = new BMenuField("srcMenuField",
19910dfe897SAxel Dörfler		B_TRANSLATE("Install from:"), fSrcMenu);
200b461fb1dSJérôme Duval	fSrcMenuField->SetAlignment(B_ALIGN_RIGHT);
20135d3acb2SJérôme Duval
202e904ecc9SMatt Madia	fDestMenuField = new BMenuField("destMenuField", B_TRANSLATE("Onto:"),
20310dfe897SAxel Dörfler		fDestMenu);
20435d3acb2SJérôme Duval	fDestMenuField->SetAlignment(B_ALIGN_RIGHT);
2057ff74a7bSStephan Aßmus
206803d0234SStephan Aßmus	fPackagesSwitch = new PaneSwitch("options_button");
207e904ecc9SMatt Madia	fPackagesSwitch->SetLabels(B_TRANSLATE("Hide optional packages"),
208e904ecc9SMatt Madia		B_TRANSLATE("Show optional packages"));
209803d0234SStephan Aßmus	fPackagesSwitch->SetMessage(new BMessage(SHOW_BOTTOM_MESSAGE));
210803d0234SStephan Aßmus	fPackagesSwitch->SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED,
2119b4593e3SStephan Aßmus		B_SIZE_UNSET));
212803d0234SStephan Aßmus	fPackagesSwitch->SetExplicitAlignment(BAlignment(B_ALIGN_LEFT,
213803d0234SStephan Aßmus		B_ALIGN_TOP));
214803d0234SStephan Aßmus
215803d0234SStephan Aßmus	fPackagesView = new PackagesView("packages_view");
216803d0234SStephan Aßmus	BScrollView* packagesScrollView = new BScrollView("packagesScroll",
217803d0234SStephan Aßmus		fPackagesView, B_WILL_DRAW, false, true);
218803d0234SStephan Aßmus
2197ff74a7bSStephan Aßmus	const char* requiredDiskSpaceString
220e904ecc9SMatt Madia		= B_TRANSLATE("Additional disk space required: 0.0 KiB");
2217ff74a7bSStephan Aßmus	fSizeView = new BStringView("size_view", requiredDiskSpaceString);
22261b3e949SJérôme Duval	fSizeView->SetAlignment(B_ALIGN_RIGHT);
2237ff74a7bSStephan Aßmus	fSizeView->SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, B_SIZE_UNLIMITED));
2247ff74a7bSStephan Aßmus	fSizeView->SetExplicitAlignment(
2257ff74a7bSStephan Aßmus		BAlignment(B_ALIGN_RIGHT, B_ALIGN_MIDDLE));
2267ff74a7bSStephan Aßmus
227e904ecc9SMatt Madia	fProgressBar = new BStatusBar("progress",
228e904ecc9SMatt Madia		B_TRANSLATE("Install progress:  "));
229803d0234SStephan Aßmus	fProgressBar->SetMaxValue(100.0);
230803d0234SStephan Aßmus
231e904ecc9SMatt Madia	fBeginButton = new BButton("begin_button", B_TRANSLATE("Begin"),
232803d0234SStephan Aßmus		new BMessage(BEGIN_MESSAGE));
233803d0234SStephan Aßmus	fBeginButton->MakeDefault(true);
234803d0234SStephan Aßmus	fBeginButton->SetEnabled(false);
235803d0234SStephan Aßmus
2362061b030SStephan Aßmus	fLaunchDriveSetupButton = new BButton("setup_button",
237e904ecc9SMatt Madia		B_TRANSLATE("Set up partitions" B_UTF8_ELLIPSIS),
2382061b030SStephan Aßmus		new BMessage(LAUNCH_DRIVE_SETUP));
2392061b030SStephan Aßmus
2403feabba6SAxel Dörfler	fLaunchBootManagerItem = new BMenuItem(B_TRANSLATE("Set up boot menu"),
241c89c29e7SStephan Aßmus		new BMessage(LAUNCH_BOOTMAN));
2423feabba6SAxel Dörfler	fLaunchBootManagerItem->SetEnabled(false);
243803d0234SStephan Aßmus
244e904ecc9SMatt Madia	fMakeBootableItem = new BMenuItem(B_TRANSLATE("Write boot sector"),
245c89c29e7SStephan Aßmus		new BMessage(MSG_WRITE_BOOT_SECTOR));
246c89c29e7SStephan Aßmus	fMakeBootableItem->SetEnabled(false);
247c89c29e7SStephan Aßmus	BMenuBar* mainMenu = new BMenuBar("main menu");
248e904ecc9SMatt Madia	BMenu* toolsMenu = new BMenu(B_TRANSLATE("Tools"));
2493feabba6SAxel Dörfler	toolsMenu->AddItem(fLaunchBootManagerItem);
250c89c29e7SStephan Aßmus	toolsMenu->AddItem(fMakeBootableItem);
251c89c29e7SStephan Aßmus	mainMenu->AddItem(toolsMenu);
252c89c29e7SStephan Aßmus
2535dcd3cd1SHannah Boneß	BLayoutBuilder::Group<>(this, B_VERTICAL, 0)
254c89c29e7SStephan Aßmus		.Add(mainMenu)
255a3e22cdaSAugustin Cavalier		.Add(fLogoGroup)
256c4bd44f3SStephan Aßmus		.Add(new BSeparatorView(B_HORIZONTAL, B_PLAIN_BORDER))
257d0ac6099SHumdinger		.AddGroup(B_VERTICAL, B_USE_ITEM_SPACING)
258d0ac6099SHumdinger			.SetInsets(B_USE_WINDOW_SPACING)
259d0ac6099SHumdinger			.AddGrid(new BGridView(B_USE_ITEM_SPACING, B_USE_ITEM_SPACING))
2607ff74a7bSStephan Aßmus				.Add(fSrcMenuField->CreateLabelLayoutItem(), 0, 0)
2617ff74a7bSStephan Aßmus				.Add(fSrcMenuField->CreateMenuBarLayoutItem(), 1, 0)
2627ff74a7bSStephan Aßmus				.Add(fDestMenuField->CreateLabelLayoutItem(), 0, 1)
2637ff74a7bSStephan Aßmus				.Add(fDestMenuField->CreateMenuBarLayoutItem(), 1, 1)
2647ff74a7bSStephan Aßmus
2657ff74a7bSStephan Aßmus				.Add(BSpaceLayoutItem::CreateVerticalStrut(5), 0, 2, 2)
2667ff74a7bSStephan Aßmus
267803d0234SStephan Aßmus				.Add(fPackagesSwitch, 0, 3, 2)
2687ff74a7bSStephan Aßmus				.Add(packagesScrollView, 0, 4, 2)
269803d0234SStephan Aßmus				.Add(fProgressBar, 0, 5, 2)
270803d0234SStephan Aßmus				.Add(fSizeView, 0, 6, 2)
2715dcd3cd1SHannah Boneß			.End()
2727ff74a7bSStephan Aßmus
273d0ac6099SHumdinger			.AddGroup(B_HORIZONTAL, B_USE_WINDOW_SPACING)
2742061b030SStephan Aßmus				.Add(fLaunchDriveSetupButton)
2757ff74a7bSStephan Aßmus				.AddGlue()
2765dcd3cd1SHannah Boneß				.Add(fBeginButton);
2777ff74a7bSStephan Aßmus
278803d0234SStephan Aßmus	// Make the optional packages and progress bar invisible on start
279803d0234SStephan Aßmus	fPackagesLayoutItem = layout_item_for(packagesScrollView);
280803d0234SStephan Aßmus	fPkgSwitchLayoutItem = layout_item_for(fPackagesSwitch);
281803d0234SStephan Aßmus	fSizeViewLayoutItem = layout_item_for(fSizeView);
282803d0234SStephan Aßmus	fProgressLayoutItem = layout_item_for(fProgressBar);
2837ff74a7bSStephan Aßmus
2847ff74a7bSStephan Aßmus	fPackagesLayoutItem->SetVisible(false);
2857ff74a7bSStephan Aßmus	fSizeViewLayoutItem->SetVisible(false);
286803d0234SStephan Aßmus	fProgressLayoutItem->SetVisible(false);
28761b3e949SJérôme Duval
2883b569698SStephan Aßmus	// Setup tool tips for the non-obvious features
2892061b030SStephan Aßmus	fLaunchDriveSetupButton->SetToolTip(
290e904ecc9SMatt Madia		B_TRANSLATE("Launch the DriveSetup utility to partition\n"
2913b569698SStephan Aßmus		"available hard drives and other media.\n"
2923b569698SStephan Aßmus		"Partitions can be initialized with the\n"
2933b569698SStephan Aßmus		"Be File System needed for a Haiku boot\n"
2944a2da425SStephan Aßmus		"partition."));
2953feabba6SAxel Dörfler//	fLaunchBootManagerItem->SetToolTip(
296e904ecc9SMatt Madia//		B_TRANSLATE("Install or uninstall the Haiku boot menu, which allows "
297e904ecc9SMatt Madia//		"to choose an operating system to boot when the computer starts.\n"
298c89c29e7SStephan Aßmus//		"If this computer already has a boot manager such as GRUB installed, "
299c89c29e7SStephan Aßmus//		"it is better to add Haiku to that menu than to overwrite it."));
300c89c29e7SStephan Aßmus//	fMakeBootableItem->SetToolTip(
301e904ecc9SMatt Madia//		B_TRANSLATE("Writes the Haiku boot code to the partition start\n"
302c89c29e7SStephan Aßmus//		"sector. This step is automatically performed by\n"
303c89c29e7SStephan Aßmus//		"the installation, but you can manually make a\n"
304c89c29e7SStephan Aßmus//		"partition bootable in case you do not need to\n"
305c89c29e7SStephan Aßmus//		"perform an installation."));
3063b569698SStephan Aßmus
3076ffb6a6eSJérôme Duval	// finish creating window
3087ff74a7bSStephan Aßmus	if (!be_roster->IsRunning(kDeskbarSignature))
3097ff74a7bSStephan Aßmus		SetFlags(Flags() | B_NOT_MINIMIZABLE);
3107ff74a7bSStephan Aßmus
31133eed030SJonas Sundström	CenterOnScreen();
3126ffb6a6eSJérôme Duval	Show();
31335d3acb2SJérôme Duval
3142061b030SStephan Aßmus	// Register to receive notifications when apps launch or quit...
3152061b030SStephan Aßmus	be_roster->StartWatching(this);
3162061b030SStephan Aßmus	// ... and check the two we are interested in.
3173feabba6SAxel Dörfler	fDriveSetupLaunched = be_roster->IsRunning(kDriveSetupSignature);
3183feabba6SAxel Dörfler	fBootManagerLaunched = be_roster->IsRunning(kBootManagerSignature);
319e904ecc9SMatt Madia
3207ff74a7bSStephan Aßmus	if (Lock()) {
3212061b030SStephan Aßmus		fLaunchDriveSetupButton->SetEnabled(!fDriveSetupLaunched);
3223feabba6SAxel Dörfler		fLaunchBootManagerItem->SetEnabled(!fBootManagerLaunched);
3237ff74a7bSStephan Aßmus		Unlock();
3247ff74a7bSStephan Aßmus	}
3257ff74a7bSStephan Aßmus
3265b9ea6c3SJérôme Duval	PostMessage(START_SCAN);
3276ffb6a6eSJérôme Duval}
3286ffb6a6eSJérôme Duval
3297ff74a7bSStephan Aßmus
3306ffb6a6eSJérôme DuvalInstallerWindow::~InstallerWindow()
3316ffb6a6eSJérôme Duval{
332d7737cc8SStephan Aßmus	_SetCopyEngineCancelSemaphore(-1);
33335d3acb2SJérôme Duval	be_roster->StopWatching(this);
3346ffb6a6eSJérôme Duval}
3356ffb6a6eSJérôme Duval
3366ffb6a6eSJérôme Duval
3376ffb6a6eSJérôme Duvalvoid
3386ffb6a6eSJérôme DuvalInstallerWindow::MessageReceived(BMessage *msg)
3396ffb6a6eSJérôme Duval{
3406ffb6a6eSJérôme Duval	switch (msg->what) {
341b4afa663SStephan Aßmus		case MSG_RESET:
34292cd10f4SStephan Aßmus		{
343d7737cc8SStephan Aßmus			_SetCopyEngineCancelSemaphore(-1);
344803d0234SStephan Aßmus
34592cd10f4SStephan Aßmus			status_t error;
34692cd10f4SStephan Aßmus			if (msg->FindInt32("error", &error) == B_OK) {
34792cd10f4SStephan Aßmus				char errorMessage[2048];
348e904ecc9SMatt Madia				snprintf(errorMessage, sizeof(errorMessage),
349e904ecc9SMatt Madia					B_TRANSLATE("An error was encountered and the "
350e904ecc9SMatt Madia					"installation was not completed:\n\n"
3514a2da425SStephan Aßmus					"Error:  %s"), strerror(error));
352aed35104SHumdinger				BAlert* alert = new BAlert("error", errorMessage, B_TRANSLATE("OK"));
353aed35104SHumdinger				alert->SetFlags(alert->Flags() | B_CLOSE_ON_ESCAPE);
354aed35104SHumdinger				alert->Go();
35592cd10f4SStephan Aßmus			}
35692cd10f4SStephan Aßmus
35759029801SStephan Aßmus			_DisableInterface(false);
358803d0234SStephan Aßmus
359803d0234SStephan Aßmus			fProgressLayoutItem->SetVisible(false);
360803d0234SStephan Aßmus			fPkgSwitchLayoutItem->SetVisible(true);
361803d0234SStephan Aßmus			_ShowOptionalPackages();
362f76e944eSStephan Aßmus			_UpdateControls();
363739dbdfaSJérôme Duval			break;
36492cd10f4SStephan Aßmus		}
3655b9ea6c3SJérôme Duval		case START_SCAN:
36659029801SStephan Aßmus			_ScanPartitions();
3675b9ea6c3SJérôme Duval			break;
3689f3d8cb6SJérôme Duval		case BEGIN_MESSAGE:
369739dbdfaSJérôme Duval			switch (fInstallStatus) {
370739dbdfaSJérôme Duval				case kReadyForInstall:
371739dbdfaSJérôme Duval				{
372348d9eacSIngo Weinhold					// get source and target
373348d9eacSIngo Weinhold					PartitionMenuItem* targetItem
374348d9eacSIngo Weinhold						= (PartitionMenuItem*)fDestMenu->FindMarked();
375348d9eacSIngo Weinhold					PartitionMenuItem* srcItem
376348d9eacSIngo Weinhold						= (PartitionMenuItem*)fSrcMenu->FindMarked();
377348d9eacSIngo Weinhold					if (srcItem == NULL || targetItem == NULL)
378348d9eacSIngo Weinhold						break;
379348d9eacSIngo Weinhold
380d7737cc8SStephan Aßmus					_SetCopyEngineCancelSemaphore(create_sem(1,
381d7737cc8SStephan Aßmus						"copy engine cancel"));
382d7737cc8SStephan Aßmus
3837a65816aSStephan Aßmus					BList* list = new BList();
384739dbdfaSJérôme Duval					int32 size = 0;
385739dbdfaSJérôme Duval					fPackagesView->GetPackagesToInstall(list, &size);
386d7737cc8SStephan Aßmus					fWorkerThread->SetLock(fCopyEngineCancelSemaphore);
387b4afa663SStephan Aßmus					fWorkerThread->SetPackagesList(list);
388b4afa663SStephan Aßmus					fWorkerThread->SetSpaceRequired(size);
3895d6a2a65SJérôme Duval					fInstallStatus = kInstalling;
390348d9eacSIngo Weinhold					fWorkerThread->StartInstall(srcItem->ID(),
391348d9eacSIngo Weinhold						targetItem->ID());
392e904ecc9SMatt Madia					fBeginButton->SetLabel(B_TRANSLATE("Stop"));
39359029801SStephan Aßmus					_DisableInterface(true);
394803d0234SStephan Aßmus
395803d0234SStephan Aßmus					fProgressBar->SetTo(0.0, NULL, NULL);
396803d0234SStephan Aßmus
397803d0234SStephan Aßmus					fPkgSwitchLayoutItem->SetVisible(false);
398803d0234SStephan Aßmus					fPackagesLayoutItem->SetVisible(false);
399803d0234SStephan Aßmus					fSizeViewLayoutItem->SetVisible(false);
400803d0234SStephan Aßmus					fProgressLayoutItem->SetVisible(true);
401739dbdfaSJérôme Duval					break;
402739dbdfaSJérôme Duval				}
403739dbdfaSJérôme Duval				case kInstalling:
404803d0234SStephan Aßmus				{
405803d0234SStephan Aßmus					_QuitCopyEngine(true);
406739dbdfaSJérôme Duval					break;
407803d0234SStephan Aßmus				}
408739dbdfaSJérôme Duval				case kFinished:
409739dbdfaSJérôme Duval					PostMessage(B_QUIT_REQUESTED);
410739dbdfaSJérôme Duval					break;
411739dbdfaSJérôme Duval				case kCancelled:
412739dbdfaSJérôme Duval					break;
413739dbdfaSJérôme Duval			}
414d98ceebbSJérôme Duval			break;
415d98ceebbSJérôme Duval		case SHOW_BOTTOM_MESSAGE:
41659029801SStephan Aßmus			_ShowOptionalPackages();
417d98ceebbSJérôme Duval			break;
4185c7514c3SStephan Aßmus		case SOURCE_PARTITION:
41959029801SStephan Aßmus			_PublishPackages();
4207a65816aSStephan Aßmus			_UpdateControls();
4211eedf230SJérôme Duval			break;
4221eedf230SJérôme Duval		case TARGET_PARTITION:
4237a65816aSStephan Aßmus			_UpdateControls();
4245b9ea6c3SJérôme Duval			break;
4252061b030SStephan Aßmus		case LAUNCH_DRIVE_SETUP:
42659029801SStephan Aßmus			_LaunchDriveSetup();
42735d3acb2SJérôme Duval			break;
4282061b030SStephan Aßmus		case LAUNCH_BOOTMAN:
4293feabba6SAxel Dörfler			_LaunchBootManager();
4302061b030SStephan Aßmus			break;
431803d0234SStephan Aßmus		case PACKAGE_CHECKBOX:
432803d0234SStephan Aßmus		{
43361b3e949SJérôme Duval			char buffer[15];
43448d79657SStephan Aßmus			fPackagesView->GetTotalSizeAsString(buffer, sizeof(buffer));
43548d79657SStephan Aßmus			char string[256];
43648d79657SStephan Aßmus			snprintf(string, sizeof(string),
437e904ecc9SMatt Madia				B_TRANSLATE("Additional disk space required: %s"), buffer);
43861b3e949SJérôme Duval			fSizeView->SetText(string);
43961b3e949SJérôme Duval			break;
44061b3e949SJérôme Duval		}
4410da53e3dSPhilippe Saint-Pierre		case ENCOURAGE_DRIVESETUP:
4420da53e3dSPhilippe Saint-Pierre		{
443aed35104SHumdinger			BAlert* alert = new BAlert("use drive setup", B_TRANSLATE("No partitions have "
444e904ecc9SMatt Madia				"been found that are suitable for installation. Please set "
445e904ecc9SMatt Madia				"up partitions and initialize at least one partition with the "
446aed35104SHumdinger				"Be File System."), B_TRANSLATE("OK"));
447aed35104SHumdinger			alert->SetFlags(alert->Flags() | B_CLOSE_ON_ESCAPE);
448aed35104SHumdinger			alert->Go();
4496b418363SPhilippe Saint-Pierre			break;
4500da53e3dSPhilippe Saint-Pierre		}
451b4afa663SStephan Aßmus		case MSG_STATUS_MESSAGE:
452803d0234SStephan Aßmus		{
4537b293a3eSStephan Aßmus// TODO: Was this supposed to prevent status messages still arriving
4547b293a3eSStephan Aßmus// after the copy engine was shut down?
4557b293a3eSStephan Aßmus//			if (fInstallStatus != kInstalling)
4567b293a3eSStephan Aßmus//				break;
457803d0234SStephan Aßmus			float progress;
458803d0234SStephan Aßmus			if (msg->FindFloat("progress", &progress) == B_OK) {
459803d0234SStephan Aßmus				const char* currentItem;
4604a2da425SStephan Aßmus				if (msg->FindString("item", &currentItem) != B_OK) {
461e904ecc9SMatt Madia					currentItem = B_TRANSLATE_COMMENT("???",
4624a2da425SStephan Aßmus						"Unknown currently copied item");
4634a2da425SStephan Aßmus				}
464803d0234SStephan Aßmus				BString trailingLabel;
465803d0234SStephan Aßmus				int32 currentCount;
466803d0234SStephan Aßmus				int32 maximumCount;
467803d0234SStephan Aßmus				if (msg->FindInt32("current", &currentCount) == B_OK
468803d0234SStephan Aßmus					&& msg->FindInt32("maximum", &maximumCount) == B_OK) {
4694a2da425SStephan Aßmus					char buffer[64];
470e904ecc9SMatt Madia					snprintf(buffer, sizeof(buffer),
471e904ecc9SMatt Madia						B_TRANSLATE_COMMENT("%1ld of %2ld",
472e904ecc9SMatt Madia							"number of files copied"),
473e904ecc9SMatt Madia						currentCount, maximumCount);
4744a2da425SStephan Aßmus					trailingLabel << buffer;
475803d0234SStephan Aßmus				} else {
476e904ecc9SMatt Madia					trailingLabel <<
477e904ecc9SMatt Madia						B_TRANSLATE_COMMENT("?? of ??", "Unknown progress");
478803d0234SStephan Aßmus				}
479803d0234SStephan Aßmus				fProgressBar->SetTo(progress, currentItem,
480803d0234SStephan Aßmus					trailingLabel.String());
481803d0234SStephan Aßmus			} else {
482803d0234SStephan Aßmus				const char *status;
483803d0234SStephan Aßmus				if (msg->FindString("status", &status) == B_OK) {
484803d0234SStephan Aßmus					fLastStatus = fStatusView->Text();
485803d0234SStephan Aßmus					_SetStatusMessage(status);
486803d0234SStephan Aßmus				} else
487803d0234SStephan Aßmus					_SetStatusMessage(fLastStatus.String());
488803d0234SStephan Aßmus			}
4896806f7f8SJérôme Duval			break;
49046065378SJérôme Duval		}
491b4afa663SStephan Aßmus		case MSG_INSTALL_FINISHED:
4927b293a3eSStephan Aßmus		{
493e904ecc9SMatt Madia
494d7737cc8SStephan Aßmus			_SetCopyEngineCancelSemaphore(-1);
495803d0234SStephan Aßmus
4967b293a3eSStephan Aßmus			PartitionMenuItem* dstItem
4977b293a3eSStephan Aßmus				= (PartitionMenuItem*)fDestMenu->FindMarked();
4988323a7cdSStephan Aßmus
499a3e22cdaSAugustin Cavalier			BString status;
5004a2da425SStephan Aßmus			if (be_roster->IsRunning(kDeskbarSignature)) {
501d52b839eSRyan Leavengood				fBeginButton->SetLabel(B_TRANSLATE("Quit"));
502a3e22cdaSAugustin Cavalier				status.SetToFormat(B_TRANSLATE("Installation "
503e904ecc9SMatt Madia					"completed. Boot sector has been written to '%s'. Press "
504e904ecc9SMatt Madia					"Quit to leave the Installer or choose a new target "
505e904ecc9SMatt Madia					"volume to perform another installation."),
506e904ecc9SMatt Madia					dstItem ? dstItem->Name() : B_TRANSLATE_COMMENT("???",
5074a2da425SStephan Aßmus						"Unknown partition name"));
5084a2da425SStephan Aßmus			} else {
509d52b839eSRyan Leavengood				fBeginButton->SetLabel(B_TRANSLATE("Restart"));
510a3e22cdaSAugustin Cavalier				status.SetToFormat(B_TRANSLATE("Installation "
511e904ecc9SMatt Madia					"completed. Boot sector has been written to '%s'. Press "
512d52b839eSRyan Leavengood					"Restart to restart the computer or choose a new target "
513e904ecc9SMatt Madia					"volume to perform another installation."),
514e904ecc9SMatt Madia					dstItem ? dstItem->Name() : B_TRANSLATE_COMMENT("???",
5154a2da425SStephan Aßmus						"Unknown partition name"));
5164a2da425SStephan Aßmus			}
5174a2da425SStephan Aßmus
518a3e22cdaSAugustin Cavalier			_SetStatusMessage(status.String());
519739dbdfaSJérôme Duval			fInstallStatus = kFinished;
52059029801SStephan Aßmus			_DisableInterface(false);
521803d0234SStephan Aßmus			fProgressLayoutItem->SetVisible(false);
522803d0234SStephan Aßmus			fPkgSwitchLayoutItem->SetVisible(true);
523803d0234SStephan Aßmus			_ShowOptionalPackages();
524bc1301d3SJérôme Duval			break;
5257b293a3eSStephan Aßmus		}
52635d3acb2SJérôme Duval		case B_SOME_APP_LAUNCHED:
52735d3acb2SJérôme Duval		case B_SOME_APP_QUIT:
52835d3acb2SJérôme Duval		{
52935d3acb2SJérôme Duval			const char *signature;
5302061b030SStephan Aßmus			if (msg->FindString("be:signature", &signature) != B_OK)
5312061b030SStephan Aßmus				break;
5323feabba6SAxel Dörfler			bool isDriveSetup = !strcasecmp(signature, kDriveSetupSignature);
5333feabba6SAxel Dörfler			bool isBootManager = !strcasecmp(signature, kBootManagerSignature);
5343feabba6SAxel Dörfler			if (isDriveSetup || isBootManager) {
5352061b030SStephan Aßmus				bool scanPartitions = false;
5362061b030SStephan Aßmus				if (isDriveSetup) {
537e904ecc9SMatt Madia					bool launched = msg->what == B_SOME_APP_LAUNCHED;
5382061b030SStephan Aßmus					// We need to scan partitions if DriveSetup has quit.
5392061b030SStephan Aßmus					scanPartitions = fDriveSetupLaunched && !launched;
5402061b030SStephan Aßmus					fDriveSetupLaunched = launched;
5412061b030SStephan Aßmus				}
5423feabba6SAxel Dörfler				if (isBootManager)
5433feabba6SAxel Dörfler					fBootManagerLaunched = msg->what == B_SOME_APP_LAUNCHED;
5442061b030SStephan Aßmus
5452061b030SStephan Aßmus				fBeginButton->SetEnabled(
5463feabba6SAxel Dörfler					!fDriveSetupLaunched && !fBootManagerLaunched);
5473feabba6SAxel Dörfler				_DisableInterface(fDriveSetupLaunched || fBootManagerLaunched);
5483feabba6SAxel Dörfler				if (fDriveSetupLaunched && fBootManagerLaunched) {
549e904ecc9SMatt Madia					_SetStatusMessage(B_TRANSLATE("Running Boot Manager and "
5502061b030SStephan Aßmus						"DriveSetup" B_UTF8_ELLIPSIS
5512061b030SStephan Aßmus						"\n\nClose both applications to continue with the "
5522061b030SStephan Aßmus						"installation."));
5532061b030SStephan Aßmus				} else if (fDriveSetupLaunched) {
554e904ecc9SMatt Madia					_SetStatusMessage(B_TRANSLATE("Running DriveSetup"
555e904ecc9SMatt Madia						B_UTF8_ELLIPSIS
5567a65816aSStephan Aßmus						"\n\nClose DriveSetup to continue with the "
5574a2da425SStephan Aßmus						"installation."));
5583feabba6SAxel Dörfler				} else if (fBootManagerLaunched) {
559e904ecc9SMatt Madia					_SetStatusMessage(B_TRANSLATE("Running Boot Manager"
560e904ecc9SMatt Madia						B_UTF8_ELLIPSIS
5612061b030SStephan Aßmus						"\n\nClose Boot Manager to continue with the "
5622061b030SStephan Aßmus						"installation."));
5632061b030SStephan Aßmus				} else {
564