DiskUsage: added ability to cancel an ongoing scan. fixes #6801.

Also, progress now goes from 0.0 to 1.0 rather than from 0.00 to 100.00
(to avoid a * 100, followed by a / 100)
This commit is contained in:
Philippe Saint-Pierre
2012-11-14 22:33:44 -05:00
parent 9029fc709b
commit 3e52a3d5e5
12 changed files with 96 additions and 41 deletions
+12 -2
View File
@@ -248,6 +248,7 @@ ControlsView::VolumeTabView::MessageReceived(BMessage* message)
} }
break; break;
case kBtnCancel:
case kBtnRescan: case kBtnRescan:
ViewForTab(Selection())->MessageReceived(message); ViewForTab(Selection())->MessageReceived(message);
break; break;
@@ -361,6 +362,7 @@ ControlsView::MessageReceived(BMessage* msg)
fVolumeTabView->MessageReceived(msg); fVolumeTabView->MessageReceived(msg);
break; break;
case kBtnCancel:
case kBtnRescan: case kBtnRescan:
fVolumeTabView->MessageReceived(msg); fVolumeTabView->MessageReceived(msg);
break; break;
@@ -385,10 +387,18 @@ ControlsView::ShowInfo(const FileInfo* info)
void void
ControlsView::SetRescanEnabled(bool enabled) ControlsView::EnableRescan()
{ {
((VolumeView*)fVolumeTabView->ViewForTab( ((VolumeView*)fVolumeTabView->ViewForTab(
fVolumeTabView->Selection()))->SetRescanEnabled(enabled); fVolumeTabView->Selection()))->EnableRescan();
}
void
ControlsView::EnableCancel()
{
((VolumeView*)fVolumeTabView->ViewForTab(
fVolumeTabView->Selection()))->EnableCancel();
} }
+2 -1
View File
@@ -28,7 +28,8 @@ public:
BVolume* FindDeviceFor(dev_t device, BVolume* FindDeviceFor(dev_t device,
bool invoke = false); bool invoke = false);
void SetRescanEnabled(bool enabled); void EnableRescan();
void EnableCancel();
void ShowInfo(const FileInfo* info); void ShowInfo(const FileInfo* info);
private: private:
+2 -1
View File
@@ -42,7 +42,7 @@ const float kMinButtonWidth = 60.0;
const float kProgBarWidth = 150.0; const float kProgBarWidth = 150.0;
const float kProgBarHeight = 16.0; const float kProgBarHeight = 16.0;
const float kReportInterval = 2.5; const float kReportInterval = 0.0025;
const float kDefaultPieSize = 400.0; const float kDefaultPieSize = 400.0;
const float kPieCenterSize = 80.0; const float kPieCenterSize = 80.0;
@@ -57,6 +57,7 @@ extern bool helpFileWasFound;
#define kMenuSelectVol 'gMSV' #define kMenuSelectVol 'gMSV'
#define kBtnRescan 'gBRF' #define kBtnRescan 'gBRF'
#define kBtnCancel 'gCAN'
#define kBtnHelp 'gHLP' #define kBtnHelp 'gHLP'
#define kScanRefresh 'gSRF' #define kScanRefresh 'gSRF'
#define kScanProgress 'gSPR' #define kScanProgress 'gSPR'
+10 -4
View File
@@ -51,9 +51,8 @@ void
MainWindow::MessageReceived(BMessage* message) MainWindow::MessageReceived(BMessage* message)
{ {
switch (message->what) { switch (message->what) {
case kBtnCancel:
case kBtnRescan: case kBtnRescan:
fControlsView->MessageReceived(message);
break;
case B_SIMPLE_DATA: case B_SIMPLE_DATA:
case B_REFS_RECEIVED: case B_REFS_RECEIVED:
fControlsView->MessageReceived(message); fControlsView->MessageReceived(message);
@@ -83,9 +82,16 @@ MainWindow::QuitRequested()
void void
MainWindow::SetRescanEnabled(bool enabled) MainWindow::EnableRescan()
{ {
fControlsView->SetRescanEnabled(enabled); fControlsView->EnableRescan();
}
void
MainWindow::EnableCancel()
{
fControlsView->EnableCancel();
} }
+2 -1
View File
@@ -26,7 +26,8 @@ public:
virtual void MessageReceived(BMessage* message); virtual void MessageReceived(BMessage* message);
virtual bool QuitRequested(); virtual bool QuitRequested();
void SetRescanEnabled(bool enabled); void EnableRescan();
void EnableCancel();
BVolume* FindDeviceFor(dev_t device, BVolume* FindDeviceFor(dev_t device,
bool invoke = false); bool invoke = false);
+10 -12
View File
@@ -181,23 +181,26 @@ void
PieView::MessageReceived(BMessage* message) PieView::MessageReceived(BMessage* message)
{ {
switch (message->what) { switch (message->what) {
case kBtnCancel:
if (fScanner != NULL)
fScanner->Cancel();
break;
case kBtnRescan: case kBtnRescan:
if (fVolume != NULL) { if (fVolume != NULL) {
if (fScanner != NULL) if (fScanner != NULL)
fScanner->Refresh(); fScanner->Refresh();
else else
_ShowVolume(fVolume); _ShowVolume(fVolume);
fWindow->EnableCancel();
Invalidate(); Invalidate();
} }
break; break;
case kScanProgress:
case kScanDone: case kScanDone:
{ fWindow->EnableRescan();
case kScanProgress:
Invalidate(); Invalidate();
break; break;
}
default: default:
BView::MessageReceived(message); BView::MessageReceived(message);
@@ -300,12 +303,8 @@ PieView::Draw(BRect updateRect)
if (fScanner->IsBusy()) { if (fScanner->IsBusy()) {
// Show progress of scanning. // Show progress of scanning.
_DrawProgressBar(updateRect); _DrawProgressBar(updateRect);
if (fWindow != NULL) } else if (fScanner->Snapshot() != NULL) {
fWindow->SetRescanEnabled(false);
} else {
_DrawPieChart(updateRect); _DrawPieChart(updateRect);
if (fWindow != NULL)
fWindow->SetRescanEnabled(true);
if (fUpdateFileAt) { if (fUpdateFileAt) {
fWindow->ShowInfo(_FileAt(fLastWhere)); fWindow->ShowInfo(_FileAt(fLastWhere));
fUpdateFileAt = false; fUpdateFileAt = false;
@@ -362,8 +361,7 @@ PieView::_DrawProgressBar(BRect updateRect)
float by = floorf((b.top + b.Height() - kProgBarHeight) / 2.0); float by = floorf((b.top + b.Height() - kProgBarHeight) / 2.0);
float ex = bx + kProgBarWidth; float ex = bx + kProgBarWidth;
float ey = by + kProgBarHeight; float ey = by + kProgBarHeight;
float mx = bx + floorf((kProgBarWidth - 2.0) float mx = bx + floorf((kProgBarWidth - 2.0) * fScanner->Progress() + 0.5);
* fScanner->Progress() / 100.0 + 0.5);
const rgb_color kBarColor = {50, 150, 255, 255}; const rgb_color kBarColor = {50, 150, 255, 255};
BRect barFrame(bx, by, ex, ey); BRect barFrame(bx, by, ex, ey);
+33 -8
View File
@@ -35,7 +35,8 @@ Scanner::Scanner(BVolume *v, BHandler *handler)
fDesiredPath(), fDesiredPath(),
fTask(), fTask(),
fBusy(false), fBusy(false),
fQuitRequested(false) fQuitRequested(false),
fPreviousSnapshot(NULL)
{ {
Run(); Run();
} }
@@ -88,6 +89,16 @@ Scanner::Refresh(FileInfo* startInfo)
} }
void
Scanner::Cancel()
{
if (!fBusy)
return;
fQuitRequested = true;
}
void void
Scanner::SetDesiredPath(string &path) Scanner::SetDesiredPath(string &path)
{ {
@@ -133,22 +144,29 @@ Scanner::_DirectoryContains(FileInfo* currentDir, entry_ref* ref)
void void
Scanner::_RunScan(FileInfo* startInfo) Scanner::_RunScan(FileInfo* startInfo)
{ {
fPreviousSnapshot = fSnapshot;
fQuitRequested = false;
BString stringScan(B_TRANSLATE("Scanning %refName%")); BString stringScan(B_TRANSLATE("Scanning %refName%"));
if (startInfo == NULL || startInfo == fSnapshot->rootDir) { if (startInfo == NULL || startInfo == fSnapshot->rootDir) {
delete fSnapshot;
fSnapshot = new VolumeSnapshot(fVolume); fSnapshot = new VolumeSnapshot(fVolume);
stringScan.ReplaceFirst("%refName%", fSnapshot->name.c_str()); stringScan.ReplaceFirst("%refName%", fSnapshot->name.c_str());
fTask = stringScan.String(); fTask = stringScan.String();
fVolumeBytesInUse = fSnapshot->capacity - fSnapshot->freeBytes; fVolumeBytesInUse = fSnapshot->capacity - fSnapshot->freeBytes;
fVolumeBytesScanned = 0; fVolumeBytesScanned = 0;
fProgress = 0.0; fProgress = 0.0;
fLastReport = -100.0; fLastReport = -1.0;
BDirectory root; BDirectory root;
fVolume->GetRootDirectory(&root); fVolume->GetRootDirectory(&root);
fSnapshot->rootDir = _GetFileInfo(&root, NULL); fSnapshot->rootDir = _GetFileInfo(&root, NULL);
if (fSnapshot->rootDir == NULL) {
delete fSnapshot;
fSnapshot = fPreviousSnapshot;
fBusy = false;
fListener.SendMessage(&fDoneMessage);
return;
}
FileInfo* freeSpace = new FileInfo; FileInfo* freeSpace = new FileInfo;
freeSpace->pseudo = true; freeSpace->pseudo = true;
BString string(B_TRANSLATE("Free on %refName%")); BString string(B_TRANSLATE("Free on %refName%"));
@@ -166,14 +184,21 @@ Scanner::_RunScan(FileInfo* startInfo)
fTask = stringScan.String(); fTask = stringScan.String();
fVolumeBytesInUse = fSnapshot->capacity - fSnapshot->freeBytes; fVolumeBytesInUse = fSnapshot->capacity - fSnapshot->freeBytes;
fVolumeBytesScanned = fVolumeBytesInUse - startInfo->size; //best guess fVolumeBytesScanned = fVolumeBytesInUse - startInfo->size; //best guess
fProgress = 100.0 * fVolumeBytesScanned / fVolumeBytesInUse; fProgress = fVolumeBytesScanned / fVolumeBytesInUse;
fLastReport = -100.0; fLastReport = -1.0;
BDirectory startDir(&startInfo->ref); BDirectory startDir(&startInfo->ref);
if (startDir.InitCheck() == B_OK) { if (startDir.InitCheck() == B_OK) {
FileInfo *parent = startInfo->parent; FileInfo *parent = startInfo->parent;
vector<FileInfo *>::iterator i = parent->children.begin(); vector<FileInfo *>::iterator i = parent->children.begin();
FileInfo* newInfo = _GetFileInfo(&startDir, parent); FileInfo* newInfo = _GetFileInfo(&startDir, parent);
if (newInfo == NULL) {
delete fSnapshot;
fSnapshot = fPreviousSnapshot;
fBusy = false;
fListener.SendMessage(&fDoneMessage);
return;
}
while (i != parent->children.end() && *i != startInfo) while (i != parent->children.end() && *i != startInfo)
i++; i++;
@@ -206,7 +231,7 @@ Scanner::_GetFileInfo(BDirectory* dir, FileInfo* parent)
while (true) { while (true) {
if (fQuitRequested) if (fQuitRequested)
break; return NULL;
if (dir->GetNextEntry(&entry) == B_ENTRY_NOT_FOUND) if (dir->GetNextEntry(&entry) == B_ENTRY_NOT_FOUND)
break; break;
@@ -223,7 +248,7 @@ Scanner::_GetFileInfo(BDirectory* dir, FileInfo* parent)
// Send a progress report periodically. // Send a progress report periodically.
fVolumeBytesScanned += child->size; fVolumeBytesScanned += child->size;
fProgress = 100.0 * fVolumeBytesScanned / fVolumeBytesInUse; fProgress = (float)fVolumeBytesScanned / fVolumeBytesInUse;
if (fProgress - fLastReport > kReportInterval) { if (fProgress - fLastReport > kReportInterval) {
fLastReport = fProgress; fLastReport = fProgress;
fListener.SendMessage(&fProgressMessage); fListener.SendMessage(&fProgressMessage);
+4 -1
View File
@@ -35,12 +35,13 @@ public:
VolumeSnapshot* Snapshot() const VolumeSnapshot* Snapshot() const
{ return fBusy ? NULL : fSnapshot; } { return fBusy ? NULL : fSnapshot; }
void Refresh(FileInfo* startInfo = NULL); void Refresh(FileInfo* startInfo = NULL);
void Cancel();
bool IsBusy() const bool IsBusy() const
{ return fBusy; } { return fBusy; }
const char* Task() const const char* Task() const
{ return fTask.c_str(); } { return fTask.c_str(); }
float Progress() const float Progress() const
{ return min_c(100.0, fProgress); } { return min_c(1.0, fProgress); }
FileInfo* CurrentDir() const FileInfo* CurrentDir() const
{ return fBusy ? NULL : fSnapshot->currentDir; } { return fBusy ? NULL : fSnapshot->currentDir; }
void ChangeDir(FileInfo* info) void ChangeDir(FileInfo* info)
@@ -71,6 +72,8 @@ private:
string fTask; string fTask;
bool fBusy; bool fBusy;
bool fQuitRequested; bool fQuitRequested;
VolumeSnapshot* fPreviousSnapshot;
}; };
#endif // SCANNER_H #endif // SCANNER_H
+6 -4
View File
@@ -97,16 +97,18 @@ StatusView::~StatusView()
void void
StatusView::SetRescanEnabled(bool enabled) StatusView::EnableRescan()
{ {
fRefreshBtn->SetEnabled(enabled); fRefreshBtn->SetLabel(B_TRANSLATE("Rescan"));
fRefreshBtn->SetMessage(new BMessage(kBtnRescan));
} }
void void
StatusView::SetBtnLabel(const char* label) StatusView::EnableCancel()
{ {
fRefreshBtn->SetLabel(label); fRefreshBtn->SetLabel(B_TRANSLATE("Abort"));
fRefreshBtn->SetMessage(new BMessage(kBtnCancel));
} }
+2 -2
View File
@@ -24,8 +24,8 @@ public:
virtual ~StatusView(); virtual ~StatusView();
void ShowInfo(const FileInfo* info); void ShowInfo(const FileInfo* info);
void SetBtnLabel(const char* label); void EnableRescan();
void SetRescanEnabled(bool enabled); void EnableCancel();
private: private:
BStringView* fPathView; BStringView* fPathView;
+11 -4
View File
@@ -52,9 +52,16 @@ VolumeView::~VolumeView()
void void
VolumeView::SetRescanEnabled(bool enabled) VolumeView::EnableRescan()
{ {
fStatusView->SetRescanEnabled(enabled); fStatusView->EnableRescan();
}
void
VolumeView::EnableCancel()
{
fStatusView->EnableCancel();
} }
@@ -62,7 +69,7 @@ void
VolumeView::SetPath(BPath path) VolumeView::SetPath(BPath path)
{ {
fPieView->SetPath(path); fPieView->SetPath(path);
fStatusView->SetBtnLabel(B_TRANSLATE("Rescan")); EnableRescan();
} }
@@ -70,9 +77,9 @@ void
VolumeView::MessageReceived(BMessage* msg) VolumeView::MessageReceived(BMessage* msg)
{ {
switch(msg->what) { switch(msg->what) {
case kBtnCancel:
case kBtnRescan: case kBtnRescan:
fPieView->MessageReceived(msg); fPieView->MessageReceived(msg);
fStatusView->SetBtnLabel(B_TRANSLATE("Rescan"));
break; break;
default: default:
+2 -1
View File
@@ -30,7 +30,8 @@ public:
virtual ~VolumeView(); virtual ~VolumeView();
virtual void MessageReceived(BMessage* message); virtual void MessageReceived(BMessage* message);
void SetRescanEnabled(bool enabled); void EnableRescan();
void EnableCancel();
void SetPath(BPath path); void SetPath(BPath path);
void ShowInfo(const FileInfo* info); void ShowInfo(const FileInfo* info);