Index: src/preferences/drivesetup/MainWindow.h
===================================================================
--- src/preferences/drivesetup/MainWindow.h	(revision 21777)
+++ src/preferences/drivesetup/MainWindow.h	(working copy)
@@ -7,8 +7,7 @@
 #define MAIN_WINDOW_H
 
 	#define MOUNT_MOUNT_ALL_MSG					'mall'
-	#define MOUNT_MOUNT_SELECTED_MSG			'msel'
-	#define UNMOUNT_UNMOUNT_SELECTED_MSG	'usel'
+	#define MOUNT_TOGGLE_SELECTED_MSG			'msel'
 	#define SETUP_FORMAT_MSG							'sfor'
 	#define SETUP_PARTITION_SELECTED_MSG		'spsl'
 	#define SETUP_INITIALIZE_MSG							'sini'
@@ -17,6 +16,10 @@
 	#define RESCAN_IDE_MSG								'ride'
 	#define RESCAN_SCSI_MSG								'rscs'
 
+	#define PARTITION_SELECTION_CHANGE_MSG						'pchg'
+	#define MOUNT_TOGGLE								'musl'
+	#define UNMOUNT_UNMOUNT_UNMOUNTMENU_SELECTED_MSG					'mmsl'
+
 	#include <interface/Window.h>
 	#include <storage/DiskDeviceRoster.h>
 
@@ -25,6 +28,7 @@
 	class BPartition;
 	class BDiskDevice;
 	class PartitionListView;
+	class DiskSystemMenu;
 	
 	/**
 	 * The main window of the app.
@@ -35,9 +39,40 @@
 	class MainWindow : public BWindow
 	{
 		private:
+			void ScanDevices();
+			void MountAllVisible();
+			
+			void UpdateMenus();
+
+			bool DoEject(BDiskDevice *disk);
+			void DoTest(BPartition *partition);
+			bool DoToggleMount(BPartition *partition, bool only_mount=false);
+
+			void HandlePartition(BMessage *message);
+			void HandleFormat(BMessage *message);
+			void HandleInitialize(BMessage *message);
+
+			void HandleMenuActions(BMessage *message);
+			void HandleMenuMounting(BMessage *message);
+			void HandleSelectionMounting(BMessage *message);
+
 			PosSettings*				fSettings;
 			BDiskDeviceRoster		fDDRoster;
 			PartitionListView*		fListView;
+
+			BMenu*				fMountMenu;
+			BMenu*				fUnMountMenu;
+			BMenu*				fSingleMountMenu;
+
+			BMenu*				fSetupMenu;
+			BMenu*				fOptionsMenu;
+			DiskSystemMenu*			fPartitionMenu;
+			DiskSystemMenu*			fInitializeMenu;
+
+			BMenuItem*			fEjectItem;
+			BMenuItem*			fTestItem;
+			BMenuItem*			fFormatItem;
+
 		public:
 			MainWindow(BRect frame, PosSettings *fSettings);
 			
Index: src/preferences/drivesetup/PosSettings.cpp
===================================================================
--- src/preferences/drivesetup/PosSettings.cpp	(revision 21777)
+++ src/preferences/drivesetup/PosSettings.cpp	(working copy)
@@ -21,35 +21,32 @@
 PosSettings::PosSettings()
 {
 	BPath path;
+        fWindowFrame.Set(32,64,760,240);
+
 	if (find_directory(B_USER_SETTINGS_DIRECTORY,&path) == B_OK)
 	{
 		path.Append(kSettingsFile);
 		BFile file(path.Path(), B_READ_ONLY);
-		if (file.InitCheck() != B_OK)
-			be_app->PostMessage(B_QUIT_REQUESTED);
-		// Now read in the data
-		if (file.Read(&fcorner, sizeof(BPoint)) != sizeof(BPoint))
-			be_app->PostMessage(B_QUIT_REQUESTED);
-		if (file.Read(&brCorner, sizeof(BPoint)) != sizeof(BPoint))
-			be_app->PostMessage(B_QUIT_REQUESTED);
+		if (file.InitCheck())
+		{
+			// Now read in the data
+			if (	file.Read(&fcorner, sizeof(BPoint)) == sizeof(BPoint) &&
+				file.Read(&brCorner, sizeof(BPoint)) == sizeof(BPoint) )
+			{
+				fWindowFrame.left=fcorner.x;
+				fWindowFrame.top=fcorner.y;
+				fWindowFrame.right=brCorner.x;
+				fWindowFrame.bottom=brCorner.y;
+			}
+		}
 	}
-	printf("settings file read.\n");
-	printf("=========================\n");
-	printf("fcorner read in as ");
-	fcorner.PrintToStream();
-	printf("brCorner read in as ");
-	brCorner.PrintToStream();
-
-	fWindowFrame.left=fcorner.x;
-	fWindowFrame.top=fcorner.y;
-	fWindowFrame.right=brCorner.x;
-	fWindowFrame.bottom=brCorner.y;
 	
 	//Check to see if the co-ords of the window are in the range of the Screen
 	BScreen screen;
 		if (screen.Frame().right >= fWindowFrame.right
 			&& screen.Frame().bottom >= fWindowFrame.bottom)
 		return;
+
 	// If they are not, lets just stick the window in the middle
 	// of the screen.
 
@@ -81,5 +78,4 @@
 	fcorner.y=f.top;
 	brCorner.x=f.right;
 	brCorner.y=f.bottom;
-brCorner.PrintToStream();
 }
Index: src/preferences/drivesetup/PartitionList.cpp
===================================================================
--- src/preferences/drivesetup/PartitionList.cpp	(revision 21777)
+++ src/preferences/drivesetup/PartitionList.cpp	(working copy)
@@ -1,74 +1,701 @@
+/*! \file PartitionList.cpp
+ *  \brief Code for the PartitionListView class and its relatives.
+ *  
+ *  This file contains the code for the PartitionListView, BBitmapStringField, 
+ *  PartitionColumn, PartitionListRow and DiskSystemMenu classes.
+ *
+*/
 #include "PartitionList.h"
+#include "MainWindow.h"
 
+#include <interface/Alert.h>
+
 #include <interface/ColumnTypes.h>
+#include <interface/PopUpMenu.h>
+#include <interface/MenuItem.h>
+
 #include <storage/Path.h>
+#include <storage/DiskDeviceVisitor.h>
+#include <storage/DiskSystem.h>
+#include <storage/DiskDevice.h>
 
+#include <storage/Volume.h>
+#include <storage/VolumeRoster.h>
+
+#define kTEXT_MARGIN	8 // also in ColumnListView.cpp
+
 extern const char*
 	SizeAsString(off_t size, char *string);; //FIXME: from MainWindow.cpp
 
 
