Browse Source

Prevent duplicated files during drag-and-drop (#19864)

release/11.3.8
Julien Lebosquain 4 months ago
parent
commit
a969551cf4
  1. 11
      src/Avalonia.Base/Input/Platform/DataObjectToDataTransferWrapper.cs
  2. 6
      src/Avalonia.X11/Clipboard/X11Clipboard.cs
  3. 6
      src/Windows/Avalonia.Win32/OleDataObjectHelper.cs
  4. 6
      src/Windows/Avalonia.Win32/OleDataObjectToDataTransferWrapper.cs

11
src/Avalonia.Base/Input/Platform/DataObjectToDataTransferWrapper.cs

@ -28,6 +28,7 @@ internal sealed class DataObjectToDataTransferWrapper(IDataObject dataObject)
var items = new List<PlatformDataTransferItem>();
var nonFileFormats = new List<DataFormat>();
var nonFileFormatStrings = new List<string>();
var hasFiles = false;
foreach (var formatString in DataObject.GetDataFormats())
{
@ -35,18 +36,28 @@ internal sealed class DataObjectToDataTransferWrapper(IDataObject dataObject)
if (formatString == DataFormats.Files)
{
if (hasFiles)
continue;
// This is not ideal as we're reading the filenames ahead of time to generate the appropriate items.
// We don't really care about that for this legacy wrapper.
if (DataObject.Get(formatString) is IEnumerable<IStorageItem> storageItems)
{
hasFiles = true;
foreach (var storageItem in storageItems)
items.Add(PlatformDataTransferItem.Create(DataFormat.File, storageItem));
}
}
else if (formatString == DataFormats.FileNames)
{
if (hasFiles)
continue;
if (DataObject.Get(formatString) is IEnumerable<string> fileNames)
{
hasFiles = true;
foreach (var fileName in fileNames)
{
if (StorageProviderHelpers.TryCreateBclStorageItem(fileName) is { } storageItem)

6
src/Avalonia.X11/Clipboard/X11Clipboard.cs

@ -327,15 +327,21 @@ namespace Avalonia.X11.Clipboard
{
List<DataFormat>? nonFileFormats = null;
var items = new List<IAsyncDataTransferItem>();
var hasFiles = false;
foreach (var format in formats)
{
if (DataFormat.File.Equals(format))
{
if (hasFiles)
continue;
// We're reading the filenames ahead of time to generate the appropriate items.
// This is async, so it should be fine.
if (await reader.TryGetAsync(format) is IEnumerable<IStorageItem> storageItems)
{
hasFiles = true;
foreach (var storageItem in storageItems)
items.Add(PlatformDataTransferItem.Create(DataFormat.File, storageItem));
}

6
src/Windows/Avalonia.Win32/OleDataObjectHelper.cs

@ -29,15 +29,15 @@ internal static class OleDataObjectHelper
tymed = TYMED.TYMED_HGLOBAL
};
public static unsafe object? TryGet(this Win32Com.IDataObject _oleDataObject, DataFormat format)
public static unsafe object? TryGet(this Win32Com.IDataObject oleDataObject, DataFormat format)
{
var formatEtc = format.ToFormatEtc();
if (_oleDataObject.QueryGetData(&formatEtc) != (uint)HRESULT.S_OK)
if (oleDataObject.QueryGetData(&formatEtc) != (uint)HRESULT.S_OK)
return null;
var medium = new STGMEDIUM();
if (_oleDataObject.GetData(&formatEtc, &medium) != (uint)HRESULT.S_OK)
if (oleDataObject.GetData(&formatEtc, &medium) != (uint)HRESULT.S_OK)
return null;
try

6
src/Windows/Avalonia.Win32/OleDataObjectToDataTransferWrapper.cs

@ -54,15 +54,21 @@ internal sealed class OleDataObjectToDataTransferWrapper(Win32Com.IDataObject ol
{
List<DataFormat>? nonFileFormats = null;
var items = new List<PlatformDataTransferItem>();
var hasFiles = false;
foreach (var format in Formats)
{
if (DataFormat.File.Equals(format))
{
if (hasFiles)
continue;
// This is not ideal as we're reading the filenames ahead of time to generate the appropriate items.
// However, it's unlikely to be a heavy operation.
if (_oleDataObject.TryGet(format) is IEnumerable<IStorageItem> storageItems)
{
hasFiles = true;
foreach (var storageItem in storageItems)
items.Add(PlatformDataTransferItem.Create(DataFormat.File, storageItem));
}

Loading…
Cancel
Save