Ticket #1420: Tracker.FSUtilsFixes.patch
File Tracker.FSUtilsFixes.patch, 6.0 KB (added by , 16 years ago) |
---|
-
FSUtils.cpp
588 588 switch (moveMode) { 589 589 case kCopySelectionTo: 590 590 case kDuplicateSelection: 591 case kMoveSelectionTo: 591 592 { 592 593 if (gStatusWindow) 593 594 gStatusWindow->CreateStatusItem(thread, kCopyState); … … 610 611 break; 611 612 } 612 613 613 case kMoveSelectionTo:614 614 case kCreateLink: 615 615 if (numItems > 10) { 616 616 // this will be fast, only put up status if lots of items … … 703 703 } 704 704 705 705 // change the move mode if needed 706 if (moveMode == kMoveSelectionTo && srcVolumeDevice != destVolumeDevice)707 // move across volumes - copy instead708 moveMode = kCopySelectionTo;709 706 if (moveMode == kCopySelectionTo && destIsTrash) 710 707 // cannot copy to trash 711 708 moveMode = kMoveSelectionTo; … … 908 905 return; 909 906 910 907 case TrackerCopyLoopControl::kReplace: 911 if (conflictingEntry.IsDirectory()) 912 // remove existing folder recursively 913 ThrowOnError(FSDeleteFolder(&conflictingEntry, loopControl, false)); 914 else 908 if (!conflictingEntry.IsDirectory()) { 915 909 ThrowOnError(conflictingEntry.Remove()); 916 break; 917 910 break; 911 } 912 // fall through if not a directory 918 913 case TrackerCopyLoopControl::kMerge: 919 914 // This flag implies that the attributes should be kept 920 915 // on the file. Just ignore it. … … 1174 1169 1175 1170 static void 1176 1171 CopyFolder(BEntry *srcEntry, BDirectory *destDir, CopyLoopControl *loopControl, 1177 BPoint *loc, bool makeOriginalName, Undo &undo )1172 BPoint *loc, bool makeOriginalName, Undo &undo, bool removeSource = false) 1178 1173 { 1179 1174 BDirectory newDir; 1180 1175 BEntry entry; … … 1209 1204 // we are about to ignore this entire directory 1210 1205 return; 1211 1206 1207 1212 1208 case TrackerCopyLoopControl::kReplace: 1213 if (isDirectory) 1214 // remove existing folder recursively 1215 ThrowOnError(FSDeleteFolder(&existingEntry, loopControl, false)); 1216 1217 else 1209 if (!isDirectory) { 1218 1210 // conflicting with a file or symbolic link, remove entry 1219 1211 ThrowOnError(existingEntry.Remove()); 1220 break; 1221 1212 break; 1213 } 1214 // fall through if directory, do not replace. 1222 1215 case TrackerCopyLoopControl::kMerge: 1223 1216 ASSERT(isDirectory); 1224 1217 // do not create a new directory, use the current one … … 1231 1224 // loop through everything in src folder and copy it to new folder 1232 1225 BDirectory srcDir(srcEntry); 1233 1226 srcDir.Rewind(); 1234 srcEntry->Unset();1235 1227 1236 1228 // create a new folder inside of destination folder 1237 1229 if (createDirectory) { … … 1284 1276 continue; 1285 1277 } 1286 1278 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 { 1289 1283 CopyFile(&entry, &statbuf, &newDir, loopControl, 0, false, undo); 1284 if (removeSource) 1285 entry.Remove(); 1286 } 1290 1287 } 1288 if (removeSource) 1289 srcEntry->Remove(); 1290 else 1291 srcEntry->Unset(); 1291 1292 } 1292 1293 1293 1294 1294 1295 status_t 1296 RecursiveMove(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(¤t) == B_OK) { 1311 if (current.IsDirectory()) { 1312 RecursiveMove(¤t, &subDir); 1313 current.Remove(); 1314 } else { 1315 current.GetName(name); 1316 if (loopControl.OverwriteOnConflict(¤t, 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 1330 status_t 1295 1331 MoveItem(BEntry *entry, BDirectory *destDir, BPoint *loc, uint32 moveMode, 1296 1332 const char *newName, Undo &undo) 1297 1333 { … … 1299 1335 try { 1300 1336 node_ref destNode; 1301 1337 StatStruct statbuf; 1302 1303 1338 MoveError::FailOnError(entry->GetStat(&statbuf)); 1304 1339 MoveError::FailOnError(entry->GetRef(&ref)); 1305 1340 MoveError::FailOnError(destDir->GetNodeRef(&destNode)); … … 1412 1447 thread_id thread = find_thread(NULL); 1413 1448 if (gStatusWindow && gStatusWindow->HasStatus(thread)) 1414 1449 gStatusWindow->UpdateStatus(thread, ref.name, 1); 1415 1450 if (entry->IsDirectory()) 1451 return RecursiveMove(entry, destDir); 1416 1452 MoveError::FailOnError(entry->MoveTo(destDir, newName)); 1417 1453 } else { 1418 1454 TrackerCopyLoopControl loopControl(find_thread(NULL)); 1419 1420 1455 bool makeOriginalName = (moveMode == kDuplicateSelection); 1421 if (S_ISDIR(statbuf.st_mode)) 1422 CopyFolder(entry, destDir, &loopControl, loc, makeOriginalName, undo );1423 else1456 if (S_ISDIR(statbuf.st_mode)) { 1457 CopyFolder(entry, destDir, &loopControl, loc, makeOriginalName, undo, moveMode == kMoveSelectionTo); 1458 } else { 1424 1459 CopyFile(entry, &statbuf, destDir, &loopControl, loc, makeOriginalName, undo); 1460 if (moveMode == kMoveSelectionTo) 1461 entry->Remove(); 1462 } 1425 1463 } 1426 1464 } catch (status_t error) { 1427 1465 // no alert, was already taken care of before … … 1833 1871 } 1834 1872 1835 1873 // delete destination item 1836 if ( destIsDir) {1874 if (!destIsDir) { 1837 1875 TrackerCopyLoopControl loopControl(find_thread(NULL)); 1838 err = FSDeleteFolder(&entry, &loopControl, false);1876 err = entry.Remove(); 1839 1877 } else 1840 err = entry.Remove();1878 return B_OK; 1841 1879 1842 1880 if (err != B_OK) { 1843 1881 BString error; … … 1862 1900 1863 1901 dir.SetTo(dir_entry); 1864 1902 dir.Rewind(); 1865 1866 1903 // loop through everything in folder and delete it, skipping trouble files 1867 1904 for (;;) { 1868 1905 if (dir.GetNextEntry(&entry) != B_OK) … … 1898 1935 if (update_status && delete_top_dir) 1899 1936 loopControl->UpdateStatus(NULL, ref, 1); 1900 1937 1901 if (delete_top_dir) 1938 if (delete_top_dir) 1902 1939 return dir_entry->Remove(); 1903 1940 else 1904 1941 return B_OK;