Click here to Skip to main content
15,885,278 members
Articles / Programming Languages / C#

SharpPrivacy - OpenPGP for C#

Rate me:
Please Sign up or sign in to vote.
4.92/5 (86 votes)
7 Jun 200314 min read 353.4K   8.4K   227  
SharpPrivacy is an OpenPGP implementation in C#. It can be used to encrypt and sign data, created OpenPGP compatible keys, and a lot more. This article explains how to use the library in your own .NET application or webpage to encrypt, sign, decrypt or verify OpenPGP messages.
// *****************************************************************************
// 
//  (c) Crownwood Consulting Limited 2002-2003
//  All rights reserved. The software and associated documentation 
//  supplied hereunder are the proprietary information of Crownwood Consulting 
//	Limited, Crownwood, Bracknell, Berkshire, England and are supplied subject 
//  to licence terms.
// 
//  Magic Version 1.7.4.0 	www.dotnetmagic.com
// *****************************************************************************

using System;
using System.IO;
using System.Xml;
using System.Text;
using System.Drawing;
using System.Windows.Forms;
using System.ComponentModel;
using System.Xml.Serialization;
using Microsoft.Win32;
using Crownwood.Magic.Menus;
using Crownwood.Magic.Common;
using Crownwood.Magic.Docking;
using Crownwood.Magic.Collections;

namespace Crownwood.Magic.Docking
{
    public enum PropogateName
    {
        BackColor,
        ActiveColor,
        ActiveTextColor,
        InactiveTextColor,
        ResizeBarColor,
        ResizeBarVector,
        CaptionFont,
		TabControlFont,
        ZoneMinMax,
        PlainTabBorder
    }

    public class DockingManager
    {
        // Instance fields
        protected bool _zoneMinMax;
        protected bool _insideFill;
        protected bool _autoResize;
        protected bool _firstHalfWidth;
        protected bool _firstHalfHeight;
        protected int _surpressVisibleEvents;
        protected int _resizeBarVector;
        protected Size _innerMinimum;
        protected Color _backColor;
        protected Color _activeColor;
        protected Color _activeTextColor;
        protected Color _inactiveTextColor;
        protected Color _resizeBarColor;
        protected Font _captionFont;
		protected Font _tabControlFont;
        protected bool _defaultBackColor;
        protected bool _defaultActiveColor;
        protected bool _defaultActiveTextColor;
        protected bool _defaultInactiveTextColor;
        protected bool _defaultResizeBarColor;
        protected bool _defaultCaptionFont;
		protected bool _defaultTabControlFont;
        protected bool _plainTabBorder;
        protected Control _innerControl;
        protected Control _outerControl;
        protected AutoHidePanel _ahpTop;
        protected AutoHidePanel _ahpLeft;
        protected AutoHidePanel _ahpBottom;
        protected AutoHidePanel _ahpRight;
        protected VisualStyle _visualStyle;
        protected ContainerControl _container;
        protected ManagerContentCollection _contents;

        public delegate void ContentHandler(Content c, EventArgs cea);
        public delegate void ContentHidingHandler(Content c, CancelEventArgs cea);
        public delegate void ContextMenuHandler(PopupMenu pm, CancelEventArgs cea);
		public delegate void TabControlCreatedHandler(Magic.Controls.TabControl tabControl);
		public delegate void SaveCustomConfigHandler(XmlTextWriter xmlOut);
        public delegate void LoadCustomConfigHandler(XmlTextReader xmlIn);

        // Exposed events
        public event ContentHandler ContentShown;
        public event ContentHandler ContentHidden;
        public event ContentHidingHandler ContentHiding;
        public event ContextMenuHandler ContextMenu;
		public event TabControlCreatedHandler TabControlCreated;
		public event SaveCustomConfigHandler SaveCustomConfig;
        public event LoadCustomConfigHandler LoadCustomConfig;

        public DockingManager(ContainerControl container, VisualStyle vs)
        {
            // Must provide a valid container instance
            if (container == null)
                throw new ArgumentNullException("Container");

            // Default state
            _container = container;
            _visualStyle = vs;
            _innerControl = null;
			_zoneMinMax = true;
			_insideFill = false;
			_autoResize = true;
			_firstHalfWidth = true;
			_firstHalfHeight = true;
			_plainTabBorder = false;
			_surpressVisibleEvents = 0;
			_innerMinimum = new Size(20, 20);
	
            // Default font/resize
			_resizeBarVector = -1;
			_captionFont = SystemInformation.MenuFont;
			_tabControlFont = SystemInformation.MenuFont;
			_defaultCaptionFont = true;
			_defaultTabControlFont = true;

			// Create and add hidden auto hide panels
			AddAutoHidePanels();

            // Define initial colors
            ResetColors();

            // Create an object to manage the collection of Content
            _contents = new ManagerContentCollection(this);

            // We want notification when contents are removed/cleared
            _contents.Clearing += new CollectionClear(OnContentsClearing);
            _contents.Removed += new CollectionChange(OnContentRemoved);

			// We want to perform special action when container is resized
			_container.Resize += new EventHandler(OnContainerResized);
			
			// A Form can cause the child controls to be reordered after the initialisation
			// but before the Form.Load event. To handle this we hook into the event and force
			// the auto hide panels to be ordered back into their proper place.
			if (_container is Form)
			{   
			    Form formContainer = _container as Form;			    
			    formContainer.Load += new EventHandler(OnFormLoaded);
			}

            // Need notification when colors change
            Microsoft.Win32.SystemEvents.UserPreferenceChanged += new UserPreferenceChangedEventHandler(OnPreferenceChanged);
        }

        public ContainerControl Container
        {
            get { return _container; }
        }

        public Control InnerControl
        {
            get { return _innerControl; }
            set { _innerControl = value; }
        }

        public Control OuterControl
        {
            get { return _outerControl; }
            set 
			{
			    if (_outerControl != value)
			    {
				    _outerControl = value;
				    
				    // Use helper routine to ensure panels are in correct positions
                    ReorderAutoHidePanels();
		        }
			}
        }

        public ManagerContentCollection Contents
        {
            get { return _contents; }
			
            set 
            {
                _contents.Clear();
                _contents = value;	
            }
        }

		public bool ZoneMinMax
		{
			get { return _zoneMinMax; }

			set 
			{ 
			    if (value != _zoneMinMax)
			    {
			        _zoneMinMax = value;
                
                    // Notify each object in docking hierarchy in case they need to know new value
                    PropogateNameValue(PropogateName.ZoneMinMax, (object)_zoneMinMax);
                } 
			}
		}

		public bool InsideFill
		{
			get { return _insideFill; }

			set
			{
				if (_insideFill != value)
				{
					_insideFill = value;

					if (_insideFill)
					{
					    // Add Fill style to innermost docking window
						AddInnerFillStyle();
			        }
					else
					{
					    // Remove Fill style from innermost docking window
						RemoveAnyFillStyle();
						
						// Ensure that inner control can be seen
                        OnContainerResized(null, EventArgs.Empty);
					}
				}
			}
		}

