[jit] Enable partial generic sharing when not using AOT as an experiment.
[mono.git] / mcs / class / Managed.Windows.Forms / System.Windows.Forms / TextBoxBase.cs
index ac751da9b71a9317787a48e79fe58ffc491eaf73..e3c1a70f5cfa98867c03c559fb6c6b8c3afcb28b 100644 (file)
@@ -38,11 +38,9 @@ using System.Collections;
 
 namespace System.Windows.Forms
 {
-#if NET_2_0
        [ComVisible (true)]
        [DefaultBindingProperty ("Text")]
        [ClassInterface (ClassInterfaceType.AutoDispatch)]
-#endif
        [DefaultEvent("TextChanged")]
        [Designer("System.Windows.Forms.Design.TextBoxBaseDesigner, " + Consts.AssemblySystem_Design)]
        public abstract class TextBoxBase : Control
@@ -55,7 +53,7 @@ namespace System.Windows.Forms
                internal bool                   backcolor_set;
                internal CharacterCasing        character_casing;
                internal bool                   hide_selection;
-               internal int                    max_length;
+               int                             max_length;
                internal bool                   modified;
                internal char                   password_char;
                internal bool                   read_only;
@@ -154,11 +152,9 @@ namespace System.Windows.Forms
                        ResumeLayout ();
                        
                        SetStyle(ControlStyles.UserPaint | ControlStyles.StandardClick, false);
-#if NET_2_0
                        SetStyle(ControlStyles.UseTextForAccessibility, false);
                        
                        base.SetAutoSizeMode (AutoSizeMode.GrowAndShrink);
-#endif
 
                        canvas_width = ClientSize.Width;
                        canvas_height = ClientSize.Height;
@@ -179,12 +175,10 @@ namespace System.Windows.Forms
                        return s.ToUpper();
                }
 
-#if NET_2_0
                internal override Size GetPreferredSizeCore (Size proposedSize)
                {
                        return new Size (Width, Height);
                }
-#endif
 
                internal override void HandleClick (int clicks, MouseEventArgs me)
                {
@@ -204,6 +198,12 @@ namespace System.Windows.Forms
                                SetStyle (ControlStyles.StandardDoubleClick, false);
                }
 
+               internal override void PaintControlBackground (PaintEventArgs pevent)
+               {
+                       if (!ThemeEngine.Current.TextBoxBaseShouldPaintBackground (this))
+                               return;
+                       base.PaintControlBackground (pevent);
+               }
                #endregion      // Private and Internal Methods
 
                #region Public Instance Properties
@@ -222,21 +222,13 @@ namespace System.Windows.Forms
                        }
                }
 
-#if NET_2_0
                [Browsable (false)]
                [EditorBrowsable (EditorBrowsableState.Never)]
-#endif
                [DefaultValue(true)]
                [Localizable(true)]
                [RefreshProperties(RefreshProperties.Repaint)]
                [MWFCategory("Behavior")]
-               public
-#if NET_2_0
-               override
-#else
-               virtual
-#endif
-               bool AutoSize {
+               public override bool AutoSize {
                        get {
                                return auto_size;
                        }
@@ -245,13 +237,10 @@ namespace System.Windows.Forms
                                if (value != auto_size) {
                                        auto_size = value;
                                        if (auto_size) {
-                                               if (PreferredHeight != ClientSize.Height) {
-                                                       ClientSize = new Size(ClientSize.Width, PreferredHeight);
+                                               if (PreferredHeight != Height) {
+                                                       Height = PreferredHeight;
                                                }
                                        }
-#if NET_1_1
-                                       OnAutoSizeChanged(EventArgs.Empty);
-#endif
                                }
                        }
                }
@@ -336,9 +325,7 @@ namespace System.Windows.Forms
                        }
                }
 
-#if NET_2_0
                [MergableProperty (false)]
