CodeWindowManager.cs :  » Development » StyleCop » Microsoft » VisualStudio » Package » C# / CSharp Open Source

Home
C# / CSharp Open Source
1.2.6.4 mono .net core
2.2.6.4 mono core
3.Aspect Oriented Frameworks
4.Bloggers
5.Build Systems
6.Business Application
7.Charting Reporting Tools
8.Chat Servers
9.Code Coverage Tools
10.Content Management Systems CMS
11.CRM ERP
12.Database
13.Development
14.Email
15.Forum
16.Game
17.GIS
18.GUI
19.IDEs
20.Installers Generators
21.Inversion of Control Dependency Injection
22.Issue Tracking
23.Logging Tools
24.Message
25.Mobile
26.Network Clients
27.Network Servers
28.Office
29.PDF
30.Persistence Frameworks
31.Portals
32.Profilers
33.Project Management
34.RSS RDF
35.Rule Engines
36.Script
37.Search Engines
38.Sound Audio
39.Source Control
40.SQL Clients
41.Template Engines
42.Testing
43.UML
44.Web Frameworks
45.Web Service
46.Web Testing
47.Wiki Engines
48.Windows Presentation Foundation
49.Workflows
50.XML Parsers
C# / C Sharp
C# / C Sharp by API
C# / CSharp Tutorial
C# / CSharp Open Source » Development » StyleCop 
StyleCop » Microsoft » VisualStudio » Package » CodeWindowManager.cs
using System;
using System.Collections;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Shell.Interop;
using Microsoft.VisualStudio.TextManager.Interop;
using OleMicrosoft.VisualStudio.OLE.Interop;
using IOleServiceProviderMicrosoft.VisualStudio.OLE.Interop.IServiceProvider;
using IServiceProviderSystem.IServiceProvider;

namespace Microsoft.VisualStudio.Package{
    /// <include file='doc\CodeWindowManager.uex' path='docs/doc[@for="CodeWindowManager"]/*' />
    /// <summary>
    /// CodeWindowManager provides a default implementation of the VSIP interface IVsCodeWindowManager
    /// and manages the LanguageService, Source, ViewFilter, and DocumentProperties objects associated
    /// with the given IVsCodeWindow.  It calls CreateViewFilter on your LanguageService for each new
    /// IVsTextView created by Visual Studio and installs the resulting filter into the command chain.
    /// You do not have to override this method, since a default view filter will be created.
    /// If your LanguageService returns an object from CreateDocumentProperties then you will have
    /// properties in the Properties Window associated with your source files.
    /// The CodeWindowManager also provides support for optional drop down combos in the IVsDropdownBar for 
    /// listing types and members by installing the TypeAndMemberDropdownBars object returned from your 
    /// LanguageService CreateDropDownHelper method.  The default return from CreateDropDownHelper is null, 
    /// which results in no drop down combos.
    /// </summary>
    [CLSCompliant(false)]
    [System.Runtime.InteropServices.ComVisible(true)]
    public class CodeWindowManager : IVsCodeWindowManager {
        TypeAndMemberDropdownBars dropDownHelper;
        IVsCodeWindow codeWindow;
        ArrayList viewFilters;
        LanguageService service;
        Source source;
        DocumentProperties properties;

        /// <include file='doc\CodeWindowManager.uex' path='docs/doc[@for="CodeWindowManager.CodeWindowManager"]/*' />
        /// <summary>
        /// The CodeWindowManager is constructed by the base LanguageService class when VS calls
        /// the IVsLanguageInfo.GetCodeWindowManager method.  You can override CreateCodeWindowManager
        /// on your LanguageService if you want to plug in a different CodeWindowManager.
        /// </summary>
        public CodeWindowManager(LanguageService service, IVsCodeWindow codeWindow, Source source) {
            this.service = service;
            this.codeWindow = codeWindow;
            this.viewFilters = new ArrayList();
            this.source = source;
            this.properties = service.CreateDocumentProperties(this);
        }

        /// <include file='doc\CodeWindowManager.uex' path='docs/doc[@for="TypeAndMemberDropdownBars.Finalize"]/*' />
        ~CodeWindowManager() {
#if  LANGTRACE
            Trace.WriteLine("~CodeWindowManager");
#endif
        }

        /// <include file='doc\CodeWindowManager.uex' path='docs/doc[@for="CodeWindowManager.Close"]/*' />
        /// <summary>Closes all view filters, and the document properties window</summary>
        public void Close() {
#if  LANGTRACE
            Trace.WriteLine("CodeWindowManager::Close");
#endif
            if (this.properties != null) this.properties.Close();
            CloseFilters();
            this.viewFilters = null;
            properties = null;
            service = null;
            source = null;
            this.codeWindow = null;
        }

        void CloseFilters() {
            if (this.viewFilters != null) {
                foreach (ViewFilter f in this.viewFilters) {
                    f.Close();
                }
                this.viewFilters.Clear();
            }
        }

        /// <include file='doc\CodeWindowManager.uex' path='docs/doc[@for="CodeWindowManager.LanguageService;"]/*' />
        /// <summary>Returns the LanguageService object that created this code window manager</summary>
        public LanguageService LanguageService {
            get { return this.service; }
        }
        /// <include file='doc\CodeWindowManager.uex' path='docs/doc[@for="CodeWindowManager.Source;"]/*' />
        /// <summary>returns the Source object associated with the IVsTextLines buffer for this code window</summary>
        public Source Source {
            get { return this.source; }
        }
        /// <include file='doc\CodeWindowManager.uex' path='docs/doc[@for="CodeWindowManager.GetFilter;"]/*' />
        /// <summary>
        /// Returns the ViewFilter for the given view or null if no matching filter is found.
        /// </summary>
        public ViewFilter GetFilter(IVsTextView view) {
            if (this.viewFilters != null) {
                foreach (ViewFilter f in this.viewFilters) {
                    if (f.TextView == view)
                        return f;
                }
            }
            return null;
        }

        /// <include file='doc\CodeWindowManager.uex' path='docs/doc[@for="CodeWindowManager.Properties;"]/*' />
        /// <summary>Returns the DocumentProperties, if any.  You can update this property if you want to 
        /// change the document properties on the fly.</summary>
        public DocumentProperties Properties {
            get { return this.properties; }
            set {
                if (this.properties != value) {
                    if (this.properties != null) this.properties.Close();
                    this.properties = value;
                    if (value != null) value.Refresh();
                }
            }
        }
        /// <include file='doc\CodeWindowManager.uex' path='docs/doc[@for="CodeWindowManager.DropDownHelper"]/*' />
        /// <summary>Return the optional TypeAndMemberDropdownBars object for the drop down combos</summary>
        public TypeAndMemberDropdownBars DropDownHelper {
            get { return this.dropDownHelper; }
        }
        /// <include file='doc\CodeWindowManager.uex' path='docs/doc[@for="CodeWindowManager.CodeWindow"]/*' />
        /// <summary>Return the IVsCodeWindow associated with this code window manager.</summary>
        public IVsCodeWindow CodeWindow {
            get { return this.codeWindow; }
        }
      
        #region IVsCodeWindowManager methods
        /// <include file='doc\CodeWindowManager.uex' path='docs/doc[@for="CodeWindowManager.AddAdornments"]/*' />
        /// <summary>Install the optional TypeAndMemberDropdownBars, and primary and secondary view filters</summary>
        public virtual int AddAdornments() {
#if  LANGTRACE
            Trace.WriteLine("CodeWindowManager::AddAdornments");
#endif
            int hr = 0;
            this.service.AddCodeWindowManager(this);

            this.source.Open();

            IVsTextView textView;
            NativeMethods.ThrowOnFailure(this.codeWindow.GetPrimaryView(out textView));

            this.dropDownHelper = this.service.CreateDropDownHelper(textView);
            if (this.dropDownHelper != null) {
                IVsDropdownBar pBar;
                IVsDropdownBarManager dbm = (IVsDropdownBarManager)this.codeWindow;
                int rc = dbm.GetDropdownBar(out pBar);
                if (rc == 0 && pBar != null)
                    NativeMethods.ThrowOnFailure(dbm.RemoveDropdownBar());
                //this.dropDownHelper = new TypeAndMemberDropdownBars(this.service);
                this.dropDownHelper.SynchronizeDropdowns(textView, 0, 0);
                NativeMethods.ThrowOnFailure(dbm.AddDropdownBar(2, this.dropDownHelper));
            }
            // attach view filter to primary view.
            if (textView != null)
                this.OnNewView(textView); // always returns S_OK.

            // attach view filter to secondary view.
            textView = null;
            hr = this.codeWindow.GetSecondaryView(out textView);
            if (hr == NativeMethods.S_OK && textView != null)
                this.OnNewView(textView); // always returns S_OK.

            return NativeMethods.S_OK;
        }

        /// <include file='doc\CodeWindowManager.uex' path='docs/doc[@for="CodeWindowManager.RemoveAdornments"]/*' />
        /// <summary>Remove drop down combos, view filters, and notify the LanguageService that the Source and
        /// CodeWindowManager is now closed</summary>
        public virtual int RemoveAdornments() {
#if  LANGTRACE
            Trace.WriteLine("CodeWindowManager::RemoveAdornments");
#endif
            try {
                if (this.dropDownHelper != null) {
                    IVsDropdownBarManager dbm = (IVsDropdownBarManager)this.codeWindow;
                    NativeMethods.ThrowOnFailure(dbm.RemoveDropdownBar());
                    this.dropDownHelper.Done();
                    this.dropDownHelper = null;
                }
            } finally {
                CloseFilters();

                if (this.source != null && this.source.Close()) {
                    this.service.OnCloseSource(this.source);
                    this.source.Dispose();
                }
                this.source = null;

                service.RemoveCodeWindowManager(this);
                this.codeWindow = null;
                this.Close();
            }
            return NativeMethods.S_OK;
        }

        /// <include file='doc\CodeWindowManager.uex' path='docs/doc[@for="CodeWindowManager.OnNewView"]/*' />
        /// <summary>Install a new view filter for the given view. This method calls your
        /// CreateViewFilter method.</summary>
        public virtual int OnNewView(IVsTextView newView) {
#if  LANGTRACE
            Trace.WriteLine("CodeWindowManager::OnNewView");
#endif
            ViewFilter filter = this.service.CreateViewFilter(this, newView);
            if (filter != null) this.viewFilters.Add(filter);
            return NativeMethods.S_OK;
        }

        /// <include file='doc\CodeWindowManager.uex' path='docs/doc[@for="CodeWindowManager.OnKillFocus"]/*' />
        public virtual void OnKillFocus(IVsTextView textView) {
        }

        /// <include file='doc\CodeWindowManager.uex' path='docs/doc[@for="CodeWindowManager.OnSetFocus"]/*' />
        /// <summary>Refresh the document properties</summary>
        public virtual void OnSetFocus(IVsTextView textView) {
            if (this.properties != null) {
                this.properties.Refresh();
            }
        }
        #endregion

    }



    /// <include file='doc\CodeWindowManager.uex' path='docs/doc[@for="TypeAndMemberDropdownBars"]/*' />
    /// <summary>
    /// Represents the two drop down bars on the top of a text editor window that allow 
    /// types and type members to be selected by name.
    /// </summary>
    [CLSCompliant(false)]
    public abstract class TypeAndMemberDropdownBars : IVsDropdownBarClient {
        /// <summary>The language service object that created this object and calls its SynchronizeDropdowns method</summary>
        private LanguageService languageService;

        /// <summary>The correspoding VS object that represents the two drop down bars. The VS object uses call backs to pull information from
        /// this object and makes itself known to this object by calling SetDropdownBar</summary>
        private IVsDropdownBar dropDownBar;

        /// <summary>The icons that prefix the type names and member signatures</summary>
        private ImageList imageList;

        /// <summary>The current text editor window</summary>
        private IVsTextView textView;

        /// <summary>The list of types that appear in the type drop down list.</summary>
        private ArrayList dropDownTypes;

        /// <summary>The list of types that appear in the member drop down list. </summary>
        private ArrayList dropDownMembers;

        private int selectedType = -1;
        private int selectedMember = -1;

        const int DropClasses = 0;
        const int DropMethods = 1;

        /// <include file='doc\CodeWindowManager.uex' path='docs/doc[@for="TypeAndMemberDropdownBars.TypeAndMemberDropdownBars"]/*' />
        protected TypeAndMemberDropdownBars(LanguageService languageService) {
            this.languageService = languageService;
            this.dropDownTypes = new ArrayList();
            this.dropDownMembers = new ArrayList();
        }

        /// <include file='doc\CodeWindowManager.uex' path='docs/doc[@for="TypeAndMemberDropdownBars.Done"]/*' />
        public void Done() { 
            if (this.imageList != null) {
                imageList.Dispose();
                imageList = null;
            }
        }


        internal void SynchronizeDropdowns(IVsTextView textView, int line, int col) {
            if (this.dropDownBar == null) return;
            this.textView = textView;
            if (OnSynchronizeDropdowns(languageService, textView, line, col, this.dropDownTypes, this.dropDownMembers, ref this.selectedType, ref this.selectedMember)) {
                NativeMethods.ThrowOnFailure(this.dropDownBar.RefreshCombo(TypeAndMemberDropdownBars.DropClasses, this.selectedType));
                NativeMethods.ThrowOnFailure(this.dropDownBar.RefreshCombo(TypeAndMemberDropdownBars.DropMethods, this.selectedMember));
            }
        }



        /// <include file='doc\CodeWindowManager.uex' path='docs/doc[@for="TypeAndMemberDropdownBars.OnSynchronizeDropdowns"]/*' />
        /// <summary>
        /// This method is called to update the drop down bars to match the current contents of the text editor window. 
        /// It is called during OnIdle when the caret position changes.  You can provide new drop down members here.
        /// It is up to you to sort the ArrayLists if you want them sorted in any particular order.
        /// </summary>
        /// <param name="languageService">The language service</param>
        /// <param name="textView">The editor window</param>
        /// <param name="line">The line on which the cursor is now positioned</param>
        /// <param name="col">The column on which the cursor is now position</param>
        /// <param name="dropDownTypes">The current list of types (you can update this)</param>
        /// <param name="dropDownMembers">The current list of members (you can update this)</param>
        /// <param name="selectedType">The selected type (you can update this)</param>
        /// <param name="selectedMember">The selected member (you can update this)</param>
        /// <returns>true if something was updated</returns>
        public abstract bool OnSynchronizeDropdowns(LanguageService languageService, IVsTextView textView, int line, int col, ArrayList dropDownTypes, ArrayList dropDownMembers, ref int selectedType, ref int selectedMember);


        // IVsDropdownBarClient methods
        /// <include file='doc\CodeWindowManager.uex' path='docs/doc[@for="TypeAndMemberDropdownBars.GetComboAttributes"]/*' />
        public virtual int GetComboAttributes(int combo, out uint entries, out uint entryType, out IntPtr iList) {
            entries = 0;
            entryType = 0;
            if (combo == TypeAndMemberDropdownBars.DropClasses && this.dropDownTypes != null)
                entries = (uint)this.dropDownTypes.Count;
            else if (this.dropDownMembers != null)
                entries = (uint)this.dropDownMembers.Count;
            entryType = (uint)(DropDownItemType.HasText | DropDownItemType.HasFontAttribute | DropDownItemType.HasImage);
            if (this.imageList == null)
                this.imageList = this.languageService.GetImageList();
            iList = this.imageList.Handle;
            return NativeMethods.S_OK;
        }

        private enum DropDownItemType {
            HasText = 1,
            HasFontAttribute = 2,
            HasImage = 4
        }

        /// <include file='doc\CodeWindowManager.uex' path='docs/doc[@for="TypeAndMemberDropdownBars.GetComboTipText"]/*' />
        public virtual int GetComboTipText(int combo, out string text) {
            if (combo == TypeAndMemberDropdownBars.DropClasses)
                text = SR.GetString(SR.ComboTypesTip);
            else
                text = SR.GetString(SR.ComboMembersTip);
            return NativeMethods.S_OK;
        }

        /// <include file='doc\CodeWindowManager.uex' path='docs/doc[@for="TypeAndMemberDropdownBars.GetEntryAttributes"]/*' />
        public virtual int GetEntryAttributes(int combo, int entry, out uint fontAttrs) {
            fontAttrs = (uint)DROPDOWNFONTATTR.FONTATTR_PLAIN;
            DropDownMember member = GetMember(combo, entry);
            if (member != null) {
                fontAttrs = (uint)member.FontAttr;
            }
            return NativeMethods.S_OK;
        }

        /// <include file='doc\CodeWindowManager.uex' path='docs/doc[@for="TypeAndMemberDropdownBars.GetEntryImage"]/*' />
        public virtual int GetEntryImage(int combo, int entry, out int imgIndex) {
            // this happens during drawing and has to be fast 
            imgIndex = -1;
            DropDownMember member = GetMember(combo, entry);
            if (member != null) {
                imgIndex = member.Glyph;
            }
            return NativeMethods.S_OK;
        }

        /// <include file='doc\CodeWindowManager.uex' path='docs/doc[@for="TypeAndMemberDropdownBars.GetEntryText"]/*' />
        public virtual int GetEntryText(int combo, int entry, out string text) {
            text = null;
            DropDownMember member = GetMember(combo, entry);
            if (member != null) {
                text = member.Label;
            }
            return NativeMethods.S_OK;
        }

        /// <include file='doc\CodeWindowManager.uex' path='docs/doc[@for="TypeAndMemberDropdownBars.OnComboGetFocus"]/*' />
        public virtual int OnComboGetFocus(int combo) {
            return NativeMethods.S_OK;
        }

        /// <include file='doc\CodeWindowManager.uex' path='docs/doc[@for="TypeAndMemberDropdownBars.GetMember"]/*' />
        public DropDownMember GetMember(int combo, int entry) {
            if (combo == TypeAndMemberDropdownBars.DropClasses) {
                if (this.dropDownTypes != null && entry >= 0 && entry < this.dropDownTypes.Count)
                    return (DropDownMember)this.dropDownTypes[entry];
            } else {
                if (this.dropDownMembers != null && entry >= 0 && entry < this.dropDownMembers.Count)
                    return (DropDownMember)this.dropDownMembers[entry];
            }
            return null;
        }

        /// <include file='doc\CodeWindowManager.uex' path='docs/doc[@for="TypeAndMemberDropdownBars.OnItemChosen"]/*' />
        public virtual int OnItemChosen(int combo, int entry) {
            DropDownMember member = GetMember(combo, entry);

            if (member != null && this.textView != null) {
                int line = member.Span.iStartLine;
                int col = member.Span.iStartIndex;
                try {
                    // Here we don't want to throw or to check the return value.
                    textView.CenterLines(line, 16);
                } catch (COMException) { }
                NativeMethods.ThrowOnFailure(this.textView.SetCaretPos(line, col));
                NativeMethods.SetFocus(this.textView.GetWindowHandle());
                this.SynchronizeDropdowns(this.textView, line, col);
            }
            return NativeMethods.S_OK;
        }

        /// <include file='doc\CodeWindowManager.uex' path='docs/doc[@for="TypeAndMemberDropdownBars.SetFocus"]/*' />
        [DllImport("user32.dll")]
        static extern void SetFocus(IntPtr hwnd);

        /// <include file='doc\CodeWindowManager.uex' path='docs/doc[@for="TypeAndMemberDropdownBars.OnItemSelected"]/*' />
        public virtual int OnItemSelected(int combo, int index) {
            //nop
            return NativeMethods.S_OK;
        }

        /// <include file='doc\CodeWindowManager.uex' path='docs/doc[@for="TypeAndMemberDropdownBars.SetDropdownBar"]/*' />
        public virtual int SetDropdownBar(IVsDropdownBar bar) {
            this.dropDownBar = bar;
            return NativeMethods.S_OK;
        }
    }

    /// <include file='doc\CodeWindowManager.uex' path='docs/doc[@for="DropDownMember"]/*' />
    [CLSCompliant(false)]
    public class DropDownMember : IComparable {

        private string label;
        private TextSpan span;
        private int glyph;
        private DROPDOWNFONTATTR fontAttr;

        /// <include file='doc\CodeWindowManager.uex' path='docs/doc[@for="DropDownMember.Label;"]/*' />
        public string Label {
            get {
                return this.label;
            }
            set {
                this.label = value;
            }
        }

        /// <include file='doc\CodeWindowManager.uex' path='docs/doc[@for="DropDownMember.Span;"]/*' />
        public TextSpan Span {
            get {
                return this.span;
            }
            set {
                this.span = value;
            }
        }
        /// <include file='doc\CodeWindowManager.uex' path='docs/doc[@for="DropDownMember.Glyph;"]/*' />
        public int Glyph {
            get {
                return this.glyph;
            }
            set {
                this.glyph = value;
            }
        }
        /// <include file='doc\CodeWindowManager.uex' path='docs/doc[@for="DropDownMember.FontAttr;"]/*' />
        public DROPDOWNFONTATTR FontAttr {
            get {
                return this.fontAttr;
            }
            set {
                this.fontAttr = value;
            }
        }

        /// <include file='doc\CodeWindowManager.uex' path='docs/doc[@for="DropDownMember.DropDownMember"]/*' />
        public DropDownMember(string label, TextSpan span, int glyph, DROPDOWNFONTATTR fontAttribute) {
            if (label == null) {
                throw new ArgumentNullException("label");
            }
            this.Label = label;
            this.Span = span;
            this.Glyph = glyph;
            this.FontAttr = fontAttribute;
        }

        /// <include file='doc\CodeWindowManager.uex' path='docs/doc[@for="DropDownMember.CompareTo"]/*' />
        public int CompareTo(object obj) {
            // if this overload is used then it assumes a case-sensitive current culture comparison
            // which allows for case-senstive languages to work
            return CompareTo(obj, StringComparison.CurrentCulture);
        }

        /// <include file='doc\CodeWindowManager.uex' path='docs/doc[@for="DropDownMember.CompareTo"]/*' />
        public int CompareTo(object obj, StringComparison stringComparison)
        {
            if (obj is DropDownMember)
            {
                return String.Compare(this.Label, ((DropDownMember)obj).Label, stringComparison);
            }
            return -1;
        }

        // Omitting Equals violates FxCop rule: IComparableImplementationsOverrideEquals.
        /// <include file='doc\CodeWindowManager.uex' path='docs/doc[@for="DropDownMember.Equals"]/*' />
        public override bool Equals(Object obj) {
            if (!(obj is DropDownMember))
                return false;
            return (this.CompareTo(obj, StringComparison.CurrentCulture) == 0);
        }

        // Omitting getHashCode violates FxCop rule: EqualsOverridesRequireGetHashCodeOverride.
        /// <include file='doc\CodeWindowManager.uex' path='docs/doc[@for="DropDownMember.GetHashCode"]/*' />
        public override int GetHashCode() {
            return this.Label.GetHashCode();
        }


        // Omitting any of the following operator overloads
        // violates FxCop rule: IComparableImplementationsOverrideOperators.
        /// <include file='doc\CodeWindowManager.uex' path='docs/doc[@for="DropDownMember.Operator=="]/*' />
        public static bool operator ==(DropDownMember m1, DropDownMember m2) {
            if (object.Equals(null, m1)) {
                return object.Equals(null, m2);
            }
            return m1.Equals(m2);
        }
        /// <include file='doc\CodeWindowManager.uex' path='docs/doc[@for="DropDownMember.Operator!="]/*' />
        public static bool operator !=(DropDownMember m1, DropDownMember m2) {
            return !(m1 == m2);
        }
        /// <include file='doc\CodeWindowManager.uex' path='docs/doc[@for="DropDownMember.OperatorMT"]/*' />
        public static bool operator <(DropDownMember m1, DropDownMember m2) {
            if (null == m1) {
                // Assume null < anything else and == null.
                return (null != m2);
            }
            else if (null == m2) {
                return false;
            }
            return (m1.CompareTo(m2, StringComparison.CurrentCulture) < 0);
        }
        /// <include file='doc\CodeWindowManager.uex' path='docs/doc[@for="DropDownMember.OperatorGT"]/*' />
        public static bool operator >(DropDownMember m1, DropDownMember m2) {
            if (null == m1) {
                // Assume null < anything else and == null.
                return false;
            }
            else if (null == m2) {
                return true;
            }
            return (m1.CompareTo(m2, StringComparison.CurrentCulture) > 0);
        }
    }
}
www.java2v.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.