From aa1df4dc4dea04956f8f2798b55637dc14eb7683 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20A=C3=9Fmus?= Date: Sun, 3 Feb 2008 17:29:48 +0000 Subject: [PATCH] Incorporate work done by James Urquhart (jamesu): * Use our own BBitmapStringField implementation which also requires our own BColumn implementation. This is just a visual improvement which makes both the eventual partiton icon and device label indent with the outline level of the list item * when setting the Unmount menu item enabled state, check wether the partition in question is the /boot volume and disallow unmounting. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@23845 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/apps/drivesetup/MainWindow.cpp | 18 ++- src/apps/drivesetup/PartitionList.cpp | 169 +++++++++++++++++++++++--- src/apps/drivesetup/PartitionList.h | 48 +++++++- 3 files changed, 207 insertions(+), 28 deletions(-) diff --git a/src/apps/drivesetup/MainWindow.cpp b/src/apps/drivesetup/MainWindow.cpp index ff73b745e2..38b0995b14 100644 --- a/src/apps/drivesetup/MainWindow.cpp +++ b/src/apps/drivesetup/MainWindow.cpp @@ -29,6 +29,8 @@ #include #include #include +#include +#include class ListPopulatorVisitor : public BDiskDeviceVisitor { @@ -81,9 +83,6 @@ private: i++) { fPartitionList->AddSpace(partition->ID(), offset, size); } - } else { - fprintf(stderr, "failed to get partitioning info: %s\n", - strerror(ret)); } } @@ -480,7 +479,18 @@ fCreateMenu->SetEnabled(false); // fDeleteMI->SetEnabled(!partition->IsMounted()); fDeleteMI->SetEnabled(false); fMountMI->SetEnabled(!partition->IsMounted()); - fUnmountMI->SetEnabled(partition->IsMounted()); + + if (partition->IsMounted()) { + // see if this partition is the boot volume + BVolume volume; + BVolume bootVolume; + if (BVolumeRoster().GetBootVolume(&bootVolume) == B_OK + && partition->GetVolume(&volume) == B_OK) { + fUnmountMI->SetEnabled(volume != bootVolume); + } else { + fUnmountMI->SetEnabled(true); + } + } } else { fInitMenu->SetEnabled(false); fDeleteMI->SetEnabled(false); diff --git a/src/apps/drivesetup/PartitionList.cpp b/src/apps/drivesetup/PartitionList.cpp index 0d9b4fcd3c..36335f5027 100644 --- a/src/apps/drivesetup/PartitionList.cpp +++ b/src/apps/drivesetup/PartitionList.cpp @@ -4,6 +4,7 @@ * * Authors: * Ithamar R. Adema + * James Urquhart * Stephan Aßmus */ #include "PartitionList.h" @@ -13,10 +14,132 @@ #include +// #pragma mark - BBitmapStringField + + +BBitmapStringField::BBitmapStringField(BBitmap* bitmap, const char* string) + : Inherited(string) + , fBitmap(bitmap) +{ +} + + +BBitmapStringField::~BBitmapStringField() +{ + delete fBitmap; +} + + +void +BBitmapStringField::SetBitmap(BBitmap* bitmap) +{ + delete fBitmap; + fBitmap = bitmap; + // TODO: cause a redraw? +} + + +// #pragma mark - PartitionColumn + + +float PartitionColumn::fTextMargin = 0.0; + + +PartitionColumn::PartitionColumn(const char* title, float width, float minWidth, + float maxWidth, uint32 truncateMode, alignment align) + : Inherited(title, width, minWidth, maxWidth, align), + fTruncateMode(truncateMode) +{ + SetWantsEvents(true); +} + + +void +PartitionColumn::DrawField(BField* field, BRect rect, BView* parent) +{ + if (fTextMargin == 0.0) { + // we are the first column to draw something and need to + // init the text margin + BFont font; + parent->GetFont(&font); + fTextMargin = ceilf(font.Size() * 0.8); + } + + BBitmapStringField* bitmapField + = dynamic_cast(field); + BStringField* stringField = dynamic_cast(field); + + if (bitmapField) { + const BBitmap* bitmap = bitmapField->Bitmap(); + + // figure out the placement + float x = 0.0; + BRect r = bitmap ? bitmap->Bounds() : BRect(0, 0, 15, 15); + 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 + fTextMargin; + width = rect.right - (x + r.Width()) - (2 * fTextMargin); + r.Set(x + r.Width(), rect.top, rect.right - width, rect.bottom); + break; + + case B_ALIGN_RIGHT: + x = rect.right - fTextMargin - r.Width(); + width = (x - rect.left - (2 * fTextMargin)); + r.Set(rect.left, rect.top, rect.left + width, rect.bottom); + break; + } + + if (width != bitmapField->Width()) { + BString truncatedString(bitmapField->String()); + parent->TruncateString(&truncatedString, fTruncateMode, width + 2); + bitmapField->SetClippedString(truncatedString.String()); + bitmapField->SetWidth(width); + } + + // draw the bitmap + if (bitmap) { + parent->SetDrawingMode(B_OP_ALPHA); + parent->DrawBitmap(bitmap, BPoint(x, y)); + parent->SetDrawingMode(B_OP_OVER); + } + + // draw the string + DrawString(bitmapField->ClippedString(), parent, r); + + } else if (stringField) { + + float width = rect.Width() - (2 * fTextMargin); + + if (width != stringField->Width()) { + BString truncatedString(stringField->String()); + + parent->TruncateString(&truncatedString, fTruncateMode, width + 2); + stringField->SetClippedString(truncatedString.String()); + stringField->SetWidth(width); + } + + DrawString(stringField->ClippedString(), parent, rect); + } +} + +bool +PartitionColumn::AcceptsField(const BField* field) const +{ + return dynamic_cast(field) != NULL; +} + + +// #pragma mark - PartitionListRow + + static const char* kUnavailableString = ""; enum { -// kBitmapColumn, kDeviceColumn, kFilesystemColumn, kVolumeNameColumn, @@ -32,11 +155,20 @@ PartitionListRow::PartitionListRow(BPartition* partition) , fOffset(partition->Offset()) , fSize(partition->Size()) { -// SetField(new BBitmapField(NULL), kBitmapColumn); - BPath path; partition->GetPath(&path); - SetField(new BStringField(path.Path()), kDeviceColumn); + + BBitmap* icon = NULL; + if (partition->IsDevice()) { + icon_size size = B_MINI_ICON; + icon = new BBitmap(BRect(0, 0, size - 1, size - 1), B_RGBA32); + if (partition->GetIcon(icon, size) != B_OK) { + delete icon; + icon = NULL; + } + } + + SetField(new BBitmapStringField(icon, path.Path()), kDeviceColumn); if (partition->ContainsFileSystem()) { SetField(new BStringField(partition->ContentType()), kFilesystemColumn); @@ -66,11 +198,10 @@ PartitionListRow::PartitionListRow(partition_id parentID, off_t offset, , fOffset(offset) , fSize(size) { -// SetField(new BBitmapField(NULL), kBitmapColumn); + // TODO: design icon for spaces on partitions + SetField(new BBitmapStringField(NULL, "-"), kDeviceColumn); - SetField(new BStringField("-"), kDeviceColumn); - - SetField(new BStringField("Empty"), kFilesystemColumn); + SetField(new BStringField(""), kFilesystemColumn); SetField(new BStringField(kUnavailableString), kVolumeNameColumn); SetField(new BStringField(kUnavailableString), kMountedAtColumn); @@ -83,18 +214,16 @@ PartitionListRow::PartitionListRow(partition_id parentID, off_t offset, PartitionListView::PartitionListView(const BRect& frame, uint32 resizeMode) : Inherited(frame, "storagelist", resizeMode, 0, B_NO_BORDER, true) { -// AddColumn(new BBitmapColumn("", 20, 20, 100, B_ALIGN_CENTER), -// kBitmapColumn); - AddColumn(new BStringColumn("Device", 150, 50, 500, B_TRUNCATE_MIDDLE), - kDeviceColumn); - AddColumn(new BStringColumn("Filesystem", 100, 50, 500, B_TRUNCATE_MIDDLE), - kFilesystemColumn); - AddColumn(new BStringColumn("Volume Name", 130, 50, 500, B_TRUNCATE_MIDDLE), - kVolumeNameColumn); - AddColumn(new BStringColumn("Mounted At", 100, 50, 500, B_TRUNCATE_MIDDLE), - kMountedAtColumn); - AddColumn(new BStringColumn("Size", 100, 50, 500, B_TRUNCATE_END, - B_ALIGN_RIGHT), kSizeColumn); + AddColumn(new PartitionColumn("Device", 150, 50, 500, + B_TRUNCATE_MIDDLE), kDeviceColumn); + AddColumn(new PartitionColumn("Filesystem", 100, 50, 500, + B_TRUNCATE_MIDDLE), kFilesystemColumn); + AddColumn(new PartitionColumn("Volume Name", 130, 50, 500, + B_TRUNCATE_MIDDLE), kVolumeNameColumn); + AddColumn(new PartitionColumn("Mounted At", 100, 50, 500, + B_TRUNCATE_MIDDLE), kMountedAtColumn); + AddColumn(new PartitionColumn("Size", 100, 50, 500, + B_TRUNCATE_END, B_ALIGN_RIGHT), kSizeColumn); SetSortingEnabled(false); } diff --git a/src/apps/drivesetup/PartitionList.h b/src/apps/drivesetup/PartitionList.h index f5f7135206..9e53296252 100644 --- a/src/apps/drivesetup/PartitionList.h +++ b/src/apps/drivesetup/PartitionList.h @@ -4,23 +4,61 @@ * * Authors: * Ithamar R. Adema + * James Urquhart * Stephan Aßmus */ #ifndef PARTITIONLIST_H #define PARTITIONLIST_H -class PartitionListRow; -class PartitionListView; - - #include +#include #include class BPartition; +// A field type displaying both a bitmap and a string so that the +// tree display looks nicer (both text and bitmap are indented) +class BBitmapStringField : public BStringField { + typedef BStringField Inherited; +public: + BBitmapStringField(BBitmap* bitmap, + const char* string); + virtual ~BBitmapStringField(); + + void SetBitmap(BBitmap* bitmap); + const BBitmap* Bitmap() const + { return fBitmap; } + +private: + BBitmap* fBitmap; +}; + + +// BColumn for PartitionListView which knows how to render +// a BBitmapStringField +class PartitionColumn : public BTitledColumn { + typedef BTitledColumn Inherited; +public: + PartitionColumn(const char* title, + float width, float minWidth, + float maxWidth, uint32 truncateMode, + alignment align = B_ALIGN_LEFT); + + virtual void DrawField(BField* field, BRect rect, + BView* parent); + + virtual bool AcceptsField(const BField* field) const; + +private: + uint32 fTruncateMode; + static float fTextMargin; +}; + + +// BRow for the PartitionListView class PartitionListRow : public BRow { typedef BRow Inherited; public: @@ -30,6 +68,8 @@ public: partition_id ID() const { return fPartitionID; } + partition_id ParentID() const + { return fParentID; } off_t Offset() const { return fOffset; } off_t Size() const