* First attempt at cleaning up the CopyLoopControl mess. Instantiate one
TrackerCopyLoopControl and pass it on when needed. Avoid access to gStatusWindow directly. Later on, I will try to make it possible to drop more files/folders onto an ongoing copy process to append it to the job, i.e. copy those files to the same target folder. * For each updating the status, entry_refs were copied instead of passed by reference, which was a bit unnecessary overhead. * Some coding style cleanup. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@35055 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
+165
-109
@@ -111,7 +111,8 @@ static status_t _RestoreTask(BObjectList<entry_ref> *);
|
|||||||
status_t CalcItemsAndSize(BObjectList<entry_ref> *refList, size_t blockSize,
|
status_t CalcItemsAndSize(BObjectList<entry_ref> *refList, size_t blockSize,
|
||||||
int32 *totalCount, off_t *totalSize);
|
int32 *totalCount, off_t *totalSize);
|
||||||
status_t MoveItem(BEntry *entry, BDirectory *destDir, BPoint *loc,
|
status_t MoveItem(BEntry *entry, BDirectory *destDir, BPoint *loc,
|
||||||
uint32 moveMode, const char *newName, Undo &undo);
|
uint32 moveMode, const char *newName, Undo &undo,
|
||||||
|
CopyLoopControl* loopControl);
|
||||||
ConflictCheckResult PreFlightNameCheck(BObjectList<entry_ref> *srcList,
|
ConflictCheckResult PreFlightNameCheck(BObjectList<entry_ref> *srcList,
|
||||||
const BDirectory *destDir, int32 *collisionCount, uint32 moveMode);
|
const BDirectory *destDir, int32 *collisionCount, uint32 moveMode);
|
||||||
status_t CheckName(uint32 moveMode, const BEntry *srcEntry,
|
status_t CheckName(uint32 moveMode, const BEntry *srcEntry,
|
||||||
@@ -171,77 +172,14 @@ const char *kSkipAttributes[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
CopyLoopControl::~CopyLoopControl()
|
CopyLoopControl::~CopyLoopControl()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
|
||||||
TrackerCopyLoopControl::FileError(const char *message, const char *name,
|
|
||||||
status_t error, bool allowContinue)
|
|
||||||
{
|
|
||||||
char buffer[512];
|
|
||||||
sprintf(buffer, message, name, strerror(error));
|
|
||||||
|
|
||||||
if (allowContinue) {
|
|
||||||
BAlert *alert = new BAlert("", buffer, "Cancel", "OK", 0,
|
|
||||||
B_WIDTH_AS_USUAL, B_STOP_ALERT);
|
|
||||||
alert->SetShortcut(0, B_ESCAPE);
|
|
||||||
return alert->Go() != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
BAlert *alert = new BAlert("", buffer, "Cancel", 0, 0,
|
|
||||||
B_WIDTH_AS_USUAL, B_STOP_ALERT);
|
|
||||||
alert->SetShortcut(0, B_ESCAPE);
|
|
||||||
alert->Go();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
TrackerCopyLoopControl::UpdateStatus(const char *name, entry_ref, int32 count,
|
|
||||||
bool optional)
|
|
||||||
{
|
|
||||||
if (gStatusWindow)
|
|
||||||
gStatusWindow->UpdateStatus(fThread, name, count, optional);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool
|
|
||||||
TrackerCopyLoopControl::CheckUserCanceled()
|
|
||||||
{
|
|
||||||
return gStatusWindow && gStatusWindow->CheckCanceledOrPaused(fThread);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
TrackerCopyLoopControl::OverwriteMode
|
|
||||||
TrackerCopyLoopControl::OverwriteOnConflict(const BEntry *, const char *,
|
|
||||||
const BDirectory *, bool, bool)
|
|
||||||
{
|
|
||||||
return kReplace;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool
|
|
||||||
TrackerCopyLoopControl::SkipEntry(const BEntry *, bool)
|
|
||||||
{
|
|
||||||
// tracker makes no exceptions
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool
|
|
||||||
TrackerCopyLoopControl::SkipAttribute(const char *attributeName)
|
|
||||||
{
|
|
||||||
for (const char **skipAttribute = kSkipAttributes; *skipAttribute;
|
|
||||||
skipAttribute++)
|
|
||||||
if (strcmp(*skipAttribute, attributeName) == 0)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
CopyLoopControl::ChecksumChunk(const char *, size_t)
|
CopyLoopControl::ChecksumChunk(const char *, size_t)
|
||||||
{
|
{
|
||||||
@@ -269,6 +207,121 @@ CopyLoopControl::PreserveAttribute(const char*)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
|
TrackerCopyLoopControl::TrackerCopyLoopControl(thread_id thread)
|
||||||
|
:
|
||||||
|
fThread(thread),
|
||||||
|
fSourceList(NULL)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TrackerCopyLoopControl::TrackerCopyLoopControl(thread_id thread,
|
||||||
|
int32 totalItems, off_t totalSize)
|
||||||
|
:
|
||||||
|
fThread(thread),
|
||||||
|
fSourceList(NULL)
|
||||||
|
{
|
||||||
|
if (gStatusWindow)
|
||||||
|
gStatusWindow->InitStatusItem(thread, totalItems, totalItems);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TrackerCopyLoopControl::~TrackerCopyLoopControl()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
TrackerCopyLoopControl::FileError(const char *message, const char *name,
|
||||||
|
status_t error, bool allowContinue)
|
||||||
|
{
|
||||||
|
char buffer[512];
|
||||||
|
sprintf(buffer, message, name, strerror(error));
|
||||||
|
|
||||||
|
if (allowContinue) {
|
||||||
|
BAlert *alert = new BAlert("", buffer, "Cancel", "OK", 0,
|
||||||
|
B_WIDTH_AS_USUAL, B_STOP_ALERT);
|
||||||
|
alert->SetShortcut(0, B_ESCAPE);
|
||||||
|
return alert->Go() != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
BAlert *alert = new BAlert("", buffer, "Cancel", 0, 0,
|
||||||
|
B_WIDTH_AS_USUAL, B_STOP_ALERT);
|
||||||
|
alert->SetShortcut(0, B_ESCAPE);
|
||||||
|
alert->Go();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
TrackerCopyLoopControl::UpdateStatus(const char *name, const entry_ref&,
|
||||||
|
int32 count, bool optional)
|
||||||
|
{
|
||||||
|
if (gStatusWindow)
|
||||||
|
gStatusWindow->UpdateStatus(fThread, name, count, optional);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
TrackerCopyLoopControl::CheckUserCanceled()
|
||||||
|
{
|
||||||
|
if (gStatusWindow == NULL)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (gStatusWindow->CheckCanceledOrPaused(fThread))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (fSourceList != NULL) {
|
||||||
|
// TODO: Check if the user dropped additional files onto this job.
|
||||||
|
// printf("%p->CheckUserCanceled()\n", this);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TrackerCopyLoopControl::OverwriteMode
|
||||||
|
TrackerCopyLoopControl::OverwriteOnConflict(const BEntry *, const char *,
|
||||||
|
const BDirectory *, bool, bool)
|
||||||
|
{
|
||||||
|
return kReplace;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
TrackerCopyLoopControl::SkipEntry(const BEntry *, bool)
|
||||||
|
{
|
||||||
|
// tracker makes no exceptions
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
TrackerCopyLoopControl::SkipAttribute(const char *attributeName)
|
||||||
|
{
|
||||||
|
for (const char **skipAttribute = kSkipAttributes; *skipAttribute;
|
||||||
|
skipAttribute++) {
|
||||||
|
if (strcmp(*skipAttribute, attributeName) == 0)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
TrackerCopyLoopControl::SetSourceList(EntryList* list)
|
||||||
|
{
|
||||||
|
fSourceList = list;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
static BNode *
|
static BNode *
|
||||||
GetWritableNode(BEntry *entry, StatStruct *statBuf = 0)
|
GetWritableNode(BEntry *entry, StatStruct *statBuf = 0)
|
||||||
{
|
{
|
||||||
@@ -396,8 +449,8 @@ FSMoveToFolder(BObjectList<entry_ref> *srcList, BEntry *destEntry,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
LaunchInNewThread("MoveTask", B_NORMAL_PRIORITY, MoveTask, srcList, destEntry,
|
LaunchInNewThread("MoveTask", B_NORMAL_PRIORITY, MoveTask, srcList,
|
||||||
pointList, moveMode);
|
destEntry, pointList, moveMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -552,7 +605,8 @@ ConfirmChangeIfWellKnownDirectory(const BEntry *entry, const char *action,
|
|||||||
static status_t
|
static status_t
|
||||||
InitCopy(uint32 moveMode, BObjectList<entry_ref> *srcList, thread_id thread,
|
InitCopy(uint32 moveMode, BObjectList<entry_ref> *srcList, thread_id thread,
|
||||||
BVolume *dstVol, BDirectory *destDir, entry_ref *destRef,
|
BVolume *dstVol, BDirectory *destDir, entry_ref *destRef,
|
||||||
bool preflightNameCheck, bool needSizeCalculation, int32 *collisionCount, ConflictCheckResult *preflightResult)
|
bool preflightNameCheck, bool needSizeCalculation, int32 *collisionCount,
|
||||||
|
ConflictCheckResult *preflightResult)
|
||||||
{
|
{
|
||||||
if (dstVol->IsReadOnly()) {
|
if (dstVol->IsReadOnly()) {
|
||||||
if (gStatusWindow)
|
if (gStatusWindow)
|
||||||
@@ -675,7 +729,8 @@ delete_point(void *point)
|
|||||||
|
|
||||||
|
|
||||||
static status_t
|
static status_t
|
||||||
MoveTask(BObjectList<entry_ref> *srcList, BEntry *destEntry, BList *pointList, uint32 moveMode)
|
MoveTask(BObjectList<entry_ref> *srcList, BEntry *destEntry, BList *pointList,
|
||||||
|
uint32 moveMode)
|
||||||
{
|
{
|
||||||
ASSERT(!srcList->IsEmpty());
|
ASSERT(!srcList->IsEmpty());
|
||||||
|
|
||||||
@@ -686,7 +741,7 @@ MoveTask(BObjectList<entry_ref> *srcList, BEntry *destEntry, BList *pointList, u
|
|||||||
dev_t destVolumeDevice = srcVolumeDevice;
|
dev_t destVolumeDevice = srcVolumeDevice;
|
||||||
|
|
||||||
StatStruct deststat;
|
StatStruct deststat;
|
||||||
BVolume volume (srcVolumeDevice);
|
BVolume volume(srcVolumeDevice);
|
||||||
entry_ref destRef;
|
entry_ref destRef;
|
||||||
const entry_ref *destRefToCheck = NULL;
|
const entry_ref *destRefToCheck = NULL;
|
||||||
|
|
||||||
@@ -732,16 +787,19 @@ MoveTask(BObjectList<entry_ref> *srcList, BEntry *destEntry, BList *pointList, u
|
|||||||
}
|
}
|
||||||
|
|
||||||
// change the move mode if needed
|
// change the move mode if needed
|
||||||
if (moveMode == kCopySelectionTo && destIsTrash)
|
if (moveMode == kCopySelectionTo && destIsTrash) {
|
||||||
// cannot copy to trash
|
// cannot copy to trash
|
||||||
moveMode = kMoveSelectionTo;
|
moveMode = kMoveSelectionTo;
|
||||||
|
}
|
||||||
|
|
||||||
if (moveMode == kMoveSelectionTo && sourceIsReadOnly)
|
if (moveMode == kMoveSelectionTo && sourceIsReadOnly)
|
||||||
moveMode = kCopySelectionTo;
|
moveMode = kCopySelectionTo;
|
||||||
|
|
||||||
bool needSizeCalculation = true;
|
bool needSizeCalculation = true;
|
||||||
if ((moveMode == kMoveSelectionTo && srcVolumeDevice == destVolumeDevice) || destIsTrash)
|
if ((moveMode == kMoveSelectionTo && srcVolumeDevice == destVolumeDevice)
|
||||||
|
|| destIsTrash) {
|
||||||
needSizeCalculation = false;
|
needSizeCalculation = false;
|
||||||
|
}
|
||||||
|
|
||||||
// we need the undo object later on, so we create it no matter
|
// we need the undo object later on, so we create it no matter
|
||||||
// if we really need it or not (it's very lightweight)
|
// if we really need it or not (it's very lightweight)
|
||||||
@@ -755,9 +813,11 @@ MoveTask(BObjectList<entry_ref> *srcList, BEntry *destEntry, BList *pointList, u
|
|||||||
status_t result = InitCopy(moveMode, srcList, thread, &volume, destDirToCheck,
|
status_t result = InitCopy(moveMode, srcList, thread, &volume, destDirToCheck,
|
||||||
&destRef, needPreflightNameCheck, needSizeCalculation, &collisionCount, &conflictCheckResult);
|
&destRef, needPreflightNameCheck, needSizeCalculation, &collisionCount, &conflictCheckResult);
|
||||||
|
|
||||||
int32 count = srcList->CountItems();
|
TrackerCopyLoopControl loopControl(thread);
|
||||||
|
loopControl.SetSourceList(srcList);
|
||||||
|
|
||||||
if (result == B_OK) {
|
if (result == B_OK) {
|
||||||
for (int32 i = 0; i < count; i++) {
|
for (int32 i = 0; i < srcList->CountItems(); i++) {
|
||||||
BPoint *loc = (BPoint *)-1;
|
BPoint *loc = (BPoint *)-1;
|
||||||
// a loc of -1 forces autoplacement, rather than copying the
|
// a loc of -1 forces autoplacement, rather than copying the
|
||||||
// position of the original node
|
// position of the original node
|
||||||
@@ -783,7 +843,7 @@ MoveTask(BObjectList<entry_ref> *srcList, BEntry *destEntry, BList *pointList, u
|
|||||||
&& srcRef->directory == deststat.st_ino))
|
&& srcRef->directory == deststat.st_ino))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (gStatusWindow && gStatusWindow->CheckCanceledOrPaused(thread))
|
if (loopControl.CheckUserCanceled())
|
||||||
break;
|
break;
|
||||||
|
|
||||||
BEntry sourceEntry(srcRef);
|
BEntry sourceEntry(srcRef);
|
||||||
@@ -824,8 +884,7 @@ MoveTask(BObjectList<entry_ref> *srcList, BEntry *destEntry, BList *pointList, u
|
|||||||
|
|
||||||
// update the status because item got skipped and the status
|
// update the status because item got skipped and the status
|
||||||
// will not get updated by the move call
|
// will not get updated by the move call
|
||||||
if (gStatusWindow)
|
loopControl.UpdateStatus(srcRef->name, *srcRef, 1);
|
||||||
gStatusWindow->UpdateStatus(thread, srcRef->name, 1);
|
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -849,7 +908,8 @@ MoveTask(BObjectList<entry_ref> *srcList, BEntry *destEntry, BList *pointList, u
|
|||||||
if (pointList)
|
if (pointList)
|
||||||
loc = (BPoint*)pointList->ItemAt(i);
|
loc = (BPoint*)pointList->ItemAt(i);
|
||||||
|
|
||||||
result = MoveItem(&sourceEntry, &destDir, loc, moveMode, NULL, undo);
|
result = MoveItem(&sourceEntry, &destDir, loc, moveMode, NULL, undo,
|
||||||
|
&loopControl);
|
||||||
if (result != B_OK)
|
if (result != B_OK)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -909,7 +969,8 @@ class MoveError {
|
|||||||
|
|
||||||
void
|
void
|
||||||
CopyFile(BEntry *srcFile, StatStruct *srcStat, BDirectory *destDir,
|
CopyFile(BEntry *srcFile, StatStruct *srcStat, BDirectory *destDir,
|
||||||
CopyLoopControl *loopControl, BPoint *loc, bool makeOriginalName, Undo &undo)
|
CopyLoopControl *loopControl, BPoint *loc, bool makeOriginalName,
|
||||||
|
Undo &undo)
|
||||||
{
|
{
|
||||||
if (loopControl->SkipEntry(srcFile, true))
|
if (loopControl->SkipEntry(srcFile, true))
|
||||||
return;
|
return;
|
||||||
@@ -1333,9 +1394,8 @@ CopyFolder(BEntry *srcEntry, BDirectory *destDir, CopyLoopControl *loopControl,
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
RecursiveMove(BEntry *entry, BDirectory *destDir)
|
RecursiveMove(BEntry *entry, BDirectory *destDir, CopyLoopControl* loopControl)
|
||||||
{
|
{
|
||||||
TrackerCopyLoopControl loopControl(find_thread(NULL));
|
|
||||||
char name[B_FILE_NAME_LENGTH];
|
char name[B_FILE_NAME_LENGTH];
|
||||||
if (entry->GetName(name) == B_OK) {
|
if (entry->GetName(name) == B_OK) {
|
||||||
if (destDir->Contains(name)) {
|
if (destDir->Contains(name)) {
|
||||||
@@ -1349,12 +1409,16 @@ RecursiveMove(BEntry *entry, BDirectory *destDir)
|
|||||||
BEntry current;
|
BEntry current;
|
||||||
while (source.GetNextEntry(¤t) == B_OK) {
|
while (source.GetNextEntry(¤t) == B_OK) {
|
||||||
if (current.IsDirectory()) {
|
if (current.IsDirectory()) {
|
||||||
RecursiveMove(¤t, &subDir);
|
RecursiveMove(¤t, &subDir, loopControl);
|
||||||
current.Remove();
|
current.Remove();
|
||||||
} else {
|
} else {
|
||||||
current.GetName(name);
|
current.GetName(name);
|
||||||
if (loopControl.OverwriteOnConflict(¤t, name, &subDir, true, false) != TrackerCopyLoopControl::kSkip)
|
if (loopControl->OverwriteOnConflict(¤t, name,
|
||||||
MoveError::FailOnError(current.MoveTo(&subDir, NULL, true));
|
&subDir, true, false)
|
||||||
|
!= TrackerCopyLoopControl::kSkip) {
|
||||||
|
MoveError::FailOnError(current.MoveTo(&subDir,
|
||||||
|
NULL, true));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1369,7 +1433,7 @@ RecursiveMove(BEntry *entry, BDirectory *destDir)
|
|||||||
|
|
||||||
status_t
|
status_t
|
||||||
MoveItem(BEntry *entry, BDirectory *destDir, BPoint *loc, uint32 moveMode,
|
MoveItem(BEntry *entry, BDirectory *destDir, BPoint *loc, uint32 moveMode,
|
||||||
const char *newName, Undo &undo)
|
const char *newName, Undo &undo, CopyLoopControl* loopControl)
|
||||||
{
|
{
|
||||||
entry_ref ref;
|
entry_ref ref;
|
||||||
try {
|
try {
|
||||||
@@ -1483,20 +1547,18 @@ MoveItem(BEntry *entry, BDirectory *destDir, BPoint *loc, uint32 moveMode,
|
|||||||
|
|
||||||
// for "Move" the size for status is always 1 - since file
|
// for "Move" the size for status is always 1 - since file
|
||||||
// size is irrelevant when simply moving to a new folder
|
// size is irrelevant when simply moving to a new folder
|
||||||
|
loopControl->UpdateStatus(ref.name, ref, 1);
|
||||||
thread_id thread = find_thread(NULL);
|
|
||||||
if (gStatusWindow)
|
|
||||||
gStatusWindow->UpdateStatus(thread, ref.name, 1);
|
|
||||||
if (entry->IsDirectory())
|
if (entry->IsDirectory())
|
||||||
return RecursiveMove(entry, destDir);
|
return RecursiveMove(entry, destDir, loopControl);
|
||||||
MoveError::FailOnError(entry->MoveTo(destDir, newName));
|
MoveError::FailOnError(entry->MoveTo(destDir, newName));
|
||||||
} else {
|
} else {
|
||||||
TrackerCopyLoopControl loopControl(find_thread(NULL));
|
|
||||||
bool makeOriginalName = (moveMode == kDuplicateSelection);
|
bool makeOriginalName = (moveMode == kDuplicateSelection);
|
||||||
if (S_ISDIR(statbuf.st_mode)) {
|
if (S_ISDIR(statbuf.st_mode)) {
|
||||||
CopyFolder(entry, destDir, &loopControl, loc, makeOriginalName, undo, moveMode == kMoveSelectionTo);
|
CopyFolder(entry, destDir, loopControl, loc, makeOriginalName,
|
||||||
|
undo, moveMode == kMoveSelectionTo);
|
||||||
} else {
|
} else {
|
||||||
CopyFile(entry, &statbuf, destDir, &loopControl, loc, makeOriginalName, undo);
|
CopyFile(entry, &statbuf, destDir, loopControl, loc,
|
||||||
|
makeOriginalName, undo);
|
||||||
if (moveMode == kMoveSelectionTo)
|
if (moveMode == kMoveSelectionTo)
|
||||||
entry->Remove();
|
entry->Remove();
|
||||||
}
|
}
|
||||||
@@ -1721,7 +1783,9 @@ MoveEntryToTrash(BEntry *entry, BPoint *loc, Undo &undo)
|
|||||||
node.WriteAttrString(kAttrOriginalPath, &originalPath);
|
node.WriteAttrString(kAttrOriginalPath, &originalPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
MoveItem(entry, &trash_dir, loc, kMoveSelectionTo, name, undo);
|
TrackerCopyLoopControl loopControl(find_thread(NULL));
|
||||||
|
MoveItem(entry, &trash_dir, loc, kMoveSelectionTo, name, undo,
|
||||||
|
&loopControl);
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1911,10 +1975,9 @@ CheckName(uint32 moveMode, const BEntry *sourceEntry, const BDirectory *destDir,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// delete destination item
|
// delete destination item
|
||||||
if (!destIsDir) {
|
if (!destIsDir)
|
||||||
TrackerCopyLoopControl loopControl(find_thread(NULL));
|
|
||||||
err = entry.Remove();
|
err = entry.Remove();
|
||||||
} else
|
else
|
||||||
return B_OK;
|
return B_OK;
|
||||||
|
|
||||||
if (err != B_OK) {
|
if (err != B_OK) {
|
||||||
@@ -2509,13 +2572,10 @@ empty_trash(void *)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (err == B_OK) {
|
if (err == B_OK) {
|
||||||
if (gStatusWindow)
|
TrackerCopyLoopControl loopControl(thread, totalCount, totalCount);
|
||||||
gStatusWindow->InitStatusItem(thread, totalCount, totalCount);
|
|
||||||
|
|
||||||
volumeRoster.Rewind();
|
volumeRoster.Rewind();
|
||||||
while (volumeRoster.GetNextVolume(&volume) == B_OK) {
|
while (volumeRoster.GetNextVolume(&volume) == B_OK) {
|
||||||
TrackerCopyLoopControl loopControl(thread);
|
|
||||||
|
|
||||||
if (volume.IsReadOnly() || !volume.IsPersistent())
|
if (volume.IsReadOnly() || !volume.IsPersistent())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@@ -2589,11 +2649,9 @@ _DeleteTask(BObjectList<entry_ref> *list, bool confirm)
|
|||||||
|
|
||||||
status_t err = CalcItemsAndSize(list, 0, &totalItems, &totalSize);
|
status_t err = CalcItemsAndSize(list, 0, &totalItems, &totalSize);
|
||||||
if (err == B_OK) {
|
if (err == B_OK) {
|
||||||
if (gStatusWindow)
|
TrackerCopyLoopControl loopControl(thread, totalItems, totalItems);
|
||||||
gStatusWindow->InitStatusItem(thread, totalItems, totalItems);
|
|
||||||
|
|
||||||
int32 count = list->CountItems();
|
int32 count = list->CountItems();
|
||||||
TrackerCopyLoopControl loopControl(thread);
|
|
||||||
for (int32 index = 0; index < count; index++) {
|
for (int32 index = 0; index < count; index++) {
|
||||||
entry_ref ref(*list->ItemAt(index));
|
entry_ref ref(*list->ItemAt(index));
|
||||||
BEntry entry(&ref);
|
BEntry entry(&ref);
|
||||||
@@ -2659,11 +2717,9 @@ _RestoreTask(BObjectList<entry_ref> *list)
|
|||||||
|
|
||||||
status_t err = CalcItemsAndSize(list, 0, &totalItems, &totalSize);
|
status_t err = CalcItemsAndSize(list, 0, &totalItems, &totalSize);
|
||||||
if (err == B_OK) {
|
if (err == B_OK) {
|
||||||
if (gStatusWindow)
|
TrackerCopyLoopControl loopControl(thread, totalItems, totalItems);
|
||||||
gStatusWindow->InitStatusItem(thread, totalItems, totalItems);
|
|
||||||
|
|
||||||
int32 count = list->CountItems();
|
int32 count = list->CountItems();
|
||||||
TrackerCopyLoopControl loopControl(thread);
|
|
||||||
for (int32 index = 0; index < count; index++) {
|
for (int32 index = 0; index < count; index++) {
|
||||||
entry_ref ref(*list->ItemAt(index));
|
entry_ref ref(*list->ItemAt(index));
|
||||||
BEntry entry(&ref);
|
BEntry entry(&ref);
|
||||||
|
|||||||
+71
-62
@@ -57,92 +57,101 @@ namespace BPrivate {
|
|||||||
|
|
||||||
class BInfoWindow;
|
class BInfoWindow;
|
||||||
|
|
||||||
|
//! Controls the copy engine; may be overriden to specify how conflicts are
|
||||||
|
// handled, etc.
|
||||||
class CopyLoopControl {
|
class CopyLoopControl {
|
||||||
// controls the copy engine; may be overriden to specify how conflicts are
|
public:
|
||||||
// handled, etc.
|
virtual ~CopyLoopControl();
|
||||||
// Installer has it's own subclass
|
|
||||||
public:
|
|
||||||
virtual ~CopyLoopControl();
|
|
||||||
virtual bool FileError(const char *message, const char *name, status_t error,
|
|
||||||
bool allowContinue) = 0;
|
|
||||||
// inform that a file error occurred while copying <name>
|
|
||||||
// returns true if user decided to continue
|
|
||||||
|
|
||||||
virtual void UpdateStatus(const char *name, entry_ref ref, int32 count,
|
//! Inform that a file error occurred while copying <name>.
|
||||||
bool optional = false) = 0;
|
// \return \c True if user decided to continue
|
||||||
|
virtual bool FileError(const char *message,
|
||||||
|
const char *name, status_t error,
|
||||||
|
bool allowContinue) = 0;
|
||||||
|
|
||||||
virtual bool CheckUserCanceled() = 0;
|
virtual void UpdateStatus(const char *name,
|
||||||
// returns true if canceled
|
const entry_ref& ref, int32 count,
|
||||||
|
bool optional = false) = 0;
|
||||||
|
|
||||||
enum OverwriteMode {
|
//! \return \c true if canceled
|
||||||
kSkip, // do not replace, go to next entry
|
virtual bool CheckUserCanceled() = 0;
|
||||||
kReplace, // remove entry before copying new one
|
|
||||||
kMerge // for folders: leave existing folder, update contents leaving
|
enum OverwriteMode {
|
||||||
// nonconflicting items
|
kSkip, // do not replace, go to next entry
|
||||||
|
kReplace, // remove entry before copying new one
|
||||||
|
kMerge // for folders: leave existing folder, update
|
||||||
|
// contents leaving nonconflicting items
|
||||||
// for files: save original attributes on file.
|
// for files: save original attributes on file.
|
||||||
};
|
};
|
||||||
|
|
||||||
virtual OverwriteMode OverwriteOnConflict(const BEntry *srcEntry,
|
//! Override to always overwrite, never overwrite, let user decide,
|
||||||
const char *destName, const BDirectory *destDir, bool srcIsDir,
|
// compare dates, etc.
|
||||||
bool dstIsDir) = 0;
|
virtual OverwriteMode OverwriteOnConflict(const BEntry *srcEntry,
|
||||||
// override to always overwrite, never overwrite, let user decide,
|
const char *destName,
|
||||||
// compare dates, etc.
|
const BDirectory *destDir,
|
||||||
|
bool srcIsDir, bool dstIsDir) = 0;
|
||||||
|
|
||||||
virtual bool SkipEntry(const BEntry *, bool file) = 0;
|
//! Override to prevent copying of a given file or directory
|
||||||
// override to prevent copying of a given file or directory
|
virtual bool SkipEntry(const BEntry *, bool file) = 0;
|
||||||
|
|
||||||
virtual void ChecksumChunk(const char *block, size_t size);
|
//! During a file copy, this is called every time a chunk of data
|
||||||
// during a file copy, this is called every time a chunk of data
|
// is copied. Users may override to keep a running checksum.
|
||||||
// is copied. Users may override to keep a running checksum.
|
virtual void ChecksumChunk(const char *block, size_t size);
|
||||||
|
|
||||||
virtual bool ChecksumFile(const entry_ref *);
|
//! This is called when a file is finished copying. Users of this
|
||||||
// This is called when a file is finished copying. Users of this
|
// class may override to verify that the checksum they've been
|
||||||
// class may override to verify that the checksum they've been
|
// computing in ChecksumChunk matches. If this returns true,
|
||||||
// computing in ChecksumChunk matches. If this returns true,
|
// the copy will continue. If false, if will abort.
|
||||||
// the copy will continue. If false, if will abort.
|
virtual bool ChecksumFile(const entry_ref *);
|
||||||
|
|
||||||
virtual bool SkipAttribute(const char *attributeName);
|
virtual bool SkipAttribute(const char *attributeName);
|
||||||
virtual bool PreserveAttribute(const char *attributeName);
|
virtual bool PreserveAttribute(const char *attributeName);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//! This is the Tracker copy-specific version of CopyLoopControl.
|
||||||
class TrackerCopyLoopControl : public CopyLoopControl {
|
class TrackerCopyLoopControl : public CopyLoopControl {
|
||||||
// this is the Tracker copy - specific version of CopyLoopControl
|
public:
|
||||||
public:
|
TrackerCopyLoopControl(thread_id);
|
||||||
TrackerCopyLoopControl(thread_id);
|
TrackerCopyLoopControl(thread_id,
|
||||||
virtual ~TrackerCopyLoopControl() {}
|
int32 totalItems, off_t totalSize);
|
||||||
|
virtual ~TrackerCopyLoopControl();
|
||||||
|
|
||||||
virtual bool FileError(const char *message, const char *name, status_t error,
|
virtual bool FileError(const char *message,
|
||||||
bool allowContinue);
|
const char *name, status_t error,
|
||||||
// inform that a file error occurred while copying <name>
|
bool allowContinue);
|
||||||
// returns true if user decided to continue
|
|
||||||
|
|
||||||
virtual void UpdateStatus(const char *name, entry_ref ref, int32 count,
|
virtual void UpdateStatus(const char *name,
|
||||||
bool optional = false);
|
const entry_ref& ref, int32 count,
|
||||||
|
bool optional = false);
|
||||||
|
|
||||||
virtual bool CheckUserCanceled();
|
virtual bool CheckUserCanceled();
|
||||||
// returns true if canceled
|
|
||||||
|
|
||||||
virtual OverwriteMode OverwriteOnConflict(const BEntry *srcEntry,
|
virtual OverwriteMode OverwriteOnConflict(const BEntry *srcEntry,
|
||||||
const char *destName, const BDirectory *destDir, bool srcIsDir,
|
const char *destName,
|
||||||
bool dstIsDir);
|
const BDirectory *destDir,
|
||||||
|
bool srcIsDir, bool dstIsDir);
|
||||||
|
|
||||||
virtual bool SkipEntry(const BEntry *, bool file);
|
virtual bool SkipEntry(const BEntry *, bool file);
|
||||||
// override to prevent copying of a given file or directory
|
virtual bool SkipAttribute(const char *attributeName);
|
||||||
|
|
||||||
virtual bool SkipAttribute(const char *attributeName);
|
|
||||||
|
|
||||||
private:
|
// One can specify an entry_ref list with the source entries. This will
|
||||||
thread_id fThread;
|
// then trigger the feature to pull additional source entries from the
|
||||||
|
// status window, such that the user can drop additional items onto the
|
||||||
|
// progress display of the ongoing copy process to copy these items to
|
||||||
|
// the same target directory.
|
||||||
|
typedef BObjectList<entry_ref> EntryList;
|
||||||
|
|
||||||
|
void SetSourceList(EntryList* list);
|
||||||
|
|
||||||
|
private:
|
||||||
|
thread_id fThread;
|
||||||
|
|
||||||
|
EntryList* fSourceList;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
inline
|
|
||||||
TrackerCopyLoopControl::TrackerCopyLoopControl(thread_id thread)
|
|
||||||
: fThread(thread)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
#define B_DESKTOP_DIR_NAME "Desktop"
|
#define B_DESKTOP_DIR_NAME "Desktop"
|
||||||
|
|
||||||
#ifndef _IMPEXP_TRACKER
|
#ifndef _IMPEXP_TRACKER
|
||||||
|
|||||||
Reference in New Issue
Block a user