Ticket #1420: Tracker.FSUtilsFixes.patch

File Tracker.FSUtilsFixes.patch, 6.0 KB (added by anevilyak, 10 years ago)

preliminary testing patch

  • FSUtils.cpp

     
    588588    switch (moveMode) {
    589589        case kCopySelectionTo:
    590590        case kDuplicateSelection:
     591        case kMoveSelectionTo:
    591592            {
    592593                if (gStatusWindow)
    593594                    gStatusWindow->CreateStatusItem(thread, kCopyState);
     
    610611                break;
    611612            }
    612613
    613         case kMoveSelectionTo:
    614614        case kCreateLink:
    615615            if (numItems > 10) {
    616616                // this will be fast, only put up status if lots of items
     
    703703    }
    704704
    705705    // change the move mode if needed
    706     if (moveMode == kMoveSelectionTo && srcVolumeDevice != destVolumeDevice)
    707         // move across volumes - copy instead
    708         moveMode = kCopySelectionTo;
    709706    if (moveMode == kCopySelectionTo && destIsTrash)
    710707        // cannot copy to trash
    711708        moveMode = kMoveSelectionTo;
     
    908905                return;
    909906
    910907            case TrackerCopyLoopControl::kReplace:
    911                 if (conflictingEntry.IsDirectory())
    912                     // remove existing folder recursively
    913                     ThrowOnError(FSDeleteFolder(&conflictingEntry, loopControl, false));
    914                 else
     908                if (!conflictingEntry.IsDirectory()) {
    915909                    ThrowOnError(conflictingEntry.Remove());
    916                 break;
    917 
     910                    break;
     911                }
     912                // fall through if not a directory
    918913            case TrackerCopyLoopControl::kMerge:
    919914                // This flag implies that the attributes should be kept
    920915                // on the file.  Just ignore it.
     
    11741169
    11751170static void
    11761171CopyFolder(BEntry *srcEntry, BDirectory *destDir, CopyLoopControl *loopControl,
    1177     BPoint *loc, bool makeOriginalName, Undo &undo)
     1172    BPoint *loc, bool makeOriginalName, Undo &undo, bool removeSource = false)
    11781173{
    11791174    BDirectory newDir;
    11801175    BEntry entry;
     
    12091204                // we are about to ignore this entire directory
    12101205                return;
    12111206
     1207           
    12121208            case TrackerCopyLoopControl::kReplace:
    1213                 if (isDirectory)
    1214                     // remove existing folder recursively
    1215                     ThrowOnError(FSDeleteFolder(&existingEntry, loopControl, false));
    1216 
    1217                 else
     1209                if (!isDirectory) {
    12181210                    // conflicting with a file or symbolic link, remove entry
    12191211                    ThrowOnError(existingEntry.Remove());
    1220                 break;
    1221 
     1212                    break;
     1213                }
     1214            // fall through if directory, do not replace.
    12221215            case TrackerCopyLoopControl::kMerge:
    12231216                ASSERT(isDirectory);
    12241217                // do not create a new directory, use the current one
     
    12311224    // loop through everything in src folder and copy it to new folder
    12321225    BDirectory srcDir(srcEntry);
    12331226    srcDir.Rewind();
    1234     srcEntry->Unset();
    12351227
    12361228    // create a new folder inside of destination folder
    12371229    if (createDirectory) {
     
    12841276                continue;
    12851277            }
    12861278           
    1287             CopyFolder(&entry, &newDir, loopControl, 0, false, undo);
    1288         } else
     1279            CopyFolder(&entry, &newDir, loopControl, 0, false, undo, removeSource);
     1280            if (removeSource)
     1281                FSDeleteFolder(&entry, loopControl, true, true, false);
     1282        } else {
    12891283            CopyFile(&entry, &statbuf, &newDir, loopControl, 0, false, undo);
     1284            if (removeSource)
     1285                entry.Remove();
     1286        }
    12901287    }
     1288    if (removeSource)
     1289        srcEntry->Remove();
     1290    else
     1291        srcEntry->Unset();
    12911292}
    12921293
    12931294
    12941295status_t
     1296RecursiveMove(BEntry *entry, BDirectory *destDir)
     1297{
     1298    TrackerCopyLoopControl loopControl(find_thread(NULL));
     1299    char name[B_FILE_NAME_LENGTH];
     1300    if (entry->GetName(name) == B_OK) {
     1301        if (destDir->Contains(name)) {
     1302            BPath path (destDir, name);
     1303            BDirectory subDir (path.Path());
     1304            entry_ref ref;
     1305            entry->GetRef(&ref);
     1306            BDirectory source(&ref);
     1307            if (source.InitCheck() == B_OK) {
     1308                source.Rewind();
     1309                BEntry current;
     1310                while (source.GetNextEntry(&current) == B_OK) {
     1311                    if (current.IsDirectory()) {
     1312                        RecursiveMove(&current, &subDir);
     1313                        current.Remove();
     1314                    } else {
     1315                        current.GetName(name);
     1316                        if (loopControl.OverwriteOnConflict(&current, name, &subDir, true, false) != TrackerCopyLoopControl::kSkip)
     1317                            MoveError::FailOnError(current.MoveTo(&subDir, NULL, true));
     1318                    }
     1319                }
     1320            }
     1321            entry->Remove();
     1322        } else {
     1323            MoveError::FailOnError(entry->MoveTo(destDir));
     1324        }
     1325    }
     1326   
     1327    return B_OK;
     1328}   
     1329
     1330status_t
    12951331MoveItem(BEntry *entry, BDirectory *destDir, BPoint *loc, uint32 moveMode,
    12961332    const char *newName, Undo &undo)
    12971333{
     
    12991335    try {
    13001336        node_ref destNode;
    13011337        StatStruct statbuf;
    1302 
    13031338        MoveError::FailOnError(entry->GetStat(&statbuf));
    13041339        MoveError::FailOnError(entry->GetRef(&ref));
    13051340        MoveError::FailOnError(destDir->GetNodeRef(&destNode));
     
    14121447            thread_id thread = find_thread(NULL);
    14131448            if (gStatusWindow && gStatusWindow->HasStatus(thread))
    14141449                gStatusWindow->UpdateStatus(thread, ref.name, 1);
    1415 
     1450            if (entry->IsDirectory())
     1451                return RecursiveMove(entry, destDir);
    14161452            MoveError::FailOnError(entry->MoveTo(destDir, newName));
    14171453        } else {
    14181454            TrackerCopyLoopControl loopControl(find_thread(NULL));
    1419 
    14201455            bool makeOriginalName = (moveMode == kDuplicateSelection);
    1421             if (S_ISDIR(statbuf.st_mode))
    1422                 CopyFolder(entry, destDir, &loopControl, loc, makeOriginalName, undo);
    1423             else
     1456            if (S_ISDIR(statbuf.st_mode)) {
     1457                CopyFolder(entry, destDir, &loopControl, loc, makeOriginalName, undo, moveMode == kMoveSelectionTo);
     1458            } else {
    14241459                CopyFile(entry, &statbuf, destDir, &loopControl, loc, makeOriginalName, undo);
     1460                if (moveMode == kMoveSelectionTo)               
     1461                    entry->Remove();
     1462            }
    14251463        }
    14261464    } catch (status_t error) {
    14271465        // no alert, was already taken care of before
     
    18331871    }
    18341872
    18351873    // delete destination item
    1836     if (destIsDir) {
     1874    if (!destIsDir) {
    18371875        TrackerCopyLoopControl loopControl(find_thread(NULL));
    1838         err = FSDeleteFolder(&entry, &loopControl, false);
     1876        err = entry.Remove();
    18391877    } else
    1840         err = entry.Remove();
     1878        return B_OK;
    18411879
    18421880    if (err != B_OK) {
    18431881        BString error;
     
    18621900
    18631901    dir.SetTo(dir_entry);
    18641902    dir.Rewind();
    1865 
    18661903    // loop through everything in folder and delete it, skipping trouble files
    18671904    for (;;) {
    18681905        if (dir.GetNextEntry(&entry) != B_OK)
     
    18981935    if (update_status && delete_top_dir)
    18991936        loopControl->UpdateStatus(NULL, ref, 1);
    19001937
    1901     if (delete_top_dir)
     1938    if (delete_top_dir) 
    19021939        return dir_entry->Remove();
    19031940    else
    19041941        return B_OK;