+const rgb_color kWhite			= { 255, 255, 255, 255 };
+const rgb_color kNormalColor = {150, 150, 150, 255};
+const rgb_color kHighlightColor = {100, 100, 0, 255};
+const rgb_color kSelectionColor = {182, 182, 182, 255};
+const rgb_color kBorderColor = {99, 154, 206, 255};
+
+BBitmapStringField::BBitmapStringField(BBitmap* bitmap, const char *string)
+	: Inherited(string),
+	fBitmap(bitmap)
+{
+
+}
+
+const BBitmap*
+BBitmapStringField::Bitmap()
+{
+	return fBitmap;
+}
+
+void
+BBitmapStringField::SetBitmap(BBitmap* bitmap)
+{
+	fBitmap = bitmap;
+}
+
+
+PartitionMenuItem::PartitionMenuItem(const char *label, BMessage *message,
+		  		     char shortcut, uint32 modifier, 
+				     BPartition *partition, bool unmount)
+	: Inherited(label, message, shortcut, modifier),
+	fPartitionID(partition->ID()),
+	fUnmount(unmount)
+{
+	BPath path;
+	
+	// Unmount items should show the mount point, whereas
+	// Mount items should show the content type & name,
+	// falling back to the device path if neccesary...
+
+	if (fUnmount)
+	{
+		partition->GetMountPoint(&path);
+		SetLabel(path.Path());
+
+		// See if this is the boot volume
+		BVolume volume;
+		BVolume boot_volume;
+		if (BVolumeRoster().GetBootVolume(&boot_volume) == B_OK)
+		{
+			partition->GetVolume(&volume);
+			SetEnabled(volume != boot_volume);
+		}
+	}
+	else
+	{		
+		char mountname[1024];
+
+		const char *real_name = partition->ContentName();
+		if (real_name)
+		{
+			sprintf(mountname, "%s (%s)", partition->ContentType(), partition->ContentName());
+			real_name = mountname;
+		}
+		else
+		{
+			// Its path will do
+			partition->GetPath(&path);
+			real_name = path.Path();
+		}
+
+		SetLabel(real_name);
+		SetEnabled(!partition->IsMounted());
+	}
+}
+
+
+DiskSystemMenu::DiskSystemMenu(	const char *title,
+				bool partitionSystems,
+				menu_layout layout = B_ITEMS_IN_COLUMN)
+	: Inherited(title, layout),
+	  fIteratePartitionSystems(partitionSystems)
+{
+}
+
+void 
+DiskSystemMenu::UpdateSystems(partition_id id)
+{
+	BDiskSystem diskSystem;
+	BDiskDeviceRoster diskRoster;
+
+	RemoveItems(0, CountItems());
+
+	diskRoster.RewindDiskSystems();
+
+	while(diskRoster.GetNextDiskSystem(&diskSystem) == B_OK)
+	{
+		// If we can't initialize it, there's no point in having it
+		if (!diskSystem.SupportsInitializing())
+			continue;
+
+		if (fIteratePartitionSystems && !diskSystem.IsPartitioningSystem())
+			continue;
+
+		if (!fIteratePartitionSystems && !diskSystem.IsFileSystem())
+			continue;
+
+		BString string;
+		string << diskSystem.PrettyName() << B_UTF8_ELLIPSIS;
+
+		BMessage* msg = new BMessage(fIteratePartitionSystems ? SETUP_PARTITION_SELECTED_MSG : SETUP_INITIALIZE_MSG);
+		msg->AddString("bdisksystem:name", diskSystem.Name());
+		AddItem(new BMenuItem(string.String(), msg));
+	}
+}
+
+
+PartitionColumn::PartitionColumn(const char* title, float width, float minWidth,
+		float maxWidth, uint32 truncate, alignment align)
+	: Inherited(title, width, minWidth, maxWidth, align),
+	fTruncate(truncate)
+{
+	SetWantsEvents(true);
+}
+
+void	PartitionColumn::MouseDown(BColumnListView *parent, BRow *row, BField *field,
+				       BRect field_rect, BPoint point, uint32 buttons)
+{
+	// Only accept right button clicks
+	BMessage *pmsg = parent->Window()->CurrentMessage();
+	int32 button = pmsg->FindInt32("buttons");
+	if (button != B_SECONDARY_MOUSE_BUTTON)
+		return;
+
+	// Now we can show the pop-up menu!
+	PartitionListView* partition_view = dynamic_cast<PartitionListView*>(parent);
+	PartitionListRow* partition_row = dynamic_cast<PartitionListRow*>(row);
+	if (partition_view && partition_row)
+	{
+		partition_view->ShowPartitionMenu(point, partition_row->ID());
+	}
+}
+
+void
+PartitionColumn::DrawField(BField* field, BRect rect, BView* parent)
+{
+	BBitmapStringField *bitmapField = dynamic_cast<BBitmapStringField *>(field);
+	BStringField *stringField = dynamic_cast<BStringField *>(field);
+
+	if (bitmapField)
+	{
+		const BBitmap *bitmap = bitmapField->Bitmap();
+	
+		if (bitmap != NULL) {
+			float x = 0.0;
+			BRect r = bitmap->Bounds();
+			float y = rect.top + ((rect.Height() - r.Height()) / 2);
+			float width = 0.0;
+	
+			switch (Alignment()) {
+				default:
+				case B_ALIGN_LEFT:
+				case B_ALIGN_CENTER:
+
+					x = rect.left + kTEXT_MARGIN;
+					width = rect.right - (x + r.Width()) - (2 * kTEXT_MARGIN);
+					r.Set(x+r.Width(),rect.top,rect.right-width,rect.bottom);
+
+					break;
+	
+				case B_ALIGN_RIGHT:
+
+					x = rect.right - kTEXT_MARGIN - r.Width();
+					width = (x - rect.left - (2 * kTEXT_MARGIN));
+					r.Set(rect.left,rect.top,rect.left+width,rect.bottom);
+
+					break;
+			}
+
+			if (width != bitmapField->Width()) {
+				BString out_string(bitmapField->String());
+	
+				parent->TruncateString(&out_string, fTruncate, width + 2);
+				bitmapField->SetClippedString(out_string.String());
+				bitmapField->SetWidth(width);
+			}
+
+			// Draw the bitmap
+
+			parent->SetDrawingMode(B_OP_ALPHA);
+			parent->DrawBitmap(bitmap, BPoint(x, y));
+			parent->SetDrawingMode(B_OP_OVER);
+
+			// Now we can draw the string
+
+			DrawString(bitmapField->ClippedString(), parent, r);
+		}
+	}
+	else if (stringField)
+	{
+		float width = rect.Width() - (2 * kTEXT_MARGIN);
+	
+		if (width != stringField->Width()) {
+			BString out_string(stringField->String());
+
+			parent->TruncateString(&out_string, fTruncate, width + 2);
+			stringField->SetClippedString(out_string.String());
+			stringField->SetWidth(width);
+		}
+		DrawString(stringField->ClippedString(), parent, rect);
+	}
+
+	// Draw a nice vertical line on the end
+	//parent->StrokeLine(BPoint(rect.right, rect.top), BPoint(rect.right, rect.bottom));
+}
+
+int
+PartitionColumn::CompareFields(BField* field1, BField* field2)
+{
+	return ICompare(((BStringField*)field1)->String(),
+		       (((BStringField*)field2)->String()));
+}
+
+bool 
+PartitionColumn::AcceptsField(const BField *field) const
+{
+	return static_cast<bool>(dynamic_cast<const BStringField*>(field));
+}
+
+
 PartitionListRow::PartitionListRow(BPartition* partition)
 	: Inherited(),
 	fPartitionID(partition->ID())
 {
 	BPath path;
 	char size[1024];
+        BBitmap *icon;
+	const char *realpath;
 
+	// Device path & associated icon (if applicable)
+
 	partition->GetPath(&path);
+	if (partition->IsDevice()) // Only show device path for actual devices (so only for /dev/disk/..../raw entries)
+		realpath = path.Path();
+	else
+		realpath = "";
 
-	SetField(new BBitmapField(NULL), 0);
+#ifdef __HAIKU	
+	icon = new BBitmap(BRect(0, 0, B_MINI_ICON - 1, B_MINI_ICON - 1), B_RGB32);
+#else
+	icon = new BBitmap(BRect(0, 0, B_MINI_ICON - 1, B_MINI_ICON - 1), B_CMAP8);
+#endif
+	if (partition->IsDevice() && partition->GetIcon(icon, B_MINI_ICON) == B_OK)
+		SetField(new BBitmapStringField(icon, realpath), 0);
+	else
+	{
+		SetField(new BBitmapStringField(NULL, realpath), 0);
+		delete icon;
+	}
 
-	if (partition->IsDevice()) // Only show device path for actual devices (so only for /dev/disk/..../raw entries)
-		SetField(new BStringField(path.Path()), 1);
+	// Partition map style field (doubles as media status)
+
+	if (partition->ContainsPartitioningSystem())
+		SetField(new BStringField(partition->ContentType()), 1);
+	else if (partition->IsDevice())
+	{
+		BDiskDevice *device = partition->Device();
+		if (device->IsRemovableMedia() && !device->HasMedia())
+			SetField(new BStringField("no media"), 1);
+		else if (device->ContainsFileSystem())
+			SetField(new BStringField("none"), 1);
+		else
+			SetField(new BStringField("unreadable"), 1);
+	}
 	else
 		SetField(new BStringField(""), 1);
 
-	if (partition->ContainsPartitioningSystem()) {
-		SetField(new BStringField(partition->ContentType()), 2);
-	} else {
-		SetField(new BStringField("n/a"), 2);
-	}
+	// Type seems to always be ""...
+	SetField(new BStringField(partition->Type()), 2);
 
-	// For now, Partition type is always empty (as we do not care)
-	SetField(new BStringField(""), 3);
+	// FileSystem & Volume details
 
 	if (partition->ContainsFileSystem()) {
-			SetField(new BStringField(partition->ContentType()), 4); // Filesystem
-			SetField(new BStringField(partition->ContentName()), 5);	// Volume Name
+			SetField(new BStringField(partition->ContentType()), 3); // Filesystem
+			SetField(new BStringField(partition->ContentName()), 4);	// Volume Name
 	} else {
+		SetField(new BStringField(""), 3);
 		SetField(new BStringField(""), 4);
-		SetField(new BStringField(""), 5);
 	}
+
+	// Mount path
 	
 	if (partition->IsMounted() && partition->GetMountPoint(&path) == B_OK) {
-		SetField(new BStringField(path.Path()),  6);
+		SetField(new BStringField(path.Path()),  5);
 	} else {
-		SetField(new BStringField(""), 6);
+		SetField(new BStringField(""), 5);
 	}
 
-	SetField(new BStringField(SizeAsString(partition->Size(), size)), 7);
+	// Size of device or partition
+
+	SetField(new BStringField(SizeAsString(partition->Size(), size)), 6);
 }
 
