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 = new MainWindow(frame);
fMainWindow->Show();
if (fSavedRefsReceived) { if (fSavedRefsReceived) {
// RefsReceived() was called earlier than ReadyToRun() // RefsReceived() was called earlier than ReadyToRun()
+2
View File
@@ -78,6 +78,7 @@ read_resources(const char* appSignature)
kVolMenuLabel = LoadString("STR_VM_LABEL"); kVolMenuLabel = LoadString("STR_VM_LABEL");
kOneFile = LoadString("STR_1_FILE"); kOneFile = LoadString("STR_1_FILE");
kManyFiles = LoadString("STR_N_FILES"); kManyFiles = LoadString("STR_N_FILES");
kStrScan = LoadString("STR_SCAN");
kStrRescan = LoadString("STR_RESCAN"); kStrRescan = LoadString("STR_RESCAN");
kStrScanningX = LoadString("STR_SCN_X"); kStrScanningX = LoadString("STR_SCN_X");
kStrUnavail = LoadString("STR_UNAVAIL"); kStrUnavail = LoadString("STR_UNAVAIL");
@@ -94,6 +95,7 @@ read_resources(const char* appSignature)
kInfoTimeFmt = LoadString("STR_TIMEFMT"); kInfoTimeFmt = LoadString("STR_TIMEFMT");
kInfoKind = LoadString("STR_KIND"); kInfoKind = LoadString("STR_KIND");
kInfoPath = LoadString("STR_PATH"); kInfoPath = LoadString("STR_PATH");
kOutdatedStr = LoadString("STR_OUTDATED");
kWindowColor = ui_color(B_PANEL_BACKGROUND_COLOR); kWindowColor = ui_color(B_PANEL_BACKGROUND_COLOR);
kOutlineColor = LoadColor("RGB_PIE_OL"); kOutlineColor = LoadColor("RGB_PIE_OL");
+3
View File
@@ -28,7 +28,9 @@
// Resources // Resources
EXTERN char* kStrScan;
EXTERN char* kStrRescan; EXTERN char* kStrRescan;
EXTERN char* kOutdatedStr;
EXTERN char* kStrScanningX; EXTERN char* kStrScanningX;
EXTERN char* kStrUnavail; EXTERN char* kStrUnavail;
EXTERN char* kVolMenuLabel; EXTERN char* kVolMenuLabel;
@@ -93,6 +95,7 @@ EXTERN bool kFoundHelpFile;
#define kScanRefresh 'gSRF' #define kScanRefresh 'gSRF'
#define kScanProgress 'gSPR' #define kScanProgress 'gSPR'
#define kScanDone 'gSDN' #define kScanDone 'gSDN'
#define kOutdatedMsg 'gOUT'
#define deg2rad(x) (2.0 * M_PI * (x) / 360.0) #define deg2rad(x) (2.0 * M_PI * (x) / 360.0)
#define rad2deg(x) (360.0 * (x) / (2.0 * M_PI)) #define rad2deg(x) (360.0 * (x) / (2.0 * M_PI))
+175 -137
View File
@@ -12,47 +12,44 @@
#include <Bitmap.h> #include <Bitmap.h>
#include <Box.h> #include <Box.h>
#include <MenuField.h> #include <TabView.h>
#include <MenuItem.h>
#include <NodeMonitor.h> #include <NodeMonitor.h>
#include <Path.h>
#include <PopUpMenu.h> #include <PopUpMenu.h>
#include <SupportDefs.h> #include <SupportDefs.h>
#include <Volume.h> #include <Volume.h>
#include <VolumeRoster.h> #include <VolumeRoster.h>
#include <Window.h> #include <Window.h>
#include <LayoutBuilder.h>
#include "Common.h" #include "Common.h"
#include "VolumeView.h"
class VolumeMenuItem: public BMenuItem { class VolumeTab: public BTab {
public: public:
VolumeMenuItem(BVolume* volume, BMessage* message); VolumeTab(BVolume* volume);
virtual ~VolumeMenuItem(); virtual ~VolumeTab();
virtual void GetContentSize(float* width, float* height); BVolume* Volume() const
virtual void DrawContent(); { return fVolume; }
float IconWidth() const;
BVolume* Volume() const virtual void DrawLabel(BView* owner, BRect frame);
{ return fVolume; }
status_t Invoke(BMessage* mesage = NULL)
{ return BMenuItem::Invoke(); }
private: private:
BBitmap* fIcon; BBitmap* fIcon;
BVolume* fVolume; 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)), fIcon(new BBitmap(BRect(0, 0, 15, 15), B_RGBA32)),
fVolume(volume) fVolume(volume)
{ {
char name[B_PATH_NAME_LENGTH];
fVolume->GetName(name);
SetLabel(name);
if (fVolume->GetIcon(fIcon, B_MINI_ICON) < B_OK) { if (fVolume->GetIcon(fIcon, B_MINI_ICON) < B_OK) {
delete fIcon; delete fIcon;
fIcon = NULL; 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 fIcon;
delete fVolume; 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 - // #pragma mark -
class ControlsView::VolumePopup: public BMenuField { class ControlsView::VolumeTabView: public BTabView {
public: public:
VolumePopup(BRect r); VolumeTabView();
virtual ~VolumePopup(); virtual ~VolumeTabView();
virtual void AttachedToWindow(); virtual void AttachedToWindow();
virtual void MessageReceived(BMessage* message); virtual void MessageReceived(BMessage* message);
virtual BRect TabFrame(int32 index) const;
BVolume* FindDeviceFor(dev_t device, BVolume* FindDeviceFor(dev_t device,
bool invoke = false); bool invoke = false);
@@ -119,16 +119,40 @@ private:
}; };
ControlsView::VolumePopup::VolumePopup(BRect r) ControlsView::VolumeTabView::VolumeTabView()
: :
BMenuField(r, NULL, kVolMenuLabel, new BPopUpMenu(kVolMenuDefault), false, BTabView("volume_tabs", B_WIDTH_FROM_LABEL)
B_FOLLOW_LEFT)
{ {
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. // Populate the menu with the persistent volumes.
fVolumeRoster = new BVolumeRoster(); fVolumeRoster = new BVolumeRoster();
@@ -136,32 +160,20 @@ ControlsView::VolumePopup::VolumePopup(BRect r)
while (fVolumeRoster->GetNextVolume(&tempVolume) == B_OK) { while (fVolumeRoster->GetNextVolume(&tempVolume) == B_OK) {
if (tempVolume.IsPersistent()) { if (tempVolume.IsPersistent()) {
BVolume* volume = new BVolume(tempVolume); BVolume* volume = new BVolume(tempVolume);
BMessage* message = new BMessage(kMenuSelectVol); VolumeTab *item = new VolumeTab(volume);
message->AddPointer(kNameVolPtr, volume); char name[B_PATH_NAME_LENGTH];
VolumeMenuItem *item = new VolumeMenuItem(volume, message); volume->GetName(name);
Menu()->AddItem(item); AddTab(new VolumeView(name, volume), item);
} }
} }
}
ControlsView::VolumePopup::~VolumePopup()
{
fVolumeRoster->StopWatching();
delete fVolumeRoster;
}
void
ControlsView::VolumePopup::AttachedToWindow()
{
// Begin watching mount and unmount events. // Begin watching mount and unmount events.
fVolumeRoster->StartWatching(BMessenger(this)); fVolumeRoster->StartWatching(BMessenger(this));
} }
void void
ControlsView::VolumePopup::MessageReceived(BMessage* message) ControlsView::VolumeTabView::MessageReceived(BMessage* message)
{ {
switch (message->what) { switch (message->what) {
case B_NODE_MONITOR: case B_NODE_MONITOR:
@@ -176,24 +188,50 @@ ControlsView::VolumePopup::MessageReceived(BMessage* message)
} }
break; 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: default:
BMenuField::MessageReceived(message); BTabView::MessageReceived(message);
break; break;
} }
} }
BVolume* BVolume*
ControlsView::VolumePopup::FindDeviceFor(dev_t device, bool invoke) ControlsView::VolumeTabView::FindDeviceFor(dev_t device, bool invoke)
{ {
BVolume* volume = NULL; BVolume* volume = NULL;
// Iterate through items looking for a BVolume representing this device. // 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) { if (item->Volume()->Device() == device) {
volume = item->Volume(); volume = item->Volume();
if (invoke) if (invoke)
item->Invoke(); Select(i);
break; break;
} }
} }
@@ -203,43 +241,36 @@ ControlsView::VolumePopup::FindDeviceFor(dev_t device, bool invoke)
void void
ControlsView::VolumePopup::_AddVolume(dev_t device) ControlsView::VolumeTabView::_AddVolume(dev_t device)
{ {
// Make sure the volume is not already in the menu. // Make sure the volume is not already in the menu.
for (int i = 0; i < Menu()->CountItems(); i++) { for (int i = 0; VolumeTab* item = (VolumeTab*)TabAt(i); i++) {
VolumeMenuItem* item = (VolumeMenuItem*)Menu()->ItemAt(i);
if (item->Volume()->Device() == device) if (item->Volume()->Device() == device)
return; return;
} }
// Add the newly mounted volume to the menu.
BVolume* volume = new BVolume(device); BVolume* volume = new BVolume(device);
BMessage* message = new BMessage(kMenuSelectVol);
message->AddPointer(kNameVolPtr, volume); VolumeTab* item = new VolumeTab(volume);
VolumeMenuItem* item = new VolumeMenuItem(volume, message); char name[B_PATH_NAME_LENGTH];
Menu()->AddItem(item); volume->GetName(name);
AddTab(new VolumeView(name, volume), item);
Invalidate();
} }
void void
ControlsView::VolumePopup::_RemoveVolume(dev_t device) ControlsView::VolumeTabView::_RemoveVolume(dev_t device)
{ {
for (int i = 0; i < Menu()->CountItems(); i++) { for (int i = 0; VolumeTab* item = (VolumeTab*)TabAt(i); i++) {
VolumeMenuItem* item = (VolumeMenuItem*)Menu()->ItemAt(i);
if (item->Volume()->Device() == device) { if (item->Volume()->Device() == device) {
// If the volume being removed is currently selected, prompt for a if (i == 0)
// different volume. Select(1);
if (item->IsMarked()) { else
// update the displayed volume label now that there is no marked Select(i - 1);
// item: RemoveTab(i);
Menu()->Superitem()->SetLabel(kVolMenuDefault); delete item;
BMessage messae(kMenuSelectVol);
messae.AddPointer(kNameVolPtr, NULL);
Window()->PostMessage(&messae);
}
Menu()->RemoveItem(item);
return; return;
} }
} }
@@ -249,43 +280,34 @@ ControlsView::VolumePopup::_RemoveVolume(dev_t device)
// #pragma mark - // #pragma mark -
ControlsView::ControlsView(BRect r) ControlsView::ControlsView()
: BView(r, NULL, B_FOLLOW_LEFT_RIGHT, 0) :
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; void
buttonWidth = kButtonMargin + StringWidth(kStrRescan); ControlsView::MessageReceived(BMessage* msg)
r.left = r.right - max_c(kMinButtonWidth, buttonWidth); {
fRescanButton = new BButton(r, NULL, kStrRescan, new BMessage(kBtnRescan), switch (msg->what) {
B_FOLLOW_RIGHT); case B_SIMPLE_DATA:
case B_REFS_RECEIVED:
fVolumeTabView->MessageReceived(msg);
break;
fVolumePopup = new VolumePopup( case kBtnRescan:
BRect(kSmallHMargin, kSmallVMargin, r.left - kSmallHMargin, kSmallVMargin)); fVolumeTabView->MessageReceived(msg);
break;
float width, height; default:
fRescanButton->GetPreferredSize(&width, &height); BView::MessageReceived(msg);
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);
} }
@@ -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* BVolume*
ControlsView::FindDeviceFor(dev_t device, bool invoke) ControlsView::FindDeviceFor(dev_t device, bool invoke)
{ {
return fVolumePopup->FindDeviceFor(device, invoke); return fVolumeTabView->FindDeviceFor(device, invoke);
} }
+11 -8
View File
@@ -9,29 +9,32 @@
#ifndef CONTROLS_VIEW_H #ifndef CONTROLS_VIEW_H
#define CONTROLS_VIEW_H #define CONTROLS_VIEW_H
#include <Button.h> #include <Button.h>
#include <View.h> #include <View.h>
class BMessage;
class BVolume; class BVolume;
struct FileInfo;
class ControlsView: public BView { class ControlsView: public BView {
public: public:
ControlsView(BRect r); ControlsView();
virtual ~ControlsView(); virtual ~ControlsView();
void SetRescanEnabled(bool enable) virtual void MessageReceived(BMessage* msg);
{ fRescanButton->SetEnabled(enable); }
BVolume* FindDeviceFor(dev_t device, BVolume* FindDeviceFor(dev_t device,
bool invoke = false); bool invoke = false);
private: void SetRescanEnabled(bool enabled);
class VolumePopup; void ShowInfo(const FileInfo* info);
VolumePopup* fVolumePopup; private:
BButton* fRescanButton; 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(103, "STR_N_FILES") "%d files";
resource(102, "STR_1_FILE") "%d file"; resource(102, "STR_1_FILE") "%d file";
resource(101, "STR_VM_LABEL") "Volume:"; resource(101, "STR_VM_LABEL") "Volume:";
resource(120, "STR_SCAN") "Scan";
resource(104, "STR_RESCAN") "Rescan"; resource(104, "STR_RESCAN") "Rescan";
resource(105, "STR_SCN_X") "Scanning "; resource(105, "STR_SCN_X") "Scanning ";
resource(106, "STR_UNAVAIL") "file unavailable"; 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(117, "STR_TIMEFMT") "%a, %d %b %Y, %r";
resource(118, "STR_KIND") "Kind"; resource(118, "STR_KIND") "Kind";
resource(119, "STR_PATH") "Path"; 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 ; SubDir HAIKU_TOP src apps diskusage ;
UsePrivateHeaders mount shared tracker ; UsePrivateHeaders mount shared tracker storage ;
SubDirHdrs $(HAIKU_TOP) src kits tracker ; SubDirHdrs $(HAIKU_TOP) src kits tracker ;
Application DiskUsage : Application DiskUsage :
@@ -14,6 +14,7 @@ Application DiskUsage :
Scanner.cpp Scanner.cpp
Snapshot.cpp Snapshot.cpp
StatusView.cpp StatusView.cpp
VolumeView.cpp
: be $(TARGET_LIBSTDC++) : be $(TARGET_LIBSTDC++)
: DiskUsage.rdef : DiskUsage.rdef
; ;
+20 -50
View File
@@ -7,8 +7,6 @@
* as long as it is accompanied by it's documentation and this copyright notice. * as long as it is accompanied by it's documentation and this copyright notice.
* The software comes with no warranty, etc. * The software comes with no warranty, etc.
*/ */
#include "MainWindow.h" #include "MainWindow.h"
#include <Application.h> #include <Application.h>
@@ -16,58 +14,28 @@
#include <Roster.h> #include <Roster.h>
#include <Screen.h> #include <Screen.h>
#include <LayoutBuilder.h>
#include "Common.h" #include "Common.h"
#include "ControlsView.h" #include "ControlsView.h"
#include "PieView.h"
#include "StatusView.h"
const float kMinWinSize = 275.0;
MainWindow::MainWindow(BRect pieRect) MainWindow::MainWindow(BRect pieRect)
: :
BWindow(pieRect, "DiskUsage", B_TITLED_WINDOW, 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(); fControlsView = new ControlsView();
r.bottom = r.top + 1.0;
fControlsView = new ControlsView(r);
float cvHeight = fControlsView->Bounds().Height();
AddChild(fControlsView);
r = Bounds(); SetLayout(new BGroupLayout(B_VERTICAL));
r.top = r.bottom - 1.0;
fStatusView = new StatusView(r);
float svHeight = fStatusView->Bounds().Height();
float winHeight = pieRect.Height() + cvHeight + svHeight; AddChild(BLayoutBuilder::Group<>(B_VERTICAL)
fStatusView->MoveTo(0.0, winHeight - svHeight); .Add(fControlsView)
ResizeTo(r.Width(), winHeight); .SetInsets(5, 5, 5, 5)
);
AddChild(fStatusView); float maxHeight = BScreen(this).Frame().Height() - 12;
fControlsView->SetExplicitMaxSize(BSize(maxHeight, maxHeight));
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);
} }
@@ -81,9 +49,11 @@ MainWindow::MessageReceived(BMessage* message)
{ {
switch (message->what) { switch (message->what) {
case kBtnRescan: case kBtnRescan:
case kMenuSelectVol: fControlsView->MessageReceived(message);
break;
case B_SIMPLE_DATA:
case B_REFS_RECEIVED: case B_REFS_RECEIVED:
fPieView->MessageReceived(message); fControlsView->MessageReceived(message);
break; break;
case kBtnHelp: case kBtnHelp:
@@ -109,16 +79,16 @@ MainWindow::QuitRequested()
void void
MainWindow::ShowInfo(const FileInfo* info) MainWindow::SetRescanEnabled(bool enabled)
{ {
fStatusView->ShowInfo(info); fControlsView->SetRescanEnabled(enabled);
} }
void 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 #ifndef MAIN_WINDOW_H
#define MAIN_WINDOW_H #define MAIN_WINDOW_H
#include <Window.h> #include <Window.h>
@@ -18,8 +17,6 @@ class BVolume;
class ControlsView; class ControlsView;
struct FileInfo; struct FileInfo;
class PieView; class PieView;
class StatusView;
class MainWindow: public BWindow { class MainWindow: public BWindow {
public: public:
@@ -29,15 +26,14 @@ public:
virtual void MessageReceived(BMessage* message); virtual void MessageReceived(BMessage* message);
virtual bool QuitRequested(); virtual bool QuitRequested();
void ShowInfo(const FileInfo* info);
void SetRescanEnabled(bool enabled); void SetRescanEnabled(bool enabled);
BVolume* FindDeviceFor(dev_t device, BVolume* FindDeviceFor(dev_t device,
bool invoke = false); bool invoke = false);
void ShowInfo(const FileInfo* info);
private: private:
ControlsView* fControlsView; ControlsView* fControlsView;
PieView* fPieView;
StatusView* fStatusView;
}; };
#endif // MAIN_WINDOW_H #endif // MAIN_WINDOW_H
+84 -123
View File
@@ -14,7 +14,6 @@
#include <fs_info.h> #include <fs_info.h>
#include <math.h> #include <math.h>
#include <Alert.h>
#include <AppFileInfo.h> #include <AppFileInfo.h>
#include <Bitmap.h> #include <Bitmap.h>
#include <Entry.h> #include <Entry.h>
@@ -41,8 +40,6 @@ static const int32 kIdxOpen = 1;
static const int32 kIdxOpenWith = 2; static const int32 kIdxOpenWith = 2;
static const int32 kIdxRescan = 3; 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 { class AppMenuItem : public BMenuItem {
public: public:
@@ -125,20 +122,17 @@ AppMenuItem::DrawContent()
// #pragma mark - PieView // #pragma mark - PieView
PieView::PieView(BRect frame, MainWindow* window) PieView::PieView(BVolume* volume)
: :
BView(frame, NULL, B_FOLLOW_ALL, BView(NULL, B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE | B_SUBPIXEL_PRECISE),
B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE | B_SUBPIXEL_PRECISE), fWindow(NULL),
fWindow(window), fScanner(NULL),
fScanners(), fVolume(volume),
fCurrentVolume(NULL),
fMouseOverInfo(), fMouseOverInfo(),
fClicked(false), fClicked(false),
fDragging(false) fDragging(false),
fOutdated(false)
{ {
SetViewColor(B_TRANSPARENT_COLOR);
SetLowColor(kWindowColor);
fMouseOverMenu = new BPopUpMenu(kEmptyStr, false, false); fMouseOverMenu = new BPopUpMenu(kEmptyStr, false, false);
fMouseOverMenu->AddItem(new BMenuItem(kMenuGetInfo, NULL), kIdxGetInfo); fMouseOverMenu->AddItem(new BMenuItem(kMenuGetInfo, NULL), kIdxGetInfo);
fMouseOverMenu->AddItem(new BMenuItem(kMenuOpen, NULL), kIdxOpen); 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() PieView::~PieView()
{ {
delete fMouseOverMenu; delete fMouseOverMenu;
delete fFileUnavailableMenu; delete fFileUnavailableMenu;
if (fScanner != NULL)
while (fScanners.size() != 0) { fScanner->RequestQuit();
ScannerMap::iterator i = fScanners.begin();
(*i).second->RequestQuit();
fScanners.erase(i);
}
} }
@@ -177,41 +174,31 @@ void
PieView::MessageReceived(BMessage* message) PieView::MessageReceived(BMessage* message)
{ {
switch (message->what) { 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: case kBtnRescan:
if (fCurrentVolume != NULL) { if (fVolume != NULL) {
fScanners[fCurrentVolume]->Refresh(); if (fScanner != NULL)
fScanner->Refresh();
else
_ShowVolume(fVolume);
fOutdated = false;
Invalidate(); Invalidate();
} }
break; break;
case kMenuSelectVol:
{
BVolume* volume;
if (message->FindPointer(kNameVolPtr, (void**)&volume) == B_OK)
_ShowVolume(volume);
break;
}
case kScanProgress: case kScanProgress:
case kScanDone: case kScanDone:
{ {
BVolume* volume; Invalidate();
if (message->FindPointer(kNameVolPtr, (void**)&volume) == B_OK break;
&& volume == fCurrentVolume) { }
case kOutdatedMsg:
{
if (!fScanner->IsBusy()) {
fOutdated = true;
Invalidate(); Invalidate();
} }
break;
} }
default: default:
@@ -251,14 +238,15 @@ PieView::MouseUp(BPoint where)
// If the primary button was released and there was no dragging happening, // If the primary button was released and there was no dragging happening,
// just zoom in or out. // just zoom in or out.
if (fClicked && !fDragging) { if (fClicked && !fDragging) {
Scanner* scanner = fScanners[fCurrentVolume];
FileInfo* info = _FileAt(where); FileInfo* info = _FileAt(where);
if (info != NULL) { if (info != NULL) {
if (info == scanner->CurrentDir()) { if (info == fScanner->CurrentDir()) {
scanner->ChangeDir(info->parent); fScanner->ChangeDir(info->parent);
fOutdated = fScanner->IsOutdated();
Invalidate(); Invalidate();
} else if (info->children.size() > 0) { } else if (info->children.size() > 0) {
scanner->ChangeDir(info); fScanner->ChangeDir(info);
fOutdated = fScanner->IsOutdated();
Invalidate(); Invalidate();
} }
} }
@@ -307,27 +295,32 @@ PieView::MouseMoved(BPoint where, uint32 transit, const BMessage* dragMessage)
void void
PieView::Draw(BRect updateRect) PieView::Draw(BRect updateRect)
{ {
if (fScanners.find(fCurrentVolume) != fScanners.end()) { if (fScanner != NULL) {
// There is a current volume. // There is a current volume.
Scanner* scanner = fScanners[fCurrentVolume]; if (fScanner->IsBusy()) {
if (scanner->IsBusy()) {
// Show progress of scanning. // Show progress of scanning.
_DrawProgressBar(updateRect); _DrawProgressBar(updateRect);
fWindow->SetRescanEnabled(false); if (fWindow != NULL)
fWindow->SetRescanEnabled(false);
} else { } else {
_DrawPieChart(updateRect); _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); void
float bx = (b.left + b.Width() - strWidth) / 2.0; PieView::SetPath(BPath path)
float by = (b.top + b.Height()) / 2.0; {
SetHighColor(0x00, 0x00, 0x00); if (fScanner == NULL)
DrawString(kVolPrompt, BPoint(bx, by)); _ShowVolume(fVolume);
fWindow->SetRescanEnabled(false);
if (fScanner != NULL) {
string desiredPath(path.Path());
fScanner->SetDesiredPath(desiredPath);
Invalidate();
} }
} }
@@ -335,57 +328,17 @@ PieView::Draw(BRect updateRect)
// #pragma mark - private // #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 void
PieView::_ShowVolume(BVolume* volume) PieView::_ShowVolume(BVolume* volume)
{ {
if (volume != NULL) { if (volume != NULL) {
if (fScanners.find(volume) == fScanners.end()) if (fScanner == NULL)
fScanners[volume] = new Scanner(volume, this); fScanner = new Scanner(volume, this);
Scanner* scanner = fScanners[volume]; if (fScanner->Snapshot() == NULL)
if (scanner->Snapshot() == NULL) fScanner->Refresh();
scanner->Refresh();
} }
fCurrentVolume = volume;
Invalidate(); Invalidate();
} }
@@ -416,7 +369,7 @@ PieView::_DrawProgressBar(BRect updateRect)
bx += 1.0; by += 1.0; bx += 1.0; by += 1.0;
ex -= 1.0; ey -= 1.0; ex -= 1.0; ey -= 1.0;
float mx = bx + floorf((kProgBarWidth - 2.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)); SetHighColor(tint_color(kWindowColor, B_DARKEN_1_TINT));
FillRect(BRect(mx, by, ex, ey)); FillRect(BRect(mx, by, ex, ey));
@@ -433,7 +386,7 @@ PieView::_DrawProgressBar(BRect updateRect)
FillRect(BRect(bx, by, mx, ey)); FillRect(BRect(bx, by, mx, ey));
// Tell what we are doing. // Tell what we are doing.
const char* task = fScanners[fCurrentVolume]->Task(); const char* task = fScanner->Task();
float strWidth = StringWidth(task); float strWidth = StringWidth(task);
bx = (b.left + b.Width() - strWidth) / 2.0; bx = (b.left + b.Width() - strWidth) / 2.0;
by -= fFontHeight + 2.0 * kSmallVMargin; by -= fFontHeight + 2.0 * kSmallVMargin;
@@ -465,7 +418,7 @@ PieView::_DrawPieChart(BRect updateRect)
pieRect.bottom += moveBy; pieRect.bottom += moveBy;
} }
int colorIdx = 0; int colorIdx = 0;
FileInfo* currentDir = fScanners[fCurrentVolume]->CurrentDir(); FileInfo* currentDir = fScanner->CurrentDir();
FileInfo* parent = currentDir; FileInfo* parent = currentDir;
while (parent != NULL) { while (parent != NULL) {
parent = parent->parent; parent = parent->parent;
@@ -474,15 +427,20 @@ PieView::_DrawPieChart(BRect updateRect)
_DrawDirectory(pieRect, currentDir, 0.0, 0.0, colorIdx % kBasePieColorCount, _DrawDirectory(pieRect, currentDir, 0.0, 0.0, colorIdx % kBasePieColorCount,
0); 0);
// This is just for the case when the mouse hovers over the view if (fOutdated) {
// while the scanning process is running and then does not move
// until after the results are shown. In that case the info will BRect b = Bounds();
// not automatically update. (TODO: fix this and put into MessageReceived()
// kScanDone - currently, fileAt() returns NULL (mouseoverinfo...)) float strWidth = StringWidth(kOutdatedStr);
BPoint where; float bx = (b.Width() - strWidth - kSmallHMargin);
uint32 ignore;
GetMouse(&where, &ignore, false); struct font_height fh;
fWindow->ShowInfo(_FileAt(where)); 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) else if (info != NULL)
info->color = colorIdx; info->color = colorIdx;
VolumeSnapshot* snapshot = fScanners[fCurrentVolume]->Snapshot(); VolumeSnapshot* snapshot = fScanner->Snapshot();
float cx = floorf(b.left + b.Width() / 2.0 + 0.5); float cx = floorf(b.left + b.Width() / 2.0 + 0.5);
float cy = floorf(b.top + b.Height() / 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); FillEllipse(BPoint(cx, cy), kPieCenterSize, kPieCenterSize);
SetHighColor(kBasePieColor[0]); 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. // Show total volume capacity.
char label[B_PATH_NAME_LENGTH]; char label[B_PATH_NAME_LENGTH];
@@ -560,7 +519,8 @@ PieView::_DrawDirectory(BRect b, FileInfo* info, float parentSpan,
SetPenSize(1.0); SetPenSize(1.0);
SetHighColor(kOutlineColor); 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. // Show the name of the volume or directory.
BString label(displayName); BString label(displayName);
@@ -803,7 +763,7 @@ PieView::_ShowContextMenu(FileInfo* info, BPoint p)
_Launch(info); _Launch(info);
break; break;
case kIdxRescan: case kIdxRescan:
fScanners[fCurrentVolume]->Refresh(info); fScanner->Refresh(info);
Invalidate(); Invalidate();
break; break;
default: // must be "Open With" submenu default: // must be "Open With" submenu
@@ -844,6 +804,7 @@ PieView::_Launch(FileInfo* info, const entry_ref* appRef)
} }
} }
void void
PieView::_OpenInfo(FileInfo* info, BPoint p) PieView::_OpenInfo(FileInfo* info, BPoint p)
{ {
+8 -6
View File
@@ -20,6 +20,7 @@
class AppMenuItem; class AppMenuItem;
class BEntry; class BEntry;
class BMenu; class BMenu;
class BPath;
class BPopUpMenu; class BPopUpMenu;
class BVolume; class BVolume;
struct entry_ref; struct entry_ref;
@@ -33,18 +34,19 @@ using std::vector;
class PieView: public BView { class PieView: public BView {
public: public:
PieView(BRect frame, MainWindow* window); PieView(BVolume* volume);
virtual ~PieView(); virtual ~PieView();
virtual void AttachedToWindow();
virtual void MessageReceived(BMessage* message); virtual void MessageReceived(BMessage* message);
virtual void MouseDown(BPoint where); virtual void MouseDown(BPoint where);
virtual void MouseUp(BPoint where); virtual void MouseUp(BPoint where);
virtual void MouseMoved(BPoint where, uint32 transit, virtual void MouseMoved(BPoint where, uint32 transit,
const BMessage* dragMessage); const BMessage* dragMessage);
virtual void Draw(BRect updateRect); virtual void Draw(BRect updateRect);
void SetPath(BPath path);
private: private:
void _HandleArg(const BEntry* entry);
void _ShowVolume(BVolume* volume); void _ShowVolume(BVolume* volume);
void _DrawProgressBar(BRect updateRect); void _DrawProgressBar(BRect updateRect);
void _DrawPieChart(BRect updateRect); void _DrawPieChart(BRect updateRect);
@@ -59,6 +61,7 @@ private:
void _Launch(FileInfo* info, void _Launch(FileInfo* info,
const entry_ref* ref = NULL); const entry_ref* ref = NULL);
void _OpenInfo(FileInfo* info, BPoint p); void _OpenInfo(FileInfo* info, BPoint p);
private: private:
struct Segment { struct Segment {
Segment() Segment()
@@ -76,12 +79,10 @@ private:
typedef vector<Segment> SegmentList; typedef vector<Segment> SegmentList;
typedef map<int, SegmentList> MouseOverInfo; typedef map<int, SegmentList> MouseOverInfo;
typedef map<BVolume*, Scanner*> ScannerMap;
private: private:
MainWindow* fWindow; MainWindow* fWindow;
ScannerMap fScanners; Scanner* fScanner;
BVolume* fCurrentVolume; BVolume* fVolume;
FileInfo* fCurrentDir; FileInfo* fCurrentDir;
MouseOverInfo fMouseOverInfo; MouseOverInfo fMouseOverInfo;
BPopUpMenu* fMouseOverMenu; BPopUpMenu* fMouseOverMenu;
@@ -91,6 +92,7 @@ private:
bool fDragging; bool fDragging;
BPoint fDragStart; BPoint fDragStart;
FileInfo* fClickedFile; FileInfo* fClickedFile;
bool fOutdated;
}; };
#endif // PIE_VIEW_H #endif // PIE_VIEW_H
+96 -4
View File
@@ -14,6 +14,7 @@
#include <string.h> #include <string.h>
#include <Directory.h> #include <Directory.h>
#include <PathMonitor.h>
#include "Common.h" #include "Common.h"
@@ -31,18 +32,27 @@ Scanner::Scanner(BVolume *v, BHandler *handler)
fDesiredPath(), fDesiredPath(),
fTask(), fTask(),
fBusy(false), fBusy(false),
fQuitRequested(false) fQuitRequested(false),
fIsWatching(false),
fModifiedEntries()
{ {
fDoneMessage.AddPointer(kNameVolPtr, fVolume);
fProgressMessage.AddPointer(kNameVolPtr, fVolume);
Run(); Run();
} }
Scanner::~Scanner() Scanner::~Scanner()
{ {
if (fIsWatching) {
BPrivate::BPathMonitor::StopWatching(BMessenger(this, this));
fIsWatching = false;
}
delete fSnapshot; 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; 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: default:
BLooper::MessageReceived(message); BLooper::MessageReceived(message);
break; break;
@@ -73,6 +115,12 @@ Scanner::Refresh(FileInfo* startInfo)
fBusy = true; 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 // Remember the current directory, if any, so we can return to it after
// the scanning is done. // the scanning is done.
if (fSnapshot != NULL && fSnapshot->currentDir != NULL) 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 // #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 void
Scanner::_RunScan(FileInfo* startInfo) 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; fBusy = false;
_ChangeToDesired(); _ChangeToDesired();
fListener.SendMessage(&fDoneMessage); fListener.SendMessage(&fDoneMessage);
+8
View File
@@ -11,6 +11,7 @@
#include <string> #include <string>
#include <vector>
#include <Looper.h> #include <Looper.h>
#include <Message.h> #include <Message.h>
@@ -49,11 +50,14 @@ public:
dev_t Device() const dev_t Device() const
{ return fVolume->Device(); } { return fVolume->Device(); }
void RequestQuit(); void RequestQuit();
bool IsOutdated();
private: private:
void _RunScan(FileInfo *startInfo); void _RunScan(FileInfo *startInfo);
FileInfo* _GetFileInfo(BDirectory* dir, FileInfo* parent); FileInfo* _GetFileInfo(BDirectory* dir, FileInfo* parent);
void _ChangeToDesired(); void _ChangeToDesired();
bool _DirectoryContains(FileInfo* currentDir,
entry_ref* ref);
BMessenger fListener; BMessenger fListener;
BMessage fDoneMessage; BMessage fDoneMessage;
@@ -69,6 +73,10 @@ private:
string fTask; string fTask;
bool fBusy; bool fBusy;
bool fQuitRequested; bool fQuitRequested;
bool fIsWatching;
std::vector<entry_ref*> fModifiedEntries;
}; };
#endif // SCANNER_H #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. * Copyright (c) 2008 Stephan Aßmus <superstippi@gmx.de>. All rights reserved.
* Distributed under the terms of the MIT/X11 license. * Distributed under the terms of the MIT/X11 license.
* *
@@ -14,73 +15,70 @@
#include <stdio.h> #include <stdio.h>
#include <Box.h> #include <Box.h>
#include <Button.h>
#include <Node.h> #include <Node.h>
#include <String.h> #include <String.h>
#include <StringView.h> #include <StringView.h>
#include <LayoutBuilder.h>
#include "Common.h" #include "Common.h"
#include "Scanner.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) fCurrentFileInfo(NULL)
{ {
SetViewColor(kWindowColor); SetViewColor(kPieBGColor);
SetLowColor(kPieBGColor);
struct font_height fh; fSizeView = new BStringView(NULL, kEmptyStr);
be_plain_font->GetHeight(&fh); fSizeView->SetExplicitMinSize(BSize(StringWidth("9999.99 GB"),
float plainHeight = ceilf(fh.ascent) + ceilf(fh.descent) B_SIZE_UNSET));
+ ceilf(fh.leading); fSizeView->SetExplicitMaxSize(BSize(StringWidth("9999.99 GB"),
float fixedHeight = ceilf(fh.ascent) + ceilf(fh.descent) B_SIZE_UNSET));
+ ceilf(fh.leading);
ResizeTo(Bounds().Width(),
2.0 * kSmallVMargin + max_c(plainHeight, fixedHeight));
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]; char testLabel[256];
sprintf(testLabel, kManyFiles, 999999); 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 fCountView = new BStringView(NULL, kEmptyStr);
r.right = r.left - kSmallHMargin; fCountView->SetExplicitMinSize(BSize(StringWidth(testLabel), B_SIZE_UNSET));
r.left = r.right - 1.0; fCountView->SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, B_SIZE_UNSET));
AddChild(new BBox(r.InsetByCopy(0, -5), NULL,
B_FOLLOW_RIGHT | B_FOLLOW_TOP_BOTTOM));
// Path display fPathView = new BStringView(NULL, kEmptyStr);
r.right = r.left - kSmallHMargin; fPathView->SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, B_SIZE_UNSET));
r.left = kSmallHMargin;
fPathView = new BStringView(r, NULL, kEmptyStr,
B_FOLLOW_LEFT_RIGHT|B_FOLLOW_TOP_BOTTOM);
AddChild(fPathView);
// Horizontal divider fRefreshBtn = new BButton(NULL, kStrScan, new BMessage(kBtnRescan));
r = Bounds();
r.bottom = r.top + 1.0; fRefreshBtn->SetExplicitMaxSize(BSize(B_SIZE_UNSET, B_SIZE_UNLIMITED));
AddChild(new BBox(r.InsetByCopy(-5, 0), NULL,
B_FOLLOW_LEFT_RIGHT | B_FOLLOW_BOTTOM, B_WILL_DRAW)); 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 void
StatusView::ShowInfo(const FileInfo* info) 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. * Copyright (c) 2008 Stephan Aßmus <superstippi@gmx.de>. All rights reserved.
* Distributed under the terms of the MIT/X11 license. * Distributed under the terms of the MIT/X11 license.
* *
@@ -9,7 +10,7 @@
#ifndef STATUS_VIEW_H #ifndef STATUS_VIEW_H
#define STATUS_VIEW_H #define STATUS_VIEW_H
#include <Button.h>
#include <View.h> #include <View.h>
#include <StringView.h> #include <StringView.h>
#include <Rect.h> #include <Rect.h>
@@ -19,17 +20,22 @@ struct FileInfo;
class StatusView: public BView { class StatusView: public BView {
public: public:
StatusView(BRect frame); StatusView();
virtual ~StatusView(); virtual ~StatusView();
void ShowInfo(const FileInfo* info); void ShowInfo(const FileInfo* info);
void SetBtnLabel(const char* label);
void SetRescanEnabled(bool enabled);
private: private:
BStringView* fPathView; BStringView* fPathView;
BStringView* fSizeView; BStringView* fSizeView;
BStringView* fCountView; BStringView* fCountView;
const FileInfo* fCurrentFileInfo; const FileInfo* fCurrentFileInfo;
BButton* fRefreshBtn;
}; };
#endif // STATUS_VIEW_H #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