-#endif
                [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
                [Editor("System.Windows.Forms.Design.StringArrayEditor, " + Consts.AssemblySystem_Design, typeof(System.Drawing.Design.UITypeEditor))]
                [Localizable(true)]
@@ -374,34 +361,24 @@ namespace System.Windows.Forms
                        }
 
                        set {
-                               int     i;
-                               int     l;
-
-                               document.Empty();
-
-                               l = value.Length;
-
-                               document.SuspendRecalc ();
-                               for (i = 0; i < l; i++) {
-
+                               StringBuilder sb = new StringBuilder ();
+                       
+                               for (int i = 0; i < value.Length; i++) {
                                        // Don't add the last line if it is just an empty line feed
                                        // the line feed is reflected in the previous line's ending 
-                                       if (i == l - 1 && value [i].Length == 0)
+                                       if (i == value.Length - 1 && value[i].Length == 0)
                                                break;
-
-                                       LineEnding ending = LineEnding.Rich;
-                                       if (value [i].EndsWith ("\r"))
-                                               ending = LineEnding.Hard;
-
-                                       document.Add (i + 1, CaseAdjust (value[i]), alignment, Font, this.ForeColor, ending);
+                                               
+                                       sb.Append (value[i] + Environment.NewLine);
                                }
 
-                               document.ResumeRecalc (true);
+                               int newline_length = Environment.NewLine.Length;
 
-                               if (IsHandleCreated)
-                                       CalculateDocument ();
+                               // We want to remove the final new line character
+                               if (sb.Length >= newline_length)
+                                       sb.Remove (sb.Length - newline_length, newline_length);
 
-                               OnTextChanged(EventArgs.Empty);
+                               Text = sb.ToString ();
                        }
                }
 
