Refactored, cleaned up
[mono.git] / mcs / class / Managed.Windows.Forms / System.Windows.Forms / TextControl.cs
index eeaba09c8651c8bb3b700a9acf7d62d45e0eae19..71e5f4207c888601bb5fc7ed4eb7d8a1cd37104b 100644 (file)
@@ -231,8 +231,6 @@ namespace System.Windows.Forms {
                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?
@@ -314,6 +312,7 @@ namespace System.Windows.Forms {
                        }
                }
 
+               // UIA: Method used via reflection in TextRangeProvider
                internal int Lines {
                        get {
                                return lines;
@@ -660,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) {
@@ -873,7 +875,7 @@ namespace System.Windows.Forms {
                                                offset_x, 
                                                line.Y - viewport_y + offset_y, 
                                                viewport_width, 
-                                               owner.Height - line.Y - viewport_y));
+                                               owner.Height - (line.Y - viewport_y)));
                                } else {
                                        // The tag was above the visible area, draw everything
                                        owner.Invalidate();
@@ -927,15 +929,14 @@ 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
@@ -945,7 +946,7 @@ namespace System.Windows.Forms {
                                                offset_x, 
                                                line.Y - viewport_y + offset_y, 
                                                viewport_width, 
-                                               owner.Height - line.Y - viewport_y));
+                                               owner.Height - (line.Y - viewport_y)));
                                } else {
                                        // The tag was above the visible area, draw everything
                                        owner.Invalidate();
@@ -1039,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;
@@ -1144,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) {
@@ -1681,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
@@ -1693,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 - offset_y, false).line_no;
-                               end = GetLineByPixel(clip.Bottom + viewport_y - offset_y, 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;
-                       }
+                       GetVisibleLineIndexes (clip, out start, out end);
 
                        // remove links in the list (used for mouse down events) that are within the clip area.
                        InvalidateLinks (clip);
@@ -1941,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));
@@ -1962,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
@@ -2004,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
@@ -2029,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);
@@ -2158,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
@@ -3130,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());
                                        }
                                }
 
@@ -3339,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;
@@ -3463,6 +3505,8 @@ 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)
                {
@@ -3977,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