midora Posted July 16, 2013 Share Posted July 16, 2013 Maybe someone could point me in the right direction to fix this exception System.InvalidCastException: Unable to cast object of type 'PaintDotNet.SaveConfigToken' to type 'OptionBased.FileTypes.OptionBasedSaveConfigToken'. at PaintDotNet.SaveConfigWidget`2.InitWidgetFromToken(SaveConfigToken sourceToken) in D:\src\pdn\pdn_35x\src\Data\SaveConfigWidget`2.cs:line 52 at PaintDotNet.Dialogs.SaveConfigDialog.set_FileType(FileType value) in D:\src\pdn\pdn_35x\src\PaintDotNet\Dialogs\SaveConfigDialog.cs:line 346 at PaintDotNet.Controls.DocumentWorkspace.GetSaveConfigToken(FileType currentFileType, SaveConfigToken currentSaveConfigToken, SaveConfigToken& newSaveConfigToken, Surface saveScratchSurface) in D:\src\pdn\pdn_35x\src\PaintDotNet\Controls\DocumentWorkspace.cs:line 1877 at PaintDotNet.Controls.DocumentWorkspace.DoSave(Boolean tryToFlatten) in D:\src\pdn\pdn_35x\src\PaintDotNet\Controls\DocumentWorkspace.cs:line 2266 at PaintDotNet.Menus.FileMenu.MenuFileSave_Click(Object sender, EventArgs e) in D:\src\pdn\pdn_35x\src\PaintDotNet\Menus\FileMenu.cs:line 245 at System.Windows.Forms.ToolStripItem.RaiseEvent(Object key, EventArgs e) at System.Windows.Forms.ToolStripMenuItem.OnClick(EventArgs e) at PaintDotNet.Menus.PdnMenuItem.OnClick(EventArgs e) in D:\src\pdn\pdn_35x\src\PaintDotNet\Menus\PdnMenuItem.cs:line 302 at System.Windows.Forms.ToolStripItem.HandleClick(EventArgs e) at PaintDotNet.Menus.PdnMenuItem.OnShortcutKeyPressed(Keys keys) in D:\src\pdn\pdn_35x\src\PaintDotNet\Menus\PdnMenuItem.cs:line 174 at PaintDotNet.PdnBaseForm.ProcessFormHotKey(Keys keyData) in D:\src\pdn\pdn_35x\src\Core\PdnBaseForm.cs:line 791 at PaintDotNet.PdnBaseForm.ProcessCmdKeyData(Keys keyData) in D:\src\pdn\pdn_35x\src\Core\PdnBaseForm.cs:line 846 at PaintDotNet.PdnBaseForm.ProcessCmdKey(Message& msg, Keys keyData) in D:\src\pdn\pdn_35x\src\Core\PdnBaseForm.cs:line 829 at System.Windows.Forms.Control.ProcessCmdKey(Message& msg, Keys keyData) at System.Windows.Forms.ContainerControl.ProcessCmdKey(Message& msg, Keys keyData) at System.Windows.Forms.Control.ProcessCmdKey(Message& msg, Keys keyData) at System.Windows.Forms.Control.ProcessCmdKey(Message& msg, Keys keyData) at System.Windows.Forms.ContainerControl.ProcessCmdKey(Message& msg, Keys keyData) at PaintDotNet.Controls.DocumentView.ProcessCmdKey(Message& msg, Keys keyData) in D:\src\pdn\pdn_35x\src\PaintDotNet\Controls\DocumentView.cs:line 1318 at System.Windows.Forms.Control.ProcessCmdKey(Message& msg, Keys keyData) at System.Windows.Forms.Control.PreProcessMessage(Message& msg) at System.Windows.Forms.Control.PreProcessControlMessageInternal(Control target, Message& msg) at System.Windows.Forms.Application.ThreadContext.PreTranslateMessage(MSG& msg) I created a new abstract filetype OptionBasedFileType and derived SvgTinyFileType from it. SvgTinyFileType does not set SupportsSaving. Loading works fine but using File->Save (via menu or keyboard) throws the above exception. There are two issue now: 1) Why does 'Save' not fall back to 'Save As' if SupportsSaving is not set 2) Why is there this cast exception Here the code of OptionBasedFileType namespace OptionBased.FileTypes { using System; using System.IO; using System.Reflection; using PaintDotNet; using OptionControls; using ControlExtensions; #if false internal class TestFileType : OptionBasedFileType { protected override void OnSaveT(Document input, Stream output, OptionBasedSaveConfigToken token, Surface scratchSurface, ProgressEventHandler progressCallback) { } protected override Document OnLoad(Stream input) { return null; } internal TestFileType() : base( "OBF - Example", 0 //| FileTypeFlags.SupportsLayers //| FileTypeFlags.SupportsCustomHeaders //| FileTypeFlags.SupportsSaving | FileTypeFlags.SupportsLoading //| FileTypeFlags.SavesWithProgress , new[] { ".obf" }) { } } #endif public sealed class OptionBasedSaveConfigToken : SaveConfigToken { // ... } public sealed class OptionBasedSaveConfigWidget : SaveConfigWidget<OptionBasedFileType, OptionBasedSaveConfigToken> { // ... protected override void InitWidgetFromToken(OptionBasedSaveConfigToken sourceToken) { // ... } protected override OptionBasedSaveConfigToken CreateTokenFromWidget() { // ... return new OptionBasedSaveConfigToken(); } public OptionBasedSaveConfigWidget(FileType fileType) : base(fileType) { } } public abstract class OptionBasedFileType : FileType<OptionBasedSaveConfigToken, OptionBasedSaveConfigWidget> { protected override sealed OptionBasedSaveConfigToken OnCreateDefaultSaveConfigTokenT() { return new OptionBasedSaveConfigToken(); } protected override sealed OptionBasedSaveConfigWidget OnCreateSaveConfigWidgetT() { return new OptionBasedSaveConfigWidget(this); } public OptionContext Context { get; private set; } internal OptionBasedFileType(OptionContext context, FileTypeFlags flags, string[] extensions) : base(context.GetTranslatedText(context.Id), flags, extensions) { Context = context; } protected OptionBasedFileType(Type type, FileTypeFlags flags, string[] extensions) : this(OptionContext.GetContext(type.Name, Assembly.GetCallingAssembly()), flags, extensions) { } } } BTW: It would be nice if Paint.NET would add the plugin to Utilities->View Plugin Load Errors if Paint.NET fails to load a filetype plugin. Quote Link to comment Share on other sites More sharing options...
Rick Brewster Posted July 18, 2013 Share Posted July 18, 2013 I'm still trying to figure out what's going on here ... (not ignoring this thread in other words) One thing to note is that using the FileType<...> and SaveConfigWidget<...> classes only gets you the benefit of compile-time type safety. They don't provide extra functionality, in other words (as far as I remember). For troubleshooting you might see if using the base FileType + SaveConfigWidget gets you anywhere. I don't know how/why, but you never know ... Quote The Paint.NET Blog: https://blog.getpaint.net/ Donations are always appreciated! https://www.getpaint.net/donate.html Link to comment Share on other sites More sharing options...
Rick Brewster Posted July 18, 2013 Share Posted July 18, 2013 Actually I bet you anything you aren't overriding SaveConfigToken.Clone(). The pattern for tokens is that they have a "copy constructor." You'll need to override Clone to say "new MyTokenType(this)". Then you have a constructor that takes MyTokenType, passes it to the base constructor (which takes a SaveConfigToken), and then in your code you copy over all of your stuff. It's a pattern that works very well, but only if you know that you're supposed to do it. I haven't look at this code in a long time but I remember that I couldn't find a good way to enforce this pattern at compile time. Quote The Paint.NET Blog: https://blog.getpaint.net/ Donations are always appreciated! https://www.getpaint.net/donate.html Link to comment Share on other sites More sharing options...
Rick Brewster Posted July 18, 2013 Share Posted July 18, 2013 As for this, you'll have to describe what happens in more detail. (Okay you told me it doesn't revert to Save As, ... so what does it do?) 1) Why does 'Save' not fall back to 'Save As' if SupportsSaving is not set Quote The Paint.NET Blog: https://blog.getpaint.net/ Donations are always appreciated! https://www.getpaint.net/donate.html Link to comment Share on other sites More sharing options...
midora Posted July 19, 2013 Author Share Posted July 19, 2013 As for this, you'll have to describe what happens in more detail. (Okay you told me it doesn't revert to Save As, ... so what does it do?) Paint.NET crashes if you are pressing Ctrl-S after loading an image using this file type (ImSVGTiny). But only if this image is the active one. I would expect a fallback to Save as if the SupportSaving flag is not set. Means it should not touch the SaveToken at all even if the implementation is not correct as you mentioned. Quote Link to comment Share on other sites More sharing options...
midora Posted July 19, 2013 Author Share Posted July 19, 2013 Overriding the Clone method avoids the crash. Thanks. Still there is no fallback to SaveAs. Means the Save dialog opens in error state because my OnSaveT throws NotImplementedException(). Pressing Ok shows an error as expected. This 'unspecified' one ;-) Quote Link to comment Share on other sites More sharing options...
Rick Brewster Posted July 19, 2013 Share Posted July 19, 2013 I've filed a bug for that, for 4.0. Quote The Paint.NET Blog: https://blog.getpaint.net/ Donations are always appreciated! https://www.getpaint.net/donate.html Link to comment Share on other sites More sharing options...
Rick Brewster Posted September 30, 2013 Share Posted September 30, 2013 This is now fixed for 4.0 (the part about saving after opening via a FileType which doesn't support saving) Quote The Paint.NET Blog: https://blog.getpaint.net/ Donations are always appreciated! https://www.getpaint.net/donate.html Link to comment Share on other sites More sharing options...
midora Posted October 1, 2013 Author Share Posted October 1, 2013 Thanks. Sounds like fine-tuning of a christmas version ;-) Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.