+
 PartitionListView::PartitionListView(const BRect& frame)
 	: Inherited(frame, "storagelist", B_FOLLOW_ALL, 0, B_PLAIN_BORDER, true)
 {
-	AddColumn(new BBitmapColumn("", 20, 20, 100, B_ALIGN_CENTER), 0);
-	AddColumn(new BStringColumn("Device", 100, 50, 500, B_TRUNCATE_MIDDLE), 1);
-	AddColumn(new BStringColumn("Map style", 100, 50, 500, B_TRUNCATE_MIDDLE), 2);
-	AddColumn(new BStringColumn("Partition Type", 100, 50, 500, B_TRUNCATE_MIDDLE), 3);
-	AddColumn(new BStringColumn("Filesystem", 100, 50, 500, B_TRUNCATE_MIDDLE), 4);
-	AddColumn(new BStringColumn("Volume Name", 100, 50, 500, B_TRUNCATE_MIDDLE), 5);
-	AddColumn(new BStringColumn("Mounted At", 100, 50, 500, B_TRUNCATE_MIDDLE), 6);
-	AddColumn(new BStringColumn("Size", 100, 50, 500, B_TRUNCATE_END), 7);
+	// The default font is a smidge too big
+
+	BFont font(be_plain_font);
+	font.SetSize(9);
+	SetFont(&font);
+
+	//SetFont(B_FONT_ROW, &font);
+	SetFont(B_FONT_HEADER, &font);
+
+	// The default colors are pretty much horrific, so lets change them!
+
+	SetColor(B_COLOR_ROW_DIVIDER, kWhite);
+	SetColor(B_COLOR_SEPARATOR_LINE, kBorderColor); // or maybe B_COLOR_SEPARATOR_BORDER
+	SetColor(B_COLOR_BACKGROUND, kWhite);
+	SetColor(B_COLOR_SELECTION, kSelectionColor);
+
+	// All the column's we'll ever need
+
+	AddColumn(new PartitionColumn("Device", 140, 50, 500, B_TRUNCATE_END), 0);
+	AddColumn(new PartitionColumn("Map style", 70, 50, 500, B_TRUNCATE_END), 1);
+	AddColumn(new PartitionColumn("Partition Type", 100, 50, 500, B_TRUNCATE_END), 2);
+	AddColumn(new PartitionColumn("Filesystem", 80, 50, 500, B_TRUNCATE_END), 3);
+	AddColumn(new PartitionColumn("Volume Name", 140, 50, 500, B_TRUNCATE_END), 4);
+	AddColumn(new PartitionColumn("Mounted At", 100, 50, 500, B_TRUNCATE_END), 5);
+	AddColumn(new PartitionColumn("Size", 80, 50, 500, B_TRUNCATE_END, B_ALIGN_RIGHT), 6);
+
+	SetSelectionMode(B_SINGLE_SELECTION_LIST);
+
+	// Setup PopUp Menu
+
+	fPopUpMenu = new BPopUpMenu("Partitions", false, true, B_ITEMS_IN_COLUMN);;
+
+	// Setup Mount menu
+	fMountMenu = new BMenu("Mount");
+	fPopUpMenu->AddItem(fMountMenu);
+	
+	//Setup Unmount menu
+	fUnMountMenu = new BMenu("Unmount");
+	fPopUpMenu->AddItem(fUnMountMenu);
+
+	fFormatItem = new BMenuItem("Format", new BMessage(SETUP_FORMAT_MSG), 'F');
+
+	//Setup Setup menu
+	fSetupMenu = new BMenu("Setup");
+		fSetupMenu->AddItem(fFormatItem);
+		fPartitionMenu = new DiskSystemMenu("Partition", true);
+		fSetupMenu->AddItem(fPartitionMenu);
+		fInitializeMenu = new DiskSystemMenu("Initialize", false);
+		//add menu for formats
+		fSetupMenu->AddItem(fInitializeMenu);
+	fPopUpMenu->AddItem(fSetupMenu);
+	
+	//Setup Options menu
+
+	fEjectItem = new BMenuItem("Eject", new BMessage(OPTIONS_EJECT_MSG), 'E');
+	fTestItem = new BMenuItem("Surface Test", new BMessage(OPTIONS_SURFACE_TEST_MSG), 'T');
+
+	fOptionsMenu = new BMenu("Options");
+		fOptionsMenu->AddItem(fEjectItem);
+		fOptionsMenu->AddItem(fTestItem);
+	fPopUpMenu->AddItem(fOptionsMenu);
 }
 
