Fixed bug where using ResXResourceWriter filename ctor caused corrupted output
[mono.git] / mcs / class / Managed.Windows.Forms / System.Windows.Forms / TextControl.cs
index bee98aef51273a6f1ebc13847f9ce98d09e86fe7..71e5f4207c888601bb5fc7ed4eb7d8a1cd37104b 100644 (file)
@@ -223,14 +223,14 @@ namespace System.Windows.Forms {
 
                internal int            viewport_x;
                internal int            viewport_y;             // The visible area of the document
+               internal int            offset_x;
+               internal int            offset_y;
                internal int            viewport_width;
                internal int            viewport_height;
 
                internal int            document_x;             // Width of the document
                internal int            document_y;             // Height of the document
 
-               internal Rectangle      invalid;
-
                internal int            crlf_size;              // 1 or 2, depending on whether we use \r\n or just \n
 
                internal TextBoxBase    owner;                  // Who's owning us?
@@ -285,6 +285,9 @@ namespace System.Windows.Forms {
                        viewport_x = 0;
                        viewport_y = 0;
 
+                       offset_x = 0;
+                       offset_y = 0;
+
                        crlf_size = 2;
 
                        // Default selection is empty
@@ -309,6 +312,7 @@ namespace System.Windows.Forms {
                        }
                }
 
+               // UIA: Method used via reflection in TextRangeProvider
                internal int Lines {
                        get {
                                return lines;
@@ -425,6 +429,32 @@ namespace System.Windows.Forms {
                        }
                }
 
+               internal int OffsetX
+               {
+                       get
+                       {
+                               return offset_x;
+                       }
+
+                       set
+                       {
+                               offset_x = value;
+                       }
+               }
+
+               internal int OffsetY
+               {
+                       get
+                       {
+                               return offset_y;
+                       }
+
+                       set
+                       {
+                               offset_y = value;
+                       }
+               }
+
                internal int ViewPortWidth {
                        get {
                                return viewport_width;
@@ -629,11 +659,14 @@ namespace System.Windows.Forms {
 
                private void SetSelectionVisible (bool value)
                {
+                       bool old_selection_visible = selection_visible;
                        selection_visible = value;
 
                        // cursor and selection are enemies, we can't have both in the same room at the same time
                        if (owner.IsHandleCreated && !owner.show_caret_w_selection)
                                XplatUI.CaretVisible (owner.Handle, !selection_visible);
+                       if (UIASelectionChanged != null && (selection_visible || old_selection_visible))
+                               UIASelectionChanged (this, EventArgs.Empty);
                }
 
                private void DecrementLines(int line_no) {
@@ -838,7 +871,11 @@ namespace System.Windows.Forms {
                                // Lineheight changed, invalidate the rest of the document
                                if ((line.Y - viewport_y) >=0 ) {
                                        // We formatted something that's in view, only draw parts of the screen
-                                       owner.Invalidate(new Rectangle(0, line.Y - viewport_y, viewport_width, owner.Height - line.Y - viewport_y));
+                                       owner.Invalidate(new Rectangle(
+                                               offset_x, 
+                                               line.Y - viewport_y + offset_y, 
+                                               viewport_width, 
+                                               owner.Height - (line.Y - viewport_y)));
                                } else {
                                        // The tag was above the visible area, draw everything
                                        owner.Invalidate();
@@ -846,17 +883,29 @@ namespace System.Windows.Forms {
                        } else {
                                switch(line.alignment) {
                                        case HorizontalAlignment.Left: {
-                                               owner.Invalidate(new Rectangle(line.X + (int)line.widths[pos] - viewport_x - 1, line.Y - viewport_y, viewport_width, line.height + 1));
+                                               owner.Invalidate(new Rectangle(
+                                                       line.X + ((int)line.widths[pos] - viewport_x - 1) + offset_x, 
+                                                       line.Y - viewport_y + offset_y, 
+                                                       viewport_width, 
+                                                       line.height + 1));
                                                break;
                                        }
 
                                        case HorizontalAlignment.Center: {
-                                               owner.Invalidate(new Rectangle(line.X, line.Y - viewport_y, viewport_width, line.height + 1));
+                                               owner.Invalidate(new Rectangle(
+                                                       line.X + offset_x, 
+                                                       line.Y - viewport_y + offset_y, 
+                                                       viewport_width, 
+                                                       line.height + 1));
                                                break;
                                        }
 
                                        case HorizontalAlignment.Right: {
-                                               owner.Invalidate(new Rectangle(line.X, line.Y - viewport_y, (int)line.widths[pos + 1] - viewport_x + line.X, line.height + 1));
+                                               owner.Invalidate(new Rectangle(
+                                                       line.X + offset_x, 
+                                                       line.Y - viewport_y + offset_y, 
+                                                       (int)line.widths[pos + 1] - viewport_x + line.X, 
+                                                       line.height + 1));
                                                break;
                                        }
                                }
@@ -880,29 +929,32 @@ namespace System.Windows.Forms {
 
                        int start_line_top = line.Y;                    
 
-                       int end_line_bottom;
-                       Line end_line;
-
-                       end_line = GetLine (line.line_no + line_count);
+                       Line end_line = GetLine (line.line_no + line_count);
                        if (end_line == null)
                                end_line = GetLine (lines);
 
-
-                       end_line_bottom = end_line.Y + end_line.height;
+                       if (end_line == null)
+                               return;
+                       
+                       int end_line_bottom = end_line.Y + end_line.height;
                        
                        if (RecalculateDocument(owner.CreateGraphicsInternal(), line.line_no, line.line_no + line_count, true)) {
                                // Lineheight changed, invalidate the rest of the document
                                if ((line.Y - viewport_y) >=0 ) {
                                        // We formatted something that's in view, only draw parts of the screen
-                                       owner.Invalidate(new Rectangle(0, line.Y - viewport_y, viewport_width, owner.Height - line.Y - viewport_y));
+                                       owner.Invalidate(new Rectangle(
+                                               offset_x, 
+                                               line.Y - viewport_y + offset_y, 
+                                               viewport_width, 
+                                               owner.Height - (line.Y - viewport_y)));
                                } else {
                                        // The tag was above the visible area, draw everything
                                        owner.Invalidate();
                                }
                        } else {
-                               int x = 0 - viewport_x;
+                               int x = 0 - viewport_x + offset_x;
                                int w = viewport_width;
-                               int y = Math.Min (start_line_top - viewport_y, line.Y - viewport_y);
+                               int y = Math.Min (start_line_top - viewport_y, line.Y - viewport_y) + offset_y;
                                int h = Math.Max (end_line_bottom - y, end_line.Y + end_line.height - y);
 
                                owner.Invalidate (new Rectangle (x, y, w, h));
@@ -988,7 +1040,7 @@ namespace System.Windows.Forms {
                                                }
                                        } else {
                                                if (char.IsLetterOrDigit (line_no_breaks_string [i]) == false &&
-                                                       "@-/:~.?=".IndexOf (line_no_breaks_string [i].ToString ()) == -1) {
+                                                       "@-/:~.?=_&".IndexOf (line_no_breaks_string [i].ToString ()) == -1) {
                                                        link_end = i - 1;
                                                        line_no_breaks_index = i;
                                                        break;
@@ -1093,11 +1145,7 @@ namespace System.Windows.Forms {
                        int best_index = -1;
 
                        for (int i = 0; i < needles.Length; i++) {
-#if  NET_2_0
                                int index = haystack.IndexOf (needles [i], start_index, StringComparison.InvariantCultureIgnoreCase);
-#else
-                               int index = haystack.ToLower().IndexOf(needles[i], start_index);
-#endif
 
                                if (index > -1) {
                                        if (term_found > -1) {
@@ -1200,7 +1248,9 @@ namespace System.Windows.Forms {
                                if (owner.Focused) {
                                        if (caret.height != caret.tag.Height)
                                                XplatUI.CreateCaret (owner.Handle, caret_width, caret.height);
-                                       XplatUI.SetCaretPos(owner.Handle, (int)caret.tag.Line.widths[caret.pos] + caret.line.X - viewport_x, caret.line.Y + caret.tag.Shift - viewport_y + caret_shift);
+                                       XplatUI.SetCaretPos(owner.Handle, 
+                                               offset_x + (int)caret.tag.Line.widths[caret.pos] + caret.line.X - viewport_x, 
+                                               offset_y + caret.line.Y + caret.tag.Shift - viewport_y + caret_shift);
                                }
 
                                if (CaretMoved != null) CaretMoved(this, EventArgs.Empty);
@@ -1226,7 +1276,9 @@ namespace System.Windows.Forms {
 
                        if (owner.ShowSelection && (!selection_visible || owner.show_caret_w_selection)) {
                                XplatUI.CreateCaret (owner.Handle, caret_width, caret.height);
-                               XplatUI.SetCaretPos(owner.Handle, (int)caret.tag.Line.widths[caret.pos] + caret.line.X - viewport_x, caret.line.Y + caret.tag.Shift - viewport_y + caret_shift);
+                               XplatUI.SetCaretPos(owner.Handle, 
+                                       (int)caret.tag.Line.widths[caret.pos] + caret.line.X - viewport_x + offset_x, 
+                                       offset_y + caret.line.Y + caret.tag.Shift - viewport_y + caret_shift);
                        }
 
                        if (CaretMoved != null) CaretMoved(this, EventArgs.Empty);
@@ -1235,7 +1287,9 @@ namespace System.Windows.Forms {
                internal void CaretHasFocus() {
                        if ((caret.tag != null) && owner.IsHandleCreated) {
                                XplatUI.CreateCaret(owner.Handle, caret_width, caret.height);
-                               XplatUI.SetCaretPos(owner.Handle, (int)caret.tag.Line.widths[caret.pos] + caret.line.X - viewport_x, caret.line.Y + caret.tag.Shift - viewport_y + caret_shift);
+                               XplatUI.SetCaretPos(owner.Handle, 
+                                       offset_x + (int)caret.tag.Line.widths[caret.pos] + caret.line.X - viewport_x, 
+                                       offset_y + caret.line.Y + caret.tag.Shift - viewport_y + caret_shift);
 
                                DisplayCaret ();
                        }
@@ -1281,7 +1335,9 @@ namespace System.Windows.Forms {
 
                        if (owner.Focused) {
                                XplatUI.CreateCaret(owner.Handle, caret_width, caret.height);
-                               XplatUI.SetCaretPos (owner.Handle, (int) caret.tag.Line.widths [caret.pos] + caret.line.X - viewport_x, caret.line.Y + viewport_y + caret_shift);
+                               XplatUI.SetCaretPos (owner.Handle, 
+                                       offset_x + (int) caret.tag.Line.widths [caret.pos] + caret.line.X - viewport_x, 
+                                       offset_y + caret.line.Y + viewport_y + caret_shift);
                                DisplayCaret ();
                        }
 
@@ -1303,7 +1359,9 @@ namespace System.Windows.Forms {
                        }
 
                        if (owner.Focused) {
-                               XplatUI.SetCaretPos(owner.Handle, (int)caret.tag.Line.widths[caret.pos] + caret.line.X - viewport_x, caret.line.Y + caret.tag.Shift - viewport_y + caret_shift);
+                               XplatUI.SetCaretPos(owner.Handle, 
+                                       offset_x + (int)caret.tag.Line.widths[caret.pos] + caret.line.X - viewport_x, 
+                                       offset_y + caret.line.Y + caret.tag.Shift - viewport_y + caret_shift);
                                DisplayCaret ();
                        }
                        
@@ -1620,6 +1678,22 @@ namespace System.Windows.Forms {
                        Console.WriteLine ("</doc>");
                }
 
+               // UIA: Used via reflection by TextProviderBehavior
+               internal void GetVisibleLineIndexes (Rectangle clip, out int start, out int end)
+               {
+                       if (multiline) {
+                               /* Expand the region slightly to be sure to
+                                * paint the full extent of the line of text.
+                                * See bug 464464.
+                                */
+                               start = GetLineByPixel(clip.Top + viewport_y - offset_y - 1, false).line_no;
+                               end = GetLineByPixel(clip.Bottom + viewport_y - offset_y + 1, false).line_no;
+                       } else {
+                               start = GetLineByPixel(clip.Left + viewport_x - offset_x, false).line_no;
+                               end = GetLineByPixel(clip.Right + viewport_x - offset_x, false).line_no;
+                       }
+               }
+
                internal void Draw (Graphics g, Rectangle clip)
                {
                        Line line;              // Current line being drawn
@@ -1632,14 +1706,7 @@ namespace System.Windows.Forms {
                        Color current_color;
 
                        // First, figure out from what line to what line we need to draw
-
-                       if (multiline) {
-                               start = GetLineByPixel(clip.Top + viewport_y, false).line_no;
-                               end = GetLineByPixel(clip.Bottom + viewport_y, false).line_no;
-                       } else {
-                               start = GetLineByPixel(clip.Left + viewport_x, false).line_no;
-                               end = GetLineByPixel(clip.Right + viewport_x, false).line_no;
-                       }
+                       GetVisibleLineIndexes (clip, out start, out end);
 
                        // remove links in the list (used for mouse down events) that are within the clip area.
                        InvalidateLinks (clip);
@@ -1653,7 +1720,7 @@ namespace System.Windows.Forms {
 
                        /// Make sure that we aren't drawing one more line then we need to
                        line = GetLine (end - 1);
-                       if (line != null && clip.Bottom == line.Y + line.height - viewport_y)
+                       if (line != null && clip.Bottom == offset_y + line.Y + line.height - viewport_y)
                                end--;
 
                        line_no = start;
@@ -1669,9 +1736,9 @@ namespace System.Windows.Forms {
                        // Non multiline selection can be handled outside of the loop
                        if (!multiline && selection_visible && owner.ShowSelection) {
                                g.FillRectangle (ThemeEngine.Current.ResPool.GetSolidBrush (ThemeEngine.Current.ColorHighlight),
-                                               selection_start.line.widths [selection_start.pos] +
+                                               offset_x + selection_start.line.widths [selection_start.pos] +
                                                selection_start.line.X - viewport_x, 
-                                               selection_start.line.Y,
+                                               offset_y + selection_start.line.Y,
                                                (selection_end.line.X + selection_end.line.widths [selection_end.pos]) -
                                                (selection_start.line.X + selection_start.line.widths [selection_start.pos]), 
                                                selection_start.line.height);
@@ -1679,7 +1746,7 @@ namespace System.Windows.Forms {
 
                        while (line_no <= end) {
                                line = GetLine (line_no);
-                               float line_y = line.Y - viewport_y;
+                               float line_y = line.Y - viewport_y + offset_y;
                                
                                tag = line.tags;
                                if (!calc_pass) {
@@ -1715,7 +1782,7 @@ namespace System.Windows.Forms {
                                        } else if (multiline) {
                                                // lets draw some selection baby!!  (non multiline selection is drawn outside the loop)
                                                g.FillRectangle (ThemeEngine.Current.ResPool.GetSolidBrush (ThemeEngine.Current.ColorHighlight),
-                                                               line.widths [line_selection_start - 1] + line.X - viewport_x, 
+                                                               offset_x + line.widths [line_selection_start - 1] + line.X - viewport_x, 
                                                                line_y, line.widths [line_selection_end - 1] - line.widths [line_selection_start - 1], 
                                                                line.height);
                                        }
@@ -1730,13 +1797,15 @@ namespace System.Windows.Forms {
                                                continue;
                                        }
 
-                                       if (((tag.X + tag.Width) < (clip.Left - viewport_x)) && (tag.X > (clip.Right - viewport_x))) {
+                                       if (((tag.X + tag.Width) < (clip.Left - viewport_x - offset_x)) && 
+                                            (tag.X > (clip.Right - viewport_x - offset_x))) {
                                                tag = tag.Next;
                                                continue;
                                        }
 
                                        if (tag.BackColor != Color.Empty) {
-                                               g.FillRectangle (ThemeEngine.Current.ResPool.GetSolidBrush (tag.BackColor), tag.X + line.X - viewport_x,
+                                               g.FillRectangle (ThemeEngine.Current.ResPool.GetSolidBrush (tag.BackColor), 
+                                                               offset_x + tag.X + line.X - viewport_x,
                                                                line_y + tag.Shift, tag.Width, line.height);
                                        }
 
@@ -1771,7 +1840,7 @@ namespace System.Windows.Forms {
                                                Rectangle text_size;
 
                                                tag.Draw (g, current_color,
-                                                               line.X - viewport_x,
+                                                               offset_x + line.X - viewport_x,
                                                                line_y + tag.Shift,
                                                                old_tag_pos - 1, Math.Min (tag.Start + tag.Length, tag_pos) - 1,
                                                                text.ToString (), out text_size, tag.IsLink);
@@ -1878,6 +1947,22 @@ namespace System.Windows.Forms {
                        return string.Empty;
                }
 
+               internal LineEnding StringToLineEnding (string ending)
+               {
+                       switch (ending) {
+                               case "\r":
+                                       return LineEnding.Limp;
+                               case "\r\n":
+                                       return LineEnding.Hard;
+                               case "\r\r\n":
+                                       return LineEnding.Soft;
+                               case "\n":
+                                       return LineEnding.Rich;
+                               default:
+                                       return LineEnding.None;
+                       }
+               }
+               
                internal void Insert (Line line, int pos, bool update_caret, string s)
                {
                        Insert (line, pos, update_caret, s, line.FindTag (pos));
@@ -1899,6 +1984,11 @@ namespace System.Windows.Forms {
                        base_line = line.line_no;
                        old_line_count = lines;
 
+                       // Discard chars after any possible -unlikely- end of file
+                       int eof_index = s.IndexOf ('\0');
+                       if (eof_index != -1)
+                               s = s.Substring (0, eof_index);
+
                        break_index = GetLineEnding (s, 0, out ending, LineEnding.Hard | LineEnding.Rich);
 
                        // There are no line feeds in our text to be pasted
@@ -1941,6 +2031,9 @@ namespace System.Windows.Forms {
                        // Allow the document to recalculate things
                        ResumeRecalc (false);
 
+                       // Update our character count
+                       CharCount += s.Length;
+
                        UpdateView (line, lines - old_line_count + 1, pos);
 
                        // Move the caret to the end of the inserted text if requested
@@ -1966,6 +2059,9 @@ namespace System.Windows.Forms {
                {
                        caret.line.InsertString (caret.pos, ch.ToString(), caret.tag);
 
+                       // Update our character count
+                       CharCount++;
+                       
                        undo.RecordTyping (caret.line, caret.pos, ch);
 
                        UpdateView (caret.line, caret.pos);
@@ -2095,10 +2191,17 @@ namespace System.Windows.Forms {
                        if ((pos == 0 && forward == false) || (pos == line.text.Length && forward == true))
                                return;
                        
-                       if (forward)
+                       undo.BeginUserAction ("Delete");
+
+                       if (forward) {
+                               undo.RecordDeleteString (line, pos, line, pos + 1);
                                DeleteChars (line, pos, 1);
-                       else
+                       } else {
+                               undo.RecordDeleteString (line, pos - 1, line, pos);
                                DeleteChars (line, pos - 1, 1);
+                       }
+
+                       undo.EndUserAction ();
                }
 
                // Combine two lines
@@ -2627,9 +2730,9 @@ namespace System.Windows.Forms {
                                #endif
 
                                owner.Invalidate(new Rectangle (
-                                       (int)l1.widths[p1] + l1.X - viewport_x, 
-                                       l1.Y - viewport_y, 
-                                       endpoint - (int)l1.widths[p1] + 1, 
+                                       offset_x + (int)l1.widths[p1] + l1.X - viewport_x, 
+                                       offset_y + l1.Y - viewport_y,
+                                       endpoint - (int) l1.widths [p1] + 1, 
                                        l1.height));
                                return;
                        }
@@ -2641,7 +2744,11 @@ namespace System.Windows.Forms {
 
                        // Three invalidates:
                        // First line from start
-                       owner.Invalidate(new Rectangle((int)l1.widths[p1] + l1.X - viewport_x, l1.Y - viewport_y, viewport_width, l1.height));
+                       owner.Invalidate(new Rectangle(
+                               offset_x + (int)l1.widths[p1] + l1.X - viewport_x, 
+                               offset_y + l1.Y - viewport_y, 
+                               viewport_width, 
+                               l1.height));
 
                        
                        // lines inbetween
@@ -2649,7 +2756,11 @@ namespace System.Windows.Forms {
                                int     y;
 
                                y = GetLine(l1.line_no + 1).Y;
-                               owner.Invalidate(new Rectangle(0, y - viewport_y, viewport_width, l2.Y - y));
+                               owner.Invalidate(new Rectangle(
+                                       offset_x, 
+                                       offset_y + y - viewport_y, 
+                                       viewport_width, 
+                                       l2.Y - y));
 
                                #if Debug
                                        Console.WriteLine("Invaliding from {0}:{1} to {2}:{3} Middle => x={4}, y={5}, {6}x{7}", l1.line_no, p1, l2.line_no, p2, 0, y - viewport_y, viewport_width, l2.Y - y);
@@ -2658,10 +2769,14 @@ namespace System.Windows.Forms {
                        
 
                        // Last line to end
-                       owner.Invalidate(new Rectangle((int)l2.widths[0] + l2.X - viewport_x, l2.Y - viewport_y, (int)l2.widths[p2] + 1, l2.height));
+                       owner.Invalidate(new Rectangle(
+                               offset_x + (int)l2.widths[0] + l2.X - viewport_x, 
+                               offset_y + l2.Y - viewport_y, 
+                               (int)l2.widths[p2] + 1, 
+                               l2.height));
+
                        #if Debug
                                Console.WriteLine("Invaliding from {0}:{1} to {2}:{3} End    => x={4}, y={5}, {6}x{7}", l1.line_no, p1, l2.line_no, p2, (int)l2.widths[0] + l2.X - viewport_x, l2.Y - viewport_y, (int)l2.widths[p2] + 1, l2.height);
-
                        #endif
                }
 
@@ -3055,11 +3170,11 @@ namespace System.Windows.Forms {
                                start = selection_start.line.line_no;
                                end = selection_end.line.line_no;
 
-                               sb.Append(selection_start.line.text.ToString(selection_start.pos, selection_start.line.text.Length - selection_start.pos) + Environment.NewLine);
+                               sb.Append(selection_start.line.text.ToString(selection_start.pos, selection_start.line.text.Length - selection_start.pos));
 
                                if ((start + 1) < end) {
                                        for (i = start + 1; i < end; i++) {
-                                               sb.Append(GetLine(i).text.ToString() + Environment.NewLine);
+                                               sb.Append(GetLine(i).text.ToString());
                                        }
                                }
 
@@ -3264,6 +3379,8 @@ namespace System.Windows.Forms {
                }
 
 
+               // UIA: Method used via reflection in TextRangeProvider
+
                /// <summary>Give it a Line number and it returns the Line object at with that line number</summary>
                internal Line GetLine(int LineNo) {
                        Line    line = document;
@@ -3388,11 +3505,16 @@ namespace System.Windows.Forms {
                        return last;
                }
 
+               // UIA: Method used via reflection in TextProviderBehavior
+
                // Give it x/y pixel coordinates and it returns the Tag at that position
                internal LineTag FindCursor (int x, int y, out int index)
                {
                        Line line;
 
+                       x -= offset_x;
+                       y -= offset_y;
+
                        line = GetLineByPixel (multiline ? y : x, false);
 
                        LineTag tag = line.GetTag (x);
@@ -3899,6 +4021,7 @@ namespace System.Windows.Forms {
                internal event EventHandler WidthChanged;
                internal event EventHandler HeightChanged;
                internal event EventHandler LengthChanged;
+               internal event EventHandler UIASelectionChanged;
                #endregion      // Events
 
                #region Administrative
@@ -4059,16 +4182,13 @@ namespace System.Windows.Forms {
                        redo_actions.Clear();
                }
 
-               internal void Undo ()
+               internal bool Undo ()
                {
                        Action action;
                        bool user_action_finished = false;
 
                        if (undo_actions.Count == 0)
-                               return;
-
-                       // Nuke the redo queue
-                       redo_actions.Clear ();
+                               return false;
 
                        locked = true;
                        do {
@@ -4120,18 +4240,17 @@ namespace System.Windows.Forms {
                        } while (!user_action_finished && undo_actions.Count > 0);
 
                        locked = false;
+
+                       return true;
                }
 
-               internal void Redo ()
+               internal bool Redo ()
                {
                        Action action;
                        bool user_action_finished = false;
 
                        if (redo_actions.Count == 0)
-                               return;
-
-                       // You can't undo anything after redoing
-                       undo_actions.Clear ();
+                               return false;
 
                        locked = true;
                        do {
@@ -4139,6 +4258,7 @@ namespace System.Windows.Forms {
                                int start_index;
 
                                action = (Action) redo_actions.Pop ();
+                               undo_actions.Push (action);
 
                                switch (action.type) {
 
@@ -4192,6 +4312,8 @@ namespace System.Windows.Forms {
                        } while (!user_action_finished && redo_actions.Count > 0);
 
                        locked = false;
+
+                       return true;
                }
                #endregion      // Internal Methods
 
@@ -4202,6 +4324,9 @@ namespace System.Windows.Forms {
                        if (locked)
                                return;
 
+                       // Nuke the redo queue
+                       redo_actions.Clear ();
+
                        Action ua = new Action ();
                        ua.type = ActionType.UserActionBegin;
                        ua.data = name;
@@ -4226,6 +4351,9 @@ namespace System.Windows.Forms {
                        if (locked)
                                return;
 
+                       // Nuke the redo queue
+                       redo_actions.Clear ();
+
                        Action  a = new Action ();
 
                        // We cant simply store the string, because then formatting would be lost
@@ -4242,6 +4370,9 @@ namespace System.Windows.Forms {
                        if (locked || str.Length == 0)
                                return;
 
+                       // Nuke the redo queue
+                       redo_actions.Clear ();
+
                        Action a = new Action ();
 
                        a.type = ActionType.InsertString;
@@ -4257,6 +4388,9 @@ namespace System.Windows.Forms {
                        if (locked)
                                return;
 
+                       // Nuke the redo queue
+                       redo_actions.Clear ();
+
                        Action a = null;
 
                        if (undo_actions.Count > 0)