2005-10-13 Peter Dennis Bartok <pbartok@novell.com>
[mono.git] / mcs / class / Managed.Windows.Forms / System.Windows.Forms / RichTextBox.cs
1 // Permission is hereby granted, free of charge, to any person obtaining
2 // a copy of this software and associated documentation files (the
3 // "Software"), to deal in the Software without restriction, including
4 // without limitation the rights to use, copy, modify, merge, publish,
5 // distribute, sublicense, and/or sell copies of the Software, and to
6 // permit persons to whom the Software is furnished to do so, subject to
7 // the following conditions:
8 // 
9 // The above copyright notice and this permission notice shall be
10 // included in all copies or substantial portions of the Software.
11 // 
12 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
13 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
14 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
15 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
16 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
17 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
18 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19 //
20 // Copyright (c) 2005 Novell, Inc. (http://www.novell.com)
21 //
22 // Authors:
23 //      Peter Bartok    <pbartok@novell.com>
24 //
25 //
26
27 // NOT COMPLETE
28
29 using System;
30 using System.ComponentModel;
31 using System.Drawing;
32 using System.IO;
33 using System.Text;
34 using RTF=System.Windows.Forms.RTF;
35
36 namespace System.Windows.Forms {
37         public class RichTextBox : TextBoxBase {
38                 #region Local Variables
39                 internal bool           auto_word_select;
40                 internal int            bullet_indent;
41                 internal bool           can_redo;
42                 internal bool           detect_urls;
43                 internal string         redo_action_name;
44                 internal int            margin_right;
45                 internal string         undo_action_name;
46                 internal float          zoom;
47
48                 private RTF.TextMap     rtf_text_map;
49                 private int             rtf_skip_width;
50                 private int             rtf_skip_count;
51                 private StringBuilder   rtf_line;
52                 private Font            rtf_font;
53                 private SolidBrush      rtf_color;
54                 private RTF.Font        rtf_rtffont;
55                 private int             rtf_rtffont_size;
56                 private FontStyle       rtf_rtfstyle;
57                 private HorizontalAlignment rtf_rtfalign;
58                 private int             rtf_cursor_x;
59                 private int             rtf_cursor_y;
60                 #endregion      // Local Variables
61
62                 #region Public Constructors
63                 public RichTextBox() {
64                         accepts_return = true;
65                         auto_word_select = false;
66                         bullet_indent = 0;
67                         can_redo = false;
68                         detect_urls = true;
69                         max_length = Int32.MaxValue;
70                         redo_action_name = string.Empty;
71                         margin_right = 0;
72                         undo_action_name = string.Empty;
73                         zoom = 1;
74                         base.Multiline = true;
75                         document.CRLFSize = 1;
76
77                         scrollbars = RichTextBoxScrollBars.Both;
78                         alignment = HorizontalAlignment.Left;
79                         this.LostFocus +=new EventHandler(RichTextBox_LostFocus);
80                         this.BackColor = ThemeEngine.Current.ColorWindow;
81                         this.ForeColor = ThemeEngine.Current.ColorWindowText;
82
83                         Console.WriteLine("A friendly request: Do not log a bug about debug messages being emitted when\n" +
84                                 "using RichTextBox. It's not yet finished, it will spew debug information, and\n" +
85                                 "it may not work the way you like it just yet. Some methods also are also not yet\n" + 
86                                 "implemented. And we're also aware that text gets bolder with every change.");
87                         Console.WriteLine("To quote Sean Gilkes: Patience is a virtue, waiting doesn't hurt you :-)");
88                 }
89                 #endregion      // Public Constructors
90
91                 #region Private & Internal Methods
92                 private void RichTextBox_LostFocus(object sender, EventArgs e) {
93                         has_focus = false;
94                         Invalidate();
95                 }
96                 #endregion      // Private & Internal Methods
97
98                 #region Public Instance Properties
99                 public override bool AllowDrop {
100                         get {
101                                 return base.AllowDrop;
102                         }
103
104                         set {
105                                 base.AllowDrop = value;
106                         }
107                 }
108
109                 [DefaultValue(false)]
110                 public override bool AutoSize {
111                         get {
112                                 return auto_size;
113                         }
114
115                         set {
116                                 base.AutoSize = value;
117                         }
118                 }
119
120                 [DefaultValue(false)]
121                 public bool AutoWordSelection {
122                         get {
123                                 return auto_word_select;
124                         }
125
126                         set {
127                                 auto_word_select = true;
128                         }
129                 }
130
131                 [Browsable(false)]
132                 [EditorBrowsable(EditorBrowsableState.Never)]
133                 public override System.Drawing.Image BackgroundImage {
134                         get {
135                                 return background_image;
136                         }
137
138                         set {
139                                 base.BackgroundImage = value;
140                         }
141                 }
142
143                 [DefaultValue(0)]
144                 [Localizable(true)]
145                 public int BulletIndent {
146                         get {
147                                 return bullet_indent;
148                         }
149
150                         set {
151                                 bullet_indent = value;
152                         }
153                 }
154
155                 [Browsable(false)]
156                 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
157                 public bool CanRedo {
158                         get {
159                                 return can_redo;
160                         }
161                 }
162
163                 [DefaultValue(true)]
164                 public bool DetectUrls {
165                         get {
166                                 return detect_urls;
167                         }
168
169                         set {
170                                 detect_urls = true;
171                         }
172                 }
173
174                 public override Font Font {
175                         get {
176                                 return base.Font;
177                         }
178
179                         set {
180                                 if (font != value) {
181                                         if (auto_size) {
182                                                 if (PreferredHeight != Height) {
183                                                         Height = PreferredHeight;
184                                                 }
185                                         }
186
187                                         base.Font = value;
188                                 }
189                         }
190                 }
191
192                 public override Color ForeColor {
193                         get {
194                                 return base.ForeColor;
195                         }
196
197                         set {
198                                 base.ForeColor = value;
199                         }
200                 }
201
202                 [DefaultValue(Int32.MaxValue)]
203                 public override int MaxLength {
204                         get {
205                                 return base.max_length;
206                         }
207
208                         set {
209                                 base.max_length = value;
210                         }
211                 }
212
213                 [DefaultValue(true)]
214                 public override bool Multiline {
215                         get {
216                                 return multiline;
217                         }
218
219                         set {
220                                 base.Multiline = value;
221                         }
222                 }
223
224                 [Browsable(false)]
225                 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
226                 [MonoTODO]
227                 public string RedoActionName {
228                         get {
229                                 return redo_action_name;
230                         }
231                 }
232
233                 [DefaultValue(0)]
234                 [Localizable(true)]
235                 [MonoTODO("Teach TextControl.RecalculateLine to consider the right margin as well")]
236                 public int RightMargin {
237                         get {
238                                 return margin_right;
239                         }
240
241                         set {
242                                 margin_right = value;
243                         }
244                 }
245
246                 [Browsable(false)]
247                 [DefaultValue("")]
248                 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
249                 [MonoTODO("finish and plug in the rtf parser/generator")]
250                 public string Rtf {
251                         get {
252                                 // FIXME
253                                 return null;
254                         }
255
256                         set {
257                                 // FIXME
258                         }
259                 }
260
261                 [DefaultValue(RichTextBoxScrollBars.Both)]
262                 [Localizable(true)]
263                 public RichTextBoxScrollBars ScrollBars {
264                         get {
265                                 return scrollbars;
266                         }
267
268                         set {
269                                 scrollbars = value;
270                         }
271                 }
272
273                 [MonoTODO("finish and plug in rtf parser/generator")]
274                 public string SelectedRtf {
275                         get {
276                                 // FIXME
277                                 return null;
278                         }
279
280                         set {
281                                 // FIXME
282                         }
283                 }
284
285                 public override string SelectedText {
286                         get {
287                                 return base.SelectedText;
288                         }
289
290                         set {
291                                 base.SelectedText = value;
292                         }
293                 }
294
295                 [Browsable(false)]
296                 [DefaultValue(HorizontalAlignment.Left)]
297                 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
298                 public HorizontalAlignment SelectionAlignment {
299                         get {
300                                 HorizontalAlignment     align;
301                                 Line                    start;
302                                 Line                    end;
303                                 Line                    line;
304
305                                 start = document.ParagraphStart(document.selection_start.line);
306                                 align = start.alignment;
307
308                                 end = document.ParagraphEnd(document.selection_end.line);
309
310                                 line = start;
311
312                                 while (true) {
313                                         if (line.alignment != align) {
314                                                 return HorizontalAlignment.Left;
315                                         }
316
317                                         if (line == end) {
318                                                 break;
319                                         }
320                                         line = document.GetLine(line.line_no + 1);
321                                 }
322
323                                 return align;
324                         }
325
326                         set {
327                                 Line                    start;
328                                 Line                    end;
329                                 Line                    line;
330
331                                 start = document.ParagraphStart(document.selection_start.line);
332
333                                 end = document.ParagraphEnd(document.selection_end.line);
334
335                                 line = start;
336
337                                 while (true) {
338                                         line.alignment = value;
339
340                                         if (line == end) {
341                                                 break;
342                                         }
343                                         line = document.GetLine(line.line_no + 1);
344                                 }
345                                 this.CalculateDocument();
346                         }
347                 }
348
349
350                 public Font SelectionFont {
351                         get {
352                                 Font    font;
353                                 LineTag start;
354                                 LineTag end;
355                                 LineTag tag;
356
357                                 start = document.selection_start.tag;
358                                 end = document.selection_end.tag;
359                                 font = document.selection_start.tag.font;
360
361                                 tag = start;
362                                 while (true) {
363                                         if (!font.Equals(tag.font)) {
364                                                 return null;
365                                         }
366
367                                         if (tag == end) {
368                                                 break;
369                                         }
370
371                                         tag = document.NextTag(tag);
372
373                                         if (tag == null) {
374                                                 break;
375                                         }
376                                 }
377
378                                 return font;
379                         }
380
381                         set {
382                                 int     sel_start;
383                                 int     sel_end;
384
385                                 sel_start = document.LineTagToCharIndex(document.selection_start.line, document.selection_start.pos);
386                                 sel_end = document.LineTagToCharIndex(document.selection_end.line, document.selection_end.pos);
387
388                                 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);
389
390                                 document.CharIndexToLineTag(sel_start, out document.selection_start.line, out document.selection_start.tag, out document.selection_start.pos);
391                                 document.CharIndexToLineTag(sel_end, out document.selection_end.line, out document.selection_end.tag, out document.selection_end.pos);
392
393                                 document.UpdateView(document.selection_start.line, 0);
394                                 document.AlignCaret();
395                                 
396                         }
397                 }
398
399                 [Localizable(true)]
400                 public override string Text {
401                         get {
402                                 return base.Text;
403                         }
404
405                         set {
406                                 base.Text = value;
407                         }
408                 }
409
410                 [Browsable(false)]
411                 public override int TextLength {
412                         get {
413                                 return base.TextLength;
414                         }
415                 }
416
417                 [Browsable(false)]
418                 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
419                 public string UndoActionName {
420                         get {
421                                 return undo_action_name;
422                         }
423                 }
424
425                 [Localizable(true)]
426                 [DefaultValue(1)]
427                 public float ZoomFactor {
428                         get {
429                                 return zoom;
430                         }
431
432                         set {
433                                 zoom = value;
434                         }
435                 }
436                 #endregion      // Public Instance Properties
437
438                 #region Protected Instance Properties
439                 protected override CreateParams CreateParams {
440                         get {
441                                 return base.CreateParams;
442                         }
443                 }
444
445                 protected override Size DefaultSize {
446                         get {
447                                 return new Size(100, 96);
448                         }
449                 }
450                 #endregion      // Protected Instance Properties
451
452                 #region Public Instance Methods
453                 public void LoadFile(System.IO.Stream data, RichTextBoxStreamType fileType) {
454                         RTF.RTF rtf;    // Not 'using SWF.RTF' to avoid ambiguities with font and color
455
456                         document.Empty();
457
458                         // FIXME - ignoring unicode
459                         if (fileType == RichTextBoxStreamType.PlainText) {
460                                 StringBuilder   sb;
461                                 int             count;
462                                 byte[]          buffer;
463
464                                 try {
465                                         sb = new StringBuilder((int)data.Length);
466                                         buffer = new byte[1024];
467                                 }
468
469                                 catch {
470                                         throw new IOException("Not enough memory to load document");
471                                 }
472
473                                 count = 0;
474                                 while (count < data.Length) {
475                                         count += data.Read(buffer, count, 1024);
476                                         sb.Append(buffer);
477                                 }
478                                 base.Text = sb.ToString();
479                                 return;
480                         }
481
482
483                         rtf = new RTF.RTF(data);
484
485                         // Prepare
486                         rtf.ClassCallback[RTF.TokenClass.Text] = new RTF.ClassDelegate(HandleText);
487                         rtf.ClassCallback[RTF.TokenClass.Control] = new RTF.ClassDelegate(HandleControl);
488
489                         rtf_skip_width = 0;
490                         rtf_skip_count = 0;
491                         rtf_line = new StringBuilder();
492                         rtf_font = Font;
493                         rtf_color = new SolidBrush(ForeColor);
494                         rtf_rtffont_size = this.Font.Height;
495                         rtf_rtfalign = HorizontalAlignment.Left;
496                         rtf_rtffont = null;
497                         rtf_cursor_x = 0;
498                         rtf_cursor_y = 1;
499
500                         rtf_text_map = new RTF.TextMap();
501                         RTF.TextMap.SetupStandardTable(rtf_text_map.Table);
502
503                         rtf.Read();     // That's it
504                         document.RecalculateDocument(CreateGraphics());
505                 }
506
507                 public void LoadFile(string path) {
508                         if (path.EndsWith(".rtf")) {
509                                 LoadFile(path, RichTextBoxStreamType.RichText);
510                         } else {
511                                 LoadFile(path, RichTextBoxStreamType.PlainText);
512                         }
513                 }
514
515                 public void LoadFile(string path, RichTextBoxStreamType fileType) {
516                         FileStream      data;
517
518                         data = null;
519
520 //                      try {
521                                 data = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, 1024);
522                                 LoadFile(data, fileType);
523 //                      }
524
525 //                      catch {
526 //                              throw new IOException("Could not open file " + path);
527 //                      }
528
529 //                      finally {
530                                 if (data != null) {
531                                         data.Close();
532 //                              }
533                         }
534                 }
535
536                 public void SaveFile(Stream data, RichTextBoxStreamType fileType) {
537                         #if later
538                         Encoding        encoding;
539
540                         if (fileType == RichTextBoxStreamType.UnicodePlainText) {
541                                 encoding = Encoding.Unicode;
542                         } else {
543                                 encoding = Encoding.ASCII;
544                         }
545                         #endif
546                 }
547
548                 public void SaveFile(string path) {
549                         if (path.EndsWith(".rtf")) {
550                                 SaveFile(path, RichTextBoxStreamType.RichText);
551                         } else {
552                                 SaveFile(path, RichTextBoxStreamType.PlainText);
553                         }
554                 }
555
556                 public void SaveFile(string path, RichTextBoxStreamType fileType) {
557                         FileStream      data;
558
559                         data = null;
560
561                         try {
562                                 data = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.None, 1024, false);
563                                 SaveFile(data, fileType);
564                         }
565
566                         catch {
567                                 throw new IOException("Could not write document to file " + path);
568                         }
569
570                         finally {
571                                 if (data != null) {
572                                         data.Close();
573                                 }
574                         }
575                 }
576
577                 #endregion      // Public Instance Methods
578
579                 #region Protected Instance Methods
580                 protected override void OnBackColorChanged(EventArgs e) {
581                         base.OnBackColorChanged (e);
582                 }
583
584                 protected override void OnContextMenuChanged(EventArgs e) {
585                         base.OnContextMenuChanged (e);
586                 }
587
588                 protected override void OnHandleCreated(EventArgs e) {
589                         base.OnHandleCreated (e);
590                 }
591
592                 protected override void OnHandleDestroyed(EventArgs e) {
593                         base.OnHandleDestroyed (e);
594                 }
595
596                 protected override void OnRightToLeftChanged(EventArgs e) {
597                         base.OnRightToLeftChanged (e);
598                 }
599
600                 protected override void OnSystemColorsChanged(EventArgs e) {
601                         base.OnSystemColorsChanged (e);
602                 }
603
604                 protected override void OnTextChanged(EventArgs e) {
605                         base.OnTextChanged (e);
606                 }
607
608                 protected override void WndProc(ref Message m) {
609                         base.WndProc (ref m);
610                 }
611                 #endregion      // Protected Instance Methods
612
613                 #region Events
614                 [Browsable(false)]
615                 [EditorBrowsable(EditorBrowsableState.Never)]
616                 public event EventHandler                       BackgroundImageChanged;
617
618                 public event ContentsResizedEventHandler        ContentsResized;
619
620                 [Browsable(false)]
621                 [EditorBrowsable(EditorBrowsableState.Never)]
622                 public event EventHandler                       DoubleClick;
623
624                 [Browsable(false)]
625                 [EditorBrowsable(EditorBrowsableState.Never)]
626                 public event DragEventHandler                   DragDrop;
627
628                 [Browsable(false)]
629                 [EditorBrowsable(EditorBrowsableState.Never)]
630                 public event DragEventHandler                   DragEnter;
631
632                 [Browsable(false)]
633                 [EditorBrowsable(EditorBrowsableState.Never)]
634                 public event EventHandler                       DragLeave;
635
636                 [Browsable(false)]
637                 [EditorBrowsable(EditorBrowsableState.Never)]
638                 public event DragEventHandler                   DragOver;
639
640                 [Browsable(false)]
641                 [EditorBrowsable(EditorBrowsableState.Never)]
642                 public event GiveFeedbackEventHandler           GiveFeedback;
643
644                 public event EventHandler                       HScroll;
645                 public event EventHandler                       ImeChange;
646                 public event LinkClickedEventHandler            LinkClicked;
647                 public event EventHandler                       Protected;
648
649                 [Browsable(false)]
650                 [EditorBrowsable(EditorBrowsableState.Never)]
651                 public event QueryContinueDragEventHandler      QueryContinueDrag;
652                 public event EventHandler                       SelectionChanged;
653                 public event EventHandler                       VScroll;
654                 #endregion      // Events
655
656                 #region Private Methods
657                 void HandleControl(RTF.RTF rtf) {
658                         switch(rtf.Major) {
659                                 case RTF.Major.Unicode: {
660                                         switch(rtf.Minor) {
661                                                 case Minor.UnicodeCharBytes: {
662                                                         rtf_skip_width = rtf.Param;
663                                                         break;
664                                                 }
665
666                                                 case Minor.UnicodeChar: {
667                                                         rtf_skip_count += rtf_skip_width;
668                                                         rtf_line.Append((char)rtf.Param);
669                                                         break;
670                                                 }
671                                         }
672                                         break;
673                                 }
674
675                                 case RTF.Major.Destination: {
676                                         Console.Write("[Got Destination control {0}]", rtf.Minor);
677                                         rtf.SkipGroup();
678                                         break;
679                                 }
680
681                                 case RTF.Major.CharAttr: {
682                                         switch(rtf.Minor) {
683                                                 case Minor.ForeColor: {
684                                                         System.Windows.Forms.RTF.Color  color;
685
686                                                         color = System.Windows.Forms.RTF.Color.GetColor(rtf, rtf.Param);
687                                                         if (color != null) {
688                                                                 FlushText(false);
689                                                                 if (color.Red == -1 && color.Green == -1 && color.Blue == -1) {
690                                                                         this.rtf_color = new SolidBrush(ForeColor);
691                                                                 } else {
692                                                                         this.rtf_color = new SolidBrush(Color.FromArgb(color.Red, color.Green, color.Blue));
693                                                                 }
694                                                         }
695                                                         break;
696                                                 }
697
698                                                 case Minor.FontSize: {
699                                                         this.rtf_rtffont_size = rtf.Param / 2;
700                                                         break;
701                                                 }
702
703                                                 case Minor.FontNum: {
704                                                         System.Windows.Forms.RTF.Font   font;
705
706                                                         font = System.Windows.Forms.RTF.Font.GetFont(rtf, rtf.Param);
707                                                         if (font != null) {
708                                                                 FlushText(false);
709                                                                 this.rtf_rtffont = font;
710                                                         }
711                                                         break;
712                                                 }
713
714                                                 case Minor.Plain: {
715                                                         FlushText(false);
716                                                         rtf_rtfstyle = FontStyle.Regular;
717                                                         break;
718                                                 }
719
720                                                 case Minor.Bold: {
721                                                         FlushText(false);
722                                                         if (rtf.Param == RTF.RTF.NoParam) {
723                                                                 rtf_rtfstyle |= FontStyle.Bold;
724                                                         } else {
725                                                                 rtf_rtfstyle &= ~FontStyle.Bold;
726                                                         }
727                                                         break;
728                                                 }
729
730                                                 case Minor.Italic: {
731                                                         FlushText(false);
732                                                         if (rtf.Param == RTF.RTF.NoParam) {
733                                                                 rtf_rtfstyle |= FontStyle.Italic;
734                                                         } else {
735                                                                 rtf_rtfstyle &= ~FontStyle.Italic;
736                                                         }
737                                                         break;
738                                                 }
739
740                                                 case Minor.StrikeThru: {
741                                                         FlushText(false);
742                                                         if (rtf.Param == RTF.RTF.NoParam) {
743                                                                 rtf_rtfstyle |= FontStyle.Strikeout;
744                                                         } else {
745                                                                 rtf_rtfstyle &= ~FontStyle.Strikeout;
746                                                         }
747                                                         break;
748                                                 }
749
750                                                 case Minor.Underline: {
751                                                         FlushText(false);
752                                                         if (rtf.Param == RTF.RTF.NoParam) {
753                                                                 rtf_rtfstyle |= FontStyle.Underline;
754                                                         } else {
755                                                                 rtf_rtfstyle &= ~FontStyle.Underline;
756                                                         }
757                                                         break;
758                                                 }
759
760                                                 case Minor.NoUnderline: {
761                                                         FlushText(false);
762                                                         rtf_rtfstyle &= ~FontStyle.Underline;
763                                                         break;
764                                                 }
765                                         }
766                                         break;
767                                 }
768
769                                 case RTF.Major.SpecialChar: {
770                                         Console.Write("[Got SpecialChar control {0}]", rtf.Minor);
771                                         SpecialChar(rtf);
772                                         break;
773                                 }
774                         }
775                 }
776
777                 void SpecialChar(RTF.RTF rtf) {
778                         switch(rtf.Minor) {
779                                 case Minor.Page:
780                                 case Minor.Sect:
781                                 case Minor.Row:
782                                 case Minor.Line:
783                                 case Minor.Par: {
784                                         FlushText(true);
785                                         break;
786                                 }
787
788                                 case Minor.Cell: {
789                                         Console.Write(" ");
790                                         break;
791                                 }
792
793                                 case Minor.NoBrkSpace: {
794                                         Console.Write(" ");
795                                         break;
796                                 }
797
798                                 case Minor.Tab: {
799                                         Console.Write("\t");
800                                         break;
801                                 }
802
803                                 case Minor.NoBrkHyphen: {
804                                         Console.Write("-");
805                                         break;
806                                 }
807
808                                 case Minor.Bullet: {
809                                         Console.Write("*");
810                                         break;
811                                 }
812
813                                 case Minor.EmDash: {
814                                         Console.Write("\97");
815                                         break;
816                                 }
817
818                                 case Minor.EnDash: {
819                                         Console.Write("\96");
820                                         break;
821                                 }
822
823                                 case Minor.LQuote: {
824                                         Console.Write("\91");
825                                         break;
826                                 }
827
828                                 case Minor.RQuote: {
829                                         Console.Write("\92");
830                                         break;
831                                 }
832
833                                 case Minor.LDblQuote: {
834                                         Console.Write("\93");
835                                         break;
836                                 }
837
838                                 case Minor.RDblQuote: {
839                                         Console.Write("\94");
840                                         break;
841                                 }
842
843                                 default: {
844                                         rtf.SkipGroup();
845                                         break;
846                                 }
847                         }
848                 }
849
850
851                 void HandleText(RTF.RTF rtf) {
852                         if (rtf_skip_count > 0) {
853                                 rtf_skip_count--;
854                                 return;
855                         }
856
857                         if ((RTF.StandardCharCode)rtf.Minor != RTF.StandardCharCode.nothing) {
858                                 rtf_line.Append(rtf_text_map[(RTF.StandardCharCode)rtf.Minor]);
859                         } else {
860                                 if ((int)rtf.Major > 31 && (int)rtf.Major < 128) {
861                                         rtf_line.Append((char)rtf.Major);
862                                 } else {
863                                         //rtf_line.Append((char)rtf.Major);
864                                         Console.Write("[Literal:0x{0:X2}]", (int)rtf.Major);
865                                 }
866                         }
867                 }
868
869                 void FlushText(bool newline) {
870                         int             length;
871                         Font            font;
872
873                         length = rtf_line.Length;
874                         if (length == 0) {
875                                 return;
876                         }
877
878                         if (rtf_rtffont != null) {
879                                 font = new Font(rtf_rtffont.Name, rtf_rtffont_size, rtf_rtfstyle);
880                         } else {
881                                 font = this.Font;
882                         }
883
884                         if (rtf_cursor_x == 0) {
885                                 document.Add(rtf_cursor_y, rtf_line.ToString(), rtf_rtfalign, font, rtf_color);
886                         } else {
887                                 Line    line;
888
889                                 line = document.GetLine(rtf_cursor_y);
890                                 document.InsertString(line, rtf_cursor_x, rtf_line.ToString());
891                                 document.FormatText(line, rtf_cursor_x, line, rtf_cursor_x + length, font, rtf_color);
892                         }
893
894                         if (newline) {
895                                 rtf_cursor_x = 0;
896                                 rtf_cursor_y++;
897                         } else {
898                                 rtf_cursor_x += length;
899                         }
900                         rtf_line.Length = 0;    // Empty line
901                 }
902                 #endregion      // Private Methods
903         }
904 }