+PartitionListView::~PartitionListView()
+{
+	delete fPopUpMenu;
+}
+
+void
+PartitionListView::UpdatePartitionMenu()
+{
+	PartitionListRow* selected_item = dynamic_cast<PartitionListRow*>(CurrentSelection());
+
+	// Clean out the old...
+
+	fMountMenu->RemoveItems(0, fMountMenu->CountItems());
+	fUnMountMenu->RemoveItems(0, fUnMountMenu->CountItems());
+
+	// Determine the enabled status of the menu's
+
+	bool mountVisible = false;
+	bool unmountVisible = false;
+	bool setupVisible = false;
+	bool optionsVisible = false;
+	bool formatVisible = false;
+	bool initializeVisible = false;
+	bool partitionVisible = false;
+	bool ejectVisible = false;
+	bool testVisible = false;
+
+	PartitionListView::GetMenuStatus(selected_item,
+		      mountVisible,
+		      unmountVisible,
+		      setupVisible,
+		      optionsVisible,
+		      formatVisible,
+		      initializeVisible,
+		      partitionVisible,
+		      ejectVisible,
+		      testVisible);
+
+	fMountMenu->SetEnabled(mountVisible);
+	fUnMountMenu->SetEnabled(unmountVisible);
+
+	fSetupMenu->SetEnabled(setupVisible);
+	fOptionsMenu->SetEnabled(optionsVisible);
+
+	fPartitionMenu->SetEnabled(partitionVisible);
+	fInitializeMenu->SetEnabled(initializeVisible);
+
+	fFormatItem->SetEnabled(formatVisible);
+	fEjectItem->SetEnabled(ejectVisible);
+	fTestItem->SetEnabled(testVisible);
+
+	// Re-populate menu's
+
+	PopulateMountMenus(fMountMenu, fUnMountMenu, selected_item);
+
+	if (partitionVisible)
+		fPartitionMenu->UpdateSystems(selected_item ? selected_item->ID() : NULL);
+	if (initializeVisible)
+		fInitializeMenu->UpdateSystems(selected_item ? selected_item->ID() : NULL);
+
+	// Associate pop-up & items with Window()
+	BWindow *window = Window();
+
+	fMountMenu->SetTargetForItems(window);
+	fUnMountMenu->SetTargetForItems(window);
+
+	fSetupMenu->SetTargetForItems(window);
+	fOptionsMenu->SetTargetForItems(window);
+
+	fPartitionMenu->SetTargetForItems(window);
+	fInitializeMenu->SetTargetForItems(window);
+}
+
+void
+PartitionListView::PopulateMountMenus(BMenu* mount, BMenu* unmount, PartitionListRow *current)
+{
+	int32 collected = RecursePopulateMountMenus(mount, unmount, current);
+
+	if (collected > 1)
+	{
+		// More than 1 possible partition to choose from!
+
+		mount->AddItem(new BMenuItem("Mount All Partitions", new BMessage(MOUNT_MOUNT_ALL_MSG), 'M'), 0);
+		mount->AddItem(new BSeparatorItem(), 1);
+	}
+	else if (collected == 1)
+	{
+		// Only 1 possible partition to choose from
+		// e.g. when you select a device with no partitions
+
+		BMenuItem *item = mount->ItemAt(0);
+		if (item)
+			item->SetLabel("Mount");
+	}
+}
+
+int32
+PartitionListView::RecursePopulateMountMenus(BMenu* mount, BMenu* unmount, PartitionListRow *current)
+{
+	int32 cur_collected = 1;
+
+	if (current)
+	{
+		PartitionMenuItem *item;
+		BPartition *partition;
+		BDiskDevice device;
+	
+		if (BDiskDeviceRoster().GetPartitionWithID(current->ID(), &device, &partition) != B_OK)
+			return cur_collected;
+	
+		if (device.IsRemovableMedia() && !device.HasMedia())
+			return cur_collected;
+	
+		if (partition->ContainsFileSystem())
+		{
+			if (partition->IsMounted())
+			{
+				BMessage *message = new BMessage(MOUNT_TOGGLE);
+				message->AddInt32("PartitionID", partition->ID());
+			
+				item = new PartitionMenuItem("UNKNOWN", message, 0, 0, partition, true);
+				unmount->AddItem(item);
+			}
+		
+			BMessage *message = new BMessage(MOUNT_TOGGLE);
+			message->AddInt32("PartitionID", partition->ID());
+		
+			item = new PartitionMenuItem("UNKNOWN", message, 0, 0, partition, false);
+			mount->AddItem(item);
+		}
+	}
+	else
+	{
+		cur_collected = 0;
+	}
+
+	for (int32 idx=0; idx < CountRows(current); idx++)
+	{
+		// Recurse!
+		PartitionListRow* row = dynamic_cast<PartitionListRow*>(RowAt(idx, current));
+		if (row != NULL)
+			cur_collected += RecursePopulateMountMenus(mount, unmount, row);
+	}
+
+	return cur_collected;
+}
+
+void 
+PartitionListView::DrawLatch(BView *view, BRect rect, LatchType position, BRow *)
+{
+	view->SetHighColor(0, 0, 0);
+
+	// Center the latch
+	rect.OffsetBy(((uint32)LatchWidth() - 10) / 2, 
+		      ((rect.bottom-rect.top) - 10) / 2);
+	rect.right = rect.left + 10;
+	rect.bottom = rect.top + 10;
+
+	DrawLatchInState(position, true, view, rect);
+
+}
+
+void
+PartitionListView::DrawLatchInState(LatchType state, bool leftAligned, BView *view, const BRect &rect)
+{
+	rgb_color outlineColor = {0, 0, 0, 255};
+	rgb_color middleColor = state == B_PRESSED_LATCH ? kHighlightColor : kNormalColor;
+
+	view->SetDrawingMode(B_OP_COPY);
+
+	switch (state) {
+		case B_CLOSED_LATCH:
+			view->BeginLineArray(6);
+			
+			if (leftAligned) {
+				view->AddLine(BPoint(rect.left + 3, rect.top + 1), 
+					BPoint(rect.left + 3, rect.bottom - 1), outlineColor);
+				view->AddLine(BPoint(rect.left + 3, rect.top + 1), 
+					BPoint(rect.left + 7, rect.top + 5), outlineColor);
+				view->AddLine(BPoint(rect.left + 7, rect.top + 5), 
+					BPoint(rect.left + 3, rect.bottom - 1), outlineColor);
+
+				view->AddLine(BPoint(rect.left + 4, rect.top + 3), 
+					BPoint(rect.left + 4, rect.bottom - 3), middleColor);
+				view->AddLine(BPoint(rect.left + 5, rect.top + 4), 
+					BPoint(rect.left + 5, rect.bottom - 4), middleColor);
+				view->AddLine(BPoint(rect.left + 5, rect.top + 5), 
+					BPoint(rect.left + 6, rect.top + 5), middleColor);
+			} else {
+				view->AddLine(BPoint(rect.right - 3, rect.top + 1), 
+					BPoint(rect.right - 3, rect.bottom - 1), outlineColor);
+				view->AddLine(BPoint(rect.right - 3, rect.top + 1), 
+					BPoint(rect.right - 7, rect.top + 5), outlineColor);
+				view->AddLine(BPoint(rect.right - 7, rect.top + 5), 
+					BPoint(rect.right - 3, rect.bottom - 1), outlineColor);
+
+				view->AddLine(BPoint(rect.right - 4, rect.top + 3), 
+					BPoint(rect.right - 4, rect.bottom - 3), middleColor);
+				view->AddLine(BPoint(rect.right - 5, rect.top + 4), 
+					BPoint(rect.right - 5, rect.bottom - 4), middleColor);
+				view->AddLine(BPoint(rect.right - 5, rect.top + 5), 
+					BPoint(rect.right - 6, rect.top + 5), middleColor);
+			}
+			view->EndLineArray();
+			break;
+
+		case B_PRESSED_LATCH:
+			view->BeginLineArray(7);
+			if (leftAligned) {
+				view->AddLine(BPoint(rect.left + 1, rect.top + 7), 
+					BPoint(rect.left + 7, rect.top + 7), outlineColor);
+				view->AddLine(BPoint(rect.left + 7, rect.top + 1), 
+					BPoint(rect.left + 7, rect.top + 7), outlineColor);
+				view->AddLine(BPoint(rect.left + 1, rect.top + 7), 
+					BPoint(rect.left + 7, rect.top + 1), outlineColor);
+
+				view->AddLine(BPoint(rect.left + 3, rect.top + 6), 
+					BPoint(rect.left + 6, rect.top + 6), middleColor);
+				view->AddLine(BPoint(rect.left + 4, rect.top + 5), 
+					BPoint(rect.left + 6, rect.top + 5), middleColor);
+				view->AddLine(BPoint(rect.left + 5, rect.top + 4), 
+					BPoint(rect.left + 6, rect.top + 4), middleColor);
+				view->AddLine(BPoint(rect.left + 6, rect.top + 3), 
+					BPoint(rect.left + 6, rect.top + 4), middleColor);
+			} else {
+				view->AddLine(BPoint(rect.right - 1, rect.top + 7), 
+					BPoint(rect.right - 7, rect.top + 7), outlineColor);
+				view->AddLine(BPoint(rect.right - 7, rect.top + 1), 
+					BPoint(rect.right - 7, rect.top + 7), outlineColor);
+				view->AddLine(BPoint(rect.right - 1, rect.top + 7), 
+					BPoint(rect.right - 7, rect.top + 1), outlineColor);
+
+				view->AddLine(BPoint(rect.right - 3, rect.top + 6), 
+					BPoint(rect.right - 6, rect.top + 6), middleColor);
+				view->AddLine(BPoint(rect.right - 4, rect.top + 5), 
+					BPoint(rect.right - 6, rect.top + 5), middleColor);
+				view->AddLine(BPoint(rect.right - 5, rect.top + 4), 
+					BPoint(rect.right - 6, rect.top + 4), middleColor);
+				view->AddLine(BPoint(rect.right - 6, rect.top + 3), 
+					BPoint(rect.right - 6, rect.top + 4), middleColor);
+			}
+			view->EndLineArray();
+			break;
+
+		case B_OPEN_LATCH:
+			view->BeginLineArray(6);
+			view->AddLine(BPoint(rect.left + 1, rect.top + 3), 
+				BPoint(rect.right - 1, rect.top + 3), outlineColor);
+			view->AddLine(BPoint(rect.left + 1, rect.top + 3), 
+				BPoint(rect.left + 5, rect.top + 7), outlineColor);
+			view->AddLine(BPoint(rect.left + 5, rect.top + 7), 
+				BPoint(rect.right - 1, rect.top + 3), outlineColor);
+
+			view->AddLine(BPoint(rect.left + 3, rect.top + 4), 
+				BPoint(rect.right - 3, rect.top + 4), middleColor);
+			view->AddLine(BPoint(rect.left + 4, rect.top + 5), 
+				BPoint(rect.right - 4, rect.top + 5), middleColor);
+			view->AddLine(BPoint(rect.left + 5, rect.top + 5), 
+				BPoint(rect.left + 5, rect.top + 6), middleColor);
+			view->EndLineArray();
+			break;
+
+		case B_NO_LATCH:
+		break;
+	}
+}
+
+void
+PartitionListView::ShowPartitionMenu(BPoint point, partition_id id)
+{
+	ConvertToScreen(&point);
+	fPopUpMenu->Go(point, true); 
+}
+
+partition_id
+PartitionListView::GetSelectedPartition()
+{
+	PartitionListRow* row = dynamic_cast<PartitionListRow*>(CurrentSelection());
+	if (row)
+		return row->ID();
+
+	return NULL;
+}
+
 PartitionListRow*
