Browse Source

Merge pull request #404 from PixiEditor/save-file-fix

Fix crash when saving a file with a filename ending in .mod
Egor Mozgovoy 3 years ago
parent
commit
934555fbe2
2 changed files with 53 additions and 20 deletions
  1. 12 3
      PixiEditor/Helpers/SupportedFilesHelper.cs
  2. 41 17
      PixiEditor/Models/IO/Exporter.cs

+ 12 - 3
PixiEditor/Helpers/SupportedFilesHelper.cs

@@ -1,5 +1,4 @@
-using PixiEditor.Models;
-using PixiEditor.Models.Enums;
+using PixiEditor.Models.Enums;
 using PixiEditor.Models.IO;
 using System;
 using System.Collections.Generic;
@@ -21,7 +20,7 @@ namespace PixiEditor.Helpers
             allFileTypeDialogsData = new List<FileTypeDialogData>();
 
             var allFormats = Enum.GetValues(typeof(FileType)).Cast<FileType>().ToList();
-            
+
             foreach (var format in allFormats)
             {
                 var fileTypeDialogData = new FileTypeDialogData(format);
@@ -75,6 +74,16 @@ namespace PixiEditor.Helpers
             return filter;
         }
 
+        public static FileType GetSaveFileTypeFromFilterIndex(bool includePixi, int filterIndex)
+        {
+            var allSupportedExtensions = GetAllSupportedFileTypes(includePixi);
+            //filter index starts at 1 for some reason
+            int index = filterIndex - 1;
+            if (allSupportedExtensions.Count <= index)
+                return FileType.Unset;
+            return allSupportedExtensions[index].FileType;
+        }
+
         public static string BuildOpenFilter()
         {
             var any = new FileTypeDialogDataSet(FileTypeDialogDataSet.SetKind.Any).GetFormattedTypes();

+ 41 - 17
PixiEditor/Models/IO/Exporter.cs

@@ -7,11 +7,9 @@ using PixiEditor.Models.Enums;
 using SkiaSharp;
 using System;
 using System.Collections.Generic;
-using System.Drawing.Imaging;
 using System.IO;
 using System.IO.Compression;
 using System.Linq;
-using System.Reflection;
 using System.Runtime.InteropServices;
 using System.Windows;
 using System.Windows.Media.Imaging;
@@ -30,11 +28,14 @@ namespace PixiEditor.Models.IO
             SaveFileDialog dialog = new SaveFileDialog
             {
                 Filter = SupportedFilesHelper.BuildSaveFilter(true),
-                FilterIndex = 0
+                FilterIndex = 0,
+                DefaultExt = "pixi"
+
             };
             if ((bool)dialog.ShowDialog())
             {
-                path = SaveAsEditableFile(document, dialog.FileName);
+                FileType filetype = SupportedFilesHelper.GetSaveFileTypeFromFilterIndex(true, dialog.FilterIndex);
+                path = SaveAsEditableFile(document, dialog.FileName, filetype);
                 return true;
             }
 
@@ -48,15 +49,28 @@ namespace PixiEditor.Models.IO
         /// <param name="document">Document to be saved.</param>
         /// <param name="path">Path where to save file.</param>
         /// <returns>Path.</returns>
-        public static string SaveAsEditableFile(Document document, string path)
+        public static string SaveAsEditableFile(Document document, string path, FileType requestedType = FileType.Unset)
         {
-            if (Path.GetExtension(path) != Constants.NativeExtension)
+            var typeFromPath = ParseImageFormat(Path.GetExtension(path));
+            FileType finalType = (typeFromPath, requestedType) switch
+            {
+                (FileType.Unset, FileType.Unset) => FileType.Pixi,
+                (var first, FileType.Unset) => first,
+                (FileType.Unset, var second) => second,
+                _ => typeFromPath,
+            };
+
+            if (typeFromPath == FileType.Unset)
+            {
+                path = AppendExtension(path, SupportedFilesHelper.GetFileTypeDialogData(finalType));
+            }
+
+            if (finalType != FileType.Pixi)
             {
-                var chosenFormat = ParseImageFormat(Path.GetExtension(path));
                 var bitmap = document.Renderer.FinalBitmap;
-                SaveAs(encodersFactory[chosenFormat](), path, bitmap.PixelWidth, bitmap.PixelHeight, bitmap);
+                SaveAs(encodersFactory[finalType](), path, bitmap.PixelWidth, bitmap.PixelHeight, bitmap);
             }
-            else if(Directory.Exists(Path.GetDirectoryName(path)))
+            else if (Directory.Exists(Path.GetDirectoryName(path)))
             {
                 Parser.PixiParser.Serialize(ParserHelpers.ToSerializable(document), path);
             }
@@ -68,6 +82,16 @@ namespace PixiEditor.Models.IO
             return path;
         }
 
+        private static string AppendExtension(string path, FileTypeDialogData data)
+        {
+            string ext = data.Extensions.First();
+            string filename = Path.GetFileName(path);
+            if (filename.Length + ext.Length > 255)
+                filename = filename.Substring(0, 255 - ext.Length);
+            filename += ext;
+            return Path.Combine(Path.GetDirectoryName(path), filename);
+        }
+
         public static FileType ParseImageFormat(string extension)
         {
             return SupportedFilesHelper.ParseImageFormat(extension);
@@ -79,7 +103,7 @@ namespace PixiEditor.Models.IO
         {
             encodersFactory[FileType.Png] = () => new PngBitmapEncoder();
             encodersFactory[FileType.Jpeg] = () => new JpegBitmapEncoder();
-            encodersFactory[FileType.Bmp] = () => new BmpBitmapEncoder(); 
+            encodersFactory[FileType.Bmp] = () => new BmpBitmapEncoder();
             encodersFactory[FileType.Gif] = () => new GifBitmapEncoder();
         }
 
@@ -90,14 +114,14 @@ namespace PixiEditor.Models.IO
         /// <param name="fileDimensions">Size of file.</param>
         public static void Export(WriteableBitmap bitmap, Size fileDimensions)
         {
-          ExportFileDialog info = new ExportFileDialog(fileDimensions);
+            ExportFileDialog info = new ExportFileDialog(fileDimensions);
 
-          // If OK on dialog has been clicked
-          if (info.ShowDialog())
-          {
-            if(encodersFactory.ContainsKey(info.ChosenFormat))
-              SaveAs(encodersFactory[info.ChosenFormat](), info.FilePath, info.FileWidth, info.FileHeight, bitmap);
-          }
+            // If OK on dialog has been clicked
+            if (info.ShowDialog())
+            {
+                if (encodersFactory.ContainsKey(info.ChosenFormat))
+                    SaveAs(encodersFactory[info.ChosenFormat](), info.FilePath, info.FileWidth, info.FileHeight, bitmap);
+            }
         }
         public static void SaveAsGZippedBytes(string path, Surface surface)
         {