Rev 2104 | Rev 2110 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed
using System;using System.Collections;using Word;namespace EA_DocGen{/// <summary>/// Summary description for TextualContent./// </summary>public class TextualContent{private static char[] trim_newlines;public static void initialise(){string s_trim_newlines = "\r\n";trim_newlines = s_trim_newlines.ToCharArray();}public static Word.Range appendDescription(string wordText){return appendDescription(wordText, false);}public static Word.Range appendDescription(string wordText, bool continuation){return appendDescription(wordText, EA_Constants.styleName_Body1, continuation);}public static Word.Range appendDescription(string wordText, string styleName, bool continuation){Word.Range wr = null;if (wordText != null && wordText.Length > 0){wr = appendAndSelectText(wordText, styleName, continuation);}else if (!EA_DocGenOptions.opt_SuppressElementDescriptionMissingWarnings){wr = appendAndSelectText("Description missing!", styleName, continuation);// For some wierd reason, if continuing on same paragraph, we have to decrement the range start by 1// otherwise the D of Description, does not get the red color or italic styleif (continuation)wr.Start--;wr.Font.Italic = 1;wr.Font.Color = Word.WdColor.wdColorRed;}return wr;}/// <summary>/// Appends a specified text string to the word document, selects the new text, and applies/// the specified style formatting to it./// </summary>/// <param name="wordText"></param>/// <param name="styleText"></param>/// <param name="continuation"></param>public static Word.Range appendAndSelectText(string wordText, string styleText){return appendAndSelectText(wordText, styleText, false );}public static Word.Range appendAndSelectText(string wordText, string styleText, bool continuation ){if (wordText.Length > 0){Word.Range WordRange = null;object startLocation;object endLocation;object style = styleText;int i;startLocation = 0;endLocation = i = createWordDoc.WordDocument.Content.End;WordRange = createWordDoc.WordDocument.Range(ref startLocation, ref endLocation);if (!continuation)WordRange.InsertAfter( "\n" );WordRange.InsertAfter( wordText );// Make a range out of the pasted textstartLocation = i;endLocation = createWordDoc.WordDocument.Content.End;WordRange = createWordDoc.WordDocument.Range(ref startLocation, ref endLocation);// and set the pasted text styleWordRange.set_Style(ref style);return WordRange;}return null;}/// <summary>/// Appends a specified text string to the word document, selects the new text, and applies/// a heading level style to it./// </summary>/// <param name="wordText"></param>/// <param name="level"></param>public static void appendAndSelectHeadingText(string wordText, int level){// A caller is requesting a new heading level so pass the level to the tracking// object so that we can predict exactly what the level numbering should be for// diagnostics and fake heading generation (see below in the switch statement).DocSectionTracking.trackDocSection(level);// Convert level to heading stylestring styleText;switch(level){case 1: styleText = EA_Constants.styleName_Heading1; break;case 2: styleText = EA_Constants.styleName_Heading2; break;case 3: styleText = EA_Constants.styleName_Heading3; break;case 4: styleText = EA_Constants.styleName_Heading4; break;case 5: styleText = EA_Constants.styleName_Heading5; break;case 6: styleText = EA_Constants.styleName_Heading6; break;case 7: styleText = EA_Constants.styleName_Heading7; break;case 8: styleText = EA_Constants.styleName_Heading8; break;case 9: styleText = EA_Constants.styleName_Heading9; break;default:// MS-Word cannot produce headings above level 9 and so we have to// fake a heading by constructing it from our document section tracking data.styleText = EA_Constants.styleName_Heading10OrAbove;wordText = DocSectionTracking.formHeadingString(wordText);break;}// append the text as a headingappendAndSelectText(wordText, styleText);}public static string trimTrailingReturns(string s){return s.TrimEnd(trim_newlines);}public static string testSuiteName(EA.Element theElement){return "Test Suite - " + theElement.Name;}public static void appendUnitTestSuite(EA.Element theElement, int recurse_level, ref ArrayList classList){if (theElement.StereotypeEx.IndexOf("API") < 0){// element does not have an API stereotype, so is not a class for which unit tests are expected.return;}// only feed non-private classes through to the unit test section of a document// NOTE: May need an override option for this filter.if (!theElement.Visibility.StartsWith("Private")){appendAndSelectHeadingText(testSuiteName(theElement), recurse_level+1);if (theElement.Tests.Count > 0){classList.Add( theElement.ElementID );foreach(EA.Test theTest in theElement.Tests){appendAndSelectHeadingText("Test Case - " + theTest.Name, recurse_level+2);appendAndSelectHeadingText("Description", recurse_level+3);appendAndSelectText(theTest.Notes, EA_Constants.styleName_Body1);appendAndSelectHeadingText("Inputs", recurse_level+3);appendAndSelectText(theTest.Input, EA_Constants.styleName_Body1);appendAndSelectHeadingText("Expected Results", recurse_level+3);appendAndSelectText(theTest.AcceptanceCriteria, EA_Constants.styleName_Body1);}}else{Word.Range wr = appendAndSelectText("Test Cases missing!", EA_Constants.styleName_Body1);wr.Font.Italic = 1;wr.Font.Color = Word.WdColor.wdColorRed;}}}public static void appendUnitTestSuite(EA.Package thePackage, int recurse_level, ref ArrayList classList){EA_ElementSorter elementSorter = new EA_ElementSorter(thePackage);EA.Element theElement = null;int theElementsRelativeLevel = 0;if (true == elementSorter.getFirst(ref theElement, ref theElementsRelativeLevel)){do{if (theElement.Type.StartsWith("Class")){appendUnitTestSuite(theElement, recurse_level, ref classList);}} while (true == elementSorter.getNext(ref theElement, ref theElementsRelativeLevel));}// Scan through the packages within this package.foreach(EA.Package lowerLevelPackage in thePackage.Packages){// recurseappendUnitTestSuite(lowerLevelPackage, recurse_level, ref classList);}}public static void SelectInsertionPointAtEndOfDocument(){object unit;object extend;unit = Word.WdUnits.wdStory;extend = Word.WdMovementType.wdMove;createWordDoc.WordApp.Selection.EndKey(ref unit, ref extend);}/// <summary>/// Generates the text for requirements. This uses custom styles to format the text/// rather than formatting it in code./// </summary>public static bool generateRequirementText( EA.Element theElement ){if ( theElement.Type.StartsWith("Requirement")){string reqID = "";string reqShortDesc = "";string reqHeadingStyle ="";string reqParaStyle = "";// Set the style depending on the statusswitch ( theElement.Status ){case "Proposed":reqHeadingStyle = EA_Constants.styleName_ReqPropHdr;reqParaStyle = EA_Constants.styleName_ReqPropBody;break;case "Rejected":reqHeadingStyle = EA_Constants.styleName_ReqRejHdr;reqParaStyle = EA_Constants.styleName_ReqRejBody;break;case "Approved":reqHeadingStyle = EA_Constants.styleName_ReqAppHdr;reqParaStyle = EA_Constants.styleName_ReqAppBody;break;default:reqHeadingStyle = EA_Constants.styleName_ReqAppHdr;reqParaStyle = EA_Constants.styleName_ReqAppBody;break;}// Pull out the ID from the nameint pos = theElement.Name.IndexOf( " ", 0, theElement.Name.Length );if (pos > 0)reqID = theElement.Name.Substring( 0, pos );// Count '.' chars in the IDint numDots = 0;foreach (char c in reqID){if (c == '.')numDots++;}// Calculate what the left/hanging indent should be based on the standard 2.5 cm plus a// factor derived from the number of dots in the IDfloat indent_cm = (float)(2.5 + (0.5 * numDots));// Pull out the short description from the rest of the namereqShortDesc = theElement.Name.Substring( pos, theElement.Name.Length-pos );reqShortDesc = reqShortDesc.Trim();// Add the textWord.Range wr_id = appendAndSelectText( reqID + '\t', reqHeadingStyle );Word.Range wr_desc = appendAndSelectText( reqShortDesc, reqHeadingStyle, true );//Bold the short descriptionwr_desc.Start = wr_desc.Start-1;wr_desc.Font.Bold = 1;// Indent according to the number of dots in the tagif (numDots > 0){wr_desc.ParagraphFormat.LeftIndent = createWordDoc.WordApp.CentimetersToPoints(indent_cm);wr_desc.ParagraphFormat.FirstLineIndent = -createWordDoc.WordApp.CentimetersToPoints(indent_cm);}// Add requirement notes/body, if there is anyif (theElement.Notes != null && theElement.Notes.Length > 0){Word.Range wr_body = appendAndSelectText( theElement.Notes, reqParaStyle );// indent according to the number of dots in the tagif (numDots > 0){wr_body.ParagraphFormat.LeftIndent = createWordDoc.WordApp.CentimetersToPoints( indent_cm );}}else{// If the requirement has no body text, its SpaceAfter will be 3, so we adjust it here to 6// just like what the body would have, if it were present.wr_desc.ParagraphFormat.SpaceAfter = 6;}return true;}return false;}}}