		public bool AutoResize
		{
			get { return _autoResize; }
			set { _autoResize = value; }
		}

		public Size InnerMinimum
		{
			get { return _innerMinimum; }
			set { _innerMinimum = value; }
		}

        public VisualStyle Style
        {
            get { return _visualStyle; }
        }

        public int ResizeBarVector
        {
            get { return _resizeBarVector; }
            
            set 
            {
                if (value != _resizeBarVector)
                {
                    _resizeBarVector = value;
                    
                    // Notify each object in docking hierarchy in case they need to know new value
                    PropogateNameValue(PropogateName.ResizeBarVector, (object)_resizeBarVector);
                }
            }
        }

        public Color BackColor
        {
            get { return _backColor; }
            
            set 
            {
                if (value != _backColor)
                {
                    _backColor = value;
                    _defaultBackColor = (_backColor == SystemColors.Control);
                    
                    // Notify each object in docking hierarchy in case they need to know new value
                    PropogateNameValue(PropogateName.BackColor, (object)_backColor);
                }
            }
        }
    
        public Color ActiveColor
        {
            get { return _activeColor; }
            
            set 
            {
                if (value != _activeColor)
                {
                    _activeColor = value;
                    _defaultActiveColor = (_activeColor == SystemColors.ActiveCaption);
                    
                    // Notify each object in docking hierarchy in case they need to know new value
                    PropogateNameValue(PropogateName.ActiveColor, (object)_activeColor);
                }
            }
        }
        
        public Color ActiveTextColor
        {
            get { return _activeTextColor; }
            
            set 
            {
                if (value != _activeTextColor)
                {
                    _activeTextColor = value;
                    _defaultActiveTextColor = (_activeTextColor == SystemColors.ActiveCaptionText);
                    
                    // Notify each object in docking hierarchy in case they need to know new value
                    PropogateNameValue(PropogateName.ActiveTextColor, (object)_activeTextColor);
                }
            }
        }

        public Color InactiveTextColor
        {
            get { return _inactiveTextColor; }
            
            set 
            {
                if (value != _inactiveTextColor)
                {
                    _inactiveTextColor = value;
                    _defaultInactiveTextColor = (_inactiveTextColor == SystemColors.ControlText);
                    
                    // Notify each object in docking hierarchy in case they need to know new value
                    PropogateNameValue(PropogateName.InactiveTextColor, (object)_inactiveTextColor);
                }
            }
        }

        public Color ResizeBarColor
        {
            get { return _resizeBarColor; }
            
            set 
            {
                if (value != _resizeBarColor)
                {
                    _resizeBarColor = value;
                    _defaultResizeBarColor = (_resizeBarColor == SystemColors.Control);
                    
                    // Notify each object in docking hierarchy in case they need to know new value
                    PropogateNameValue(PropogateName.ResizeBarColor, (object)_resizeBarColor);
                }
            }
        }
        
        public Font CaptionFont
        {
            get { return _captionFont; }
            
            set 
            {
                if (value != _captionFont)
                {
                    _captionFont = value;
                    _defaultCaptionFont = (_captionFont == SystemInformation.MenuFont);
                    
                    // Notify each object in docking hierarchy in case they need to know new value
                    PropogateNameValue(PropogateName.CaptionFont, (object)_captionFont);
                }
            }
        }

        public Font TabControlFont
        {
            get { return _tabControlFont; }
            
            set 
            {
                if (value != _tabControlFont)
                {
                    _tabControlFont = value;
                    _defaultTabControlFont = (_captionFont == SystemInformation.MenuFont);
                    
                    // Notify each object in docking hierarchy in case they need to know new value
                    PropogateNameValue(PropogateName.TabControlFont, (object)_tabControlFont);
                }
            }
        }

        public bool PlainTabBorder
        {
            get { return _plainTabBorder; }
            
            set 
            {
                if (value != _plainTabBorder)
                {
                    _plainTabBorder = value;
                    
                    // Notify each object in docking hierarchy in case they need to know new value
                    PropogateNameValue(PropogateName.PlainTabBorder, (object)_plainTabBorder);
                }
            }
        }

        public void ResetColors()
        {
            _backColor = SystemColors.Control;
            _inactiveTextColor = SystemColors.ControlText;
            _activeColor = SystemColors.ActiveCaption;
            _activeTextColor = SystemColors.ActiveCaptionText;
            _resizeBarColor = SystemColors.Control;
            _defaultBackColor = true;
            _defaultActiveColor = true;
            _defaultActiveTextColor = true;
            _defaultInactiveTextColor = true;
            _defaultResizeBarColor = true;

            PropogateNameValue(PropogateName.BackColor, (object)_backColor);
            PropogateNameValue(PropogateName.ActiveColor, (object)_activeColor);
            PropogateNameValue(PropogateName.ActiveTextColor, (object)_activeTextColor);
            PropogateNameValue(PropogateName.InactiveTextColor, (object)_inactiveTextColor);
            PropogateNameValue(PropogateName.ResizeBarColor, (object)_resizeBarColor);
        }

        public void UpdateInsideFill()
		{
			// Is inside fill ability enabled?
			if (_insideFill)
			{
				// Reduce flicker
				_container.SuspendLayout();
				
				// Ensure correct zone has the Fill style
				RemoveAnyFillStyle();
				AddInnerFillStyle();

				_container.ResumeLayout();
			}
		}

		public virtual bool ToggleContentAutoHide(Content c)
		{
			// Content must be visible
			if (!c.Visible)
				return false;

			// Content is not allows to be floating
			// (if visible then content must have a valiud ParentWindowContent)
			if (c.ParentWindowContent.State == State.Floating)
				return false;

			// Is the content currently in auto hide mode?
			if (c.ParentWindowContent.ParentZone == null)
			{
				// Find the hosting panel for the window content instance
				AutoHidePanel ahp = AutoHidePanelForState(c.ParentWindowContent.State);
				
				// Ask the panel to un-autohide
				ahp.InvertAutoHideWindowContent(c.ParentWindowContent as WindowContentTabbed);
			}
			else
			{
				// No, so inform the window content to become auto hidden now
				InvertAutoHideWindowContent(c.ParentWindowContent);
			}

			// Success!
			return true;
		}

		public virtual bool ShowContent(Content c)
		{
            // Validate the incoming Content instance is a valid reference
            // and is a current instance within our internal collection
            if ((c == null) || !_contents.Contains(c))
                return false;
		
			// Remove it from view by removing from current WindowContent container
            if (!c.Visible)
			{
                // Do not generate hiding/hidden/shown events
                _surpressVisibleEvents++;

                // Manageing Zones should remove display AutoHide windows
                RemoveShowingAutoHideWindows();
                               
                // Use the assigned restore object to position the Content appropriately
				if (c.Docked)
				{
				    if (c.AutoHidden)
				        c.AutoHideRestore.PerformRestore(this);
				    else
					    c.DockingRestore.PerformRestore(this);
			    }
				else
					c.FloatingRestore.PerformRestore(this);

                // Enable generation hiding/hidden/shown events
                _surpressVisibleEvents--;

                // Generate event
				OnContentShown(c);

				return true;
			}
			else
				return false;
		}

