Subversion Repositories DevTools

Rev

Rev 2134 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 2134 Rev 2136
Line 1... Line 1...
1
using System;
1
using System;
2
using System.Collections;
2
using System.Collections;
3
using System.Text;
3
using System.Text;
-
 
4
using System.Text.RegularExpressions;
4
using Word;
5
using Microsoft.Office.Interop.Word;
5
using Microsoft.Office.Core;
6
using Microsoft.Office.Core;
6
 
7
 
7
 
8
 
8
// TODO
9
// TODO
9
//
10
//
Line 76... Line 77...
76
         STYLE_ID_LIST_NUMBER_4,
77
         STYLE_ID_LIST_NUMBER_4,
77
         STYLE_ID_LIST_ALPHA_0,
78
         STYLE_ID_LIST_ALPHA_0,
78
         STYLE_ID_LIST_ALPHA_1,
79
         STYLE_ID_LIST_ALPHA_1,
79
         STYLE_ID_LIST_ALPHA_2,
80
         STYLE_ID_LIST_ALPHA_2,
80
         STYLE_ID_LIST_ALPHA_3,
81
         STYLE_ID_LIST_ALPHA_3,
81
         STYLE_ID_LIST_ALPHA_4
82
         STYLE_ID_LIST_ALPHA_4,
82
         // do not put anything below here
83
         // do not put anything below here
-
 
84
         STYLE_ID_FONT_COLOR
83
      };
85
      };
84
 
86
 
85
      // A token is a block of text associated with a tag (style) name and type
87
      // A token is a block of text associated with a tag (style) name and type
86
      private struct token_type
88
      private struct token_type
