Revision 139ac1e8 trunk/Pithos.Core/Agents/FileSystemWatcherAdapter.cs
b/trunk/Pithos.Core/Agents/FileSystemWatcherAdapter.cs | ||
---|---|---|
42 | 42 |
using System.Diagnostics.Contracts; |
43 | 43 |
using System.IO; |
44 | 44 |
using System.Threading.Tasks; |
45 |
using Pithos.Interfaces; |
|
45 | 46 |
|
46 | 47 |
namespace Pithos.Core.Agents |
47 | 48 |
{ |
... | ... | |
106 | 107 |
// as this is actually a MOVE operation |
107 | 108 |
//Deleting by Shift+Delete results in a delete event for each file followed by the delete of the folder itself |
108 | 109 |
_cachedDeletedFullPath = e.FullPath; |
109 |
|
|
110 |
|
|
110 | 111 |
//TODO: This requires synchronization of the _cachedDeletedFullPath field |
111 | 112 |
//TODO: This creates a new task for each file even though we can cancel any existing tasks if a new event arrives |
112 | 113 |
//Maybe, use a timer instead of a task |
... | ... | |
199 | 200 |
//If the actual action is a Move, raise a Move event instead of the actual event |
200 | 201 |
var newDirectory = Path.GetDirectoryName(e.FullPath); |
201 | 202 |
var oldDirectory = Path.GetDirectoryName(_cachedDeletedFullPath); |
203 |
|
|
202 | 204 |
if (Moved != null) |
205 |
{ |
|
203 | 206 |
Moved(sender, new MovedEventArgs(newDirectory, newName, oldDirectory, oldName)); |
207 |
//If the moved item is a dictionary, we need to raise a change event for each child item |
|
208 |
//When a directory is moved within the same volume, Windows raises events only for the directory object, |
|
209 |
//not its children. This happens because the move actually changes a single directory entry. It doesn't |
|
210 |
//affect the entries of the children. |
|
211 |
var directory = new DirectoryInfo(e.FullPath); |
|
212 |
if (directory.Exists) |
|
213 |
{ |
|
214 |
foreach (var child in directory.EnumerateFileSystemInfos("*", SearchOption.AllDirectories)) |
|
215 |
{ |
|
216 |
var newChildDirectory = Path.GetDirectoryName(child.FullName); |
|
217 |
|
|
218 |
var relativePath=child.AsRelativeTo(newDirectory); |
|
219 |
var relativeFolder = Path.GetDirectoryName(relativePath); |
|
220 |
var oldChildDirectory = Path.Combine(oldDirectory, relativeFolder); |
|
221 |
Moved(sender,new MovedEventArgs(newChildDirectory,child.Name,oldChildDirectory,child.Name)); |
|
222 |
} |
|
223 |
} |
|
224 |
|
|
225 |
} |
|
226 |
|
|
204 | 227 |
} |
205 | 228 |
finally |
206 | 229 |
{ |
... | ... | |
223 | 246 |
var deletedFileName = Path.GetFileName(_cachedDeletedFullPath); |
224 | 247 |
var deletedFileDirectory = Path.GetDirectoryName(_cachedDeletedFullPath); |
225 | 248 |
|
226 |
if (Deleted!=null) |
|
227 |
Deleted(sender, new FileSystemEventArgs(WatcherChangeTypes.Deleted, deletedFileDirectory, deletedFileName)); |
|
249 |
//Only a single file Delete event is raised when moving a file to the Recycle Bin, as this is actually a MOVE operation |
|
250 |
//In this case we need to raise the proper events for all child objects of the deleted directory. |
|
251 |
//UNFORTUNATELY, this can't be detected here, eg. by retrieving the child objects, because they are already deleted |
|
252 |
//This should be done at a higher level, eg by checking the stored state |
|
253 |
if (Deleted != null) |
|
254 |
Deleted(sender,new FileSystemEventArgs(WatcherChangeTypes.Deleted, deletedFileDirectory, deletedFileName)); |
|
228 | 255 |
|
229 | 256 |
_cachedDeletedFullPath = null; |
230 | 257 |
} |
Also available in: Unified diff