		public virtual void ShowAllContents()
		{
			_container.SuspendLayout();

			foreach(Content c in _contents)
				ShowContent(c);

			UpdateInsideFill();

			_container.ResumeLayout();
		}

		public virtual void HideContent(Content c)
		{
			HideContent(c, true, true);
		}

		public virtual void HideContent(Content c, bool record, bool reorder)
		{
            // Remove it from view by removing from current WindowContent container
            if (c.Visible)
            {
                // Do not generate hiding/hidden/shown events
                _surpressVisibleEvents++;

                // Manageing Zones should remove display AutoHide windows
                RemoveShowingAutoHideWindows();
                
                if (record)
				{
					// Tell the Content to create a new Restore object to record its current location
					c.RecordRestore();
				}

                if (c.AutoHidden)
                {
                    // Remove it from its current AutoHidePanel
                    c.AutoHidePanel.RemoveContent(c);
                }
                else
                {
                    // Remove the Content from its current WindowContent
                    c.ParentWindowContent.Contents.Remove(c);
                }
                
				if (reorder)
				{
					// Move the Content to the start of the list
					_contents.SetIndex(0, c); 
				}

				UpdateInsideFill();

                // Enable generation hiding/hidden/shown events
                _surpressVisibleEvents--;
                
                // Generate event
				OnContentHidden(c);
            }
		}

		public virtual void HideAllContents()
		{
			_container.SuspendLayout();

			int count = _contents.Count;

			// Hide in reverse order so that a ShowAll in forward order gives accurate restore
			for(int index=count-1; index>=0; index--)
			{
			    // Cannot hide something already hidden
			    if (_contents[index].Visible)
			    {
                    // Generate event
                    if (!OnContentHiding(_contents[index]))
                    {
                        HideContent(_contents[index], true, false);
                    }
                }
		    }

			UpdateInsideFill();

			_container.ResumeLayout();
		}

        public virtual Window CreateWindowForContent(Content c)
        {
            return CreateWindowForContent(c, new EventHandler(OnContentClose), 
										     new EventHandler(OnRestore),
                                             new EventHandler(OnInvertAutoHide),
                                             new ContextHandler(OnShowContextMenu));
        }

        public virtual Window CreateWindowForContent(Content c,
                                                     EventHandler contentClose,
                                                     EventHandler restore,
                                                     EventHandler invertAutoHide,
                                                     ContextHandler showContextMenu)
        {
            // Create new instance with correct style
            WindowContent wc = new WindowContentTabbed(this, _visualStyle);

            WindowDetailCaption wdc;

            // Create a style specific caption detail
            if (_visualStyle == VisualStyle.IDE)
                wdc = new WindowDetailCaptionIDE(this, contentClose, restore,
                                                 invertAutoHide, showContextMenu);
            else
                wdc = new WindowDetailCaptionPlain(this, contentClose, restore,
                                                   invertAutoHide, showContextMenu);

            // Add the caption to the window display
            wc.WindowDetails.Add(wdc);

            if (c != null)
            {
                // Add provided Content to this instance
                wc.Contents.Add(c);
            }

            return wc;
        }    
            
        public virtual Zone CreateZoneForContent(State zoneState)
        {
			return CreateZoneForContent(zoneState, _container);
		}

        protected virtual Zone CreateZoneForContent(State zoneState, ContainerControl destination)
        {
            DockStyle ds;
            Direction direction;

            // Find relevant values dependant on required state
            ValuesFromState(zoneState, out ds, out direction);

            // Create a new ZoneSequence which can host Content
            ZoneSequence zs = new ZoneSequence(this, zoneState, _visualStyle, direction, _zoneMinMax);

            // Set the appropriate docking style
            zs.Dock = ds;

			if (destination != null)
			{
				// Add this Zone to the display
				destination.Controls.Add(zs);
			}

            return zs;
        }

        public WindowContent AddContentWithState(Content c, State newState)
        {
            // Validate the incoming Content instance is a valid reference
            // and is a current instance within our internal collection
            if ((c == null) || !_contents.Contains(c))
                return null;
		
            // Do not generate hiding/hidden/shown events
            _surpressVisibleEvents++;

            // Manageing Zones should remove display AutoHide windows
            RemoveShowingAutoHideWindows();
                
            // Is the window already part of a WindowContent?
            if (c.ParentWindowContent != null)
            {
				// If it used to be in a floating mode, then record state change
				if (c.ParentWindowContent.ParentZone.State == State.Floating)
					c.ContentLeavesFloating();

                // Remove the Content from its current WindowContent
                c.ParentWindowContent.Contents.Remove(c);
            }

            // Create a new Window instance appropriate for hosting a Content object
            Window w = CreateWindowForContent(c);

			ContainerControl destination = null;

	        if (newState != State.Floating)
			{
				destination = _container;
		        destination.SuspendLayout();
			}

            // Create a new Zone capable of hosting a WindowContent
            Zone z = CreateZoneForContent(newState, destination);

	        if (newState == State.Floating)
			{
			    // Content is not in the docked state
			    c.Docked = false;
			
				// destination a new floating form
				destination = new FloatingForm(this, z, new ContextHandler(OnShowContextMenu));

				// Define its location
				destination.Location = c.DisplayLocation;
				
				// ...and its size, add the height of the caption bar to the requested content size
				destination.Size = new Size(c.FloatingSize.Width, 
				                            c.FloatingSize.Height + SystemInformation.ToolWindowCaptionHeight);
			}
			
            // Add the Window to the Zone
            z.Windows.Add(w);

	        if (newState != State.Floating)
			{
				// Set the Zone to be the least important of our Zones
				ReorderZoneToInnerMost(z);

				UpdateInsideFill();

	            destination.ResumeLayout();
			}
			else
				destination.Show();

            // Enable generation hiding/hidden/shown events
            _surpressVisibleEvents--;

            // Generate event to indicate content is now visible
            OnContentShown(c);

            return w as WindowContent;
        }

