2009-07-11 Michael Barker <mike@middlesoft.co.uk>
[mono.git] / mcs / class / Managed.Windows.Forms / System.Windows.Forms / ToolStripTextBox.cs
1 //
2 // ToolStripTextBox.cs
3 //
4 // Permission is hereby granted, free of charge, to any person obtaining
5 // a copy of this software and associated documentation files (the
6 // "Software"), to deal in the Software without restriction, including
7 // without limitation the rights to use, copy, modify, merge, publish,
8 // distribute, sublicense, and/or sell copies of the Software, and to
9 // permit persons to whom the Software is furnished to do so, subject to
10 // the following conditions:
11 // 
12 // The above copyright notice and this permission notice shall be
13 // included in all copies or substantial portions of the Software.
14 // 
15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 //
23 // Copyright (c) 2006 Jonathan Pobst
24 //
25 // Authors:
26 //      Jonathan Pobst (monkey@jpobst.com)
27 //
28 #if NET_2_0
29 using System.Drawing;
30 using System.ComponentModel;
31 using System.Windows.Forms.Design;
32 using System.Runtime.InteropServices;
33
34 namespace System.Windows.Forms
35 {
36         [ToolStripItemDesignerAvailability (ToolStripItemDesignerAvailability.ToolStrip | ToolStripItemDesignerAvailability.MenuStrip | ToolStripItemDesignerAvailability.ContextMenuStrip)]
37         public class ToolStripTextBox : ToolStripControlHost
38         {
39                 private BorderStyle border_style;
40
41                 #region Public Constructors
42                 public ToolStripTextBox () : base (new ToolStripTextBoxControl ())
43                 {
44                         ToolStripTextBoxControl text_box = TextBox as ToolStripTextBoxControl;
45                         text_box.OwnerItem = this;
46                         text_box.border_style = BorderStyle.None;
47                         text_box.TopMargin = 3; // need to explicitly set the margin
48                         text_box.Border = BorderStyle.Fixed3D; // ToolStripTextBoxControl impl, not TextBox
49                         this.border_style = BorderStyle.Fixed3D;
50                 }
51
52                 [EditorBrowsable (EditorBrowsableState.Never)]
53                 public ToolStripTextBox (Control c) : base (c)
54                 {
55                         throw new NotSupportedException ("This construtor cannot be used.");
56                 }
57
58                 public ToolStripTextBox (string name) : this ()
59                 {
60                         base.Name = name;
61                 }
62                 #endregion
63
64                 #region Public Properties
65                 [DefaultValue (false)]
66                 public bool AcceptsReturn {
67                         get { return this.TextBox.AcceptsReturn; }
68                         set { this.TextBox.AcceptsReturn = value; }
69                 }
70
71                 [DefaultValue (false)]
72                 public bool AcceptsTab {
73                         get { return this.TextBox.AcceptsTab; }
74                         set { this.TextBox.AcceptsTab = value; }
75                 }
76
77                 [MonoTODO ("AutoCompletion algorithm is currently not implemented.")]
78                 [Browsable (true)]
79                 [Localizable (true)]
80                 [EditorBrowsable (EditorBrowsableState.Always)]
81                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
82                 [Editor ("System.Windows.Forms.Design.ListControlStringCollectionEditor, " + Consts.AssemblySystem_Design, typeof (System.Drawing.Design.UITypeEditor))]
83                 public AutoCompleteStringCollection AutoCompleteCustomSource {
84                         get { return this.TextBox.AutoCompleteCustomSource; }
85                         set { this.TextBox.AutoCompleteCustomSource = value; }
86                 }
87                 
88                 [MonoTODO("AutoCompletion algorithm is currently not implemented.")]
89                 [Browsable (true)]
90                 [DefaultValue (AutoCompleteMode.None)]
91                 [EditorBrowsable (EditorBrowsableState.Always)]
92                 public AutoCompleteMode AutoCompleteMode {
93                         get { return this.TextBox.AutoCompleteMode; }
94                         set { this.TextBox.AutoCompleteMode = value; }
95                 }
96
97                 [MonoTODO("AutoCompletion algorithm is currently not implemented.")]
98                 [Browsable (true)]
99                 [DefaultValue (AutoCompleteSource.None)]
100                 [EditorBrowsable (EditorBrowsableState.Always)]
101                 public AutoCompleteSource AutoCompleteSource {
102                         get { return this.TextBox.AutoCompleteSource; }
103                         set { this.TextBox.AutoCompleteSource = value; }
104                 }
105
106                 [Browsable (false)]
107                 [EditorBrowsable (EditorBrowsableState.Never)]
108                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
109                 public override Image BackgroundImage {
110                         get { return base.BackgroundImage; }
111                         set { base.BackgroundImage = value; }
112                 }
113
114                 [Browsable (false)]
115                 [EditorBrowsable (EditorBrowsableState.Never)]
116                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
117                 public override ImageLayout BackgroundImageLayout {
118                         get { return base.BackgroundImageLayout; }
119                         set { base.BackgroundImageLayout = value; }
120                 }
121
122                 [DefaultValue (BorderStyle.Fixed3D)]
123                 [DispId (-504)]
124                 public BorderStyle BorderStyle {
125                         get { return this.border_style; }
126                         set { 
127                                 if (this.border_style != value) {
128                                         this.border_style = value;
129                                         (base.Control as ToolStripTextBoxControl).Border = value;
130                                         this.OnBorderStyleChanged (EventArgs.Empty);
131                                 }
132                         }
133                 }
134
135                 [Browsable (false)]
136                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
137                 public bool CanUndo {
138                         get { return this.TextBox.CanUndo; }
139                 }
140
141                 [DefaultValue (CharacterCasing.Normal)]
142                 public CharacterCasing CharacterCasing {
143                         get { return this.TextBox.CharacterCasing; }
144                         set { this.TextBox.CharacterCasing = value; }
145                 }
146
147                 [DefaultValue (true)]
148                 public bool HideSelection {
149                         get { return this.TextBox.HideSelection; }
150                         set { this.TextBox.HideSelection = value; }
151                 }
152
153                 [Localizable (true)]
154                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
155                 [Editor ("System.Windows.Forms.Design.StringArrayEditor, " + Consts.AssemblySystem_Design, typeof (System.Drawing.Design.UITypeEditor))]
156                 public string[] Lines {
157                         get { return this.TextBox.Lines; }
158                         set { this.TextBox.Lines = value; }
159                 }
160
161                 [Localizable (true)]
162                 [DefaultValue (32767)]
163                 public int MaxLength {
164                         get { return this.TextBox.MaxLength; }
165                         set { this.TextBox.MaxLength = value; }
166                 }
167
168                 [Browsable (false)]
169                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
170                 public bool Modified {
171                         get { return this.TextBox.Modified; }
172                         set { this.TextBox.Modified = value; }
173                 }
174
175                 [Localizable (true)]
176                 [Browsable (false)]
177                 [EditorBrowsable (EditorBrowsableState.Never)]
178                 [DefaultValue (false)]
179                 [RefreshProperties (RefreshProperties.All)]
180                 public bool Multiline {
181                         get { return this.TextBox.Multiline; }
182                         set { this.TextBox.Multiline = value; }
183                 }
184
185                 [DefaultValue (false)]
186                 public bool ReadOnly {
187                         get { return this.TextBox.ReadOnly; }
188                         set { this.TextBox.ReadOnly = value; }
189                 }
190
191                 [Browsable (false)]
192                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
193                 public string SelectedText {
194                         get { return this.TextBox.SelectedText; }
195                         set { this.TextBox.SelectedText = value; }
196                 }
197
198                 [Browsable (false)]
199                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
200                 public int SelectionLength {
201                         get { return this.TextBox.SelectionLength == -1 ? 0 : this.TextBox.SelectionLength; }
202                         set { this.TextBox.SelectionLength = value; }
203                 }
204
205                 [Browsable (false)]
206                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
207                 public int SelectionStart {
208                         get { return this.TextBox.SelectionStart; }
209                         set { this.TextBox.SelectionStart = value; }
210                 }
211
212                 [DefaultValue (true)]
213                 public bool ShortcutsEnabled {
214                         get { return this.TextBox.ShortcutsEnabled; }
215                         set { this.TextBox.ShortcutsEnabled = value; }
216                 }
217                 
218                 [Browsable (false)]
219                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
220                 public TextBox TextBox {
221                         get { return (TextBox)base.Control; }
222                 }
223
224                 [Localizable (true)]
225                 [DefaultValue (HorizontalAlignment.Left)]
226                 public HorizontalAlignment TextBoxTextAlign {
227                         get { return this.TextBox.TextAlign; }
228                         set { this.TextBox.TextAlign = value; }
229                 }
230
231                 [Browsable (false)]
232                 public int TextLength {
233                         get { return this.TextBox.TextLength; }
234                 }
235
236                 [Localizable (true)]
237                 [Browsable (false)]
238                 [EditorBrowsable (EditorBrowsableState.Never)]
239                 [DefaultValue (true)]
240                 public bool WordWrap {
241                         get { return this.TextBox.WordWrap; }
242                         set { this.TextBox.WordWrap = value; }
243                 }
244                 #endregion
245
246                 #region Protected Properties
247                 protected internal override Padding DefaultMargin { get { return new Padding (1, 0, 1, 0); } }
248                 protected override Size DefaultSize { get { return new Size (100, 22); } }
249                 #endregion
250
251                 #region Public Methods
252                 public void AppendText (string text)
253                 {
254                         this.TextBox.AppendText (text);
255                 }
256
257                 public void Clear ()
258                 {
259                         this.TextBox.Clear ();
260                 }
261
262                 public void ClearUndo ()
263                 {
264                         this.TextBox.ClearUndo ();
265                 }
266
267                 public void Copy ()
268                 {
269                         this.TextBox.Copy ();
270                 }
271
272                 public void Cut ()
273                 {
274                         this.TextBox.Cut ();
275                 }
276
277                 public void DeselectAll ()
278                 {
279                         this.TextBox.DeselectAll ();
280                 }
281                 
282                 public char GetCharFromPosition (Point pt)
283                 {
284                         return this.TextBox.GetCharFromPosition (pt);
285                 }
286                 
287                 public int GetCharIndexFromPosition (Point pt)
288                 {
289                         return this.TextBox.GetCharIndexFromPosition (pt);
290                 }
291                 
292                 public int GetFirstCharIndexFromLine (int lineNumber)
293                 {
294                         return this.TextBox.GetFirstCharIndexFromLine (lineNumber);
295                 }
296                 
297                 public int GetFirstCharIndexOfCurrentLine ()
298                 {
299                         return this.TextBox.GetFirstCharIndexOfCurrentLine ();
300                 }
301                 
302                 public int GetLineFromCharIndex (int index)
303                 {
304                         return this.TextBox.GetLineFromCharIndex (index);
305                 }
306                 
307                 public Point GetPositionFromCharIndex (int index)
308                 {
309                         return this.TextBox.GetPositionFromCharIndex (index);
310                 }
311                 
312                 public override Size GetPreferredSize (Size constrainingSize)
313                 {
314                         return base.GetPreferredSize (constrainingSize);
315                 }
316
317                 public void Paste ()
318                 {
319                         this.TextBox.Paste ();
320                 }
321
322                 public void ScrollToCaret ()
323                 {
324                         this.TextBox.ScrollToCaret ();
325                 }
326
327                 public void Select (int start, int length)
328                 {
329                         this.TextBox.Select (start, length);
330                 }
331
332                 public void SelectAll ()
333                 {
334                         this.TextBox.SelectAll ();
335                 }
336
337                 public void Undo ()
338                 {
339                         this.TextBox.Undo ();
340                 }
341                 #endregion
342
343                 #region Protected Methods
344                 protected virtual void OnAcceptsTabChanged (EventArgs e)
345                 {
346                         EventHandler eh = (EventHandler)Events [AcceptsTabChangedEvent];
347                         if (eh != null)
348                                 eh (this, e);
349                 }
350
351                 protected virtual void OnBorderStyleChanged (EventArgs e)
352                 {
353                         EventHandler eh = (EventHandler)Events [BorderStyleChangedEvent];
354                         if (eh != null)
355                                 eh (this, e);
356                 }
357
358                 protected virtual void OnHideSelectionChanged (EventArgs e)
359                 {
360                         EventHandler eh = (EventHandler)Events [HideSelectionChangedEvent];
361                         if (eh != null)
362                                 eh (this, e);
363                 }
364
365                 protected virtual void OnModifiedChanged (EventArgs e)
366                 {
367                         EventHandler eh = (EventHandler)Events [ModifiedChangedEvent];
368                         if (eh != null)
369                                 eh (this, e);
370                 }
371
372                 protected virtual void OnMultilineChanged (EventArgs e)
373                 {
374                         EventHandler eh = (EventHandler)Events [MultilineChangedEvent];
375                         if (eh != null)
376                                 eh (this, e);
377                 }
378
379                 protected virtual void OnReadOnlyChanged (EventArgs e)
380                 {
381                         EventHandler eh = (EventHandler)Events [ReadOnlyChangedEvent];
382                         if (eh != null)
383                                 eh (this, e);
384                 }
385
386                 protected override void OnSubscribeControlEvents (Control control)
387                 {
388                         base.OnSubscribeControlEvents (control);
389
390                         this.TextBox.AcceptsTabChanged += new EventHandler (HandleAcceptsTabChanged);
391                         this.TextBox.HideSelectionChanged += new EventHandler (HandleHideSelectionChanged);
392                         this.TextBox.ModifiedChanged += new EventHandler (HandleModifiedChanged);
393                         this.TextBox.MultilineChanged += new EventHandler (HandleMultilineChanged);
394                         this.TextBox.ReadOnlyChanged += new EventHandler (HandleReadOnlyChanged);
395                         this.TextBox.TextAlignChanged += new EventHandler (HandleTextAlignChanged);
396                         this.TextBox.TextChanged += new EventHandler (HandleTextChanged);
397                 }
398
399                 protected override void OnUnsubscribeControlEvents (Control control)
400                 {
401                         base.OnUnsubscribeControlEvents (control);
402                 }
403                 #endregion
404
405                 #region Public Events
406                 static object AcceptsTabChangedEvent = new object ();
407                 static object BorderStyleChangedEvent = new object ();
408                 static object HideSelectionChangedEvent = new object ();
409                 static object ModifiedChangedEvent = new object ();
410                 static object MultilineChangedEvent = new object ();
411                 static object ReadOnlyChangedEvent = new object ();
412                 static object TextBoxTextAlignChangedEvent = new object ();
413
414                 public event EventHandler AcceptsTabChanged {
415                         add { Events.AddHandler (AcceptsTabChangedEvent, value); }
416                         remove {Events.RemoveHandler (AcceptsTabChangedEvent, value); }
417                 }
418                 public event EventHandler BorderStyleChanged {
419                         add { Events.AddHandler (BorderStyleChangedEvent, value); }
420                         remove {Events.RemoveHandler (BorderStyleChangedEvent, value); }
421                 }
422                 public event EventHandler HideSelectionChanged {
423                         add { Events.AddHandler (HideSelectionChangedEvent, value); }
424                         remove {Events.RemoveHandler (HideSelectionChangedEvent, value); }
425                 }
426                 public event EventHandler ModifiedChanged {
427                         add { Events.AddHandler (ModifiedChangedEvent, value); }
428                         remove {Events.RemoveHandler (ModifiedChangedEvent, value); }
429                 }
430                 [Browsable (false)]
431                 [EditorBrowsable (EditorBrowsableState.Never)]
432                 public event EventHandler MultilineChanged {
433                         add { Events.AddHandler (MultilineChangedEvent, value); }
434                         remove {Events.RemoveHandler (MultilineChangedEvent, value); }
435                 }
436                 public event EventHandler ReadOnlyChanged {
437                         add { Events.AddHandler (ReadOnlyChangedEvent, value); }
438                         remove {Events.RemoveHandler (ReadOnlyChangedEvent, value); }
439                 }
440                 public event EventHandler TextBoxTextAlignChanged {
441                         add { Events.AddHandler (TextBoxTextAlignChangedEvent, value); }
442                         remove {Events.RemoveHandler (TextBoxTextAlignChangedEvent, value); }
443                 }
444                 #endregion
445
446                 #region Private Methods
447                 private void HandleTextAlignChanged (object sender, EventArgs e)
448                 {
449                         EventHandler eh = (EventHandler)(Events [TextBoxTextAlignChangedEvent]);
450                         if (eh != null)
451                                 eh (this, e);
452                 }
453
454                 private void HandleReadOnlyChanged (object sender, EventArgs e)
455                 {
456                         OnReadOnlyChanged (e);
457                 }
458
459                 private void HandleMultilineChanged (object sender, EventArgs e)
460                 {
461                         OnMultilineChanged (e);
462                 }
463
464                 private void HandleModifiedChanged (object sender, EventArgs e)
465                 {
466                         OnModifiedChanged (e);
467                 }
468
469                 private void HandleHideSelectionChanged (object sender, EventArgs e)
470                 {
471                         OnHideSelectionChanged (e);
472                 }
473
474                 private void HandleAcceptsTabChanged (object sender, EventArgs e)
475                 {
476                         OnAcceptsTabChanged (e);
477                 }
478
479                 private void HandleTextChanged (object sender, EventArgs e)
480                 {
481                         OnTextChanged (e);
482                 }
483                 #endregion
484
485                 private class ToolStripTextBoxControl : TextBox
486                 {
487                         private BorderStyle border;
488                         private Timer tooltip_timer;
489                         private ToolTip tooltip_window;
490                         private ToolStripItem owner_item;
491                         
492                         public ToolStripTextBoxControl () : base ()
493                         {
494                         }
495
496                         protected override void OnLostFocus (EventArgs e)
497                         {
498                                 base.OnLostFocus (e);
499                                 Invalidate ();
500                         }
501                         
502                         protected override void OnMouseEnter (EventArgs e)
503                         {
504                                 base.OnMouseEnter (e);
505                                 Invalidate ();
506
507                                 if (ShowToolTips)
508                                         ToolTipTimer.Start ();
509
510                         }
511
512                         protected override void OnMouseLeave (EventArgs e)
513                         {
514                                 base.OnMouseLeave (e);
515                                 Invalidate ();
516
517                                 ToolTipTimer.Stop ();
518                                 ToolTipWindow.Hide (this);
519                         }
520
521                         internal override void OnPaintInternal (PaintEventArgs e)
522                         {
523                                 base.OnPaintInternal (e);
524
525                                 if ((this.Focused || this.Entered || border == BorderStyle.FixedSingle) && border != BorderStyle.None) {
526                                         ToolStripRenderer tsr = (this.Parent as ToolStrip).Renderer;
527
528                                         if (tsr is ToolStripProfessionalRenderer)
529                                                 using (Pen p = new Pen ((tsr as ToolStripProfessionalRenderer).ColorTable.ButtonSelectedBorder))
530                                                         e.Graphics.DrawRectangle (p, new Rectangle (0, 0, this.Width - 1, this.Height - 1));
531                                 }
532                         }
533                         
534                         internal BorderStyle Border {
535                                 set {
536                                         border = value;
537                                         Invalidate ();
538                                 }
539                         }
540
541                         internal ToolStripItem OwnerItem {
542                                 set { owner_item = value; }
543                         }
544                                         
545                         #region Stuff for ToolTips
546                         private bool ShowToolTips {
547                                 get {
548                                         if (Parent == null)
549                                                 return false;
550                                                 
551                                         return (Parent as ToolStrip).ShowItemToolTips;
552                                 }
553                         }
554
555                         private Timer ToolTipTimer {
556                                 get {
557                                         if (tooltip_timer == null) {
558                                                 tooltip_timer = new Timer ();
559                                                 tooltip_timer.Enabled = false;
560                                                 tooltip_timer.Interval = 500;
561                                                 tooltip_timer.Tick += new EventHandler (ToolTipTimer_Tick);
562                                         }
563
564                                         return tooltip_timer;
565                                 }
566                         }
567
568                         private ToolTip ToolTipWindow {
569                                 get {
570                                         if (tooltip_window == null)
571                                                 tooltip_window = new ToolTip ();
572
573                                         return tooltip_window;
574                                 }
575                         }
576
577                         private void ToolTipTimer_Tick (object o, EventArgs args)
578                         {
579                                 string tooltip = owner_item.GetToolTip ();
580
581                                 if (!string.IsNullOrEmpty (tooltip))
582                                         ToolTipWindow.Present (this, tooltip);
583
584                                 ToolTipTimer.Stop ();
585                         }
586                         #endregion
587                 }
588         }
589 }
590 #endif