diff --git a/src/Greenshot.Base/Core/ClipboardHelper.cs b/src/Greenshot.Base/Core/ClipboardHelper.cs index 02a7f03f1..fd8610857 100644 --- a/src/Greenshot.Base/Core/ClipboardHelper.cs +++ b/src/Greenshot.Base/Core/ClipboardHelper.cs @@ -31,6 +31,7 @@ using System.Text; using System.Threading; using System.Windows.Forms; using Greenshot.Base.Core.Enums; +using Greenshot.Base.Core.FileFormatHandlers; using Greenshot.Base.IniFile; using Greenshot.Base.Interfaces; using Greenshot.Base.Interfaces.Plugin; @@ -1135,10 +1136,11 @@ EndSelection:<<<<<<<4 string[] dropFileNames = (string[]) dataObject.GetData(DataFormats.FileDrop); if (dropFileNames != null && dropFileNames.Length > 0) { + var supportedExtensions = FileFormatHandlerRegistry.ExtensionsFor(FileFormatHandlerActions.LoadFromStream).ToList(); return dropFileNames .Where(filename => !string.IsNullOrEmpty(filename)) .Where(Path.HasExtension) - .Where(filename => ImageHelper.StreamConverters.Keys.Contains(Path.GetExtension(filename).ToLowerInvariant().Substring(1))); + .Where(filename => supportedExtensions.Contains(Path.GetExtension(filename).ToLowerInvariant().Substring(1))); } return Enumerable.Empty(); diff --git a/src/Greenshot.Base/Core/FileFormatHandlers/FileFormatHandlerRegistry.cs b/src/Greenshot.Base/Core/FileFormatHandlers/FileFormatHandlerRegistry.cs new file mode 100644 index 000000000..9d41f25e6 --- /dev/null +++ b/src/Greenshot.Base/Core/FileFormatHandlers/FileFormatHandlerRegistry.cs @@ -0,0 +1,44 @@ +/* + * Greenshot - a free and open source screenshot tool + * Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom + * + * For more information see: https://getgreenshot.org/ + * The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 1 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +using System.Collections.Generic; +using System.Linq; +using Greenshot.Base.Interfaces; + +namespace Greenshot.Base.Core.FileFormatHandlers +{ + public static class FileFormatHandlerRegistry + { + public static readonly IList FileFormatHandlers = new List(); + + static FileFormatHandlerRegistry() + { + FileFormatHandlers.Add(new IconFileFormatHandler()); + FileFormatHandlers.Add(new GreenshotFileFormatHandler()); + FileFormatHandlers.Add(new DefaultFileFormatHandler()); + } + + public static IEnumerable ExtensionsFor(FileFormatHandlerActions fileFormatHandlerAction) + { + return FileFormatHandlers.SelectMany(ffh => ffh.SupportedExtensions(fileFormatHandlerAction)).Distinct(); + } + } +} diff --git a/src/Greenshot.Base/Core/FileFormatHandlers/GreenshotFileFormatHandler.cs b/src/Greenshot.Base/Core/FileFormatHandlers/GreenshotFileFormatHandler.cs index f43d8ff54..93885cde0 100644 --- a/src/Greenshot.Base/Core/FileFormatHandlers/GreenshotFileFormatHandler.cs +++ b/src/Greenshot.Base/Core/FileFormatHandlers/GreenshotFileFormatHandler.cs @@ -20,6 +20,7 @@ */ using System; +using System.Collections.Generic; using System.Drawing; using System.IO; using System.Linq; @@ -30,29 +31,51 @@ namespace Greenshot.Base.Core.FileFormatHandlers { public class GreenshotFileFormatHandler : IFileFormatHandler { - private static readonly string[] SupportedExtensions = { "greenshot" }; + private static readonly string[] OurExtensions = { "greenshot" }; - public bool CanDoActionForExtension(FileFormatHandlerActions fileFormatHandlerAction, string extension) + /// + public IEnumerable SupportedExtensions(FileFormatHandlerActions fileFormatHandlerAction) + { + if (fileFormatHandlerAction == FileFormatHandlerActions.LoadDrawableFromStream) + { + return Enumerable.Empty(); + } + + return OurExtensions; + } + + /// + public bool Supports(FileFormatHandlerActions fileFormatHandlerAction, string extension) { if (fileFormatHandlerAction == FileFormatHandlerActions.LoadDrawableFromStream) { return false; } - return SupportedExtensions.Contains(extension); + + return OurExtensions.Contains(extension); } - public void SaveToStream(Bitmap bitmap, Stream destination, string extension) + + /// + public int PriorityFor(FileFormatHandlerActions fileFormatHandlerAction, string extension) { - throw new NotImplementedException(); + return int.MaxValue; } - public Bitmap Load(Stream stream, string extension) + public bool TrySaveToStream(Bitmap bitmap, Stream destination, string extension) + { + // TODO: Implement this + return false; + } + + public bool TryLoadFromStream(Stream stream, string extension, out Bitmap bitmap) { var surface = SimpleServiceProvider.Current.GetInstance>().Invoke(); - return (Bitmap)surface.GetImageForExport(); + bitmap = (Bitmap)surface.GetImageForExport(); + return true; } - public IDrawableContainer LoadDrawableFromStream(Stream stream, string extension, ISurface parent) + public bool TryLoadDrawableFromStream(Stream stream, string extension, out IDrawableContainer drawableContainer, ISurface parent) { throw new NotImplementedException(); } diff --git a/src/Greenshot.Base/Core/FileFormatHandlers/PngFileFormatHandler.cs b/src/Greenshot.Base/Core/FileFormatHandlers/PngFileFormatHandler.cs index 6eab0ae6a..c4ee2ec0f 100644 --- a/src/Greenshot.Base/Core/FileFormatHandlers/PngFileFormatHandler.cs +++ b/src/Greenshot.Base/Core/FileFormatHandlers/PngFileFormatHandler.cs @@ -20,6 +20,7 @@ */ using System; +using System.Collections.Generic; using System.Drawing; using System.IO; using System.Linq; @@ -28,31 +29,55 @@ using Greenshot.Base.Interfaces.Drawing; namespace Greenshot.Base.Core.FileFormatHandlers { + /// + /// This can be an ImageSharp implementation + /// public class PngFileFormatHandler : IFileFormatHandler { - private static readonly string[] SupportedExtensions = { "png" }; + private static readonly string[] OurExtensions = { "png" }; - public bool CanDoActionForExtension(FileFormatHandlerActions fileFormatHandlerAction, string extension) + /// + public IEnumerable SupportedExtensions(FileFormatHandlerActions fileFormatHandlerAction) + { + if (fileFormatHandlerAction == FileFormatHandlerActions.LoadDrawableFromStream) + { + return Enumerable.Empty(); + } + + return OurExtensions; + } + + /// + public bool Supports(FileFormatHandlerActions fileFormatHandlerAction, string extension) { if (fileFormatHandlerAction == FileFormatHandlerActions.LoadDrawableFromStream) { return false; } - return SupportedExtensions.Contains(extension); + + return OurExtensions.Contains(extension); + } + /// + public int PriorityFor(FileFormatHandlerActions fileFormatHandlerAction, string extension) + { + return int.MaxValue; } - public void SaveToStream(Bitmap bitmap, Stream destination, string extension) + public bool TryLoadFromStream(Stream stream, string extension, out Bitmap bitmap) { + // TODO: Implement this throw new NotImplementedException(); } - public Bitmap Load(Stream stream, string extension) + public bool TrySaveToStream(Bitmap bitmap, Stream destination, string extension) { - throw new NotImplementedException(); + // TODO: Implement this + return false; } - public IDrawableContainer LoadDrawableFromStream(Stream stream, string extension, ISurface parent) + public bool TryLoadDrawableFromStream(Stream stream, string extension, out IDrawableContainer drawableContainer, ISurface parent) { + // TODO: Implement this throw new NotImplementedException(); } } diff --git a/src/Greenshot.Base/Core/ImageHelper.cs b/src/Greenshot.Base/Core/ImageHelper.cs index 4aa0207fc..40fb5b2ca 100644 --- a/src/Greenshot.Base/Core/ImageHelper.cs +++ b/src/Greenshot.Base/Core/ImageHelper.cs @@ -25,6 +25,7 @@ using System.Drawing; using System.Drawing.Drawing2D; using System.Drawing.Imaging; using System.IO; +using System.Linq; using Greenshot.Base.Core.FileFormatHandlers; using Greenshot.Base.Effects; using Greenshot.Base.IniFile; @@ -56,14 +57,6 @@ namespace Greenshot.Base.Core private static readonly CoreConfiguration CoreConfig = IniConfig.GetIniSection(); private const int ExifOrientationId = 0x0112; - public static readonly IList FileFormatHandlers = new List(); - - static ImageHelper() - { - FileFormatHandlers.Add(new IconFileFormatHandler()); - FileFormatHandlers.Add(new GreenshotFileFormatHandler()); - FileFormatHandlers.Add(new DefaultFileFormatHandler()); - } /// /// Make sure the image is orientated correctly @@ -1720,12 +1713,15 @@ namespace Greenshot.Base.Core startingPosition = 0; } - foreach (var fileFormatHandler in FileFormatHandlers) + foreach (var fileFormatHandler in FileFormatHandlerRegistry.FileFormatHandlers + .Where(ffh => ffh.Supports(FileFormatHandlerActions.LoadFromStream, extension)) + .OrderBy(ffh => ffh.PriorityFor(FileFormatHandlerActions.LoadFromStream, extension))) { - if (!fileFormatHandler.CanDoActionForExtension(FileFormatHandlerActions.Load, extension)) continue; - stream.Seek(startingPosition, SeekOrigin.Begin); - return fileFormatHandler.Load(stream, extension); + if (fileFormatHandler.TryLoadFromStream(stream, extension, out var bitmap)) + { + return bitmap; + } } return null; diff --git a/src/Greenshot.Base/Core/NetworkHelper.cs b/src/Greenshot.Base/Core/NetworkHelper.cs index 5170db504..e9671db38 100644 --- a/src/Greenshot.Base/Core/NetworkHelper.cs +++ b/src/Greenshot.Base/Core/NetworkHelper.cs @@ -24,9 +24,11 @@ using System.Collections.Generic; using System.Drawing; using System.Globalization; using System.IO; +using System.Linq; using System.Net; using System.Text; using System.Text.RegularExpressions; +using Greenshot.Base.Core.FileFormatHandlers; using Greenshot.Base.IniFile; using Greenshot.Base.Interfaces; using Greenshot.Base.Interfaces.Plugin; @@ -94,7 +96,8 @@ namespace Greenshot.Base.Core public static Image DownloadImage(string url) { var extensions = new StringBuilder(); - foreach (var extension in ImageHelper.StreamConverters.Keys) + var supportedExtensions = FileFormatHandlerRegistry.ExtensionsFor(FileFormatHandlerActions.LoadFromStream).ToList(); + foreach (var extension in supportedExtensions) { if (string.IsNullOrEmpty(extension)) { diff --git a/src/Greenshot.Base/Interfaces/IFileFormatHandler.cs b/src/Greenshot.Base/Interfaces/IFileFormatHandler.cs index e7d5c7a83..04442d71b 100644 --- a/src/Greenshot.Base/Interfaces/IFileFormatHandler.cs +++ b/src/Greenshot.Base/Interfaces/IFileFormatHandler.cs @@ -32,7 +32,7 @@ namespace Greenshot.Base.Interfaces public enum FileFormatHandlerActions { SaveToStream, - Load, + LoadFromStream, LoadDrawableFromStream } diff --git a/src/Greenshot.Editor/EditorInitialize.cs b/src/Greenshot.Editor/EditorInitialize.cs new file mode 100644 index 000000000..e3b2667fd --- /dev/null +++ b/src/Greenshot.Editor/EditorInitialize.cs @@ -0,0 +1,34 @@ +/* + * Greenshot - a free and open source screenshot tool + * Copyright (C) 2007-2021 Thomas Braun, Jens Klingen, Robin Krom + * + * For more information see: https://getgreenshot.org/ + * The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 1 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +using Greenshot.Base.Core.FileFormatHandlers; +using Greenshot.Editor.FileFormatHandlers; + +namespace Greenshot.Editor +{ + public static class EditorInitialize + { + public static void Initialize() + { + FileFormatHandlerRegistry.FileFormatHandlers.Add(new SvgFileFormatHandler()); + } + } +} diff --git a/src/Greenshot.Editor/FileFormatHandlers/SvgFileFormatHandler.cs b/src/Greenshot.Editor/FileFormatHandlers/SvgFileFormatHandler.cs index 95a683240..aa0a512de 100644 --- a/src/Greenshot.Editor/FileFormatHandlers/SvgFileFormatHandler.cs +++ b/src/Greenshot.Editor/FileFormatHandlers/SvgFileFormatHandler.cs @@ -20,6 +20,7 @@ */ using System; +using System.Collections.Generic; using System.Drawing; using System.Drawing.Imaging; using System.IO; @@ -39,48 +40,67 @@ namespace Greenshot.Editor.FileFormatHandlers public class SvgFileFormatHandler : IFileFormatHandler { private static readonly ILog Log = LogManager.GetLogger(typeof(ImageHelper)); + private static readonly string[] OurExtensions = { "svg" }; - private static readonly string[] SupportedExtensions = { "svg" }; - - public bool CanDoActionForExtension(FileFormatHandlerActions fileFormatHandlerAction, string extension) + /// + public IEnumerable SupportedExtensions(FileFormatHandlerActions fileFormatHandlerAction) { - if (fileFormatHandlerAction == FileFormatHandlerActions.SaveToStream) + if (fileFormatHandlerAction == FileFormatHandlerActions.LoadDrawableFromStream) + { + return Enumerable.Empty(); + } + + return OurExtensions; + } + + /// + public bool Supports(FileFormatHandlerActions fileFormatHandlerAction, string extension) + { + if (fileFormatHandlerAction == FileFormatHandlerActions.LoadDrawableFromStream) { return false; } - return SupportedExtensions.Contains(extension); + + return OurExtensions.Contains(extension); + } + /// + public int PriorityFor(FileFormatHandlerActions fileFormatHandlerAction, string extension) + { + return int.MaxValue; } - public void SaveToStream(Bitmap bitmap, Stream destination, string extension) + public bool TryLoadFromStream(Stream stream, string extension, out Bitmap bitmap) { - throw new NotImplementedException(); - } - - public Bitmap Load(Stream stream, string extension) - { - var svgDocument = SvgDocument.Open(stream); int width = (int)svgDocument.ViewBox.Width; int height = (int)svgDocument.ViewBox.Height; try { - var result = ImageHelper.CreateEmpty(width, height, PixelFormat.Format32bppArgb, Color.Transparent); - svgDocument.Draw(result); - return result; + bitmap = ImageHelper.CreateEmpty(width, height, PixelFormat.Format32bppArgb, Color.Transparent); + svgDocument.Draw(bitmap); + return true; } catch (Exception ex) { Log.Error("Can't load SVG", ex); } - return null; + bitmap = null; + return false; } - public IDrawableContainer LoadDrawableFromStream(Stream stream, string extension, ISurface parent) + public bool TrySaveToStream(Bitmap bitmap, Stream destination, string extension) + { + // TODO: Implement this + return false; + } + + public bool TryLoadDrawableFromStream(Stream stream, string extension, out IDrawableContainer drawableContainer, ISurface parent) { var svgDocument = SvgDocument.Open(stream); - return new SvgContainer(svgDocument, parent); + drawableContainer = new SvgContainer(svgDocument, parent); + return true; } } } diff --git a/src/Greenshot/GreenshotMain.cs b/src/Greenshot/GreenshotMain.cs index 2d42d4b11..0e4b9bd92 100644 --- a/src/Greenshot/GreenshotMain.cs +++ b/src/Greenshot/GreenshotMain.cs @@ -23,6 +23,7 @@ using System; using System.Globalization; using System.Net; using System.Reflection; +using Greenshot.Editor; using Greenshot.Forms; namespace Greenshot @@ -65,6 +66,7 @@ namespace Greenshot CultureInfo.DefaultThreadCurrentCulture = CultureInfo.InvariantCulture; CultureInfo.DefaultThreadCurrentUICulture = CultureInfo.InvariantCulture; + EditorInitialize.Initialize(); MainForm.Start(args); } }