2007-04-02 Jonathan Pobst <monkey@jpobst.com>
[mono.git] / mcs / class / Managed.Windows.Forms / System.Windows.Forms / DataGridTextBoxColumn.cs
index 8f1dc16024edc9e6e8483ae38c1a402050755b91..ab31cdbb977d2c78b35770b0d19ceae1e035a973 100644 (file)
@@ -24,8 +24,6 @@
 //
 //
 
-// NOT COMPLETE
-
 using System.ComponentModel;
 using System.Drawing;
 using System.Runtime.InteropServices;
@@ -37,217 +35,303 @@ namespace System.Windows.Forms
        {
                #region Local Variables
                private string format;
-               private IFormatProvider format_provider;
+               private IFormatProvider format_provider = null;
                private StringFormat string_format =  new StringFormat ();
+               private DataGridTextBox textbox;
+               private static readonly int offset_x = 2;
+               private static readonly int offset_y = 2;
                #endregion      // Local Variables
 
                #region Constructors
-               public DataGridTextBoxColumn ()
+               public DataGridTextBoxColumn () : this (null, String.Empty, false)
                {
-                       
                }
-               
-               public DataGridTextBoxColumn (PropertyDescriptor prop) : base (prop)
+
+               public DataGridTextBoxColumn (PropertyDescriptor prop) : this (prop, String.Empty, false)
                {
-                       format = string.Empty;
-                       
                }
                
-               // TODO: What is isDefault for?
-               public DataGridTextBoxColumn (PropertyDescriptor prop,  bool isDefault) : base (prop)
+               public DataGridTextBoxColumn (PropertyDescriptor prop,  bool isDefault) : this (prop, String.Empty, isDefault)
                {
-                       format = string.Empty;
                }
-               
-               public DataGridTextBoxColumn (PropertyDescriptor prop,  string format) : base (prop)
+
+               public DataGridTextBoxColumn (PropertyDescriptor prop,  string format) : this (prop, format, false)
                {
-                       this.format = format;                   
                }
                
-               // TODO: What is isDefault for?
                public DataGridTextBoxColumn (PropertyDescriptor prop,  string format, bool isDefault) : base (prop)
                {
-                       this.format = format;
+                       Format = format;
+                       is_default = isDefault;
+
+                       textbox = new DataGridTextBox ();
+                       textbox.Multiline = true;
+                       textbox.WordWrap = false;
+                       textbox.BorderStyle = BorderStyle.None;
+                       textbox.Visible = false;
                }
-               
+
                #endregion
 
                #region Public Instance Properties
+               [Editor("System.Windows.Forms.Design.DataGridColumnStyleFormatEditor, " + Consts.AssemblySystem_Design, typeof(System.Drawing.Design.UITypeEditor))]
+#if NET_2_0
+               [DefaultValue (null)]
+#endif
                public string Format {
-                       get {
-                               return format;
-                       }
+                       get { return format; }
                        set {
                                if (value != format) {
                                        format = value;
+                                       Invalidate ();
                                }
                        }
                }
-               
+
+               [Browsable(false)]
+               [EditorBrowsable(EditorBrowsableState.Advanced)]
                public IFormatProvider FormatInfo {
-                       get {
-                               return format_provider;
-                       }
+                       get { return format_provider; }
                        set {
                                if (value != format_provider) {
                                        format_provider = value;
                                }
                        }
                }
-               
-               public PropertyDescriptor PropertyDescriptor {
-                       set { 
-                               base.PropertyDescriptor = value;
-                       }
+
+               [DefaultValue(null)]
+               public override PropertyDescriptor PropertyDescriptor {
+                       set { base.PropertyDescriptor = value; }
                }
-               
+
                public override bool ReadOnly {
-                       get {
-                               return base.ReadOnly;
-                       }
-                       set {
-                               base.ReadOnly = value;
-                       }
+                       get { return base.ReadOnly; }
+                       set { base.ReadOnly = value; }
                }
                
-               [MonoTODO]
+               [Browsable(false)]
                public virtual TextBox TextBox {
-                       get {
-                               return null;
-                       }                       
+                       get { return textbox; }
                }
                #endregion      // Public Instance Properties
 
                #region Public Instance Methods
-               
-               [MonoTODO]
+
                protected internal override void Abort (int rowNum)
                {
-                       
+                       EndEdit ();                     
                }
                
-               [MonoTODO]
                protected internal override bool Commit (CurrencyManager dataSource, int rowNum)
                {
-                       throw new NotImplementedException ();   
+                       /* Do not write data if not editing. */
+                       if (textbox.IsInEditOrNavigateMode)
+                               return true;
+
+                       try {
+                               string existing_text = GetFormattedValue (dataSource, rowNum);
+
+                               if (existing_text != textbox.Text) {
+                                       if (textbox.Text == NullText)
+                                               SetColumnValueAtRow (dataSource, rowNum, DBNull.Value);
+                                       else
+                                               SetColumnValueAtRow (dataSource, rowNum, textbox.Text);
+                               }
+                       }
+                       catch {
+                               return false;
+                       }
+                       
+                       EndEdit ();                     
+                       return true;
                }
-               
+
                [MonoTODO]
                protected internal override void ConcedeFocus ()
                {
-                       
+                       HideEditBox ();
                }
-               
-               [MonoTODO]
-               protected internal override void Edit (CurrencyManager source, int rowNum,  Rectangle bounds,  bool _readonly, string instantText, bool cellIsVisible)
+
+               protected internal override void Edit (CurrencyManager source, int rowNum,  Rectangle bounds,  bool _ro, string instantText, bool cellIsVisible)
                {
+                       grid.SuspendLayout ();
+
+                       textbox.TextAlign = alignment;
                        
+                       bool ro = false;
+
+                       ro = (TableStyleReadOnly || ReadOnly || _ro);
+
+                       if (!ro && instantText != null) {
+                               textbox.Text = instantText;
+                       }
+                       else {
+                               textbox.Text = GetFormattedValue (source, rowNum);
+                       }
+
+                       textbox.ReadOnly = ro;
+                       textbox.Bounds = new Rectangle (new Point (bounds.X + offset_x, bounds.Y + offset_y),
+                                                       new Size (bounds.Width - offset_x, bounds.Height - offset_y));
+                       textbox.IsInEditOrNavigateMode = ro || instantText == null;
+                       textbox.Visible = cellIsVisible;
+                       textbox.Focus ();
+                       textbox.SelectAll ();
+                       grid.ResumeLayout (false);
                }
-               
-               [MonoTODO]
+
                protected void EndEdit ()
                {
-                       
+                       HideEditBox ();
                }
-               
-               [MonoTODO]
+
                protected internal override void EnterNullValue ()
                {
-                       
+                       textbox.Text = NullText;
                }
-               
+
                protected internal override int GetMinimumHeight ()
                {
                        return FontHeight + 3;
                }
-               
-               [MonoTODO]
+
                protected internal override int GetPreferredHeight (Graphics g, object value)
                {
-                       throw new NotImplementedException ();
+                       string text = GetFormattedValue (value);
+                       System.Text.RegularExpressions.Regex r = new System.Text.RegularExpressions.Regex("/\r\n/");
+                       int lines = r.Matches (text).Count;
+                       return this.DataGridTableStyle.DataGrid.Font.Height * (lines+1) + 1;
                }
-               
-               [MonoTODO]
+
                protected internal override Size GetPreferredSize (Graphics g, object value)
                {
-                       throw new NotImplementedException ();
+                       string text = GetFormattedValue (value);
+                       Size s = Size.Ceiling (g.MeasureString (text, this.DataGridTableStyle.DataGrid.Font));
+                       s.Width += 4;
+                       return s;
                }
-               
+
                [MonoTODO]
                protected void HideEditBox ()
                {
-                       
-               }       
-               
+                       if (textbox.Visible) {
+                               grid.SuspendLayout ();
+                               textbox.Bounds = Rectangle.Empty;
+                               textbox.Visible = false;
+                               textbox.IsInEditOrNavigateMode = true;
+                               grid.ResumeLayout (false);
+                       }
+               }
+
                protected internal override void Paint (Graphics g, Rectangle bounds, CurrencyManager source, int rowNum)
                {
                        Paint (g, bounds, source, rowNum, false);
                }
-               
+
                protected internal override void Paint (Graphics g, Rectangle bounds, CurrencyManager source, int rowNum, bool alignToRight)
                {
-                       Paint (g, bounds, source, rowNum, ThemeEngine.Current.ResPool.GetSolidBrush (DataGridTableStyle.BackColor), 
+                       Paint (g, bounds, source, rowNum, ThemeEngine.Current.ResPool.GetSolidBrush (DataGridTableStyle.BackColor),
                                ThemeEngine.Current.ResPool.GetSolidBrush (DataGridTableStyle.ForeColor), alignToRight);
                }
-                               
+
                protected internal override void Paint (Graphics g, Rectangle bounds, CurrencyManager source, int rowNum, Brush backBrush, Brush foreBrush, bool alignToRight)
                {
-                       object obj;
-                       obj = GetColumnValueAtRow (source, rowNum);
-                       
-                       PaintText (g, bounds, obj.ToString (),  backBrush, foreBrush, alignToRight);
+                       PaintText (g, bounds, GetFormattedValue (source, rowNum),  backBrush, foreBrush, alignToRight);
                }
-                               
-               protected void PaintText (Graphics g, Rectangle bounds, string text,  bool alignToRight)
+
+               protected void PaintText (Graphics g, Rectangle bounds, string text, bool alignToRight)
                {
-                       
-               }               
-               
+                       PaintText (g, bounds, text,  ThemeEngine.Current.ResPool.GetSolidBrush (DataGridTableStyle.BackColor),
+                               ThemeEngine.Current.ResPool.GetSolidBrush (DataGridTableStyle.ForeColor), alignToRight);
+               }
+
                protected void PaintText (Graphics g, Rectangle textBounds, string text, Brush backBrush, Brush foreBrush, bool alignToRight)
-               {                       
+               {
                        if (alignToRight == true) {
                                string_format.FormatFlags |= StringFormatFlags.DirectionRightToLeft;
                        } else {
                                string_format.FormatFlags &= ~StringFormatFlags.DirectionRightToLeft;
                        }
                        
+                       switch (alignment) {
+                       case HorizontalAlignment.Center:
+                               string_format.Alignment = StringAlignment.Center;
+                               break;
+                       case HorizontalAlignment.Right:
+                               string_format.Alignment = StringAlignment.Far;
+                               break;                  
+                       default:
+                               string_format.Alignment = StringAlignment.Near;
+                               break;
+                       }                       
+                                       
+                       g.FillRectangle (backBrush, textBounds);
+                       PaintGridLine (g, textBounds);
+                       
+                       textBounds.Y += offset_y;
+                       textBounds.Height -= offset_y;
+                       
                        string_format.FormatFlags |= StringFormatFlags.NoWrap;
+                       g.DrawString (text, DataGridTableStyle.DataGrid.Font, foreBrush, textBounds, string_format);
                        
-                       g.DrawString (text, DataGridTableStyle.DataGrid.Font, foreBrush, textBounds, string_format);    
                }
                
-               [MonoTODO]
                protected internal override void ReleaseHostedControl ()
-               {
-                       
+               {                       
+                       if (textbox != null) {
+                               grid.SuspendLayout ();
+                               grid.Controls.Remove (textbox);
+                               grid.Invalidate (new Rectangle (textbox.Location, textbox.Size));
+                               textbox.Dispose ();
+                               textbox = null;
+                               grid.ResumeLayout (false);
+                       }
                }
-               
+
                protected override void SetDataGridInColumn (DataGrid value)
                {
-                       base.SetDataGridInColumn (value);                       
-               }
+                       base.SetDataGridInColumn (value);
 
-               [MonoTODO]
+                       if (value != null) {
+                               textbox.SetDataGrid (grid);                     
+                               grid.SuspendLayout ();
+                               grid.Controls.Add (textbox);
+                               grid.ResumeLayout (false);
+                       }
+               }
+               
                protected internal override void UpdateUI (CurrencyManager source, int rowNum, string instantText)
                {
-                       
+                       if (textbox.Visible // I don't really like this, but it gets DataGridTextBoxColumnTest.TestUpdateUI passing
+                           && textbox.IsInEditOrNavigateMode) {
+                               textbox.Text = GetFormattedValue (source, rowNum);
+                       }
+                       else {
+                               textbox.Text = instantText;
+                       }
                }
 
                #endregion      // Public Instance Methods
-               
-               
+
+
                #region Private Instance Methods
-               
-               // We use DataGridTextBox to render everything that DataGridBoolColumn does not
-               internal static bool CanRenderType (Type type)
-               {                       
-                       return (type != typeof (Boolean));
+
+               private string GetFormattedValue (CurrencyManager source, int rowNum)
+               {
+                       object obj = GetColumnValueAtRow (source, rowNum);
+                       return GetFormattedValue (obj);
                }
-               #endregion Private Instance Methods     
 
+               private string GetFormattedValue (object obj)
+               {
+                       if (DBNull.Value.Equals(obj) || obj == null)
+                               return NullText;
+                       
+                       if (format != null && format != String.Empty && obj as IFormattable != null)
+                               return ((IFormattable)obj).ToString (format, format_provider);
 
-               #region Events
+                       return obj.ToString ();
 
-               #endregion      // Events
+               }
+               #endregion Private Instance Methods
        }
 }