[haiku-commits] r35055 - haiku/trunk/src/kits/tracker

  • From: superstippi@xxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Wed, 13 Jan 2010 18:20:01 +0100 (CET)

Author: stippi
Date: 2010-01-13 18:20:01 +0100 (Wed, 13 Jan 2010)
New Revision: 35055
Changeset: http://dev.haiku-os.org/changeset/35055/haiku

Modified:
   haiku/trunk/src/kits/tracker/FSUtils.cpp
   haiku/trunk/src/kits/tracker/FSUtils.h
Log:
 * 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.


Modified: haiku/trunk/src/kits/tracker/FSUtils.cpp
===================================================================
--- haiku/trunk/src/kits/tracker/FSUtils.cpp    2010-01-13 17:19:14 UTC (rev 
35054)
+++ haiku/trunk/src/kits/tracker/FSUtils.cpp    2010-01-13 17:20:01 UTC (rev 
35055)
@@ -111,7 +111,8 @@
 status_t CalcItemsAndSize(BObjectList<entry_ref> *refList, size_t blockSize,
        int32 *totalCount, off_t *totalSize);
 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,
        const BDirectory *destDir, int32 *collisionCount, uint32 moveMode);
 status_t CheckName(uint32 moveMode, const BEntry *srcEntry,
@@ -171,12 +172,69 @@
 };
 
 
+// #pragma mark -
+
+
 CopyLoopControl::~CopyLoopControl()
 {
 }
 
 
+void
+CopyLoopControl::ChecksumChunk(const char *, size_t)
+{
+}
+
+
 bool
+CopyLoopControl::ChecksumFile(const entry_ref *)
+{
+       return true;
+}
+
+
+bool
+CopyLoopControl::SkipAttribute(const char*)
+{
+       return false;
+}
+
+
+bool
+CopyLoopControl::PreserveAttribute(const char*)
+{
+       return false;
+}
+
+
+// #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)
 {
@@ -199,8 +257,8 @@
 
 
 void
-TrackerCopyLoopControl::UpdateStatus(const char *name, entry_ref, int32 count,
-       bool optional)
+TrackerCopyLoopControl::UpdateStatus(const char *name, const entry_ref&,
+       int32 count, bool optional)
 {
        if (gStatusWindow)
                gStatusWindow->UpdateStatus(fThread, name, count, optional);
@@ -210,7 +268,18 @@
 bool
 TrackerCopyLoopControl::CheckUserCanceled()
 {
-       return gStatusWindow && gStatusWindow->CheckCanceledOrPaused(fThread);
+       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;
 }
 
 
@@ -234,41 +303,25 @@
 TrackerCopyLoopControl::SkipAttribute(const char *attributeName)
 {
        for (const char **skipAttribute = kSkipAttributes; *skipAttribute;
-               skipAttribute++)
+               skipAttribute++) {
                if (strcmp(*skipAttribute, attributeName) == 0)
                        return true;
+       }
 
        return false;
 }
 
 
 void
-CopyLoopControl::ChecksumChunk(const char *, size_t)
+TrackerCopyLoopControl::SetSourceList(EntryList* list)
 {
+       fSourceList = list;
 }
 
 
-bool
-CopyLoopControl::ChecksumFile(const entry_ref *)
-{
-       return true;
-}
+// #pragma mark -
 
 
-bool
-CopyLoopControl::SkipAttribute(const char*)
-{
-       return false;
-}
-
-
-bool
-CopyLoopControl::PreserveAttribute(const char*)
-{
-       return false;
-}
-
-
 static BNode *
 GetWritableNode(BEntry *entry, StatStruct *statBuf = 0)
 {
@@ -396,8 +449,8 @@
                return;
        }
 
-       LaunchInNewThread("MoveTask", B_NORMAL_PRIORITY, MoveTask, srcList, 
destEntry,
-               pointList, moveMode);
+       LaunchInNewThread("MoveTask", B_NORMAL_PRIORITY, MoveTask, srcList,
+               destEntry, pointList, moveMode);
 }
 
 
@@ -552,7 +605,8 @@
 static status_t
 InitCopy(uint32 moveMode, BObjectList<entry_ref> *srcList, thread_id thread,
        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 (gStatusWindow)
@@ -675,7 +729,8 @@
 
 
 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());
 
