OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 function FileCopyManager() { | 5 function FileCopyManager() { |
6 this.copyTasks_ = []; | 6 this.copyTasks_ = []; |
7 this.cancelObservers_ = []; | 7 this.cancelObservers_ = []; |
8 this.cancelRequested_ = false; | 8 this.cancelRequested_ = false; |
9 } | 9 } |
10 | 10 |
(...skipping 15 matching lines...) Expand all Loading... | |
26 | 26 |
27 this.pendingDirectories = []; | 27 this.pendingDirectories = []; |
28 this.pendingFiles = []; | 28 this.pendingFiles = []; |
29 this.pendingBytes = 0; | 29 this.pendingBytes = 0; |
30 | 30 |
31 this.completedDirectories = []; | 31 this.completedDirectories = []; |
32 this.completedFiles = []; | 32 this.completedFiles = []; |
33 this.completedBytes = 0; | 33 this.completedBytes = 0; |
34 | 34 |
35 this.deleteAfterCopy = false; | 35 this.deleteAfterCopy = false; |
36 this.sourceAndTargetOnGData = false; | |
36 | 37 |
37 // If directory already exists, we try to make a copy named 'dir (X)', | 38 // If directory already exists, we try to make a copy named 'dir (X)', |
38 // where X is a number. When we do this, all subsequent copies from | 39 // where X is a number. When we do this, all subsequent copies from |
39 // inside the subtree should be mapped to the new directory name. | 40 // inside the subtree should be mapped to the new directory name. |
40 // For example, if 'dir' was copied as 'dir (1)', then 'dir\file.txt' should | 41 // For example, if 'dir' was copied as 'dir (1)', then 'dir\file.txt' should |
41 // become 'dir (1)\file.txt'. | 42 // become 'dir (1)\file.txt'. |
42 this.renamedDirectories_ = []; | 43 this.renamedDirectories_ = []; |
43 } | 44 } |
44 | 45 |
45 FileCopyManager.Task.prototype.setEntries = function(entries, callback) { | 46 FileCopyManager.Task.prototype.setEntries = function(entries, callback) { |
46 var self = this; | 47 var self = this; |
47 | 48 |
48 function onEntriesRecursed(result) { | 49 function onEntriesRecursed(result) { |
49 self.pendingDirectories = result.dirEntries; | 50 self.pendingDirectories = result.dirEntries; |
50 self.pendingFiles = result.fileEntries; | 51 self.pendingFiles = result.fileEntries; |
51 self.pendingBytes = result.fileBytes; | 52 self.pendingBytes = result.fileBytes; |
52 callback(); | 53 callback(); |
53 } | 54 } |
54 | 55 |
55 this.originalEntries = entries; | 56 this.originalEntries = entries; |
56 util.recurseAndResolveEntries(entries, onEntriesRecursed); | 57 // When moving directories, FileEntry.moveTo() is used if both source |
58 // and target are on GData. There is no need to recurse into directories. | |
59 var recurse = !(this.deleteAfterCopy && this.sourceAndTargetOnGData); | |
60 util.recurseAndResolveEntries(entries, recurse, onEntriesRecursed); | |
57 } | 61 } |
58 | 62 |
59 FileCopyManager.Task.prototype.takeNextEntry = function() { | 63 FileCopyManager.Task.prototype.takeNextEntry = function() { |
60 if (this.pendingDirectories.length) | 64 if (this.pendingDirectories.length) |
61 return this.pendingDirectories.shift(); | 65 return this.pendingDirectories.shift(); |
62 | 66 |
63 if (this.pendingFiles.length) | 67 if (this.pendingFiles.length) |
64 return this.pendingFiles.shift(); | 68 return this.pendingFiles.shift(); |
65 | 69 |
66 return null; | 70 return null; |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
186 if (!this.cancelRequested_) | 190 if (!this.cancelRequested_) |
187 return false; | 191 return false; |
188 | 192 |
189 this.doCancel_(); | 193 this.doCancel_(); |
190 return true; | 194 return true; |
191 } | 195 } |
192 | 196 |
193 /** | 197 /** |
194 * Convert string in clipboard to entries and kick off pasting. | 198 * Convert string in clipboard to entries and kick off pasting. |
195 */ | 199 */ |
196 FileCopyManager.prototype.paste = function(clipboard, targetEntry, root) { | 200 FileCopyManager.prototype.paste = function(clipboard, targetEntry, |
201 sourceAndTargetOnGData, root) { | |
197 var self = this; | 202 var self = this; |
198 var results = { | 203 var results = { |
199 sourceDirEntry: null, | 204 sourceDirEntry: null, |
200 entries: [], | 205 entries: [], |
201 isCut: false | 206 isCut: false |
202 }; | 207 }; |
203 | 208 |
204 function onPathError(err) { | 209 function onPathError(err) { |
205 var event = new cr.Event('copy-progress'); | 210 var event = new cr.Event('copy-progress'); |
206 event.reason = 'ERROR'; | 211 event.reason = 'ERROR'; |
207 event.error = new FileCopyManager.Error('FILESYSTEM_ERROR', err); | 212 event.error = new FileCopyManager.Error('FILESYSTEM_ERROR', err); |
208 self.dispatchEvent(event); | 213 self.dispatchEvent(event); |
209 } | 214 } |
210 | 215 |
211 function onSourceEntryFound(dirEntry) { | 216 function onSourceEntryFound(dirEntry) { |
212 function onComplete() { | 217 function onComplete() { |
213 self.queueCopy(results.sourceDirEntry, | 218 self.queueCopy(results.sourceDirEntry, |
214 targetEntry, | 219 targetEntry, |
215 results.entries, | 220 results.entries, |
216 results.isCut); | 221 results.isCut, |
222 sourceAndTargetOnGData); | |
217 } | 223 } |
218 | 224 |
219 function onEntryFound(entry) { | 225 function onEntryFound(entry) { |
220 // When getDirectories/getFiles finish, they call addEntry with null. | 226 // When getDirectories/getFiles finish, they call addEntry with null. |
221 // We dont want to add null to our entries. | 227 // We dont want to add null to our entries. |
222 if (entry != null) { | 228 if (entry != null) { |
223 results.entries.push(entry); | 229 results.entries.push(entry); |
224 added++; | 230 added++; |
225 if (added == total && results.sourceDirEntry != null) | 231 if (added == total && results.sourceDirEntry != null) |
226 onComplete(); | 232 onComplete(); |
(...skipping 28 matching lines...) Expand all Loading... | |
255 onSourceEntryFound, | 261 onSourceEntryFound, |
256 onPathError); | 262 onPathError); |
257 } | 263 } |
258 | 264 |
259 /** | 265 /** |
260 * Initiate a file copy. | 266 * Initiate a file copy. |
261 */ | 267 */ |
262 FileCopyManager.prototype.queueCopy = function(sourceDirEntry, | 268 FileCopyManager.prototype.queueCopy = function(sourceDirEntry, |
263 targetDirEntry, | 269 targetDirEntry, |
264 entries, | 270 entries, |
265 deleteAfterCopy) { | 271 deleteAfterCopy, |
272 sourceAndTargetOnGData) { | |
266 var self = this; | 273 var self = this; |
267 var copyTask = new FileCopyManager.Task(sourceDirEntry, targetDirEntry); | 274 var copyTask = new FileCopyManager.Task(sourceDirEntry, targetDirEntry); |
268 copyTask.deleteAfterCopy = deleteAfterCopy; | 275 copyTask.deleteAfterCopy = deleteAfterCopy; |
276 copyTask.sourceAndTargetOnGData = sourceAndTargetOnGData; | |
269 copyTask.setEntries(entries, function() { | 277 copyTask.setEntries(entries, function() { |
270 self.copyTasks_.push(copyTask); | 278 self.copyTasks_.push(copyTask); |
271 if (self.copyTasks_.length == 1) { | 279 if (self.copyTasks_.length == 1) { |
272 // This moved us from 0 to 1 active tasks, let the servicing begin! | 280 // This moved us from 0 to 1 active tasks, let the servicing begin! |
273 self.serviceAllTasks_(); | 281 self.serviceAllTasks_(); |
274 } | 282 } |
275 }); | 283 }); |
276 | 284 |
277 return copyTask; | 285 return copyTask; |
278 }; | 286 }; |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
346 | 354 |
347 for (var i = 0; i < task.originalEntries.length; i++) { | 355 for (var i = 0; i < task.originalEntries.length; i++) { |
348 util.removeFileOrDirectory( | 356 util.removeFileOrDirectory( |
349 task.originalEntries[i], onEntryDeleted, onFilesystemError); | 357 task.originalEntries[i], onEntryDeleted, onFilesystemError); |
350 } | 358 } |
351 } | 359 } |
352 | 360 |
353 function onEntryServiced(targetEntry, size) { | 361 function onEntryServiced(targetEntry, size) { |
354 if (!targetEntry) { | 362 if (!targetEntry) { |
355 // All done with the entries in this task. | 363 // All done with the entries in this task. |
356 if (task.deleteAfterCopy) { | 364 // If files are moved within GData, FileEntry.moveTo() is used and |
357 deleteOriginals() | 365 // there is no need to delete the original files. |
366 if (task.deleteAfterCopy && !task.sourceAndTargetOnGData) { | |
367 deleteOriginals(); | |
358 } else { | 368 } else { |
359 onTaskComplete(); | 369 onTaskComplete(); |
360 } | 370 } |
361 return; | 371 return; |
362 } | 372 } |
363 | 373 |
364 var event = new cr.Event('copy-progress'); | 374 var event = new cr.Event('copy-progress'); |
365 event.reason = 'PROGRESS'; | 375 event.reason = 'PROGRESS'; |
366 self.dispatchEvent(event); | 376 self.dispatchEvent(event); |
367 | 377 |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
454 } | 464 } |
455 } | 465 } |
456 | 466 |
457 function onTargetNotResolved(err) { | 467 function onTargetNotResolved(err) { |
458 // We expect to be unable to resolve the target file, since we're going | 468 // We expect to be unable to resolve the target file, since we're going |
459 // to create it during the copy. However, if the resolve fails with | 469 // to create it during the copy. However, if the resolve fails with |
460 // anything other than NOT_FOUND, that's trouble. | 470 // anything other than NOT_FOUND, that's trouble. |
461 if (err.code != FileError.NOT_FOUND_ERR) | 471 if (err.code != FileError.NOT_FOUND_ERR) |
462 return onError('FILESYSTEM_ERROR', err); | 472 return onError('FILESYSTEM_ERROR', err); |
463 | 473 |
474 if (task.sourceAndTargetOnGData) { | |
475 if (task.deleteAfterCopy) { | |
476 sourceEntry.moveTo(targetDirEntry, targetRelativePath, | |
dgozman
2012/03/12 09:46:03
Can we have such copyTo/moveTo methods for all ent
Ben Chan
2012/03/12 14:58:47
It's possible to use copyTo/moveTo for native file
| |
477 onCopyComplete, onError); | |
478 return; | |
479 } else { | |
480 // TODO(benchan): GDataFileSystem has not implemented directory copy, | |
481 // and thus we only call FileEntry.copyTo() for files. Revisit this | |
482 // code when GDataFileSystem supports directory copy. | |
483 if (!sourceEntry.isDirectory) { | |
484 sourceEntry.copyTo(targetDirEntry, targetRelativePath, | |
485 onCopyComplete, onError); | |
486 return; | |
487 } | |
488 } | |
489 } | |
490 | |
464 if (sourceEntry.isDirectory) { | 491 if (sourceEntry.isDirectory) { |
465 targetDirEntry.getDirectory( | 492 targetDirEntry.getDirectory( |
466 targetRelativePath, | 493 targetRelativePath, |
467 {create: true, exclusive: true}, | 494 {create: true, exclusive: true}, |
468 function(targetEntry) { | 495 function(targetEntry) { |
469 if (targetRelativePath != originalPath) { | 496 if (targetRelativePath != originalPath) { |
470 task.registerRename(originalPath, targetRelativePath); | 497 task.registerRename(originalPath, targetRelativePath); |
471 } | 498 } |
472 onCopyComplete(targetEntry); | 499 onCopyComplete(targetEntry); |
473 }, | 500 }, |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
519 successCallback(targetEntry, file.size) | 546 successCallback(targetEntry, file.size) |
520 }; | 547 }; |
521 writer.write(file); | 548 writer.write(file); |
522 } | 549 } |
523 | 550 |
524 targetEntry.createWriter(onWriterCreated, errorCallback); | 551 targetEntry.createWriter(onWriterCreated, errorCallback); |
525 } | 552 } |
526 | 553 |
527 sourceEntry.file(onSourceFileFound, errorCallback); | 554 sourceEntry.file(onSourceFileFound, errorCallback); |
528 }; | 555 }; |
OLD | NEW |