Skip to content

Fix issues with drag&drop from special locations #9435

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Jun 19, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/Files.FullTrust/Win32API.cs
Original file line number Diff line number Diff line change
Expand Up @@ -505,7 +505,7 @@ public static string GenerateUniquePath(string path)

for (ushort count = 1; File.Exists(uniquePath); count++)
{
if (countMatch != null)
if (countMatch.Success)
{
uniquePath = Path.Combine(directory, $"{nameWithoutExt[..countMatch.Index]}({count}){extension}");
}
Expand All @@ -523,7 +523,7 @@ public static string GenerateUniquePath(string path)

for (ushort Count = 1; Directory.Exists(uniquePath); Count++)
{
if (countMatch != null)
if (countMatch.Success)
{
uniquePath = Path.Combine(directory, $"{Name[..countMatch.Index]}({Count})");
}
Expand Down
12 changes: 11 additions & 1 deletion src/Files.Shared/ShellOperationResult.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Collections.Generic;
using System.Linq;

namespace Files.Shared
{
Expand All @@ -9,8 +10,17 @@ public ShellOperationResult()
Items = new List<ShellOperationItemResult>();
}

/// <summary>
/// File operation results: success and error code. Can contains multiple results for the same source file.
/// E.g. if the shell shows a "replace" confirmation dialog, results can be both COPYENGINE_S_PENDING and COPYENGINE_S_USER_IGNORED.
/// </summary>
public List<ShellOperationItemResult> Items { get; set; }
public bool Succeeded { get; set; }

/// <summary>
/// Final results of a file operation. Contains last status for each source file.
/// </summary>
public List<ShellOperationItemResult> Final =>
Items.GroupBy(x => new { Src = x.Source, Dst = x.Destination }).Select(x => x.Last()).ToList();
}

public class ShellOperationItemResult
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ await DialogDisplayHelper.ShowDialogAsync(
else
{
// CopyFileFromApp only works on file not directories
var fsSourceFolder = await source.ToStorageItemResult(associatedInstance);
var fsSourceFolder = await source.ToStorageItemResult();
var fsDestinationFolder = await associatedInstance.FilesystemViewModel.GetFolderFromPathAsync(PathNormalization.GetParentDir(destination));
var fsResult = (FilesystemResult)(fsSourceFolder.ErrorCode | fsDestinationFolder.ErrorCode);

Expand Down Expand Up @@ -241,7 +241,7 @@ await DialogDisplayHelper.ShowDialogAsync(
Debug.WriteLine(System.Runtime.InteropServices.Marshal.GetLastWin32Error());

FilesystemResult<BaseStorageFolder> destinationResult = await associatedInstance.FilesystemViewModel.GetFolderFromPathAsync(PathNormalization.GetParentDir(destination));
var sourceResult = await source.ToStorageItemResult(associatedInstance);
var sourceResult = await source.ToStorageItemResult();
fsResult = sourceResult.ErrorCode | destinationResult.ErrorCode;

if (fsResult)
Expand Down Expand Up @@ -386,7 +386,7 @@ await DialogDisplayHelper.ShowDialogAsync(
{
Debug.WriteLine(System.Runtime.InteropServices.Marshal.GetLastWin32Error());

var fsSourceFolder = await source.ToStorageItemResult(associatedInstance);
var fsSourceFolder = await source.ToStorageItemResult();
var fsDestinationFolder = await associatedInstance.FilesystemViewModel.GetFolderFromPathAsync(PathNormalization.GetParentDir(destination));
fsResult = fsSourceFolder.ErrorCode | fsDestinationFolder.ErrorCode;

Expand Down Expand Up @@ -435,7 +435,7 @@ await DialogDisplayHelper.ShowDialogAsync(
Debug.WriteLine(System.Runtime.InteropServices.Marshal.GetLastWin32Error());

FilesystemResult<BaseStorageFolder> destinationResult = await associatedInstance.FilesystemViewModel.GetFolderFromPathAsync(PathNormalization.GetParentDir(destination));
var sourceResult = await source.ToStorageItemResult(associatedInstance);
var sourceResult = await source.ToStorageItemResult();
fsResult = sourceResult.ErrorCode | destinationResult.ErrorCode;

if (fsResult)
Expand Down Expand Up @@ -601,7 +601,7 @@ public async Task<IStorageHistory> RenameAsync(IStorageItemWithPath source,
&& !FilesystemHelpers.ContainsRestrictedCharacters(newName)
&& !FilesystemHelpers.ContainsRestrictedFileName(newName))
{
var renamed = await source.ToStorageItemResult(associatedInstance)
var renamed = await source.ToStorageItemResult()
.OnSuccess(async (t) =>
{
if (t.Name.Equals(newName, StringComparison.CurrentCultureIgnoreCase))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ public async Task<IStorageHistory> CopyItemsAsync(IList<IStorageItemWithPath> so
result &= (FilesystemResult)(status == AppServiceResponseStatus.Success
&& response.Get("Success", false));
var shellOpResult = JsonConvert.DeserializeObject<ShellOperationResult>(response.Get("Result", ""));
copyResult.Items.AddRange(shellOpResult?.Items ?? Enumerable.Empty<ShellOperationItemResult>());
copyResult.Items.AddRange(shellOpResult?.Final ?? Enumerable.Empty<ShellOperationItemResult>());
}
if (sourceReplace.Any())
{
Expand All @@ -126,7 +126,7 @@ public async Task<IStorageHistory> CopyItemsAsync(IList<IStorageItemWithPath> so
result &= (FilesystemResult)(status == AppServiceResponseStatus.Success
&& response.Get("Success", false));
var shellOpResult = JsonConvert.DeserializeObject<ShellOperationResult>(response.Get("Result", ""));
copyResult.Items.AddRange(shellOpResult?.Items ?? Enumerable.Empty<ShellOperationItemResult>());
copyResult.Items.AddRange(shellOpResult?.Final ?? Enumerable.Empty<ShellOperationItemResult>());
}

if (connection != null)
Expand Down Expand Up @@ -260,7 +260,7 @@ await sourceMatch.Select(x => x.dest).ToListAsync(),
var result = (FilesystemResult)(status == AppServiceResponseStatus.Success
&& response.Get("Success", false));
var shellOpResult = JsonConvert.DeserializeObject<ShellOperationResult>(response.Get("Result", ""));
createResult.Items.AddRange(shellOpResult?.Items ?? Enumerable.Empty<ShellOperationItemResult>());
createResult.Items.AddRange(shellOpResult?.Final ?? Enumerable.Empty<ShellOperationItemResult>());

result &= (FilesystemResult)createResult.Items.All(x => x.Succeeded);

Expand All @@ -271,7 +271,7 @@ await sourceMatch.Select(x => x.dest).ToListAsync(),
if (createdSources.Any())
{
var item = StorageHelpers.FromPathAndType(createdSources.Single().Destination, source.ItemType);
var storageItem = await item.ToStorageItem(associatedInstance);
var storageItem = await item.ToStorageItem();
return (new StorageHistory(FileOperationType.CreateNew, item.CreateList(), null), storageItem);
}
return (null, null);
Expand Down Expand Up @@ -396,7 +396,7 @@ public async Task<IStorageHistory> DeleteItemsAsync(IList<IStorageItemWithPath>
var result = (FilesystemResult)(status == AppServiceResponseStatus.Success
&& response.Get("Success", false));
var shellOpResult = JsonConvert.DeserializeObject<ShellOperationResult>(response.Get("Result", ""));
deleteResult.Items.AddRange(shellOpResult?.Items ?? Enumerable.Empty<ShellOperationItemResult>());
deleteResult.Items.AddRange(shellOpResult?.Final ?? Enumerable.Empty<ShellOperationItemResult>());

if (connection != null)
{
Expand Down Expand Up @@ -522,7 +522,7 @@ public async Task<IStorageHistory> MoveItemsAsync(IList<IStorageItemWithPath> so
result &= (FilesystemResult)(status == AppServiceResponseStatus.Success
&& response.Get("Success", false));
var shellOpResult = JsonConvert.DeserializeObject<ShellOperationResult>(response.Get("Result", ""));
moveResult.Items.AddRange(shellOpResult?.Items ?? Enumerable.Empty<ShellOperationItemResult>());
moveResult.Items.AddRange(shellOpResult?.Final ?? Enumerable.Empty<ShellOperationItemResult>());
}
if (sourceReplace.Any())
{
Expand All @@ -539,7 +539,7 @@ public async Task<IStorageHistory> MoveItemsAsync(IList<IStorageItemWithPath> so
result &= (FilesystemResult)(status == AppServiceResponseStatus.Success
&& response.Get("Success", false));
var shellOpResult = JsonConvert.DeserializeObject<ShellOperationResult>(response.Get("Result", ""));
moveResult.Items.AddRange(shellOpResult?.Items ?? Enumerable.Empty<ShellOperationItemResult>());
moveResult.Items.AddRange(shellOpResult?.Final ?? Enumerable.Empty<ShellOperationItemResult>());
}

if (connection != null)
Expand Down Expand Up @@ -647,7 +647,7 @@ public async Task<IStorageHistory> RenameAsync(IStorageItemWithPath source, stri
var result = (FilesystemResult)(status == AppServiceResponseStatus.Success
&& response.Get("Success", false));
var shellOpResult = JsonConvert.DeserializeObject<ShellOperationResult>(response.Get("Result", ""));
renameResult.Items.AddRange(shellOpResult?.Items ?? Enumerable.Empty<ShellOperationItemResult>());
renameResult.Items.AddRange(shellOpResult?.Final ?? Enumerable.Empty<ShellOperationItemResult>());

result &= (FilesystemResult)renameResult.Items.All(x => x.Succeeded);

Expand Down Expand Up @@ -745,7 +745,7 @@ public async Task<IStorageHistory> RestoreItemsFromTrashAsync(IList<IStorageItem
var result = (FilesystemResult)(status == AppServiceResponseStatus.Success
&& response.Get("Success", false));
var shellOpResult = JsonConvert.DeserializeObject<ShellOperationResult>(response.Get("Result", ""));
moveResult.Items.AddRange(shellOpResult?.Items ?? Enumerable.Empty<ShellOperationItemResult>());
moveResult.Items.AddRange(shellOpResult?.Final ?? Enumerable.Empty<ShellOperationItemResult>());

if (connection != null)
{
Expand Down
42 changes: 13 additions & 29 deletions src/Files.Uwp/Helpers/StorageHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@ namespace Files.Uwp.Helpers
/// </summary>
public static class StorageHelpers
{
public static async Task<IStorageItem> ToStorageItem(this IStorageItemWithPath item, IShellPage associatedInstance = null)
public static async Task<IStorageItem> ToStorageItem(this IStorageItemWithPath item)
{
return (await item.ToStorageItemResult(associatedInstance)).Result;
return (await item.ToStorageItemResult()).Result;
}

public static async Task<TRequested> ToStorageItem<TRequested>(string path, IShellPage associatedInstance = null) where TRequested : IStorageItem
public static async Task<TRequested> ToStorageItem<TRequested>(string path) where TRequested : IStorageItem
{
FilesystemResult<BaseStorageFile> file = null;
FilesystemResult<BaseStorageFolder> folder = null;
Expand Down Expand Up @@ -110,28 +110,14 @@ public static async Task<TRequested> ToStorageItem<TRequested>(string path, IShe

async Task GetFile()
{
if (associatedInstance == null || associatedInstance.FilesystemViewModel == null)
{
var rootItem = await FilesystemTasks.Wrap(() => DrivesManager.GetRootFromPathAsync(path));
file = await FilesystemTasks.Wrap(() => StorageFileExtensions.DangerousGetFileFromPathAsync(path, rootItem));
}
else
{
file = await associatedInstance.FilesystemViewModel.GetFileFromPathAsync(path);
}
var rootItem = await FilesystemTasks.Wrap(() => DrivesManager.GetRootFromPathAsync(path));
file = await FilesystemTasks.Wrap(() => StorageFileExtensions.DangerousGetFileFromPathAsync(path, rootItem));
}

async Task GetFolder()
{
if (associatedInstance == null)
{
var rootItem = await FilesystemTasks.Wrap(() => DrivesManager.GetRootFromPathAsync(path));
folder = await FilesystemTasks.Wrap(() => StorageFileExtensions.DangerousGetFolderFromPathAsync(path, rootItem));
}
else
{
folder = await associatedInstance?.FilesystemViewModel?.GetFolderFromPathAsync(path);
}
var rootItem = await FilesystemTasks.Wrap(() => DrivesManager.GetRootFromPathAsync(path));
folder = await FilesystemTasks.Wrap(() => StorageFileExtensions.DangerousGetFolderFromPathAsync(path, rootItem));
}
}

Expand All @@ -141,18 +127,16 @@ public static async Task<long> GetFileSize(this IStorageFile file)
return (long)properties.Size;
}

public static async Task<FilesystemResult<IStorageItem>> ToStorageItemResult(this IStorageItemWithPath item, IShellPage associatedInstance = null)
public static async Task<FilesystemResult<IStorageItem>> ToStorageItemResult(this IStorageItemWithPath item)
{
var returnedItem = new FilesystemResult<IStorageItem>(null, FileSystemStatusCode.Generic);
var rootItem = associatedInstance == null ? await FilesystemTasks.Wrap(() => DrivesManager.GetRootFromPathAsync(item.Path)) : null;
var rootItem = await FilesystemTasks.Wrap(() => DrivesManager.GetRootFromPathAsync(item.Path));
if (!string.IsNullOrEmpty(item.Path))
{
returnedItem = (item.ItemType == FilesystemItemType.File) ?
ToType<IStorageItem, BaseStorageFile>(associatedInstance != null ?
await associatedInstance.FilesystemViewModel.GetFileFromPathAsync(item.Path) :
ToType<IStorageItem, BaseStorageFile>(
await FilesystemTasks.Wrap(() => StorageFileExtensions.DangerousGetFileFromPathAsync(item.Path, rootItem))) :
ToType<IStorageItem, BaseStorageFolder>(associatedInstance != null ?
await associatedInstance.FilesystemViewModel.GetFolderFromPathAsync(item.Path) :
ToType<IStorageItem, BaseStorageFolder>(
await FilesystemTasks.Wrap(() => StorageFileExtensions.DangerousGetFolderFromPathAsync(item.Path, rootItem)));
}
if (returnedItem.Result == null && item.Item != null)
Expand All @@ -169,9 +153,9 @@ public static IStorageItemWithPath FromPathAndType(string customPath, Filesystem
(IStorageItemWithPath)new StorageFolderWithPath(null, customPath);
}

public static async Task<FilesystemItemType> GetTypeFromPath(string path, IShellPage associatedInstance = null)
public static async Task<FilesystemItemType> GetTypeFromPath(string path)
{
IStorageItem item = await ToStorageItem<IStorageItem>(path, associatedInstance);
IStorageItem item = await ToStorageItem<IStorageItem>(path);

return item == null ? FilesystemItemType.File : (item.IsOfType(StorageItemTypes.Folder) ? FilesystemItemType.Directory : FilesystemItemType.File);
}
Expand Down
4 changes: 2 additions & 2 deletions src/Files.Uwp/Helpers/WallpaperHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@ namespace Files.Uwp.Helpers
{
public static class WallpaperHelpers
{
public static async void SetAsBackground(WallpaperType type, string filePath, IShellPage associatedInstance)
public static async void SetAsBackground(WallpaperType type, string filePath)
{
if (UserProfilePersonalizationSettings.IsSupported())
{
// Get the path of the selected file
BaseStorageFile sourceFile = await StorageHelpers.ToStorageItem<BaseStorageFile>(filePath, associatedInstance);
BaseStorageFile sourceFile = await StorageHelpers.ToStorageItem<BaseStorageFile>(filePath);
if (sourceFile == null)
{
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ public virtual async void CreateShortcut(RoutedEventArgs e)

public virtual void SetAsLockscreenBackgroundItem(RoutedEventArgs e)
{
WallpaperHelpers.SetAsBackground(WallpaperType.LockScreen, SlimContentPage.SelectedItem.ItemPath, associatedInstance);
WallpaperHelpers.SetAsBackground(WallpaperType.LockScreen, SlimContentPage.SelectedItem.ItemPath);
}

public virtual async void SetAsDesktopBackgroundItem(RoutedEventArgs e)
Expand All @@ -130,7 +130,7 @@ public virtual async void SetAsDesktopBackgroundItem(RoutedEventArgs e)
}
else
{
WallpaperHelpers.SetAsBackground(WallpaperType.Desktop, SlimContentPage.SelectedItem.ItemPath, associatedInstance);
WallpaperHelpers.SetAsBackground(WallpaperType.Desktop, SlimContentPage.SelectedItem.ItemPath);
}
}

Expand Down Expand Up @@ -396,14 +396,14 @@ async void Manager_DataRequested(DataTransferManager sender, DataRequestedEventA
}
else if (item.PrimaryItemAttribute == StorageItemTypes.Folder && !item.IsZipItem)
{
if (await StorageHelpers.ToStorageItem<BaseStorageFolder>(item.ItemPath, associatedInstance) is BaseStorageFolder folder)
if (await StorageHelpers.ToStorageItem<BaseStorageFolder>(item.ItemPath) is BaseStorageFolder folder)
{
items.Add(folder);
}
}
else
{
if (await StorageHelpers.ToStorageItem<BaseStorageFile>(item.ItemPath, associatedInstance) is BaseStorageFile file)
if (await StorageHelpers.ToStorageItem<BaseStorageFile>(item.ItemPath) is BaseStorageFile file)
{
items.Add(file);
}
Expand Down
2 changes: 1 addition & 1 deletion src/Files.Uwp/ViewModels/Properties/FileProperties.cs
Original file line number Diff line number Diff line change
Expand Up @@ -356,7 +356,7 @@ private async void ViewModel_PropertyChanged(object sender, System.ComponentMode
private async Task<string> GetHashForFileAsync(ListedItem fileItem, string nameOfAlg, CancellationToken token, IProgress<float> progress, IShellPage associatedInstance)
{
HashAlgorithmProvider algorithmProvider = HashAlgorithmProvider.OpenAlgorithm(nameOfAlg);
BaseStorageFile file = await StorageHelpers.ToStorageItem<BaseStorageFile>((fileItem as ShortcutItem)?.TargetPath ?? fileItem.ItemPath, associatedInstance);
BaseStorageFile file = await StorageHelpers.ToStorageItem<BaseStorageFile>((fileItem as ShortcutItem)?.TargetPath ?? fileItem.ItemPath);
if (file == null)
{
return "";
Expand Down