@@ -686,7 +741,7 @@
        dev_t destVolumeDevice = srcVolumeDevice;
 
        StatStruct deststat;
-       BVolume volume (srcVolumeDevice);
+       BVolume volume(srcVolumeDevice);
        entry_ref destRef;
        const entry_ref *destRefToCheck = NULL;
 
@@ -732,16 +787,19 @@
        }
 
        // change the move mode if needed
-       if (moveMode == kCopySelectionTo && destIsTrash)
+       if (moveMode == kCopySelectionTo && destIsTrash) {
                // cannot copy to trash
                moveMode = kMoveSelectionTo;
+       }
 
        if (moveMode == kMoveSelectionTo && sourceIsReadOnly)
                moveMode = kCopySelectionTo;
 
        bool needSizeCalculation = true;
-       if ((moveMode == kMoveSelectionTo && srcVolumeDevice == 
destVolumeDevice) || destIsTrash)
+       if ((moveMode == kMoveSelectionTo && srcVolumeDevice == 
destVolumeDevice)
+               || destIsTrash) {
                needSizeCalculation = false;
+       }
 
        // we need the undo object later on, so we create it no matter
        // if we really need it or not (it's very lightweight)
@@ -755,9 +813,11 @@
        status_t result = InitCopy(moveMode, srcList, thread, &volume, 
destDirToCheck,
                &destRef, needPreflightNameCheck, needSizeCalculation, 
&collisionCount, &conflictCheckResult);
 
-       int32 count = srcList->CountItems();
+       TrackerCopyLoopControl loopControl(thread);
+       loopControl.SetSourceList(srcList);
+
        if (result == B_OK) {
-               for (int32 i = 0; i < count; i++) {
+               for (int32 i = 0; i < srcList->CountItems(); i++) {
                        BPoint *loc = (BPoint *)-1;
                                // a loc of -1 forces autoplacement, rather 
than copying the
                                // position of the original node
@@ -783,7 +843,7 @@
                                        && srcRef->directory == 
deststat.st_ino))
                                continue;
 
-                       if (gStatusWindow && 
gStatusWindow->CheckCanceledOrPaused(thread))
+                       if (loopControl.CheckUserCanceled())
                                break;
 
                        BEntry sourceEntry(srcRef);
@@ -824,8 +884,7 @@
 
                                // update the status because item got skipped 
and the status
                                // will not get updated by the move call
-                               if (gStatusWindow)
-                                       gStatusWindow->UpdateStatus(thread, 
srcRef->name, 1);
+                               loopControl.UpdateStatus(srcRef->name, *srcRef, 
1);
 
                                continue;
                        }
@@ -849,7 +908,8 @@
                        if (pointList)
                                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)
                                break;
                }
@@ -909,7 +969,8 @@
 
 void
 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))
                return;
@@ -1333,9 +1394,8 @@
 
 
 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];
        if (entry->GetName(name) == B_OK) {
                if (destDir->Contains(name)) {
@@ -1349,12 +1409,16 @@
                                BEntry current;
                                while (source.GetNextEntry(&current) == B_OK) {
                                        if (current.IsDirectory()) {
-                                               RecursiveMove(&current, 
&subDir);
+                                               RecursiveMove(&current, 
&subDir, loopControl);
                                                current.Remove();
                                        } else {
                                                current.GetName(name);
-                                               if 
(loopControl.OverwriteOnConflict(&current, name, &subDir, true, false) != 
TrackerCopyLoopControl::kSkip)
-                                                       
MoveError::FailOnError(current.MoveTo(&subDir, NULL, true));
+                                               if 
(loopControl->OverwriteOnConflict(&current, name,
+                                                       &subDir, true, false)
+                                                               != 
TrackerCopyLoopControl::kSkip) {
+                                                       
MoveError::FailOnError(current.MoveTo(&subDir,
+                                                               NULL, true));
+                                               }
                                        }
                                }
                        }
@@ -1369,7 +1433,7 @@
 
 status_t
 MoveItem(BEntry *entry, BDirectory *destDir, BPoint *loc, uint32 moveMode,
-       const char *newName, Undo &undo)
+       const char *newName, Undo &undo, CopyLoopControl* loopControl)
 {
        entry_ref ref;
        try {
@@ -1483,20 +1547,18 @@
 
                        // for "Move" the size for status is always 1 - since 
file
                        // size is irrelevant when simply moving to a new folder
-
-                       thread_id thread = find_thread(NULL);
-                       if (gStatusWindow)
-                               gStatusWindow->UpdateStatus(thread, ref.name, 
1);
+                       loopControl->UpdateStatus(ref.name, ref, 1);
                        if (entry->IsDirectory())
-                               return RecursiveMove(entry, destDir);
+                               return RecursiveMove(entry, destDir, 
loopControl);
                        MoveError::FailOnError(entry->MoveTo(destDir, newName));
                } else {
-                       TrackerCopyLoopControl loopControl(find_thread(NULL));
                        bool makeOriginalName = (moveMode == 
kDuplicateSelection);
                        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 {
-                               CopyFile(entry, &statbuf, destDir, 
&loopControl, loc, makeOriginalName, undo);
+                               CopyFile(entry, &statbuf, destDir, loopControl, 
loc,
+                                       makeOriginalName, undo);
                                if (moveMode == kMoveSelectionTo)
                                        entry->Remove();
                        }
@@ -1721,7 +1783,9 @@
                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;
 }
 
@@ -1911,10 +1975,9 @@
        }
 
        // delete destination item