        public WindowContent AddContentToWindowContent(Content c, WindowContent wc)
        {
            // Validate the incoming Content instance is a valid reference
            // and is a current instance within our internal collection
            if ((c == null) || !_contents.Contains(c))
                return null;

            // Validate the incoming WindowContent instance is a valid reference
            if (wc == null)
                return null;

            // Is Content already part of given Window then nothing to do
            if (c.ParentWindowContent == wc)
                return wc;
            else
            {
				bool valid = true;

                // Do not generate hiding/hidden/shown events
                _surpressVisibleEvents++;

                // Manageing Zones should remove display AutoHide windows
                RemoveShowingAutoHideWindows();
                
                if (c.ParentWindowContent != null)
                {
					// Is there a change in docking state?
					if (c.ParentWindowContent.ParentZone.State != wc.ParentZone.State)
					{
						// If it used to be in a floating mode, then record state change
						if (c.ParentWindowContent.ParentZone.State == State.Floating)
							c.ContentLeavesFloating();
						else
							c.ContentBecomesFloating();
					}

                    // Remove the Content from its current WindowContent
                    c.ParentWindowContent.Contents.Remove(c);
                }
                else
                {
					// If a window content is in AutoHide then it will not have a parent zone
					if (wc.ParentZone != null)
					{
						// If adding to a floating window then it is not docked
						if (wc.ParentZone.State == State.Floating)
							c.Docked = false;
					}
					else
					{
						// Cannot dynamically add into an autohide parent
						valid = false;
					}
                }

				if (valid)
				{
					// Add the existing Content to this instance
					wc.Contents.Add(c);
				}

                // Enable generation hiding/hidden/shown events
                _surpressVisibleEvents--;

				if (valid)
				{
					// Generate event to indicate content is now visible
					OnContentShown(c);
				}

                return wc;
            }
        }

        public Window AddContentToZone(Content c, Zone z, int index)
        {
            // Validate the incoming Content instance is a valid reference
            // and is a current instance within our internal collection
            if ((c == null) || !_contents.Contains(c))
                return null;

            // Validate the incoming Zone instance is a valid reference
            if (z == null) 
                return null;

            // Do not generate hiding/hidden/shown events
            _surpressVisibleEvents++;

            // Manageing Zones should remove display AutoHide windows
            RemoveShowingAutoHideWindows();
                
            // Is the window already part of a WindowContent?
            if (c.ParentWindowContent != null)
            {
				// Is there a change in docking state?
				if (c.ParentWindowContent.ParentZone.State != z.State)
				{
					// If it used to be in a floating mode, then record state change
					if (c.ParentWindowContent.ParentZone.State == State.Floating)
						c.ContentLeavesFloating();
					else
						c.ContentBecomesFloating();
				}

                // Remove the Content from its current WindowContent
                c.ParentWindowContent.Contents.Remove(c);
            }
            else
            {
                // If target zone is floating window then we are no longer docked
                if (z.State == State.Floating)
                    c.Docked = false;
            }

            // Create a new WindowContent instance according to our style
            Window w = CreateWindowForContent(c);

            // Add the Window to the Zone at given position
            z.Windows.Insert(index, w);

            // Enable generation hiding/hidden/shown events
            _surpressVisibleEvents--;

            // Generate event to indicate content is now visible
            OnContentShown(c);

            return w;
        }

		public Rectangle InnerResizeRectangle(Control source)
		{
			// Start with a rectangle that represents the entire client area
			Rectangle client = _container.ClientRectangle;

			int count = _container.Controls.Count;
			int inner = _container.Controls.IndexOf(_innerControl);
			int sourceIndex = _container.Controls.IndexOf(source);

			// Process each control outside the inner control
			for(int index=count-1; index>inner; index--)
			{
				Control item = _container.Controls[index];

				bool insideSource = (index < sourceIndex);

				switch(item.Dock)
				{
				    case DockStyle.Left:
					    client.Width -= item.Width;
					    client.X += item.Width;

					    if (insideSource)
						    client.Width -= item.Width;
					    break;
				    case DockStyle.Right:
					    client.Width -= item.Width;

					    if (insideSource)
					    {
						    client.Width -= item.Width;
						    client.X += item.Width;
					    }
					    break;
				    case DockStyle.Top:
					    client.Height -= item.Height;
					    client.Y += item.Height;

					    if (insideSource)
						    client.Height -= item.Height;
					    break;
				    case DockStyle.Bottom:
					    client.Height -= item.Height;

					    if (insideSource)
					    {
						    client.Height -= item.Height;
						    client.Y += item.Height;
					    }
					    break;
				    case DockStyle.Fill:
				    case DockStyle.None:
					    break;
				}
			}

			return client;
		}

        public void ReorderZoneToInnerMost(Zone zone)
        {
            int index = 0;

            // If there is no control specified as the one for all Zones to be placed
            // in front of then simply add the Zone at the start of the list so it is
            // in front of all controls.
            if (_innerControl != null)
            {
                // Find position of specified control and place after it in the list 
                // (hence adding one to the returned value)
                index = _container.Controls.IndexOf(_innerControl) + 1;
            }

            // Find current position of the Zone to be repositioned
            int current = _container.Controls.IndexOf(zone);

            // If the old position is before the new position then we need to 
            // subtract one. As the collection will remove the Control from the
            // old position before inserting it in the new, thus reducing the index
            // by 1 before the insert occurs.
            if (current < index)
                index--;

            // Found a Control that is not a Zone, so need to insert straight it
            _container.Controls.SetChildIndex(zone, index);
            
            // Manageing Zones should remove display AutoHide windows
            RemoveShowingAutoHideWindows();
        }

        public void ReorderZoneToOuterMost(Zone zone)
        {
            // Get index of the outer control (minus AutoHidePanel's)
            int index = OuterControlIndex();

            // Find current position of the Zone to be repositioned
            int current = _container.Controls.IndexOf(zone);

            // If the old position is before the new position then we need to 
            // subtract one. As the collection will remove the Control from the
            // old position before inserting it in the new, thus reducing the index
            // by 1 before the insert occurs.
            if (current < index)
                index--;

            // Found a Control that is not a Zone, so need to insert straight it
            _container.Controls.SetChildIndex(zone, index);

            // Manageing Zones should remove display AutoHide windows
            RemoveShowingAutoHideWindows();
        }
        
        public int OuterControlIndex()
        {
            int index = _container.Controls.Count;

            // If there is no control specified as the one for all Zones to be placed behind 
            // then simply add the Zone at the end of the list so it is behind all controls.
            if (_outerControl != null)
            {
                // Find position of specified control and place before it in the list 
                index = _container.Controls.IndexOf(_outerControl);
            }

            // Adjust backwards to prevent being after any AutoHidePanels
            for(; index>0; index--)
                if (!(_container.Controls[index-1] is AutoHidePanel))
                    break;
                    
            return index;
        }

        public void RemoveShowingAutoHideWindows()
        {
            _ahpLeft.RemoveShowingWindow();
            _ahpRight.RemoveShowingWindow();
            _ahpTop.RemoveShowingWindow();
            _ahpBottom.RemoveShowingWindow();
        }
        
        internal void RemoveShowingAutoHideWindowsExcept(AutoHidePanel except)
        {
            if (except != _ahpLeft)
                _ahpLeft.RemoveShowingWindow();

            if (except != _ahpRight)
                _ahpRight.RemoveShowingWindow();
            
            if (except != _ahpTop)
                _ahpTop.RemoveShowingWindow();
            
            if (except != _ahpBottom)
                _ahpBottom.RemoveShowingWindow();
        }

