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:31:21 -05:00
parent 9029fc709b
commit 3e52a3d5e5
12 changed files with 96 additions and 41 deletions

View File

@ -248,6 +248,7 @@ ControlsView::VolumeTabView::MessageReceived(BMessage* message)
}
break;
case kBtnCancel:
case kBtnRescan:
ViewForTab(Selection())->MessageReceived(message);
break;
@ -361,6 +362,7 @@ ControlsView::MessageReceived(BMessage* msg)
fVolumeTabView->MessageReceived(msg);
break;
case kBtnCancel:
case kBtnRescan:
fVolumeTabView->MessageReceived(msg);
break;
@ -385,10 +387,18 @@ ControlsView::ShowInfo(const FileInfo* info)
void
ControlsView::SetRescanEnabled(bool enabled)
ControlsView::EnableRescan()
{
((VolumeView*)fVolumeTabView->ViewForTab(
fVolumeTabView->Selection()))->SetRescanEnabled(enabled);
fVolumeTabView->Selection()))->EnableRescan();
}
void
ControlsView::EnableCancel()
{
((VolumeView*)fVolumeTabView->ViewForTab(
fVolumeTabView->Selection()))->EnableCancel();
}

View File

@ -28,7 +28,8 @@ public:
BVolume* FindDeviceFor(dev_t device,
bool invoke = false);
void SetRescanEnabled(bool enabled);
void EnableRescan();
void EnableCancel();
void ShowInfo(const FileInfo* info);
private:

View File

@ -42,7 +42,7 @@ const float kMinButtonWidth = 60.0;
const float kProgBarWidth = 150.0;
const float kProgBarHeight = 16.0;
const float kReportInterval = 2.5;
const float kReportInterval = 0.0025;
const float kDefaultPieSize = 400.0;
const float kPieCenterSize = 80.0;
@ -57,6 +57,7 @@ extern bool helpFileWasFound;
#define kMenuSelectVol 'gMSV'
#define kBtnRescan 'gBRF'
#define kBtnCancel 'gCAN'
#define kBtnHelp 'gHLP'
#define kScanRefresh 'gSRF'
#define kScanProgress 'gSPR'

View File

