diff --git a/src/Files.Launcher/Files.Launcher.csproj b/src/Files.Launcher/Files.Launcher.csproj
index fbb6926ad298..c398e1c4538c 100644
--- a/src/Files.Launcher/Files.Launcher.csproj
+++ b/src/Files.Launcher/Files.Launcher.csproj
@@ -39,13 +39,13 @@
false
- Always
+ PreserveNewest
- Always
+ PreserveNewest
- Always
+ PreserveNewest
diff --git a/src/Files.Uwp/BaseLayout.cs b/src/Files.Uwp/BaseLayout.cs
index f75e9d56ddd0..254b9a637d32 100644
--- a/src/Files.Uwp/BaseLayout.cs
+++ b/src/Files.Uwp/BaseLayout.cs
@@ -39,6 +39,9 @@
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Navigation;
using static Files.Uwp.Helpers.PathNormalization;
+using System.Collections.Specialized;
+using System.Runtime.InteropServices;
+using Windows.Storage.FileProperties;
namespace Files.Uwp
{
@@ -376,7 +379,7 @@ public virtual void ResetItemOpacity()
}
}
- protected ListedItem GetItemFromElement(object element)
+ protected ListedItem GetItemFromElement(object element)
{
var item = element as ContentControl;
if (item == null || !CanGetItemFromElement(element))
@@ -858,95 +861,21 @@ protected virtual void Page_CharacterReceived(CoreWindow sender, CharacterReceiv
protected async void FileList_DragItemsStarting(object sender, DragItemsStartingEventArgs e)
{
- ConcurrentBag selectedStorageItems = new ConcurrentBag();
-
+ // Only support IStorageItem capable paths
e.Items.OfType().ForEach(item => SelectedItems.Add(item));
- var itemsCount = e.Items.Count;
- PostedStatusBanner banner = itemsCount > 50 ? App.OngoingTasksViewModel.PostOperationBanner(
- string.Empty,
- string.Format("StatusPreparingItemsDetails_Plural".GetLocalized(), itemsCount),
- 0,
- ReturnResult.InProgress,
- FileOperationType.Prepare, new CancellationTokenSource()) : null;
-
try
{
- await e.Items.OfType().ParallelForEachAsync(async item =>
- {
- if (banner != null)
- {
- ((IProgress)banner.Progress).Report(selectedStorageItems.Count / (float)itemsCount * 100);
- }
-
- if (item is FtpItem ftpItem)
- {
- if (item.PrimaryItemAttribute is StorageItemTypes.File or StorageItemTypes.Folder)
- {
- selectedStorageItems.Add(await ftpItem.ToStorageItem());
- }
- }
- else if (item.PrimaryItemAttribute == StorageItemTypes.File || item is ZipItem)
- {
- var result = await ParentShellPageInstance.FilesystemViewModel.GetFileFromPathAsync(item.ItemPath)
- .OnSuccess(t => selectedStorageItems.Add(t));
- if (!result)
- {
- throw new IOException($"Failed to process {item.ItemPath}.", (int)result.ErrorCode);
- }
- }
- else if (item.PrimaryItemAttribute == StorageItemTypes.Folder)
- {
- var result = await ParentShellPageInstance.FilesystemViewModel.GetFolderFromPathAsync(item.ItemPath)
- .OnSuccess(t => selectedStorageItems.Add(t));
- if (!result)
- {
- throw new IOException($"Failed to process {item.ItemPath}.", (int)result.ErrorCode);
- }
- }
- }, 10, banner?.CancellationToken ?? default);
- }
- catch (Exception ex)
- {
- if (ex.HResult == (int)FileSystemStatusCode.Unauthorized)
- {
- var itemList = e.Items.OfType().Select(x => StorageHelpers.FromPathAndType(
- x.ItemPath, x.PrimaryItemAttribute == StorageItemTypes.File ? FilesystemItemType.File : FilesystemItemType.Directory));
- e.Data.Properties["FileDrop"] = itemList.ToList();
- }
- else
- {
- e.Cancel = true;
- }
- banner?.Remove();
- return;
- }
-
- banner?.Remove();
-
- var onlyStandard = selectedStorageItems.All(x => x is StorageFile || x is StorageFolder || x is SystemStorageFile || x is SystemStorageFolder);
- if (onlyStandard)
- {
- selectedStorageItems = new ConcurrentBag(await selectedStorageItems.ToStandardStorageItemsAsync());
+ // Get the log file to use its properties. For some reason the drag and drop operation
+ // requires a BasicProperties object even though does not seem to be used.
+ // We supply it regardless for every VirtualStorageItem because it is checked for
+ var fakeFilePropsItem = await StorageFile.GetFileFromPathAsync(Path.Combine(ApplicationData.Current.LocalFolder.Path, "debug.log"));
+ var props = await fakeFilePropsItem.GetBasicPropertiesAsync();
+ var itemList = e.Items.OfType().Where(x => !(x.IsHiddenItem && x.IsLinkItem && x.IsRecycleBinItem && x.IsShortcutItem)).Select(x => new VirtualStorageItem(x, props));
+ e.Data.SetStorageItems(itemList, false);
+ //e.Data.RequestedOperation = DataPackageOperation.Move;
}
- if (selectedStorageItems.Count == 1)
- {
- if (selectedStorageItems.Single() is IStorageFile file)
- {
- var itemExtension = Path.GetExtension(file.Name);
- if (ImagePreviewViewModel.Extensions.Any((ext) => ext.Equals(itemExtension, StringComparison.OrdinalIgnoreCase)))
- {
- var streamRef = Windows.Storage.Streams.RandomAccessStreamReference.CreateFromFile(file);
- e.Data.SetBitmap(streamRef);
- }
- }
- e.Data.SetStorageItems(selectedStorageItems, false);
- }
- else if (selectedStorageItems.Count > 1)
- {
- e.Data.SetStorageItems(selectedStorageItems, false);
- }
- else
+ catch (Exception)
{
e.Cancel = true;
}
diff --git a/src/Files.Uwp/Files.Uwp.csproj b/src/Files.Uwp/Files.Uwp.csproj
index 3a201a8c643e..699fcd80f915 100644
--- a/src/Files.Uwp/Files.Uwp.csproj
+++ b/src/Files.Uwp/Files.Uwp.csproj
@@ -179,6 +179,7 @@
+
diff --git a/src/Files.Uwp/Filesystem/StorageItems/VirtualStorageItem.cs b/src/Files.Uwp/Filesystem/StorageItems/VirtualStorageItem.cs
new file mode 100644
index 000000000000..972017331270
--- /dev/null
+++ b/src/Files.Uwp/Filesystem/StorageItems/VirtualStorageItem.cs
@@ -0,0 +1,63 @@
+using System;
+using System.Threading.Tasks;
+using Windows.Foundation;
+using Windows.Storage;
+using Windows.Storage.FileProperties;
+
+namespace Files.Uwp.Filesystem.StorageItems
+{
+ ///
+ /// Implements IStorageItem, allowing us to get an instance of IStorageItem for a ListedItem
+ /// representing a standard filesystem item. As such, VirtualStorageItem does not support hidden,
+ /// shortcut, or link items.
+ ///
+ public class VirtualStorageItem : IStorageItem
+ {
+ private readonly ListedItem item;
+ private readonly BasicProperties props;
+
+ public VirtualStorageItem(ListedItem item, BasicProperties props)
+ {
+ this.item = item;
+ this.props = props;
+ }
+
+ public IAsyncAction RenameAsync(string desiredName)
+ {
+ throw new NotImplementedException();
+ }
+
+ public IAsyncAction RenameAsync(string desiredName, NameCollisionOption option)
+ {
+ throw new NotImplementedException();
+ }
+
+ public IAsyncAction DeleteAsync()
+ {
+ throw new NotImplementedException();
+ }
+
+ public IAsyncAction DeleteAsync(StorageDeleteOption option)
+ {
+ throw new NotImplementedException();
+ }
+
+ public IAsyncOperation GetBasicPropertiesAsync()
+ {
+ return Task.FromResult(props).AsAsyncOperation();
+ }
+
+ public bool IsOfType(StorageItemTypes type)
+ {
+ return item.PrimaryItemAttribute == type;
+ }
+
+ public FileAttributes Attributes => item.PrimaryItemAttribute == StorageItemTypes.File ? FileAttributes.Normal : FileAttributes.Directory;
+
+ public DateTimeOffset DateCreated => item.ItemDateCreatedReal;
+
+ public string Name => item.ItemName;
+
+ public string Path => item.ItemPath;
+ }
+}