        public void BringAutoHideIntoView(Content c)
        {
            if (_ahpLeft.ContainsContent(c))
                _ahpLeft.BringContentIntoView(c);     

            if (_ahpRight.ContainsContent(c))
                _ahpRight.BringContentIntoView(c);     

            if (_ahpTop.ContainsContent(c))
                _ahpTop.BringContentIntoView(c);     

            if (_ahpBottom.ContainsContent(c))
                _ahpBottom.BringContentIntoView(c);     
        }            
        
        public void ValuesFromState(State newState, out DockStyle dockState, out Direction direction)
        {
            switch(newState)
            {
                case State.Floating:
                    dockState = DockStyle.Fill;
                    direction = Direction.Vertical;
                    break;
                case State.DockTop:
                    dockState = DockStyle.Top;
                    direction = Direction.Horizontal;
                    break;
                case State.DockBottom:
                    dockState = DockStyle.Bottom;
                    direction = Direction.Horizontal;
                    break;
                case State.DockRight:
                    dockState = DockStyle.Right;
                    direction = Direction.Vertical;
                    break;
                case State.DockLeft:
                default:
                    dockState = DockStyle.Left;
                    direction = Direction.Vertical;
                    break;
            }
        }

		public byte[] SaveConfigToArray()
		{
			return SaveConfigToArray(Encoding.Unicode);	
		}

		public byte[] SaveConfigToArray(Encoding encoding)
		{
			// Create a memory based stream
			MemoryStream ms = new MemoryStream();
			
			// Save into the file stream
			SaveConfigToStream(ms, encoding);

			// Must remember to close
			ms.Close();

			// Return an array of bytes that contain the streamed XML
			return ms.GetBuffer();
		}

		public void SaveConfigToFile(string filename)
		{
			SaveConfigToFile(filename, Encoding.Unicode);
		}

		public void SaveConfigToFile(string filename, Encoding encoding)
		{
			// Create/Overwrite existing file
			FileStream fs = new FileStream(filename, FileMode.Create);
			
			// Save into the file stream
			SaveConfigToStream(fs, encoding);		

			// Must remember to close
			fs.Close();
		}

		public void SaveConfigToStream(Stream stream, Encoding encoding)
		{
			XmlTextWriter xmlOut = new XmlTextWriter(stream, encoding); 

			// Use indenting for readability
			xmlOut.Formatting = Formatting.Indented;
			
			// Always begin file with identification and warning
			xmlOut.WriteStartDocument();
			xmlOut.WriteComment(" Magic, The User Interface library for .NET (www.dotnetmagic.com) ");
			xmlOut.WriteComment(" Modifying this generated file will probably render it invalid ");

			// Associate a version number with the root element so that future version of the code
			// will be able to be backwards compatible or at least recognise out of date versions
			xmlOut.WriteStartElement("DockingConfig");
			xmlOut.WriteAttributeString("FormatVersion", "5");
			xmlOut.WriteAttributeString("InsideFill", _insideFill.ToString());
			xmlOut.WriteAttributeString("InnerMinimum", ConversionHelper.SizeToString(_innerMinimum));

			// We need to hide all content during the saving process, but then restore
			// them back again before leaving so the user does not see any change
			_container.SuspendLayout();

			// Store a list of those content hidden during processing
			ContentCollection hideContent = new ContentCollection();

			// Let create a copy of the current contents in current order, because
			// we cannot 'foreach' a collection that is going to be altered during its
			// processing by the 'HideContent'.
			ContentCollection origContents = _contents.Copy();

            // Do not generate hiding/hidden/shown events
            _surpressVisibleEvents++;
            
            int count = origContents.Count;

            // Hide in reverse order so that a ShowAll in forward order gives accurate restore
            for(int index=count-1; index>=0; index--)
            {
                Content c = origContents[index];
            
				c.RecordRestore();
				c.SaveToXml(xmlOut);

				// If visible then need to hide so that subsequent attempts to 
				// RecordRestore will not take its position into account
				if (c.Visible)
				{
					hideContent.Insert(0, c);
					HideContent(c);
				}
			}
			
			// Allow an event handler a chance to add custom information after ours
			OnSaveCustomConfig(xmlOut);

			// Put content we hide back again
			foreach(Content c in hideContent)
				ShowContent(c);

            // Enable generation of hiding/hidden/shown events
            _surpressVisibleEvents--;
            
            // Reapply any fill style required
			AddInnerFillStyle();

			_container.ResumeLayout();

			// Terminate the root element and document        
			xmlOut.WriteEndElement();
			xmlOut.WriteEndDocument();

			// This should flush all actions and close the file
			xmlOut.Close();			
		}

		public void LoadConfigFromArray(byte[] buffer)
		{
			// Create a memory based stream
			MemoryStream ms = new MemoryStream(buffer);
			
			// Save into the file stream
			LoadConfigFromStream(ms);

			// Must remember to close
			ms.Close();
		}

		public void LoadConfigFromFile(string filename)
		{
			// Open existing file
			FileStream fs = new FileStream(filename, FileMode.Open);
			
			// Load from the file stream
			LoadConfigFromStream(fs);		

			// Must remember to close
			fs.Close();
		}

		public void LoadConfigFromStream(Stream stream)
		{
			XmlTextReader xmlIn = new XmlTextReader(stream); 

			// Ignore whitespace, not interested
			xmlIn.WhitespaceHandling = WhitespaceHandling.None;

			// Moves the reader to the root element.
			xmlIn.MoveToContent();

			// Double check this has the correct element name
			if (xmlIn.Name != "DockingConfig")
				throw new ArgumentException("Root element must be 'DockingConfig'");

			// Load the format version number
			string version = xmlIn.GetAttribute(0);
			string insideFill = xmlIn.GetAttribute(1);
			string innerSize = xmlIn.GetAttribute(2);

            // Convert format version from string to double
            int formatVersion = (int)Convert.ToDouble(version);
            
            // We can only load 3 upward version formats
            if (formatVersion < 3)
                throw new ArgumentException("Can only load Version 3 and upwards Docking Configuration files");

            // Convert from string to proper types
			_insideFill = (bool)Convert.ToBoolean(insideFill);
			_innerMinimum = ConversionHelper.StringToSize(innerSize);

			ContentCollection cc = new ContentCollection();

			do
			{
                // Read the next Element
				if (!xmlIn.Read())
					throw new ArgumentException("An element was expected but could not be read in");

				// Have we reached the end of root element?
				if ((xmlIn.NodeType == XmlNodeType.EndElement) && (xmlIn.Name == "DockingConfig"))
					break;

				// Is the element name 'Content'
				if (xmlIn.Name == "Content")
				{
                    // Process this Content element
                    cc.Insert(0, new Content(xmlIn, formatVersion));
                }
				else
				{
				    // Must have reached end of our code, let the custom handler deal with this
                    OnLoadCustomConfig(xmlIn);

                    // Ignore anything else that might be in the XML
                    xmlIn.Close();			
                   
                    // Exit
                    break;
                }

			} while(!xmlIn.EOF);

			xmlIn.Close();			

			// Reduce flicker during window operations
			_container.SuspendLayout();

			// Hide all the current content items
			HideAllContents();

			// Attempt to apply loaded settings
			foreach(Content loaded in cc)
			{
				Content c = _contents[loaded.Title];

				// Do we have any loaded information for this item?
				if (c != null)
				{
					// Copy across the loaded values of interest
                    c.Docked = loaded.Docked;
                    c.AutoHidden = loaded.AutoHidden;
                    c.CaptionBar = loaded.CaptionBar;
                    c.CloseButton = loaded.CloseButton;
                    c.DisplaySize = loaded.DisplaySize;
					c.DisplayLocation = loaded.DisplayLocation;
					c.AutoHideSize = loaded.AutoHideSize;
					c.FloatingSize = loaded.FloatingSize;
					c.DefaultRestore = loaded.DefaultRestore;
					c.AutoHideRestore = loaded.AutoHideRestore;
					c.DockingRestore = loaded.DockingRestore;
					c.FloatingRestore = loaded.FloatingRestore;

					// Allow the Restore objects a chance to rehook into object instances
					c.ReconnectRestore();					

					// Was the loaded item visible?
					if (loaded.Visible)
					{
						// Make it visible now
						ShowContent(c);
					}
				}
			}

			// Reapply any fill style required
			AddInnerFillStyle();

			// Reduce flicker during window operations
			_container.ResumeLayout();
			
			// If any AutoHostPanel's have become visible we need to force a repaint otherwise
			// the area not occupied by the TabStub instances will be painted the correct color
			_ahpLeft.Invalidate();
            _ahpRight.Invalidate();
            _ahpTop.Invalidate();
            _ahpBottom.Invalidate();
        }
        
