Jump to content

FileType plugin: 'Unable to cast object' exception


Recommended Posts

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.

 

 

 

 

 

 

 

 

 

 

 

 

midoras signature.gif

Link to comment
Share on other sites

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 ...

The Paint.NET Blog: https://blog.getpaint.net/

Donations are always appreciated! https://www.getpaint.net/donate.html

forumSig_bmwE60.jpg

Link to comment
Share on other sites

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.

The Paint.NET Blog: https://blog.getpaint.net/

Donations are always appreciated! https://www.getpaint.net/donate.html

forumSig_bmwE60.jpg

Link to comment
Share on other sites

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

The Paint.NET Blog: https://blog.getpaint.net/

Donations are always appreciated! https://www.getpaint.net/donate.html

forumSig_bmwE60.jpg

Link to comment
Share on other sites

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.

midoras signature.gif

Link to comment
Share on other sites

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 ;-)

midoras signature.gif

Link to comment
Share on other sites

  • 2 months later...

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...