DiskUsage enhancement (ticket #3520)

* the volume are now displayed in tabs, mounting and unmounting volume adds and remove tabs accordingly
 * the infos (file size, etc..) are now displayed below the graph
 * node monitoring tells you when your current view is outdated. (the ticket suggested to adjust the view automatically, but I'll wait for comments on this first).
 * Drag&Dropping a file on the graph changes the tabview to the tab representing the volume owning that file.



git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@38958 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Philippe Saint-Pierre
2010-10-12 23:50:09 +00:00
parent 4cbffbf53f
commit dde4ac4386
17 changed files with 614 additions and 389 deletions
+1
View File
@@ -90,6 +90,7 @@ App::ReadyToRun()
}
fMainWindow = new MainWindow(frame);
fMainWindow->Show();
if (fSavedRefsReceived) {
// RefsReceived() was called earlier than ReadyToRun()
+2
View File
@@ -78,6 +78,7 @@ read_resources(const char* appSignature)
kVolMenuLabel = LoadString("STR_VM_LABEL");
kOneFile = LoadString("STR_1_FILE");
kManyFiles = LoadString("STR_N_FILES");
kStrScan = LoadString("STR_SCAN");
kStrRescan = LoadString("STR_RESCAN");
kStrScanningX = LoadString("STR_SCN_X");
kStrUnavail = LoadString("STR_UNAVAIL");
@@ -94,6 +95,7 @@ read_resources(const char* appSignature)
kInfoTimeFmt = LoadString("STR_TIMEFMT");
kInfoKind = LoadString("STR_KIND");
kInfoPath = LoadString("STR_PATH");
kOutdatedStr = LoadString("STR_OUTDATED");
kWindowColor = ui_color(B_PANEL_BACKGROUND_COLOR);
kOutlineColor = LoadColor("RGB_PIE_OL");
+3
View File
@@ -28,7 +28,9 @@
// Resources
EXTERN char* kStrScan;
EXTERN char* kStrRescan;
EXTERN char* kOutdatedStr;
EXTERN char* kStrScanningX;
EXTERN char* kStrUnavail;
EXTERN char* kVolMenuLabel;
@@ -93,6 +95,7 @@ EXTERN bool kFoundHelpFile;
#define kScanRefresh 'gSRF'
#define kScanProgress 'gSPR'
#define kScanDone 'gSDN'
#define kOutdatedMsg 'gOUT'
#define deg2rad(x) (2.0 * M_PI * (x) / 360.0)
#define rad2deg(x) (360.0 * (x) / (2.0 * M_PI))
+175 -137
View File
@@ -12,47 +12,44 @@
#include <Bitmap.h>
#include <Box.h>
#include <MenuField.h>
#include <MenuItem.h>
#include <TabView.h>
#include <NodeMonitor.h>
#include <Path.h>
#include <PopUpMenu.h>
#include <SupportDefs.h>
#include <Volume.h>
#include <VolumeRoster.h>
#include <Window.h>
#include <LayoutBuilder.h>
#include "Common.h"
#include "VolumeView.h"
class VolumeMenuItem: public BMenuItem {
class VolumeTab: public BTab {
public:
VolumeMenuItem(BVolume* volume, BMessage* message);
virtual ~VolumeMenuItem();
VolumeTab(BVolume* volume);
virtual ~VolumeTab();
virtual void GetContentSize(float* width, float* height);
virtual void DrawContent();
BVolume* Volume() const
{ return fVolume; }
float IconWidth() const;
BVolume* Volume() const
{ return fVolume; }
status_t Invoke(BMessage* mesage = NULL)
{ return BMenuItem::Invoke(); }
virtual void DrawLabel(BView* owner, BRect frame);
private:
BBitmap* fIcon;
BVolume* fVolume;
BBitmap* fIcon;
BVolume* fVolume;
};
VolumeMenuItem::VolumeMenuItem(BVolume* volume, BMessage* message)
VolumeTab::VolumeTab(BVolume* volume)
:
BMenuItem(kEmptyStr, message),
BTab(),
fIcon(new BBitmap(BRect(0, 0, 15, 15), B_RGBA32)),
fVolume(volume)
{
char name[B_PATH_NAME_LENGTH];
fVolume->GetName(name);
SetLabel(name);
if (fVolume->GetIcon(fIcon, B_MINI_ICON) < B_OK) {
delete fIcon;
fIcon = NULL;
@@ -60,53 +57,56 @@ VolumeMenuItem::VolumeMenuItem(BVolume* volume, BMessage* message)
}
VolumeMenuItem::~VolumeMenuItem()
float
VolumeTab::IconWidth() const
{
if (fIcon != NULL)
// add a small margin
return fIcon->Bounds().Width() + kSmallHMargin;
else
return 0.0f;
}
void
VolumeTab::DrawLabel(BView* owner, BRect frame)
{
owner->SetDrawingMode(B_OP_OVER);
if (fIcon != NULL) {
owner->MovePenTo(frame.left + kSmallHMargin,
(frame.top + frame.bottom - fIcon->Bounds().Height()) / 2.0);
owner->DrawBitmap(fIcon);
}
font_height fh;
owner->GetFontHeight(&fh);
owner->SetHighColor(ui_color(B_CONTROL_TEXT_COLOR));
owner->DrawString(Label(),
BPoint(frame.left + IconWidth() + kSmallHMargin,
(frame.top + frame.bottom - fh.ascent - fh.descent) / 2.0
+ fh.ascent));
}
VolumeTab::~VolumeTab()
{
delete fIcon;
delete fVolume;
}
void
VolumeMenuItem::GetContentSize(float* width, float* height)
{
*width = be_plain_font->StringWidth(Label());
struct font_height fh;
be_plain_font->GetHeight(&fh);
float fontHeight = fh.ascent + fh.descent + fh.leading;
if (fIcon) {
*height = max_c(fontHeight, fIcon->Bounds().Height());
*width += fIcon->Bounds().Width() + kSmallHMargin;
} else
*height = fontHeight;
}
void
VolumeMenuItem::DrawContent()
{
if (fIcon) {
Menu()->SetDrawingMode(B_OP_OVER);
Menu()->MovePenBy(0.0, -1.0);
Menu()->DrawBitmap(fIcon);
Menu()->SetDrawingMode(B_OP_COPY);
Menu()->MovePenBy(fIcon->Bounds().Width() + kSmallHMargin, 0.0);
}
BMenuItem::DrawContent();
}
// #pragma mark -
class ControlsView::VolumePopup: public BMenuField {
class ControlsView::VolumeTabView: public BTabView {
public:
VolumePopup(BRect r);
virtual ~VolumePopup();
VolumeTabView();
virtual ~VolumeTabView();
virtual void AttachedToWindow();
virtual void MessageReceived(BMessage* message);
virtual BRect TabFrame(int32 index) const;
BVolume* FindDeviceFor(dev_t device,
bool invoke = false);
@@ -119,16 +119,40 @@ private:
};
ControlsView::VolumePopup::VolumePopup(BRect r)
ControlsView::VolumeTabView::VolumeTabView()
:
BMenuField(r, NULL, kVolMenuLabel, new BPopUpMenu(kVolMenuDefault), false,
B_FOLLOW_LEFT)
BTabView("volume_tabs", B_WIDTH_FROM_LABEL)
{
SetViewColor(kWindowColor);
SetLowColor(kWindowColor);
}
SetDivider(kSmallHMargin + StringWidth(kVolMenuLabel));
ControlsView::VolumeTabView::~VolumeTabView()
{
fVolumeRoster->StopWatching();
delete fVolumeRoster;
}
BRect
ControlsView::VolumeTabView::TabFrame(int32 index) const
{
float height = BTabView::TabFrame(index).Height();
float x = 0.0f;
for (int32 i = 0; i < index; i++) {
x += StringWidth(TabAt(i)->Label()) + 3.0f * kSmallHMargin
+ ((VolumeTab*)TabAt(i))->IconWidth();
}
return BRect(x, 0.0f,
x + StringWidth(TabAt(index)->Label()) + 3.0f * kSmallHMargin
+ ((VolumeTab*)TabAt(index))->IconWidth(),
height);
}
void
ControlsView::VolumeTabView::AttachedToWindow()
{
// Populate the menu with the persistent volumes.
fVolumeRoster = new BVolumeRoster();
@@ -136,32 +160,20 @@ ControlsView::VolumePopup::VolumePopup(BRect r)
while (fVolumeRoster->GetNextVolume(&tempVolume) == B_OK) {
if (tempVolume.IsPersistent()) {
BVolume* volume = new BVolume(tempVolume);
BMessage* message = new BMessage(kMenuSelectVol);
message->AddPointer(kNameVolPtr, volume);
VolumeMenuItem *item = new VolumeMenuItem(volume, message);
Menu()->AddItem(item);
VolumeTab *item = new VolumeTab(volume);
char name[B_PATH_NAME_LENGTH];
volume->GetName(name);
AddTab(new VolumeView(name, volume), item);
}
}
}
ControlsView::VolumePopup::~VolumePopup()
{
fVolumeRoster->StopWatching();
delete fVolumeRoster;
}
void
ControlsView::VolumePopup::AttachedToWindow()
{
// Begin watching mount and unmount events.
fVolumeRoster->StartWatching(BMessenger(this));
}
void
ControlsView::VolumePopup::MessageReceived(BMessage* message)
ControlsView::VolumeTabView::MessageReceived(BMessage* message)
{
switch (message->what) {
case B_NODE_MONITOR:
@@ -176,24 +188,50 @@ ControlsView::VolumePopup::MessageReceived(BMessage* message)
}
break;
case kBtnRescan:
ViewForTab(Selection())->MessageReceived(message);
break;
case B_SIMPLE_DATA:
case B_REFS_RECEIVED:
{
entry_ref ref;
for (int i = 0; message->FindRef("refs", i, &ref) == B_OK; i++) {
BEntry entry(&ref, true);
BPath path;
entry.GetPath(&path);
dev_t device = dev_for_path(path.Path());
for (int j = 0; VolumeTab* item = (VolumeTab*)TabAt(j); j++) {
if (item->Volume()->Device() == device) {
Select(j);
((VolumeView*)(item->View()))->SetPath(path);
break;
}
}
}
break;
}
default:
BMenuField::MessageReceived(message);
BTabView::MessageReceived(message);
break;
}
}
BVolume*
ControlsView::VolumePopup::FindDeviceFor(dev_t device, bool invoke)
ControlsView::VolumeTabView::FindDeviceFor(dev_t device, bool invoke)
{
BVolume* volume = NULL;
// Iterate through items looking for a BVolume representing this device.
for (int i = 0; VolumeMenuItem* item = (VolumeMenuItem*)Menu()->ItemAt(i); i++) {
for (int i = 0; VolumeTab* item = (VolumeTab*)TabAt(i); i++) {
if (item->Volume()->Device() == device) {
volume = item->Volume();
if (invoke)
item->Invoke();
Select(i);
break;
}
}
@@ -203,43 +241,36 @@ ControlsView::VolumePopup::FindDeviceFor(dev_t device, bool invoke)
void
ControlsView::VolumePopup::_AddVolume(dev_t device)
ControlsView::VolumeTabView::_AddVolume(dev_t device)
{
// Make sure the volume is not already in the menu.
for (int i = 0; i < Menu()->CountItems(); i++) {
VolumeMenuItem* item = (VolumeMenuItem*)Menu()->ItemAt(i);
for (int i = 0; VolumeTab* item = (VolumeTab*)TabAt(i); i++) {
if (item->Volume()->Device() == device)
return;
}
// Add the newly mounted volume to the menu.
BVolume* volume = new BVolume(device);
BMessage* message = new BMessage(kMenuSelectVol);
message->AddPointer(kNameVolPtr, volume);
VolumeMenuItem* item = new VolumeMenuItem(volume, message);
Menu()->AddItem(item);
VolumeTab* item = new VolumeTab(volume);
char name[B_PATH_NAME_LENGTH];
volume->GetName(name);
AddTab(new VolumeView(name, volume), item);
Invalidate();
}
void
ControlsView::VolumePopup::_RemoveVolume(dev_t device)
ControlsView::VolumeTabView::_RemoveVolume(dev_t device)
{
for (int i = 0; i < Menu()->CountItems(); i++) {
VolumeMenuItem* item = (VolumeMenuItem*)Menu()->ItemAt(i);
for (int i = 0; VolumeTab* item = (VolumeTab*)TabAt(i); i++) {
if (item->Volume()->Device() == device) {
// If the volume being removed is currently selected, prompt for a
// different volume.
if (item->IsMarked()) {
// update the displayed volume label now that there is no marked
// item:
Menu()->Superitem()->SetLabel(kVolMenuDefault);
BMessage messae(kMenuSelectVol);
messae.AddPointer(kNameVolPtr, NULL);
Window()->PostMessage(&messae);
}
Menu()->RemoveItem(item);
if (i == 0)
Select(1);
else
Select(i - 1);
RemoveTab(i);
delete item;
return;
}
}
@@ -249,43 +280,34 @@ ControlsView::VolumePopup::_RemoveVolume(dev_t device)
// #pragma mark -
ControlsView::ControlsView(BRect r)
: BView(r, NULL, B_FOLLOW_LEFT_RIGHT, 0)
ControlsView::ControlsView()
:
BView(NULL, B_WILL_DRAW)
{
SetViewColor(kWindowColor);
SetLayout(new BGroupLayout(B_VERTICAL));
fVolumeTabView = new VolumeTabView();
AddChild(BLayoutBuilder::Group<>(B_VERTICAL)
.Add(fVolumeTabView)
);
}
r.top += kSmallVMargin;
r.right -= kSmallHMargin;
float buttonWidth = kButtonMargin + StringWidth(kHelpBtnLabel);
r.left = r.right - buttonWidth;
BButton* helpButton = new BButton(r, NULL, kHelpBtnLabel, new BMessage(kBtnHelp),
B_FOLLOW_RIGHT);
if (!kFoundHelpFile)
helpButton->SetEnabled(false);
r.right = r.left - kSmallHMargin;
buttonWidth = kButtonMargin + StringWidth(kStrRescan);
r.left = r.right - max_c(kMinButtonWidth, buttonWidth);
fRescanButton = new BButton(r, NULL, kStrRescan, new BMessage(kBtnRescan),
B_FOLLOW_RIGHT);
void
ControlsView::MessageReceived(BMessage* msg)
{
switch (msg->what) {
case B_SIMPLE_DATA:
case B_REFS_RECEIVED:
fVolumeTabView->MessageReceived(msg);
break;
fVolumePopup = new VolumePopup(
BRect(kSmallHMargin, kSmallVMargin, r.left - kSmallHMargin, kSmallVMargin));
case kBtnRescan:
fVolumeTabView->MessageReceived(msg);
break;
float width, height;
fRescanButton->GetPreferredSize(&width, &height);
ResizeTo(Bounds().Width(), height + 6.0);
// Horizontal divider
r = Bounds();
r.top = r.bottom - 1.0;
r.left -= 5.0; r.right += 5.0;
BBox* divider = new BBox(r, NULL, B_FOLLOW_LEFT_RIGHT, B_WILL_DRAW);
AddChild(fVolumePopup);
AddChild(divider);
AddChild(fRescanButton);
AddChild(helpButton);
default:
BView::MessageReceived(msg);
}
}
@@ -294,8 +316,24 @@ ControlsView::~ControlsView()
}
void
ControlsView::ShowInfo(const FileInfo* info)
{
((VolumeView*)fVolumeTabView->ViewForTab(
fVolumeTabView->Selection()))->ShowInfo(info);
}
void
ControlsView::SetRescanEnabled(bool enabled)
{
((VolumeView*)fVolumeTabView->ViewForTab(
fVolumeTabView->Selection()))->SetRescanEnabled(enabled);
}
BVolume*
ControlsView::FindDeviceFor(dev_t device, bool invoke)
{
return fVolumePopup->FindDeviceFor(device, invoke);
return fVolumeTabView->FindDeviceFor(device, invoke);
}
+12 -9
View File
@@ -9,29 +9,32 @@
#ifndef CONTROLS_VIEW_H
#define CONTROLS_VIEW_H
#include <Button.h>
#include <View.h>
class BMessage;
class BVolume;
struct FileInfo;
class ControlsView: public BView {
public:
ControlsView(BRect r);
ControlsView();
virtual ~ControlsView();
void SetRescanEnabled(bool enable)
{ fRescanButton->SetEnabled(enable); }
virtual void MessageReceived(BMessage* msg);
BVolume* FindDeviceFor(dev_t device,
bool invoke = false);
private:
class VolumePopup;
VolumePopup* fVolumePopup;
BButton* fRescanButton;
void SetRescanEnabled(bool enabled);
void ShowInfo(const FileInfo* info);
private:
class VolumeTabView;
VolumeTabView* fVolumeTabView;
};
+2 -1
View File
@@ -62,6 +62,7 @@ resource(101, "N_PIE_COLORS") (uint8)4;
resource(103, "STR_N_FILES") "%d files";
resource(102, "STR_1_FILE") "%d file";
resource(101, "STR_VM_LABEL") "Volume:";
resource(120, "STR_SCAN") "Scan";
resource(104, "STR_RESCAN") "Rescan";
resource(105, "STR_SCN_X") "Scanning ";
resource(106, "STR_UNAVAIL") "file unavailable";
@@ -78,4 +79,4 @@ resource(116, "STR_MOD") "Modified";
resource(117, "STR_TIMEFMT") "%a, %d %b %Y, %r";
resource(118, "STR_KIND") "Kind";
resource(119, "STR_PATH") "Path";
resource(121, "STR_OUTDATED") "Outdated view";
+2 -1
View File
@@ -1,6 +1,6 @@
SubDir HAIKU_TOP src apps diskusage ;
UsePrivateHeaders mount shared tracker ;
UsePrivateHeaders mount shared tracker storage ;
SubDirHdrs $(HAIKU_TOP) src kits tracker ;
Application DiskUsage :
@@ -14,6 +14,7 @@ Application DiskUsage :
Scanner.cpp
Snapshot.cpp
StatusView.cpp
VolumeView.cpp
: be $(TARGET_LIBSTDC++)
: DiskUsage.rdef
;
+20 -50
View File
@@ -7,8 +7,6 @@
* as long as it is accompanied by it's documentation and this copyright notice.
* The software comes with no warranty, etc.
*/
#include "MainWindow.h"
#include <Application.h>
@@ -16,58 +14,28 @@
#include <Roster.h>
#include <Screen.h>
#include <LayoutBuilder.h>
#include "Common.h"
#include "ControlsView.h"
#include "PieView.h"
#include "StatusView.h"
const float kMinWinSize = 275.0;
MainWindow::MainWindow(BRect pieRect)
:
BWindow(pieRect, "DiskUsage", B_TITLED_WINDOW,
B_ASYNCHRONOUS_CONTROLS | B_QUIT_ON_WINDOW_CLOSE)
B_ASYNCHRONOUS_CONTROLS | B_QUIT_ON_WINDOW_CLOSE
| B_AUTO_UPDATE_SIZE_LIMITS)
{
BRect r = Bounds();
r.bottom = r.top + 1.0;
fControlsView = new ControlsView(r);
float cvHeight = fControlsView->Bounds().Height();
AddChild(fControlsView);
fControlsView = new ControlsView();
r = Bounds();
r.top = r.bottom - 1.0;
fStatusView = new StatusView(r);
float svHeight = fStatusView->Bounds().Height();
SetLayout(new BGroupLayout(B_VERTICAL));
float winHeight = pieRect.Height() + cvHeight + svHeight;
fStatusView->MoveTo(0.0, winHeight - svHeight);
ResizeTo(r.Width(), winHeight);
AddChild(fStatusView);
r = fControlsView->Frame();
r.top = r.bottom + 1.0;
r.bottom = fStatusView->Frame().top - 1.0;
fPieView = new PieView(r, this);
AddChild(fPieView);
Show();
// Note: The following code is semi-broken because BScreen::Frame()
// returns incorrect dimensions for the G200 in 1152x864 mode. I reported
// this bug, and Be said it's not a bug -- the Matrox driver actually uses
// a resolution of 1152x900 in that mode. Oh well.
Lock();
float extraHeight = fControlsView->Bounds().Height()
+ fStatusView->Bounds().Height();
float minHeight = kMinWinSize + extraHeight;
float maxHeight = BScreen(this).Frame().Height();
float maxWidth = maxHeight - extraHeight;
Unlock();
SetSizeLimits(kMinWinSize, maxWidth, minHeight, maxHeight);
AddChild(BLayoutBuilder::Group<>(B_VERTICAL)
.Add(fControlsView)
.SetInsets(5, 5, 5, 5)
);
float maxHeight = BScreen(this).Frame().Height() - 12;
fControlsView->SetExplicitMaxSize(BSize(maxHeight, maxHeight));
}
@@ -81,9 +49,11 @@ MainWindow::MessageReceived(BMessage* message)
{
switch (message->what) {
case kBtnRescan:
case kMenuSelectVol:
fControlsView->MessageReceived(message);
break;
case B_SIMPLE_DATA:
case B_REFS_RECEIVED:
fPieView->MessageReceived(message);
fControlsView->MessageReceived(message);
break;
case kBtnHelp:
@@ -109,16 +79,16 @@ MainWindow::QuitRequested()
void
MainWindow::ShowInfo(const FileInfo* info)
MainWindow::SetRescanEnabled(bool enabled)
{
fStatusView->ShowInfo(info);
fControlsView->SetRescanEnabled(enabled);
}
void
MainWindow::SetRescanEnabled(bool enabled)
MainWindow::ShowInfo(const FileInfo* info)
{
fControlsView->SetRescanEnabled(enabled);
fControlsView->ShowInfo(info);
}
+2 -6
View File
@@ -10,7 +10,6 @@
#ifndef MAIN_WINDOW_H
#define MAIN_WINDOW_H
#include <Window.h>
@@ -18,8 +17,6 @@ class BVolume;
class ControlsView;
struct FileInfo;
class PieView;
class StatusView;
class MainWindow: public BWindow {
public:
@@ -29,15 +26,14 @@ public:
virtual void MessageReceived(BMessage* message);
virtual bool QuitRequested();
void ShowInfo(const FileInfo* info);
void SetRescanEnabled(bool enabled);
BVolume* FindDeviceFor(dev_t device,
bool invoke = false);
void ShowInfo(const FileInfo* info);
private:
ControlsView* fControlsView;
PieView* fPieView;
StatusView* fStatusView;
};
#endif // MAIN_WINDOW_H
+85 -124
View File
@@ -14,7 +14,6 @@
#include <fs_info.h>
#include <math.h>
#include <Alert.h>
#include <AppFileInfo.h>
#include <Bitmap.h>
#include <Entry.h>
@@ -41,8 +40,6 @@ static const int32 kIdxOpen = 1;
static const int32 kIdxOpenWith = 2;
static const int32 kIdxRescan = 3;
// TODO: It would be nice to make a common base class for AppMenuItem and
// VolMenuItem (menu items that include an icon).
class AppMenuItem : public BMenuItem {
public:
@@ -125,20 +122,17 @@ AppMenuItem::DrawContent()
// #pragma mark - PieView
PieView::PieView(BRect frame, MainWindow* window)
PieView::PieView(BVolume* volume)
:
BView(frame, NULL, B_FOLLOW_ALL,
B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE | B_SUBPIXEL_PRECISE),
fWindow(window),
fScanners(),
fCurrentVolume(NULL),
BView(NULL, B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE | B_SUBPIXEL_PRECISE),
fWindow(NULL),
fScanner(NULL),
fVolume(volume),
fMouseOverInfo(),
fClicked(false),
fDragging(false)
fDragging(false),
fOutdated(false)
{
SetViewColor(B_TRANSPARENT_COLOR);
SetLowColor(kWindowColor);
fMouseOverMenu = new BPopUpMenu(kEmptyStr, false, false);
fMouseOverMenu->AddItem(new BMenuItem(kMenuGetInfo, NULL), kIdxGetInfo);
fMouseOverMenu->AddItem(new BMenuItem(kMenuOpen, NULL), kIdxOpen);
@@ -160,16 +154,19 @@ PieView::PieView(BRect frame, MainWindow* window)
}
void
PieView::AttachedToWindow()
{
fWindow = (MainWindow*)Window();
}
PieView::~PieView()
{
delete fMouseOverMenu;
delete fFileUnavailableMenu;
while (fScanners.size() != 0) {
ScannerMap::iterator i = fScanners.begin();
(*i).second->RequestQuit();
fScanners.erase(i);
}
if (fScanner != NULL)
fScanner->RequestQuit();
}
@@ -177,41 +174,31 @@ void
PieView::MessageReceived(BMessage* message)
{
switch (message->what) {
case B_SIMPLE_DATA:
case B_REFS_RECEIVED:
{
entry_ref ref;
for (int i = 0; message->FindRef("refs", i, &ref) == B_OK; i++) {
BEntry entry(&ref, true);
_HandleArg(&entry);
}
break;
}
case kBtnRescan:
if (fCurrentVolume != NULL) {
fScanners[fCurrentVolume]->Refresh();
if (fVolume != NULL) {
if (fScanner != NULL)
fScanner->Refresh();
else
_ShowVolume(fVolume);
fOutdated = false;
Invalidate();
}
break;
case kMenuSelectVol:
{
BVolume* volume;
if (message->FindPointer(kNameVolPtr, (void**)&volume) == B_OK)
_ShowVolume(volume);
break;
}
case kScanProgress:
case kScanDone:
{
BVolume* volume;
if (message->FindPointer(kNameVolPtr, (void**)&volume) == B_OK
&& volume == fCurrentVolume) {
Invalidate();
break;
}
case kOutdatedMsg:
{
if (!fScanner->IsBusy()) {
fOutdated = true;
Invalidate();
}
break;
}
default:
@@ -251,14 +238,15 @@ PieView::MouseUp(BPoint where)
// If the primary button was released and there was no dragging happening,
// just zoom in or out.
if (fClicked && !fDragging) {
Scanner* scanner = fScanners[fCurrentVolume];
FileInfo* info = _FileAt(where);
if (info != NULL) {
if (info == scanner->CurrentDir()) {
scanner->ChangeDir(info->parent);
if (info == fScanner->CurrentDir()) {
fScanner->ChangeDir(info->parent);
fOutdated = fScanner->IsOutdated();
Invalidate();
} else if (info->children.size() > 0) {
scanner->ChangeDir(info);
fScanner->ChangeDir(info);
fOutdated = fScanner->IsOutdated();
Invalidate();
}
}
@@ -307,27 +295,32 @@ PieView::MouseMoved(BPoint where, uint32 transit, const BMessage* dragMessage)
void
PieView::Draw(BRect updateRect)
{
if (fScanners.find(fCurrentVolume) != fScanners.end()) {
if (fScanner != NULL) {
// There is a current volume.
Scanner* scanner = fScanners[fCurrentVolume];
if (scanner->IsBusy()) {
if (fScanner->IsBusy()) {
// Show progress of scanning.
_DrawProgressBar(updateRect);
fWindow->SetRescanEnabled(false);
if (fWindow != NULL)
fWindow->SetRescanEnabled(false);
} else {
_DrawPieChart(updateRect);
fWindow->SetRescanEnabled(true);
if (fWindow != NULL)
fWindow->SetRescanEnabled(true);
}
} else {
// No volume has been selected, so display a prompt for one.
FillRect(updateRect, B_SOLID_LOW);
BRect b = Bounds();
float strWidth = StringWidth(kVolPrompt);
float bx = (b.left + b.Width() - strWidth) / 2.0;
float by = (b.top + b.Height()) / 2.0;
SetHighColor(0x00, 0x00, 0x00);
DrawString(kVolPrompt, BPoint(bx, by));
fWindow->SetRescanEnabled(false);
}
}
void
PieView::SetPath(BPath path)
{
if (fScanner == NULL)
_ShowVolume(fVolume);
if (fScanner != NULL) {
string desiredPath(path.Path());
fScanner->SetDesiredPath(desiredPath);
Invalidate();
}
}
@@ -335,57 +328,17 @@ PieView::Draw(BRect updateRect)
// #pragma mark - private
void
PieView::_HandleArg(const BEntry* entry)
{
// Going through these seemingly pointless gyrations (instead of getting
// the dev_t directly from the BEntry) allows us to process volumes
// properly. It looks like a dropped volume refers to dev_t 1 (why?), but
// getting the dev_t from the path allows us to get at the dev_t where the
// root directory actually lives.
BPath path;
entry->GetPath(&path);
dev_t device = dev_for_path(path.Path());
// Set the desired path in the scanner.
Scanner* scanner = NULL;
ScannerMap::iterator i = fScanners.begin();
while (i != fScanners.end()) {
if ((*i).second->Device() == device) {
scanner = (*i).second;
break;
}
i++;
}
if (scanner == NULL) {
BVolume* volume = fWindow->FindDeviceFor(device);
if (volume != NULL)
scanner = fScanners[volume] = new Scanner(volume, this);
}
if (scanner != NULL) {
string desiredPath(path.Path());
scanner->SetDesiredPath(desiredPath);
// Select the volume on the menu.
fWindow->FindDeviceFor(device, true);
}
}
void
PieView::_ShowVolume(BVolume* volume)
{
if (volume != NULL) {
if (fScanners.find(volume) == fScanners.end())
fScanners[volume] = new Scanner(volume, this);
Scanner* scanner = fScanners[volume];
if (scanner->Snapshot() == NULL)
scanner->Refresh();
if (fScanner == NULL)
fScanner = new Scanner(volume, this);
if (fScanner->Snapshot() == NULL)
fScanner->Refresh();
}
fCurrentVolume = volume;
Invalidate();
}
@@ -416,7 +369,7 @@ PieView::_DrawProgressBar(BRect updateRect)
bx += 1.0; by += 1.0;
ex -= 1.0; ey -= 1.0;
float mx = bx + floorf((kProgBarWidth - 2.0)
* fScanners[fCurrentVolume]->Progress() / 100.0 + 0.5);
* fScanner->Progress() / 100.0 + 0.5);
SetHighColor(tint_color(kWindowColor, B_DARKEN_1_TINT));
FillRect(BRect(mx, by, ex, ey));
@@ -433,7 +386,7 @@ PieView::_DrawProgressBar(BRect updateRect)
FillRect(BRect(bx, by, mx, ey));
// Tell what we are doing.
const char* task = fScanners[fCurrentVolume]->Task();
const char* task = fScanner->Task();
float strWidth = StringWidth(task);
bx = (b.left + b.Width() - strWidth) / 2.0;
by -= fFontHeight + 2.0 * kSmallVMargin;
@@ -465,7 +418,7 @@ PieView::_DrawPieChart(BRect updateRect)
pieRect.bottom += moveBy;
}
int colorIdx = 0;
FileInfo* currentDir = fScanners[fCurrentVolume]->CurrentDir();
FileInfo* currentDir = fScanner->CurrentDir();
FileInfo* parent = currentDir;
while (parent != NULL) {
parent = parent->parent;
@@ -473,16 +426,21 @@ PieView::_DrawPieChart(BRect updateRect)
}
_DrawDirectory(pieRect, currentDir, 0.0, 0.0, colorIdx % kBasePieColorCount,
0);
if (fOutdated) {
BRect b = Bounds();
// This is just for the case when the mouse hovers over the view
// while the scanning process is running and then does not move
// until after the results are shown. In that case the info will
// not automatically update. (TODO: fix this and put into MessageReceived()
// kScanDone - currently, fileAt() returns NULL (mouseoverinfo...))
BPoint where;
uint32 ignore;
GetMouse(&where, &ignore, false);
fWindow->ShowInfo(_FileAt(where));
float strWidth = StringWidth(kOutdatedStr);
float bx = (b.Width() - strWidth - kSmallHMargin);
struct font_height fh;
be_plain_font->GetHeight(&fh);
float by = (b.Height() - ceil(fh.descent) - kSmallVMargin);
SetHighColor(0x00, 0x00, 0x00);
DrawString(kOutdatedStr, BPoint(bx, by));
}
}
@@ -500,7 +458,7 @@ PieView::_DrawDirectory(BRect b, FileInfo* info, float parentSpan,
else if (info != NULL)
info->color = colorIdx;
VolumeSnapshot* snapshot = fScanners[fCurrentVolume]->Snapshot();
VolumeSnapshot* snapshot = fScanner->Snapshot();
float cx = floorf(b.left + b.Width() / 2.0 + 0.5);
float cy = floorf(b.top + b.Height() / 2.0 + 0.5);
@@ -525,7 +483,8 @@ PieView::_DrawDirectory(BRect b, FileInfo* info, float parentSpan,
FillEllipse(BPoint(cx, cy), kPieCenterSize, kPieCenterSize);
SetHighColor(kBasePieColor[0]);
FillArc(BPoint(cx, cy), kPieCenterSize, kPieCenterSize, 0.0, mySpan);
FillArc(BPoint(cx, cy), kPieCenterSize, kPieCenterSize, 0.0,
mySpan);
// Show total volume capacity.
char label[B_PATH_NAME_LENGTH];
@@ -560,7 +519,8 @@ PieView::_DrawDirectory(BRect b, FileInfo* info, float parentSpan,
SetPenSize(1.0);
SetHighColor(kOutlineColor);
StrokeEllipse(BPoint(cx, cy), kPieCenterSize + 0.5, kPieCenterSize + 0.5);
StrokeEllipse(BPoint(cx, cy), kPieCenterSize + 0.5,
kPieCenterSize + 0.5);
// Show the name of the volume or directory.
BString label(displayName);
@@ -803,7 +763,7 @@ PieView::_ShowContextMenu(FileInfo* info, BPoint p)
_Launch(info);
break;
case kIdxRescan:
fScanners[fCurrentVolume]->Refresh(info);
fScanner->Refresh(info);
Invalidate();
break;
default: // must be "Open With" submenu
@@ -844,6 +804,7 @@ PieView::_Launch(FileInfo* info, const entry_ref* appRef)
}
}
void
PieView::_OpenInfo(FileInfo* info, BPoint p)
{
+8 -6
View File
@@ -20,6 +20,7 @@
class AppMenuItem;
class BEntry;
class BMenu;
class BPath;
class BPopUpMenu;
class BVolume;
struct entry_ref;
@@ -33,18 +34,19 @@ using std::vector;
class PieView: public BView {
public:
PieView(BRect frame, MainWindow* window);
PieView(BVolume* volume);
virtual ~PieView();
virtual void AttachedToWindow();
virtual void MessageReceived(BMessage* message);
virtual void MouseDown(BPoint where);
virtual void MouseUp(BPoint where);
virtual void MouseMoved(BPoint where, uint32 transit,
const BMessage* dragMessage);
virtual void Draw(BRect updateRect);
void SetPath(BPath path);
private:
void _HandleArg(const BEntry* entry);
void _ShowVolume(BVolume* volume);
void _DrawProgressBar(BRect updateRect);
void _DrawPieChart(BRect updateRect);
@@ -59,6 +61,7 @@ private:
void _Launch(FileInfo* info,
const entry_ref* ref = NULL);
void _OpenInfo(FileInfo* info, BPoint p);
private:
struct Segment {
Segment()
@@ -76,12 +79,10 @@ private:
typedef vector<Segment> SegmentList;
typedef map<int, SegmentList> MouseOverInfo;
typedef map<BVolume*, Scanner*> ScannerMap;
private:
MainWindow* fWindow;
ScannerMap fScanners;
BVolume* fCurrentVolume;
Scanner* fScanner;
BVolume* fVolume;
FileInfo* fCurrentDir;
MouseOverInfo fMouseOverInfo;
BPopUpMenu* fMouseOverMenu;
@@ -91,6 +92,7 @@ private:
bool fDragging;
BPoint fDragStart;
FileInfo* fClickedFile;
bool fOutdated;
};
#endif // PIE_VIEW_H
+96 -4
View File
@@ -14,6 +14,7 @@
#include <string.h>
#include <Directory.h>
#include <PathMonitor.h>
#include "Common.h"
@@ -31,18 +32,27 @@ Scanner::Scanner(BVolume *v, BHandler *handler)
fDesiredPath(),
fTask(),
fBusy(false),
fQuitRequested(false)
fQuitRequested(false),
fIsWatching(false),
fModifiedEntries()
{
fDoneMessage.AddPointer(kNameVolPtr, fVolume);
fProgressMessage.AddPointer(kNameVolPtr, fVolume);
Run();
}
Scanner::~Scanner()
{
if (fIsWatching) {
BPrivate::BPathMonitor::StopWatching(BMessenger(this, this));
fIsWatching = false;
}
delete fSnapshot;
while (fModifiedEntries.size() != 0) {
entry_ref* entry = *fModifiedEntries.begin();
delete entry;
fModifiedEntries.erase(fModifiedEntries.begin());
}
}
@@ -58,6 +68,38 @@ Scanner::MessageReceived(BMessage* message)
break;
}
case B_PATH_MONITOR:
{
dev_t device;
ino_t directory;
const char* name = "";
const char* path;
if (((message->FindInt32("device", &device) != B_OK)
|| (message->FindInt64("directory", &directory) != B_OK)
|| (message->FindString("name", &name) != B_OK))
&& ((message->FindString("path", &path) != B_OK)
|| (message->FindInt32("device", &device) != B_OK)))
return;
entry_ref* reportedEntry;
if (strlen(name) > 0)
reportedEntry = new entry_ref(device, directory, name);
else {
BEntry entry(path);
reportedEntry = new entry_ref();
entry.GetRef(reportedEntry);
}
fModifiedEntries.push_back(reportedEntry);
if (IsOutdated()) {
BMessage msg(kOutdatedMsg);
fListener.SendMessage(&msg);
}
}
default:
BLooper::MessageReceived(message);
break;
@@ -73,6 +115,12 @@ Scanner::Refresh(FileInfo* startInfo)
fBusy = true;
while (fModifiedEntries.size() != 0) {
entry_ref* entry = *fModifiedEntries.begin();
delete entry;
fModifiedEntries.erase(fModifiedEntries.begin());
}
// Remember the current directory, if any, so we can return to it after
// the scanning is done.
if (fSnapshot != NULL && fSnapshot->currentDir != NULL)
@@ -112,9 +160,43 @@ Scanner::RequestQuit()
}
bool
Scanner::IsOutdated()
{
FileInfo* currentDir = (fSnapshot->currentDir != NULL ?
fSnapshot->currentDir : fSnapshot->rootDir);
BDirectory currentDirectory(&(currentDir->ref));
bool isOutdated = currentDirectory.InitCheck() != B_OK;
vector<entry_ref*>::iterator i = fModifiedEntries.begin();
while (!isOutdated && i != fModifiedEntries.end()) {
BEntry entry(*i);
isOutdated = _DirectoryContains(currentDir, *i)
|| currentDirectory.Contains(&entry);
i++;
}
return isOutdated;
}
// #pragma mark - private
bool
Scanner::_DirectoryContains(FileInfo* currentDir, entry_ref* ref)
{
vector<FileInfo*>::iterator i = currentDir->children.begin();
bool contains = currentDir->ref == *ref;
while (!contains && i != currentDir->children.end()) {
contains |= _DirectoryContains((*i), ref);
i++;
}
return contains;
}
void
Scanner::_RunScan(FileInfo* startInfo)
{
@@ -168,6 +250,16 @@ Scanner::_RunScan(FileInfo* startInfo)
}
}
if (!fIsWatching) {
string path;
fSnapshot->rootDir->GetPath(path);
BPrivate::BPathMonitor::StartWatching(path.c_str(),
B_WATCH_ALL | B_WATCH_RECURSIVELY, BMessenger(this, this));
fIsWatching = true;
}
fBusy = false;
_ChangeToDesired();
fListener.SendMessage(&fDoneMessage);
+8
View File
@@ -11,6 +11,7 @@
#include <string>
#include <vector>
#include <Looper.h>
#include <Message.h>
@@ -49,11 +50,14 @@ public:
dev_t Device() const
{ return fVolume->Device(); }
void RequestQuit();
bool IsOutdated();
private:
void _RunScan(FileInfo *startInfo);
FileInfo* _GetFileInfo(BDirectory* dir, FileInfo* parent);
void _ChangeToDesired();
bool _DirectoryContains(FileInfo* currentDir,
entry_ref* ref);
BMessenger fListener;
BMessage fDoneMessage;
@@ -69,6 +73,10 @@ private:
string fTask;
bool fBusy;
bool fQuitRequested;
bool fIsWatching;
std::vector<entry_ref*> fModifiedEntries;
};
#endif // SCANNER_H
+61 -49
View File
@@ -1,4 +1,5 @@
/*
* Copyright (c) 2010 Philippe St-Pierre <stpere@gmail.com>. All rights reserved.
* Copyright (c) 2008 Stephan Aßmus <superstippi@gmx.de>. All rights reserved.
* Distributed under the terms of the MIT/X11 license.
*
@@ -14,73 +15,70 @@
#include <stdio.h>
#include <Box.h>
#include <Button.h>
#include <Node.h>
#include <String.h>
#include <StringView.h>
#include <LayoutBuilder.h>
#include "Common.h"
#include "Scanner.h"
StatusView::StatusView(BRect rect)
StatusView::StatusView()
:
BView(rect, NULL, B_FOLLOW_LEFT_RIGHT | B_FOLLOW_BOTTOM, B_WILL_DRAW),
BView(NULL, B_WILL_DRAW),
fCurrentFileInfo(NULL)
{
SetViewColor(kWindowColor);
SetViewColor(kPieBGColor);
SetLowColor(kPieBGColor);
struct font_height fh;
be_plain_font->GetHeight(&fh);
float plainHeight = ceilf(fh.ascent) + ceilf(fh.descent)
+ ceilf(fh.leading);
float fixedHeight = ceilf(fh.ascent) + ceilf(fh.descent)
+ ceilf(fh.leading);
ResizeTo(Bounds().Width(),
2.0 * kSmallVMargin + max_c(plainHeight, fixedHeight));
fSizeView = new BStringView(NULL, kEmptyStr);
fSizeView->SetExplicitMinSize(BSize(StringWidth("9999.99 GB"),
B_SIZE_UNSET));
fSizeView->SetExplicitMaxSize(BSize(StringWidth("9999.99 GB"),
B_SIZE_UNSET));
BRect r = Bounds();
r.top += kSmallVMargin;
// Size display
r.right -= kSmallHMargin;
r.left = r.right - StringWidth("9999.99 GB");
fSizeView = new BStringView(r, NULL, kEmptyStr,
B_FOLLOW_RIGHT | B_FOLLOW_TOP_BOTTOM);
AddChild(fSizeView);
// Vertical divider
r.right = r.left - kSmallHMargin;
r.left = r.right - 1.0;
AddChild(new BBox(r.InsetByCopy(0, -5), NULL,
B_FOLLOW_RIGHT | B_FOLLOW_TOP_BOTTOM));
// Count display
char testLabel[256];
sprintf(testLabel, kManyFiles, 999999);
r.right = r.left - kSmallHMargin;
r.left = r.right - (StringWidth(testLabel) + kSmallHMargin);
fCountView = new BStringView(r, NULL, kEmptyStr,
B_FOLLOW_RIGHT|B_FOLLOW_TOP_BOTTOM);
AddChild(fCountView);
// Vertical divider
r.right = r.left - kSmallHMargin;
r.left = r.right - 1.0;
AddChild(new BBox(r.InsetByCopy(0, -5), NULL,
B_FOLLOW_RIGHT | B_FOLLOW_TOP_BOTTOM));
fCountView = new BStringView(NULL, kEmptyStr);
fCountView->SetExplicitMinSize(BSize(StringWidth(testLabel), B_SIZE_UNSET));
fCountView->SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, B_SIZE_UNSET));
// Path display
r.right = r.left - kSmallHMargin;
r.left = kSmallHMargin;
fPathView = new BStringView(r, NULL, kEmptyStr,
B_FOLLOW_LEFT_RIGHT|B_FOLLOW_TOP_BOTTOM);
AddChild(fPathView);
fPathView = new BStringView(NULL, kEmptyStr);
fPathView->SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, B_SIZE_UNSET));
// Horizontal divider
r = Bounds();
r.bottom = r.top + 1.0;
AddChild(new BBox(r.InsetByCopy(-5, 0), NULL,
B_FOLLOW_LEFT_RIGHT | B_FOLLOW_BOTTOM, B_WILL_DRAW));
fRefreshBtn = new BButton(NULL, kStrScan, new BMessage(kBtnRescan));
fRefreshBtn->SetExplicitMaxSize(BSize(B_SIZE_UNSET, B_SIZE_UNLIMITED));
BBox* divider1 = new BBox(BRect(), B_EMPTY_STRING, B_FOLLOW_ALL_SIDES,
B_WILL_DRAW | B_FRAME_EVENTS, B_FANCY_BORDER);
BBox* divider2 = new BBox(BRect(), B_EMPTY_STRING, B_FOLLOW_ALL_SIDES,
B_WILL_DRAW | B_FRAME_EVENTS, B_FANCY_BORDER);
divider1->SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, 1));
divider2->SetExplicitMaxSize(BSize(1, B_SIZE_UNLIMITED));
SetLayout(new BGroupLayout(B_VERTICAL));
AddChild(BLayoutBuilder::Group<>(B_HORIZONTAL)
.AddGroup(B_VERTICAL)
.Add(fPathView)
.Add(divider1)
.AddGroup(B_HORIZONTAL)
.Add(fCountView)
.Add(divider2)
.Add(fSizeView)
.End()
.End()
.AddStrut(kSmallHMargin)
.Add(fRefreshBtn)
.SetInsets(kSmallHMargin, kSmallVMargin, kSmallVMargin, kSmallVMargin)
);
}
@@ -89,6 +87,20 @@ StatusView::~StatusView()
}
void
StatusView::SetRescanEnabled(bool enabled)
{
fRefreshBtn->SetEnabled(enabled);
}
void
StatusView::SetBtnLabel(const char* label)
{
fRefreshBtn->SetLabel(label);
}
void
StatusView::ShowInfo(const FileInfo* info)
{
+8 -2
View File
@@ -1,4 +1,5 @@
/*
* Copyright (c) 2010 Philippe St-Pierre <stpere@gmail.com>. All rights reserved.
* Copyright (c) 2008 Stephan Aßmus <superstippi@gmx.de>. All rights reserved.
* Distributed under the terms of the MIT/X11 license.
*
@@ -9,7 +10,7 @@
#ifndef STATUS_VIEW_H
#define STATUS_VIEW_H
#include <Button.h>
#include <View.h>
#include <StringView.h>
#include <Rect.h>
@@ -19,17 +20,22 @@ struct FileInfo;
class StatusView: public BView {
public:
StatusView(BRect frame);
StatusView();
virtual ~StatusView();
void ShowInfo(const FileInfo* info);
void SetBtnLabel(const char* label);
void SetRescanEnabled(bool enabled);
private:
BStringView* fPathView;
BStringView* fSizeView;
BStringView* fCountView;
const FileInfo* fCurrentFileInfo;
BButton* fRefreshBtn;
};
#endif // STATUS_VIEW_H
+85
View File
@@ -0,0 +1,85 @@
/*
* Copyright (c) 2010 Philippe Saint-Pierre, stpere@gmail.com
* All rights reserved. Distributed under the terms of the MIT license.
*
* Copyright (c) 1999 Mike Steed. You are free to use and distribute this software
* as long as it is accompanied by it's documentation and this copyright notice.
* The software comes with no warranty, etc.
*/
#include <Box.h>
#include <Button.h>
#include <StringView.h>
#include <Volume.h>
#include <Path.h>
#include <LayoutBuilder.h>
#include "Common.h"
#include "MainWindow.h"
#include "PieView.h"
#include "StatusView.h"
#include "VolumeView.h"
const float kMinWinSize = 275.0;
VolumeView::VolumeView(const char* name, BVolume* volume)
: BView(name, B_WILL_DRAW)
{
SetLayout(new BGroupLayout(B_HORIZONTAL));
fPieView = new PieView(volume);
fPieView->SetExplicitMinSize(BSize(kMinWinSize, kMinWinSize));
fStatusView = new StatusView();
AddChild(BLayoutBuilder::Group<>(B_VERTICAL)
.Add(fPieView)
.Add(fStatusView)
);
}
VolumeView::~VolumeView()
{
}
void
VolumeView::SetRescanEnabled(bool enabled)
{
fStatusView->SetRescanEnabled(enabled);
}
void
VolumeView::SetPath(BPath path)
{
fPieView->SetPath(path);
fStatusView->SetBtnLabel(kStrRescan);
}
void
VolumeView::MessageReceived(BMessage* msg)
{
msg->PrintToStream();
switch(msg->what) {
case kBtnRescan:
fPieView->MessageReceived(msg);
fStatusView->SetBtnLabel(kStrRescan);
break;
default:
BView::MessageReceived(msg);
}
}
void
VolumeView::ShowInfo(const FileInfo* info)
{
fStatusView->ShowInfo(info);
}
+44
View File
@@ -0,0 +1,44 @@
/*
* Copyright (c) 2010 Philippe Saint-Pierre, stpere@gmail.com
* All rights reserved. Distributed under the terms of the MIT license.
*
* Copyright (c) 1999 Mike Steed. You are free to use and distribute this software
* as long as it is accompanied by it's documentation and this copyright notice.
* The software comes with no warranty, etc.
*/
#ifndef VOLUMETAB_VIEW_H
#define VOLUMETAB_VIEW_H
#include <View.h>
class BButton;
class BPath;
class BStringView;
class BVolume;
class PieView;
class MainWindow;
class StatusView;
struct FileInfo;
class VolumeView: public BView {
public:
VolumeView(const char* name, BVolume* volume);
virtual ~VolumeView();
virtual void MessageReceived(BMessage* message);
void SetRescanEnabled(bool enabled);
void SetPath(BPath path);
void ShowInfo(const FileInfo* info);
private:
PieView* fPieView;
StatusView* fStatusView;
};
#endif