        public void PropogateNameValue(PropogateName name, object value)
        {
            foreach(Control c in _container.Controls)
            {
                Zone z = c as Zone;

                // Only interested in our Zones
                if (z != null)
                    z.PropogateNameValue(name, value);
            }

            // If the docking manager is created for a Container that does not
            // yet have a parent control then we need to double check before
            // trying to enumerate the owned forms.
            if (_container.FindForm() != null)
            {
                foreach(Form f in _container.FindForm().OwnedForms)
                {
                    FloatingForm ff = f as FloatingForm;
                    
                    // Only interested in our FloatingForms
                    if (ff != null)
                        ff.PropogateNameValue(name, value);
                }
            }
            
            // Propogate into the AutoHidePanel objects
            _ahpTop.PropogateNameValue(name, value);
            _ahpLeft.PropogateNameValue(name, value);
            _ahpRight.PropogateNameValue(name, value);
            _ahpBottom.PropogateNameValue(name, value);
        }

		public virtual bool OnContentHiding(Content c)
        {
            CancelEventArgs cea = new CancelEventArgs();

            if (_surpressVisibleEvents == 0)
            {
                // Allow user to prevent hide operation                
                if (ContentHiding != null)
                    ContentHiding(c, cea);
            }
            
            // Was action cancelled?                        
            return cea.Cancel;
        }

		public virtual void OnContentHidden(Content c)
        {
            if (_surpressVisibleEvents == 0)
            {
                // Notify operation has completed
                if (ContentHidden != null)
                    ContentHidden(c, EventArgs.Empty);
            }
        }

		public virtual void OnContentShown(Content c)
        {
            if (_surpressVisibleEvents == 0)
            {
                // Notify operation has completed
                if (ContentShown != null)
                    ContentShown(c, EventArgs.Empty);
            }
        }

		public virtual void OnTabControlCreated(Magic.Controls.TabControl tabControl)
		{ 
			// Notify interested parties about creation of a new TabControl instance
			if (TabControlCreated != null)
				TabControlCreated(tabControl);
		}
		
		public virtual void OnSaveCustomConfig(XmlTextWriter xmlOut)
		{
            // Notify interested parties that they can add their own custom data
            if (SaveCustomConfig != null)
                SaveCustomConfig(xmlOut);
        }

        public virtual void OnLoadCustomConfig(XmlTextReader xmlIn)
        {
            // Notify interested parties that they can add their own custom data
            if (LoadCustomConfig != null)
                LoadCustomConfig(xmlIn);
        }
        
        protected virtual void OnContentsClearing()
        {
            _container.SuspendLayout();

			// Hide them all will gracefully remove them from view
			HideAllContents();

            _container.ResumeLayout();
        }

        protected virtual void OnContentRemoved(int index, object value)
        {
            _container.SuspendLayout();

            Content c = value as Content;

			// Hide the content will gracefully remove it from view
            if (c != null)
				HideContent(c, true, false);

            _container.ResumeLayout();
        }

        protected virtual void OnContentClose(object sender, EventArgs e)
        {
            WindowDetailCaption wdc = sender as WindowDetailCaption;
            
            // Was Close generated by a Caption detail?
            if (wdc != null)
            {
                WindowContentTabbed wct = wdc.ParentWindow as WindowContentTabbed;
                
                // Is the Caption part of a WindowContentTabbed object?
                if (wct != null)
                {
                    // Find the Content object that is the target
                    Content c = wct.CurrentContent;
                    
                    if (c != null)
                    {
                        // Was action cancelled?                        
                        if (!OnContentHiding(c))
                            wct.HideCurrentContent();
                    }
                }
            }
        }
        
        protected virtual void OnInvertAutoHide(object sender, EventArgs e)
        {
            WindowDetail detail = sender as WindowDetail;

            // Get access to Content that initiated AutoHide for its Window
            WindowContent wc = detail.ParentWindow as WindowContent;
                        
			// Make the window content auto hide
			InvertAutoHideWindowContent(wc);
        }
        
		protected virtual void InvertAutoHideWindowContent(WindowContent wc)
		{
			// Do not generate hiding/hidden/shown events
			_surpressVisibleEvents++;

			// Create a collection of the Content in the same window
			ContentCollection cc = new ContentCollection();
	            
			// Add all Content into collection
			foreach(Content c in wc.Contents)
				cc.Add(c);

			// Add to the correct AutoHidePanel
			AutoHideContents(cc, wc.State);

			// Enable generate hiding/hidden/shown events
			_surpressVisibleEvents--;
		}

		internal AutoHidePanel AutoHidePanelForState(State state)
        {
            AutoHidePanel ahp = null;

            // Grab the correct hosting panel
            switch(state)
            {
                case State.DockLeft:
                    ahp = _ahpLeft;
                    break;
                case State.DockRight:
                    ahp = _ahpRight;
                    break;
                case State.DockTop:
                    ahp = _ahpTop;
                    break;
                case State.DockBottom:
                    ahp = _ahpBottom;
                    break;
            }

            return ahp;
        }
        
        internal void AutoHideContents(ContentCollection cc, State state)
        {
            // Hide all the Content instances. This will cause the restore objects to be 
            // created and so remember the docking positions for when they are restored
            foreach(Content c in cc)
                HideContent(c);

            AutoHidePanel ahp = AutoHidePanelForState(state);

            // Pass management of Contents into the panel            
            ahp.AddContentsAsGroup(cc);
        }

