Fixed typo
[mono.git] / mcs / class / Managed.Windows.Forms / System.Windows.Forms / NumericUpDown.cs
index 5d37864c1ba472fb56bbe6a19ef83f6f4225eef5..928535f49dcb21d1e110f46879fa2eb21a45dfb0 100644 (file)
 //     Peter Bartok            <pbartok@novell.com>
 //
 
-// COMPLETE
-
 using System;
 using System.Collections;
 using System.ComponentModel;
 using System.Drawing;
+using System.Globalization;
 using System.Runtime.InteropServices;
 using System.Text;
 using System.Windows.Forms;
@@ -39,6 +38,11 @@ using System.Windows.Forms;
 namespace System.Windows.Forms {
        [DefaultEvent("ValueChanged")]
        [DefaultProperty("Value")]
+#if NET_2_0
+       [DefaultBindingProperty ("Value")]
+       [ClassInterface (ClassInterfaceType.AutoDispatch)]
+       [ComVisible (true)]
+#endif
        public class NumericUpDown : UpDownBase, ISupportInitialize {
                #region Local Variables
                private int     suppress_validation;
@@ -48,7 +52,7 @@ namespace System.Windows.Forms {
                private decimal maximum;
                private decimal minimum;
                private bool    thousands_separator;
-               private decimal value;
+               private decimal dvalue;
                #endregion      // Local Variables
 
                #region Public Constructors
@@ -57,9 +61,11 @@ namespace System.Windows.Forms {
                        decimal_places = 0;
                        hexadecimal = false;
                        increment = 1M;
-                       maximum = 100.0M;
+                       maximum = 100M;
                        minimum = 0.0M;
                        thousands_separator = false;
+
+                       Text = "0";
                }
                #endregion      // Public Constructors
 
@@ -150,9 +156,7 @@ namespace System.Windows.Forms {
 
                        set {
                                decimal_places = value;
-                               if (!UserEdit) {
-                                       UpdateEditText();
-                               }
+                               UpdateEditText();
                        }
                }
 
@@ -164,9 +168,7 @@ namespace System.Windows.Forms {
 
                        set {
                                hexadecimal = value;
-                               if (!UserEdit) {
-                                       UpdateEditText();
-                               }
+                               UpdateEditText();
                        }
                }
 
@@ -196,8 +198,8 @@ namespace System.Windows.Forms {
                                if (minimum > maximum)
                                        minimum = maximum;
 
-                               if (value > maximum)
-                                       value = maximum;
+                               if (dvalue > maximum)
+                                       Value = maximum;
                        }
                }
 
@@ -213,8 +215,8 @@ namespace System.Windows.Forms {
                                if (maximum < minimum)
                                        maximum = minimum;
 
-                               if (value < minimum)
-                                       value = minimum;
+                               if (dvalue < minimum)
+                                       Value = minimum;
                        }
                }
 
@@ -224,11 +226,11 @@ namespace System.Windows.Forms {
                [EditorBrowsable(EditorBrowsableState.Never)]
                public override string Text {
                        get {
-                               return base.txtView.Text;
+                               return base.Text;
                        }
 
                        set {
-                               base.txtView.Text = value;
+                               base.Text = value;
                        }
                }
 
@@ -241,31 +243,30 @@ namespace System.Windows.Forms {
 
                        set {
                                thousands_separator = value;
-
-                               if (!UserEdit) {
-                                       UpdateEditText();
-                               }
+                               UpdateEditText();
                        }
                }
 
                [Bindable(true)]
                public decimal Value {
                        get {
-                               return value;
+                               if (UserEdit)
+                                       dvalue = ParseEditText (Text);
+                               return dvalue;
                        }
 
                        set {
-                               Console.WriteLine ("Getting a: " + value);
                                if (suppress_validation <= 0) {
                                        if ((value < minimum) || (value > maximum)) {
                                                throw new ArgumentException("NumericUpDown.Value must be within the specified Minimum and Maximum values", "value");
                                        }
                                }
-
-                               this.value = value;
-                               OnValueChanged(EventArgs.Empty);
-                               UpdateEditText();
-                       } 
+                               if (value != dvalue) {
+                                       dvalue = value;
+                                       OnValueChanged(EventArgs.Empty);
+                                       Text = UpdateEditText (dvalue);
+                               }
+                       }
                }
                #endregion      // Public Instance Properties
 
@@ -274,14 +275,6 @@ namespace System.Windows.Forms {
                        suppress_validation++;
                }
 
-               public override void DownButton() {
-                       if (UserEdit) {
-                               ParseEditText();
-                       }
-
-                       Value = Math.Max(minimum, unchecked(value - increment));
-               }
-
                public void EndInit() {
                        suppress_validation--;
                        if (suppress_validation == 0)
@@ -289,14 +282,24 @@ namespace System.Windows.Forms {
                }
 
                public override string ToString() {
-                       return string.Format("{0}: value {1} in range [{2}, {3}]", base.ToString(), value, minimum, maximum);
+                       return string.Format("{0}, Minimum = {1}, Maximum = {2}", base.ToString(), minimum, maximum);
+               }
+
+               public override void DownButton() {
+                       decimal val = dvalue;
+                       if (UserEdit) {
+                               val = ParseEditText (Text);
+                       }
+
+                       Value = Math.Max(minimum, unchecked(val - increment));
                }
 
                public override void UpButton() {
+                       decimal val = dvalue;
                        if (UserEdit)
-                               ParseEditText();
+                               val = ParseEditText (Text);
 
-                       Value = Math.Min(maximum, unchecked(value + increment));
+                       Value = Math.Min(maximum, unchecked(val + increment));
                }
                #endregion      // Public Instance Methods
 
@@ -315,59 +318,75 @@ namespace System.Windows.Forms {
                                return;
                        }
 
-                       string acceptable = hexadecimal ? "\b-.,0123456789ABCDEF" : "\b-.,0123456789";
+                       NumberFormatInfo nfi = CultureInfo.CurrentCulture.NumberFormat;
+                       string pressedKey = e.KeyChar.ToString ();
 
-                       if (acceptable.IndexOf(e.KeyChar) < 0) {
-                               // prevent the key from reaching the text box
-                               e.Handled = true;
+                       if ((pressedKey != nfi.NegativeSign) && (pressedKey != nfi.NumberDecimalSeparator) && 
+                               (pressedKey != nfi.NumberGroupSeparator)) {
+                               string acceptable = hexadecimal ? "\b0123456789abcdefABCDEF" : "\b0123456789";
+                               if (acceptable.IndexOf (e.KeyChar) == -1) {
+                                       // FIXME: produce beep to signal that "invalid" key was pressed
+                                       // prevent the key from reaching the text box
+                                       e.Handled = true;
+                               }
                        }
 
                        base.OnTextBoxKeyPress(source, e);
                }
 
                protected virtual void OnValueChanged(EventArgs e) {
-                       if (ValueChanged != null) {
-                               ValueChanged(this, e);
-                       }
+                       EventHandler eh = (EventHandler)(Events [ValueChangedEvent]);
+                       if (eh != null)
+                               eh (this, e);
                }
 
-               protected void ParseEditText() {
+               protected void ParseEditText () {
+                       Value = ParseEditText (Text);
                        UserEdit = false;
+               }
+
+               private decimal ParseEditText (string text) {
+                       UserEdit = false;
+                       decimal ret = dvalue;
 
                        try {
-                               string user_edit_text = Text.Replace(",", "").Trim();
+                               string user_edit_text = text;
 
                                if (!hexadecimal) {
-                                       value = decimal.Parse(user_edit_text);
+                                       ret = decimal.Parse(user_edit_text, CultureInfo.CurrentCulture);
                                } else {
-                                       value = 0M;
-
-                                       for (int i=0; i < user_edit_text.Length; i++) {
-                                               int hex_digit = Convert.ToInt32(user_edit_text.Substring(i, 1), 16);
-
-                                               value = unchecked(value * 16M + (decimal)hex_digit);
-                                       }
+#if !NET_2_0
+                                       ret = Convert.ToDecimal (Convert.ToInt32 (user_edit_text, 16));
+#else
+                                       ret = Convert.ToDecimal (Convert.ToInt32 (user_edit_text, 10));
+#endif
                                }
 
-                               if (value < minimum) {
-                                       value = minimum;
+                               if (ret < minimum) {
+                                       ret = minimum;
                                }
 
-                               if (value > maximum) {
-                                       value = maximum;
+                               if (ret > maximum) {
+                                       ret = maximum;
                                }
-
-                               OnValueChanged(EventArgs.Empty);
                        }
                        catch {}
+                       return ret;
                }
 
                protected override void UpdateEditText() {
+                       Text = UpdateEditText (ParseEditText (Text));
+               }
+
+               private string UpdateEditText (decimal val) {
                        if (suppress_validation > 0)
-                               return;
+                               return Text;
+
+                       decimal ret = val;
+                       string text = Text;
 
                        if (UserEdit)
-                               ParseEditText(); // validate user input
+                               ret = ParseEditText (text); // parse user input
 
                        if (!hexadecimal) {
                                // "N" and "F" differ only in that "N" includes commas
@@ -385,14 +404,14 @@ namespace System.Windows.Forms {
                                format_string += decimal_places;
 
                                ChangingText = true;
-                               Text = value.ToString(format_string);
+                               text = ret.ToString(format_string, CultureInfo.CurrentCulture);
                        }
                        else {
                                // Decimal.ToString doesn't know the "X" formatter, and
                                // converting it to an int is narrowing, so do it
                                // manually...
 
-                               int[] bits = decimal.GetBits(value);
+                               int[] bits = decimal.GetBits(ret);
 
                                bool negative = (bits[3] < 0);
 
@@ -415,12 +434,12 @@ namespace System.Windows.Forms {
                                }
 
                                if (num_chars == 0) {
-                                       ChangingText = true;
-                                       Text = "0";
-                                       return;
+//                                     ChangingText = true;
+                                       text = "0";
+                                       return text;
                                }
 
-                               StringBuilder chars = new StringBuilder();
+                               StringBuilder chars = new StringBuilder ();
 
                                if (negative)
                                        chars.Append('-');
@@ -442,23 +461,39 @@ namespace System.Windows.Forms {
                                        }
                                }
 
-                               ChangingText = true;
-                               Text = chars.ToString();
+//                             ChangingText = true;
+                               text = chars.ToString();
                        }
+                       return text;
                }
 
                protected override void ValidateEditText() {
-                       ParseEditText();
-                       UpdateEditText();
+                       Value = ParseEditText (Text);
                }
+
+#if NET_2_0
+               protected override void OnLostFocus(EventArgs e) {
+                       base.OnLostFocus(e);
+                       if (this.UserEdit)
+                               this.UpdateEditText();
+               }
+#endif
                #endregion      // Protected Instance Methods
 
                #region Events
-               public event EventHandler ValueChanged;
+               static object ValueChangedEvent = new object ();
+
+               public event EventHandler ValueChanged {
+                       add { Events.AddHandler (ValueChangedEvent, value); }
+                       remove { Events.RemoveHandler (ValueChangedEvent, value); }
+               }
 
                [Browsable(false)]
                [EditorBrowsable(EditorBrowsableState.Never)]
-               public event EventHandler TextChanged;
+               public new event EventHandler TextChanged {
+                       add { base.TextChanged += value; }
+                       remove { base.TextChanged -= value; }
+               }
                #endregion      // Events
        }
 }