locked
Cannot get custom editor to use the provisional tab. RRS feed

  • Question

  • Hi,

    I cannot get my custom editor working with the new provisional tab in VS11.

    My Editor is defined on the package as
    [ProvideEditorExtension(typeof(MyEditorFactory), ".my", 50)]

    And my EditorFactory looks like this
    [Guid("7e574ed2-97f6-4594-b7f3-a403f8056443")
    public sealed class MyEditorFactory : IVsEditorFactory
    {
        public int SetSite(Microsoft.VisualStudio.OLE.Interop.IServiceProvider psp)
        {           
            return VSConstants.S_OK;
        }

        public int MapLogicalView(ref Guid rguidLogicalView, out string pbstrPhysicalView)
        {
            pbstrPhysicalView = null;
            return VSConstants.S_OK;
        }

        public int Close()
        {
            return VSConstants.S_OK;
        }

        [SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)]
        public int CreateEditorInstance(
                        uint grfCreateDoc,
                        string streamName,
                        string streamID,
                        IVsHierarchy pvHier,
                        uint itemid,
                        System.IntPtr punkDocDataExisting,
                        out System.IntPtr ppunkDocView,
                        out System.IntPtr ppunkDocData,
                        out string pbstrEditorCaption,
                        out Guid pguidCmdUI,
                        out int pgrfCDW)
        {
            ppunkDocView = IntPtr.Zero;
            ppunkDocData = IntPtr.Zero;
            pguidCmdUI = new Guid("7e574ed2-97f6-4594-b7f3-a403f8056443");
            pgrfCDW = 0;
            pbstrEditorCaption = null; // allows extensions in the tab name like "[Design]"

            // validate inputs
            if ((grfCreateDoc & (VSConstants.CEF_OPENFILE | VSConstants.CEF_SILENT)) == 0)
            {
                return VSConstants.E_INVALIDARG;
            }
            if (punkDocDataExisting != IntPtr.Zero)
            {
                return VSConstants.VS_E_INCOMPATIBLEDOCDATA;
            }

            var editor = new MyEditorPane();
            editor.StreamId = streamID;
            var iu = Marshal.GetIUnknownForObject(editor);
            Debug.Assert(iu.ToInt64() > 0, "docview is not valid");
            ppunkDocView =
            ppunkDocData = iu;
           
            return VSConstants.S_OK;
        }
    }

    Everything works perfectly fine when I open .my files normally:
    var dte = (DTE)this.GetService(typeof(SDTE));
    dte.ItemOperations.OpenFile(fullpath, Constants.vsViewKindAny);

    But if I try to execute the same code within the provisional scope like this:
    using (new NewDocumentStateScope(__VSNEWDOCUMENTSTATE.NDS_Provisional, VSConstants.NewDocumentStateReason.Navigation))
    {
        var dte = (DTE)this.GetService(typeof(SDTE));
     dte.ItemOperations.OpenFile(fullpath, Constants.vsViewKindAny);
    }

    Then my CreateEditorInstance method does not get called and the OpenFile call fails with a COMException "Operation aborted (Exception from HRESULT: 0x80004004 (E_ABORT))". I cannot get any more details out of the ActivityLog.

    The OpenFile operation is called from within a spearate ToolWindow, but I doubt that this will cause an issue!?
    I also tried to provide a LogicalView for my editor, without any effect:
    [ProvideEditorLogicalView(typeof(MyEditorFactory), VSConstants.LOGVIEWID.Any_string, IsTrusted = true)]


    Can someone have any idea, why that isn't working?
    Is there a more detailed documentation regarding the provisional tab out there?

    Cheers,
    Rainier


    A programmer ia a tool to convert coffein to code.

    Friday, February 8, 2013 7:54 PM

Answers

  • Hi Rainier,

    As you’ve discovered, editors are not able to participate in the preview tab by default.  The editor needs to declare that it supports preview by specifying appropriate attributes for the physical view(s) it offers.

    The easiest way to do this is to set the CommonPhysicalViewAttributes property of the ProvideEditorFactory attribute.  The property can be a combination of one or more of these flags:

    enum __VSPHYSICALVIEWATTRIBUTES
    {
        PVA_None = 0x00000000,

        // The physical view may open slowly.  "Slow" in this sense means anything longer
        // than approximately two seconds, and the time to consider starts when the editor
        // is created and ends when the UI thread is no longer blocked.  If the editor
        // takes longer than two seconds to load its file or fully render its content, but
        // that activity takes place on a background thread and doesn't block the UI thread,
        // the non-blocking activity does not need to be considered when assessing slowness.
        PVA_OpensSlowly = 0x00000001,

        // The physical view supports being hosted in a preview tab (i.e. it is a document
        // window, not tool window, modal dialog, etc.).
        PVA_SupportsPreview = 0x00000002,
    };

    PVA_OpensSlowly will prevent the editor from being used to preview files where responsiveness is important.  An example of this is previewing the selected item in Solution Explorer.  It will only preview files whose editors have PVA_SupportsPreview but do not have PVA_OpensSlowly.

    Regards,
    Jeff Robison [MSFT]

    Friday, February 8, 2013 10:34 PM

All replies

  • Hi Rainier,

    As you’ve discovered, editors are not able to participate in the preview tab by default.  The editor needs to declare that it supports preview by specifying appropriate attributes for the physical view(s) it offers.

    The easiest way to do this is to set the CommonPhysicalViewAttributes property of the ProvideEditorFactory attribute.  The property can be a combination of one or more of these flags:

    enum __VSPHYSICALVIEWATTRIBUTES
    {
        PVA_None = 0x00000000,

        // The physical view may open slowly.  "Slow" in this sense means anything longer
        // than approximately two seconds, and the time to consider starts when the editor
        // is created and ends when the UI thread is no longer blocked.  If the editor
        // takes longer than two seconds to load its file or fully render its content, but
        // that activity takes place on a background thread and doesn't block the UI thread,
        // the non-blocking activity does not need to be considered when assessing slowness.
        PVA_OpensSlowly = 0x00000001,

        // The physical view supports being hosted in a preview tab (i.e. it is a document
        // window, not tool window, modal dialog, etc.).
        PVA_SupportsPreview = 0x00000002,
    };

    PVA_OpensSlowly will prevent the editor from being used to preview files where responsiveness is important.  An example of this is previewing the selected item in Solution Explorer.  It will only preview files whose editors have PVA_SupportsPreview but do not have PVA_OpensSlowly.

    Regards,
    Jeff Robison [MSFT]

    Friday, February 8, 2013 10:34 PM
  • Wow, I would never have figured that out on my own. Thanks a lot! It's working perfectly now.

    A programmer ia a tool to convert coffein to code.

    Saturday, February 9, 2013 9:58 AM