2008-06-02 Andy Hume <andyhume32@yahoo.co.uk>
[mono.git] / mcs / class / Managed.Windows.Forms / System.Windows.Forms / TextBox.cs
index 223ffa1015d1a1c02575a24bc82ad0cf0d4afaa3..145d9550d165a5a52c2eaab60a14444ea75940d3 100644 (file)
@@ -21,7 +21,7 @@
 //
 // Authors:
 //     Peter Bartok    pbartok@novell.com
-//
+//     Daniel Nauck    (dna(at)mono-project(dot)de)
 //
 
 // NOT COMPLETE
@@ -30,8 +30,17 @@ using System;
 using System.ComponentModel;
 using System.ComponentModel.Design;
 using System.Drawing;
+#if NET_2_0
+using System.Runtime.InteropServices;
+#endif
 
 namespace System.Windows.Forms {
+
+#if NET_2_0
+       [ComVisible(true)]
+       [ClassInterface (ClassInterfaceType.AutoDispatch)]
+       [Designer ("System.Windows.Forms.Design.TextBoxDesigner, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.IDesigner")]
+#endif
        public class TextBox : TextBoxBase {
                #region Variables
                private ContextMenu     menu;
@@ -41,6 +50,13 @@ namespace System.Windows.Forms {
                private MenuItem        paste;
                private MenuItem        delete;
                private MenuItem        select_all;
+
+#if NET_2_0
+               private bool use_system_password_char = false;
+               private AutoCompleteStringCollection auto_complete_custom_source = null;
+               private AutoCompleteMode auto_complete_mode = AutoCompleteMode.None;
+               private AutoCompleteSource auto_complete_source = AutoCompleteSource.None;
+#endif
                #endregion      // Variables
 
                #region Public Constructors
@@ -49,8 +65,11 @@ namespace System.Windows.Forms {
                        scrollbars = RichTextBoxScrollBars.None;
                        alignment = HorizontalAlignment.Left;
                        this.LostFocus +=new EventHandler(TextBox_LostFocus);
-                       this.BackColor = ThemeEngine.Current.ColorWindow;
-                       this.ForeColor = ThemeEngine.Current.ColorWindowText;
+                       this.RightToLeftChanged += new EventHandler (TextBox_RightToLeftChanged);
+
+                       BackColor = SystemColors.Window;
+                       ForeColor = SystemColors.WindowText;
+                       backcolor_set = false;
 
                        SetStyle (ControlStyles.StandardClick | ControlStyles.StandardDoubleClick, false);
                        SetStyle (ControlStyles.FixedHeight, true);
@@ -72,29 +91,161 @@ namespace System.Windows.Forms {
                        paste.Click += new EventHandler(paste_Click);
                        delete.Click += new EventHandler(delete_Click);
                        select_all.Click += new EventHandler(select_all_Click);
+
+                       document.multiline = false;
                }
-               #endregion      // Public Constructors
 
+               #endregion      // Public Constructors
 
                #region Private & Internal Methods
+
+               void TextBox_RightToLeftChanged (object sender, EventArgs e)
+               {
+                       UpdateAlignment ();
+               }
+
                private void TextBox_LostFocus(object sender, EventArgs e) {
-                       has_focus = false;
-                       Invalidate();
+                       if (hide_selection)
+                               document.InvalidateSelectionArea ();
+               }
+
+               private void UpdateAlignment ()
+               {
+                       HorizontalAlignment new_alignment = alignment;
+                       RightToLeft rtol = GetInheritedRtoL ();
+
+                       if (rtol == RightToLeft.Yes) {
+                               if (new_alignment == HorizontalAlignment.Left)
+                                       new_alignment = HorizontalAlignment.Right;
+                               else if (new_alignment == HorizontalAlignment.Right)
+                                       new_alignment = HorizontalAlignment.Left;
+                       }
+
+                       document.alignment = new_alignment;
+
+                       // MS word-wraps if alignment isn't left
+                       if (Multiline) {
+                               if (alignment != HorizontalAlignment.Left) {
+                                       document.Wrap = true;
+                               } else {
+                                       document.Wrap = word_wrap;
+                               }
+                       }
+
+                       for (int i = 1; i <= document.Lines; i++) {
+                               document.GetLine (i).Alignment = new_alignment;
+                       }
+
+                       document.RecalculateDocument (CreateGraphicsInternal ());
+
+                       Invalidate ();  // Make sure we refresh
                }
+
+               internal override Color ChangeBackColor (Color backColor)
+               {
+                       if (backColor == Color.Empty) {
+#if NET_2_0
+                               if (!ReadOnly)
+                                       backColor = SystemColors.Window;
+#else
+                               backColor = SystemColors.Window;
+#endif
+                               backcolor_set = false;
+                       }
+                       return backColor;
+               }
+
+#if NET_2_0
+               void OnAutoCompleteCustomSourceChanged(object sender, CollectionChangeEventArgs e) {
+                       if(auto_complete_source == AutoCompleteSource.CustomSource) {
+                               //FIXME: handle add, remove and refresh events in AutoComplete algorithm.
+                       }
+               }
+#endif
                #endregion      // Private & Internal Methods
 
                #region Public Instance Properties
 #if NET_2_0
-               private bool use_system_password_char = false;
+               [MonoTODO("AutoCompletion algorithm is currently not implemented.")]
+               [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
+               [Browsable (true)]
+               [EditorBrowsable (EditorBrowsableState.Always)]
+               [Localizable (true)]
+               [Editor ("System.Windows.Forms.Design.ListControlStringCollectionEditor, " + Consts.AssemblySystem_Design,
+                "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
+               public AutoCompleteStringCollection AutoCompleteCustomSource { 
+                       get {
+                               if(auto_complete_custom_source == null) {
+                                       auto_complete_custom_source = new AutoCompleteStringCollection ();
+                                       auto_complete_custom_source.CollectionChanged += new CollectionChangeEventHandler (OnAutoCompleteCustomSourceChanged);
+                               }
+                               return auto_complete_custom_source;
+                       }
+                       set {
+                               if(auto_complete_custom_source == value)
+                                       return;
+
+                               if(auto_complete_custom_source != null) //remove eventhandler from old collection
+                                       auto_complete_custom_source.CollectionChanged -= new CollectionChangeEventHandler (OnAutoCompleteCustomSourceChanged);
+
+                               auto_complete_custom_source = value;
+
+                               if(auto_complete_custom_source != null)
+                                       auto_complete_custom_source.CollectionChanged += new CollectionChangeEventHandler (OnAutoCompleteCustomSourceChanged);
+                       }
+               }
+
+               [MonoTODO("AutoCompletion algorithm is currently not implemented.")]
+               [Browsable (true)]
+               [EditorBrowsable (EditorBrowsableState.Always)]
+               [DefaultValue (AutoCompleteMode.None)]
+               public AutoCompleteMode AutoCompleteMode {
+                       get { return auto_complete_mode; }
+                       set {
+                               if(auto_complete_mode == value)
+                                       return;
+
+                               if((value < AutoCompleteMode.None) || (value > AutoCompleteMode.SuggestAppend))
+                                       throw new InvalidEnumArgumentException (Locale.GetText ("Enum argument value '{0}' is not valid for AutoCompleteMode", value));
+
+                               auto_complete_mode = value;
+                       }
+               }
+
+               [MonoTODO("AutoCompletion algorithm is currently not implemented.")]
+               [Browsable (true)]
+               [EditorBrowsable (EditorBrowsableState.Always)]
+               [DefaultValue (AutoCompleteSource.None)]
+               [TypeConverter (typeof (TextBoxAutoCompleteSourceConverter))]
+               public AutoCompleteSource AutoCompleteSource {
+                       get { return auto_complete_source; }
+                       set {
+                               if(auto_complete_source == value)
+                                       return;
+
+                               if(!Enum.IsDefined (typeof (AutoCompleteSource), value))
+                                       throw new InvalidEnumArgumentException (Locale.GetText ("Enum argument value '{0}' is not valid for AutoCompleteSource", value));
+
+                               auto_complete_source = value;
+                       }
+               }
 
                [DefaultValue(false)]
+               [RefreshProperties (RefreshProperties.Repaint)]
                public bool UseSystemPasswordChar {
                        get {
                                return use_system_password_char;
                        }
 
                        set {
-                               use_system_password_char = value;
+                               if (use_system_password_char != value) {
+                                       use_system_password_char = value;
+                                       
+                                       if (!Multiline)
+                                               document.PasswordChar = PasswordChar.ToString ();
+                                       else
+                                               document.PasswordChar = string.Empty;
+                               }
                        }
                }
 #endif
@@ -109,7 +260,7 @@ namespace System.Windows.Forms {
                        set {
                                if (value != accepts_return) {
                                        accepts_return = value;
-                               }       
+                               }
                        }
                }
 
@@ -130,6 +281,9 @@ namespace System.Windows.Forms {
                [Localizable(true)]
                [DefaultValue('\0')]
                [MWFCategory("Behavior")]
+#if NET_2_0
+               [RefreshProperties (RefreshProperties.Repaint)]
+#endif
                public char PasswordChar {
                        get {
 #if NET_2_0
@@ -143,11 +297,12 @@ namespace System.Windows.Forms {
                        set {
                                if (value != password_char) {
                                        password_char = value;
-                                       if (!multiline) {
-                                               document.PasswordChar = value.ToString();
+                                       if (!Multiline) {
+                                               document.PasswordChar = PasswordChar.ToString ();
                                        } else {
-                                               document.PasswordChar = "";
+                                               document.PasswordChar = string.Empty;
                                        }
+                                       this.CalculateDocument();
                                }
                        }
                }
@@ -161,6 +316,10 @@ namespace System.Windows.Forms {
                        }
 
                        set {
+                               if (!Enum.IsDefined (typeof (ScrollBars), value))
+                                       throw new InvalidEnumArgumentException ("value", (int) value,
+                                               typeof (ScrollBars));
+
                                if (value != (ScrollBars)scrollbars) {
                                        scrollbars = (RichTextBoxScrollBars)value;
                                        base.CalculateScrollBars();
@@ -168,6 +327,7 @@ namespace System.Windows.Forms {
                        }
                }
 
+#if ONLY_1_1
                [Browsable(false)]
                [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
                public override int SelectionLength {
@@ -178,7 +338,7 @@ namespace System.Windows.Forms {
                                base.SelectionLength = value;
                        }
                }
-
+#endif
 
                public override string Text {
                        get {
@@ -202,25 +362,23 @@ namespace System.Windows.Forms {
                                if (value != alignment) {
                                        alignment = value;
 
-                                       // MS word-wraps if alignment isn't left
-                                       if (multiline) {
-                                               if (alignment != HorizontalAlignment.Left) {
-                                                       document.Wrap = true;
-                                               } else {
-                                                       document.Wrap = word_wrap;
-                                               }
-                                       }
+                                       UpdateAlignment ();
 
-                                       for (int i = 1; i <= document.Lines; i++) {
-                                               document.GetLine(i).Alignment = value;
-                                       }
-                                       document.RecalculateDocument(CreateGraphicsInternal());
                                        OnTextAlignChanged(EventArgs.Empty);
                                }
                        }
                }
                #endregion      // Public Instance Properties
 
+#if NET_2_0
+               public void Paste (string text)
+               {
+                       document.ReplaceSelection (CaseAdjust (text), false);
+
+                       ScrollToCaret();
+                       OnTextChanged(EventArgs.Empty);
+               }
+#endif
                #region Protected Instance Methods
                protected override CreateParams CreateParams {
                        get {
@@ -228,48 +386,95 @@ namespace System.Windows.Forms {
                        }
                }
 
+#if ONLY_1_1
                protected override ImeMode DefaultImeMode {
                        get {
                                return base.DefaultImeMode;
                        }
                }
-               #endregion      // Protected Instance Methods
+#endif
+#if NET_2_0
+               protected override void Dispose (bool disposing)
+               {
+                       base.Dispose (disposing);
+               }
+#endif
 
-               #region Protected Instance Methods
-               protected override bool IsInputKey(Keys keyData) {
+               protected override bool IsInputKey (Keys keyData)
+               {
                        return base.IsInputKey (keyData);
                }
 
-               protected override void OnGotFocus(EventArgs e) {
-                       has_focus=true;
-                       Invalidate();
+               protected override void OnGotFocus (EventArgs e)
+               {
                        base.OnGotFocus (e);
+                       if (selection_length == -1 && !has_been_focused)
+                               SelectAllNoScroll ();
+                       has_been_focused = true;
                }
 
-               protected override void OnHandleCreated(EventArgs e) {
+               protected override void OnHandleCreated (EventArgs e)
+               {
                        base.OnHandleCreated (e);
                }
 
-               protected override void OnMouseUp(MouseEventArgs e) {
-                       base.OnMouseUp (e);
+#if ONLY_1_1
+               protected override void OnMouseUp(MouseEventArgs mevent)
+               {
+                       base.OnMouseUp (mevent);
                }
+#endif
 
-               protected virtual void OnTextAlignChanged(EventArgs e) {
-                       if (TextAlignChanged != null) {
-                               TextAlignChanged(this, e);
-                       }
+               protected virtual void OnTextAlignChanged (EventArgs e)
+               {
+                       EventHandler eh = (EventHandler)(Events [TextAlignChangedEvent]);
+                       if (eh != null)
+                               eh (this, e);
                }
 
-               protected override void WndProc(ref Message m) {
+               protected override void WndProc (ref Message m)
+               {
+                       switch ((Msg)m.Msg) {
+                               case Msg.WM_LBUTTONDOWN:
+                                       // When the textbox gets focus by LBUTTON (but not by middle or right)
+                                       // it does not do the select all / scroll thing.
+                                       has_been_focused = true;
+                                       FocusInternal (true);
+                                       break;
+                       }
+
                        base.WndProc(ref m);
                }
                #endregion      // Protected Instance Methods
 
                #region Events
-               public event EventHandler TextAlignChanged;
+               static object TextAlignChangedEvent = new object ();
+
+               public event EventHandler TextAlignChanged {
+                       add { Events.AddHandler (TextAlignChangedEvent, value); }
+                       remove { Events.RemoveHandler (TextAlignChangedEvent, value); }
+               }
                #endregion      // Events
 
                #region Private Methods
+
+               internal override ContextMenu ContextMenuInternal {
+                       get {
+                               ContextMenu res = base.ContextMenuInternal;
+                               if (res == menu)
+                                       return null;
+                               return res;
+                       }
+                       set {
+                               base.ContextMenuInternal = value;
+                       }
+               }
+
+               internal void RestoreContextMenu ()
+               {
+                       ContextMenuInternal = menu;
+               }
+
                private void menu_Popup(object sender, EventArgs e) {
                        if (SelectionLength == 0) {
                                cut.Enabled = false;
@@ -290,6 +495,10 @@ namespace System.Windows.Forms {
                        } else {
                                undo.Enabled = true;
                        }
+
+                       if (ReadOnly) {
+                               undo.Enabled = cut.Enabled = paste.Enabled = delete.Enabled = false;
+                       }
                }
 
                private void undo_Click(object sender, EventArgs e) {
@@ -309,12 +518,60 @@ namespace System.Windows.Forms {
                }
 
                private void delete_Click(object sender, EventArgs e) {
-                       SelectedText = "";
+                       SelectedText = string.Empty;
                }
 
                private void select_all_Click(object sender, EventArgs e) {
                        SelectAll();
                }
                #endregion      // Private Methods
+
+#if NET_2_0
+               public override bool Multiline {
+                       get {
+                               return base.Multiline;
+                       }
+
+                       set {
+                               base.Multiline = value;
+                       }
+               }
+
+               protected override void OnBackColorChanged (EventArgs e)
+               {
+                       base.OnBackColorChanged (e);
+               }
+               
+               protected override void OnFontChanged (EventArgs e)
+               {
+                       base.OnFontChanged (e);
+               }
+
+               protected override void OnHandleDestroyed (EventArgs e)
+               {
+                       base.OnHandleDestroyed (e);
+               }
+#endif
        }
+       
+#if NET_2_0
+       internal class TextBoxAutoCompleteSourceConverter : EnumConverter
+       {
+               public TextBoxAutoCompleteSourceConverter(Type type)
+                       : base(type)
+               { }
+
+               public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)
+               {
+                       StandardValuesCollection stdv = base.GetStandardValues(context);
+                       AutoCompleteSource[] arr = new AutoCompleteSource[stdv.Count];
+                       stdv.CopyTo(arr, 0);
+                       AutoCompleteSource[] arr2 = Array.FindAll(arr, delegate (AutoCompleteSource value) {
+                               // No "ListItems" in a TextBox.
+                               return value != AutoCompleteSource.ListItems;
+                       });
+                       return new StandardValuesCollection(arr2);
+               }
+       }
+#endif
 }