in sources/Google.Solutions.Mvvm/Controls/FileBrowser.cs [674:785]
internal async Task PasteFilesAsync(IDataObject dataObject)
{
Precondition.ExpectNotNull(this.fileSystem, nameof(this.fileSystem));
Precondition.ExpectNotNull(this.navigationState, nameof(this.navigationState));
Debug.Assert(this.currentDirectoryContents != null);
Debug.Assert(this.currentDirectoryContents!.Count == this.fileList.Items.Count);
var filesToCopy = GetPastableFiles(dataObject, true);
if (!filesToCopy.Any())
{
return;
}
//
// Show a progress dialog to track overall progress.
//
using (var progressDialog = this.ProgressDialog.StartCopyOperation(
this,
(ulong)filesToCopy.Count(),
(ulong)filesToCopy.Sum(f => f.Length)))
{
var copyProgress = new Progress<int>(
delta => progressDialog.OnBytesCompleted((ulong)delta));
foreach (var file in filesToCopy)
{
if (progressDialog.CancellationToken.IsCancellationRequested)
{
break;
}
try
{
//
// Perform the file copy in the background.
//
// NB. If the underlying file system session is closed,
// we expect I/O operations to be cancelled.
//
await Task
.Run(async () =>
{
using (var sourceStream = file.OpenRead())
using (var targetStream = await this.fileSystem!
.OpenFileAsync(
this.navigationState!.Directory,
file.Name,
FileMode.Create,
FileAccess.Write)
.ConfigureAwait(false))
{
await sourceStream
.CopyToAsync(
targetStream,
copyProgress,
this.StreamCopyBufferSize,
progressDialog.CancellationToken)
.ConfigureAwait(false);
}
})
.ConfigureAwait(true);
}
catch (Exception e) when (e.IsCancellation())
{
//
// Ignore, and don't touch the UI because
// it might no longer be in a good state.
//
return;
}
catch (Exception e)
{
//
// Update dialog to avoid a situation where the
// dialog still indicates that the copy is progressing
// while we're showing an error dialog at the same time.
//
progressDialog.IsBlockedByError = true;
var parameters = new TaskDialogParameters(
"Copy files",
$"Unable to copy {file.Name}",
e.Unwrap().Message)
{
Icon = TaskDialogIcon.Error
};
parameters.Buttons.Add(new TaskDialogCommandLinkButton(
"Skip this file",
DialogResult.Ignore));
parameters.Buttons.Add(TaskDialogStandardButton.Cancel);
if (this.TaskDialog.ShowDialog(this, parameters)
== DialogResult.Cancel)
{
return;
}
}
finally
{
progressDialog.IsBlockedByError = false;
progressDialog.OnItemCompleted();
}
}
}
//
// Refresh as there might be some new files now.
//
await RefreshAsync().ConfigureAwait(true);
}