-       if (!destIsDir) {
-               TrackerCopyLoopControl loopControl(find_thread(NULL));
+       if (!destIsDir)
                err = entry.Remove();
-       } else
+       else
                return B_OK;
 
        if (err != B_OK) {
@@ -2509,13 +2572,10 @@
        }
 
        if (err == B_OK) {
-               if (gStatusWindow)
-                       gStatusWindow->InitStatusItem(thread, totalCount, 
totalCount);
+               TrackerCopyLoopControl loopControl(thread, totalCount, 
totalCount);
 
                volumeRoster.Rewind();
                while (volumeRoster.GetNextVolume(&volume) == B_OK) {
-                       TrackerCopyLoopControl loopControl(thread);
-
                        if (volume.IsReadOnly() || !volume.IsPersistent())
                                continue;
 
@@ -2589,11 +2649,9 @@
 
        status_t err = CalcItemsAndSize(list, 0, &totalItems, &totalSize);
        if (err == B_OK) {
-               if (gStatusWindow)
-                       gStatusWindow->InitStatusItem(thread, totalItems, 
totalItems);
+               TrackerCopyLoopControl loopControl(thread, totalItems, 
totalItems);
 
                int32 count = list->CountItems();
-               TrackerCopyLoopControl loopControl(thread);
                for (int32 index = 0; index < count; index++) {
                        entry_ref ref(*list->ItemAt(index));
                        BEntry entry(&ref);
@@ -2659,11 +2717,9 @@
 
        status_t err = CalcItemsAndSize(list, 0, &totalItems, &totalSize);
        if (err == B_OK) {
-               if (gStatusWindow)
-                       gStatusWindow->InitStatusItem(thread, totalItems, 
totalItems);
+               TrackerCopyLoopControl loopControl(thread, totalItems, 
totalItems);
 
                int32 count = list->CountItems();
-               TrackerCopyLoopControl loopControl(thread);
                for (int32 index = 0; index < count; index++) {
                        entry_ref ref(*list->ItemAt(index));
                        BEntry entry(&ref);

Modified: haiku/trunk/src/kits/tracker/FSUtils.h
===================================================================
--- haiku/trunk/src/kits/tracker/FSUtils.h      2010-01-13 17:19:14 UTC (rev 
35054)
+++ haiku/trunk/src/kits/tracker/FSUtils.h      2010-01-13 17:20:01 UTC (rev 
35055)
@@ -57,92 +57,101 @@
 
 class BInfoWindow;
 
+//! Controls the copy engine; may be overriden to specify how conflicts are
+// handled, etc.
 class CopyLoopControl {
-       // controls the copy engine; may be overriden to specify how conflicts 
are
-       // handled, etc.
-       // 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
+public:
+       virtual                                         ~CopyLoopControl();
 
-               virtual void UpdateStatus(const char *name, entry_ref ref, 
int32 count,
-                       bool optional = false) = 0;
+       //! Inform that a file error occurred while copying <name>.
+       // \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;
-                       // returns true if canceled
+       virtual void                            UpdateStatus(const char *name,
+                                                                       const 
entry_ref& ref, int32 count,
+                                                                       bool 
optional = false) = 0;
 
-               enum OverwriteMode {
-                       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
+       //! \return \c true if canceled
+       virtual bool                            CheckUserCanceled() = 0;
+
+                       enum OverwriteMode {
+                               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.
-               };
+                       };
 
-               virtual OverwriteMode OverwriteOnConflict(const BEntry 
*srcEntry,
-                       const char *destName, const BDirectory *destDir, bool 
srcIsDir,
-                       bool dstIsDir) = 0;
-                       // override to always overwrite, never overwrite, let 
user decide,
-                       // compare dates, etc.
+       //! Override to always overwrite, never overwrite, let user decide,
+       // compare dates, etc.
+       virtual OverwriteMode           OverwriteOnConflict(const BEntry 
*srcEntry,
+                                                                       const 
char *destName,
+                                                                       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
-                       // is copied.  Users may override to keep a running 
checksum.
+       //! During a file copy, this is called every time a chunk of data
+       // 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
-                       // class may override to verify that the checksum 
they've been
-                       // computing in ChecksumChunk matches.  If this returns 
true,
-                       // the copy will continue.  If false, if will abort.
+       //! This is called when a file is finished copying.  Users of this
+       // class may override to verify that the checksum they've been
+       // computing in ChecksumChunk matches.  If this returns true,
+       // the copy will continue.  If false, if will abort.
+       virtual bool                            ChecksumFile(const entry_ref *);
 
-               virtual bool SkipAttribute(const char *attributeName);
-               virtual bool PreserveAttribute(const char *attributeName);
+       virtual bool                            SkipAttribute(const char 
*attributeName);
+       virtual bool                            PreserveAttribute(const char 
*attributeName);
 };
 
 
+//! This is the Tracker copy-specific version of CopyLoopControl.
 class TrackerCopyLoopControl : public CopyLoopControl {
-       // this is the Tracker copy - specific version of CopyLoopControl
-       public:
-               TrackerCopyLoopControl(thread_id);
-               virtual ~TrackerCopyLoopControl() {}
+public:
+                                                               
TrackerCopyLoopControl(thread_id);
+                                                               
TrackerCopyLoopControl(thread_id,
+                                                                       int32 
totalItems, off_t totalSize);
+       virtual                                         
~TrackerCopyLoopControl();
 
-               virtual bool FileError(const char *message, const char *name, 
status_t error,
-                       bool allowContinue);
-                       // inform that a file error occurred while copying 
<name>
-                       // returns true if user decided to continue
+       virtual bool                            FileError(const char *message,
+                                                                       const 
char *name, status_t error,
+                                                                       bool 
allowContinue);
 
-               virtual void UpdateStatus(const char *name, entry_ref ref, 
int32 count,
-                       bool optional = false);
+       virtual void                            UpdateStatus(const char *name,
+                                                                       const 
entry_ref& ref, int32 count,
+                                                                       bool 
optional = false);
 
-               virtual bool CheckUserCanceled();
-                       // returns true if canceled
+       virtual bool                            CheckUserCanceled();
 
-               virtual OverwriteMode OverwriteOnConflict(const BEntry 
*srcEntry,
-                       const char *destName, const BDirectory *destDir, bool 
srcIsDir,
-                       bool dstIsDir);
+       virtual OverwriteMode           OverwriteOnConflict(const BEntry 
*srcEntry,
+                                                                       const 
char *destName,
+                                                                       const 
BDirectory *destDir,
+                                                                       bool 
srcIsDir, bool dstIsDir);
 
-               virtual bool SkipEntry(const BEntry *, bool file);
-                       // override to prevent copying of a given file or 
directory
+       virtual bool                            SkipEntry(const BEntry *, bool 
file);
+       virtual bool                            SkipAttribute(const char 
*attributeName);
 
-               virtual bool SkipAttribute(const char *attributeName);
 
-       private:
-               thread_id fThread;
+       // One can specify an entry_ref list with the source entries. This will
+       // 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"
 
 #ifndef _IMPEXP_TRACKER


Other related posts: