Click here to Skip to main content
15,893,668 members
Articles / Desktop Programming / Windows Forms

Diagrams with Reflector and the Graph Plug-in (Part 2)

Rate me:
Please Sign up or sign in to vote.
4.27/5 (7 votes)
23 Feb 2009CPOL6 min read 35.2K   1.1K   38  
Graphing other dependencies, without Reflector now.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Reflection;
using System.Text;
using System.Windows.Forms;

using Refractor.Common;
using WeifenLuo.WinFormsUI.Docking;

namespace Refractor
{
    public class WindowManager : IServiceProvider, IWindowManager 
    {
        public object GetService(Type serviceType)
        {
            if (serviceType == typeof(WindowManager))
                return this;

            if (serviceType == typeof(IWindowManager))
                return this as IWindowManager;

            if (serviceType == typeof(IStatusManager))
                return _statusManager as IStatusManager;

            if (serviceType == typeof(ILogView))
                return _logView as ILogView;

            if (serviceType == typeof(IProjectBrowser))
                return _projectBrowser as IProjectBrowser;

            if (serviceType == typeof(IMenuManager))
                return _menuManager as IMenuManager;

            _logView.LogStr("ERROR : GetService failed on type : " + serviceType.Name);

            return null;
        }

        public void SetActiveItem(BaseItem item, object sender)
        {
            // todo? get rid of this, passthrough to project manager, and then back.
            // better to have pm control it all anyhow?
            _projectBrowser.SetActiveItem(item, sender);
        }

        public PluginOptions GetPluginOptions(string pluginID)
        {
            return _pluginManager.GetPluginOptions(pluginID);
        }

        
        private LogView _logView;
        internal LogView Logger { get { return _logView; } }
        
        private DockPanel _dockPanel;
        internal DockPanel DockPanel { get { return _dockPanel; } }

        private ProjectBrowser _projectBrowser;
        internal ProjectBrowser ProjectBrowser { get { return _projectBrowser; } }

        private StatusManager _statusManager;
        internal IStatusManager StatusManager { get { return _statusManager; } }

        private MenuManager _menuManager;
        internal MenuManager MenuManager { get { return _menuManager; } }

        private Dictionary<string, DockContent> _windows = new Dictionary<string, DockContent>();
        internal Dictionary<string, DockContent> Windows { get { return _windows; } }

        private FavouritesBrowser _favouritesBrowser;
        internal FavouritesBrowser Favourites { get { return _favouritesBrowser; } }

        private HistoryBrowser _historyBrowser;
        internal HistoryBrowser History { get { return _historyBrowser; } }

        private PluginManager _pluginManager;
        internal PluginManager PluginManager { get { return _pluginManager; } }

        internal ApplicationOptions AppOptions;


        internal WindowManager(MainForm form, DockPanel dockPanel, StatusStrip statusStrip, MenuStrip menuStrip)
        {
            _mainForm = form;

            _dockPanel = dockPanel;

            _statusManager = new StatusManager(this, statusStrip);
            _menuManager = new MenuManager(this, menuStrip);

            _logView = new LogView(this);
            _projectBrowser = new ProjectBrowser(this);
            _projectBrowser.OnFilesChanged += new EventHandler(_projectBrowser_OnFilesChanged);
            _favouritesBrowser = new FavouritesBrowser(this);
            _historyBrowser = new HistoryBrowser(this);
        }

        internal void Init()
        {
            _logView.Clear();
            _logView.LogStr("Refractor starts at " + DateTime.Now.ToString());

            // Update our resource helper.
            Common.ResourceHelper.CheckAssembly(Assembly.GetExecutingAssembly());

            // Load plugins.
            _pluginManager = new PluginManager(this);
            _pluginManager.LoadPlugins();

            // Set File Dialogs.
            _ofdFiles = new OpenFileDialog();
            _ofdFiles.InitialDirectory = Application.ExecutablePath;

            _ofdFiles.Filter = GetFilterString();

            _ofdFiles.FilterIndex = 1;
            _ofdFiles.RestoreDirectory = false;
            _ofdFiles.Multiselect = true;

            _ofdProject = new OpenFileDialog();
            _ofdProject.InitialDirectory = Application.ExecutablePath;
            _ofdProject.Filter = "Project files (*.rfp)|*.rfp|All files (*.*)|*.*";
            _ofdProject.FilterIndex = 1;
            _ofdProject.RestoreDirectory = false;

            _sfd = new SaveFileDialog();
            _sfd.InitialDirectory = Application.ExecutablePath;
            _sfd.DefaultExt = ".rpf";
            _sfd.RestoreDirectory = true;

            // Load main app options.
            LoadApplicationOptions();
        }

        internal void Finish()
        {
            SaveApplicationOptions();

            _logView.LogStr("Refractor ends at " + DateTime.Now.ToString());
        }

        internal IDockContent GetContentFromPersistString(string persistString)
        {
            if (persistString == _projectBrowser.GetType().ToString())
                return _projectBrowser;

            if (persistString == _logView.GetType().ToString())
                return _logView;

            if (persistString == _favouritesBrowser.GetType().ToString())
                return _favouritesBrowser;

            if (persistString == _historyBrowser.GetType().ToString())
                return _historyBrowser;

            foreach (KeyValuePair<string, DockContent> pair in _windows)
            {
                if (persistString == pair.Value.GetType().ToString())
                    return pair.Value;
            }

            return null;
        }

        internal void OpenFilesDialog()
        {
            if (_ofdFiles.ShowDialog() == DialogResult.OK)
            {
                _projectBrowser.Show(this.DockPanel);
                _projectBrowser.AddFiles(_ofdFiles.FileNames);
            }
        }

        internal void OpenProjectDialog()
        {
            if (_ofdProject.ShowDialog() == DialogResult.OK)
            {
                _projectBrowser.LoadProject(_ofdProject.FileName, false);
            }
        }

        internal void SaveProjectDialog()
        {
            if (_sfd.ShowDialog() == DialogResult.OK)
            {
                _projectBrowser.SaveProject(_sfd.FileName);
            }
        }


        internal void AddPlugin(string id, DockContent control, bool isDefault)
        {
            if (_windows.ContainsKey(id))
            {
                _logView.LogStr("ERROR : Failed to get unique window id");
                return;
            }

            _windows.Add(id, control);

            // Attach the on visible handler, which may be responsible for
            // calling the update.
            control.VisibleChanged += new EventHandler(Window_VisibleChanged);
        }

        internal void UpdateWindow(IWindowPlugin plugin)
        {
            string id = plugin.GetID();

            if (!_windows.ContainsKey(id))
            {
                _logView.LogStr("ERROR : UpdatePlugin failed to find plugin : " + id);
                return;
            }

            _windows[id] = (DockContent)plugin;
        }

        internal void RemovePlugin(string id)
        {
            if (!_windows.ContainsKey(id)) return;

            DockContent window = _windows[id];

            _windows.Remove(id);
        }

        internal void UpdatePluginItem(IWindowPlugin plugin, BaseItem item)
        {
            CachedSet(plugin as DockContent, item, false);            
        }

        internal void BroadcastItemChange(object sender, BaseItem item)
        {
            foreach (KeyValuePair<string, DockContent> pair in _windows)
            {
                if (pair.Value is IActiveItemViewer)
                {
                    if (pair.Value is IWindowPlugin)
                    {
                        List<Type> types = (pair.Value as IWindowPlugin).GetHandledTypes();

                        if (item == null)
                        {
                            CachedSet(pair.Value, item, true);
                        }
                        else if (types != null && types.Contains(item.GetType()))
                        {
                            BaseItem currentItem = (pair.Value as IActiveItemViewer).GetActiveItem();

                            if (item != currentItem)
                            {
                                CachedSet(pair.Value, item, false);
                            }
                        }                        
                    }
                }
            }
        }

        internal void BroadcastRefresh(object sender, BaseItem item)
        {
            foreach (KeyValuePair<string, DockContent> pair in _windows)
            {
                if (pair.Value is IActiveItemViewer)
                {
                    if (pair.Value is IWindowPlugin)
                    {
                        CachedSetRefresh(pair.Value, item);
                    }
                }
            }
        }

        internal void SetWindowItems(List<string> windowNames, List<string> itemIds)
        {
            // Set current items for all the windows.
            foreach (KeyValuePair<string, DockContent> pair in _windows)
            {
                // These are dealt with by the project browser files changed event.
                if ((pair.Value as IWindowPlugin).GetKind() == WindowPluginKind.MainWindow)
                    continue;

                int idx = windowNames.IndexOf(pair.Key);

                if (idx > -1)
                {
                    BaseItem item = _projectBrowser.Lookup(itemIds[idx]);

                    CachedSet(pair.Value, item, false);
                }
            }
        }

        internal void GetWindowItems(List<string> windowNames, List<string> itemIds)
        {
            // Get the current items for all the windows.
            windowNames.Clear();
            itemIds.Clear();


            foreach (KeyValuePair<string, DockContent> pair in _windows)
            {
                try
                {
                    if (pair.Value is IActiveItemViewer)
                    {
                        BaseItem item = (pair.Value as IActiveItemViewer).GetActiveItem();

                        if (item != null)
                        {
                            windowNames.Add(pair.Key);
                            itemIds.Add(item.GetID());
                        }
                    }
                }
                catch (Exception exc)
                {
                    if (_logView.LogCatchAll(exc, "Unexpected plugin error")) throw;
                }
            }
        }

        internal void SetCaption(string caption)
        {
            if (string.IsNullOrEmpty(caption))
                _mainForm.Text = "Refractor";
            else
                _mainForm.Text = "Refractor [" + caption + "]";
        }


        private MainForm _mainForm;
        private OpenFileDialog _ofdFiles;
        private OpenFileDialog _ofdProject;
        private SaveFileDialog _sfd;
        private Dictionary<DockContent, BaseItem> _activeItems = new Dictionary<DockContent, BaseItem>();
        private Dictionary<DockContent, BaseItem> _activeItemsRefresh = new Dictionary<DockContent, BaseItem>();
        private Dictionary<Type, DockContent> _defaults = new Dictionary<Type, DockContent>();
        private object _lock = new object();

        private void Window_VisibleChanged(object sender, EventArgs e)
        {
            if (!(sender is IActiveItemViewer)) return;
            if (!(sender is DockContent)) return;

            DockContent window = (sender as DockContent);
            if (!window.Visible) return;

            if (!_activeItems.ContainsKey(sender as DockContent)) return;                            

            SetItemInternal(window, _activeItems[window]);
        }

        private void CachedSet(DockContent window, BaseItem item, bool force)
        {
            // Add or get from local storage.
            if (!_activeItems.ContainsKey(window))
            {
                _activeItems.Add(window, item);
            }
            else
            {
                _activeItems[window] = item;
            }

            // Set immediately if visible or force, otherwise set in VisibleChanged.
            if (force || window.Visible)
            {
                SetItemInternal(window, item);
            }
        }

        private void CachedSetRefresh(DockContent window, BaseItem item)
        {
            // Add or get from local storage.
            if (!_activeItemsRefresh.ContainsKey(window))
            {
                _activeItemsRefresh.Add(window, item);
            }
            else
            {
                _activeItemsRefresh[window] = item;
            }

            // Set immediately if visible, otherwise set in VisibleChanged.
            if (window.Visible)
            {
                SetItemRefreshInternal(window, item);
            }
        }

        private void SetItemInternal(DockContent window, BaseItem item)
        {
            try
            {
                IActiveItemViewer viewer = window as IActiveItemViewer;
                IWindowPlugin plugin = window as IWindowPlugin;

                // Always set a main window plugin, but only set others if they've changed.
                if (plugin.GetKind() == WindowPluginKind.MainWindow ||
                    viewer.GetActiveItem() != item)
                {
                    viewer.SetActiveItem(item);
                }
            }
            catch (Exception exc)
            {
                if (_logView.LogCatchAll(exc, "Unexpected plugin error")) throw;
            }                        
        }

        private void SetItemRefreshInternal(DockContent window, BaseItem item)
        {
            try
            {
                IActiveItemViewer viewer = window as IActiveItemViewer;
                IWindowPlugin plugin = window as IWindowPlugin;

                viewer.SetRefresh(item);
            }
            catch (Exception exc)
            {
                if (_logView.LogCatchAll(exc, "Unexpected plugin error")) throw;
            }
        }

        
        private void _projectBrowser_OnFilesChanged(object sender, EventArgs e)
        {
            BaseItem item = sender as RootItem;
            if (item == null) return;

            // Set current items for all the windows, MainWindow plugins only.
            foreach (KeyValuePair<string, DockContent> pair in _windows)
            {
                if ((pair.Value as IWindowPlugin).GetKind() != WindowPluginKind.MainWindow)
                    continue;

                CachedSet(pair.Value, item, false);
            }
        }
        
        private string GetFilterString()
        {
            StringBuilder sb = new StringBuilder("All files (*.*)|*.*|");
            List<string> allHandled = new List<string>();
            foreach (IParserPlugin plugin in _pluginManager.ParserPlugins)
            {
                try
                {
                    List<string> exts = plugin.HandlesExtensions();
                    
                    sb.Append(plugin.GetID());
                    
                    sb.Append(" (");
                    for (int i = 0; i < exts.Count; i++)
                    {
                        sb.Append("*");
                        sb.Append(exts[i]);
                        if (i < exts.Count - 1) sb.Append(";");
                    }
                    sb.Append(")|");
                    for (int i = 0; i < exts.Count; i++)
                    {
                        sb.Append("*");
                        sb.Append(exts[i]);
                        if (i < exts.Count - 1) sb.Append(";");
                    }
                    sb.Append("|");

                    for (int i = 0; i < exts.Count; i++)
                    {
                        if (!allHandled.Contains(exts[i])) 
                            allHandled.Add(exts[i]);
                    }
                }
                catch (Exception exc)
                {
                    if (_logView.LogCatchAll(exc, "Unexpected plugin error")) throw;
                }
            }

            sb.Append("All handled types (");
            for (int i = 0; i < allHandled.Count; i++)
            {
                sb.Append("*");
                sb.Append(allHandled[i]);
                if (i < allHandled.Count - 1) sb.Append(";");
            }
            sb.Append(")|");
            for (int i = 0; i < allHandled.Count; i++)
            {
                sb.Append("*");
                sb.Append(allHandled[i]);
                if (i < allHandled.Count - 1) sb.Append(";");
            }

            string result = sb.ToString();
            return result;
        }


        private void LoadApplicationOptions()
        {
            string appConfigFilename = Application.ExecutablePath + ".xml";
            if (File.Exists(appConfigFilename))
            {
                try
                {
                    string s = File.ReadAllText(Application.ExecutablePath + ".xml");
                    Hwd.Serialization.Decoder decoder = new Hwd.Serialization.Decoder();
                    AppOptions = (ApplicationOptions)decoder.Decode(s);
                }
                catch (Hwd.Serialization.SerializationException exc)
                {
                    _logView.LogExcStr(exc, "Failed deserializing application options");
                }
            }
            else
            {
                AppOptions = new ApplicationOptions();
            }

            if (AppOptions == null)
            {
                AppOptions = new ApplicationOptions();
            }

            // Apply UI settings to project browser.
            ProjectBrowser.TreeView.Columns[0].Width = AppOptions.ProjectCol0Width;
            ProjectBrowser.TreeView.Columns[1].Width = AppOptions.ProjectCol1Width;
            ProjectBrowser.TreeView.Columns[2].Width = AppOptions.ProjectCol2Width;
            ProjectBrowser.TreeView.Columns[3].Width = AppOptions.ProjectCol3Width;

            // Set the plugin options.
            PluginManager.SetAllOptions(
                AppOptions.PluginOptions,
                AppOptions.PluginParserOptions);
        }

        private void SaveApplicationOptions()
        {
            // Update the options from the UI.
            AppOptions.ProjectFilename = ProjectBrowser.ProjectFilename;
            AppOptions.ProjectCol0Width = ProjectBrowser.TreeView.Columns[0].Width;
            AppOptions.ProjectCol1Width = ProjectBrowser.TreeView.Columns[1].Width;
            AppOptions.ProjectCol2Width = ProjectBrowser.TreeView.Columns[2].Width;
            AppOptions.ProjectCol3Width = ProjectBrowser.TreeView.Columns[3].Width;

            // Update the options from the plugins.
            PluginManager.GetAllOptions(
                AppOptions.PluginOptions,
                AppOptions.PluginParserOptions);

            
            string appConfigFilename = Application.ExecutablePath + ".xml";
            try
            {
                Hwd.Serialization.Encoder encoder = new Hwd.Serialization.Encoder();
                string s = encoder.Encode(AppOptions);
                File.WriteAllText(appConfigFilename, s);
            }
            catch (Hwd.Serialization.SerializationException exc)
            {
                _logView.LogExcStr(exc, "Failed serializing application options");
            }
        }


    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Web Developer
United Kingdom United Kingdom
hughdoar@hotmail.com

Comments and Discussions