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 items = new List<PlatformDataTransferItem>();
var nonFileFormats = new List<DataFormat>(); var nonFileFormats = new List<DataFormat>();
var nonFileFormatStrings = new List<string>(); var nonFileFormatStrings = new List<string>();
var hasFiles = false;
foreach (var formatString in DataObject.GetDataFormats()) foreach (var formatString in DataObject.GetDataFormats())
{ {
@ -35,18 +36,28 @@ internal sealed class DataObjectToDataTransferWrapper(IDataObject dataObject)
if (formatString == DataFormats.Files) 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. // 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. // We don't really care about that for this legacy wrapper.
if (DataObject.Get(formatString) is IEnumerable<IStorageItem> storageItems) if (DataObject.Get(formatString) is IEnumerable<IStorageItem> storageItems)
{ {
hasFiles = true;
foreach (var storageItem in storageItems) foreach (var storageItem in storageItems)
items.Add(PlatformDataTransferItem.Create(DataFormat.File, storageItem)); items.Add(PlatformDataTransferItem.Create(DataFormat.File, storageItem));
} }
} }
else if (formatString == DataFormats.FileNames) else if (formatString == DataFormats.FileNames)
{ {
if (hasFiles)
continue;
if (DataObject.Get(formatString) is IEnumerable<string> fileNames) if (DataObject.Get(formatString) is IEnumerable<string> fileNames)
{ {
hasFiles = true;
foreach (var fileName in fileNames) foreach (var fileName in fileNames)
{ {
if (StorageProviderHelpers.TryCreateBclStorageItem(fileName) is { } storageItem) 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; List<DataFormat>? nonFileFormats = null;
var items = new List<IAsyncDataTransferItem>(); var items = new List<IAsyncDataTransferItem>();
var hasFiles = false;
foreach (var format in formats) foreach (var format in formats)
{ {
if (DataFormat.File.Equals(format)) if (DataFormat.File.Equals(format))
{ {
if (hasFiles)
continue;
// We're reading the filenames ahead of time to generate the appropriate items. // We're reading the filenames ahead of time to generate the appropriate items.
// This is async, so it should be fine. // This is async, so it should be fine.
if (await reader.TryGetAsync(format) is IEnumerable<IStorageItem> storageItems) if (await reader.TryGetAsync(format) is IEnumerable<IStorageItem> storageItems)
{ {
hasFiles = true;
foreach (var storageItem in storageItems) foreach (var storageItem in storageItems)
items.Add(PlatformDataTransferItem.Create(DataFormat.File, storageItem)); 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 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(); var formatEtc = format.ToFormatEtc();
if (_oleDataObject.QueryGetData(&formatEtc) != (uint)HRESULT.S_OK) if (oleDataObject.QueryGetData(&formatEtc) != (uint)HRESULT.S_OK)
return null; return null;
var medium = new STGMEDIUM(); var medium = new STGMEDIUM();
if (_oleDataObject.GetData(&formatEtc, &medium) != (uint)HRESULT.S_OK) if (oleDataObject.GetData(&formatEtc, &medium) != (uint)HRESULT.S_OK)
return null; return null;
try try

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

@ -54,15 +54,21 @@ internal sealed class OleDataObjectToDataTransferWrapper(Win32Com.IDataObject ol
{ {
List<DataFormat>? nonFileFormats = null; List<DataFormat>? nonFileFormats = null;
var items = new List<PlatformDataTransferItem>(); var items = new List<PlatformDataTransferItem>();
var hasFiles = false;
foreach (var format in Formats) foreach (var format in Formats)
{ {
if (DataFormat.File.Equals(format)) 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. // 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. // However, it's unlikely to be a heavy operation.
if (_oleDataObject.TryGet(format) is IEnumerable<IStorageItem> storageItems) if (_oleDataObject.TryGet(format) is IEnumerable<IStorageItem> storageItems)
{ {
hasFiles = true;
foreach (var storageItem in storageItems) foreach (var storageItem in storageItems)
items.Add(PlatformDataTransferItem.Create(DataFormat.File, storageItem)); items.Add(PlatformDataTransferItem.Create(DataFormat.File, storageItem));
} }

Loading…
Cancel
Save