@@ -489,15 +466,20 @@ namespace System.Windows.Forms
                [Browsable(false)]
                [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
                [EditorBrowsable(EditorBrowsableState.Advanced)]
+               // This returns the preferred outer height, not the client height.
                public int PreferredHeight {
                        get {
-                               return Font.Height + (BorderStyle == BorderStyle.None ? 0 : 7);
+                               int clientDelta = Height - ClientSize.Height;
+                               if (BorderStyle != BorderStyle.None)
+                                       return Font.Height + 7 + clientDelta;
+
+                               // usually in borderless mode the top margin is 0, but
+                               // try to access it, in case it was set manually, as ToolStrip* controls do
+                               return Font.Height + TopMargin + clientDelta;
                        }
                }
 
-#if NET_2_0
                [RefreshProperties (RefreshProperties.Repaint)] 
-#endif
                [DefaultValue(false)]
                [MWFCategory("Behavior")]
                public bool ReadOnly {
@@ -508,14 +490,12 @@ namespace System.Windows.Forms
                        set {
                                if (value != read_only) {
                                        read_only = value;
-#if NET_2_0
                                        if (!backcolor_set) {
                                                if (read_only)
                                                        background_color = SystemColors.Control;
                                                else
                                                        background_color = SystemColors.Window;
                                        }
-#endif
                                        OnReadOnlyChanged(EventArgs.Empty);
                                        Invalidate ();
                                }
@@ -528,14 +508,13 @@ namespace System.Windows.Forms
                        get {
                                string retval = document.GetSelection ();
 
-#if ONLY_1_1
-                               if (!IsHandleCreated && retval == string.Empty)
-                                       return null;
-#endif
                                return retval;
                        }
 
                        set {
+                               if (value == null)
+                                       value = String.Empty;
+
                                document.ReplaceSelection(CaseAdjust(value), false);
 
                                ScrollToCaret();
@@ -549,22 +528,13 @@ namespace System.Windows.Forms
                        get {
                                int res = document.SelectionLength ();
 
-#if !NET_2_0
-                               if (res == 0 && !IsHandleCreated)
-                                       res = -1;
-#endif
-
                                return res;
                        }
 
                        set {
                                if (value < 0) {
                                        string msg = String.Format ("'{0}' is not a valid value for 'SelectionLength'", value);
-#if NET_2_0
                                        throw new ArgumentOutOfRangeException ("SelectionLength", msg);
-#else
-                                       throw new ArgumentException (msg);
-#endif
                                }
 
                                document.InvalidateSelectionArea ();
@@ -598,13 +568,12 @@ namespace System.Windows.Forms
                        set {
                                if (value < 0) {
                                        string msg = String.Format ("'{0}' is not a valid value for 'SelectionStart'", value);
-#if NET_2_0
                                        throw new ArgumentOutOfRangeException ("SelectionStart", msg);
-#else
-                                       throw new ArgumentException (msg);
-#endif
                                }
 
+                               // If SelectionStart has been used, we don't highlight on focus
+                               has_been_focused = true;
+                               
                                document.InvalidateSelectionArea ();
                                document.SetSelectionStart (value, false);
                                if (selection_length > -1)
@@ -616,7 +585,6 @@ namespace System.Windows.Forms
                        }
                }
 
-#if NET_2_0
                [DefaultValue (true)]
                public virtual bool ShortcutsEnabled {
                        get { return shortcuts_enabled; }
@@ -625,7 +593,6 @@ namespace System.Windows.Forms
 
                [Editor ("System.ComponentModel.Design.MultilineStringEditor, " + Consts.AssemblySystem_Design,
                         "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
-#endif
                [Localizable(true)]
                public override string Text {
                        get {
@@ -650,24 +617,21 @@ namespace System.Windows.Forms
                                if (value == Text)
                                        return;
 
+                               document.Empty ();
                                if ((value != null) && (value != "")) {
-
-                                       document.Empty ();
-
                                        document.Insert (document.GetLine (1), 0, false, value);
-                                                       
-                                       document.PositionCaret (document.GetLine (1), 0);
-                                       document.SetSelectionToCaret (true);
-
-                                       ScrollToCaret ();
                                } else {
-                                       document.Empty();
-                                       if (IsHandleCreated)
+                                       if (IsHandleCreated) {
+                                               document.SetSelectionToCaret (true);
                                                CalculateDocument ();
+                                       }
                                }
+                                                       
+                               document.PositionCaret (document.GetLine (1), 0);
+                               document.SetSelectionToCaret (true);
+
+                               ScrollToCaret ();
 
-                               // set the var so OnModifiedChanged is not raised
-                               modified = false;
                                OnTextChanged(EventArgs.Empty);
                        }
                }
@@ -700,7 +664,6 @@ namespace System.Windows.Forms
                        }
                }
 
-#if NET_2_0
                [Browsable (false)]
                [EditorBrowsable (EditorBrowsableState.Never)]
                public override ImageLayout BackgroundImageLayout {
@@ -719,10 +682,18 @@ namespace System.Windows.Forms
                protected override Cursor DefaultCursor {
                        get { return Cursors.IBeam; }
                }
-#endif
                #endregion      // Public Instance Properties
 
                #region Protected Instance Properties
+               protected override bool CanEnableIme {
+                       get {
+                               if (ReadOnly || password_char != '\0')
+                                       return false;
+                                       
+                               return true;
+                       }
+               }
+
                protected override CreateParams CreateParams {
                        get {
                                return base.CreateParams;
@@ -735,14 +706,12 @@ namespace System.Windows.Forms
                        }
                }
 
-#if NET_2_0
                // Currently our double buffering breaks our scrolling, so don't let people enable this
                [EditorBrowsable (EditorBrowsableState.Never)]
                protected override bool DoubleBuffered {
                        get { return false; }
                        set { }
                }
-#endif
 
                #endregion      // Protected Instance Properties
 
@@ -769,12 +738,14 @@ namespace System.Windows.Forms
                        //
                        has_been_focused = true;
 
+                       Modified = false;
                        OnTextChanged(EventArgs.Empty);
                }
 
                public void Clear ()
                {
-                       Text = null;
+                       Modified = false;
+                       Text = string.Empty;
                }
 
                public void ClearUndo ()
@@ -805,6 +776,7 @@ namespace System.Windows.Forms
                        document.ReplaceSelection (String.Empty, false);
                        document.undo.EndUserAction ();
 
+                       Modified = true;
                        OnTextChanged (EventArgs.Empty);
                }
 
@@ -858,22 +830,23 @@ namespace System.Windows.Forms
                        return String.Concat (base.ToString (), ", Text: ", Text);
                }
 
-               [MonoTODO("Deleting is classed as Typing, instead of its own Undo event")]
+               [MonoInternalNote ("Deleting is classed as Typing, instead of its own Undo event")]
                public void Undo ()
                {
-                       if (document.undo.Undo ())
+                       if (document.undo.Undo ()) {
+                               Modified = true;
                                OnTextChanged (EventArgs.Empty);
+                       }
                }
 
-#if NET_2_0
                public void DeselectAll ()
                {
                        SelectionLength = 0;
                }
 
-               public virtual char GetCharFromPosition (Point p)
+               public virtual char GetCharFromPosition (Point pt)
                {
-                       return GetCharFromPositionInternal (p);
+                       return GetCharFromPositionInternal (pt);
                }
                
                internal virtual char GetCharFromPositionInternal (Point p)
@@ -904,10 +877,10 @@ namespace System.Windows.Forms
                        return tag.Line.text [index];
                }
 
-               public virtual int GetCharIndexFromPosition (Point p)
+               public virtual int GetCharIndexFromPosition (Point pt)
                {
                        int line_index;
-                       LineTag tag = document.FindCursor (p.X, p.Y, out line_index);
+                       LineTag tag = document.FindCursor (pt.X, pt.Y, out line_index);
                        if (tag == null)
                                return 0;
 
@@ -944,9 +917,9 @@ namespace System.Windows.Forms
                                        line.Y + document.viewport_y + tag.Shift);
                }
 
-               public int GetFirstCharIndexFromLine (int line_number)
+               public int GetFirstCharIndexFromLine (int lineNumber)
                {
-                       Line line = document.GetLine (line_number + 1);
+                       Line line = document.GetLine (lineNumber + 1);
                        if (line == null)
                                return -1;
                                        
@@ -957,7 +930,6 @@ namespace System.Windows.Forms
                {
                        return document.LineTagToCharIndex (document.caret.line, 0);
                }
-#endif
                #endregion      // Public Instance Methods
 
                #region Protected Instance Methods
@@ -1011,15 +983,6 @@ namespace System.Windows.Forms
                                eh (this, e);
                }
 
-#if ONLY_1_1
-               protected virtual void OnAutoSizeChanged (EventArgs e)
-               {
-                       EventHandler eh = (EventHandler)(Events [AutoSizeChangedEvent]);
-                       if (eh != null)
-                               eh (this, e);
-               }
-#endif
-
                protected virtual void OnBorderStyleChanged (EventArgs e)
                {
                        EventHandler eh = (EventHandler)(Events [BorderStyleChangedEvent]);
@@ -1032,7 +995,7 @@ namespace System.Windows.Forms
                        base.OnFontChanged (e);
 
                        if (auto_size && !document.multiline) {
-                               if (PreferredHeight != ClientSize.Height) {
+                               if (PreferredHeight != Height) {
                                        Height = PreferredHeight;
                                }
                        }
@@ -1070,12 +1033,10 @@ namespace System.Windows.Forms
                                eh (this, e);
                }
 
-#if NET_2_0
                protected override void OnPaddingChanged (EventArgs e)
                {
                        base.OnPaddingChanged (e);
                }
-#endif
 
                protected virtual void OnReadOnlyChanged (EventArgs e)
                {
@@ -1084,14 +1045,18 @@ namespace System.Windows.Forms
                                eh (this, e);
                }
 
-#if NET_2_0
                protected override bool ProcessCmdKey (ref Message msg, Keys keyData)
                {
                        return base.ProcessCmdKey (ref msg, keyData);
                }
-#endif
                protected override bool ProcessDialogKey (Keys keyData)
                {
+                       // The user can use Ctrl-Tab or Ctrl-Shift-Tab to move control focus
+                       // instead of inserting a Tab.  However, the focus-moving-tab-stuffs
+                       // doesn't work if Ctrl is pushed, so we remove it before sending it.
+                       if (accepts_tab && (keyData & (Keys.Control | Keys.Tab)) == (Keys.Control | Keys.Tab))
+                               keyData ^= Keys.Control;
+                               
                        return base.ProcessDialogKey(keyData);
                }
 
@@ -1205,10 +1170,13 @@ namespace System.Windows.Forms
                                                }
                                        }
 
