2007-06-06 Jonathan Pobst <monkey@jpobst.com>
[mono.git] / mcs / class / Managed.Windows.Forms / System.Windows.Forms / DataGridTextBoxColumn.cs
index dac9b40039add1de0d6cae543681114d3d5334d0..b1c853ab1b39ac76e14cdff149ab8160808093b1 100644 (file)
 //
 //
 
-// NOT COMPLETE
-
 using System.ComponentModel;
 using System.Drawing;
+using System.Globalization;
 using System.Runtime.InteropServices;
 using System.Diagnostics;
 
@@ -40,8 +39,8 @@ namespace System.Windows.Forms
                private IFormatProvider format_provider = null;
                private StringFormat string_format =  new StringFormat ();
                private DataGridTextBox textbox;
-               private static readonly int offset_x = 0;
-               private static readonly int offset_y = 0;
+               private static readonly int offset_x = 2;
+               private static readonly int offset_y = 2;
                #endregion      // Local Variables
 
                #region Constructors
@@ -77,6 +76,9 @@ namespace System.Windows.Forms
 
                #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; }
                        set {
@@ -118,32 +120,44 @@ namespace System.Windows.Forms
 
                protected internal override void Abort (int rowNum)
                {
-                       EndEdit ();                     
+                       EndEdit ();
                }
                
                protected internal override bool Commit (CurrencyManager dataSource, int rowNum)
                {
+                       textbox.Bounds = Rectangle.Empty;
+
                        /* Do not write data if not editing. */
                        if (textbox.IsInEditOrNavigateMode)
                                return true;
 
                        try {
-                               object obj = GetColumnValueAtRow (dataSource, rowNum);
-                               string existing_text = GetFormattedString (obj);
+                               string existing_text = GetFormattedValue (dataSource, rowNum);
 
                                if (existing_text != textbox.Text) {
-                                       if (textbox.Text == NullText)
+                                       if (textbox.Text == NullText) {
                                                SetColumnValueAtRow (dataSource, rowNum, DBNull.Value);
-                                       else
-                                               SetColumnValueAtRow (dataSource, rowNum, textbox.Text);
+                                       } else {
+                                               object newValue = textbox.Text;
+
+                                               TypeConverter converter = TypeDescriptor.GetConverter (
+                                                       PropertyDescriptor.PropertyType);
+                                               if (converter != null && converter.CanConvertFrom (typeof (string))) {
+                                                       newValue = converter.ConvertFrom (null, CultureInfo.CurrentCulture,
+                                                               textbox.Text);
+                                                       if (converter.CanConvertTo (typeof (string)))
+                                                               textbox.Text = (string) converter.ConvertTo (null, 
+                                                                       CultureInfo.CurrentCulture, newValue, typeof (string));
+                                               }
+
+                                               SetColumnValueAtRow (dataSource, rowNum, newValue);
+                                       }
                                }
-                       }
-                       catch (Exception e) {
-                               Console.WriteLine ("exception!?!?!?! {0}", e);
+                       } catch {
                                return false;
                        }
                        
-                       EndEdit ();                     
+                       EndEdit ();
                        return true;
                }
 
@@ -157,39 +171,41 @@ namespace System.Windows.Forms
                {
                        grid.SuspendLayout ();
 
+                       textbox.TextChanged -= new EventHandler (textbox_TextChanged);
+
                        textbox.TextAlign = alignment;
                        
-                       if ((ParentReadOnly == true)  || 
-                               (ParentReadOnly == false && ReadOnly == true) || 
-                               (ParentReadOnly == false && _ro == true)) {
-                               textbox.ReadOnly = true;
-                       } else {
-                               textbox.ReadOnly = false;
-                       }                       
-                       
-                       if (instantText != null && instantText != "") {
+                       bool ro = false;
+
+                       ro = (TableStyleReadOnly || ReadOnly || _ro);
+
+                       if (!ro && instantText != null) {
                                textbox.Text = instantText;
-                       }
-                       else {
-                               object obj = GetColumnValueAtRow (source, rowNum);
-                               if (obj == null)
-                                       textbox.Text = "";
-                               else
-                                       textbox.Text = GetFormattedString (obj);
+                               textbox.IsInEditOrNavigateMode = false;
+                       } else {
+                               textbox.Text = GetFormattedValue (source, rowNum);
                        }
 
-                       textbox.Location = new Point (bounds.X + offset_x, bounds.Y + offset_y);
-                       textbox.Size = new Size (bounds.Width - offset_x, bounds.Height - offset_y);
+                       textbox.TextChanged += new EventHandler (textbox_TextChanged);
 
-                       textbox.IsInEditOrNavigateMode = true;
+                       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.Visible = cellIsVisible;
-                       textbox.Focus ();
                        textbox.SelectAll ();
+                       textbox.Focus ();
                        grid.ResumeLayout (false);
+
+               }
+
+               void textbox_TextChanged (object o, EventArgs e)
+               {
+                       textbox.IsInEditOrNavigateMode = false;
                }
 
                protected void EndEdit ()
                {
+                       textbox.TextChanged -= new EventHandler (textbox_TextChanged);
                        HideEditBox ();
                }
 
@@ -203,28 +219,33 @@ namespace System.Windows.Forms
                        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);
-                       }
+                       if (!textbox.Visible)
+                               return;
+
+                       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)
@@ -240,10 +261,7 @@ namespace System.Windows.Forms
 
                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, GetFormattedString (obj),  backBrush, foreBrush, alignToRight);