-PartitionListView::FindRow(partition_id id)
+PartitionListView::FindRow(partition_id id, PartitionListRow* current)
 {
-	for (int32 idx=0; idx < CountRows(); idx++) {
-		PartitionListRow* item = dynamic_cast<PartitionListRow*>(RowAt(idx));
-		if (item != NULL && item->ID() == id)
-			return item;
+	if (current && current->ID() == id)
+		return current;
+
+	for (int32 idx=0; idx < CountRows(current); idx++)
+	{
+		PartitionListRow* row = dynamic_cast<PartitionListRow*>(RowAt(idx, current));
+		if (row != NULL)
+		{
+			row = FindRow(id, row);
+			if (row)
+				return row;
+		}
 	}
 
 	return NULL;
@@ -103,3 +730,82 @@
 	
 	return partitionrow;
 }
+
+void
+PartitionListView::GetMenuStatus(PartitionListRow *selected_item,
+				      bool& mountVisible,
+				      bool& unmountVisible,
+				      bool& setupVisible,
+				      bool& optionsVisible,
+				      bool& formatVisible,
+				      bool& initializeVisible,
+				      bool& partitionVisible,
+				      bool& ejectVisible,
+				      bool& testVisible)
+{
+	testVisible = true;
+
+	if (!selected_item)
+	{
+		// Obviously not selected anything!
+
+		mountVisible = true;
+		unmountVisible = true;
+		setupVisible = false;
+		optionsVisible = false;
+
+		return;
+	}
+
+	// Selected something, lets see what it is...
+
+	BPartition *currentPartition;
+	BDiskDevice currentDevice;
+	partition_id id = selected_item->ID();
+
+	if (BDiskDeviceRoster().GetPartitionWithID(id, &currentDevice, &currentPartition) == B_OK && (!(currentDevice.IsRemovableMedia() && !currentDevice.HasMedia())))
+	{
+		// Selected something we can work with
+
+		if (currentDevice.IsReadOnlyMedia())
+		{
+			setupVisible = false;
+		}
+
+		if (currentPartition->IsMounted())
+		{
+			ejectVisible = currentDevice.IsRemovableMedia();
+			initializeVisible = false;
+			partitionVisible = false;
+		}
+		else if (currentDevice.IsRemovableMedia())
+		{
+			ejectVisible = currentDevice.HasMedia();
+			initializeVisible = currentDevice.HasMedia();
+			partitionVisible = (currentPartition->IsDevice() && currentDevice.HasMedia());
+		}
+		else
+		{
+			ejectVisible = false;
+			initializeVisible = true;
+			partitionVisible = currentPartition->IsDevice();
+		}
+	
+		formatVisible = false; // not 100% sure what this equates to
+
+		mountVisible = true;
+		unmountVisible = true;
+		setupVisible = true;
+		optionsVisible = true;
+	}
+	else
+	{
+		// Selected something we can't work with!
+
+		mountVisible = false;
+		unmountVisible = false;
+		setupVisible = false;
+		optionsVisible = false;
+	}
+}
+
Index: src/preferences/drivesetup/PartitionList.h
===================================================================
--- src/preferences/drivesetup/PartitionList.h	(revision 21777)
+++ src/preferences/drivesetup/PartitionList.h	(working copy)
@@ -1,3 +1,7 @@
+/*! \file MainWindow.h
+    \brief Header for the PartitionListView class and its relatives.
+    
+*/
 #ifndef PARTITIONLIST_H
 #define PARTITIONLIST_H
 
@@ -4,12 +8,87 @@
 class PartitionListRow;
 class PartitionListView;
 
+#include <interface/ColumnTypes.h>
 #include <interface/ColumnListView.h>
+#include <interface/Menu.h>
+#include <interface/MenuItem.h>
 #include <storage/Partition.h>
 
 // Forward declarations
 class BPartition;
 
+
+// A bitmap *and* a string!
+class BBitmapStringField : public BStringField
+{
+typedef BStringField Inherited;
+	public:
+		BBitmapStringField	(BBitmap* bitmap, const char *string);
+
+		const BBitmap*		Bitmap	();
+		void	SetBitmap	(BBitmap* bitmap);
+
+	private:
+		BBitmap*		fBitmap;
+};
+
+
+// Specialized menu item for the mount/unmount menu's
+class PartitionMenuItem : public BMenuItem
+{
+typedef BMenuItem Inherited;
+public:
+	PartitionMenuItem(const char *label, BMessage *message,
+			  char shortcut, uint32 modifier, BPartition *partition, bool unmount);
+
+	partition_id ID() { return fPartitionID; }
+private:
+	partition_id fPartitionID;
+	bool         fUnmount;
+};
+
+
+// Menu which lists iterated DiskSystem's
+class DiskSystemMenu : public BMenu
+{
+typedef BMenu Inherited;
+public:
+	DiskSystemMenu(	const char *title,
+			bool partitionSystems,
+			menu_layout layout = B_ITEMS_IN_COLUMN);
+
+	void UpdateSystems(partition_id id);
+
+private:
+	bool fIteratePartitionSystems;
+};
+
+
+// Column for PartitionListView
+class PartitionColumn : public BTitledColumn
+{
+typedef BTitledColumn Inherited;
+public:
+	PartitionColumn(const char* title, float width, float minWidth,
+		float maxWidth, uint32 truncate, alignment align = B_ALIGN_LEFT);
+
+	virtual void	MouseDown(BColumnListView *parent, BRow *row, BField *field,
+			          BRect field_rect, BPoint point, uint32 buttons);
+
+	virtual void	DrawField	(BField* field,
+				 BRect rect,						 BView* parent);
+
+	virtual int		CompareFields		(BField* field1,
+							 BField* field2);
+
+	virtual	bool		AcceptsField        (const BField* field) const;
+
+	private:
+		uint32		fTruncate;
+};
+
+
+// Row for the PartitionListView
 class PartitionListRow : public BRow
 {
 	typedef BRow Inherited;
@@ -21,14 +100,54 @@
 	partition_id fPartitionID;
 };
 
+
+// List which display's all of those BPartition's
 class PartitionListView : public BColumnListView
 {
 	typedef BColumnListView Inherited;
 public:
 	PartitionListView(const BRect& frame);
+	~PartitionListView();
+
+	partition_id GetSelectedPartition();
+
+	void ShowPartitionMenu(BPoint point, partition_id id);
+	void UpdatePartitionMenu();
+
+	void PopulateMountMenus(BMenu* mount, BMenu* unmount, PartitionListRow *current=NULL);
+	int32 RecursePopulateMountMenus(BMenu* mount, BMenu* unmount, PartitionListRow *current);
+
+	virtual void	DrawLatch(BView*, BRect, LatchType, BRow*);
+	virtual void DrawLatchInState(LatchType state, bool leftAligned, BView *view, const BRect &rect);
 	
-	PartitionListRow* FindRow(partition_id id);
+	PartitionListRow* FindRow(partition_id id,  PartitionListRow* current=NULL);
 	PartitionListRow* AddPartition(BPartition* partition);
+
+	static void GetMenuStatus(PartitionListRow *selected_item,
+				      bool& mountVisible,
+				      bool& unmountVisible,
+				      bool& setupVisible,
+				      bool& optionsVisible,
+				      bool& formatVisible,
+				      bool& initializeVisible,
+				      bool& partitionVisible,
+				      bool& ejectVisible,
+				      bool& testVisible); // Yikes!
+
+private:
+	BPopUpMenu *fPopUpMenu;
+
+	BMenu* fMountMenu;
+	BMenu* fUnMountMenu;
+	BMenu* fSetupMenu;
+	BMenu* fOptionsMenu;
+
+	BMenuItem* fFormatItem;
+	BMenuItem* fEjectItem;
+	BMenuItem* fTestItem;
+
+	DiskSystemMenu* fInitializeMenu;
+	DiskSystemMenu* fPartitionMenu;
 };
 
 #endif /* PARTITIONLIST_H */
Index: src/preferences/drivesetup/MainWindow.cpp
===================================================================
--- src/preferences/drivesetup/MainWindow.cpp	(revision 21777)
+++ src/preferences/drivesetup/MainWindow.cpp	(working copy)
@@ -9,6 +9,8 @@
 #include "PartitionList.h"
 #include "PosSettings.h"
 
+#include <interface/Alert.h>
+
 #include <interface/MenuItem.h>
 #include <interface/MenuBar.h>
 #include <interface/Menu.h>
@@ -23,16 +25,23 @@
 #include <storage/DiskDevice.h>
 #include <storage/Partition.h>
 #include <storage/Path.h>
+#include <storage/Volume.h>
+#include <storage/VolumeRoster.h>
 
 class DriveVisitor : public BDiskDeviceVisitor 
 {
 public:
-	DriveVisitor(PartitionListView* list);
+	DriveVisitor(PartitionListView* list, BMenu *mountmenu, BMenu *umountmenu);
 
 	bool Visit(BDiskDevice *device);
 	bool Visit(BPartition *partition, int32 level);
+
+	void Sync();
 private:
+
 	PartitionListView* fPartitionList;
+	BMenu*		   fMountMenu;
+	BMenu*		   fUnMountMenu;
 };
 
 const char*
@@ -88,6 +97,7 @@
 }
 #endif
 