        internal AutoHidePanel AutoHidePanelForContent(Content c)
        {
            if (_ahpLeft.ContainsContent(c))
                return _ahpLeft;     

            if (_ahpRight.ContainsContent(c))
                return _ahpRight;     

            if (_ahpTop.ContainsContent(c))
                return _ahpTop;     

            if (_ahpBottom.ContainsContent(c))
                return _ahpBottom;     
                
            return null;
        }

        internal int SurpressVisibleEvents
        {
            get { return _surpressVisibleEvents; }
            set { _surpressVisibleEvents = value; }
        }

        protected void AddAutoHidePanels()
        {
            // Create an instance for each container edge (they default to being hidden)
            _ahpTop = new AutoHidePanel(this, DockStyle.Top);
            _ahpLeft = new AutoHidePanel(this, DockStyle.Left);
            _ahpBottom = new AutoHidePanel(this, DockStyle.Bottom);
            _ahpRight = new AutoHidePanel(this, DockStyle.Right);
        
			_ahpTop.Name = "Top";
			_ahpLeft.Name = "Left";
			_ahpBottom.Name = "Bottom";
			_ahpRight.Name = "Right";
		    
            // Add to the end of the container we manage
            _container.Controls.AddRange(new Control[]{_ahpBottom, _ahpTop, _ahpRight, _ahpLeft});
		}
		            
        protected void RepositionControlBefore(Control target, Control source)
        {
            // Find indexs of the two controls
            int targetPos = _container.Controls.IndexOf(target);
            int sourcePos = _container.Controls.IndexOf(source);

            // If the source is being moved further up the list then we must decrement the target index 
            // as the move is carried out in two phases. First the source control is removed from the 
            // collection and then added at the given requested index. So when insertion point needs 
            // ahjusting to reflec the fact the control has been removed before being inserted.
            if (targetPos >= sourcePos)
                targetPos--;

            _container.Controls.SetChildIndex(source, targetPos);			
        }

        protected virtual void OnRestore(object sender, EventArgs e)
        {
            WindowDetailCaption wdc = sender as WindowDetailCaption;

			// Was Restore generated by a Caption detail?
			if (wdc != null)
			{
				RemoveAnyFillStyle();

                WindowContent wc = wdc.ParentWindow as WindowContent;

				// Is the Caption part of a WindowContent object?
				if (wc != null)
				{
					ContentCollection copy = new ContentCollection();

					// Make every Content of the WindowContent record its
					// current position and remember it for when the future
					foreach(Content c in wc.Contents)
					{
						c.RecordRestore();

						// Invert docked status
						c.Docked = (c.Docked == false);

						copy.Add(c);
					}

					int copyCount = copy.Count;

					// Must have at least one!
					if (copyCount >= 1)
					{
						// Remove from current WindowContent and restore its position
						HideContent(copy[0], false, true);
						ShowContent(copy[0]);

						// Any other content to be moved along with it?
						if (copyCount >= 2)
						{
							WindowContent newWC = copy[0].ParentWindowContent;

							if (newWC != null)
							{
								// Transfer each one to its new location
								for(int index=1; index<copyCount; index++)
								{
									HideContent(copy[index], false, true);
									newWC.Contents.Add(copy[index]);
								}
							}
						}
					}
				}

				AddInnerFillStyle();
			}
		}

		protected void AddInnerFillStyle()
		{
			if (_insideFill)
			{
				// Find the innermost Zone which must be the first one in the collection
				foreach(Control c in _container.Controls)
				{
					Zone z = c as Zone;

					// Only interested in our Zones
					if (z != null)
					{
						// Make it fill all remaining space
						z.Dock = DockStyle.Fill;

						// Exit
						break;
					}
				}
			}
		}

		protected void RemoveAnyFillStyle()
		{
			// Check each Zone in the container
			foreach(Control c in _container.Controls)
			{
				Zone z = c as Zone;

				if (z != null)
				{
					// Only interested in ones with the Fill dock style
					if (z.Dock == DockStyle.Fill)
					{
						DockStyle ds;
						Direction direction;

						// Find relevant values dependant on required state
						ValuesFromState(z.State, out ds, out direction);
			
						// Reassign its correct Dock style
						z.Dock = ds;
					}
				}
			}
		}

        protected void OnFormLoaded(object sender, EventArgs e)
        {
            // A Form can cause the child controls to be reordered after the initialisation
            // but before the Form.Load event. To handle this we reorder the auto hide panels
            // on the Form.Load event to ensure they are correctly positioned.
            ReorderAutoHidePanels();
        }

        protected void ReorderAutoHidePanels()
        {
            if (_outerControl == null)
            {
                int count = _container.Controls.Count;

                // Position the AutoHidePanel's at end of controls
                _container.Controls.SetChildIndex(_ahpLeft, count - 1);
                _container.Controls.SetChildIndex(_ahpRight, count - 1);
                _container.Controls.SetChildIndex(_ahpTop, count - 1);
                _container.Controls.SetChildIndex(_ahpBottom, count - 1);
            }
            else
            {
                // Position the AutoHidePanel's as last items before OuterControl
                RepositionControlBefore(_outerControl, _ahpBottom);
                RepositionControlBefore(_outerControl, _ahpTop);
                RepositionControlBefore(_outerControl, _ahpRight);
                RepositionControlBefore(_outerControl, _ahpLeft);
            }
        }
        
        protected void OnContainerResized(object sender, EventArgs e)
		{
		    if (_autoResize)
		    {
			    Rectangle inner = InnerResizeRectangle(null);			

			    // Shrink by the minimum size
			    inner.Width -= _innerMinimum.Width;
			    inner.Height -= _innerMinimum.Height;
    			
			    Form f = _container as Form;

			    // If the container is a Form then ignore resizing because of becoming Minimized
			    if ((f == null) || ((f != null) && (f.WindowState != FormWindowState.Minimized)))
			    {
				    if ((inner.Width < 0) || (inner.Height < 0))
				    {
					    _container.SuspendLayout();

					    ZoneCollection zcLeft = new ZoneCollection();
					    ZoneCollection zcRight = new ZoneCollection();
					    ZoneCollection zcTop = new ZoneCollection();
					    ZoneCollection zcBottom = new ZoneCollection();

					    // Construct a list of the docking windows on the left and right edges
					    foreach(Control c in _container.Controls)
					    {
						    Zone z = c as Zone;

						    if (z != null)
						    {
							    switch(z.State)
							    {
							        case State.DockLeft:
								        zcLeft.Add(z);
								        break;
							        case State.DockRight:
								        zcRight.Add(z);
								        break;
							        case State.DockTop:
								        zcTop.Add(z);
								        break;
							        case State.DockBottom:
								        zcBottom.Add(z);
								        break;
							    }
						    }
					    }

					    if (inner.Width < 0)
						    ResizeDirection(-inner.Width, zcLeft, zcRight, Direction.Horizontal);

					    if (inner.Height < 0)
						    ResizeDirection(-inner.Height, zcTop, zcBottom, Direction.Vertical);

					    _container.ResumeLayout();
				    }
			    }
	        }
		}

