Merge pull request #268 from pcc/menudeactivate
[mono.git] / mcs / class / Managed.Windows.Forms / System.Windows.Forms / ToolStrip.cs
index 6c04b09f99244e90e581617c1a2f60939fd07b65..30c0d89f5fb40633ee7a05e3dc555e6408b74e67 100644 (file)
 //     Jonathan Pobst (monkey@jpobst.com)
 //
 
-#if NET_2_0
 using System;
 using System.Runtime.InteropServices;
 using System.ComponentModel;
 using System.Drawing;
 using System.Windows.Forms.Layout;
 using System.Collections.Generic;
+using System.ComponentModel.Design.Serialization;
 
 namespace System.Windows.Forms
 {
@@ -40,9 +40,12 @@ namespace System.Windows.Forms
        [ClassInterface (ClassInterfaceType.AutoDispatch)]
        [DefaultEvent ("ItemClicked")]
        [DefaultProperty ("Items")]
-       public class ToolStrip : ScrollableControl, IComponent, IDisposable
+       [Designer ("System.Windows.Forms.Design.ToolStripDesigner, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.IDesigner")]
+       [DesignerSerializer ("System.Windows.Forms.Design.ToolStripCodeDomSerializer, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.Serialization.CodeDomSerializer, " + Consts.AssemblySystem_Design)]
+       public class ToolStrip : ScrollableControl, IComponent, IDisposable, IToolStripData
        {
                #region Private Variables
+               private bool allow_item_reorder;
                private bool allow_merge;
                private Color back_color;
                private bool can_overflow;
@@ -66,14 +69,19 @@ namespace System.Windows.Forms
                private List<ToolStripItem> pre_merge_items;
                private ToolStripRenderer renderer;
                private ToolStripRenderMode render_mode;
+               private ToolStripTextDirection text_direction;
                private Timer tooltip_timer;
-               private ToolTip.ToolTipWindow tooltip_window;
+               private ToolTip tooltip_window;
                private bool show_item_tool_tips;
                private bool stretch;
 
                private ToolStripItem mouse_currently_over;
                internal bool menu_selected;
                private ToolStripItem tooltip_currently_showing;
+               private ToolTip.TipState tooltip_state;
+
+               const int InitialToolTipDelay = 500;
+               const int ToolTipDelay = 5000;
                #endregion
 
                #region Public Constructors
@@ -89,14 +97,16 @@ namespace System.Windows.Forms
                        SetStyle (ControlStyles.SupportsTransparentBackColor, true);
 
                        this.SuspendLayout ();
-                       this.items = new ToolStripItemCollection (this, items);
+                       
+                       this.items = new ToolStripItemCollection (this, items, true);
                        this.allow_merge = true;
                        base.AutoSize = true;
+                       this.SetAutoSizeMode (AutoSizeMode.GrowAndShrink);
                        this.back_color = Control.DefaultBackColor;
                        this.can_overflow = true;
                        base.CausesValidation = false;
                        this.default_drop_down_direction = ToolStripDropDownDirection.BelowRight;
-                       this.displayed_items = new ToolStripItemCollection (this, null);
+                       this.displayed_items = new ToolStripItemCollection (this, null, true);
                        this.Dock = this.DefaultDock;
                        base.Font = new Font ("Tahoma", 8.25f);
                        this.fore_color = Control.DefaultForeColor;
@@ -111,8 +121,8 @@ namespace System.Windows.Forms
                        this.render_mode = ToolStripRenderMode.ManagerRenderMode;
                        this.show_item_tool_tips = this.DefaultShowItemToolTips;
                        base.TabStop = false;
+                       this.text_direction = ToolStripTextDirection.Horizontal;
                        this.ResumeLayout ();
-                       DoAutoSize ();
                        
                        // Register with the ToolStripManager
                        ToolStripManager.AddToolStrip (this);
@@ -120,9 +130,23 @@ namespace System.Windows.Forms
                #endregion
 
                #region Public Properties
+               [MonoTODO ("Stub, does nothing")]
+               public override bool AllowDrop {
+                       get { return base.AllowDrop; }
+                       set { base.AllowDrop = value; }
+               }
+
+               [MonoTODO ("Stub, does nothing")]
+               [DefaultValue (false)]
+               public bool AllowItemReorder {
+                       get { return this.allow_item_reorder; }
+                       set { this.allow_item_reorder = value; }
+               }
+               
+               [DefaultValue (true)]
                public bool AllowMerge {
                        get { return this.allow_merge; }
-                       set { this.allow_merge = false; }
+                       set { this.allow_merge = value; }
                }
                
                public override AnchorStyles Anchor {
@@ -132,6 +156,7 @@ namespace System.Windows.Forms
 
                [Browsable (false)]
                [EditorBrowsable (EditorBrowsableState.Never)]
+               [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
                public override bool AutoScroll {
                        get { return base.AutoScroll; }
                        set { base.AutoScroll = value; }
@@ -139,6 +164,7 @@ namespace System.Windows.Forms
 
                [Browsable (false)]
                [EditorBrowsable (EditorBrowsableState.Never)]
+               [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
                public new Size AutoScrollMargin {
                        get { return base.AutoScrollMargin; }
                        set { base.AutoScrollMargin = value; }
@@ -146,6 +172,7 @@ namespace System.Windows.Forms
 
                [Browsable (false)]
                [EditorBrowsable (EditorBrowsableState.Never)]
+               [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
                public new Size AutoScrollMinSize {
                        get { return base.AutoScrollMinSize; }
                        set { base.AutoScrollMinSize = value; }
@@ -153,6 +180,7 @@ namespace System.Windows.Forms
 
                [Browsable (false)]
                [EditorBrowsable (EditorBrowsableState.Never)]
+               [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
                public new Point AutoScrollPosition {
                        get { return base.AutoScrollPosition; }
                        set { base.AutoScrollPosition = value; }
@@ -172,6 +200,11 @@ namespace System.Windows.Forms
                        set { this.back_color = value; }
                }
 
+               public override BindingContext BindingContext {
+                       get { return base.BindingContext; }
+                       set { base.BindingContext = value; }
+               }
+               
                [DefaultValue (true)]
                public bool CanOverflow {
                        get { return this.can_overflow; }
@@ -305,7 +338,7 @@ namespace System.Windows.Forms
                                        if (!Enum.IsDefined (typeof (ToolStripGripStyle), value))
                                                throw new InvalidEnumArgumentException (string.Format ("Enum argument value '{0}' is not valid for ToolStripGripStyle", value));
                                        this.grip_style = value;
-                                       this.PerformLayout ();
+                                       this.PerformLayout (this, "GripStyle");
                                }
                        }
                }
@@ -353,6 +386,7 @@ namespace System.Windows.Forms
                        }
                }
 
+               [MergableProperty (false)]
                [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
                public virtual ToolStripItemCollection Items {
                        get { return this.items; }
@@ -372,7 +406,12 @@ namespace System.Windows.Forms
                [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
                public LayoutSettings LayoutSettings {
                        get { return this.layout_settings; }
-                       set { this.layout_settings = value; }
+                       set { 
+                               if (this.layout_settings != value) {
+                                       this.layout_settings = value;
+                                       PerformLayout (this, "LayoutSettings");
+                               }
+                       }
                }
                
                [AmbientValue (ToolStripLayoutStyle.StackWithOverflow)]
@@ -404,7 +443,7 @@ namespace System.Windows.Forms
                                                
                                        this.layout_settings = this.CreateLayoutSettings (value);
                                        
-                                       this.PerformLayout ();
+                                       this.PerformLayout (this, "LayoutStyle");
                                        this.OnLayoutStyleChanged (EventArgs.Empty);
                                }
                        }
@@ -434,7 +473,7 @@ namespace System.Windows.Forms
                                if (this.renderer != value) {
                                        this.renderer = value; 
                                        this.render_mode = ToolStripRenderMode.Custom;
-                                       this.PerformLayout ();
+                                       this.PerformLayout (this, "Renderer");
                                        this.OnRendererChanged (EventArgs.Empty);
                                }
                        }
@@ -448,9 +487,11 @@ namespace System.Windows.Forms
 
                                if (value == ToolStripRenderMode.Custom && this.renderer == null)
                                        throw new NotSupportedException ("Must set Renderer property before setting RenderMode to Custom");
-                               if (value == ToolStripRenderMode.Professional || value == ToolStripRenderMode.System)
+                               else if (value == ToolStripRenderMode.Professional)
                                        this.Renderer = new ToolStripProfessionalRenderer ();
-
+                               else if (value == ToolStripRenderMode.System)
+                                       this.Renderer = new ToolStripSystemRenderer ();
+                                       
                                this.render_mode = value;
                        }
                }
@@ -471,7 +512,27 @@ namespace System.Windows.Forms
                [DispId(-516)]
                public new bool TabStop {
                        get { return base.TabStop; }
-                       set { base.TabStop = value; }
+                       set { 
+                               base.TabStop = value;
+                               SetStyle (ControlStyles.Selectable, value);
+                       }
+               }
+
+               [DefaultValue (ToolStripTextDirection.Horizontal)]
+               public virtual ToolStripTextDirection TextDirection {
+                       get { return this.text_direction; }
+                       set {
+                               if (!Enum.IsDefined (typeof (ToolStripTextDirection), value))
+                                       throw new InvalidEnumArgumentException (string.Format ("Enum argument value '{0}' is not valid for ToolStripTextDirection", value));
+
+                               if (this.text_direction != value) {
+                                       this.text_direction = value;
+                                       
+                                       this.PerformLayout (this, "TextDirection");
+                                               
+                                       this.Invalidate ();
+                               }
+                       }
                }
 
                [Browsable (false)]
@@ -489,13 +550,23 @@ namespace System.Windows.Forms
                protected virtual bool DefaultShowItemToolTips { get { return true; } }
                protected override Size DefaultSize { get { return new Size (100, 25); } }
                protected internal virtual ToolStripItemCollection DisplayedItems { get { return this.displayed_items; } }
+               protected internal virtual Size MaxItemSize {
+                       get { return new Size (Width - (GripStyle == ToolStripGripStyle.Hidden ? 1 : 8), Height); }
+               }
                #endregion
 
                #region Public Methods
+               [EditorBrowsable (EditorBrowsableState.Never)]
                public new Control GetChildAtPoint (Point point)
                {
                        return base.GetChildAtPoint (point);
                }
+
+               [EditorBrowsable (EditorBrowsableState.Never)]
+               public new Control GetChildAtPoint (Point pt, GetChildAtPointSkip skipValue)
+               {
+                       return base.GetChildAtPoint (pt, skipValue);
+               }
                
                public ToolStripItem GetItemAt (Point point)
                {
@@ -597,12 +668,12 @@ namespace System.Windows.Forms
                        return current_best;
                }
 
+               [EditorBrowsable (EditorBrowsableState.Never)]
                public void ResetMinimumSize ()
                {
                        this.MinimumSize = new Size (-1, -1);
                }
 
-               [Browsable (false)]
                [EditorBrowsable (EditorBrowsableState.Never)]
                public new void SetAutoScrollMargin (int x, int y)
                {
@@ -618,11 +689,7 @@ namespace System.Windows.Forms
                #region Protected Methods
                protected override AccessibleObject CreateAccessibilityInstance ()
                {
-                       AccessibleObject ao = new AccessibleObject (this);
-                       
-                       ao.role = AccessibleRole.ToolBar;
-                       
-                       return ao;
+                       return new ToolStripAccessibleObject (this);
                }
                
                protected override ControlCollection CreateControlsInstance ()
@@ -645,7 +712,7 @@ namespace System.Windows.Forms
                {
                        switch (layoutStyle) {
                                case ToolStripLayoutStyle.Flow:
-                                       return new FlowLayoutSettings ();
+                                       return new FlowLayoutSettings (this);
                                case ToolStripLayoutStyle.Table:
                                        //return new TableLayoutSettings ();
                                case ToolStripLayoutStyle.StackWithOverflow:
@@ -659,16 +726,47 @@ namespace System.Windows.Forms
                protected override void Dispose (bool disposing)
                {
                        if (!IsDisposed) {
-                               ToolStripManager.RemoveToolStrip (this);
+
+                               if(disposing) {
+                                       // Event Handler must be stopped before disposing Items.
+                                       Events.Dispose();
+
+                                       CloseToolTip (null);
+                                       // ToolStripItem.Dispose modifes the collection,
+                                       // so we iterate it in reverse order
+                                       for (int i = Items.Count - 1; i >= 0; i--)
+                                               Items [i].Dispose ();
+
+                                       if (this.overflow_button != null && this.overflow_button.drop_down != null)
+                                               this.overflow_button.drop_down.Dispose ();
+
+                                       ToolStripManager.RemoveToolStrip (this);
+                               }
                                base.Dispose (disposing);
                        }
                }
+
+               [MonoTODO ("Stub, never called")]
+               protected virtual void OnBeginDrag (EventArgs e)
+               {
+                       EventHandler eh = (EventHandler)(Events[BeginDragEvent]);
+                       if (eh != null)
+                               eh (this, e);
+               }
                
                protected override void OnDockChanged (EventArgs e)
                {
                        base.OnDockChanged (e);
                }
 
+               [MonoTODO ("Stub, never called")]
+               protected virtual void OnEndDrag (EventArgs e)
+               {
+                       EventHandler eh = (EventHandler)(Events[EndDragEvent]);
+                       if (eh != null)
+                               eh (this, e);
+               }
+
                protected override bool IsInputChar (char charCode)
                {
                        return base.IsInputChar (charCode);
@@ -709,10 +807,13 @@ namespace System.Windows.Forms
 
                protected internal virtual void OnItemAdded (ToolStripItemEventArgs e)
                {
-                       e.Item.Available = true;
+                       if (e.Item.InternalVisible)
+                               e.Item.Available = true;
+                               
                        e.Item.SetPlacement (ToolStripItemPlacement.Main);
-                       this.DoAutoSize ();
-                       this.PerformLayout ();
+                       
+                       if (this.Created)
+                               this.PerformLayout ();
                        
                        ToolStripItemEventHandler eh = (ToolStripItemEventHandler)(Events [ItemAddedEvent]);
                        if (eh != null)
@@ -721,7 +822,8 @@ namespace System.Windows.Forms
 
                protected virtual void OnItemClicked (ToolStripItemClickedEventArgs e)
                {
-                       ToolStripManager.SetActiveToolStrip (null);
+                       if (this.KeyboardActive)
+                               ToolStripManager.SetActiveToolStrip (null, false);
                        
                        ToolStripItemClickedEventHandler eh = (ToolStripItemClickedEventHandler)(Events [ItemClickedEvent]);
                        if (eh != null)
@@ -737,7 +839,6 @@ namespace System.Windows.Forms
 
                protected override void OnLayout (LayoutEventArgs e)
                {
-                       DoAutoSize ();
                        base.OnLayout (e);
 
                        this.SetDisplayedItems ();
@@ -778,22 +879,22 @@ namespace System.Windows.Forms
                {
                        if (mouse_currently_over != null)
                        {
-                               if (this is MenuStrip && !(mouse_currently_over as ToolStripMenuItem).HasDropDownItems) {
-                                       if (!menu_selected)
-                                               (this as MenuStrip).FireMenuActivate ();
-                                       
-                                       return;
-                               }
-                                       
-                               mouse_currently_over.FireEvent (mea, ToolStripItemEventType.MouseDown);
-                               
+                               ToolStripItem focused = GetCurrentlyFocusedItem ();
+
+                               if (focused != null && focused != mouse_currently_over)
+                                       this.FocusInternal (true);
+
                                if (this is MenuStrip && !menu_selected) {
                                        (this as MenuStrip).FireMenuActivate ();
                                        menu_selected = true;                           
                                }
+                                       
+                               mouse_currently_over.FireEvent (mea, ToolStripItemEventType.MouseDown);
+                               
+                               if (this is MenuStrip && mouse_currently_over is ToolStripMenuItem && !(mouse_currently_over as ToolStripMenuItem).HasDropDownItems)
+                                       return;
                        } else {
-                               if (this is MenuStrip)
-                                       this.HideMenus (true, ToolStripDropDownCloseReason.AppClicked);
+                               this.Dismiss (ToolStripDropDownCloseReason.AppClicked);
                        }
                        
                        if (this is MenuStrip)
@@ -860,16 +961,17 @@ namespace System.Windows.Forms
                protected override void OnMouseUp (MouseEventArgs mea)
                {
                        // If we're currently over an item (set in MouseMove)
-                       if (mouse_currently_over != null) {
+                       if (mouse_currently_over != null && !(mouse_currently_over is ToolStripControlHost) && mouse_currently_over.Enabled) {
+                               // Fire our ItemClicked event
+                               OnItemClicked (new ToolStripItemClickedEventArgs (mouse_currently_over));
+                                       
                                // Fire the item's MouseUp event
-                               mouse_currently_over.FireEvent (mea, ToolStripItemEventType.MouseUp);
+                               if (mouse_currently_over != null)
+                                       mouse_currently_over.FireEvent (mea, ToolStripItemEventType.MouseUp);
 
                                // The event handler may have blocked until the mouse moved off of the ToolStripItem
                                if (mouse_currently_over == null)
                                        return;
-                                       
-                               // Fire our ItemClicked event
-                               OnItemClicked (new ToolStripItemClickedEventArgs (mouse_currently_over));
                        }
 
                        base.OnMouseUp (mea);
@@ -883,10 +985,14 @@ namespace System.Windows.Forms
                        this.OnPaintGrip (e);
 
                        // Make each item draw itself
-                       foreach (ToolStripItem tsi in this.displayed_items) {
-                               e.Graphics.TranslateTransform (tsi.Bounds.Left, tsi.Bounds.Top);
-                               tsi.FireEvent (e, ToolStripItemEventType.Paint);
-                               e.Graphics.ResetTransform ();
+                       for (int i = 0; i < displayed_items.Count; i++) {
+                               ToolStripItem tsi = displayed_items[i];
+                               
+                               if (tsi.Visible) {
+                                       e.Graphics.TranslateTransform (tsi.Bounds.Left, tsi.Bounds.Top);
+                                       tsi.FireEvent (e, ToolStripItemEventType.Paint);
+                                       e.Graphics.ResetTransform ();
+                               }
                        }
 
                        // Paint the Overflow button if it's visible
@@ -896,33 +1002,23 @@ namespace System.Windows.Forms
                                e.Graphics.ResetTransform ();
                        }
 
-                       Rectangle affected_bounds = new Rectangle (new Point (0, 0), this.Size);
-                       Rectangle connected_area = Rectangle.Empty;
-
-                       if (this is ToolStripDropDown && (this as ToolStripDropDown).OwnerItem != null && !(this as ToolStripDropDown).OwnerItem.IsOnDropDown)
-                               connected_area = new Rectangle (1, 0, (this as ToolStripDropDown).OwnerItem.Width - 2, 2);
+                       Rectangle affected_bounds = new Rectangle (Point.Empty, this.Size);
 
                        ToolStripRenderEventArgs pevent = new ToolStripRenderEventArgs (e.Graphics, this, affected_bounds, Color.Empty);
-                       pevent.InternalConnectedArea = connected_area;
+                       pevent.InternalConnectedArea = CalculateConnectedArea ();
 
                        this.Renderer.DrawToolStripBorder (pevent);
                }
 
                [EditorBrowsable (EditorBrowsableState.Advanced)]
-               protected override void OnPaintBackground (PaintEventArgs pevent)
+               protected override void OnPaintBackground (PaintEventArgs e)
                {
-                       base.OnPaintBackground (pevent);
-
-                       Rectangle affected_bounds = new Rectangle (new Point (0, 0), this.Size);
-                       Rectangle connected_area = Rectangle.Empty;
+                       base.OnPaintBackground (e);
 
-                       if (this is ToolStripDropDown && (this as ToolStripDropDown).OwnerItem != null && !(this as ToolStripDropDown).OwnerItem.IsOnDropDown)
-                               connected_area = new Rectangle (1, 0, (this as ToolStripDropDown).OwnerItem.Width - 2, 2);
-                       
-                       ToolStripRenderEventArgs e = new ToolStripRenderEventArgs (pevent.Graphics, this, affected_bounds, Color.Empty);
-                       e.InternalConnectedArea = connected_area;
+                       Rectangle affected_bounds = new Rectangle (Point.Empty, this.Size);
+                       ToolStripRenderEventArgs tsrea = new ToolStripRenderEventArgs (e.Graphics, this, affected_bounds, SystemColors.Control);
                        
-                       this.Renderer.DrawToolStripBackground (e);
+                       this.Renderer.DrawToolStripBackground (tsrea);
                }
 
                protected internal virtual void OnPaintGrip (PaintEventArgs e)
@@ -974,16 +1070,22 @@ namespace System.Windows.Forms
 
                protected override void OnVisibleChanged (EventArgs e)
                {
+                       if (!Visible)
+                               CloseToolTip (null);
+
                        base.OnVisibleChanged (e);
                }
 
-               protected override bool ProcessCmdKey (ref Message msg, Keys keyData)
+               protected override bool ProcessCmdKey (ref Message m, Keys keyData)
                {
-                       return base.ProcessCmdKey (ref msg, keyData);
+                       return base.ProcessCmdKey (ref m, keyData);
                }
 
                protected override bool ProcessDialogKey (Keys keyData)
                {
+                       if (!this.KeyboardActive)
+                               return false;
+                               
                        // Give each item a chance to handle the key
                        foreach (ToolStripItem tsi in this.Items)
                                if (tsi.ProcessDialogKey (keyData))
@@ -993,10 +1095,44 @@ namespace System.Windows.Forms
                        if (this.ProcessArrowKey (keyData))
                                return true;
                        
+                       ToolStrip ts = null;
+                       
                        switch (keyData) {
                                case Keys.Escape:
                                        this.Dismiss (ToolStripDropDownCloseReason.Keyboard);
                                        return true;
+                       
+                               case Keys.Control | Keys.Tab:
+                                       ts = ToolStripManager.GetNextToolStrip (this, true);
+                                       
+                                       if (ts != null) {
+                                               foreach (ToolStripItem tsi in this.Items)
+                                                       tsi.Dismiss (ToolStripDropDownCloseReason.Keyboard);
+
+                                               ToolStripManager.SetActiveToolStrip (ts, true);
+                                               ts.SelectNextToolStripItem (null, true);
+                                       }
+                                       
+                                       return true;
+                               case Keys.Control | Keys.Shift | Keys.Tab:
+                                       ts = ToolStripManager.GetNextToolStrip (this, false);
+
+                                       if (ts != null) {
+                                               foreach (ToolStripItem tsi in this.Items)
+                                                       tsi.Dismiss (ToolStripDropDownCloseReason.Keyboard);
+
+                                               ToolStripManager.SetActiveToolStrip (ts, true);
+                                               ts.SelectNextToolStripItem (null, true);
+                                       }
+                                       
+                                       return true;
+                               case Keys.Down:
+                               case Keys.Up:
+                               case Keys.Left:
+                               case Keys.Right:
+                                       if (GetCurrentlySelectedItem () is ToolStripControlHost)
+                                               return false;
+                                       break;
                        }
 
                        return base.ProcessDialogKey (keyData);
@@ -1004,8 +1140,36 @@ namespace System.Windows.Forms
 
                protected override bool ProcessMnemonic (char charCode)
                {
+                       // If any item has an explicit mnemonic, it gets the message
+                       foreach (ToolStripItem tsi in this.Items)
+                               if (tsi.Enabled && tsi.Visible && !string.IsNullOrEmpty (tsi.Text) && Control.IsMnemonic (charCode, tsi.Text))
+                                       return tsi.ProcessMnemonic (charCode);
+
+                       string code = Char.ToUpper (charCode).ToString ();
+                       
+                       // If any item's text starts with our letter, it gets the message
+                       if ((Control.ModifierKeys & Keys.Alt) != 0 || this is ToolStripDropDownMenu)
+                               foreach (ToolStripItem tsi in this.Items)
+                                       if (tsi.Enabled && tsi.Visible && !string.IsNullOrEmpty (tsi.Text) && tsi.Text.ToUpper ().StartsWith (code) && !(tsi is ToolStripControlHost))
+                                               return tsi.ProcessMnemonic (charCode);
+
                        return base.ProcessMnemonic (charCode);
                }
+
+               [MonoTODO ("Stub, does nothing")]
+               [EditorBrowsable (EditorBrowsableState.Advanced)]
+               protected virtual void RestoreFocus ()
+               {
+               }
+
+               protected override void Select (bool directed, bool forward)
+               {
+                       foreach (ToolStripItem tsi in this.DisplayedItems)
+                               if (tsi.CanSelect) {
+                                       tsi.Select ();
+                                       break;
+                               }
+               }
                
                protected override void SetBoundsCore (int x, int y, int width, int height, BoundsSpecified specified)
                {
@@ -1014,7 +1178,7 @@ namespace System.Windows.Forms
 
                protected virtual void SetDisplayedItems ()
                {
-                       this.displayed_items.Clear ();
+                       this.displayed_items.ClearInternal ();
                        
                        foreach (ToolStripItem tsi in this.items)
                                if (tsi.Placement == ToolStripItemPlacement.Main && tsi.Available) {
@@ -1041,20 +1205,20 @@ namespace System.Windows.Forms
                
                protected internal static void SetItemParent (ToolStripItem item, ToolStrip parent)
                {
-                       if (item.Parent != null) {
-                               item.Parent.Items.RemoveNoOwnerOrLayout (item);
-                               
-                               if (item.Parent is ToolStripOverflow)
-                                       (item.Parent as ToolStripOverflow).ParentToolStrip.Items.RemoveNoOwnerOrLayout (item);
+                       if (item.Owner != null) {
+                               item.Owner.Items.RemoveNoOwnerOrLayout (item);
+
+                               if (item.Owner is ToolStripOverflow)
+                                       (item.Owner as ToolStripOverflow).ParentToolStrip.Items.RemoveNoOwnerOrLayout (item);
                        }
                        
                        parent.Items.AddNoOwnerOrLayout (item);
                        item.Parent = parent;
                }
 
-               protected override void SetVisibleCore (bool value)
+               protected override void SetVisibleCore (bool visible)
                {
-                       base.SetVisibleCore (value);
+                       base.SetVisibleCore (visible);
                }
 
                protected override void WndProc (ref Message m)
@@ -1064,6 +1228,8 @@ namespace System.Windows.Forms
                #endregion
 
                #region Public Events
+               static object BeginDragEvent = new object ();
+               static object EndDragEvent = new object ();
                static object ItemAddedEvent = new object ();
                static object ItemClickedEvent = new object ();
                static object ItemRemovedEvent = new object ();
@@ -1079,6 +1245,12 @@ namespace System.Windows.Forms
                        remove { base.AutoSizeChanged -= value; }
                }
 
+               [MonoTODO ("Event never raised")]
+               public event EventHandler BeginDrag {
+                       add { Events.AddHandler (BeginDragEvent, value); }
+                       remove { Events.RemoveHandler (BeginDragEvent, value); }
+               }
+
                [Browsable (false)]
                public new event EventHandler CausesValidationChanged {
                        add { base.CausesValidationChanged += value; }
@@ -1086,12 +1258,14 @@ namespace System.Windows.Forms
                }
 
                [Browsable (false)]
+               [EditorBrowsable (EditorBrowsableState.Never)]
                public new event ControlEventHandler ControlAdded {
                        add { base.ControlAdded += value; }
                        remove { base.ControlAdded -= value; }
                }
 
                [Browsable (false)]
+               [EditorBrowsable (EditorBrowsableState.Never)]
                public new event ControlEventHandler ControlRemoved {
                        add { base.ControlRemoved += value; }
                        remove { base.ControlRemoved -= value; }
@@ -1103,6 +1277,12 @@ namespace System.Windows.Forms
                        remove { base.CursorChanged -= value; }
                }
 
+               [MonoTODO ("Event never raised")]
+               public event EventHandler EndDrag {
+                       add { Events.AddHandler (EndDragEvent, value); }
+                       remove { Events.RemoveHandler (EndDragEvent, value); }
+               }
+
                [Browsable (false)]
                public new event EventHandler ForeColorChanged {
                        add { base.ForeColorChanged += value; }
@@ -1155,23 +1335,41 @@ namespace System.Windows.Forms
                                        
                                        if (value)
                                                Application.KeyboardCapture = this;
-                                       else if (Application.KeyboardCapture == this)
+                                       else if (Application.KeyboardCapture == this) {
                                                Application.KeyboardCapture = null;
+                                               ToolStripManager.ActivatedByKeyboard = false;
+                                       }
+                                       
+                                       // Redraw for mnemonic underlines
+                                       this.Invalidate ();
                                }
                        }
                }
                #endregion
                
                #region Private Methods
+               internal virtual Rectangle CalculateConnectedArea ()
+               {
+                       return Rectangle.Empty;
+               }
+               
                internal void ChangeSelection (ToolStripItem nextItem)
                {
                        if (Application.KeyboardCapture != this)
-                               ToolStripManager.SetActiveToolStrip (this);
+                               ToolStripManager.SetActiveToolStrip (this, ToolStripManager.ActivatedByKeyboard);
                                
                        foreach (ToolStripItem tsi in this.Items)
                                if (tsi != nextItem)
                                        tsi.Dismiss (ToolStripDropDownCloseReason.Keyboard);
-                                       
+
+                       ToolStripItem current = GetCurrentlySelectedItem ();
+
+                       if (current != null && !(current is ToolStripControlHost))
+                               this.FocusInternal (true);
+
+                       if (nextItem is ToolStripControlHost)
+                               (nextItem as ToolStripControlHost).Focus ();
+
                        nextItem.Select ();
                        
                        if (nextItem.Parent is MenuStrip && (nextItem.Parent as MenuStrip).MenuDroppedDown)
@@ -1194,15 +1392,9 @@ namespace System.Windows.Forms
                        // Make sure all of our items are deselected and repainted
                        foreach (ToolStripItem tsi in this.Items)
                                tsi.Dismiss (reason);
-               }
-               
-               private void DoAutoSize ()
-               {
-                       if (this.AutoSize == true && this.Dock == DockStyle.None)
-                               this.Size = GetPreferredSize (Size.Empty);
                                
-                       if (this.AutoSize == true && this.Orientation == Orientation.Horizontal && (this.Dock == DockStyle.Top || this.Dock == DockStyle.Bottom))
-                               this.Height = GetPreferredSize (Size.Empty).Height;
+                       // We probably need to redraw for mnemonic underlines
+                       this.Invalidate ();
                }
 
                internal ToolStripItem GetCurrentlySelectedItem ()
@@ -1214,30 +1406,91 @@ namespace System.Windows.Forms
                        return null;
                }
                
-               public override Size GetPreferredSize (Size proposedSize)
+               internal ToolStripItem GetCurrentlyFocusedItem ()
+               {
+                       foreach (ToolStripItem tsi in this.DisplayedItems)
+                               if ((tsi is ToolStripControlHost) && (tsi as ToolStripControlHost).Control.Focused)
+                                       return tsi;
+
+                       return null;
+               }
+
+               internal override Size GetPreferredSizeCore (Size proposedSize)
+               {
+                       return GetToolStripPreferredSize (proposedSize);
+               }
+               
+               internal virtual Size GetToolStripPreferredSize (Size proposedSize)
                {
-                       Size new_size = new Size (0, this.Height);
+                       Size new_size = Size.Empty;
+
+                       // TODO: This is total duct tape.  We really have to call into the correct
+                       // layout engine, do a dry run of the layout, and find out our true
+                       // preferred dimensions.
+                       if (this.LayoutStyle == ToolStripLayoutStyle.Flow) {
+                               Point currentLocation = Point.Empty;
+                               int tallest = 0;
+                               
+                               foreach (ToolStripItem tsi in items)
+                                       if (tsi.Available) {
+                                               Size tsi_preferred = tsi.GetPreferredSize (Size.Empty);
 
+                                               if ((DisplayRectangle.Width - currentLocation.X) < (tsi_preferred.Width + tsi.Margin.Horizontal)) {
+
+                                                       currentLocation.Y += tallest;
+                                                       tallest = 0;
+                                                       
+                                                       currentLocation.X = DisplayRectangle.Left;
+                                               }
+
+                                               // Offset the left margin and set the control to our point
+                                               currentLocation.Offset (tsi.Margin.Left, 0);
+                                               tallest = Math.Max (tallest, tsi_preferred.Height + tsi.Margin.Vertical);
+                                               
+                                               // Update our location pointer
+                                               currentLocation.X += tsi_preferred.Width + tsi.Margin.Right;
+                                       }
+
+                               currentLocation.Y += tallest;
+                               return new Size (currentLocation.X + this.Padding.Horizontal, currentLocation.Y + this.Padding.Vertical);
+                       }
+                               
                        if (this.orientation == Orientation.Vertical) {
                                foreach (ToolStripItem tsi in this.items)
-                                       if (tsi.GetPreferredSize (Size.Empty).Height + tsi.Margin.Top + tsi.Margin.Bottom > new_size.Height)
-                                               new_size.Height = tsi.GetPreferredSize (Size.Empty).Height + tsi.Margin.Top + tsi.Margin.Bottom;
+                                       if (tsi.Available)  {
+                                               Size tsi_preferred = tsi.GetPreferredSize (Size.Empty);
+                                               new_size.Height += tsi_preferred.Height + tsi.Margin.Top + tsi.Margin.Bottom;
 
-                               new_size.Height += this.Padding.Top + this.Padding.Bottom;
-                               new_size.Width = this.Width;
+                                               if (new_size.Width < (this.Padding.Horizontal + tsi_preferred.Width + tsi.Margin.Horizontal))
+                                                       new_size.Width = (this.Padding.Horizontal + tsi_preferred.Width + tsi.Margin.Horizontal);
+                                       }
+
+                               new_size.Height += (this.GripRectangle.Height + this.GripMargin.Vertical + this.Padding.Vertical + 4);
+                               
+                               if (new_size.Width == 0)
+                                       new_size.Width = ExplicitBounds.Width;
+                                       
+                               return new_size;
                        } else {
                                foreach (ToolStripItem tsi in this.items) 
                                        if (tsi.Available) {
                                                Size tsi_preferred = tsi.GetPreferredSize (Size.Empty);
                                                new_size.Width += tsi_preferred.Width + tsi.Margin.Left + tsi.Margin.Right;
                                                
-                                               if (new_size.Height < (this.Padding.Vertical + tsi_preferred.Height))
-                                                       new_size.Height = (this.Padding.Vertical + tsi_preferred.Height);
+                                               if (new_size.Height < (this.Padding.Vertical + tsi_preferred.Height + tsi.Margin.Vertical))
+                                                       new_size.Height = (this.Padding.Vertical + tsi_preferred.Height + tsi.Margin.Vertical);
                                        }
-                       }
+                                       
+                               new_size.Width += (this.GripRectangle.Width + this.GripMargin.Horizontal + this.Padding.Horizontal + 4);
+
+                               if (new_size.Height == 0)
+                                       new_size.Height = ExplicitBounds.Height;
 
-                       new_size.Width += (this.GripRectangle.Width + this.GripMargin.Horizontal + this.Padding.Horizontal + 4);
-                       return new_size;
+                               if (this is StatusStrip)
+                                       new_size.Height = Math.Max (new_size.Height, 22);
+                                       
+                               return new_size;
+                       }
                }
                
                internal virtual ToolStrip GetTopLevelToolStrip ()
@@ -1245,23 +1498,11 @@ namespace System.Windows.Forms
                        return this;
                }
                
-               internal void HandleItemClick (ToolStripItem dismissingItem)
+               internal virtual void HandleItemClick (ToolStripItem dismissingItem)
                {
                        this.GetTopLevelToolStrip ().Dismiss (ToolStripDropDownCloseReason.ItemClicked);
-                       this.OnItemClicked (new ToolStripItemClickedEventArgs (dismissingItem));
                }
                
-               internal void HideMenus (bool release, ToolStripDropDownCloseReason reason)
-               {
-                       if (this is MenuStrip && release && menu_selected)
-                               (this as MenuStrip).FireMenuDeactivate ();
-                               
-                       if (release)
-                               menu_selected = false;
-                               
-                       NotifySelectedChanged (null);
-               }
-
                internal void NotifySelectedChanged (ToolStripItem tsi)
                {
                        foreach (ToolStripItem tsi2 in this.DisplayedItems)
@@ -1292,49 +1533,101 @@ namespace System.Windows.Forms
 
                internal virtual bool ProcessArrowKey (Keys keyData)
                {
+                       ToolStripItem tsi;
+                       
                        switch (keyData) {
                                case Keys.Right:
+                                       tsi = this.GetCurrentlySelectedItem ();
+                                       
+                                       if (tsi is ToolStripControlHost)
+                                               return false;
+                                       
+                                       tsi = this.SelectNextToolStripItem (tsi, true);
+                                       
+                                       if (tsi is ToolStripControlHost)
+                                               (tsi as ToolStripControlHost).Focus ();
+                                               
+                                       return true;
                                case Keys.Tab:
-                                       this.SelectNextToolStripItem (this.GetCurrentlySelectedItem (), true);
+                                       tsi = this.GetCurrentlySelectedItem ();
+
+                                       tsi = this.SelectNextToolStripItem (tsi, true);
+
+                                       if (tsi is ToolStripControlHost)
+                                               (tsi as ToolStripControlHost).Focus ();
+                                               
                                        return true;
                                case Keys.Left:
+                                       tsi = this.GetCurrentlySelectedItem ();
+
+                                       if (tsi is ToolStripControlHost)
+                                               return false;
+
+                                       tsi = this.SelectNextToolStripItem (tsi, false);
+
+                                       if (tsi is ToolStripControlHost)
+                                               (tsi as ToolStripControlHost).Focus ();
+
+                                       return true;
                                case Keys.Shift | Keys.Tab:
-                                       this.SelectNextToolStripItem (this.GetCurrentlySelectedItem (), false);
+                                       tsi = this.GetCurrentlySelectedItem ();
+                                       
+                                       tsi = this.SelectNextToolStripItem (tsi, false);
+
+                                       if (tsi is ToolStripControlHost)
+                                               (tsi as ToolStripControlHost).Focus ();
+
                                        return true;
                        }
 
                        return false;
                }
 
-               internal virtual void SelectNextToolStripItem (ToolStripItem start, bool forward)
+               internal virtual ToolStripItem SelectNextToolStripItem (ToolStripItem start, bool forward)
                {
                        ToolStripItem next_item = this.GetNextItem (start, forward ? ArrowDirection.Right : ArrowDirection.Left);
                        
+                       if (next_item == null)
+                               return next_item;
+                               
                        this.ChangeSelection (next_item);
+
+                       if (next_item is ToolStripControlHost)
+                               (next_item as ToolStripControlHost).Focus ();
+               
+                       return next_item;
                }
 
                #region Stuff for ToolTips
                private void MouseEnteredItem (ToolStripItem item)
                {
-                       if (this.show_item_tool_tips) {
+                       if (this.show_item_tool_tips && !(item is ToolStripTextBox)) {
+                               ToolTipTimer.Interval = InitialToolTipDelay;
+                               tooltip_state = ToolTip.TipState.Initial;
                                tooltip_currently_showing = item;
                                ToolTipTimer.Start ();
                        }
                }
-               
-               private void MouseLeftItem (ToolStripItem item)
+       
+               private void CloseToolTip (ToolStripItem item)
                {
                        ToolTipTimer.Stop ();
-                       ToolTipWindow.Hide ();
+                       ToolTipWindow.Hide (this);
                        tooltip_currently_showing = null;
+                       tooltip_state = ToolTip.TipState.Down;
                }
-               
+
+               private void MouseLeftItem (ToolStripItem item)
+               {
+                       CloseToolTip (item);
+               }
+
                private Timer ToolTipTimer {
                        get {
                                if (tooltip_timer == null) {
                                        tooltip_timer = new Timer ();
                                        tooltip_timer.Enabled = false;
-                                       tooltip_timer.Interval = 500;
+                                       tooltip_timer.Interval = InitialToolTipDelay;
                                        tooltip_timer.Tick += new EventHandler (ToolTipTimer_Tick);
                                }
                                
@@ -1342,25 +1635,41 @@ namespace System.Windows.Forms
                        }
                }
                
-               private ToolTip.ToolTipWindow ToolTipWindow {
+               private ToolTip ToolTipWindow {
                        get {
                                if (tooltip_window == null)
-                                       tooltip_window = new ToolTip.ToolTipWindow ();
+                                       tooltip_window = new ToolTip ();
                                        
                                return tooltip_window;
                        }
                }
                
-               private void ToolTipTimer_Tick (object o, EventArgs args)
+               private void ShowToolTip ()
                {
                        string tooltip = tooltip_currently_showing.GetToolTip ();
                        
-                       if (!string.IsNullOrEmpty (tooltip))
+                       if (!string.IsNullOrEmpty (tooltip)) {
                                ToolTipWindow.Present (this, tooltip);
+                               ToolTipTimer.Interval = ToolTipDelay;
+                               ToolTipTimer.Start ();
+                               tooltip_state = ToolTip.TipState.Show;
+                       }
 
                        tooltip_currently_showing.FireEvent (EventArgs.Empty, ToolStripItemEventType.MouseHover);
+               }
 
+               private void ToolTipTimer_Tick (object o, EventArgs args)
+               {
                        ToolTipTimer.Stop ();
+
+                       switch (tooltip_state) {
+                               case ToolTip.TipState.Initial:
+                                       ShowToolTip ();
+                                       break;
+                               case ToolTip.TipState.Show:
+                                       CloseToolTip (null);
+                                       break;
+                       }
                }
                #endregion
 
@@ -1401,10 +1710,6 @@ namespace System.Windows.Forms
                                foreach (ToolStripItem tsi in this.Items)
                                        this.pre_merge_items.Add (tsi);
                                }
-                               
-                               if (this is MenuStrip)
-                                       foreach (ToolStripMenuItem tsmi in this.Items)
-                                               tsmi.DropDown.BeginMerge ();
                        }
                }
                
@@ -1441,6 +1746,40 @@ namespace System.Windows.Forms
                }
                #endregion
                #endregion
+
+               #region ToolStripAccessibleObject
+               [ComVisible (true)]
+               public class ToolStripAccessibleObject : ControlAccessibleObject
+               {
+                       #region Public Constructor
+                       public ToolStripAccessibleObject (ToolStrip owner) : base (owner)
+                       {
+                       }
+                       #endregion
+                       
+                       #region Public Properties
+                       public override AccessibleRole Role {
+                               get { return AccessibleRole.ToolBar; }
+                       }
+                       #endregion
+
+                       #region Public Methods
+                       public override AccessibleObject GetChild (int index)
+                       {
+                               return base.GetChild (index);
+                       }
+
+                       public override int GetChildCount ()
+                       {
+                               return (owner as ToolStrip).Items.Count;
+                       }
+
+                       public override AccessibleObject HitTest (int x, int y)
+                       {
+                               return base.HitTest (x, y);
+                       }
+                       #endregion
+               }
+               #endregion
        }
 }
-#endif