2007-01-01 Jonathan Pobst <monkey@jpobst.com>
[mono.git] / mcs / class / Managed.Windows.Forms / System.Windows.Forms / TextBox.cs
index 8cefc0c5d4d33311d1c534e54151b74bcefdb55f..882418e25d452654d83f233fc29f372ecc91a55f 100644 (file)
 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 //
-// Copyright (c) 2004 Novell, Inc. (http://www.novell.com)
+// Copyright (c) 2004-2006 Novell, Inc. (http://www.novell.com)
 //
 // Authors:
 //     Peter Bartok    pbartok@novell.com
-//
+//     Daniel Nauck    (dna(at)mono-project(dot)de)
 //
 
 // NOT COMPLETE
 
 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)]
+#endif
        public class TextBox : TextBoxBase {
-               #region Local Variables
-               internal char                   password_char;
-               #endregion      // Local Variables
+               #region Variables
+               private ContextMenu     menu;
+               private MenuItem        undo;
+               private MenuItem        cut;
+               private MenuItem        copy;
+               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
                public TextBox() {
-                       accepts_return = false;
-                       password_char = '\u25cf';
-                       scrollbars = ScrollBars.None;
+
+                       scrollbars = RichTextBoxScrollBars.None;
                        alignment = HorizontalAlignment.Left;
+                       this.LostFocus +=new EventHandler(TextBox_LostFocus);
+                       this.BackColor = ThemeEngine.Current.ColorWindow;
+                       this.ForeColor = ThemeEngine.Current.ColorWindowText;
+
+                       SetStyle (ControlStyles.StandardClick | ControlStyles.StandardDoubleClick, false);
+                       SetStyle (ControlStyles.FixedHeight, true);
+
+                       undo = new MenuItem(Locale.GetText("&Undo"));
+                       cut = new MenuItem(Locale.GetText("Cu&t"));
+                       copy = new MenuItem(Locale.GetText("&Copy"));
+                       paste = new MenuItem(Locale.GetText("&Paste"));
+                       delete = new MenuItem(Locale.GetText("&Delete"));
+                       select_all = new MenuItem(Locale.GetText("Select &All"));
+
+                       menu = new ContextMenu(new MenuItem[] { undo, new MenuItem("-"), cut, copy, paste, delete, new MenuItem("-"), select_all});
+                       ContextMenu = menu;
+
+                       menu.Popup += new EventHandler(menu_Popup);
+                       undo.Click += new EventHandler(undo_Click);
+                       cut.Click += new EventHandler(cut_Click);
+                       copy.Click += new EventHandler(copy_Click);
+                       paste.Click += new EventHandler(paste_Click);
+                       delete.Click += new EventHandler(delete_Click);
+                       select_all.Click += new EventHandler(select_all_Click);
                }
                #endregion      // Public Constructors
 
+
+               #region Private & Internal Methods
+               private void TextBox_LostFocus(object sender, EventArgs e) {
+                       Invalidate();
+               }
+#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
+               [MonoTODO("AutoCompletion algorithm is currently not implemented.")]
+               [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
+               [Browsable (true)]
+               [EditorBrowsable (EditorBrowsableState.Always)]
+               [Localizable (true)]
+               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)]
+               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)]
+               public bool UseSystemPasswordChar {
+                       get {
+                               return use_system_password_char;
+                       }
+
+                       set {
+                               use_system_password_char = value;
+                       }
+               }
+#endif
+
+               [DefaultValue(false)]
+               [MWFCategory("Behavior")]
                public bool AcceptsReturn {
                        get {
                                return accepts_return;
@@ -57,6 +191,8 @@ namespace System.Windows.Forms {
                        }
                }
 
+               [DefaultValue(CharacterCasing.Normal)]
+               [MWFCategory("Behavior")]
                public CharacterCasing CharacterCasing {
                        get {
                                return character_casing;
@@ -69,30 +205,59 @@ namespace System.Windows.Forms {
                        }
                }
 
+               [Localizable(true)]
+               [DefaultValue('\0')]
+               [MWFCategory("Behavior")]
                public char PasswordChar {
                        get {
+#if NET_2_0
+                               if (use_system_password_char) {
+                                       return '*';
+                               }
+#endif
                                return password_char;
                        }
 
                        set {
                                if (value != password_char) {
                                        password_char = value;
+                                       if (!multiline) {
+                                               document.PasswordChar = value.ToString();
+                                       } else {
+                                               document.PasswordChar = "";
+                                       }
                                }
                        }
                }
 
+               [DefaultValue(ScrollBars.None)]
+               [Localizable(true)]
+               [MWFCategory("Appearance")]
                public ScrollBars ScrollBars {
                        get {
-                               return scrollbars;
+                               return (ScrollBars)scrollbars;
                        }
 
                        set {
-                               if (value != scrollbars) {
-                                       scrollbars = value;
+                               if (value != (ScrollBars)scrollbars) {
+                                       scrollbars = (RichTextBoxScrollBars)value;
+                                       base.CalculateScrollBars();
                                }
                        }
                }
 
+               [Browsable(false)]
+               [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
+               public override int SelectionLength {
+                       get {
+                               return base.SelectionLength;
+                       }
+                       set {
+                               base.SelectionLength = value;
+                       }
+               }
+
+
                public override string Text {
                        get {
                                return base.Text;
@@ -103,6 +268,9 @@ namespace System.Windows.Forms {
                        }
                }
 
+               [DefaultValue(HorizontalAlignment.Left)]
+               [Localizable(true)]
+               [MWFCategory("Appearance")]
                public HorizontalAlignment TextAlign {
                        get {
                                return alignment;
@@ -111,10 +279,20 @@ namespace System.Windows.Forms {
                        set {
                                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;
+                                               }
+                                       }
+
                                        for (int i = 1; i <= document.Lines; i++) {
                                                document.GetLine(i).Alignment = value;
                                        }
-                                       document.RecalculateDocument(CreateGraphics());
+                                       document.RecalculateDocument(CreateGraphicsInternal());
                                        OnTextAlignChanged(EventArgs.Empty);
                                }
                        }
@@ -146,6 +324,7 @@ namespace System.Windows.Forms {
 
                protected override void OnHandleCreated(EventArgs e) {
                        base.OnHandleCreated (e);
+                       SelectAll ();
                }
 
                protected override void OnMouseUp(MouseEventArgs e) {
@@ -153,9 +332,9 @@ namespace System.Windows.Forms {
                }
 
                protected virtual void OnTextAlignChanged(EventArgs e) {
-                       if (TextAlignChanged != null) {
-                               TextAlignChanged(this, e);
-                       }
+                       EventHandler eh = (EventHandler)(Events [TextAlignChangedEvent]);
+                       if (eh != null)
+                               eh (this, e);
                }
 
                protected override void WndProc(ref Message m) {
@@ -164,7 +343,81 @@ namespace System.Windows.Forms {
                #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 GetContextMenuInternal ()
+               {
+                       ContextMenu  res = base.GetContextMenuInternal ();
+                       if (res == menu)
+                               return null;
+                       return res;
+               }
+
+               private void menu_Popup(object sender, EventArgs e) {
+                       if (SelectionLength == 0) {
+                               cut.Enabled = false;
+                               copy.Enabled = false;
+                       } else {
+                               cut.Enabled = true;
+                               copy.Enabled = true;
+                       }
+
+                       if (SelectionLength == TextLength) {
+                               select_all.Enabled = false;
+                       } else {
+                               select_all.Enabled = true;
+                       }
+
+                       if (!CanUndo) {
+                               undo.Enabled = false;
+                       } else {
+                               undo.Enabled = true;
+                       }
+               }
+
+               private void undo_Click(object sender, EventArgs e) {
+                       Undo();
+               }
+
+               private void cut_Click(object sender, EventArgs e) {
+                       Cut();
+               }
+
+               private void copy_Click(object sender, EventArgs e) {
+                       Copy();
+               }
+
+               private void paste_Click(object sender, EventArgs e) {
+                       Paste();
+               }
+
+               private void delete_Click(object sender, EventArgs e) {
+                       SelectedText = "";
+               }
+
+               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;
+                       }
+               }
+#endif
        }
 }