Subversion Repositories DevTools

Rev

Rev 2104 | Rev 2110 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2094 ghuddy 1
using System;
2
using System.Collections;
3
using Word;
4
 
5
namespace EA_DocGen
6
{
7
	/// <summary>
8
	/// Summary description for TextualContent.
9
	/// </summary>
2106 ghuddy 10
   public class TextualContent
11
   {
12
      private static char[] trim_newlines;
2094 ghuddy 13
 
2106 ghuddy 14
      public static void initialise()
2094 ghuddy 15
      {
2106 ghuddy 16
         string s_trim_newlines = "\r\n";
17
         trim_newlines = s_trim_newlines.ToCharArray();
2094 ghuddy 18
      }
19
 
2106 ghuddy 20
      public static Word.Range appendDescription(string wordText)
2094 ghuddy 21
      {
2106 ghuddy 22
         return appendDescription(wordText, false);
2098 ghuddy 23
      }
24
 
2106 ghuddy 25
      public static Word.Range appendDescription(string wordText, bool continuation)
2098 ghuddy 26
      {
2106 ghuddy 27
         return appendDescription(wordText, EA_Constants.styleName_Body1, continuation);
2098 ghuddy 28
      }
29
 
2106 ghuddy 30
      public static Word.Range appendDescription(string wordText, string styleName, bool continuation)
2098 ghuddy 31
      {
2094 ghuddy 32
         Word.Range wr = null;
33
 
34
         if (wordText != null && wordText.Length > 0)
2106 ghuddy 35
         {
2098 ghuddy 36
            wr = appendAndSelectText(wordText, styleName, continuation);
2106 ghuddy 37
         }
38
         else if (!EA_DocGenOptions.opt_SuppressElementDescriptionMissingWarnings)
2094 ghuddy 39
         {
2098 ghuddy 40
            wr = appendAndSelectText("Description missing!", styleName, continuation);
41
            // For some wierd reason, if continuing on same paragraph, we have to decrement the range start by 1
42
            // otherwise the D of Description, does not get the red color or italic style
43
            if (continuation)
44
               wr.Start--;
2094 ghuddy 45
            wr.Font.Italic = 1;
46
            wr.Font.Color = Word.WdColor.wdColorRed;
47
         }
48
         return wr;
49
      }
50
 
2098 ghuddy 51
 
2094 ghuddy 52
 
53
      /// <summary>
54
      /// Appends a specified text string to the word document, selects the new text, and applies
55
      /// the specified style formatting to it.
56
      /// </summary>
57
      /// <param name="wordText"></param>
58
      /// <param name="styleText"></param>
59
      /// <param name="continuation"></param>
2106 ghuddy 60
      public static Word.Range appendAndSelectText(string wordText, string styleText) 
2094 ghuddy 61
      { 
62
         return appendAndSelectText(wordText, styleText, false );
63
      }
64
 
65
 
2106 ghuddy 66
      public static Word.Range appendAndSelectText(string wordText, string styleText, bool continuation )
2094 ghuddy 67
      {
68
         if (wordText.Length > 0)
69
         {
70
            Word.Range WordRange = null;
71
            object startLocation;
72
            object endLocation;
73
 
74
            object style = styleText;
75
            int i;
76
            startLocation = 0;
2106 ghuddy 77
            endLocation = i = createWordDoc.WordDocument.Content.End;
2094 ghuddy 78
 
2106 ghuddy 79
            WordRange = createWordDoc.WordDocument.Range(ref startLocation, ref endLocation);
2094 ghuddy 80
 
81
            if (!continuation)
82
               WordRange.InsertAfter( "\n" );
83
 
84
            WordRange.InsertAfter( wordText );
85
 
86
            // Make a range out of the pasted text
87
            startLocation = i;
2106 ghuddy 88
            endLocation = createWordDoc.WordDocument.Content.End;
89
            WordRange = createWordDoc.WordDocument.Range(ref startLocation, ref endLocation);
2094 ghuddy 90
 
91
            // and set the pasted text style
92
            WordRange.set_Style(ref style);
93
            return WordRange;
94
         }
95
         return null;
96
      }
97
 
98
 
99
      /// <summary>
100
      /// Appends a specified text string to the word document, selects the new text, and applies
101
      /// a heading level style to it. 
102
      /// </summary>
103
      /// <param name="wordText"></param>
104
      /// <param name="level"></param>
2106 ghuddy 105
      public static void appendAndSelectHeadingText(string wordText, int level)
2094 ghuddy 106
      {
2104 ghuddy 107
         // A caller is requesting a new heading level so pass the level to the tracking
108
         // object so that we can predict exactly what the level numbering should be for
109
         // diagnostics and fake heading generation (see below in the switch statement).
2106 ghuddy 110
         DocSectionTracking.trackDocSection(level);
2104 ghuddy 111
 
2094 ghuddy 112
         // Convert level to heading style
113
         string styleText;
114
         switch(level)
115
         {
116
            case 1: styleText = EA_Constants.styleName_Heading1; break;
117
            case 2: styleText = EA_Constants.styleName_Heading2; break;
118
            case 3: styleText = EA_Constants.styleName_Heading3; break;
119
            case 4: styleText = EA_Constants.styleName_Heading4; break;
120
            case 5: styleText = EA_Constants.styleName_Heading5; break;
121
            case 6: styleText = EA_Constants.styleName_Heading6; break;
122
            case 7: styleText = EA_Constants.styleName_Heading7; break;
123
            case 8: styleText = EA_Constants.styleName_Heading8; break;
124
            case 9: styleText = EA_Constants.styleName_Heading9; break;
2104 ghuddy 125
 
126
            default: 
127
               // MS-Word cannot produce headings above level 9 and so we have to 
128
               // fake a heading by constructing it from our document section tracking data.
129
               styleText = EA_Constants.styleName_Heading10OrAbove;
2106 ghuddy 130
               wordText = DocSectionTracking.formHeadingString(wordText);
2104 ghuddy 131
               break;
2094 ghuddy 132
         }
133
         // append the text as a heading
134
         appendAndSelectText(wordText, styleText);
135
      }
136
 
2106 ghuddy 137
      public static string trimTrailingReturns(string s)
2094 ghuddy 138
      {
2106 ghuddy 139
          return s.TrimEnd(trim_newlines);
140
      }
141
 
142
 
143
 
144
      public static string testSuiteName(EA.Element theElement)
145
      {
2094 ghuddy 146
         return "Test Suite - " + theElement.Name;
147
      }
148
 
149
 
2106 ghuddy 150
      public static void appendUnitTestSuite(EA.Element theElement, int recurse_level, ref ArrayList classList)
2094 ghuddy 151
      {
2104 ghuddy 152
         if (theElement.StereotypeEx.IndexOf("API") < 0)
153
         {
154
            // element does not have an API stereotype, so is not a class for which unit tests are expected.
155
            return;
156
         }
157
 
2094 ghuddy 158
         // only feed non-private classes through to the unit test section of a document
159
         // NOTE: May need an override option for this filter.
160
         if (!theElement.Visibility.StartsWith("Private"))
161
         {
162
            appendAndSelectHeadingText(testSuiteName(theElement), recurse_level+1);
163
 
164
            if (theElement.Tests.Count > 0)
165
            {
166
               classList.Add( theElement.ElementID );
167
 
168
               foreach(EA.Test theTest in theElement.Tests)
169
               {
170
                  appendAndSelectHeadingText("Test Case - " + theTest.Name, recurse_level+2);
171
 
172
                  appendAndSelectHeadingText("Description", recurse_level+3);
173
                  appendAndSelectText(theTest.Notes, EA_Constants.styleName_Body1);
174
 
175
                  appendAndSelectHeadingText("Inputs", recurse_level+3);
176
                  appendAndSelectText(theTest.Input, EA_Constants.styleName_Body1);
177
 
178
                  appendAndSelectHeadingText("Expected Results", recurse_level+3);
179
                  appendAndSelectText(theTest.AcceptanceCriteria, EA_Constants.styleName_Body1);
180
               }
181
            }
182
            else
183
            {
184
               Word.Range wr = appendAndSelectText("Test Cases missing!", EA_Constants.styleName_Body1);
185
               wr.Font.Italic = 1;
186
               wr.Font.Color = Word.WdColor.wdColorRed;
187
            }
188
         }
189
      }
190
 
191
 
2106 ghuddy 192
      public static void appendUnitTestSuite(EA.Package thePackage, int recurse_level, ref ArrayList classList)
2094 ghuddy 193
      {
194
         EA_ElementSorter elementSorter = new EA_ElementSorter(thePackage);
195
         EA.Element theElement = null;
196
         int theElementsRelativeLevel = 0;
197
         if (true == elementSorter.getFirst(ref theElement, ref theElementsRelativeLevel))
198
         {
199
            do
200
            {
201
               if (theElement.Type.StartsWith("Class"))
202
               {
2106 ghuddy 203
                  appendUnitTestSuite(theElement, recurse_level, ref classList);
2094 ghuddy 204
               }
205
 
206
            } while (true == elementSorter.getNext(ref theElement, ref theElementsRelativeLevel));
207
         }
208
 
209
         // Scan through the packages within this package.
210
         foreach(EA.Package lowerLevelPackage in thePackage.Packages)
211
         {
212
            // recurse
2106 ghuddy 213
            appendUnitTestSuite(lowerLevelPackage, recurse_level, ref classList);
2094 ghuddy 214
         }
215
      }
216
 
217
 
2106 ghuddy 218
      public static void SelectInsertionPointAtEndOfDocument()
2094 ghuddy 219
      {
220
         object unit; 
221
         object extend;
222
 
223
         unit = Word.WdUnits.wdStory; 
224
         extend = Word.WdMovementType.wdMove;
2106 ghuddy 225
         createWordDoc.WordApp.Selection.EndKey(ref unit, ref extend);
2094 ghuddy 226
      }
227
 
228
 
229
      /// <summary>
230
      /// Generates the text for requirements.  This uses custom styles to format the text 
231
      /// rather than formatting it in code.
232
      /// </summary>
2106 ghuddy 233
      public static bool generateRequirementText( EA.Element theElement )
2094 ghuddy 234
      {
235
         if ( theElement.Type.StartsWith("Requirement"))
236
         {
2104 ghuddy 237
            string reqID = "";
238
            string reqShortDesc = "";
239
            string reqHeadingStyle ="";
240
            string reqParaStyle = "";
2106 ghuddy 241
 
2104 ghuddy 242
 
243
            // Set the style depending on the status
244
            switch ( theElement.Status )
2094 ghuddy 245
            {
2104 ghuddy 246
               case "Proposed":
247
                  reqHeadingStyle = EA_Constants.styleName_ReqPropHdr;
248
                  reqParaStyle    = EA_Constants.styleName_ReqPropBody;
249
                  break;
2094 ghuddy 250
 
2104 ghuddy 251
               case "Rejected":
252
                  reqHeadingStyle = EA_Constants.styleName_ReqRejHdr;
253
                  reqParaStyle    = EA_Constants.styleName_ReqRejBody;
254
                  break;
2094 ghuddy 255
 
2104 ghuddy 256
               case "Approved":
257
                  reqHeadingStyle = EA_Constants.styleName_ReqAppHdr;
258
                  reqParaStyle    = EA_Constants.styleName_ReqAppBody;
259
                  break;
2094 ghuddy 260
 
2104 ghuddy 261
               default:
262
                  reqHeadingStyle = EA_Constants.styleName_ReqAppHdr;
263
                  reqParaStyle    = EA_Constants.styleName_ReqAppBody;
264
                  break;
265
            }
2094 ghuddy 266
 
2104 ghuddy 267
            // Pull out the ID from the name
268
            int pos = theElement.Name.IndexOf( " ", 0, theElement.Name.Length );
2106 ghuddy 269
            if (pos > 0)
270
               reqID = theElement.Name.Substring( 0, pos );
2094 ghuddy 271
 
2106 ghuddy 272
            // Count '.' chars in the ID
273
            int numDots = 0;
274
            foreach (char c in reqID)
275
            {
276
               if (c == '.')
277
                  numDots++;
278
            }
279
 
280
            // Calculate what the left/hanging indent should be based on the standard 2.5 cm plus a 
281
            // factor derived from the number of dots in the ID
282
            float indent_cm = (float)(2.5 + (0.5 * numDots));
283
 
2104 ghuddy 284
            // Pull out the short description from the rest of the name
285
            reqShortDesc = theElement.Name.Substring( pos, theElement.Name.Length-pos );
286
            reqShortDesc = reqShortDesc.Trim();
2094 ghuddy 287
 
2104 ghuddy 288
            // Add the text
2106 ghuddy 289
            Word.Range wr_id = appendAndSelectText( reqID + '\t', reqHeadingStyle );
2094 ghuddy 290
 
2106 ghuddy 291
            Word.Range wr_desc = appendAndSelectText( reqShortDesc, reqHeadingStyle, true );
2094 ghuddy 292
 
2106 ghuddy 293
            //Bold the short description
294
            wr_desc.Start = wr_desc.Start-1;
295
            wr_desc.Font.Bold = 1;
296
 
297
            // Indent according to the number of dots in the tag
298
            if (numDots > 0)
299
            {
300
               wr_desc.ParagraphFormat.LeftIndent      =  createWordDoc.WordApp.CentimetersToPoints(indent_cm);
301
               wr_desc.ParagraphFormat.FirstLineIndent = -createWordDoc.WordApp.CentimetersToPoints(indent_cm);
302
            }
303
 
304
            // Add requirement notes/body, if there is any
305
            if (theElement.Notes != null && theElement.Notes.Length > 0)
306
            {
307
               Word.Range wr_body = appendAndSelectText( theElement.Notes, reqParaStyle );
308
 
309
               // indent according to the number of dots in the tag
310
               if (numDots > 0)
311
               {
312
                  wr_body.ParagraphFormat.LeftIndent = createWordDoc.WordApp.CentimetersToPoints( indent_cm );
313
               }
314
            }
315
            else
316
            {
317
               // If the requirement has no body text, its SpaceAfter will be 3, so we adjust it here to 6
318
               // just like what the body would have, if it were present.
319
               wr_desc.ParagraphFormat.SpaceAfter = 6;
320
            }
321
 
2104 ghuddy 322
            return true;
323
 
2094 ghuddy 324
         }
325
 
326
         return false;
327
      }
328
 
329
 
330
 
2106 ghuddy 331
   }
2094 ghuddy 332
}