Browse Source

Fixed clipboard pasting

Krzysztof Krysiński 1 year ago
parent
commit
d3ea65dd61

+ 22 - 1
src/PixiEditor.AvaloniaUI/Helpers/Extensions/DataObjectExtensions.cs

@@ -1,5 +1,6 @@
 using System.Collections;
 using System.Collections;
 using System.Collections.Generic;
 using System.Collections.Generic;
+using System.IO;
 using System.Linq;
 using System.Linq;
 using Avalonia.Input;
 using Avalonia.Input;
 using Avalonia.Platform.Storage;
 using Avalonia.Platform.Storage;
@@ -22,11 +23,31 @@ public static class DataObjectExtensions
     public static IStorageItem[] GetFileDropList(this IDataObject data)
     public static IStorageItem[] GetFileDropList(this IDataObject data)
     {
     {
         if (!data.Contains(DataFormats.Files))
         if (!data.Contains(DataFormats.Files))
-            return Array.Empty<IStorageItem>();
+            return[];
 
 
         return ((IEnumerable<IStorageItem>)data.Get(DataFormats.Files)).ToArray();
         return ((IEnumerable<IStorageItem>)data.Get(DataFormats.Files)).ToArray();
     }
     }
 
 
+    public static bool TryGetRawTextPath(this IDataObject data, out string? path)
+    {
+        if (!data.Contains(DataFormats.Text))
+        {
+            path = null;
+            return false;
+        }
+
+        string text = data.GetText();
+
+        if (Directory.Exists(text) || File.Exists(text))
+        {
+            path = text;
+            return true;
+        }
+
+        path = null;
+        return false;
+    }
+
     public static VecI GetVecI(this IDataObject data, string format)
     public static VecI GetVecI(this IDataObject data, string format)
     {
     {
         if (!data.Contains(format))
         if (!data.Contains(format))

+ 7 - 0
src/PixiEditor.AvaloniaUI/Helpers/Extensions/PixelFormatHelper.cs

@@ -24,6 +24,13 @@ internal static class PixelFormatHelper
             return true;
             return true;
         }
         }
 
 
+        if (format == PixelFormats.Bgra8888)
+        {
+            alphaType = AlphaType.Unpremul;
+            colorType = ColorType.Bgra8888;
+            return true;
+        }
+
         /*if (format == PixelFormats.Bgra32)
         /*if (format == PixelFormats.Bgra32)
         {
         {
             alphaType = AlphaType.Unpremul;
             alphaType = AlphaType.Unpremul;

+ 6 - 1
src/PixiEditor.AvaloniaUI/Helpers/SupportedFilesHelper.cs

@@ -60,9 +60,14 @@ internal class SupportedFilesHelper
         return Path.Combine(Path.GetDirectoryName(path), filename);
         return Path.Combine(Path.GetDirectoryName(path), filename);
     }
     }
 
 
-    public static bool IsSupportedFile(string path)
+    public static bool IsSupported(string path)
     {
     {
         var ext = Path.GetExtension(path.ToLower());
         var ext = Path.GetExtension(path.ToLower());
+        if (string.IsNullOrEmpty(ext))
+        {
+            ext = $".{path.ToLower()}";
+        }
+
         return IsExtensionSupported(ext);
         return IsExtensionSupported(ext);
     }
     }
 
 

+ 47 - 9
src/PixiEditor.AvaloniaUI/Models/Controllers/ClipboardController.cs

@@ -184,12 +184,17 @@ internal static class ClipboardController
             return surfaces;
             return surfaces;
         }
         }
 
 
-        if (!data.Contains(DataFormats.Files))
+        var paths = data.GetFileDropList().Select(x => x.Path.AbsolutePath).ToList();
+        if(paths != null && data.TryGetRawTextPath(out string? textPath))
+        {
+            paths.Add(textPath);
+        }
+
+        if (paths == null || paths.Count == 0)
         {
         {
             return surfaces;
             return surfaces;
         }
         }
 
 
-        var paths = data.GetFileDropList().Select(x => x.Path.AbsolutePath).ToArray();
         foreach (string? path in paths)
         foreach (string? path in paths)
         {
         {
             if (path is null || !Importer.IsSupportedFile(path))
             if (path is null || !Importer.IsSupportedFile(path))
@@ -243,13 +248,36 @@ internal static class ClipboardController
     [Evaluator.CanExecute("PixiEditor.Clipboard.HasImageInClipboard")]
     [Evaluator.CanExecute("PixiEditor.Clipboard.HasImageInClipboard")]
     public static async Task<bool> IsImageInClipboard()
     public static async Task<bool> IsImageInClipboard()
     {
     {
-        var files = await Clipboard.GetDataAsync(DataFormats.Files);
-        if (files == null)
+        var formats = await Clipboard.GetFormatsAsync();
+        if (formats == null || formats.Length == 0)
             return false;
             return false;
 
 
-        string[] fileArray = ((IEnumerable<string>)files).ToArray();
+        bool isImage = IsImageFormat(formats);
+
+        if (!isImage)
+        {
+            string path = await TryFindImageInFiles(formats);
+            return path != string.Empty;
+        }
+
+        return isImage;
+    }
+
+    private static async Task<string> TryFindImageInFiles(string[] formats)
+    {
+        foreach (string format in formats)
+        {
+            if (format == DataFormats.Text)
+            {
+                string text = await Clipboard.GetTextAsync();
+                if (Importer.IsSupportedFile(text))
+                {
+                    return text;
+                }
+            }
+        }
 
 
-        return IsImageFormat(fileArray);
+        return string.Empty;
     }
     }
 
 
     public static bool IsImage(IDataObject? dataObject)
     public static bool IsImage(IDataObject? dataObject)
@@ -291,9 +319,19 @@ internal static class ClipboardController
 
 
     private static Bitmap FromPNG(IDataObject data)
     private static Bitmap FromPNG(IDataObject data)
     {
     {
-        MemoryStream pngStream = (MemoryStream)data.Get("PNG");
-        Bitmap bitmap = new Bitmap(pngStream);
-        return bitmap;
+        object obj = data.Get("PNG");
+        if(obj is byte[] bytes)
+        {
+            using MemoryStream stream = new MemoryStream(bytes);
+            return new Bitmap(stream);
+        }
+
+        if (obj is MemoryStream memoryStream)
+        {
+            return new Bitmap(memoryStream);
+        }
+
+        throw new InvalidDataException("PNG data is not in a supported format.");
     }
     }
 
 
     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);

+ 1 - 1
src/PixiEditor.AvaloniaUI/Models/IO/Importer.cs

@@ -147,7 +147,7 @@ internal class Importer : ObservableObject
 
 
     public static bool IsSupportedFile(string path)
     public static bool IsSupportedFile(string path)
     {
     {
-        return SupportedFilesHelper.IsSupportedFile(path);
+        return SupportedFilesHelper.IsSupported(path);
     }
     }
 
 
     public static Surface LoadFromGZippedBytes(string path)
     public static Surface LoadFromGZippedBytes(string path)