@ -51,9 +51,8 @@ void
MainWindow::MessageReceived(BMessage* message)
{
switch (message->what) {
case kBtnCancel:
case kBtnRescan:
fControlsView->MessageReceived(message);
break;
case B_SIMPLE_DATA:
case B_REFS_RECEIVED:
fControlsView->MessageReceived(message);
@ -83,9 +82,16 @@ MainWindow::QuitRequested()
void
MainWindow::SetRescanEnabled(bool enabled)
MainWindow::EnableRescan()
{
fControlsView->SetRescanEnabled(enabled);
fControlsView->EnableRescan();
}
void
MainWindow::EnableCancel()
{
fControlsView->EnableCancel();
}

View File

@ -26,7 +26,8 @@ public:
virtual void MessageReceived(BMessage* message);
virtual bool QuitRequested();
void SetRescanEnabled(bool enabled);
void EnableRescan();
void EnableCancel();
BVolume* FindDeviceFor(dev_t device,
bool invoke = false);

View File

@ -181,23 +181,26 @@ void
PieView::MessageReceived(BMessage* message)
{
switch (message->what) {
case kBtnCancel:
if (fScanner != NULL)
fScanner->Cancel();
break;
case kBtnRescan:
if (fVolume != NULL) {
if (fScanner != NULL)
fScanner->Refresh();
else
_ShowVolume(fVolume);
fWindow->EnableCancel();
Invalidate();
}
break;
case kScanProgress:
case kScanDone:
{
fWindow->EnableRescan();
case kScanProgress:
Invalidate();
break;
}
default:
BView::MessageReceived(message);
@ -300,12 +303,8 @@ PieView::Draw(BRect updateRect)
if (fScanner->IsBusy()) {
// Show progress of scanning.
_DrawProgressBar(updateRect);
if (fWindow != NULL)
fWindow->SetRescanEnabled(false);
} else {
} else if (fScanner->Snapshot() != NULL) {
_DrawPieChart(updateRect);
if (fWindow != NULL)
fWindow->SetRescanEnabled(true);
if (fUpdateFileAt) {
fWindow->ShowInfo(_FileAt(fLastWhere));
fUpdateFileAt = false;
@ -362,8 +361,7 @@ PieView::_DrawProgressBar(BRect updateRect)
float by = floorf((b.top + b.Height() - kProgBarHeight) / 2.0);
float ex = bx + kProgBarWidth;
float ey = by + kProgBarHeight;
float mx = bx + floorf((kProgBarWidth - 2.0)
* fScanner->Progress() / 100.0 + 0.5);
float mx = bx + floorf((kProgBarWidth - 2.0) * fScanner->Progress() + 0.5);
const rgb_color kBarColor = {50, 150, 255, 255};
BRect barFrame(bx, by, ex, ey);

View File

@ -35,7 +35,8 @@ Scanner::Scanner(BVolume *v, BHandler *handler)
fDesiredPath(),
fTask(),
fBusy(false),
fQuitRequested(false)
fQuitRequested(false),
fPreviousSnapshot(NULL)
{
Run();
}
@ -88,6 +89,16 @@ Scanner::Refresh(FileInfo* startInfo)
}
void
Scanner::Cancel()
{
if (!fBusy)
return;
fQuitRequested = true;
}
void
Scanner::SetDesiredPath(string &path)
{
@ -133,22 +144,29 @@ Scanner::_DirectoryContains(FileInfo* currentDir, entry_ref* ref)
void
Scanner::_RunScan(FileInfo* startInfo)
{
fPreviousSnapshot = fSnapshot;
fQuitRequested = false;
BString stringScan(B_TRANSLATE("Scanning %refName%"));
if (startInfo == NULL || startInfo == fSnapshot->rootDir) {
delete fSnapshot;
fSnapshot = new VolumeSnapshot(fVolume);
stringScan.ReplaceFirst("%refName%", fSnapshot->name.c_str());
fTask = stringScan.String();
fVolumeBytesInUse = fSnapshot->capacity - fSnapshot->freeBytes;
fVolumeBytesScanned = 0;
fProgress = 0.0;
fLastReport = -100.0;
fLastReport = -1.0;
BDirectory root;
fVolume->GetRootDirectory(&root);
fSnapshot->rootDir = _GetFileInfo(&root, NULL);
if (fSnapshot->rootDir == NULL) {
delete fSnapshot;
fSnapshot = fPreviousSnapshot;
fBusy = false;
fListener.SendMessage(&fDoneMessage);
return;
}
FileInfo* freeSpace = new FileInfo;
freeSpace->pseudo = true;
BString string(B_TRANSLATE("Free on %refName%"));
@ -166,14 +184,21 @@ Scanner::_RunScan(FileInfo* startInfo)
fTask = stringScan.String();
fVolumeBytesInUse = fSnapshot->capacity - fSnapshot->freeBytes;
fVolumeBytesScanned = fVolumeBytesInUse - startInfo->size; //best guess
fProgress = 100.0 * fVolumeBytesScanned / fVolumeBytesInUse;
fLastReport = -100.0;
fProgress = fVolumeBytesScanned / fVolumeBytesInUse;
fLastReport = -1.0;
BDirectory startDir(&startInfo->ref);
if (startDir.InitCheck() == B_OK) {
FileInfo *parent = startInfo->parent;
vector<FileInfo *>::iterator i = parent->children.begin();
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)
i++;
@ -206,7 +231,7 @@ Scanner::_GetFileInfo(BDirectory* dir, FileInfo* parent)
while (true) {
if (fQuitRequested)
break;
return NULL;
if (dir->GetNextEntry(&entry) == B_ENTRY_NOT_FOUND)
break;
@ -223,7 +248,7 @@ Scanner::_GetFileInfo(BDirectory* dir, FileInfo* parent)
// Send a progress report periodically.
fVolumeBytesScanned += child->size;
fProgress = 100.0 * fVolumeBytesScanned / fVolumeBytesInUse;
fProgress = (float)fVolumeBytesScanned / fVolumeBytesInUse;
if (fProgress - fLastReport > kReportInterval) {
fLastReport = fProgress;
fListener.SendMessage(&fProgressMessage);

View File

@ -35,12 +35,13 @@ public:
VolumeSnapshot* Snapshot() const
{ return fBusy ? NULL : fSnapshot; }
void Refresh(FileInfo* startInfo = NULL);
void Cancel();
bool IsBusy() const
{ return fBusy; }
const char* Task() const
{ return fTask.c_str(); }
float Progress() const
{ return min_c(100.0, fProgress); }
{ return min_c(1.0, fProgress); }
FileInfo* CurrentDir() const
{ return fBusy ? NULL : fSnapshot->currentDir; }
void ChangeDir(FileInfo* info)
@ -71,6 +72,8 @@ private:
string fTask;
bool fBusy;
bool fQuitRequested;
VolumeSnapshot* fPreviousSnapshot;
};
#endif // SCANNER_H

View File

@ -97,16 +97,18 @@ StatusView::~StatusView()
void
StatusView::SetRescanEnabled(bool enabled)
StatusView::EnableRescan()
{
fRefreshBtn->SetEnabled(enabled);
fRefreshBtn->SetLabel(B_TRANSLATE("Rescan"));
fRefreshBtn->SetMessage(new BMessage(kBtnRescan));
}
void
StatusView::SetBtnLabel(const char* label)
StatusView::EnableCancel()
{
fRefreshBtn->SetLabel(label);
fRefreshBtn->SetLabel(B_TRANSLATE("Abort"));
fRefreshBtn->SetMessage(new BMessage(kBtnCancel));
}

View File

@ -24,8 +24,8 @@ public:
virtual ~StatusView();
void ShowInfo(const FileInfo* info);
void SetBtnLabel(const char* label);
void SetRescanEnabled(bool enabled);
void EnableRescan();
void EnableCancel();
private:
BStringView* fPathView;

View File

@ -52,9 +52,16 @@ VolumeView::~VolumeView()
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)
{
fPieView->SetPath(path);
fStatusView->SetBtnLabel(B_TRANSLATE("Rescan"));
EnableRescan();
}
@ -70,9 +77,9 @@ void
VolumeView::MessageReceived(BMessage* msg)
{
switch(msg->what) {
case kBtnCancel:
case kBtnRescan:
fPieView->MessageReceived(msg);
fStatusView->SetBtnLabel(B_TRANSLATE("Rescan"));
break;
default:

View File

@ -30,7 +30,8 @@ public:
virtual ~VolumeView();
virtual void MessageReceived(BMessage* message);
void SetRescanEnabled(bool enabled);
void EnableRescan();
void EnableCancel();
void SetPath(BPath path);
void ShowInfo(const FileInfo* info);