+
 /**
  * Constructor.
  * @param frame The size to make the window.
@@ -95,39 +105,43 @@
 MainWindow::MainWindow(BRect frame, PosSettings *Settings)
 	: BWindow(frame, "DriveSetup", B_DOCUMENT_WINDOW,  B_ASYNCHRONOUS_CONTROLS | B_NOT_ZOOMABLE)
 {
-	BMenu *partitionMenu, *initMenu;
 	BMenu *menu;
 
 	fSettings = Settings;
 	
 	BMenuBar* rootMenu = new BMenuBar(Bounds(), "root menu");
-	//Setup Mount menu
-	menu = new BMenu("Mount");
-	menu->AddItem(new BMenuItem("Mount All Partitions", new BMessage(MOUNT_MOUNT_ALL_MSG), 'M'));
-	menu->AddSeparatorItem();
-	rootMenu->AddItem(menu);
+
+	// Setup Mount menu
+	fMountMenu = new BMenu("Mount");
+	rootMenu->AddItem(fMountMenu);
 	
-	//Setup Unmount menu
-	menu = new BMenu("Unmount");
-	rootMenu->AddItem(menu);
+	// Setup Unmount menu
+	fUnMountMenu = new BMenu("Unmount");
+	rootMenu->AddItem(fUnMountMenu);
 	
-	//Setup Setup menu
-	menu = new BMenu("Setup");
-		menu->AddItem(new BMenuItem("Format", new BMessage(SETUP_FORMAT_MSG), 'F'));
-		partitionMenu = new BMenu("Partition");
-		menu->AddItem(partitionMenu);
-		initMenu = new BMenu("Initialize");
+	fFormatItem = new BMenuItem("Format", new BMessage(SETUP_FORMAT_MSG), 'F');
+
+	// Setup Setup menu
+	fSetupMenu = new BMenu("Setup");
+		fSetupMenu->AddItem(fFormatItem);
+		fPartitionMenu = new DiskSystemMenu("Partition", true);
+		fSetupMenu->AddItem(fPartitionMenu);
+		fInitializeMenu = new DiskSystemMenu("Initialize", false);
 		//add menu for formats
-		menu->AddItem(initMenu);
-	rootMenu->AddItem(menu);
+		fSetupMenu->AddItem(fInitializeMenu);
+	rootMenu->AddItem(fSetupMenu);
 	
-	//Setup Options menu
-	menu = new BMenu("Options");
-		menu->AddItem(new BMenuItem("Eject", new BMessage(OPTIONS_EJECT_MSG), 'E'));
-		menu->AddItem(new BMenuItem("Surface Test", new BMessage(OPTIONS_SURFACE_TEST_MSG), 'T'));
-	rootMenu->AddItem(menu);
+	// Setup Options menu
+
+	fEjectItem = new BMenuItem("Eject", new BMessage(OPTIONS_EJECT_MSG), 'E');
+	fTestItem = new BMenuItem("Surface Test", new BMessage(OPTIONS_SURFACE_TEST_MSG), 'T');
+
+	fOptionsMenu = new BMenu("Options");
+		fOptionsMenu->AddItem(fEjectItem);
+		fOptionsMenu->AddItem(fTestItem);
+	rootMenu->AddItem(fOptionsMenu);
 	
-	//Setup Rescan menu
+	// Setup Rescan menu
 	menu = new BMenu("Rescan");
 		menu->AddItem(new BMenuItem("IDE", new BMessage(RESCAN_IDE_MSG)));
 		menu->AddItem(new BMenuItem("SCSI", new BMessage(RESCAN_SCSI_MSG)));
@@ -135,31 +149,17 @@
 		
 	AddChild(rootMenu);
 
+	// Setup partition list
 	BRect r(Bounds());
 	r.top = rootMenu->Frame().bottom +1;
 	fListView = new PartitionListView(r);
 	AddChild(fListView);
 
-	// Now update filesystem/partition menus with values
-	BDiskSystem diskSystem;
-	fDDRoster.RewindDiskSystems();
-	while(fDDRoster.GetNextDiskSystem(&diskSystem) == B_OK) {
-		if (diskSystem.IsPartitioningSystem()) {
-			BMessage* msg = new BMessage(SETUP_PARTITION_SELECTED_MSG);
-			msg->AddString("bdisksystem:name", diskSystem.Name());
-			partitionMenu->AddItem(new BMenuItem(diskSystem.PrettyName(), msg));
-		} else if (diskSystem.IsFileSystem()) {
-			BMessage* msg = new BMessage(SETUP_INITIALIZE_MSG);
-			msg->AddString("bdisksystem:name", diskSystem.Name());
-			initMenu->AddItem(new BMenuItem(diskSystem.PrettyName(), msg));
-		}
-	}
+	fListView->SetSelectionMessage(new BMessage(PARTITION_SELECTION_CHANGE_MSG));
 
-	// Now visit all disks in the system and show their contents
-	DriveVisitor driveVisitor(fListView);
-	BPartition *partition = NULL;
-	BDiskDevice device;
-	fDDRoster.VisitEachPartition(&driveVisitor, &device, &partition);
+	// Finally we can grab our data!
+	
+	ScanDevices();
 }
 
 /**
@@ -167,79 +167,451 @@
  * @param message The message recieved by the window.
  */	
 void MainWindow::MessageReceived(BMessage *message){
+	switch(message->what)
+	{
+	
+		case PARTITION_SELECTION_CHANGE_MSG:
 
-	switch(message->what){
-	
+			// 
+			UpdateMenus();
+
+			break;
+
 		case MOUNT_MOUNT_ALL_MSG:
-		
-			printf("MOUNT_MOUNT_ALL_MSG\n");
+
+			// Mount all listed partitions
+			MountAllVisible();
+			UpdateMenus();
+
 			break;
 			
-		case MOUNT_MOUNT_SELECTED_MSG:
-		
-			printf("MOUNT_MOUNT_SELECTED_MSG\n");
-			break;
+		case MOUNT_TOGGLE:
 			
-		case UNMOUNT_UNMOUNT_SELECTED_MSG:
-		
-			printf("UNMOUNT_UNMOUNT_SELECTED_MSG\n");
+			HandleMenuMounting(message);
+
 			break;
 		
 		case SETUP_FORMAT_MSG:
+
+			if (fListView->CurrentSelection())
+				HandleFormat(message);
+
+			break;
 		
-			printf("SETUP_FORMAT_MSG\n");
+		case SETUP_PARTITION_SELECTED_MSG:
+
+			if (fListView->CurrentSelection())
+				HandlePartition(message);
+
 			break;
-			
+
 		case SETUP_INITIALIZE_MSG:
+
+			if (fListView->CurrentSelection())
+				HandleInitialize(message);
 		
-			printf("SETUP_INITIALIZE_MSG\n");
 			break;
-			
+
+		case MOUNT_TOGGLE_SELECTED_MSG:
 		case OPTIONS_EJECT_MSG:
-		
-			printf("OPTIONS_EJECT_MSG\n");
-			break;
-			
 		case OPTIONS_SURFACE_TEST_MSG:
-		
-			printf("OPTIONS_SURFACE_TEST_MSG\n");
+
+			if (fListView->CurrentSelection())
+				HandleMenuActions(message); 
 			break;
 			
 		case RESCAN_IDE_MSG:
 		
-			printf("RESCAN_IDE_MSG\n");
+			ScanDevices();
 			break;
 			
 		case RESCAN_SCSI_MSG:
 		
-			printf("RESCAN_SCSI_MSG\n");
+			ScanDevices();
 			break;
 			
 		default:
 		
 			BWindow::MessageReceived(message);
 			
-	}//switch
+	}
 	
 }
 