87
      {
89
      {
Line 97... Line 99...
97
      // appended to the word document. For this formatting, we need to remember the word
99
      // appended to the word document. For this formatting, we need to remember the word
98
      // ranges that denote the text and the style name to apply. So we do it in a list of
100
      // ranges that denote the text and the style name to apply. So we do it in a list of
99
      // the following item.
101
      // the following item.
100
      private struct postFormat_type
102
      private struct postFormat_type
101
      {
103
      {
102
         public postFormat_type(Word.Range wr, token_type tk)
104
         public postFormat_type(Range wr, token_type tk)
103
         {
105
         {
104
            m_wr = wr;
106
            m_wr = wr;
105
            m_tk = tk;
107
            m_tk = tk;
106
         }
108
         }
107
         public Word.Range m_wr;
109
         public Range m_wr;
108
         public token_type m_tk;
110
         public token_type m_tk;
109
      };
111
      };
110
 
112
 
111
      // Use a hash table for recording the allowed tags and their attributes, facilitating rapid
113
      // Use a hash table for recording the allowed tags and their attributes, facilitating rapid
112
      // lookup during parsing.
114
      // lookup during parsing.
Line 132... Line 134...
132
 
134
 
133
         // MS-Word formatting tags
135
         // MS-Word formatting tags
134
         styleDefs.Add( "b", formStyleDef( style_type_e.STYLE_MS_WORD, style_id_e.STYLE_ID_BOLD, EA_Constants.styleName_Bold      , 0, style_handling_e.STYLE_POST_FORMAT) );
136
         styleDefs.Add( "b", formStyleDef( style_type_e.STYLE_MS_WORD, style_id_e.STYLE_ID_BOLD, EA_Constants.styleName_Bold      , 0, style_handling_e.STYLE_POST_FORMAT) );
135
         styleDefs.Add( "i", formStyleDef( style_type_e.STYLE_MS_WORD, style_id_e.STYLE_ID_ITALIC, EA_Constants.styleName_Italic    , 0, style_handling_e.STYLE_POST_FORMAT) );
137
         styleDefs.Add( "i", formStyleDef( style_type_e.STYLE_MS_WORD, style_id_e.STYLE_ID_ITALIC, EA_Constants.styleName_Italic    , 0, style_handling_e.STYLE_POST_FORMAT) );
136
         styleDefs.Add( "u", formStyleDef( style_type_e.STYLE_MS_WORD, style_id_e.STYLE_ID_UNDERLINE, EA_Constants.styleName_Underline , 0, style_handling_e.STYLE_POST_FORMAT) );
138
         styleDefs.Add( "u", formStyleDef( style_type_e.STYLE_MS_WORD, style_id_e.STYLE_ID_UNDERLINE, EA_Constants.styleName_Underline , 0, style_handling_e.STYLE_POST_FORMAT) );
-
 
139
         styleDefs.Add("font", formStyleDef(style_type_e.STYLE_MS_WORD, style_id_e.STYLE_ID_FONT_COLOR, EA_Constants.styleName_Font_Color, 0, style_handling_e.STYLE_POST_FORMAT));
137
 
140
 
138
         styleDefs.Add( "lb0", formStyleDef( style_type_e.STYLE_MS_WORD, style_id_e.STYLE_ID_LIST_BULLET_0, EA_Constants.styleName_ListBullet0,1, style_handling_e.STYLE_POST_FORMAT ) );
141
         styleDefs.Add( "lb0", formStyleDef( style_type_e.STYLE_MS_WORD, style_id_e.STYLE_ID_LIST_BULLET_0, EA_Constants.styleName_ListBullet0,1, style_handling_e.STYLE_POST_FORMAT ) );
139
         styleDefs.Add( "lb1", formStyleDef( style_type_e.STYLE_MS_WORD, style_id_e.STYLE_ID_LIST_BULLET_1, EA_Constants.styleName_ListBullet1,2, style_handling_e.STYLE_POST_FORMAT ) );
142
         styleDefs.Add( "lb1", formStyleDef( style_type_e.STYLE_MS_WORD, style_id_e.STYLE_ID_LIST_BULLET_1, EA_Constants.styleName_ListBullet1,2, style_handling_e.STYLE_POST_FORMAT ) );
140
         styleDefs.Add( "lb2", formStyleDef( style_type_e.STYLE_MS_WORD, style_id_e.STYLE_ID_LIST_BULLET_2, EA_Constants.styleName_ListBullet2,3, style_handling_e.STYLE_POST_FORMAT ) );
143
         styleDefs.Add( "lb2", formStyleDef( style_type_e.STYLE_MS_WORD, style_id_e.STYLE_ID_LIST_BULLET_2, EA_Constants.styleName_ListBullet2,3, style_handling_e.STYLE_POST_FORMAT ) );
141
         styleDefs.Add( "lb3", formStyleDef( style_type_e.STYLE_MS_WORD, style_id_e.STYLE_ID_LIST_BULLET_3, EA_Constants.styleName_ListBullet3,4, style_handling_e.STYLE_POST_FORMAT ) );
144
         styleDefs.Add( "lb3", formStyleDef( style_type_e.STYLE_MS_WORD, style_id_e.STYLE_ID_LIST_BULLET_3, EA_Constants.styleName_ListBullet3,4, style_handling_e.STYLE_POST_FORMAT ) );
Line 233... Line 236...
233
         int pos_tagName;
236
         int pos_tagName;
234
         int pos_ContentStart;
237
         int pos_ContentStart;
235
         int pos_ContentEnd;
238
         int pos_ContentEnd;
236
         bool lookingForTagEnd;
239
         bool lookingForTagEnd;
237
         bool foundError = false;
240
         bool foundError = false;
238
         Word.Range wr_body;
241
         Range wr_body;
239
 
242
 
240
         // Convert EA7.1 embedded RTF controls into EA_DocGen controls where possible
243
         // Convert EA7.1 embedded RTF controls into EA_DocGen controls where possible
241
         s = convert_EA7_1_RTF_ListTag(s, "<ol>\r\n", "</ol>", "<ln0>", "</ln0>");
244
         s = convert_EA7_1_RTF_ListTag(s, "<ol>\r\n", "</ol>", "<ln0>", "</ln0>");
242
         s = convert_EA7_1_RTF_ListTag(s, "<ul>\r\n", "</ul>", "<lb0>", "</lb0>");
245
         s = convert_EA7_1_RTF_ListTag(s, "<ul>\r\n", "</ul>", "<lb0>", "</lb0>");
243
 
246
 
Line 246... Line 249...
246
         // human users and so EAv7.1 converts < and > chars into a form such that they do not look like RTF tags.
249
         // human users and so EAv7.1 converts < and > chars into a form such that they do not look like RTF tags.
247
         // We have to convert EA's escaping mechanism back into ascii text chars otherwise the parser wont work.
250
         // We have to convert EA's escaping mechanism back into ascii text chars otherwise the parser wont work.
248
         // There may be issues to resolve with this parser if EAv7.1 users have used any of EA's RTF editing features
251
         // There may be issues to resolve with this parser if EAv7.1 users have used any of EA's RTF editing features
249
         // because if they do, the < and > chars there will not be escaped and the parser will find them and try to
252
         // because if they do, the < and > chars there will not be escaped and the parser will find them and try to
250
         // decode them. Most will probably not be decodable.
253
         // decode them. Most will probably not be decodable.
251
         s = s.Replace("&lt;","<");
-
 
252
         s = s.Replace("&gt;",">");
254
         s = TextualContent.HtmlDecode(s);
-
 
255
 
253
 
256
 
254
         // Begin to construct a range that will eventually encompass ALL of the text we will serialize during the execution
257
         // Begin to construct a range that will eventually encompass ALL of the text we will serialize during the execution
255
         // of this function. This is needed later only if the caller has specified a requirement style that needs to have 
258
         // of this function. This is needed later only if the caller has specified a requirement style that needs to have 
256
         // global strikethrough or italicising applied to (all of) the text
259
         // global strikethrough or italicising applied to (all of) the text
257
         object startLocation;
260
         object startLocation;
Line 319... Line 322...
319
 
322
 
320
            // look for the closing bracket of the tag
323
            // look for the closing bracket of the tag
321
            pos = s.IndexOf(">", pos+1);
324
            pos = s.IndexOf(">", pos+1);
322
            if (pos >= 0)
325
            if (pos >= 0)
323
            {
326
            {
-
 
327
               string sTag = s.Substring(pos_tagName, pos - pos_tagName);
-
 
328
 
-
 
329
               if (!isEnding)
-
 
330
               {
-
 
331
                   // check for font start tag with color attribute
-
 
332
                   Regex re = new Regex("font.*?color=\"#(?<color>[0-9A-F]*)\"",RegexOptions.IgnoreCase);
-
 
333
                   if (re.IsMatch(sTag))
-
 
334
                     sTag = "font";
-
 
335
               }
-
 
336
 
324
               // use hash table to identify the tag
337
               // use hash table to identify the tag
325
               found = styleDefs.Contains(s.Substring(pos_tagName, pos - pos_tagName));
338
               found = styleDefs.Contains(sTag);
326
            }
339
            }
327
            else
340
            else
328
            {
341
            {
329
               // Cannot find any '>' so we should just exit the loop
342
               // Cannot find any '>' so we should just exit the loop
330
               break;
343
               break;
Line 385... Line 398...
385
               }
398
               }
386
               else
399
               else
387
               {
400
               {
388
                  // If there is content prior to now that has not been consumed, tokenise it now
401
                  // If there is content prior to now that has not been consumed, tokenise it now
389
                  if ((pos_LeftBracket - pos_ContentStart) > 0)
402
                  if ((pos_LeftBracket - pos_ContentStart) > 0)
-
 
403
 
390
                  {
404
                  {
391
                     token.txt = s.Substring(pos_ContentStart, pos_LeftBracket - pos_ContentStart);
405
                     token.txt = s.Substring(pos_ContentStart, pos_LeftBracket - pos_ContentStart);
392
                     tokens.Add(token);
406
                     tokens.Add(token);
393
                  }
407
                  }
394
 
408
 
Line 403... Line 417...
403
                  else
417
                  else
404
                  {
418
                  {
405
                     // update the token variable with this tags atributes from the hash table lookup. This overwrites
419
                     // update the token variable with this tags atributes from the hash table lookup. This overwrites
406
                     // the default values assigned when parsing began, or when we resumed parsing after dealing with
420
                     // the default values assigned when parsing began, or when we resumed parsing after dealing with
407
                     // the previous token found.
421
                     // the previous token found.
-
 
422
 
408
                     token_type lookupToken = ((token_type)styleDefs[s.Substring(pos_tagName, pos_RightBracket-pos_tagName)]);
423
                     string df = s.Substring(pos_tagName, pos_RightBracket-pos_tagName);
-
 
424
 
-
 
425
                     // check for font tag with color attribute
-
 
426
                     int iFontColor = -1;
-
 
427
                     Regex re = new Regex("font.*?color=\"#(?<color>[0-9A-F]*)\"", RegexOptions.IgnoreCase);
-
 
428
                     if (re.IsMatch(df))
-
 
429
                     {
-
 
430
                         // get color attribute value
-
 
431
                         string sColor = re.Matches(df)[0].Groups["color"].Value;
-
 
432
                         iFontColor = Convert.ToInt32(sColor,16);
-
 
433
                         df = "font";
-
 
434
                     }
-
 
435
                      
-
 
436
                     token_type lookupToken = ((token_type)styleDefs[df]);
409
                     token.styleId   = lookupToken.styleId;
437
                     token.styleId   = lookupToken.styleId;
410
                     token.styleType = lookupToken.styleType;
438
                     token.styleType = lookupToken.styleType;
411
                     token.styleName = lookupToken.styleName;
439
                     token.styleName = lookupToken.styleName;
-
 
440
                     if (token.styleId == style_id_e.STYLE_ID_FONT_COLOR)
-
 
441
                         token.level = iFontColor;
-
 
442
                     else
412
                     token.level     = lookupToken.level;
443
                         token.level = lookupToken.level;
413
                     token.styleHandling = lookupToken.styleHandling;
444
                     token.styleHandling = lookupToken.styleHandling;
414
                     token.txt = null; // we dont know what the text content will be yet. This is obtained when we encounter the end tag
445
                     token.txt = null; // we dont know what the text content will be yet. This is obtained when we encounter the end tag
415
 
446
 
416
                     pos_ContentStart = pos_RightBracket + 1;
447
                     pos_ContentStart = pos_RightBracket + 1;
417
 
448
 
Line 580... Line 611...
580
                     last_list_level = 0;
611
                     last_list_level = 0;
581
                     break;
612
                     break;
582
 
613
 
583
                  case style_id_e.STYLE_ID_UNDERLINE:
614
                  case style_id_e.STYLE_ID_UNDERLINE:
584
                     pf.m_wr.Select();
615
                     pf.m_wr.Select();
585
                     createWordDoc.WordApp.Selection.Range.Underline = Word.WdUnderline.wdUnderlineSingle;
616
                     createWordDoc.WordApp.Selection.Range.Underline = WdUnderline.wdUnderlineSingle;
586
                     last_list_level = 0;
617
                     last_list_level = 0;
587
                     break;
618
                     break;
588
 
619
 
-
 
620
                   case style_id_e.STYLE_ID_FONT_COLOR:
-
 
621
                     pf.m_wr.Select();
-
 
622
                     createWordDoc.WordApp.Selection.Range.Font.Color = (WdColor) ReverseRGB((UInt32)pf.m_tk.level);
-
 
623
                     last_list_level = 0;
-
 
624
                    break;
-
 
625
 
589
                  default:
626
                  default:
590
                     // Handle bullets/lists
627
                     // Handle bullets/lists
591
                     if (pf.m_tk.styleId >= style_id_e.STYLE_ID_LIST_BULLET_0)
628
                     if (pf.m_tk.styleId >= style_id_e.STYLE_ID_LIST_BULLET_0)
592
                     {
629
                     {
593
                        style = pf.m_tk.styleName;
630
                        style = pf.m_tk.styleName;
Line 604... Line 641...
604
                           {
641
                           {
605
                              // To restart numbering, the only way to do it is to (re-)apply the list template to the 
642
                              // To restart numbering, the only way to do it is to (re-)apply the list template to the 
606
                              // selection with a "continue previous list" setting of false, and an "apply to"
643
                              // selection with a "continue previous list" setting of false, and an "apply to"
607
                              // setting of "whole list". 
644
                              // setting of "whole list". 
608
                              object continuePreviousList = false;
645
                              object continuePreviousList = false;
609
                              object applyTo = Word.WdListApplyTo.wdListApplyToWholeList;
646
                              object applyTo = WdListApplyTo.wdListApplyToWholeList;
610
                              object defListBehavour = Word.WdDefaultListBehavior.wdWord10ListBehavior;
647
                              object defListBehavour = WdDefaultListBehavior.wdWord10ListBehavior;
611
                              
648
                              
612
                              Word.ListTemplate lt = createWordDoc.WordApp.Selection.Range.ListFormat.ListTemplate;
649
                              ListTemplate lt = createWordDoc.WordApp.Selection.Range.ListFormat.ListTemplate;
613
 
650
 
614
                              createWordDoc.WordApp.Selection.Range.ListFormat.ApplyListTemplate(
651
                              createWordDoc.WordApp.Selection.Range.ListFormat.ApplyListTemplate(
615
                                 lt, ref continuePreviousList, ref applyTo, ref defListBehavour);
652
                                 lt, ref continuePreviousList, ref applyTo, ref defListBehavour);
616
                           }
653
                           }
617
                        }
654
                        }
Line 634... Line 671...
634
         if (callerStyle.Equals(EA_Constants.styleName_ReqPropBody))
671
         if (callerStyle.Equals(EA_Constants.styleName_ReqPropBody))
635
         {
672
         {
636
            // Complete construction of a range that will encompass ALL of the text we will serialize during the execution
673
            // Complete construction of a range that will encompass ALL of the text we will serialize during the execution
637
            // of this function
674
            // of this function
638
            endLocation = createWordDoc.WordDocument.Content.End;
675
            endLocation = createWordDoc.WordDocument.Content.End;
639
            Word.Range wr_total = createWordDoc.WordDocument.Range(ref startLocation, ref endLocation);
676
            Range wr_total = createWordDoc.WordDocument.Range(ref startLocation, ref endLocation);
640
            while (wr_total.Characters.Last.Text.Equals("\r") || wr_total.Characters.Last.Text.Equals("\n"))
677
            while (wr_total.Characters.Last.Text.Equals("\r") || wr_total.Characters.Last.Text.Equals("\n"))
641
               wr_total.End = wr_total.End - 1;  // don't format the \r\n char at the end - doing so causes wierd ms-word exceptions later on
678
               wr_total.End = wr_total.End - 1;  // don't format the \r\n char at the end - doing so causes wierd ms-word exceptions later on
642
 
679
 
643
            // italicise
680
            // italicise
644
            wr_total.Font.Italic = (int)MsoTriState.msoTrue;
681
            wr_total.Font.Italic = (int)MsoTriState.msoTrue;
Line 646... Line 683...
646
         else if (callerStyle.Equals(EA_Constants.styleName_ReqRejBody))
683
         else if (callerStyle.Equals(EA_Constants.styleName_ReqRejBody))
647
         {
684
         {
648
            // Complete construction of a range that will encompass ALL of the text we will serialize during the execution
685
            // Complete construction of a range that will encompass ALL of the text we will serialize during the execution
649
            // of this function
686
            // of this function
650
            endLocation = createWordDoc.WordDocument.Content.End;
687
            endLocation = createWordDoc.WordDocument.Content.End;
651
            Word.Range wr_total = createWordDoc.WordDocument.Range(ref startLocation, ref endLocation);
688
            Range wr_total = createWordDoc.WordDocument.Range(ref startLocation, ref endLocation);
652
            while (wr_total.Characters.Last.Text.Equals("\r") || wr_total.Characters.Last.Text.Equals("\n"))
689
            while (wr_total.Characters.Last.Text.Equals("\r") || wr_total.Characters.Last.Text.Equals("\n"))
653
               wr_total.End = wr_total.End - 1;  // don't format the \r\n char at the end - doing so causes wierd ms-word exceptions later on
690
               wr_total.End = wr_total.End - 1;  // don't format the \r\n char at the end - doing so causes wierd ms-word exceptions later on
654
 
691
 
655
            // strikethrough - use msoCTrue since msoTrue simply toggles strikethough attribute, or so it seems
692
            // strikethrough - use msoCTrue since msoTrue simply toggles strikethough attribute, or so it seems
656
            wr_total.Font.StrikeThrough = (int)MsoTriState.msoCTrue;
693
            wr_total.Font.StrikeThrough = (int)MsoTriState.msoCTrue;
657
         }
694
         }
658
 
695
 
659
         return true;
696
         return true;
660
      }
697
      }
661
 
698
 
662
 
-
 
-
 
699
      public static UInt32 ReverseRGB(UInt32 value)
663
 
700
      {
-
 
701
          UInt32 i = (value & 0x000000FFU) << 16 | (value & 0x0000FF00U) |
-
 
702
                 (value & 0x00FF0000U) >> 16;
-
 
703
          return i;
664
 
704
      }
665
 
705
 
666
   }
706
   }
667
}
707
}