-                                       OnTextChanged(EventArgs.Empty);
                                        document.AlignCaret();
                                        document.UpdateCaret();
                                        CaretMoved(this, null);
+
+                                       Modified = true;
+                                       OnTextChanged (EventArgs.Empty);
+               
                                        return true;
                                }
                        }
@@ -1359,8 +1327,10 @@ namespace System.Windows.Forms
                                        if (!read_only && accepts_tab && document.multiline) {
                                                document.InsertCharAtCaret ('\t', true);
 
-                                               OnTextChanged(EventArgs.Empty);
                                                CaretMoved(this, null);
+                                               Modified = true;
+                                               OnTextChanged (EventArgs.Empty);
+
                                                return true;
                                        }
                                        break;
@@ -1390,6 +1360,11 @@ namespace System.Windows.Forms
                        return false;
                }
 
+               internal virtual void RaiseSelectionChanged ()
+               {
+                       // Do nothing, overridden in RTB
+               }
+               
                private void HandleBackspace (bool control)
                {
                        bool    fire_changed;
@@ -1454,9 +1429,12 @@ namespace System.Windows.Forms
                                }
                        }
 
-                       if (fire_changed)
+                       CaretMoved (this, null);
+
+                       if (fire_changed) {
+                               Modified = true;
                                OnTextChanged(EventArgs.Empty);
-                       CaretMoved(this, null);
+                       }
                }
 
                private void HandleEnter ()
