2007-01-02 Chris Toshok <toshok@ximian.com>
[mono.git] / mcs / class / Managed.Windows.Forms / System.Windows.Forms / RichTextBox.cs
index 5b13b0cc178104b52c63ddcdf823bd433da543bb..775b0c3c74afbec231aa9e4c677cc178604ffb25 100644 (file)
@@ -17,7 +17,7 @@
 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 //
-// Copyright (c) 2005 Novell, Inc. (http://www.novell.com)
+// Copyright (c) 2005-2006 Novell, Inc. (http://www.novell.com)
 //
 // Authors:
 //     Peter Bartok    <pbartok@novell.com>
@@ -50,7 +50,6 @@ namespace System.Windows.Forms {
                private int             rtf_skip_width;
                private int             rtf_skip_count;
                private StringBuilder   rtf_line;
-               private Font            rtf_font;
                private SolidBrush      rtf_color;
                private RTF.Font        rtf_rtffont;
                private int             rtf_rtffont_size;
@@ -58,6 +57,7 @@ namespace System.Windows.Forms {
                private HorizontalAlignment rtf_rtfalign;
                private int             rtf_cursor_x;
                private int             rtf_cursor_y;
+               private int             rtf_chars;
                #endregion      // Local Variables
 
                #region Public Constructors
@@ -83,17 +83,19 @@ namespace System.Windows.Forms {
                        ForeColor = ThemeEngine.Current.ColorWindowText;
                        base.HScrolled += new EventHandler(RichTextBox_HScrolled);
                        base.VScrolled += new EventHandler(RichTextBox_VScrolled);
+
+#if NET_2_0
+                       SetStyle (ControlStyles.StandardDoubleClick, false);
+#endif
                }
                #endregion      // Public Constructors
 
                #region Private & Internal Methods
                private void RichTextBox_LostFocus(object sender, EventArgs e) {
-                       has_focus = false;
                        Invalidate();
                }
 
                private void RichTextBox_GotFocus(object sender, EventArgs e) {
-                       has_focus = true;
                        Invalidate();
                }
                #endregion      // Private & Internal Methods
@@ -135,13 +137,8 @@ namespace System.Windows.Forms {
                [Browsable(false)]
                [EditorBrowsable(EditorBrowsableState.Never)]
                public override System.Drawing.Image BackgroundImage {
-                       get {
-                               return background_image;
-                       }
-
-                       set {
-                               base.BackgroundImage = value;
-                       }
+                       get { return base.BackgroundImage; }
+                       set { base.BackgroundImage = value; }
                }
 
                [DefaultValue(0)]
@@ -196,7 +193,7 @@ namespace System.Windows.Forms {
                                        // Font changes always set the whole doc to that font
                                        start = document.GetLine(1);
                                        end = document.GetLine(document.Lines);
-                                       document.FormatText(start, 1, end, end.text.Length, base.Font, new SolidBrush(this.ForeColor));
+                                       document.FormatText(start, 1, end, end.text.Length + 1, base.Font, null, null, FormatSpecified.Font);
                                }
                        }
                }
@@ -258,13 +255,10 @@ namespace System.Windows.Forms {
                [Browsable(false)]
                [DefaultValue("")]
                [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
-               [MonoTODO("Implement setter")]
                public string Rtf {
                        get {
                                Line            start_line;
                                Line            end_line;
-                               int             current;
-                               int             total;
 
                                start_line = document.GetLine(1);
                                end_line = document.GetLine(document.Lines);
@@ -280,6 +274,8 @@ namespace System.Windows.Forms {
                                InsertRTFFromStream(data, 0, 1);
 
                                data.Close();
+
+                               Invalidate();
                        }
                }
 
@@ -298,7 +294,6 @@ namespace System.Windows.Forms {
                [Browsable(false)]
                [DefaultValue("")]
                [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
-               [MonoTODO("Implement setter")]
                public string SelectedRtf {
                        get {
                                return GenerateRTF(document.selection_start.line, document.selection_start.pos, document.selection_end.line, document.selection_end.pos).ToString();
@@ -308,20 +303,26 @@ namespace System.Windows.Forms {
                                MemoryStream    data;
                                int             x;
                                int             y;
+                               int             sel_start;
+                               int             chars;
                                Line            line;
+                               LineTag         tag;
 
                                if (document.selection_visible) {
-                                       document.ReplaceSelection("");
+                                       document.ReplaceSelection("", false);
                                }
 
+                               sel_start = document.LineTagToCharIndex(document.selection_start.line, document.selection_start.pos);
+
                                data = new MemoryStream(Encoding.ASCII.GetBytes(value), false);
-                               InsertRTFFromStream(data, document.selection_start.pos, document.selection_start.line.line_no, out x, out y);
+                               InsertRTFFromStream(data, document.selection_start.pos, document.selection_start.line.line_no, out x, out y, out chars);
                                data.Close();
 
-                               line = document.GetLine(y);
-                               document.SetSelection(document.GetLine(y), x);
-                               document.PositionCaret(line, x);
-
+                               document.CharIndexToLineTag(sel_start + chars + (y - document.selection_start.line.line_no) * 2, out line, out tag, out sel_start);
+                               document.SetSelection(line, sel_start);
+                               document.PositionCaret(line, sel_start);
+                               document.DisplayCaret();
+                               ScrollToCaret();
                                OnTextChanged(EventArgs.Empty);
                        }
                }
@@ -393,20 +394,77 @@ namespace System.Windows.Forms {
                        }
                }
 
+               [Browsable(false)]
+               [DefaultValue(false)]
+               [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
                [MonoTODO]
+               public bool SelectionBullet {
+                       get {
+                               return false;
+                       }
+
+                       set {
+                       }
+               }
+
+               [Browsable(false)]
+               [DefaultValue(0)]
+               [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
+               [MonoTODO]
+               public int SelectionCharOffset {
+                       get {
+                               return 0;
+                       }
+
+                       set {
+                       }
+               }
+
+               [Browsable(false)]
+               [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
                public Color SelectionColor {
                        get {
-                               throw new NotImplementedException();
+                               Color   color;
+                               LineTag start;
+                               LineTag end;
+                               LineTag tag;
+
+                               start = document.selection_start.tag;
+                               end = document.selection_end.tag;
+                               color = ((SolidBrush)document.selection_start.tag.color).Color;
+
+                               tag = start;
+                               while (true) {
+                                       if (!color.Equals(((SolidBrush)tag.color).Color)) {
+                                               return Color.Empty;
+                                       }
+
+                                       if (tag == end) {
+                                               break;
+                                       }
+
+                                       tag = document.NextTag(tag);
+
+                                       if (tag == null) {
+                                               break;
+                                       }
+                               }
+
+                               return color;
                        }
 
                        set {
-                               int     sel_start;
-                               int     sel_end;
+                               FontDefinition  attributes;
+                               int             sel_start;
+                               int             sel_end;
+
+                               attributes = new FontDefinition();
+                               attributes.color = value;
 
                                sel_start = document.LineTagToCharIndex(document.selection_start.line, document.selection_start.pos);
                                sel_end = document.LineTagToCharIndex(document.selection_end.line, document.selection_end.pos);
-Console.WriteLine("FIXME - SelectionColor should not alter font");
-                               document.FormatText(document.selection_start.line, document.selection_start.pos + 1, document.selection_end.line, document.selection_end.pos, document.selection_start.tag.font, new SolidBrush(value));
+
+                               document.FormatText(document.selection_start.line, document.selection_start.pos + 1, document.selection_end.line, document.selection_end.pos + 1, attributes);
 
                                document.CharIndexToLineTag(sel_start, out document.selection_start.line, out document.selection_start.tag, out document.selection_start.pos);
                                document.CharIndexToLineTag(sel_end, out document.selection_end.line, out document.selection_end.tag, out document.selection_end.pos);
@@ -450,20 +508,100 @@ Console.WriteLine("FIXME - SelectionColor should not alter font");
                        }
 
                        set {
-                               int     sel_start;
-                               int     sel_end;
+                               FontDefinition  attributes;
+                               int             sel_start;
+                               int             sel_end;
+
+                               attributes = new FontDefinition();
+                               attributes.font_obj = value;
 
                                sel_start = document.LineTagToCharIndex(document.selection_start.line, document.selection_start.pos);
                                sel_end = document.LineTagToCharIndex(document.selection_end.line, document.selection_end.pos);
 
-                               document.FormatText(document.selection_start.line, document.selection_start.pos + 1, document.selection_end.line, document.selection_end.pos, value, document.selection_start.tag.color);
+                               document.FormatText(document.selection_start.line, document.selection_start.pos + 1, document.selection_end.line, document.selection_end.pos + 1, attributes);
 
                                document.CharIndexToLineTag(sel_start, out document.selection_start.line, out document.selection_start.tag, out document.selection_start.pos);
                                document.CharIndexToLineTag(sel_end, out document.selection_end.line, out document.selection_end.tag, out document.selection_end.pos);
 
                                document.UpdateView(document.selection_start.line, 0);
                                document.AlignCaret();
-                               
+
+                       }
+               }
+
+               [Browsable(false)]
+               [DefaultValue(0)]
+               [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
+               [MonoTODO]
+               public int SelectionHangingIndent {
+                       get {
+                               return 0;
+                       }
+
+                       set {
+                       }
+               }
+
+               [Browsable(false)]
+               [DefaultValue(0)]
+               [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
+               [MonoTODO]
+               public int SelectionIndent {
+                       get {
+                               return 0;
+                       }
+
+                       set {
+                       }
+               }
+
+               [Browsable(false)]
+               [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
+               public override int SelectionLength {
+                       get {
+                               return base.SelectionLength;
+                       }
+
+                       set {
+                               base.SelectionLength = value;
+                       }
+               }
+
+               [Browsable(false)]
+               [DefaultValue(false)]
+               [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
+               [MonoTODO]
+               public bool SelectionProtected {
+                       get {
+                               return false;
+                       }
+
+                       set {
+                       }
+               }
+
+               [Browsable(false)]
+               [DefaultValue(0)]
+               [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
+               [MonoTODO]
+               public int SelectionRightIndent {
+                       get {
+                               return 0;
+                       }
+
+                       set {
+                       }
+               }
+
+               [Browsable(false)]
+               [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
+               [MonoTODO]
+               public int[] SelectionTabs {
+                       get {
+                               return new int[0];
+                       }
+
+                       set {
                        }
                }
 
@@ -484,6 +622,17 @@ Console.WriteLine("FIXME - SelectionColor should not alter font");
                        }
                }
 
+               [DefaultValue(false)]
+               [MonoTODO]
+               public bool ShowSelectionMargin {
+                       get {
+                               return false;
+                       }
+
+                       set {
+                       }
+               }
+
                [Localizable(true)]
                public override string Text {
                        get {
@@ -506,7 +655,7 @@ Console.WriteLine("FIXME - SelectionColor should not alter font");
                [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
                public string UndoActionName {
                        get {
-                               return undo_action_name;
+                               return document.undo.UndoName;
                        }
                }
 
@@ -538,6 +687,15 @@ Console.WriteLine("FIXME - SelectionColor should not alter font");
                #endregion      // Protected Instance Properties
 
                #region Public Instance Methods
+               public bool CanPaste(DataFormats.Format clipFormat) {
+                       if ((clipFormat.Name == DataFormats.Rtf) ||
+                               (clipFormat.Name == DataFormats.Text) ||
+                               (clipFormat.Name == DataFormats.UnicodeText)) {
+                                       return true;
+                       }
+                       return false;
+               }
+
                public int Find(char[] characterSet) {
                        return Find(characterSet, -1, -1);
                }
@@ -688,8 +846,6 @@ Console.WriteLine("FIXME - SelectionColor should not alter font");
                }
 
                public void LoadFile(System.IO.Stream data, RichTextBoxStreamType fileType) {
-                       RTF.RTF rtf;    // Not 'using SWF.RTF' to avoid ambiguities with font and color
-
                        document.Empty();
 
                        // FIXME - ignoring unicode
@@ -717,9 +873,13 @@ Console.WriteLine("FIXME - SelectionColor should not alter font");
                        }
 
                        InsertRTFFromStream(data, 0, 1);
+
+                       document.PositionCaret (document.GetLine (1), 0);
+                       document.SetSelectionToCaret (true);
+                       ScrollToCaret ();
                }
 
-               [MonoTODO("Make smarter RTF detection")]
+               [MonoTODO("Make smarter RTF detection?")]
                public void LoadFile(string path) {
                        if (path.EndsWith(".rtf")) {
                                LoadFile(path, RichTextBoxStreamType.RichText);
@@ -749,6 +909,14 @@ Console.WriteLine("FIXME - SelectionColor should not alter font");
                        }
                }
 
+               public void Paste(DataFormats.Format clipFormat) {
+                       base.Paste(Clipboard.GetDataObject(), clipFormat, false);
+               }
+
+               [MonoTODO()]
+               public void Redo() {
+               }
+
                public void SaveFile(Stream data, RichTextBoxStreamType fileType) {
                        Encoding        encoding;
                        int             i;
@@ -838,10 +1006,20 @@ Console.WriteLine("FIXME - SelectionColor should not alter font");
                #endregion      // Public Instance Methods
 
                #region Protected Instance Methods
+               protected virtual object CreateRichEditOleCallback() {
+                       throw new NotImplementedException();
+               }
+
                protected override void OnBackColorChanged(EventArgs e) {
                        base.OnBackColorChanged (e);
                }
 
+               protected virtual void OnContentsResized(ContentsResizedEventArgs e) {
+                       ContentsResizedEventHandler eh = (ContentsResizedEventHandler)(Events [ContentsResizedEvent]);
+                       if (eh != null)
+                               eh (this, e);
+               }
+
                protected override void OnContextMenuChanged(EventArgs e) {
                        base.OnContextMenuChanged (e);
                }
@@ -855,15 +1033,40 @@ Console.WriteLine("FIXME - SelectionColor should not alter font");
                }
 
                protected virtual void OnHScroll(EventArgs e) {
-                       if (HScroll != null) {
-                               HScroll(this, e);
-                       }
+                       EventHandler eh = (EventHandler)(Events [HScrollEvent]);
+                       if (eh != null)
+                               eh (this, e);
+               }
+
+               [MonoTODO("Determine when to call this")]
+               protected virtual void OnImeChange(EventArgs e) {
+                       EventHandler eh = (EventHandler)(Events [ImeChangeEvent]);
+                       if (eh != null)
+                               eh (this, e);
+               }
+
+               protected virtual void OnLinkClicked(LinkClickedEventArgs e) {
+                       LinkClickedEventHandler eh = (LinkClickedEventHandler)(Events [LinkClickedEvent]);
+                       if (eh != null)
+                               eh (this, e);
+               }
+
+               protected virtual void OnProtected(EventArgs e) {
+                       EventHandler eh = (EventHandler)(Events [ProtectedEvent]);
+                       if (eh != null)
+                               eh (this, e);
                }
 
                protected override void OnRightToLeftChanged(EventArgs e) {
                        base.OnRightToLeftChanged (e);
                }
 
+               protected virtual void OnSelectionChanged(EventArgs e) {
+                       EventHandler eh = (EventHandler)(Events [SelectionChangedEvent]);
+                       if (eh != null)
+                               eh (this, e);
+               }
+
                protected override void OnSystemColorsChanged(EventArgs e) {
                        base.OnSystemColorsChanged (e);
                }
@@ -873,9 +1076,9 @@ Console.WriteLine("FIXME - SelectionColor should not alter font");
                }
 
                protected virtual void OnVScroll(EventArgs e) {
-                       if (VScroll != null) {
-                               VScroll(this, e);
-                       }
+                       EventHandler eh = (EventHandler)(Events [VScrollEvent]);
+                       if (eh != null)
+                               eh (this, e);
                }
 
                protected override void WndProc(ref Message m) {
@@ -884,50 +1087,117 @@ Console.WriteLine("FIXME - SelectionColor should not alter font");
                #endregion      // Protected Instance Methods
 
                #region Events
+               static object ContentsResizedEvent = new object ();
+               static object HScrollEvent = new object ();
+               static object ImeChangeEvent = new object ();
+               static object LinkClickedEvent = new object ();
+               static object ProtectedEvent = new object ();
+               static object SelectionChangedEvent = new object ();
+               static object VScrollEvent = new object ();
+
                [Browsable(false)]
                [EditorBrowsable(EditorBrowsableState.Never)]
-               public event EventHandler                       BackgroundImageChanged;
+               public new event EventHandler BackgroundImageChanged {
+                       add { base.BackgroundImageChanged += value; }
+                       remove { base.BackgroundImageChanged -= value; }
+               }
 
-               public event ContentsResizedEventHandler        ContentsResized;
+               public event ContentsResizedEventHandler ContentsResized {
+                       add { Events.AddHandler (ContentsResizedEvent, value); }
+                       remove { Events.RemoveHandler (ContentsResizedEvent, value); }
+               }
 
                [Browsable(false)]
                [EditorBrowsable(EditorBrowsableState.Never)]
-               public event EventHandler                       DoubleClick;
+               public new event EventHandler DoubleClick {
+                       add { base.DoubleClick += value; }
+                       remove { base.DoubleClick -= value; }
+               }
 
                [Browsable(false)]
                [EditorBrowsable(EditorBrowsableState.Never)]
-               public event DragEventHandler                   DragDrop;
+               public new event DragEventHandler DragDrop {
+                       add { base.DragDrop += value; }
+                       remove { base.DragDrop -= value; }
+               }
 
                [Browsable(false)]
                [EditorBrowsable(EditorBrowsableState.Never)]
-               public event DragEventHandler                   DragEnter;
+               public new event DragEventHandler DragEnter {
+                       add { base.DragEnter += value; }
+                       remove { base.DragEnter -= value; }
+               }
 
                [Browsable(false)]
                [EditorBrowsable(EditorBrowsableState.Never)]
-               public event EventHandler                       DragLeave;
+               public new event EventHandler DragLeave {
+                       add { base.DragLeave += value; }
+                       remove { base.DragLeave -= value; }
+               }
+
 
                [Browsable(false)]
                [EditorBrowsable(EditorBrowsableState.Never)]
-               public event DragEventHandler                   DragOver;
+               public new event DragEventHandler DragOver {
+                       add { base.DragOver += value; }
+                       remove { base.DragOver -= value; }
+               }
+
 
                [Browsable(false)]
                [EditorBrowsable(EditorBrowsableState.Never)]
-               public event GiveFeedbackEventHandler           GiveFeedback;
+               public new event GiveFeedbackEventHandler GiveFeedback {
+                       add { base.GiveFeedback += value; }
+                       remove { base.GiveFeedback -= value; }
+               }
+
+               public event EventHandler HScroll {
+                       add { Events.AddHandler (HScrollEvent, value); }
+                       remove { Events.RemoveHandler (HScrollEvent, value); }
+               }
+
+               public event EventHandler ImeChange {
+                       add { Events.AddHandler (ImeChangeEvent, value); }
+                       remove { Events.RemoveHandler (ImeChangeEvent, value); }
+               }
 
-               public event EventHandler                       HScroll;
-               public event EventHandler                       ImeChange;
-               public event LinkClickedEventHandler            LinkClicked;
-               public event EventHandler                       Protected;
+               public event LinkClickedEventHandler LinkClicked {
+                       add { Events.AddHandler (LinkClickedEvent, value); }
+                       remove { Events.RemoveHandler (LinkClickedEvent, value); }
+               }
+
+               public event EventHandler Protected {
+                       add { Events.AddHandler (ProtectedEvent, value); }
+                       remove { Events.RemoveHandler (ProtectedEvent, value); }
+               }
 
                [Browsable(false)]
                [EditorBrowsable(EditorBrowsableState.Never)]
-               public event QueryContinueDragEventHandler      QueryContinueDrag;
-               public event EventHandler                       SelectionChanged;
-               public event EventHandler                       VScroll;
+               public new event QueryContinueDragEventHandler QueryContinueDrag {
+                       add { base.QueryContinueDrag += value; }
+                       remove { base.QueryContinueDrag -= value; }
+               }
+
+               public event EventHandler SelectionChanged {
+                       add { Events.AddHandler (SelectionChangedEvent, value); }
+                       remove { Events.RemoveHandler (SelectionChangedEvent, value); }
+               }
+
+               public event EventHandler VScroll {
+                       add { Events.AddHandler (VScrollEvent, value); }
+                       remove { Events.RemoveHandler (VScrollEvent, value); }
+               }
                #endregion      // Events
 
                #region Private Methods
+
+               internal override void SelectWord ()
+               {
+                       document.ExpandSelection(CaretSelection.Word, false);
+               }
+
                private void HandleControl(RTF.RTF rtf) {
+//                     Console.WriteLine ("HANDLING MAJOR:  {0}      MINOR:  {1}", rtf.Major, rtf.Minor);
                        switch(rtf.Major) {
                                case RTF.Major.Unicode: {
                                        switch(rtf.Minor) {
@@ -946,7 +1216,7 @@ Console.WriteLine("FIXME - SelectionColor should not alter font");
                                }
 
                                case RTF.Major.Destination: {
-                                       Console.Write("[Got Destination control {0}]", rtf.Minor);
+//                                     Console.Write("[Got Destination control {0}]", rtf.Minor);
                                        rtf.SkipGroup();
                                        break;
                                }
@@ -958,7 +1228,7 @@ Console.WriteLine("FIXME - SelectionColor should not alter font");
 
                                                        color = System.Windows.Forms.RTF.Color.GetColor(rtf, rtf.Param);
                                                        if (color != null) {
-                                                               FlushText(false);
+                                                               FlushText(rtf, false);
                                                                if (color.Red == -1 && color.Green == -1 && color.Blue == -1) {
                                                                        this.rtf_color = new SolidBrush(ForeColor);
                                                                } else {
@@ -969,6 +1239,7 @@ Console.WriteLine("FIXME - SelectionColor should not alter font");
                                                }
 
                                                case Minor.FontSize: {
+                                                       FlushText(rtf, false);
                                                        this.rtf_rtffont_size = rtf.Param / 2;
                                                        break;
                                                }
@@ -978,20 +1249,20 @@ Console.WriteLine("FIXME - SelectionColor should not alter font");
 
                                                        font = System.Windows.Forms.RTF.Font.GetFont(rtf, rtf.Param);
                                                        if (font != null) {
-                                                               FlushText(false);
+                                                               FlushText(rtf, false);
                                                                this.rtf_rtffont = font;
                                                        }
                                                        break;
                                                }
 
                                                case Minor.Plain: {
-                                                       FlushText(false);
+                                                       FlushText(rtf, false);
                                                        rtf_rtfstyle = FontStyle.Regular;
                                                        break;
                                                }
 
                                                case Minor.Bold: {
-                                                       FlushText(false);
+                                                       FlushText(rtf, false);
                                                        if (rtf.Param == RTF.RTF.NoParam) {
                                                                rtf_rtfstyle |= FontStyle.Bold;
                                                        } else {
@@ -1001,7 +1272,7 @@ Console.WriteLine("FIXME - SelectionColor should not alter font");
                                                }
 
                                                case Minor.Italic: {
-                                                       FlushText(false);
+                                                       FlushText(rtf, false);
                                                        if (rtf.Param == RTF.RTF.NoParam) {
                                                                rtf_rtfstyle |= FontStyle.Italic;
                                                        } else {
@@ -1011,7 +1282,7 @@ Console.WriteLine("FIXME - SelectionColor should not alter font");
                                                }
 
                                                case Minor.StrikeThru: {
-                                                       FlushText(false);
+                                                       FlushText(rtf, false);
                                                        if (rtf.Param == RTF.RTF.NoParam) {
                                                                rtf_rtfstyle |= FontStyle.Strikeout;
                                                        } else {
@@ -1021,17 +1292,17 @@ Console.WriteLine("FIXME - SelectionColor should not alter font");
                                                }
 
                                                case Minor.Underline: {
-                                                       FlushText(false);
+                                                       FlushText(rtf, false);
                                                        if (rtf.Param == RTF.RTF.NoParam) {
                                                                rtf_rtfstyle |= FontStyle.Underline;
                                                        } else {
-                                                               rtf_rtfstyle &= ~FontStyle.Underline;
+                                                               rtf_rtfstyle = rtf_rtfstyle & ~FontStyle.Underline;
                                                        }
                                                        break;
                                                }
 
                                                case Minor.NoUnderline: {
-                                                       FlushText(false);
+                                                       FlushText(rtf, false);
                                                        rtf_rtfstyle &= ~FontStyle.Underline;
                                                        break;
                                                }
@@ -1040,7 +1311,7 @@ Console.WriteLine("FIXME - SelectionColor should not alter font");
                                }
 
                                case RTF.Major.SpecialChar: {
-                                       Console.Write("[Got SpecialChar control {0}]", rtf.Minor);
+                                       //Console.Write("[Got SpecialChar control {0}]", rtf.Minor);
                                        SpecialChar(rtf);
                                        break;
                                }
@@ -1054,7 +1325,7 @@ Console.WriteLine("FIXME - SelectionColor should not alter font");
                                case Minor.Row:
                                case Minor.Line:
                                case Minor.Par: {
-                                       FlushText(true);
+                                       FlushText(rtf, true);
                                        break;
                                }
 
@@ -1069,52 +1340,59 @@ Console.WriteLine("FIXME - SelectionColor should not alter font");
                                }
 
                                case Minor.Tab: {
-                                       Console.Write("\t");
+                                       rtf_line.Append ("\t");
+//                                     FlushText (rtf, false);
                                        break;
                                }
 
+                               case Minor.NoReqHyphen:
                                case Minor.NoBrkHyphen: {
-                                       Console.Write("-");
+                                       rtf_line.Append ("-");
+//                                     FlushText (rtf, false);
                                        break;
                                }
 
                                case Minor.Bullet: {
-                                       Console.Write("*");
+                                       Console.WriteLine("*");
                                        break;
                                }
 
+                       case Minor.WidowCtrl:
+                               break;
+
                                case Minor.EmDash: {
-                                       Console.Write("\97");
+                               rtf_line.Append ("\u2014");
                                        break;
                                }
 
                                case Minor.EnDash: {
-                                       Console.Write("\96");
+                                       rtf_line.Append ("\u2013");
                                        break;
                                }
-
+/*
                                case Minor.LQuote: {
-                                       Console.Write("\91");
+                                       Console.Write("\u2018");
                                        break;
                                }
 
                                case Minor.RQuote: {
-                                       Console.Write("\92");
+                                       Console.Write("\u2019");
                                        break;
                                }
 
                                case Minor.LDblQuote: {
-                                       Console.Write("\93");
+                                       Console.Write("\u201C");
                                        break;
                                }
 
                                case Minor.RDblQuote: {
-                                       Console.Write("\94");
+                                       Console.Write("\u201D");
                                        break;
                                }
-
+*/
                                default: {
-                                       rtf.SkipGroup();
+//                                     Console.WriteLine ("skipped special char:   {0}", rtf.Minor);
+//                                     rtf.SkipGroup();
                                        break;
                                }
                        }
@@ -1138,29 +1416,50 @@ Console.WriteLine("FIXME - SelectionColor should not alter font");
                        }
                }
 
-               private void FlushText(bool newline) {
+               private void FlushText(RTF.RTF rtf, bool newline) {
                        int             length;
                        Font            font;
 
                        length = rtf_line.Length;
-                       if (length == 0) {
+                       if (!newline && (length == 0)) {
                                return;
                        }
 
-                       if (rtf_rtffont != null) {
-                               font = new Font(rtf_rtffont.Name, rtf_rtffont_size, rtf_rtfstyle);
-                       } else {
-                               font = this.Font;
+                       if (rtf_rtffont == null) {
+                               // First font in table is default
+                               rtf_rtffont = System.Windows.Forms.RTF.Font.GetFont(rtf, 0);
+                       }
+
+                       font = new Font(rtf_rtffont.Name, rtf_rtffont_size, rtf_rtfstyle);
+
+                       if (rtf_color == null) {
+                               System.Windows.Forms.RTF.Color color;
+
+                               // First color in table is default
+                               color = System.Windows.Forms.RTF.Color.GetColor(rtf, 0);
+
+                               if ((color == null) || (color.Red == -1 && color.Green == -1 && color.Blue == -1)) {
+                                       rtf_color = new SolidBrush(ForeColor);
+                               } else {
+                                       rtf_color = new SolidBrush(Color.FromArgb(color.Red, color.Green, color.Blue));
+                               }
                        }
 
+                       rtf_chars += rtf_line.Length;
+
                        if (rtf_cursor_x == 0) {
                                document.Add(rtf_cursor_y, rtf_line.ToString(), rtf_rtfalign, font, rtf_color);
                        } else {
                                Line    line;
 
                                line = document.GetLine(rtf_cursor_y);
-                               document.InsertString(line, rtf_cursor_x, rtf_line.ToString());
-                               document.FormatText(line, rtf_cursor_x + 1, line, rtf_cursor_x + 1 + length, font, rtf_color); // FormatText is 1-based
+                               if (rtf_line.Length > 0) {
+                                       document.InsertString(line, rtf_cursor_x, rtf_line.ToString());
+                                       document.FormatText(line, rtf_cursor_x + 1, line, rtf_cursor_x + 1 + length, font, rtf_color, null, FormatSpecified.Font | FormatSpecified.Color); // FormatText is 1-based
+                               }
+                               if (newline) {
+                                       document.Split(line, rtf_cursor_x + length);
+                               }
                        }
 
                        if (newline) {
@@ -1175,10 +1474,12 @@ Console.WriteLine("FIXME - SelectionColor should not alter font");
                private void InsertRTFFromStream(Stream data, int cursor_x, int cursor_y) {
                        int     x;
                        int     y;
+                       int     chars;
 
-                       InsertRTFFromStream(data, cursor_x, cursor_y, out x, out y);
+                       InsertRTFFromStream(data, cursor_x, cursor_y, out x, out y, out chars);
                }
-               private void InsertRTFFromStream(Stream data, int cursor_x, int cursor_y, out int to_x, out int to_y) {
+
+               private void InsertRTFFromStream(Stream data, int cursor_x, int cursor_y, out int to_x, out int to_y, out int chars) {
                        RTF.RTF         rtf;
 
                        rtf = new RTF.RTF(data);
@@ -1190,31 +1491,38 @@ Console.WriteLine("FIXME - SelectionColor should not alter font");
                        rtf_skip_width = 0;
                        rtf_skip_count = 0;
                        rtf_line = new StringBuilder();
-                       rtf_font = Font;
-                       rtf_color = new SolidBrush(ForeColor);
-                       rtf_rtffont_size = this.Font.Height;
+                       rtf_color = null;
+                       rtf_rtffont_size = (int)this.Font.Size;
                        rtf_rtfalign = HorizontalAlignment.Left;
+                       rtf_rtfstyle = FontStyle.Regular;
                        rtf_rtffont = null;
                        rtf_cursor_x = cursor_x;
                        rtf_cursor_y = cursor_y;
+                       rtf_chars = 0;
+                       rtf.DefaultFont(this.Font.Name);
 
                        rtf_text_map = new RTF.TextMap();
                        RTF.TextMap.SetupStandardTable(rtf_text_map.Table);
 
+                       document.NoRecalc = true;
+
                        try {
                                rtf.Read();     // That's it
-                               FlushText(false);
+                               FlushText(rtf, false);
                        }
 
-                       catch (RTF.RTFException) {
-                               // Seems to be plain text...
-                               
+                       catch (RTF.RTFException e) {
+                               // Seems to be plain text or broken RTF
+                               Console.WriteLine("RTF Parsing failure: {0}", e.Message);
                        }
 
                        to_x = rtf_cursor_x;
                        to_y = rtf_cursor_y;
+                       chars = rtf_chars;
+
+                       document.RecalculateDocument(CreateGraphicsInternal(), cursor_y, document.Lines, false);
+                       document.NoRecalc = false;
 
-                       document.RecalculateDocument(CreateGraphics(), cursor_y, document.Lines, false);
                        document.Invalidate(document.GetLine(cursor_y), 0, document.GetLine(document.Lines), -1);
                }
 
@@ -1251,8 +1559,8 @@ Console.WriteLine("FIXME - SelectionColor should not alter font");
                                rtf.Append(String.Format("\\f{0}", font_index));        // Font table entry
                        }
 
-                       if ((prev_font == null) || (prev_font.Height != font.Height)) {
-                               rtf.Append(String.Format("\\fs{0}", font.Height * 2));          // Font size
+                       if ((prev_font == null) || (prev_font.Size != font.Size)) {
+                               rtf.Append(String.Format("\\fs{0}", (int)(font.Size * 2)));             // Font size
                        }
 
                        if ((prev_font == null) || (font.Bold != prev_font.Bold)) {
@@ -1301,6 +1609,7 @@ Console.WriteLine("FIXME - SelectionColor should not alter font");
                        rtf.Append(text);
                }
 
+               // start_pos and end_pos are 0-based
                private StringBuilder GenerateRTF(Line start_line, int start_pos, Line end_line, int end_pos) {
                        StringBuilder   sb;
                        ArrayList       fonts;
@@ -1359,7 +1668,7 @@ Console.WriteLine("FIXME - SelectionColor should not alter font");
                                                }
                                        }
 
-                                       pos += tag.length;
+                                       pos = tag.start + tag.length - 1;
                                        tag = tag.next;
                                }
                                pos = 0;
@@ -1388,7 +1697,7 @@ Console.WriteLine("FIXME - SelectionColor should not alter font");
                        sb.Append("}\n");
 
                        // Emit the color table (if needed)
-                       if (colors.Count > 1) {
+                       if ((colors.Count > 1) || ((((Color)colors[0]).R != this.ForeColor.R) || (((Color)colors[0]).G != this.ForeColor.G) || (((Color)colors[0]).B != this.ForeColor.B))) {
                                sb.Append("{\\colortbl ");                      // Header and NO! default color
                                for (i = 0; i < colors.Count; i++) {
                                        sb.Append(String.Format("\\red{0}", ((Color)colors[i]).R));
@@ -1450,11 +1759,13 @@ Console.WriteLine("FIXME - SelectionColor should not alter font");
                                                }
                                        }
 
-                                       pos += tag.length;
+                                       pos = tag.start + tag.length - 1;
                                        tag = tag.next;
                                }
-                               if (!line.soft_break) {
-                                       sb.Append("\\par\n");
+                               if (pos >= line.text.Length) {
+                                       if (!line.soft_break) {
+                                               sb.Append("\\par\n");
+                                       }
                                }
                                pos = 0;
                                line_no++;