diff --git a/src/Greenshot.Base/Core/FileFormatHandlers/FileFormatHandlerRegistry.cs b/src/Greenshot.Base/Core/FileFormatHandlers/FileFormatHandlerRegistry.cs index 47603fa2a..1fe5e6860 100644 --- a/src/Greenshot.Base/Core/FileFormatHandlers/FileFormatHandlerRegistry.cs +++ b/src/Greenshot.Base/Core/FileFormatHandlers/FileFormatHandlerRegistry.cs @@ -28,13 +28,50 @@ using Greenshot.Base.Interfaces.Drawing; namespace Greenshot.Base.Core.FileFormatHandlers { + /// + /// This is the registry where all IFileFormatHandler are registered and can be used + /// public static class FileFormatHandlerRegistry { public static IList FileFormatHandlers { get; } = new List(); + /// + /// Make sure we handle the input extension always the same, by "normalizing" it + /// + /// string + /// string + public static string NormalizeExtension(string extension) + { + if (string.IsNullOrEmpty(extension)) + { + return null; + } + + extension = extension.ToLowerInvariant(); + return !extension.StartsWith(".") ? $".{extension}" : extension; + } + + /// + /// + /// + /// + /// public static IEnumerable ExtensionsFor(FileFormatHandlerActions fileFormatHandlerAction) { - return FileFormatHandlers.SelectMany(ffh => ffh.SupportedExtensions(fileFormatHandlerAction)).Distinct(); + return FileFormatHandlers.Where(ffh => ffh.SupportedExtensions.ContainsKey(fileFormatHandlerAction)).SelectMany(ffh => ffh.SupportedExtensions[fileFormatHandlerAction]).Distinct(); + } + + /// + /// Extension method to check if a certain IFileFormatHandler supports a certain action with a specific extension + /// + /// IFileFormatHandler + /// FileFormatHandlerActions + /// string + /// bool + public static bool Supports(this IFileFormatHandler fileFormatHandler, FileFormatHandlerActions fileFormatHandlerAction, string extension) + { + extension = NormalizeExtension(extension); + return fileFormatHandler.SupportedExtensions.ContainsKey(fileFormatHandlerAction) && fileFormatHandler.SupportedExtensions[fileFormatHandlerAction].Contains(extension); } /// @@ -48,6 +85,8 @@ namespace Greenshot.Base.Core.FileFormatHandlers /// bool public static bool TrySaveToStream(Bitmap bitmap, Stream destination, string extension) { + extension = NormalizeExtension(extension); + var fileFormatHandler = FileFormatHandlers .Where(ffh => ffh.Supports(FileFormatHandlerActions.LoadFromStream, extension)) .OrderBy(ffh => ffh.PriorityFor(FileFormatHandlerActions.LoadFromStream, extension)) @@ -71,6 +110,8 @@ namespace Greenshot.Base.Core.FileFormatHandlers /// bool true if it was successful public static bool TryLoadDrawableFromStream(Stream stream, string extension, out IDrawableContainer drawableContainer, ISurface parentSurface = null) { + extension = NormalizeExtension(extension); + var fileFormatHandler = FileFormatHandlers .Where(ffh => ffh.Supports(FileFormatHandlerActions.LoadDrawableFromStream, extension)) .OrderBy(ffh => ffh.PriorityFor(FileFormatHandlerActions.LoadDrawableFromStream, extension)) @@ -94,6 +135,8 @@ namespace Greenshot.Base.Core.FileFormatHandlers /// bool true if it was successful public static bool TryLoadFromStream(Stream stream, string extension, out Bitmap bitmap) { + extension = NormalizeExtension(extension); + var fileFormatHandler = FileFormatHandlers .Where(ffh => ffh.Supports(FileFormatHandlerActions.LoadFromStream, extension)) .OrderBy(ffh => ffh.PriorityFor(FileFormatHandlerActions.LoadFromStream, extension)) diff --git a/src/Greenshot.Base/Interfaces/IFileFormatHandler.cs b/src/Greenshot.Base/Interfaces/IFileFormatHandler.cs index 7281f0228..55e0c3839 100644 --- a/src/Greenshot.Base/Interfaces/IFileFormatHandler.cs +++ b/src/Greenshot.Base/Interfaces/IFileFormatHandler.cs @@ -42,19 +42,9 @@ namespace Greenshot.Base.Interfaces public interface IFileFormatHandler { /// - /// Delivers the extension that the supplied action supports + /// Registry for all the extensions this IFileFormatHandler support /// - /// FileFormatHandlerActions - /// IEnumerable{string} - IEnumerable SupportedExtensions(FileFormatHandlerActions fileFormatHandlerAction); - - /// - ///Does this IFileFormatHandler support the specified action for the specified extension? - /// - /// FileFormatHandlerActions - /// string - /// bool true if this IFileFormatHandler can support the action for the extension - public bool Supports(FileFormatHandlerActions fileFormatHandlerAction, string extension); + IDictionary> SupportedExtensions { get; } /// /// Priority (from high int.MinValue, low int.MaxValue) of this IFileFormatHandler for the specified action and extension diff --git a/src/Greenshot.Editor/FileFormatHandlers/AbstractFileFormatHandler.cs b/src/Greenshot.Editor/FileFormatHandlers/AbstractFileFormatHandler.cs index 84b8496ce..0ab077c96 100644 --- a/src/Greenshot.Editor/FileFormatHandlers/AbstractFileFormatHandler.cs +++ b/src/Greenshot.Editor/FileFormatHandlers/AbstractFileFormatHandler.cs @@ -1,7 +1,6 @@ using System.Collections.Generic; using System.Drawing; using System.IO; -using System.Linq; using Greenshot.Base.Interfaces; using Greenshot.Base.Interfaces.Drawing; using Greenshot.Editor.Drawing; @@ -10,40 +9,13 @@ namespace Greenshot.Editor.FileFormatHandlers { public abstract class AbstractFileFormatHandler : IFileFormatHandler { - /// - /// Make sure we handle the input extension always the same, by "normalizing" it - /// - /// string - /// string - protected string NormalizeExtension(string extension) - { - if (string.IsNullOrEmpty(extension)) - { - return null; - } - - extension = extension.ToLowerInvariant(); - return !extension.StartsWith(".") ? $".{extension}" : extension; - } - - protected abstract string[] OurExtensions { get; } - /// - public virtual IEnumerable SupportedExtensions(FileFormatHandlerActions fileFormatHandlerAction) - { - return OurExtensions; - } - - /// - public virtual bool Supports(FileFormatHandlerActions fileFormatHandlerAction, string extension) - { - return OurExtensions.Contains(NormalizeExtension(extension)); - } + public IDictionary> SupportedExtensions { get; } = new Dictionary>(); /// public virtual int PriorityFor(FileFormatHandlerActions fileFormatHandlerAction, string extension) { - return int.MaxValue; + return 0; } public abstract bool TrySaveToStream(Bitmap bitmap, Stream destination, string extension); diff --git a/src/Greenshot.Editor/FileFormatHandlers/DefaultFileFormatHandler.cs b/src/Greenshot.Editor/FileFormatHandlers/DefaultFileFormatHandler.cs index 97ab042e6..130f2b304 100644 --- a/src/Greenshot.Editor/FileFormatHandlers/DefaultFileFormatHandler.cs +++ b/src/Greenshot.Editor/FileFormatHandlers/DefaultFileFormatHandler.cs @@ -19,6 +19,7 @@ * along with this program. If not, see . */ +using System.Collections.Generic; using System.Drawing; using System.Drawing.Imaging; using System.IO; @@ -32,12 +33,19 @@ namespace Greenshot.Editor.FileFormatHandlers /// public class DefaultFileFormatHandler : AbstractFileFormatHandler, IFileFormatHandler { - protected override string[] OurExtensions { get; } = { ".png", ".bmp", ".gif", ".jpg", ".jpeg", ".tiff", ".tif" }; + private readonly List _ourExtensions = new() { ".png", ".bmp", ".gif", ".jpg", ".jpeg", ".tiff", ".tif" }; + + public DefaultFileFormatHandler() + { + SupportedExtensions[FileFormatHandlerActions.LoadDrawableFromStream] = _ourExtensions; + SupportedExtensions[FileFormatHandlerActions.LoadFromStream] = _ourExtensions; + SupportedExtensions[FileFormatHandlerActions.SaveToStream] = _ourExtensions; + } /// public override bool TrySaveToStream(Bitmap bitmap, Stream destination, string extension) { - ImageFormat imageFormat = NormalizeExtension(extension) switch + ImageFormat imageFormat = extension switch { ".png" => ImageFormat.Png, ".bmp" => ImageFormat.Bmp, diff --git a/src/Greenshot.Editor/FileFormatHandlers/DibFileFormatHandler.cs b/src/Greenshot.Editor/FileFormatHandlers/DibFileFormatHandler.cs index 607374ac9..d152a432d 100644 --- a/src/Greenshot.Editor/FileFormatHandlers/DibFileFormatHandler.cs +++ b/src/Greenshot.Editor/FileFormatHandlers/DibFileFormatHandler.cs @@ -20,6 +20,7 @@ */ using System; +using System.Collections.Generic; using System.Drawing; using System.Drawing.Imaging; using System.IO; @@ -38,7 +39,15 @@ namespace Greenshot.Editor.FileFormatHandlers { private const double DpiToPelsPerMeter = 39.3701; private static readonly ILog Log = LogManager.GetLogger(typeof(DibFileFormatHandler)); - protected override string[] OurExtensions { get; } = { ".dib", ".format17" }; + + private readonly List _ourExtensions = new() { ".dib", ".format17" }; + + public DibFileFormatHandler() + { + SupportedExtensions[FileFormatHandlerActions.LoadDrawableFromStream] = _ourExtensions; + SupportedExtensions[FileFormatHandlerActions.LoadFromStream] = _ourExtensions; + SupportedExtensions[FileFormatHandlerActions.SaveToStream] = _ourExtensions; + } /// public override bool TrySaveToStream(Bitmap bitmap, Stream destination, string extension) diff --git a/src/Greenshot.Editor/FileFormatHandlers/GreenshotFileFormatHandler.cs b/src/Greenshot.Editor/FileFormatHandlers/GreenshotFileFormatHandler.cs index 150a98327..fecfc2276 100644 --- a/src/Greenshot.Editor/FileFormatHandlers/GreenshotFileFormatHandler.cs +++ b/src/Greenshot.Editor/FileFormatHandlers/GreenshotFileFormatHandler.cs @@ -23,7 +23,6 @@ using System; using System.Collections.Generic; using System.Drawing; using System.IO; -using System.Linq; using Greenshot.Base.Core; using Greenshot.Base.Interfaces; @@ -31,28 +30,12 @@ namespace Greenshot.Editor.FileFormatHandlers { public class GreenshotFileFormatHandler : AbstractFileFormatHandler, IFileFormatHandler { - protected override string[] OurExtensions { get; } = { ".greenshot" }; - - /// - public override IEnumerable SupportedExtensions(FileFormatHandlerActions fileFormatHandlerAction) + private readonly List _ourExtensions = new() { ".greenshot" }; + public GreenshotFileFormatHandler() { - if (fileFormatHandlerAction == FileFormatHandlerActions.LoadDrawableFromStream) - { - return Enumerable.Empty(); - } - - return OurExtensions; - } - - /// - public override bool Supports(FileFormatHandlerActions fileFormatHandlerAction, string extension) - { - if (fileFormatHandlerAction == FileFormatHandlerActions.SaveToStream) - { - return false; - } - - return OurExtensions.Contains(NormalizeExtension(extension)); + SupportedExtensions[FileFormatHandlerActions.LoadDrawableFromStream] = _ourExtensions; + SupportedExtensions[FileFormatHandlerActions.LoadFromStream] = _ourExtensions; + //SupportedExtensions[FileFormatHandlerActions.SaveToStream] = _ourExtensions; } public override bool TrySaveToStream(Bitmap bitmap, Stream destination, string extension) diff --git a/src/Greenshot.Editor/FileFormatHandlers/IconFileFormatHandler.cs b/src/Greenshot.Editor/FileFormatHandlers/IconFileFormatHandler.cs index 4a29545a4..6a15ea0ba 100644 --- a/src/Greenshot.Editor/FileFormatHandlers/IconFileFormatHandler.cs +++ b/src/Greenshot.Editor/FileFormatHandlers/IconFileFormatHandler.cs @@ -20,6 +20,7 @@ */ using System; +using System.Collections.Generic; using System.Drawing; using System.Drawing.Imaging; using System.IO; @@ -30,14 +31,19 @@ using log4net; namespace Greenshot.Editor.FileFormatHandlers { /// - /// THis is the default .NET bitmap file format handler + /// THis is the .ico format handler /// public class IconFileFormatHandler : AbstractFileFormatHandler, IFileFormatHandler { private static readonly ILog Log = LogManager.GetLogger(typeof(IconFileFormatHandler)); - protected override string[] OurExtensions { get; } = { ".ico" }; + private readonly List _ourExtensions = new() { ".ico" }; + public IconFileFormatHandler() + { + SupportedExtensions[FileFormatHandlerActions.LoadDrawableFromStream] = _ourExtensions; + SupportedExtensions[FileFormatHandlerActions.LoadFromStream] = _ourExtensions; + } public override bool TrySaveToStream(Bitmap bitmap, Stream destination, string extension) { diff --git a/src/Greenshot.Editor/FileFormatHandlers/MetaFileFormatHandler.cs b/src/Greenshot.Editor/FileFormatHandlers/MetaFileFormatHandler.cs index 1245c3b71..7c5d23a4a 100644 --- a/src/Greenshot.Editor/FileFormatHandlers/MetaFileFormatHandler.cs +++ b/src/Greenshot.Editor/FileFormatHandlers/MetaFileFormatHandler.cs @@ -36,27 +36,12 @@ namespace Greenshot.Editor.FileFormatHandlers /// public class MetaFileFormatHandler : AbstractFileFormatHandler, IFileFormatHandler { - protected override string[] OurExtensions { get; } = { ".wmf", ".emf" }; - - public override IEnumerable SupportedExtensions(FileFormatHandlerActions fileFormatHandlerAction) + private readonly List _ourExtensions = new (){ ".wmf", ".emf" }; + + public MetaFileFormatHandler() { - if (fileFormatHandlerAction == FileFormatHandlerActions.SaveToStream) - { - return Enumerable.Empty(); - } - - return OurExtensions; - } - - /// - public override bool Supports(FileFormatHandlerActions fileFormatHandlerAction, string extension) - { - if (fileFormatHandlerAction == FileFormatHandlerActions.SaveToStream) - { - return false; - } - - return OurExtensions.Contains(NormalizeExtension(extension)); + SupportedExtensions[FileFormatHandlerActions.LoadDrawableFromStream] = _ourExtensions; + SupportedExtensions[FileFormatHandlerActions.LoadFromStream] = _ourExtensions; } /// diff --git a/src/Greenshot.Editor/FileFormatHandlers/SvgFileFormatHandler.cs b/src/Greenshot.Editor/FileFormatHandlers/SvgFileFormatHandler.cs index 33011a17a..38cf4c47a 100644 --- a/src/Greenshot.Editor/FileFormatHandlers/SvgFileFormatHandler.cs +++ b/src/Greenshot.Editor/FileFormatHandlers/SvgFileFormatHandler.cs @@ -23,7 +23,6 @@ using System; using System.Collections.Generic; using System.Drawing; using System.IO; -using System.Linq; using Greenshot.Base.Interfaces; using Greenshot.Base.Interfaces.Drawing; using Greenshot.Editor.Drawing; @@ -38,28 +37,12 @@ namespace Greenshot.Editor.FileFormatHandlers public class SvgFileFormatHandler : AbstractFileFormatHandler, IFileFormatHandler { private static readonly ILog Log = LogManager.GetLogger(typeof(SvgFileFormatHandler)); - protected override string[] OurExtensions { get; } = { ".svg" }; + private readonly List _ourExtensions = new() { ".svg" }; - /// - public override IEnumerable SupportedExtensions(FileFormatHandlerActions fileFormatHandlerAction) + public SvgFileFormatHandler() { - if (fileFormatHandlerAction == FileFormatHandlerActions.SaveToStream) - { - return Enumerable.Empty(); - } - - return OurExtensions; - } - - /// - public override bool Supports(FileFormatHandlerActions fileFormatHandlerAction, string extension) - { - if (fileFormatHandlerAction == FileFormatHandlerActions.SaveToStream) - { - return false; - } - - return OurExtensions.Contains(NormalizeExtension(extension)); + SupportedExtensions[FileFormatHandlerActions.LoadDrawableFromStream] = _ourExtensions; + SupportedExtensions[FileFormatHandlerActions.LoadFromStream] = _ourExtensions; } public override bool TryLoadFromStream(Stream stream, string extension, out Bitmap bitmap) diff --git a/src/Greenshot.Editor/FileFormatHandlers/WmpFileFormatHandler.cs b/src/Greenshot.Editor/FileFormatHandlers/WmpFileFormatHandler.cs index 6f0974dea..b03eb8652 100644 --- a/src/Greenshot.Editor/FileFormatHandlers/WmpFileFormatHandler.cs +++ b/src/Greenshot.Editor/FileFormatHandlers/WmpFileFormatHandler.cs @@ -19,6 +19,7 @@ * along with this program. If not, see . */ +using System.Collections.Generic; using System.Drawing; using System.IO; using System.Windows.Media.Imaging; @@ -28,11 +29,19 @@ using Greenshot.Base.Core; namespace Greenshot.Editor.FileFormatHandlers { /// - /// This is the default .NET bitmap file format handler + /// This is the System.Windows.Media.Imaging (WPF) file format handler /// public class WmpFileFormatHandler : AbstractFileFormatHandler, IFileFormatHandler { - protected override string[] OurExtensions { get; } = { ".jxr", ".wdp", ".wmp" }; + private List LoadFromStreamExtensions { get; } = new() { ".jxr", ".wdp", ".wmp", ".heic", ".heif" }; + private List SaveToStreamExtensions { get; } = new() { ".jxr" }; + + public WmpFileFormatHandler() + { + SupportedExtensions[FileFormatHandlerActions.LoadDrawableFromStream] = LoadFromStreamExtensions; + SupportedExtensions[FileFormatHandlerActions.LoadFromStream] = LoadFromStreamExtensions; + SupportedExtensions[FileFormatHandlerActions.SaveToStream] = SaveToStreamExtensions; + } /// public override bool TrySaveToStream(Bitmap bitmap, Stream destination, string extension) @@ -57,8 +66,8 @@ namespace Greenshot.Editor.FileFormatHandlers /// public override bool TryLoadFromStream(Stream stream, string extension, out Bitmap bitmap) { - var decoder = new WmpBitmapDecoder(stream, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.None); - var bitmapSource = decoder.Frames[0]; + var bitmapDecoder = BitmapDecoder.Create(stream, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.None); + var bitmapSource = bitmapDecoder.Frames[0]; bitmap = bitmapSource.ToBitmap(); return true; } diff --git a/src/Greenshot/Forms/MainForm.cs b/src/Greenshot/Forms/MainForm.cs index f1c4f8bbc..d92dc0814 100644 --- a/src/Greenshot/Forms/MainForm.cs +++ b/src/Greenshot/Forms/MainForm.cs @@ -36,6 +36,7 @@ using Greenshot.Base; using Greenshot.Base.Controls; using Greenshot.Base.Core; using Greenshot.Base.Core.Enums; +using Greenshot.Base.Core.FileFormatHandlers; using Greenshot.Base.Help; using Greenshot.Base.IniFile; using Greenshot.Base.Interfaces; @@ -936,9 +937,11 @@ namespace Greenshot.Forms private void CaptureFile(IDestination destination = null) { + var extensions = FileFormatHandlerRegistry.ExtensionsFor(FileFormatHandlerActions.LoadFromStream).Select(e => $"*{e}").ToList(); + var openFileDialog = new OpenFileDialog { - Filter = @"Image files (*.greenshot, *.png, *.jpg, *.gif, *.bmp, *.ico, *.tiff, *.wmf)|*.greenshot; *.png; *.jpg; *.jpeg; *.gif; *.bmp; *.ico; *.tiff; *.tif; *.wmf" + Filter = @$"Image files ({string.Join(", ", extensions)})|{string.Join("; ", extensions)}" }; if (openFileDialog.ShowDialog() != DialogResult.OK) {