@@ -1471,13 +1449,13 @@ namespace System.Windows.Forms
                                line = document.CaretLine;
 
                                document.Split (document.CaretLine, document.CaretTag, document.CaretPosition);
-                               line.ending = LineEnding.Rich;
+                               line.ending = document.StringToLineEnding (Environment.NewLine);
                                document.InsertString (line, line.text.Length, document.LineEndingToString (line.ending));
                                
-                               OnTextChanged (EventArgs.Empty);
-
                                document.UpdateView (line, document.Lines - line.line_no, 0);
                                CaretMoved (this, null);
+                               Modified = true;
+                               OnTextChanged (EventArgs.Empty);
                        }
                }
                
@@ -1552,13 +1530,13 @@ namespace System.Windows.Forms
 
                                        if (document.Length < max_length) {
                                                document.InsertCharAtCaret(c, true);
-#if NET_2_0
                                                OnTextUpdate ();
-#endif
+                                               CaretMoved (this, null);
+                                               Modified = true;
                                                OnTextChanged(EventArgs.Empty);
-                                               CaretMoved(this, null);
+
                                        } else {
-                                               XplatUI.AudibleAlert();
+                                               XplatUI.AudibleAlert(AlertType.Default);
                                        }
                                        return;
                                } else if (ch == 8) {
@@ -1579,6 +1557,11 @@ namespace System.Windows.Forms
                                document.CaretLostFocus ();
                                break;
 
+                       case Msg.WM_NCPAINT:
+                               if (!ThemeEngine.Current.TextBoxBaseHandleWmNcPaint (this, ref m))
+                                       base.WndProc(ref m);
+                               break;
+
                        default:
                                base.WndProc(ref m);
                                return;
@@ -1603,10 +1586,8 @@ namespace System.Windows.Forms
                        remove { Events.RemoveHandler (AcceptsTabChangedEvent, value); }
                }
 
-#if NET_2_0
                [Browsable (false)]
                [EditorBrowsable (EditorBrowsableState.Never)]
-#endif
                public new event EventHandler AutoSizeChanged {
                        add { Events.AddHandler (AutoSizeChangedEvent, value); }
                        remove { Events.RemoveHandler (AutoSizeChangedEvent, value); }
@@ -1654,7 +1635,6 @@ namespace System.Windows.Forms
                        remove { base.BackgroundImageChanged -= value; }
                }
 
-#if NET_2_0
                [Browsable (false)]
                [EditorBrowsable (EditorBrowsableState.Never)]
                public new event EventHandler BackgroundImageLayoutChanged {
@@ -1679,19 +1659,19 @@ namespace System.Windows.Forms
 
                [Browsable (true)]
                [EditorBrowsable (EditorBrowsableState.Always)]
-#else
-               [Browsable(false)]
-               [EditorBrowsable(EditorBrowsableState.Advanced)]
-#endif
                public new event EventHandler Click {
                        add { base.Click += value; }
                        remove { base.Click -= value; }
                }
 
                // XXX should this not manipulate base.Paint?
+#pragma warning disable 0067
+               [MonoTODO]
                [Browsable(false)]
                [EditorBrowsable(EditorBrowsableState.Never)]
                public new event PaintEventHandler Paint;
+#pragma warning restore 0067
+
                #endregion      // Events
 
                #region Private Methods
@@ -1737,6 +1717,27 @@ namespace System.Windows.Forms
                        }
                }
 
