e3ba6f155e9e0a67f970d8f2d9cf995948f7b00e
[mono.git] / mcs / class / Managed.Windows.Forms / System.Windows.Forms / TextBox.cs
1 // Permission is hereby granted, free of charge, to any person obtaining
2 // a copy of this software and associated documentation files (the
3 // "Software"), to deal in the Software without restriction, including
4 // without limitation the rights to use, copy, modify, merge, publish,
5 // distribute, sublicense, and/or sell copies of the Software, and to
6 // permit persons to whom the Software is furnished to do so, subject to
7 // the following conditions:
8 // 
9 // The above copyright notice and this permission notice shall be
10 // included in all copies or substantial portions of the Software.
11 // 
12 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
13 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
14 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
15 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
16 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
17 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
18 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19 //
20 // Copyright (c) 2004-2006 Novell, Inc. (http://www.novell.com)
21 //
22 // Authors:
23 //      Peter Bartok    pbartok@novell.com
24 //     Daniel Nauck    (dna(at)mono-project(dot)de)
25 //
26
27 // NOT COMPLETE
28
29 using System;
30 using System.ComponentModel;
31 using System.ComponentModel.Design;
32 using System.Drawing;
33 #if NET_2_0
34 using System.Runtime.InteropServices;
35 #endif
36
37 namespace System.Windows.Forms {
38
39 #if NET_2_0
40         [ComVisible(true)]
41 #endif
42         public class TextBox : TextBoxBase {
43                 #region Variables
44                 private ContextMenu     menu;
45                 private MenuItem        undo;
46                 private MenuItem        cut;
47                 private MenuItem        copy;
48                 private MenuItem        paste;
49                 private MenuItem        delete;
50                 private MenuItem        select_all;
51 #if NET_2_0
52                 private bool use_system_password_char = false;
53                 private AutoCompleteStringCollection auto_complete_custom_source = null;
54                 private AutoCompleteMode auto_complete_mode = AutoCompleteMode.None;
55                 private AutoCompleteSource auto_complete_source = AutoCompleteSource.None;
56 #endif
57                 #endregion      // Variables
58
59                 #region Public Constructors
60                 public TextBox() {
61
62                         scrollbars = RichTextBoxScrollBars.None;
63                         alignment = HorizontalAlignment.Left;
64                         this.LostFocus +=new EventHandler(TextBox_LostFocus);
65                         this.BackColor = ThemeEngine.Current.ColorWindow;
66                         this.ForeColor = ThemeEngine.Current.ColorWindowText;
67
68                         SetStyle (ControlStyles.StandardClick | ControlStyles.StandardDoubleClick, false);
69                         SetStyle (ControlStyles.FixedHeight, true);
70
71                         undo = new MenuItem(Locale.GetText("&Undo"));
72                         cut = new MenuItem(Locale.GetText("Cu&t"));
73                         copy = new MenuItem(Locale.GetText("&Copy"));
74                         paste = new MenuItem(Locale.GetText("&Paste"));
75                         delete = new MenuItem(Locale.GetText("&Delete"));
76                         select_all = new MenuItem(Locale.GetText("Select &All"));
77
78                         menu = new ContextMenu(new MenuItem[] { undo, new MenuItem("-"), cut, copy, paste, delete, new MenuItem("-"), select_all});
79                         ContextMenu = menu;
80
81                         menu.Popup += new EventHandler(menu_Popup);
82                         undo.Click += new EventHandler(undo_Click);
83                         cut.Click += new EventHandler(cut_Click);
84                         copy.Click += new EventHandler(copy_Click);
85                         paste.Click += new EventHandler(paste_Click);
86                         delete.Click += new EventHandler(delete_Click);
87                         select_all.Click += new EventHandler(select_all_Click);
88                 }
89                 #endregion      // Public Constructors
90
91
92                 #region Private & Internal Methods
93                 private void TextBox_LostFocus(object sender, EventArgs e) {
94                         Invalidate();
95                 }
96 #if NET_2_0
97                 void OnAutoCompleteCustomSourceChanged(object sender, CollectionChangeEventArgs e) {
98                         if(auto_complete_source == AutoCompleteSource.CustomSource) {
99                                 //FIXME: handle add, remove and refresh events in AutoComplete algorithm.
100                         }
101                 }
102 #endif
103                 #endregion      // Private & Internal Methods
104
105                 #region Public Instance Properties
106 #if NET_2_0
107                 [MonoTODO("AutoCompletion algorithm is currently not implemented.")]
108                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
109                 [Browsable (true)]
110                 [EditorBrowsable (EditorBrowsableState.Always)]
111                 [Localizable (true)]
112                 public AutoCompleteStringCollection AutoCompleteCustomSource { 
113                         get {
114                                 if(auto_complete_custom_source == null) {
115                                         auto_complete_custom_source = new AutoCompleteStringCollection ();
116                                         auto_complete_custom_source.CollectionChanged += new CollectionChangeEventHandler (OnAutoCompleteCustomSourceChanged);
117                                 }
118                                 return auto_complete_custom_source;
119                         }
120                         set {
121                                 if(auto_complete_custom_source == value)
122                                         return;
123
124                                 if(auto_complete_custom_source != null) //remove eventhandler from old collection
125                                         auto_complete_custom_source.CollectionChanged -= new CollectionChangeEventHandler (OnAutoCompleteCustomSourceChanged);
126
127                                 auto_complete_custom_source = value;
128
129                                 if(auto_complete_custom_source != null)
130                                         auto_complete_custom_source.CollectionChanged += new CollectionChangeEventHandler (OnAutoCompleteCustomSourceChanged);
131                         }
132                 }
133
134                 [MonoTODO("AutoCompletion algorithm is currently not implemented.")]
135                 [Browsable (true)]
136                 [EditorBrowsable (EditorBrowsableState.Always)]
137                 [DefaultValue (AutoCompleteMode.None)]
138                 public AutoCompleteMode AutoCompleteMode {
139                         get { return auto_complete_mode; }
140                         set {
141                                 if(auto_complete_mode == value)
142                                         return;
143
144                                 if((value < AutoCompleteMode.None) || (value > AutoCompleteMode.SuggestAppend))
145                                         throw new InvalidEnumArgumentException (Locale.GetText ("Enum argument value '{0}' is not valid for AutoCompleteMode", value));
146
147                                 auto_complete_mode = value;
148                         }
149                 }
150
151                 [MonoTODO("AutoCompletion algorithm is currently not implemented.")]
152                 [Browsable (true)]
153                 [EditorBrowsable (EditorBrowsableState.Always)]
154                 [DefaultValue (AutoCompleteSource.None)]
155                 public AutoCompleteSource AutoCompleteSource {
156                         get { return auto_complete_source; }
157                         set {
158                                 if(auto_complete_source == value)
159                                         return;
160
161                                 if(!Enum.IsDefined (typeof (AutoCompleteSource), value))
162                                         throw new InvalidEnumArgumentException (Locale.GetText ("Enum argument value '{0}' is not valid for AutoCompleteSource", value));
163
164                                 auto_complete_source = value;
165                         }
166                 }
167
168                 [DefaultValue(false)]
169                 public bool UseSystemPasswordChar {
170                         get {
171                                 return use_system_password_char;
172                         }
173
174                         set {
175                                 use_system_password_char = value;
176                         }
177                 }
178 #endif
179
180                 [DefaultValue(false)]
181                 [MWFCategory("Behavior")]
182                 public bool AcceptsReturn {
183                         get {
184                                 return accepts_return;
185                         }
186
187                         set {
188                                 if (value != accepts_return) {
189                                         accepts_return = value;
190                                 }       
191                         }
192                 }
193
194                 [DefaultValue(CharacterCasing.Normal)]
195                 [MWFCategory("Behavior")]
196                 public CharacterCasing CharacterCasing {
197                         get {
198                                 return character_casing;
199                         }
200
201                         set {
202                                 if (value != character_casing) {
203                                         character_casing = value;
204                                 }
205                         }
206                 }
207
208                 [Localizable(true)]
209                 [DefaultValue('\0')]
210                 [MWFCategory("Behavior")]
211                 public char PasswordChar {
212                         get {
213 #if NET_2_0
214                                 if (use_system_password_char) {
215                                         return '*';
216                                 }
217 #endif
218                                 return password_char;
219                         }
220
221                         set {
222                                 if (value != password_char) {
223                                         password_char = value;
224                                         if (!multiline) {
225                                                 document.PasswordChar = value.ToString();
226                                         } else {
227                                                 document.PasswordChar = "";
228                                         }
229                                 }
230                         }
231                 }
232
233                 [DefaultValue(ScrollBars.None)]
234                 [Localizable(true)]
235                 [MWFCategory("Appearance")]
236                 public ScrollBars ScrollBars {
237                         get {
238                                 return (ScrollBars)scrollbars;
239                         }
240
241                         set {
242                                 if (value != (ScrollBars)scrollbars) {
243                                         scrollbars = (RichTextBoxScrollBars)value;
244                                         base.CalculateScrollBars();
245                                 }
246                         }
247                 }
248
249                 [Browsable(false)]
250                 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
251                 public override int SelectionLength {
252                         get {
253                                 return base.SelectionLength;
254                         }
255                         set {
256                                 base.SelectionLength = value;
257                         }
258                 }
259
260
261                 public override string Text {
262                         get {
263                                 return base.Text;
264                         }
265
266                         set {
267                                 base.Text = value;
268                         }
269                 }
270
271                 [DefaultValue(HorizontalAlignment.Left)]
272                 [Localizable(true)]
273                 [MWFCategory("Appearance")]
274                 public HorizontalAlignment TextAlign {
275                         get {
276                                 return alignment;
277                         }
278
279                         set {
280                                 if (value != alignment) {
281                                         alignment = value;
282
283                                         // MS word-wraps if alignment isn't left
284                                         if (multiline) {
285                                                 if (alignment != HorizontalAlignment.Left) {
286                                                         document.Wrap = true;
287                                                 } else {
288                                                         document.Wrap = word_wrap;
289                                                 }
290                                         }
291
292                                         for (int i = 1; i <= document.Lines; i++) {
293                                                 document.GetLine(i).Alignment = value;
294                                         }
295                                         document.RecalculateDocument(CreateGraphicsInternal());
296                                         OnTextAlignChanged(EventArgs.Empty);
297                                 }
298                         }
299                 }
300                 #endregion      // Public Instance Properties
301
302                 #region Protected Instance Methods
303                 protected override CreateParams CreateParams {
304                         get {
305                                 return base.CreateParams;
306                         }
307                 }
308
309                 protected override ImeMode DefaultImeMode {
310                         get {
311                                 return base.DefaultImeMode;
312                         }
313                 }
314                 #endregion      // Protected Instance Methods
315
316                 #region Protected Instance Methods
317                 protected override bool IsInputKey(Keys keyData) {
318                         return base.IsInputKey (keyData);
319                 }
320
321                 protected override void OnGotFocus(EventArgs e) {
322                         base.OnGotFocus (e);
323                 }
324
325                 protected override void OnHandleCreated(EventArgs e) {
326                         base.OnHandleCreated (e);
327                         SelectAll ();
328                 }
329
330                 protected override void OnMouseUp(MouseEventArgs e) {
331                         base.OnMouseUp (e);
332                 }
333
334                 protected virtual void OnTextAlignChanged(EventArgs e) {
335                         EventHandler eh = (EventHandler)(Events [TextAlignChangedEvent]);
336                         if (eh != null)
337                                 eh (this, e);
338                 }
339
340                 protected override void WndProc(ref Message m) {
341                         base.WndProc(ref m);
342                 }
343                 #endregion      // Protected Instance Methods
344
345                 #region Events
346                 static object TextAlignChangedEvent = new object ();
347
348                 public event EventHandler TextAlignChanged {
349                         add { Events.AddHandler (TextAlignChangedEvent, value); }
350                         remove { Events.RemoveHandler (TextAlignChangedEvent, value); }
351                 }
352                 #endregion      // Events
353
354                 #region Private Methods
355
356                 internal override ContextMenu GetContextMenuInternal ()
357                 {
358                         ContextMenu  res = base.GetContextMenuInternal ();
359                         if (res == menu)
360                                 return null;
361                         return res;
362                 }
363
364                 private void menu_Popup(object sender, EventArgs e) {
365                         if (SelectionLength == 0) {
366                                 cut.Enabled = false;
367                                 copy.Enabled = false;
368                         } else {
369                                 cut.Enabled = true;
370                                 copy.Enabled = true;
371                         }
372
373                         if (SelectionLength == TextLength) {
374                                 select_all.Enabled = false;
375                         } else {
376                                 select_all.Enabled = true;
377                         }
378
379                         if (!CanUndo) {
380                                 undo.Enabled = false;
381                         } else {
382                                 undo.Enabled = true;
383                         }
384                 }
385
386                 private void undo_Click(object sender, EventArgs e) {
387                         Undo();
388                 }
389
390                 private void cut_Click(object sender, EventArgs e) {
391                         Cut();
392                 }
393
394                 private void copy_Click(object sender, EventArgs e) {
395                         Copy();
396                 }
397
398                 private void paste_Click(object sender, EventArgs e) {
399                         Paste();
400                 }
401
402                 private void delete_Click(object sender, EventArgs e) {
403                         SelectedText = "";
404                 }
405
406                 private void select_all_Click(object sender, EventArgs e) {
407                         SelectAll();
408                 }
409                 #endregion      // Private Methods
410
411 #if NET_2_0
412                 public override bool Multiline {
413                         get {
414                                 return base.Multiline;
415                         }
416
417                         set {
418                                 base.Multiline = value;
419                         }
420                 }
421
422                 protected override void OnFontChanged (EventArgs e)
423                 {
424                         base.OnFontChanged (e);
425                 }
426 #endif
427         }
428 }