Restructuring of the FileFormatHandler, to make it easier to configure what extensions are supported for different actions.

This commit is contained in:
Robin Krom 2022-02-10 16:22:46 +01:00
commit 1a72e6661e
No known key found for this signature in database
GPG key ID: BCC01364F1371490
11 changed files with 107 additions and 116 deletions

View file

@ -28,13 +28,50 @@ using Greenshot.Base.Interfaces.Drawing;
namespace Greenshot.Base.Core.FileFormatHandlers namespace Greenshot.Base.Core.FileFormatHandlers
{ {
/// <summary>
/// This is the registry where all IFileFormatHandler are registered and can be used
/// </summary>
public static class FileFormatHandlerRegistry public static class FileFormatHandlerRegistry
{ {
public static IList<IFileFormatHandler> FileFormatHandlers { get; } = new List<IFileFormatHandler>(); public static IList<IFileFormatHandler> FileFormatHandlers { get; } = new List<IFileFormatHandler>();
/// <summary>
/// Make sure we handle the input extension always the same, by "normalizing" it
/// </summary>
/// <param name="extension">string</param>
/// <returns>string</returns>
public static string NormalizeExtension(string extension)
{
if (string.IsNullOrEmpty(extension))
{
return null;
}
extension = extension.ToLowerInvariant();
return !extension.StartsWith(".") ? $".{extension}" : extension;
}
/// <summary>
///
/// </summary>
/// <param name="fileFormatHandlerAction"></param>
/// <returns></returns>
public static IEnumerable<string> ExtensionsFor(FileFormatHandlerActions fileFormatHandlerAction) public static IEnumerable<string> 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();
}
/// <summary>
/// Extension method to check if a certain IFileFormatHandler supports a certain action with a specific extension
/// </summary>
/// <param name="fileFormatHandler">IFileFormatHandler</param>
/// <param name="fileFormatHandlerAction">FileFormatHandlerActions</param>
/// <param name="extension">string</param>
/// <returns>bool</returns>
public static bool Supports(this IFileFormatHandler fileFormatHandler, FileFormatHandlerActions fileFormatHandlerAction, string extension)
{
extension = NormalizeExtension(extension);
return fileFormatHandler.SupportedExtensions.ContainsKey(fileFormatHandlerAction) && fileFormatHandler.SupportedExtensions[fileFormatHandlerAction].Contains(extension);
} }
/// <summary> /// <summary>
@ -48,6 +85,8 @@ namespace Greenshot.Base.Core.FileFormatHandlers
/// <returns>bool</returns> /// <returns>bool</returns>
public static bool TrySaveToStream(Bitmap bitmap, Stream destination, string extension) public static bool TrySaveToStream(Bitmap bitmap, Stream destination, string extension)
{ {
extension = NormalizeExtension(extension);
var fileFormatHandler = FileFormatHandlers var fileFormatHandler = FileFormatHandlers
.Where(ffh => ffh.Supports(FileFormatHandlerActions.LoadFromStream, extension)) .Where(ffh => ffh.Supports(FileFormatHandlerActions.LoadFromStream, extension))
.OrderBy(ffh => ffh.PriorityFor(FileFormatHandlerActions.LoadFromStream, extension)) .OrderBy(ffh => ffh.PriorityFor(FileFormatHandlerActions.LoadFromStream, extension))
@ -71,6 +110,8 @@ namespace Greenshot.Base.Core.FileFormatHandlers
/// <returns>bool true if it was successful</returns> /// <returns>bool true if it was successful</returns>
public static bool TryLoadDrawableFromStream(Stream stream, string extension, out IDrawableContainer drawableContainer, ISurface parentSurface = null) public static bool TryLoadDrawableFromStream(Stream stream, string extension, out IDrawableContainer drawableContainer, ISurface parentSurface = null)
{ {
extension = NormalizeExtension(extension);
var fileFormatHandler = FileFormatHandlers var fileFormatHandler = FileFormatHandlers
.Where(ffh => ffh.Supports(FileFormatHandlerActions.LoadDrawableFromStream, extension)) .Where(ffh => ffh.Supports(FileFormatHandlerActions.LoadDrawableFromStream, extension))
.OrderBy(ffh => ffh.PriorityFor(FileFormatHandlerActions.LoadDrawableFromStream, extension)) .OrderBy(ffh => ffh.PriorityFor(FileFormatHandlerActions.LoadDrawableFromStream, extension))
@ -94,6 +135,8 @@ namespace Greenshot.Base.Core.FileFormatHandlers
/// <returns>bool true if it was successful</returns> /// <returns>bool true if it was successful</returns>
public static bool TryLoadFromStream(Stream stream, string extension, out Bitmap bitmap) public static bool TryLoadFromStream(Stream stream, string extension, out Bitmap bitmap)
{ {
extension = NormalizeExtension(extension);
var fileFormatHandler = FileFormatHandlers var fileFormatHandler = FileFormatHandlers
.Where(ffh => ffh.Supports(FileFormatHandlerActions.LoadFromStream, extension)) .Where(ffh => ffh.Supports(FileFormatHandlerActions.LoadFromStream, extension))
.OrderBy(ffh => ffh.PriorityFor(FileFormatHandlerActions.LoadFromStream, extension)) .OrderBy(ffh => ffh.PriorityFor(FileFormatHandlerActions.LoadFromStream, extension))

View file

@ -42,19 +42,9 @@ namespace Greenshot.Base.Interfaces
public interface IFileFormatHandler public interface IFileFormatHandler
{ {
/// <summary> /// <summary>
/// Delivers the extension that the supplied action supports /// Registry for all the extensions this IFileFormatHandler support
/// </summary> /// </summary>
/// <param name="fileFormatHandlerAction">FileFormatHandlerActions</param> IDictionary<FileFormatHandlerActions, IList<string>> SupportedExtensions { get; }
/// <returns>IEnumerable{string}</returns>
IEnumerable<string> SupportedExtensions(FileFormatHandlerActions fileFormatHandlerAction);
/// <summary>
///Does this IFileFormatHandler support the specified action for the specified extension?
/// </summary>
/// <param name="fileFormatHandlerAction">FileFormatHandlerActions</param>
/// <param name="extension">string</param>
/// <returns>bool true if this IFileFormatHandler can support the action for the extension</returns>
public bool Supports(FileFormatHandlerActions fileFormatHandlerAction, string extension);
/// <summary> /// <summary>
/// Priority (from high int.MinValue, low int.MaxValue) of this IFileFormatHandler for the specified action and extension /// Priority (from high int.MinValue, low int.MaxValue) of this IFileFormatHandler for the specified action and extension

View file

@ -1,7 +1,6 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Drawing; using System.Drawing;
using System.IO; using System.IO;
using System.Linq;
using Greenshot.Base.Interfaces; using Greenshot.Base.Interfaces;
using Greenshot.Base.Interfaces.Drawing; using Greenshot.Base.Interfaces.Drawing;
using Greenshot.Editor.Drawing; using Greenshot.Editor.Drawing;
@ -10,40 +9,13 @@ namespace Greenshot.Editor.FileFormatHandlers
{ {
public abstract class AbstractFileFormatHandler : IFileFormatHandler public abstract class AbstractFileFormatHandler : IFileFormatHandler
{ {
/// <summary>
/// Make sure we handle the input extension always the same, by "normalizing" it
/// </summary>
/// <param name="extension">string</param>
/// <returns>string</returns>
protected string NormalizeExtension(string extension)
{
if (string.IsNullOrEmpty(extension))
{
return null;
}
extension = extension.ToLowerInvariant();
return !extension.StartsWith(".") ? $".{extension}" : extension;
}
protected abstract string[] OurExtensions { get; }
/// <inheritdoc /> /// <inheritdoc />
public virtual IEnumerable<string> SupportedExtensions(FileFormatHandlerActions fileFormatHandlerAction) public IDictionary<FileFormatHandlerActions, IList<string>> SupportedExtensions { get; } = new Dictionary<FileFormatHandlerActions, IList<string>>();
{
return OurExtensions;
}
/// <inheritdoc />
public virtual bool Supports(FileFormatHandlerActions fileFormatHandlerAction, string extension)
{
return OurExtensions.Contains(NormalizeExtension(extension));
}
/// <inheritdoc /> /// <inheritdoc />
public virtual int PriorityFor(FileFormatHandlerActions fileFormatHandlerAction, string extension) public virtual int PriorityFor(FileFormatHandlerActions fileFormatHandlerAction, string extension)
{ {
return int.MaxValue; return 0;
} }
public abstract bool TrySaveToStream(Bitmap bitmap, Stream destination, string extension); public abstract bool TrySaveToStream(Bitmap bitmap, Stream destination, string extension);

View file

@ -19,6 +19,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
using System.Collections.Generic;
using System.Drawing; using System.Drawing;
using System.Drawing.Imaging; using System.Drawing.Imaging;
using System.IO; using System.IO;
@ -32,12 +33,19 @@ namespace Greenshot.Editor.FileFormatHandlers
/// </summary> /// </summary>
public class DefaultFileFormatHandler : AbstractFileFormatHandler, IFileFormatHandler public class DefaultFileFormatHandler : AbstractFileFormatHandler, IFileFormatHandler
{ {
protected override string[] OurExtensions { get; } = { ".png", ".bmp", ".gif", ".jpg", ".jpeg", ".tiff", ".tif" }; private readonly List<string> _ourExtensions = new() { ".png", ".bmp", ".gif", ".jpg", ".jpeg", ".tiff", ".tif" };
public DefaultFileFormatHandler()
{
SupportedExtensions[FileFormatHandlerActions.LoadDrawableFromStream] = _ourExtensions;
SupportedExtensions[FileFormatHandlerActions.LoadFromStream] = _ourExtensions;
SupportedExtensions[FileFormatHandlerActions.SaveToStream] = _ourExtensions;
}
/// <inheritdoc /> /// <inheritdoc />
public override bool TrySaveToStream(Bitmap bitmap, Stream destination, string extension) public override bool TrySaveToStream(Bitmap bitmap, Stream destination, string extension)
{ {
ImageFormat imageFormat = NormalizeExtension(extension) switch ImageFormat imageFormat = extension switch
{ {
".png" => ImageFormat.Png, ".png" => ImageFormat.Png,
".bmp" => ImageFormat.Bmp, ".bmp" => ImageFormat.Bmp,

View file

@ -20,6 +20,7 @@
*/ */
using System; using System;
using System.Collections.Generic;
using System.Drawing; using System.Drawing;
using System.Drawing.Imaging; using System.Drawing.Imaging;
using System.IO; using System.IO;
@ -38,7 +39,15 @@ namespace Greenshot.Editor.FileFormatHandlers
{ {
private const double DpiToPelsPerMeter = 39.3701; private const double DpiToPelsPerMeter = 39.3701;
private static readonly ILog Log = LogManager.GetLogger(typeof(DibFileFormatHandler)); private static readonly ILog Log = LogManager.GetLogger(typeof(DibFileFormatHandler));
protected override string[] OurExtensions { get; } = { ".dib", ".format17" };
private readonly List<string> _ourExtensions = new() { ".dib", ".format17" };
public DibFileFormatHandler()
{
SupportedExtensions[FileFormatHandlerActions.LoadDrawableFromStream] = _ourExtensions;
SupportedExtensions[FileFormatHandlerActions.LoadFromStream] = _ourExtensions;
SupportedExtensions[FileFormatHandlerActions.SaveToStream] = _ourExtensions;
}
/// <inheritdoc /> /// <inheritdoc />
public override bool TrySaveToStream(Bitmap bitmap, Stream destination, string extension) public override bool TrySaveToStream(Bitmap bitmap, Stream destination, string extension)

View file

@ -23,7 +23,6 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Drawing; using System.Drawing;
using System.IO; using System.IO;
using System.Linq;
using Greenshot.Base.Core; using Greenshot.Base.Core;
using Greenshot.Base.Interfaces; using Greenshot.Base.Interfaces;
@ -31,28 +30,12 @@ namespace Greenshot.Editor.FileFormatHandlers
{ {
public class GreenshotFileFormatHandler : AbstractFileFormatHandler, IFileFormatHandler public class GreenshotFileFormatHandler : AbstractFileFormatHandler, IFileFormatHandler
{ {
protected override string[] OurExtensions { get; } = { ".greenshot" }; private readonly List<string> _ourExtensions = new() { ".greenshot" };
public GreenshotFileFormatHandler()
/// <inheritdoc />
public override IEnumerable<string> SupportedExtensions(FileFormatHandlerActions fileFormatHandlerAction)
{ {
if (fileFormatHandlerAction == FileFormatHandlerActions.LoadDrawableFromStream) SupportedExtensions[FileFormatHandlerActions.LoadDrawableFromStream] = _ourExtensions;
{ SupportedExtensions[FileFormatHandlerActions.LoadFromStream] = _ourExtensions;
return Enumerable.Empty<string>(); //SupportedExtensions[FileFormatHandlerActions.SaveToStream] = _ourExtensions;
}
return OurExtensions;
}
/// <inheritdoc />
public override bool Supports(FileFormatHandlerActions fileFormatHandlerAction, string extension)
{
if (fileFormatHandlerAction == FileFormatHandlerActions.SaveToStream)
{
return false;
}
return OurExtensions.Contains(NormalizeExtension(extension));
} }
public override bool TrySaveToStream(Bitmap bitmap, Stream destination, string extension) public override bool TrySaveToStream(Bitmap bitmap, Stream destination, string extension)

View file

@ -20,6 +20,7 @@
*/ */
using System; using System;
using System.Collections.Generic;
using System.Drawing; using System.Drawing;
using System.Drawing.Imaging; using System.Drawing.Imaging;
using System.IO; using System.IO;
@ -30,14 +31,19 @@ using log4net;
namespace Greenshot.Editor.FileFormatHandlers namespace Greenshot.Editor.FileFormatHandlers
{ {
/// <summary> /// <summary>
/// THis is the default .NET bitmap file format handler /// THis is the .ico format handler
/// </summary> /// </summary>
public class IconFileFormatHandler : AbstractFileFormatHandler, IFileFormatHandler public class IconFileFormatHandler : AbstractFileFormatHandler, IFileFormatHandler
{ {
private static readonly ILog Log = LogManager.GetLogger(typeof(IconFileFormatHandler)); private static readonly ILog Log = LogManager.GetLogger(typeof(IconFileFormatHandler));
protected override string[] OurExtensions { get; } = { ".ico" }; private readonly List<string> _ourExtensions = new() { ".ico" };
public IconFileFormatHandler()
{
SupportedExtensions[FileFormatHandlerActions.LoadDrawableFromStream] = _ourExtensions;
SupportedExtensions[FileFormatHandlerActions.LoadFromStream] = _ourExtensions;
}
public override bool TrySaveToStream(Bitmap bitmap, Stream destination, string extension) public override bool TrySaveToStream(Bitmap bitmap, Stream destination, string extension)
{ {

View file

@ -36,27 +36,12 @@ namespace Greenshot.Editor.FileFormatHandlers
/// </summary> /// </summary>
public class MetaFileFormatHandler : AbstractFileFormatHandler, IFileFormatHandler public class MetaFileFormatHandler : AbstractFileFormatHandler, IFileFormatHandler
{ {
protected override string[] OurExtensions { get; } = { ".wmf", ".emf" }; private readonly List<string> _ourExtensions = new (){ ".wmf", ".emf" };
public override IEnumerable<string> SupportedExtensions(FileFormatHandlerActions fileFormatHandlerAction) public MetaFileFormatHandler()
{ {
if (fileFormatHandlerAction == FileFormatHandlerActions.SaveToStream) SupportedExtensions[FileFormatHandlerActions.LoadDrawableFromStream] = _ourExtensions;
{ SupportedExtensions[FileFormatHandlerActions.LoadFromStream] = _ourExtensions;
return Enumerable.Empty<string>();
}
return OurExtensions;
}
/// <inheritdoc />
public override bool Supports(FileFormatHandlerActions fileFormatHandlerAction, string extension)
{
if (fileFormatHandlerAction == FileFormatHandlerActions.SaveToStream)
{
return false;
}
return OurExtensions.Contains(NormalizeExtension(extension));
} }
/// <inheritdoc /> /// <inheritdoc />

View file

@ -23,7 +23,6 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Drawing; using System.Drawing;
using System.IO; using System.IO;
using System.Linq;
using Greenshot.Base.Interfaces; using Greenshot.Base.Interfaces;
using Greenshot.Base.Interfaces.Drawing; using Greenshot.Base.Interfaces.Drawing;
using Greenshot.Editor.Drawing; using Greenshot.Editor.Drawing;
@ -38,28 +37,12 @@ namespace Greenshot.Editor.FileFormatHandlers
public class SvgFileFormatHandler : AbstractFileFormatHandler, IFileFormatHandler public class SvgFileFormatHandler : AbstractFileFormatHandler, IFileFormatHandler
{ {
private static readonly ILog Log = LogManager.GetLogger(typeof(SvgFileFormatHandler)); private static readonly ILog Log = LogManager.GetLogger(typeof(SvgFileFormatHandler));
protected override string[] OurExtensions { get; } = { ".svg" }; private readonly List<string> _ourExtensions = new() { ".svg" };
/// <inheritdoc /> public SvgFileFormatHandler()
public override IEnumerable<string> SupportedExtensions(FileFormatHandlerActions fileFormatHandlerAction)
{ {
if (fileFormatHandlerAction == FileFormatHandlerActions.SaveToStream) SupportedExtensions[FileFormatHandlerActions.LoadDrawableFromStream] = _ourExtensions;
{ SupportedExtensions[FileFormatHandlerActions.LoadFromStream] = _ourExtensions;
return Enumerable.Empty<string>();
}
return OurExtensions;
}
/// <inheritdoc />
public override bool Supports(FileFormatHandlerActions fileFormatHandlerAction, string extension)
{
if (fileFormatHandlerAction == FileFormatHandlerActions.SaveToStream)
{
return false;
}
return OurExtensions.Contains(NormalizeExtension(extension));
} }
public override bool TryLoadFromStream(Stream stream, string extension, out Bitmap bitmap) public override bool TryLoadFromStream(Stream stream, string extension, out Bitmap bitmap)

View file

@ -19,6 +19,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
using System.Collections.Generic;
using System.Drawing; using System.Drawing;
using System.IO; using System.IO;
using System.Windows.Media.Imaging; using System.Windows.Media.Imaging;
@ -28,11 +29,19 @@ using Greenshot.Base.Core;
namespace Greenshot.Editor.FileFormatHandlers namespace Greenshot.Editor.FileFormatHandlers
{ {
/// <summary> /// <summary>
/// This is the default .NET bitmap file format handler /// This is the System.Windows.Media.Imaging (WPF) file format handler
/// </summary> /// </summary>
public class WmpFileFormatHandler : AbstractFileFormatHandler, IFileFormatHandler public class WmpFileFormatHandler : AbstractFileFormatHandler, IFileFormatHandler
{ {
protected override string[] OurExtensions { get; } = { ".jxr", ".wdp", ".wmp" }; private List<string> LoadFromStreamExtensions { get; } = new() { ".jxr", ".wdp", ".wmp", ".heic", ".heif" };
private List<string> SaveToStreamExtensions { get; } = new() { ".jxr" };
public WmpFileFormatHandler()
{
SupportedExtensions[FileFormatHandlerActions.LoadDrawableFromStream] = LoadFromStreamExtensions;
SupportedExtensions[FileFormatHandlerActions.LoadFromStream] = LoadFromStreamExtensions;
SupportedExtensions[FileFormatHandlerActions.SaveToStream] = SaveToStreamExtensions;
}
/// <inheritdoc /> /// <inheritdoc />
public override bool TrySaveToStream(Bitmap bitmap, Stream destination, string extension) public override bool TrySaveToStream(Bitmap bitmap, Stream destination, string extension)
@ -57,8 +66,8 @@ namespace Greenshot.Editor.FileFormatHandlers
/// <inheritdoc /> /// <inheritdoc />
public override bool TryLoadFromStream(Stream stream, string extension, out Bitmap bitmap) public override bool TryLoadFromStream(Stream stream, string extension, out Bitmap bitmap)
{ {
var decoder = new WmpBitmapDecoder(stream, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.None); var bitmapDecoder = BitmapDecoder.Create(stream, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.None);
var bitmapSource = decoder.Frames[0]; var bitmapSource = bitmapDecoder.Frames[0];
bitmap = bitmapSource.ToBitmap(); bitmap = bitmapSource.ToBitmap();
return true; return true;
} }

View file

@ -36,6 +36,7 @@ using Greenshot.Base;
using Greenshot.Base.Controls; using Greenshot.Base.Controls;
using Greenshot.Base.Core; using Greenshot.Base.Core;
using Greenshot.Base.Core.Enums; using Greenshot.Base.Core.Enums;
using Greenshot.Base.Core.FileFormatHandlers;
using Greenshot.Base.Help; using Greenshot.Base.Help;
using Greenshot.Base.IniFile; using Greenshot.Base.IniFile;
using Greenshot.Base.Interfaces; using Greenshot.Base.Interfaces;
@ -936,9 +937,11 @@ namespace Greenshot.Forms
private void CaptureFile(IDestination destination = null) private void CaptureFile(IDestination destination = null)
{ {
var extensions = FileFormatHandlerRegistry.ExtensionsFor(FileFormatHandlerActions.LoadFromStream).Select(e => $"*{e}").ToList();
var openFileDialog = new OpenFileDialog 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) if (openFileDialog.ShowDialog() != DialogResult.OK)
{ {