+void
+MainWindow::UpdateMenus()
+{
+	PartitionListRow *selected_item = dynamic_cast<PartitionListRow*>(fListView->CurrentSelection());
+
+	// Clean out the old..
+
+	fMountMenu->RemoveItems(0, fMountMenu->CountItems());
+	fUnMountMenu->RemoveItems(0, fUnMountMenu->CountItems());
+
+	// Determine the enabled status of the menu's
+
+	bool mountVisible = false;
+	bool unmountVisible = false;
+	bool setupVisible = false;
+	bool optionsVisible = false;
+	bool formatVisible = false;
+	bool initializeVisible = false;
+	bool partitionVisible = false;
+	bool ejectVisible = false;
+	bool testVisible = false;
+
+	PartitionListView::GetMenuStatus(selected_item,
+		      mountVisible,
+		      unmountVisible,
+		      setupVisible,
+		      optionsVisible,
+		      formatVisible,
+		      initializeVisible,
+		      partitionVisible,
+		      ejectVisible,
+		      testVisible);
+
+	fMountMenu->SetEnabled(mountVisible);
+	fUnMountMenu->SetEnabled(unmountVisible);
+
+	fSetupMenu->SetEnabled(setupVisible);
+	fOptionsMenu->SetEnabled(optionsVisible);
+
+	fFormatItem->SetEnabled(formatVisible);
+
+	fInitializeMenu->SetEnabled(initializeVisible);
+	fPartitionMenu->SetEnabled(partitionVisible);
+
+	fEjectItem->SetEnabled(ejectVisible);
+	fTestItem->SetEnabled(testVisible);
+
+	// Re-populate menu's
+
+	if (partitionVisible)
+		fPartitionMenu->UpdateSystems(selected_item ? selected_item->ID() : NULL);
+	if (initializeVisible)
+		fInitializeMenu->UpdateSystems(selected_item ? selected_item->ID() : NULL);
+
+	fListView->PopulateMountMenus(fMountMenu, fUnMountMenu, selected_item);
+	fListView->UpdatePartitionMenu();
+}
+
 /**
+ * Scans for devices & places them in the controls
+ */
+void
+MainWindow::ScanDevices()
+{
+	fListView->Clear();
+
+	// Now visit all disks in the system and show their contents
+	DriveVisitor driveVisitor(fListView, fMountMenu, fUnMountMenu);
+	BPartition *partition = NULL;
+	BDiskDevice device;
+	fDDRoster.VisitEachPartition(&driveVisitor, &device, &partition);
+
+	UpdateMenus();
+}
+
+
+bool
+MainWindow::DoEject(BDiskDevice* disk)
+{	
+	status_t status;
+	BString string;
+
+	// Try to eject, giving an error message where neccesary
+	// and updating everything upon success
+
+	if (disk->HasMedia())
+	{
+		status = disk->Eject(true);
+		if (status < B_OK) {
+			string << "Error ejecting disk. (" << strerror(status) << ")";
+				(new BAlert("", string.String(), "OK"))->Go(0);
+		}
+		else
+		{
+			UpdateMenus();
+			return true;
+		}
+	}
+
+	return true;
+}
+
+void
+MainWindow::DoTest(BPartition *partition)
+{
+	// InitCheck on DiskDevice? StartWatching*?
+
+	// TODO
+
+	(new BAlert("", "Not implemented", "OK"))->Go(0);
+}
+
+bool
+MainWindow::DoToggleMount(BPartition *partition, bool only_mount)
+{
+	status_t status;
+	BString string;
+
+	// Try to mount or unmount (only the former if only_mount),
+	// giving an error message where neccesary and updating everything 
+	// upon success
+
+	if (!partition->IsMounted())
+	{
+		status = partition->Mount();
+		if (status < B_OK) {
+			string << "Error mounting volume. (" << strerror(status) << ")";
+				(new BAlert("", string.String(), "OK"))->Go(0);
+		}
+		else
+		{
+			UpdateMenus();
+			return true;
+		}
+	}
+	else if (!only_mount)
+	{
+		status = partition->Unmount();
+		if (status < B_OK) {
+			string << "Error unmounting volume. (" << strerror(status) << ")";
+				(new BAlert("", string.String(), "OK"))->Go(0);
+		}
+		else
+		{
+			UpdateMenus();
+			return true;
+		}
+	}
+
+	return false;
+}
+
+void 
+MainWindow::HandleMenuActions(BMessage *message)
+{
+	BPartition *currentPartition;
+	BDiskDevice currentDevice;
+
+	if (fDDRoster.GetPartitionWithID(fListView->GetSelectedPartition(), &currentDevice, &currentPartition) != B_OK)
+		return;
+
+	// These messages all require a BPartition / BDiskDevice,
+	// so they are all delegated here to eliminate unneccesary
+	// redundancy
+
+	switch(message->what)
+	{
+		case MOUNT_TOGGLE_SELECTED_MSG:
+		
+			DoToggleMount(currentPartition);
+
+			break;
+
+		case OPTIONS_EJECT_MSG:
+		
+			DoEject(&currentDevice);
+			UpdateMenus();
+		
+			break;
+			
+		case OPTIONS_SURFACE_TEST_MSG:
+
+			DoTest(currentPartition);
+
+			// Defragment ? Repair ? 
+			break;
+	}
+
+	UpdateMenus();
+}
+
+
+void MainWindow::HandleFormat(BMessage* message)
+{
+	// TODO (?)
+
+	(new BAlert("", "Not implemented", "OK"))->Go(0);
+}
+
+void MainWindow::HandlePartition(BMessage* message)
+{
+	const char *disk_system;
+	status_t error = B_OK;
+
+	if (message->FindString("bdisksystem:name", &disk_system) != B_OK)
+		return;
+
+	// Lets find this disk system!
+
+	BDiskSystem diskSystem;
+	fDDRoster.RewindDiskSystems();
+	while(fDDRoster.GetNextDiskSystem(&diskSystem) == B_OK)
+	{
+		if (!diskSystem.IsPartitioningSystem())
+			continue;
+
+		if (!strcmp(disk_system, diskSystem.Name()))
+		{
+			// Found it!
+			
+			// TODO
+			// GetChildCreationParameterEditor...
+
+			(new BAlert("", "If this was implemented, we'd show you a nice parameters dialog!", "OK"))->Go(0);
+
+			break;
+		}
+	}
+
+	if (error != B_OK)
+	{
+		// Show a nasty error message
+
+		BString string;
+		string << "Error initializing. (" << strerror(error) << ")";
+			(new BAlert("", string.String(), "OK"))->Go(0);
+	}
+}
+
+
+void MainWindow::HandleInitialize(BMessage* message)
+{
+	const char *disk_system;
+	status_t error = B_OK;
+
+	if (message->FindString("bdisksystem:name", &disk_system) != B_OK)
+		return;
+
+	// Lets find this disk system!
+
+	BDiskSystem diskSystem;
+	fDDRoster.RewindDiskSystems();
+	while(fDDRoster.GetNextDiskSystem(&diskSystem) == B_OK)
+	{
+		if (!diskSystem.IsFileSystem())
+			continue;
+
+		if (!strcmp(disk_system, diskSystem.Name()))
+		{
+			// Now lets see if we can init it...
+			
+			BPartition *partition;
+			BDiskDevice device;
+	
+			error = fDDRoster.GetPartitionWithID(fListView->GetSelectedPartition(), &device, &partition);
+
+			if (error != B_OK)
+				break;
+
+			// TBD: is Uninitialize() required?
+			if (partition->CanInitialize(disk_system))
+			{
+				// TODO
+				(new BAlert("", "If this was implemented, we'd show you a nice parameters dialog!", "OK"))->Go(0);
+
+				break;
+/*
+				BDiskDeviceParameterEditor *editor;
+				const char *editor_parameters;
+				const char *editor_name = "TODO";
+
+				error = partition->GetInitializationParameterEditor(disk_system, &editor);
+
+				if (error != B_OK)
+					break;
+
+				// TODO: figure out how to invoke the editor and grab the parameters!
+
+				error = partition->ValidateInitialize(disk_system, editor_name, editor_parameters);
+
+				if (error != B_OK)
+					break;
+
+				error = partition->Initialize(disk_system, editor_name, editor_parameters);
+
+				if (error != B_OK)
+					break;
+*/
+			}
+			else
+			{
+				error = B_NOT_ALLOWED;
+			}
+		}
+	}
+
+	if (error != B_OK)
+	{
+		// Show a nasty error message
+
+		BString string;
+		string << "Error initializing. (" << strerror(error) << ")";
+			(new BAlert("", string.String(), "OK"))->Go(0);
+	}
+}
+
+void
+MainWindow::HandleMenuMounting(BMessage *message)
+{
+	partition_id id;
+
+	if (message->FindInt32("PartitionID", &id) == B_OK)
+	{
+		BPartition *partition;
+		BDiskDevice device;
+
+		if (fDDRoster.GetPartitionWithID(id, &device, &partition) == B_OK)
+		{
+			DoToggleMount(partition);
+		}
+	}
+}
+
+void MainWindow::MountAllVisible()
+{
+	// Iterate through fMountMenu mounting all of the associated partitions
+
+	for (int32 idx=2; idx < fMountMenu->CountItems(); idx++)
+	{
+		PartitionMenuItem *item = dynamic_cast<PartitionMenuItem*>(fMountMenu->ItemAt(idx));
+		if (item)
+		{
+			BPartition *partition;
+			BDiskDevice device;
+
+			if (!fDDRoster.GetPartitionWithID(item->ID(), &device, &partition) == B_OK)
+				continue;
+			
+			DoToggleMount(partition, true);
+		}
+	}
+}
+
+/**
  * Quits and Saves settings.
  */	
 bool 
 MainWindow::QuitRequested()
 {
 	bool accepted = BWindow::QuitRequested();
-	if (accepted) {
+	if (accepted)
+	{
 		fSettings->SetWindowPosition(Frame());
-    	be_app->PostMessage(B_QUIT_REQUESTED);
+		be_app->PostMessage(B_QUIT_REQUESTED);
 	}
 	
 	return accepted;
 }
 
-DriveVisitor::DriveVisitor(PartitionListView* list)
-	: fPartitionList(list)
+
+DriveVisitor::DriveVisitor(PartitionListView* list, BMenu *mountmenu, BMenu *unmountmenu)
+	: fPartitionList(list),
+	  fMountMenu(mountmenu),
+	  fUnMountMenu(unmountmenu)
 {
 }
 
@@ -270,3 +642,4 @@
 
 	return false; // Don't stop yet!
 }
+