		protected void ResizeDirection(int remainder, ZoneCollection zcAlpha, ZoneCollection zcBeta, Direction dir)
		{
			bool alter;
			int available;
			int half1, half2;

			// Keep going till all space found or nowhere to get it from
			while((remainder > 0) && ((zcAlpha.Count > 0) || (zcBeta.Count > 0)))
			{
				if (dir == Direction.Horizontal)
				{
					_firstHalfWidth = (_firstHalfWidth != true);
					alter = _firstHalfWidth;
				}
				else
				{
					_firstHalfHeight = (_firstHalfHeight != true);
					alter = _firstHalfHeight;
				}

				// Alternate between left and right getting the remainder
				if (alter)
				{
					half1 = (remainder / 2) + 1;
					half2 = remainder - half1;
				}
				else
				{
					half2 = (remainder / 2) + 1;
					half1 = remainder - half2;
				}

				// Any Zone of the left to use?
				if (zcAlpha.Count > 0)
				{
					Zone z = zcAlpha[0];

					// Find how much space it can offer up
					if (dir == Direction.Horizontal)
						available = z.Width - z.MinimumWidth;
					else
						available = z.Height - z.MinimumHeight;

					if (available > 0)
					{
						// Only take away the maximum we need
						if (available > half1)
							available = half1;
						else
							zcAlpha.Remove(z);

						// Resize the control accordingly
						if (dir == Direction.Horizontal)
							z.Width = z.Width - available;
						else
							z.Height = z.Height - available;

						// Reduce total amount left to allocate
						remainder -= available;
					}
					else
						zcAlpha.Remove(z);
				}

				// Any Zone of the left to use?
				if (zcBeta.Count > 0)
				{
					Zone z = zcBeta[0];

					// Find how much space it can offer up
					if (dir == Direction.Horizontal)
						available = z.Width - z.MinimumWidth;
					else
						available = z.Height - z.MinimumHeight;

					if (available > 0)
					{
						// Only take away the maximum we need
						if (available > half2)
							available = half2;
						else
							zcBeta.Remove(z);

						// Resize the control accordingly
						if (dir == Direction.Horizontal)
							z.Width = z.Width - available;
						else
							z.Height = z.Height - available;

						// Reduce total amount left to allocate
						remainder -= available;
					}
					else
						zcBeta.Remove(z);
				}
			}
		}

        protected void OnPreferenceChanged(object sender, UserPreferenceChangedEventArgs e)
        {
            if (_defaultBackColor)
            {
                _backColor = SystemColors.Control;
                PropogateNameValue(PropogateName.BackColor, (object)SystemColors.Control);
            }

            if (_defaultActiveColor)
            {
                _activeColor = SystemColors.ActiveCaption;
                PropogateNameValue(PropogateName.ActiveColor, (object)SystemColors.ActiveCaption);
            }
            
            if (_defaultActiveTextColor)
            {
                _activeTextColor = SystemColors.ActiveCaptionText;
                PropogateNameValue(PropogateName.ActiveTextColor, (object)SystemColors.ActiveCaptionText);
            }

            if (_defaultInactiveTextColor)
            {
                _inactiveTextColor = SystemColors.ControlText;
                PropogateNameValue(PropogateName.InactiveTextColor, (object)SystemColors.ControlText);
            }

            if (_defaultResizeBarColor)
            {
                _resizeBarColor = SystemColors.Control;
                PropogateNameValue(PropogateName.ResizeBarColor, (object)SystemColors.Control);
            }

            if (_defaultCaptionFont)
            {
                _captionFont = SystemInformation.MenuFont;
                PropogateNameValue(PropogateName.CaptionFont, (object)SystemInformation.MenuFont);
            }

            if (_defaultTabControlFont)
            {
                _tabControlFont = SystemInformation.MenuFont;
                PropogateNameValue(PropogateName.TabControlFont, (object)SystemInformation.MenuFont);
            }
        }

		public virtual void OnShowContextMenu(Point screenPos)
		{
            PopupMenu context = new PopupMenu();

			// The order of Content displayed in the context menu is not the same as
			// the order of Content in the _contents collection. The latter has its
			// ordering changed to enable Restore functionality to work.
			ContentCollection temp = new ContentCollection();

			foreach(Content c in _contents)
			{
				int count = temp.Count;
				int index = 0;

				// Find best place to add into the temp collection
				for(; index<count; index++)
				{
					if (c.Order < temp[index].Order)
						break;
				}

				temp.Insert(index, c);
			}

			// Create a context menu entry per Content
			foreach(Content t in temp)
			{
				MenuCommand mc = new MenuCommand(t.Title, new EventHandler(OnToggleContentVisibility));
				mc.Checked = t.Visible;
				mc.Tag = t;

				context.MenuCommands.Add(mc);
			}

			// Add a separator 
			context.MenuCommands.Add(new MenuCommand("-"));

			// Add fixed entries to end to effect all content objects
			context.MenuCommands.Add(new MenuCommand("Show All", new EventHandler(OnShowAll)));
			context.MenuCommands.Add(new MenuCommand("Hide All", new EventHandler(OnHideAll)));

			// Ensure menu has same style as the docking windows
            context.Style = _visualStyle;

            if (OnContextMenu(context))
            {
                // Show it!
                context.TrackPopup(screenPos);
            }
		}

        protected bool OnContextMenu(PopupMenu context)
        {
            CancelEventArgs cea = new CancelEventArgs();
        
            if (ContextMenu != null)
                ContextMenu(context, cea);
                
            return !cea.Cancel;
        }

		protected void OnToggleContentVisibility(object sender, EventArgs e)
		{
			MenuCommand mc = sender as MenuCommand;

			if (mc != null)
			{
				Content c = mc.Tag as Content;

				if (c != null)
				{
					if (c.Visible)
						HideContent(c);
					else
						ShowContent(c);
				}
			}
		}

		protected void OnShowAll(object sender, EventArgs e)
		{
			ShowAllContents();
		}

		protected void OnHideAll(object sender, EventArgs e)
		{
			HideAllContents();
		}
    }
}

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 has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Austria Austria
My name is Daniel and I am from Austria.
When I was in High School, all I wanted to do was programming. After finishing High School, I joined a company for which I wrote a project management utility in Visual Basic 6. It was then that I realised that programming all day long was nothing I wanted to do for the rest of my life.

I quit the job and started to study computer and media security at polytechnical university in Hagenberg/Austria.

As of now, I'm still studying. I still like to program, as long as I can do something else too. Recently I switched my favorite programming language to c#. Together with a friend from university, we started a project where we implement OpenPGP (RFC2440) in c#.

Comments and Discussions