|
@@ -86,7 +86,8 @@ internal static class ClipboardController
|
|
}
|
|
}
|
|
else if (document.TransformViewModel.TransformActive || lastTransform != null)
|
|
else if (document.TransformViewModel.TransformActive || lastTransform != null)
|
|
{
|
|
{
|
|
- RectD transform = document.TransformViewModel.TransformActive ? document.TransformViewModel.Corners.AABBBounds
|
|
|
|
|
|
+ RectD transform = document.TransformViewModel.TransformActive
|
|
|
|
+ ? document.TransformViewModel.Corners.AABBBounds
|
|
: lastTransform.Value;
|
|
: lastTransform.Value;
|
|
var surface =
|
|
var surface =
|
|
document.TryExtractAreaFromSelected(
|
|
document.TryExtractAreaFromSelected(
|
|
@@ -149,7 +150,7 @@ internal static class ClipboardController
|
|
copyArea = document.TransformViewModel.Corners.AABBBounds;
|
|
copyArea = document.TransformViewModel.Corners.AABBBounds;
|
|
}
|
|
}
|
|
|
|
|
|
- if(copyArea.IsZeroOrNegativeArea || copyArea.HasNaNOrInfinity)
|
|
|
|
|
|
+ if (copyArea.IsZeroOrNegativeArea || copyArea.HasNaNOrInfinity)
|
|
{
|
|
{
|
|
NoticeDialog.Show("SELECTED_AREA_EMPTY", "NOTHING_TO_COPY");
|
|
NoticeDialog.Show("SELECTED_AREA_EMPTY", "NOTHING_TO_COPY");
|
|
return;
|
|
return;
|
|
@@ -185,8 +186,13 @@ internal static class ClipboardController
|
|
await pngData.AsStream().CopyToAsync(pngStream);
|
|
await pngData.AsStream().CopyToAsync(pngStream);
|
|
|
|
|
|
var pngArray = pngStream.ToArray();
|
|
var pngArray = pngStream.ToArray();
|
|
- data.Set(ClipboardDataFormats.Png, pngArray);
|
|
|
|
- data.Set(ClipboardDataFormats.ImageSlashPng, pngArray);
|
|
|
|
|
|
+ foreach (string format in ClipboardDataFormats.PngFormats)
|
|
|
|
+ {
|
|
|
|
+ if (!data.Contains(format))
|
|
|
|
+ {
|
|
|
|
+ data.Set(format, pngArray);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
|
|
pngStream.Position = 0;
|
|
pngStream.Position = 0;
|
|
try
|
|
try
|
|
@@ -221,17 +227,19 @@ internal static class ClipboardController
|
|
/// <summary>
|
|
/// <summary>
|
|
/// Pastes image from clipboard into new layer.
|
|
/// Pastes image from clipboard into new layer.
|
|
/// </summary>
|
|
/// </summary>
|
|
- public static bool TryPaste(DocumentViewModel document, DocumentManagerViewModel manager, IEnumerable<IDataObject>
|
|
|
|
- data, bool pasteAsNew = false)
|
|
|
|
|
|
+ public static async Task<bool> TryPaste(DocumentViewModel document, DocumentManagerViewModel manager,
|
|
|
|
+ IImportObject[]
|
|
|
|
+ data, bool pasteAsNew = false)
|
|
{
|
|
{
|
|
- Guid sourceDocument = GetSourceDocument(data, document.Id);
|
|
|
|
- Guid[] layerIds = GetLayerIds(data);
|
|
|
|
|
|
+ Guid sourceDocument = await GetSourceDocument(data, document.Id);
|
|
|
|
+ Guid[] layerIds = await GetLayerIds(data);
|
|
|
|
|
|
bool hasPos = data.Any(x => x.Contains(ClipboardDataFormats.PositionFormat));
|
|
bool hasPos = data.Any(x => x.Contains(ClipboardDataFormats.PositionFormat));
|
|
|
|
|
|
IDocument? targetDoc = manager.Documents.FirstOrDefault(x => x.Id == sourceDocument);
|
|
IDocument? targetDoc = manager.Documents.FirstOrDefault(x => x.Id == sourceDocument);
|
|
|
|
|
|
- if (targetDoc != null && pasteAsNew && layerIds is { Length: > 0 } && (!hasPos || AllMatchesPos(layerIds, data, targetDoc)))
|
|
|
|
|
|
+ if (targetDoc != null && pasteAsNew && layerIds is { Length: > 0 } &&
|
|
|
|
+ (!hasPos || await AllMatchesPos(layerIds, data, targetDoc)))
|
|
{
|
|
{
|
|
foreach (var layerId in layerIds)
|
|
foreach (var layerId in layerIds)
|
|
{
|
|
{
|
|
@@ -250,7 +258,7 @@ internal static class ClipboardController
|
|
return true;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
|
|
- List<DataImage> images = GetImage(data);
|
|
|
|
|
|
+ List<DataImage> images = await GetImage(data);
|
|
if (images.Count == 0)
|
|
if (images.Count == 0)
|
|
return false;
|
|
return false;
|
|
|
|
|
|
@@ -291,16 +299,14 @@ internal static class ClipboardController
|
|
return true;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
|
|
- private static bool AllMatchesPos(Guid[] layerIds, IEnumerable<IDataObject> data, IDocument doc)
|
|
|
|
|
|
+ private static async Task<bool> AllMatchesPos(Guid[] layerIds, IImportObject[] dataFormats, IDocument doc)
|
|
{
|
|
{
|
|
- var dataObjects = data as IDataObject[] ?? data.ToArray();
|
|
|
|
-
|
|
|
|
- var dataObjectWithPos = dataObjects.FirstOrDefault(x => x.Contains(ClipboardDataFormats.PositionFormat));
|
|
|
|
|
|
+ var dataObjectWithPos = dataFormats.FirstOrDefault(x => x.Contains(ClipboardDataFormats.PositionFormat));
|
|
VecD pos = VecD.Zero;
|
|
VecD pos = VecD.Zero;
|
|
|
|
|
|
if (dataObjectWithPos != null)
|
|
if (dataObjectWithPos != null)
|
|
{
|
|
{
|
|
- pos = dataObjectWithPos.GetVecD(ClipboardDataFormats.PositionFormat);
|
|
|
|
|
|
+ pos = await GetVecD(ClipboardDataFormats.PositionFormat, dataFormats);
|
|
}
|
|
}
|
|
|
|
|
|
RectD? tightBounds = null;
|
|
RectD? tightBounds = null;
|
|
@@ -325,13 +331,13 @@ internal static class ClipboardController
|
|
return tightBounds.HasValue && tightBounds.Value.Pos.AlmostEquals(pos);
|
|
return tightBounds.HasValue && tightBounds.Value.Pos.AlmostEquals(pos);
|
|
}
|
|
}
|
|
|
|
|
|
- private static Guid[] GetLayerIds(IEnumerable<IDataObject> data)
|
|
|
|
|
|
+ private static async Task<Guid[]> GetLayerIds(IImportObject[] formats)
|
|
{
|
|
{
|
|
- foreach (var dataObject in data)
|
|
|
|
|
|
+ foreach (var dataObject in formats)
|
|
{
|
|
{
|
|
if (dataObject.Contains(ClipboardDataFormats.LayerIdList))
|
|
if (dataObject.Contains(ClipboardDataFormats.LayerIdList))
|
|
{
|
|
{
|
|
- byte[] layerIds = (byte[])dataObject.Get(ClipboardDataFormats.LayerIdList);
|
|
|
|
|
|
+ byte[] layerIds = await Clipboard.GetDataAsync(ClipboardDataFormats.LayerIdList) as byte[];
|
|
string layerIdsString = System.Text.Encoding.UTF8.GetString(layerIds);
|
|
string layerIdsString = System.Text.Encoding.UTF8.GetString(layerIds);
|
|
return layerIdsString.Split(';').Select(Guid.Parse).ToArray();
|
|
return layerIdsString.Split(';').Select(Guid.Parse).ToArray();
|
|
}
|
|
}
|
|
@@ -340,13 +346,14 @@ internal static class ClipboardController
|
|
return [];
|
|
return [];
|
|
}
|
|
}
|
|
|
|
|
|
- private static Guid GetSourceDocument(IEnumerable<IDataObject> data, Guid fallback)
|
|
|
|
|
|
+ private static async Task<Guid> GetSourceDocument(IImportObject[] formats, Guid fallback)
|
|
{
|
|
{
|
|
- foreach (var dataObject in data)
|
|
|
|
|
|
+ foreach (var dataObject in formats)
|
|
{
|
|
{
|
|
if (dataObject.Contains(ClipboardDataFormats.DocumentFormat))
|
|
if (dataObject.Contains(ClipboardDataFormats.DocumentFormat))
|
|
{
|
|
{
|
|
- byte[] guidBytes = (byte[])dataObject.Get(ClipboardDataFormats.DocumentFormat);
|
|
|
|
|
|
+ var data = await Clipboard.GetDataAsync(ClipboardDataFormats.DocumentFormat);
|
|
|
|
+ byte[] guidBytes = (byte[])data;
|
|
string guidString = System.Text.Encoding.UTF8.GetString(guidBytes);
|
|
string guidString = System.Text.Encoding.UTF8.GetString(guidBytes);
|
|
return Guid.Parse(guidString);
|
|
return Guid.Parse(guidString);
|
|
}
|
|
}
|
|
@@ -361,73 +368,68 @@ internal static class ClipboardController
|
|
public static async Task<bool> TryPasteFromClipboard(DocumentViewModel document, DocumentManagerViewModel manager,
|
|
public static async Task<bool> TryPasteFromClipboard(DocumentViewModel document, DocumentManagerViewModel manager,
|
|
bool pasteAsNew = false)
|
|
bool pasteAsNew = false)
|
|
{
|
|
{
|
|
- var data = await TryGetDataObject();
|
|
|
|
|
|
+ var data = await TryGetImportObjects();
|
|
if (data == null)
|
|
if (data == null)
|
|
return false;
|
|
return false;
|
|
|
|
|
|
- return TryPaste(document, manager, data, pasteAsNew);
|
|
|
|
|
|
+ return await TryPaste(document, manager, data, pasteAsNew);
|
|
}
|
|
}
|
|
|
|
|
|
- private static async Task<List<DataObject?>> TryGetDataObject()
|
|
|
|
|
|
+ private static async Task<ClipboardPromiseObject[]> TryGetImportObjects()
|
|
{
|
|
{
|
|
string[] formats = await Clipboard.GetFormatsAsync();
|
|
string[] formats = await Clipboard.GetFormatsAsync();
|
|
if (formats.Length == 0)
|
|
if (formats.Length == 0)
|
|
return null;
|
|
return null;
|
|
|
|
|
|
- List<DataObject?> dataObjects = new();
|
|
|
|
|
|
+ List<ClipboardPromiseObject?> dataObjects = new();
|
|
|
|
|
|
for (int i = 0; i < formats.Length; i++)
|
|
for (int i = 0; i < formats.Length; i++)
|
|
{
|
|
{
|
|
string format = formats[i];
|
|
string format = formats[i];
|
|
- var obj = await Clipboard.GetDataAsync(format);
|
|
|
|
-
|
|
|
|
- if (obj == null)
|
|
|
|
- continue;
|
|
|
|
-
|
|
|
|
- DataObject data = new DataObject();
|
|
|
|
- data.Set(format, obj);
|
|
|
|
-
|
|
|
|
- dataObjects.Add(data);
|
|
|
|
|
|
+ dataObjects.Add(new ClipboardPromiseObject(format, Clipboard));
|
|
}
|
|
}
|
|
|
|
|
|
- return dataObjects;
|
|
|
|
|
|
+ return dataObjects.ToArray();
|
|
}
|
|
}
|
|
|
|
|
|
public static async Task<List<DataImage>> GetImagesFromClipboard()
|
|
public static async Task<List<DataImage>> GetImagesFromClipboard()
|
|
{
|
|
{
|
|
- var dataObj = await TryGetDataObject();
|
|
|
|
- return GetImage(dataObj);
|
|
|
|
|
|
+ var dataObj = await TryGetImportObjects();
|
|
|
|
+ return await GetImage(dataObj);
|
|
}
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// <summary>
|
|
/// Gets images from clipboard, supported PNG and Bitmap.
|
|
/// Gets images from clipboard, supported PNG and Bitmap.
|
|
/// </summary>
|
|
/// </summary>
|
|
- public static List<DataImage> GetImage(IEnumerable<IDataObject?> data)
|
|
|
|
|
|
+ public static async Task<List<DataImage>> GetImage(IImportObject[] importableObjects)
|
|
{
|
|
{
|
|
List<DataImage> surfaces = new();
|
|
List<DataImage> surfaces = new();
|
|
|
|
|
|
- if (data == null)
|
|
|
|
|
|
+ if (importableObjects == null)
|
|
return surfaces;
|
|
return surfaces;
|
|
|
|
|
|
VecD pos = VecD.Zero;
|
|
VecD pos = VecD.Zero;
|
|
|
|
|
|
string? importingType = null;
|
|
string? importingType = null;
|
|
|
|
+ bool pngImported = false;
|
|
|
|
|
|
- foreach (var dataObject in data)
|
|
|
|
|
|
+ foreach (var dataObject in importableObjects)
|
|
{
|
|
{
|
|
- if (importingType is null or "bytes" && TryExtractSingleImage(dataObject, out var singleImage))
|
|
|
|
|
|
+ var img = await TryExtractSingleImage(dataObject);
|
|
|
|
+ if (importingType is null or "bytes" && img != null && !pngImported)
|
|
{
|
|
{
|
|
- surfaces.Add(new DataImage(singleImage,
|
|
|
|
|
|
+ surfaces.Add(new DataImage(img,
|
|
dataObject.Contains(ClipboardDataFormats.PositionFormat)
|
|
dataObject.Contains(ClipboardDataFormats.PositionFormat)
|
|
- ? (VecI)dataObject.GetVecD(ClipboardDataFormats.PositionFormat)
|
|
|
|
|
|
+ ? (VecI)await GetVecD(ClipboardDataFormats.PositionFormat, importableObjects)
|
|
: (VecI)pos));
|
|
: (VecI)pos));
|
|
importingType = "bytes";
|
|
importingType = "bytes";
|
|
|
|
+ pngImported = true;
|
|
continue;
|
|
continue;
|
|
}
|
|
}
|
|
|
|
|
|
if (dataObject.Contains(ClipboardDataFormats.PositionFormat))
|
|
if (dataObject.Contains(ClipboardDataFormats.PositionFormat))
|
|
{
|
|
{
|
|
- pos = dataObject.GetVecD(ClipboardDataFormats.PositionFormat);
|
|
|
|
|
|
+ pos = await GetVecD(ClipboardDataFormats.PositionFormat, importableObjects);
|
|
for (var i = 0; i < surfaces.Count; i++)
|
|
for (var i = 0; i < surfaces.Count; i++)
|
|
{
|
|
{
|
|
var surface = surfaces[i];
|
|
var surface = surfaces[i];
|
|
@@ -435,10 +437,11 @@ internal static class ClipboardController
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- var paths = dataObject.GetFileDropList().Select(x => x.Path.LocalPath).ToList();
|
|
|
|
- if (paths != null && dataObject.TryGetRawTextPath(out string? textPath))
|
|
|
|
|
|
+ var paths = (await GetFileDropList(dataObject))?.Select(x => x.Path.LocalPath).ToList();
|
|
|
|
+ string[]? rawPaths = await TryGetRawTextPaths(dataObject);
|
|
|
|
+ if (paths != null && rawPaths != null)
|
|
{
|
|
{
|
|
- paths.Add(textPath);
|
|
|
|
|
|
+ paths.AddRange(rawPaths);
|
|
}
|
|
}
|
|
|
|
|
|
if (paths == null || paths.Count == 0 || (importingType != null && importingType != "files"))
|
|
if (paths == null || paths.Count == 0 || (importingType != null && importingType != "files"))
|
|
@@ -467,7 +470,7 @@ internal static class ClipboardController
|
|
|
|
|
|
string filename = Path.GetFullPath(path);
|
|
string filename = Path.GetFullPath(path);
|
|
surfaces.Add(new DataImage(filename, imported,
|
|
surfaces.Add(new DataImage(filename, imported,
|
|
- (VecI)dataObject.GetVecD(ClipboardDataFormats.PositionFormat)));
|
|
|
|
|
|
+ (VecI)await GetVecD(ClipboardDataFormats.PositionFormat, importableObjects)));
|
|
importingType = "files";
|
|
importingType = "files";
|
|
}
|
|
}
|
|
catch
|
|
catch
|
|
@@ -480,6 +483,104 @@ internal static class ClipboardController
|
|
return surfaces;
|
|
return surfaces;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ private static async Task<string[]?> TryGetRawTextPaths(IImportObject importObj)
|
|
|
|
+ {
|
|
|
|
+ if (!importObj.Contains(DataFormats.Text) && !importObj.Contains(ClipboardDataFormats.UriList))
|
|
|
|
+ {
|
|
|
|
+ return null;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ string text = null;
|
|
|
|
+ try
|
|
|
|
+ {
|
|
|
|
+ text = await importObj.GetDataAsync(DataFormats.Text) as string;
|
|
|
|
+ }
|
|
|
|
+ catch(InvalidCastException ex) // bug on x11
|
|
|
|
+ {
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ string[] paths = [text];
|
|
|
|
+ if (text == null)
|
|
|
|
+ {
|
|
|
|
+ if (await importObj.GetDataAsync(ClipboardDataFormats.UriList) is byte[] bytes)
|
|
|
|
+ {
|
|
|
|
+ paths = Encoding.UTF8.GetString(bytes).Split(['\n', '\r'], StringSplitOptions.RemoveEmptyEntries);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (paths.Length == 0)
|
|
|
|
+ {
|
|
|
|
+ return null;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ List<string> validPaths = new();
|
|
|
|
+
|
|
|
|
+ foreach (string path in paths)
|
|
|
|
+ {
|
|
|
|
+ if (string.IsNullOrWhiteSpace(path))
|
|
|
|
+ continue;
|
|
|
|
+
|
|
|
|
+ if (Directory.Exists(path) || File.Exists(path))
|
|
|
|
+ {
|
|
|
|
+ validPaths.Add(path);
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ try
|
|
|
|
+ {
|
|
|
|
+ Uri uri = new Uri(path);
|
|
|
|
+ if (uri.IsAbsoluteUri && (Directory.Exists(uri.LocalPath) || File.Exists(uri.LocalPath)))
|
|
|
|
+ {
|
|
|
|
+ validPaths.Add(uri.LocalPath);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ catch (UriFormatException)
|
|
|
|
+ {
|
|
|
|
+ // Ignore invalid URIs
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return validPaths.Count > 0 ? validPaths.ToArray() : null;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private static async Task<IEnumerable<IStorageItem>> GetFileDropList(IImportObject obj)
|
|
|
|
+ {
|
|
|
|
+ if (!obj.Contains(DataFormats.Files))
|
|
|
|
+ return [];
|
|
|
|
+
|
|
|
|
+ var data = await obj.GetDataAsync(DataFormats.Files);
|
|
|
|
+ if (data == null)
|
|
|
|
+ return [];
|
|
|
|
+
|
|
|
|
+ if (data is IEnumerable<IStorageItem> storageItems)
|
|
|
|
+ return storageItems;
|
|
|
|
+
|
|
|
|
+ if (data is Task<object> task)
|
|
|
|
+ {
|
|
|
|
+ data = await task;
|
|
|
|
+ if (data is IEnumerable<IStorageItem> storageItemsFromTask)
|
|
|
|
+ return storageItemsFromTask;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return [];
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ private static async Task<VecD> GetVecD(string format, IImportObject[] availableFormats)
|
|
|
|
+ {
|
|
|
|
+ var firstFormat = availableFormats.FirstOrDefault(x => x.Contains(format));
|
|
|
|
+ if (firstFormat == null)
|
|
|
|
+ return new VecD(-1, -1);
|
|
|
|
+
|
|
|
|
+ byte[] bytes = (byte[])await firstFormat.GetDataAsync(format);
|
|
|
|
+
|
|
|
|
+ if (bytes is { Length: < 16 })
|
|
|
|
+ return new VecD(-1, -1);
|
|
|
|
+
|
|
|
|
+ return VecD.FromBytes(bytes);
|
|
|
|
+ }
|
|
|
|
+
|
|
public static bool IsImage(IDataObject? dataObject)
|
|
public static bool IsImage(IDataObject? dataObject)
|
|
{
|
|
{
|
|
if (dataObject == null)
|
|
if (dataObject == null)
|
|
@@ -501,7 +602,7 @@ internal static class ClipboardController
|
|
return false;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
|
|
- return HasData(dataObject, ClipboardDataFormats.Png, ClipboardDataFormats.ImageSlashPng);
|
|
|
|
|
|
+ return HasData(dataObject, ClipboardDataFormats.PngFormats);
|
|
}
|
|
}
|
|
|
|
|
|
public static async Task<bool> IsImageInClipboard()
|
|
public static async Task<bool> IsImageInClipboard()
|
|
@@ -515,7 +616,20 @@ internal static class ClipboardController
|
|
if (!isImage)
|
|
if (!isImage)
|
|
{
|
|
{
|
|
string path = await TryFindImageInFiles(formats);
|
|
string path = await TryFindImageInFiles(formats);
|
|
- return Path.Exists(path);
|
|
|
|
|
|
+ try
|
|
|
|
+ {
|
|
|
|
+ Uri uri = new Uri(path);
|
|
|
|
+ return Path.Exists(uri.LocalPath);
|
|
|
|
+ }
|
|
|
|
+ catch (UriFormatException)
|
|
|
|
+ {
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+ catch (Exception ex)
|
|
|
|
+ {
|
|
|
|
+ CrashHelper.SendExceptionInfo(ex);
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
return isImage;
|
|
return isImage;
|
|
@@ -525,15 +639,7 @@ internal static class ClipboardController
|
|
{
|
|
{
|
|
foreach (string format in formats)
|
|
foreach (string format in formats)
|
|
{
|
|
{
|
|
- if (format == DataFormats.Text)
|
|
|
|
- {
|
|
|
|
- string text = await ClipboardController.GetTextFromClipboard();
|
|
|
|
- if (Importer.IsSupportedFile(text))
|
|
|
|
- {
|
|
|
|
- return text;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- else if (format == DataFormats.Files)
|
|
|
|
|
|
+ if (format == DataFormats.Files || format == ClipboardDataFormats.UriList)
|
|
{
|
|
{
|
|
var files = await ClipboardController.Clipboard.GetDataAsync(format);
|
|
var files = await ClipboardController.Clipboard.GetDataAsync(format);
|
|
if (files is IEnumerable<IStorageItem> storageFiles)
|
|
if (files is IEnumerable<IStorageItem> storageFiles)
|
|
@@ -553,6 +659,28 @@ internal static class ClipboardController
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ if (files is byte[] bytes)
|
|
|
|
+ {
|
|
|
|
+ string utf8String = Encoding.UTF8.GetString(bytes);
|
|
|
|
+ string[] paths = utf8String.Split(['\n', '\r'], StringSplitOptions.RemoveEmptyEntries);
|
|
|
|
+ foreach (string path in paths)
|
|
|
|
+ {
|
|
|
|
+ if (Importer.IsSupportedFile(path))
|
|
|
|
+ {
|
|
|
|
+ return path;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (format == DataFormats.Text)
|
|
|
|
+ {
|
|
|
|
+ string text = await ClipboardController.GetTextFromClipboard();
|
|
|
|
+ if (Importer.IsSupportedFile(text))
|
|
|
|
+ {
|
|
|
|
+ return text;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@@ -563,7 +691,7 @@ internal static class ClipboardController
|
|
{
|
|
{
|
|
foreach (var format in formats)
|
|
foreach (var format in formats)
|
|
{
|
|
{
|
|
- if (format == ClipboardDataFormats.Png)
|
|
|
|
|
|
+ if (ClipboardDataFormats.PngFormats.Contains(format, StringComparer.OrdinalIgnoreCase))
|
|
{
|
|
{
|
|
return true;
|
|
return true;
|
|
}
|
|
}
|
|
@@ -577,38 +705,55 @@ internal static class ClipboardController
|
|
return false;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
|
|
- private static Surface FromPNG(IDataObject data)
|
|
|
|
|
|
+ private static async Task<Surface?> FromPNG(IImportObject importObj)
|
|
{
|
|
{
|
|
- object obj = data.Get("PNG");
|
|
|
|
- if (obj is byte[] bytes)
|
|
|
|
|
|
+ object? pngData = null;
|
|
|
|
+ foreach (string format in ClipboardDataFormats.PngFormats)
|
|
|
|
+ {
|
|
|
|
+ if (importObj.Contains(format))
|
|
|
|
+ {
|
|
|
|
+ object? data = await importObj.GetDataAsync(format);
|
|
|
|
+ if (data == null)
|
|
|
|
+ continue;
|
|
|
|
+
|
|
|
|
+ pngData = data;
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (pngData is byte[] bytes)
|
|
{
|
|
{
|
|
return Surface.Load(bytes);
|
|
return Surface.Load(bytes);
|
|
}
|
|
}
|
|
|
|
|
|
- if (obj is MemoryStream memoryStream)
|
|
|
|
|
|
+ if (pngData is MemoryStream memoryStream)
|
|
{
|
|
{
|
|
bytes = memoryStream.ToArray();
|
|
bytes = memoryStream.ToArray();
|
|
return Surface.Load(bytes);
|
|
return Surface.Load(bytes);
|
|
}
|
|
}
|
|
|
|
|
|
- throw new InvalidDataException("PNG data is not in a supported format.");
|
|
|
|
|
|
+ return null;
|
|
}
|
|
}
|
|
|
|
|
|
private static bool HasData(IDataObject dataObject, params string[] formats) => formats.Any(dataObject.Contains);
|
|
private static bool HasData(IDataObject dataObject, params string[] formats) => formats.Any(dataObject.Contains);
|
|
|
|
|
|
- private static bool TryExtractSingleImage(IDataObject data, [NotNullWhen(true)] out Surface? result)
|
|
|
|
|
|
+ private static async Task<Surface?> TryExtractSingleImage(IImportObject importedObj)
|
|
{
|
|
{
|
|
try
|
|
try
|
|
{
|
|
{
|
|
Surface source;
|
|
Surface source;
|
|
- if (data.Contains(ClipboardDataFormats.Png) || data.Contains(ClipboardDataFormats.ImageSlashPng))
|
|
|
|
|
|
+ bool dataContainsPng = ClipboardDataFormats.PngFormats.Any(importedObj.Contains);
|
|
|
|
+ if (dataContainsPng)
|
|
{
|
|
{
|
|
- source = FromPNG(data);
|
|
|
|
|
|
+ source = await FromPNG(importedObj);
|
|
|
|
+ if (source == null)
|
|
|
|
+ {
|
|
|
|
+ return null;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
else
|
|
else
|
|
{
|
|
{
|
|
- result = null;
|
|
|
|
- return false;
|
|
|
|
|
|
+ return null;
|
|
}
|
|
}
|
|
|
|
|
|
/*if (source.Format.Value.IsSkiaSupported())
|
|
/*if (source.Format.Value.IsSkiaSupported())
|
|
@@ -624,13 +769,11 @@ internal static class ClipboardController
|
|
result = SurfaceHelpers.FromBitmap(newFormat);
|
|
result = SurfaceHelpers.FromBitmap(newFormat);
|
|
}*/
|
|
}*/
|
|
|
|
|
|
- result = source;
|
|
|
|
- return true;
|
|
|
|
|
|
+ return source;
|
|
}
|
|
}
|
|
catch { }
|
|
catch { }
|
|
|
|
|
|
- result = null;
|
|
|
|
- return false;
|
|
|
|
|
|
+ return null;
|
|
}
|
|
}
|
|
|
|
|
|
public static async Task CopyNodes(Guid[] nodeIds, Guid docId)
|
|
public static async Task CopyNodes(Guid[] nodeIds, Guid docId)
|
|
@@ -650,17 +793,20 @@ internal static class ClipboardController
|
|
|
|
|
|
public static async Task<Guid[]> GetIds(string format)
|
|
public static async Task<Guid[]> GetIds(string format)
|
|
{
|
|
{
|
|
- var data = await TryGetDataObject();
|
|
|
|
- return GetIds(data, format);
|
|
|
|
|
|
+ var data = await TryGetImportObjects();
|
|
|
|
+ return await GetIds(data, format);
|
|
}
|
|
}
|
|
|
|
|
|
- private static Guid[] GetIds(IEnumerable<IDataObject?> data, string format)
|
|
|
|
|
|
+
|
|
|
|
+ private static async Task<Guid[]> GetIds(IEnumerable<IImportObject?> data, string format)
|
|
{
|
|
{
|
|
foreach (var dataObject in data)
|
|
foreach (var dataObject in data)
|
|
{
|
|
{
|
|
if (dataObject.Contains(format))
|
|
if (dataObject.Contains(format))
|
|
{
|
|
{
|
|
- byte[] nodeIds = (byte[])dataObject.Get(format);
|
|
|
|
|
|
+ byte[] nodeIds = await dataObject.GetDataAsync(format) as byte[];
|
|
|
|
+ if (nodeIds == null || nodeIds.Length == 0)
|
|
|
|
+ return [];
|
|
string nodeIdsString = System.Text.Encoding.UTF8.GetString(nodeIds);
|
|
string nodeIdsString = System.Text.Encoding.UTF8.GetString(nodeIds);
|
|
return nodeIdsString.Split(';').Select(Guid.Parse).ToArray();
|
|
return nodeIdsString.Split(';').Select(Guid.Parse).ToArray();
|
|
}
|
|
}
|
|
@@ -702,7 +848,7 @@ internal static class ClipboardController
|
|
data.Set(ClipboardDataFormats.DocumentFormat, Encoding.UTF8.GetBytes(docId.ToString()));
|
|
data.Set(ClipboardDataFormats.DocumentFormat, Encoding.UTF8.GetBytes(docId.ToString()));
|
|
|
|
|
|
byte[] idsBytes = Encoding.UTF8.GetBytes(string.Join(";", ids.Select(x => x.ToString())));
|
|
byte[] idsBytes = Encoding.UTF8.GetBytes(string.Join(";", ids.Select(x => x.ToString())));
|
|
-
|
|
|
|
|
|
+
|
|
data.Set(format, idsBytes);
|
|
data.Set(format, idsBytes);
|
|
|
|
|
|
await Clipboard.SetDataObjectAsync(data);
|
|
await Clipboard.SetDataObjectAsync(data);
|
|
@@ -710,7 +856,7 @@ internal static class ClipboardController
|
|
|
|
|
|
public static async Task<Guid> GetDocumentId()
|
|
public static async Task<Guid> GetDocumentId()
|
|
{
|
|
{
|
|
- var data = await TryGetDataObject();
|
|
|
|
|
|
+ var data = await TryGetImportObjects();
|
|
if (data == null)
|
|
if (data == null)
|
|
return Guid.Empty;
|
|
return Guid.Empty;
|
|
|
|
|
|
@@ -718,7 +864,7 @@ internal static class ClipboardController
|
|
{
|
|
{
|
|
if (dataObject.Contains(ClipboardDataFormats.DocumentFormat))
|
|
if (dataObject.Contains(ClipboardDataFormats.DocumentFormat))
|
|
{
|
|
{
|
|
- byte[] guidBytes = (byte[])dataObject.Get(ClipboardDataFormats.DocumentFormat);
|
|
|
|
|
|
+ byte[] guidBytes = (byte[])await dataObject.GetDataAsync(ClipboardDataFormats.DocumentFormat);
|
|
string guidString = System.Text.Encoding.UTF8.GetString(guidBytes);
|
|
string guidString = System.Text.Encoding.UTF8.GetString(guidBytes);
|
|
return Guid.Parse(guidString);
|
|
return Guid.Parse(guidString);
|
|
}
|
|
}
|