+               internal int TopMargin {
+                       get {
+                               return document.top_margin;
+                       }
+                       set {
+                               document.top_margin = value;
+                       }
+               }
+
+               #region UIA Framework Properties
+
+               internal ScrollBar UIAHScrollBar {
+                       get { return hscroll; }
+               }
+
+               internal ScrollBar UIAVScrollBar {
+                       get { return vscroll; }
+               }
+
+               #endregion UIA Framework Properties
+
                internal Graphics CreateGraphicsInternal ()
                {
                        if (IsHandleCreated)
@@ -1747,15 +1748,7 @@ namespace System.Windows.Forms
 
                internal override void OnPaintInternal (PaintEventArgs pevent)
                {
-                       // Fill background
-                       if (backcolor_set || (Enabled && !read_only)) {
-                               pevent.Graphics.FillRectangle(ThemeEngine.Current.ResPool.GetSolidBrush(BackColor), pevent.ClipRectangle);
-                       } else {
-                               pevent.Graphics.FillRectangle(ThemeEngine.Current.ResPool.GetSolidBrush(ThemeEngine.Current.ColorControl), pevent.ClipRectangle);
-                       }
-                       
-                       // Draw the viewable document
-                       document.Draw(pevent.Graphics, pevent.ClipRectangle);
+                       Draw (pevent.Graphics, pevent.ClipRectangle);
 
                        //
                        // OnPaint does not get raised on MS (see bug #80639)
@@ -1763,12 +1756,20 @@ namespace System.Windows.Forms
                        pevent.Handled = true;
                }
 
+               internal void Draw (Graphics g, Rectangle clippingArea)
+               {
+                       ThemeEngine.Current.TextBoxBaseFillBackground (this, g, clippingArea);
+                       
+                       // Draw the viewable document
+                       document.Draw(g, clippingArea);
+               }
+
                private void FixupHeight ()
                {
                        if (!richtext) {
                                if (!document.multiline) {
-                                       if (PreferredHeight != ClientSize.Height) {
-                                               ClientSize = new Size (ClientSize.Width, PreferredHeight);
+                                       if (PreferredHeight != Height) {
+                                               Height = PreferredHeight;
                                        }
                                }
                        }
@@ -1875,6 +1876,10 @@ namespace System.Windows.Forms
                                if (click_mode == CaretSelection.Position) {
                                        document.SetSelectionToCaret(false);
                                        document.DisplayCaret();
+                                       
+                                       // Only raise if there is text.
+                                       if (Text.Length > 0)
+                                               RaiseSelectionChanged ();
                                }
 
                                if (scroll_timer != null) {
@@ -2064,7 +2069,10 @@ namespace System.Windows.Forms
                                switch (scrollbars) {
                                case RichTextBoxScrollBars.Both:
                                case RichTextBoxScrollBars.Horizontal:
-                                       hscroll.Visible = hscroll.Enabled;
+                                       if (richtext)
+                                               hscroll.Visible = hscroll.Enabled;
+                                       else
+                                               hscroll.Visible = this.Multiline;
                                        break;
                                case RichTextBoxScrollBars.ForcedBoth:
                                case RichTextBoxScrollBars.ForcedHorizontal:
@@ -2081,12 +2089,10 @@ namespace System.Windows.Forms
                        switch (scrollbars) {
                        case RichTextBoxScrollBars.Both:
                        case RichTextBoxScrollBars.Vertical:
-
-                               if (richtext) {
+                               if (richtext)
                                        vscroll.Visible = vscroll.Enabled;
-                               } else {
-                                       vscroll.Visible = true;
-                               }
+                               else 
+                                       vscroll.Visible = this.Multiline;
                                break;
                        case RichTextBoxScrollBars.ForcedBoth:
                        case RichTextBoxScrollBars.ForcedVertical:
@@ -2224,11 +2230,7 @@ namespace System.Windows.Forms
                        }
 
                        if (found_link == false) {
-#if NET_2_0
                                XplatUI.SetCursor (window.Handle, DefaultCursor.handle);
-#else
-                               XplatUI.SetCursor(window.Handle, Cursors.IBeam.handle);
-#endif
                                current_link = null;
                        }
                }
@@ -2306,7 +2308,7 @@ namespace System.Windows.Forms
                                if (pos.X < (document.ViewPortX)) {
                                        do {
                                                if ((hscroll.Value - document.ViewPortWidth / 3) >= hscroll.Minimum) {
-                                                       hscroll.Value -= document.ViewPortWidth / 3;
+                                                       hscroll.SafeValueSet (hscroll.Value - document.ViewPortWidth / 3);
                                                } else {
                                                        hscroll.Value = hscroll.Minimum;
                                                }
@@ -2317,7 +2319,7 @@ namespace System.Windows.Forms
                                if ((pos.X >= (document.ViewPortWidth + document.ViewPortX)) && (hscroll.Value != hscroll.Maximum)) {
                                        if ((pos.X - document.ViewPortWidth + 1) <= hscroll.Maximum) {
                                                if (pos.X - document.ViewPortWidth >= 0) {
-                                                       hscroll.Value = pos.X - document.ViewPortWidth + 1;
+                                                       hscroll.SafeValueSet (pos.X - document.ViewPortWidth + 1);
                                                } else {
                                                        hscroll.Value = 0;
                                                }
@@ -2335,6 +2337,9 @@ namespace System.Windows.Forms
                                // FIXME - implement center cursor alignment
                        }
 
+                       if (Text.Length > 0)
+                               RaiseSelectionChanged ();
+                       
                        if (!document.multiline)
                                return;
 
@@ -2342,7 +2347,7 @@ namespace System.Windows.Forms
                        height = document.CaretLine.Height + 1;
 
                        if (pos.Y < document.ViewPortY)
-                               vscroll.Value = pos.Y;
+                               vscroll.SafeValueSet (pos.Y);
                        if ((pos.Y + height) > (document.ViewPortY + canvas_height))
                                vscroll.Value = Math.Min (vscroll.Maximum, pos.Y - canvas_height + height);
                }
@@ -2380,6 +2385,7 @@ namespace System.Windows.Forms
                                document.undo.BeginUserAction (Locale.GetText ("Paste"));
                                ((RichTextBox)this).SelectedRtf = (string)clip.GetData(DataFormats.Rtf);
                                document.undo.EndUserAction ();
+                               Modified = true;
                                return true;
                        } else if (format.Name == DataFormats.Bitmap) {
                                document.undo.BeginUserAction (Locale.GetText ("Paste"));
@@ -2400,21 +2406,25 @@ namespace System.Windows.Forms
                                this.SelectedText = s;
                                document.undo.EndUserAction ();
                        } else {
-                               if ((s.Length + document.Length) < max_length) {
+                               if ((s.Length + (document.Length - SelectedText.Length)) < max_length) {
                                        document.undo.BeginUserAction (Locale.GetText ("Paste"));
                                        this.SelectedText = s;
                                        document.undo.EndUserAction ();
-                               } else if (document.Length < max_length) {
+                               } else if ((document.Length - SelectedText.Length) < max_length) {
                                        document.undo.BeginUserAction (Locale.GetText ("Paste"));
-                                       this.SelectedText = s.Substring (0, max_length - document.Length);
+                                       this.SelectedText = s.Substring (0, max_length - (document.Length - SelectedText.Length));
                                        document.undo.EndUserAction ();
                                }
                        }
 
+                       Modified = true;
                        return true;
                }
 
-               internal abstract Color ChangeBackColor (Color backColor);
+               internal virtual Color ChangeBackColor (Color backColor)
+               {
+                       return backColor;
+               }
 
                internal override bool IsInputCharInternal (char charCode)
                {
@@ -2451,7 +2461,6 @@ namespace System.Windows.Forms
                }
                #endregion
 
-#if NET_2_0
                // This is called just before OnTextChanged is called.
                internal virtual void OnTextUpdate ()
                {
@@ -2473,10 +2482,9 @@ namespace System.Windows.Forms
                        return line_out.LineNo;
                }
 
-               protected override void OnMouseUp (MouseEventArgs e)
+               protected override void OnMouseUp (MouseEventArgs mevent)
                {
-                       base.OnMouseUp (e);
+                       base.OnMouseUp (mevent);
                }
-#endif
        }
 }