+                       PaintText (g, bounds, GetFormattedValue (source, rowNum),  backBrush, foreBrush, alignToRight);
                }
 
                protected void PaintText (Graphics g, Rectangle bounds, string text, bool alignToRight)
@@ -266,68 +284,85 @@ namespace System.Windows.Forms
                                break;
                        case HorizontalAlignment.Right:
                                string_format.Alignment = StringAlignment.Far;
-                               break;                  
+                               break;
                        default:
                                string_format.Alignment = StringAlignment.Near;
                                break;
-                       }                       
-                                       
+                       }
+                       
                        g.FillRectangle (backBrush, textBounds);
                        PaintGridLine (g, textBounds);
-                       
+
+                       textBounds.X += offset_x;
+                       textBounds.Width -= offset_x;
+
                        textBounds.Y += offset_y;
                        textBounds.Height -= offset_y;
-                       
+
                        string_format.FormatFlags |= StringFormatFlags.NoWrap;
                        g.DrawString (text, DataGridTableStyle.DataGrid.Font, foreBrush, textBounds, string_format);
                        
                }
                
                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);
-                       }
+               {
+                       if (textbox == null)
+                               return;
+
+                       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);
 
-                       if (value != null) {
-                               textbox.SetDataGrid (grid);                     
-                               grid.SuspendLayout ();
-                               grid.Controls.Add (textbox);
-                               grid.ResumeLayout (false);
-                       }
+                       if (value == null)
+                               return;
+
+                       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
 
-               private string GetFormattedString (object obj)
+               private string GetFormattedValue (CurrencyManager source, int rowNum)
                {
-                       if (obj == null)
-                               return "";
+                       object obj = GetColumnValueAtRow (source, rowNum);
+                       return GetFormattedValue (obj);
+               }
 
-                       if (obj == DBNull.Value)
+               private string GetFormattedValue (object obj)
+               {
+                       if (DBNull.Value.Equals(obj) || obj == null)
                                return NullText;
-                       
-                       if (format != null && obj as IFormattable != null) {
-                               return ((IFormattable)obj).ToString (format, format_provider);
-                       }
+
+                       if (format != null && format != String.Empty && obj as IFormattable != null)
+                               return ((IFormattable) obj).ToString (format, format_provider);
+
+                       TypeConverter converter = TypeDescriptor.GetConverter (
+                               PropertyDescriptor.PropertyType);
+                       if (converter != null && converter.CanConvertTo (typeof (string)))
+                               return (string) converter.ConvertTo (null, CultureInfo.CurrentCulture,
+                                       obj, typeof (string));
 
                        return obj.ToString ();