Subversion Repositories DevTools

Rev

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

Rev Author Line No. Line
2088 ghuddy 1
using System;
2
using System.Drawing;
3
using System.Collections;
2094 ghuddy 4
using System.Text;
2088 ghuddy 5
using System.ComponentModel;
6
using System.Windows.Forms;
7
using Word;
2092 ghuddy 8
using Microsoft.Office.Core;
2106 ghuddy 9
using System.Threading;
2088 ghuddy 10
 
11
namespace EA_DocGen
12
{
13
 
14
 
15
   /// <summary>
16
   /// Summary description for createWordDoc.
17
   /// </summary>
18
   public class createWordDoc : System.Windows.Forms.Form
19
   {
20
      // Enterprise Architect Model related data
21
      private EA.Package EA_ParentPackage = null;
22
      private EA.Project EA_Project;
2094 ghuddy 23
 
2106 ghuddy 24
      private Thread creationThread = null;           // Document generation thread
25
      public static bool abortCreationThread;         // Used to abort the document generation thread
26
      private bool mustClose = false;                 // Used to signal closure required for doc generation dialog
27
      private bool docGenCompletedNormally = false;   // Used to indicate if success message is made just prior to thread exit
2088 ghuddy 28
 
29
      private bool oneShot_skipRootPackage = false;
2094 ghuddy 30
      private bool oneShot_skipRootElementHeading = false;
2088 ghuddy 31
 
2104 ghuddy 32
      private int processingLink = 0;
33
 
34
      private ArrayList processedElements = null;
35
 
2094 ghuddy 36
      // This data is designed to support unit test traceability. As such, it is only of real use
37
      // when making s/w design documents. It allows all non-private classes to be collected into
38
      // a list in order to generate a design-to-unit-test traceability table.
2104 ghuddy 39
      private ArrayList classesNeedingUnitTests = null;
2094 ghuddy 40
      private ArrayList classesWithUnitTests = null;
41
      private Word.Table utTraceabilityTable = null;
42
 
2088 ghuddy 43
      // MS-Office Word related data
2106 ghuddy 44
      public static Word.Application WordApp = null;
45
      public static Word.Document WordDocument = null;
2094 ghuddy 46
 
2106 ghuddy 47
      // Form data
48
      public System.Windows.Forms.TextBox textBox_template;
2088 ghuddy 49
      private System.Windows.Forms.Button button_browse_template;
2106 ghuddy 50
      public System.Windows.Forms.TextBox textBox_output_file;
2088 ghuddy 51
      private System.Windows.Forms.Button button_browse_output_file;
52
      private System.Windows.Forms.Button button_cancel;
53
      private System.Windows.Forms.Button button_generate;
54
      private System.Windows.Forms.Button button_view_output;
55
      private System.Windows.Forms.Label label1;
56
      private System.Windows.Forms.Label label2;
57
      private System.Windows.Forms.CheckBox checkBox_WordVisibility;
2106 ghuddy 58
      private System.Windows.Forms.CheckBox checkBox_keep_on_top;
59
 
2088 ghuddy 60
      /// <summary>
61
      /// Required designer variable.
62
      /// </summary>
63
      private System.ComponentModel.Container components = null;
64
 
2106 ghuddy 65
      public createWordDoc(EA.Package theParentPackage)
2088 ghuddy 66
      {
67
         //
68
         // Required for Windows Form Designer support
69
         //
70
         InitializeComponent();
71
 
72
         EA_ParentPackage = theParentPackage;
2106 ghuddy 73
         EA_Project       = Main.EA_Repository.GetProjectInterface();
2088 ghuddy 74
 
2106 ghuddy 75
         DocSectionTracking.initialise();
76
         TabularContent.initialise();
77
         TextualContent.initialise();
78
         StyleContent.initialise();
2126 ghuddy 79
         TextParser.initialise();
2088 ghuddy 80
 
81
         WordApp = new Word.Application();
82
      }
83
 
2094 ghuddy 84
 
2088 ghuddy 85
      /// <summary>
86
      /// Clean up any resources being used.
87
      /// </summary>
88
      protected override void Dispose( bool disposing )
89
      {
90
         if( disposing )
91
         {
92
            if(components != null)
93
            {
94
               components.Dispose();
95
            }
96
         }
97
         base.Dispose( disposing );
98
      }
99
 
100
 
101
 
102
 
103
      #region Windows Form Designer generated code
104
      /// <summary>
105
      /// Required method for Designer support - do not modify
106
      /// the contents of this method with the code editor.
107
      /// </summary>
108
      private void InitializeComponent()
109
      {
110
         this.textBox_template = new System.Windows.Forms.TextBox();
111
         this.button_browse_template = new System.Windows.Forms.Button();
112
         this.textBox_output_file = new System.Windows.Forms.TextBox();
113
         this.button_browse_output_file = new System.Windows.Forms.Button();
114
         this.button_cancel = new System.Windows.Forms.Button();
115
         this.button_generate = new System.Windows.Forms.Button();
116
         this.button_view_output = new System.Windows.Forms.Button();
117
         this.label1 = new System.Windows.Forms.Label();
118
         this.label2 = new System.Windows.Forms.Label();
119
         this.checkBox_WordVisibility = new System.Windows.Forms.CheckBox();
2106 ghuddy 120
         this.checkBox_keep_on_top = new System.Windows.Forms.CheckBox();
2088 ghuddy 121
         this.SuspendLayout();
122
         // 
123
         // textBox_template
124
         // 
2106 ghuddy 125
         this.textBox_template.Location = new System.Drawing.Point(8, 32);
2088 ghuddy 126
         this.textBox_template.Name = "textBox_template";
2106 ghuddy 127
         this.textBox_template.Size = new System.Drawing.Size(696, 22);
2088 ghuddy 128
         this.textBox_template.TabIndex = 0;
129
         this.textBox_template.Text = "";
130
         this.textBox_template.TextChanged += new System.EventHandler(this.textBox_template_TextChanged);
131
         // 
132
         // button_browse_template
133
         // 
2106 ghuddy 134
         this.button_browse_template.Location = new System.Drawing.Point(712, 32);
2088 ghuddy 135
         this.button_browse_template.Name = "button_browse_template";
2106 ghuddy 136
         this.button_browse_template.Size = new System.Drawing.Size(64, 23);
137
         this.button_browse_template.TabIndex = 4;
2088 ghuddy 138
         this.button_browse_template.Text = "Browse";
139
         this.button_browse_template.Click += new System.EventHandler(this.button_browse_template_Click);
140
         // 
141
         // textBox_output_file
142
         // 
2106 ghuddy 143
         this.textBox_output_file.Location = new System.Drawing.Point(8, 96);
2088 ghuddy 144
         this.textBox_output_file.Name = "textBox_output_file";
2106 ghuddy 145
         this.textBox_output_file.Size = new System.Drawing.Size(696, 22);
146
         this.textBox_output_file.TabIndex = 1;
2088 ghuddy 147
         this.textBox_output_file.Text = "";
148
         this.textBox_output_file.TextChanged += new System.EventHandler(this.textBox_output_file_TextChanged);
149
         // 
150
         // button_browse_output_file
151
         // 
2106 ghuddy 152
         this.button_browse_output_file.Location = new System.Drawing.Point(712, 96);
2088 ghuddy 153
         this.button_browse_output_file.Name = "button_browse_output_file";
2106 ghuddy 154
         this.button_browse_output_file.Size = new System.Drawing.Size(64, 24);
155
         this.button_browse_output_file.TabIndex = 5;
2088 ghuddy 156
         this.button_browse_output_file.Text = "Browse";
157
         this.button_browse_output_file.Click += new System.EventHandler(this.button_browse_output_file_Click);
158
         // 
159
         // button_cancel
160
         // 
2106 ghuddy 161
         this.button_cancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
162
         this.button_cancel.Location = new System.Drawing.Point(648, 152);
2088 ghuddy 163
         this.button_cancel.Name = "button_cancel";
2106 ghuddy 164
         this.button_cancel.Size = new System.Drawing.Size(128, 32);
165
         this.button_cancel.TabIndex = 3;
166
         this.button_cancel.Text = "Close / Abort";
2088 ghuddy 167
         this.button_cancel.Click += new System.EventHandler(this.button_cancel_Click);
168
         // 
169
         // button_generate
170
         // 
2106 ghuddy 171
         this.button_generate.Location = new System.Drawing.Point(496, 152);
2088 ghuddy 172
         this.button_generate.Name = "button_generate";
2106 ghuddy 173
         this.button_generate.Size = new System.Drawing.Size(128, 32);
174
         this.button_generate.TabIndex = 2;
2088 ghuddy 175
         this.button_generate.Text = "Generate";
176
         this.button_generate.Click += new System.EventHandler(this.button_generate_Click);
177
         // 
178
         // button_view_output
179
         // 
2098 ghuddy 180
         this.button_view_output.Enabled = false;
2106 ghuddy 181
         this.button_view_output.Location = new System.Drawing.Point(336, 152);
2088 ghuddy 182
         this.button_view_output.Name = "button_view_output";
2106 ghuddy 183
         this.button_view_output.Size = new System.Drawing.Size(128, 32);
2088 ghuddy 184
         this.button_view_output.TabIndex = 6;
185
         this.button_view_output.Text = "View Output";
186
         this.button_view_output.Click += new System.EventHandler(this.button_view_output_Click);
187
         // 
188
         // label1
189
         // 
2106 ghuddy 190
         this.label1.Location = new System.Drawing.Point(8, 8);
2088 ghuddy 191
         this.label1.Name = "label1";
192
         this.label1.Size = new System.Drawing.Size(224, 23);
193
         this.label1.TabIndex = 7;
194
         this.label1.Text = "Input Template or Document Name";
195
         // 
196
         // label2
197
         // 
2106 ghuddy 198
         this.label2.Location = new System.Drawing.Point(8, 72);
2088 ghuddy 199
         this.label2.Name = "label2";
200
         this.label2.Size = new System.Drawing.Size(280, 23);
201
         this.label2.TabIndex = 8;
202
         this.label2.Text = "Output Document Name";
203
         // 
204
         // checkBox_WordVisibility
205
         // 
2122 ghuddy 206
         this.checkBox_WordVisibility.Checked = true;
207
         this.checkBox_WordVisibility.CheckState = System.Windows.Forms.CheckState.Checked;
2106 ghuddy 208
         this.checkBox_WordVisibility.Location = new System.Drawing.Point(8, 168);
2088 ghuddy 209
         this.checkBox_WordVisibility.Name = "checkBox_WordVisibility";
210
         this.checkBox_WordVisibility.Size = new System.Drawing.Size(256, 24);
2106 ghuddy 211
         this.checkBox_WordVisibility.TabIndex = 7;
2088 ghuddy 212
         this.checkBox_WordVisibility.Text = "Show MS-WORD During Construction";
213
         // 
2106 ghuddy 214
         // checkBox_keep_on_top
215
         // 
216
         this.checkBox_keep_on_top.Checked = true;
217
         this.checkBox_keep_on_top.CheckState = System.Windows.Forms.CheckState.Checked;
218
         this.checkBox_keep_on_top.Location = new System.Drawing.Point(8, 136);
219
         this.checkBox_keep_on_top.Name = "checkBox_keep_on_top";
220
         this.checkBox_keep_on_top.Size = new System.Drawing.Size(224, 24);
221
         this.checkBox_keep_on_top.TabIndex = 9;
222
         this.checkBox_keep_on_top.Text = "Keep dialog on top";
223
         this.checkBox_keep_on_top.CheckedChanged += new System.EventHandler(this.checkBox_keep_on_top_CheckedChanged);
224
         // 
2088 ghuddy 225
         // createWordDoc
226
         // 
2106 ghuddy 227
         this.AcceptButton = this.button_generate;
2088 ghuddy 228
         this.AutoScaleBaseSize = new System.Drawing.Size(6, 15);
2106 ghuddy 229
         this.CancelButton = this.button_cancel;
230
         this.ClientSize = new System.Drawing.Size(784, 202);
231
         this.Controls.Add(this.checkBox_keep_on_top);
2088 ghuddy 232
         this.Controls.Add(this.textBox_output_file);
233
         this.Controls.Add(this.textBox_template);
2122 ghuddy 234
         this.Controls.Add(this.checkBox_WordVisibility);
2088 ghuddy 235
         this.Controls.Add(this.label2);
236
         this.Controls.Add(this.label1);
237
         this.Controls.Add(this.button_view_output);
238
         this.Controls.Add(this.button_generate);
239
         this.Controls.Add(this.button_cancel);
240
         this.Controls.Add(this.button_browse_output_file);
241
         this.Controls.Add(this.button_browse_template);
2106 ghuddy 242
         this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
2088 ghuddy 243
         this.Name = "createWordDoc";
2106 ghuddy 244
         this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide;
245
         this.Text = "Generate Document From Document Model";
246
         this.TopMost = true;
2088 ghuddy 247
         this.Closing += new System.ComponentModel.CancelEventHandler(this.createWordDoc_Closing);
248
         this.ResumeLayout(false);
249
 
250
      }
251
      #endregion
252
 
253
 
254
      #region Message handlers
255
      private void button_view_output_Click(object sender, System.EventArgs e)
256
      {
257
         if (WordApp != null)
258
         {
259
            WordApp.Visible = true;
260
         }
2094 ghuddy 261
         button_view_output.Enabled = false;
2088 ghuddy 262
      }
263
 
264
 
265
      private void button_generate_Click(object sender, System.EventArgs e)
266
      {
267
         if (this.textBox_template.Text.Length > 0)
268
         {
269
            if (this.textBox_output_file.Text.Length > 0)
270
            {
2106 ghuddy 271
               creationThread = new Thread(new ThreadStart(createTheWordDoc));
272
               creationThread.ApartmentState = ApartmentState.STA;
273
               creationThread.Priority = ThreadPriority.Highest;
274
               creationThread.Start();
2088 ghuddy 275
            }
276
            else
277
            {
278
               MessageBox.Show("Error - must specify an output file");
279
            }
280
         }
281
         else
282
         {
283
            MessageBox.Show("Error - must specify an input template file");
284
         }
285
      }
286
 
2106 ghuddy 287
 
2088 ghuddy 288
      private void button_cancel_Click(object sender, System.EventArgs e)
289
      {
290
      }
291
 
2106 ghuddy 292
 
2088 ghuddy 293
      private void button_browse_template_Click(object sender, System.EventArgs e)
294
      {
295
         OpenFileDialog dialog = new OpenFileDialog();
296
         dialog.Filter = "Word Files (*.doc;*.dot)|*.doc;*.dot|All files(*.*)|*.*";
297
         dialog.FilterIndex = 1;
2106 ghuddy 298
         if (DialogResult.OK == dialog.ShowDialog())
299
         {
300
            this.textBox_template.Text = dialog.FileName;
301
         }
2088 ghuddy 302
      }
303
 
2106 ghuddy 304
 
2088 ghuddy 305
      private void button_browse_output_file_Click(object sender, System.EventArgs e)
306
      {
307
         OpenFileDialog dialog = new OpenFileDialog();
308
         dialog.Filter = "Word Files (*.doc;*.dot)|*.doc;*.dot|All files(*.*)|*.*";
309
         dialog.FilterIndex = 1;
310
         dialog.CheckFileExists = false;
2106 ghuddy 311
         if (DialogResult.OK == dialog.ShowDialog())
312
         {
313
            this.textBox_output_file.Text = dialog.FileName;
314
         }
2088 ghuddy 315
      }
316
 
2106 ghuddy 317
 
2088 ghuddy 318
      private void textBox_template_TextChanged(object sender, System.EventArgs e)
319
      {
320
 
321
      }
322
 
2106 ghuddy 323
 
324
      private void checkBox_keep_on_top_CheckedChanged(object sender, System.EventArgs e)
325
      {
326
         this.TopMost = this.checkBox_keep_on_top.Checked; 
327
      }
328
 
329
 
2088 ghuddy 330
      private void textBox_output_file_TextChanged(object sender, System.EventArgs e)
331
      {
332
 
333
      }
334
 
2106 ghuddy 335
 
2088 ghuddy 336
      private void createWordDoc_Closing(object sender, System.ComponentModel.CancelEventArgs e)
337
      {
2106 ghuddy 338
         if (creationThread != null && creationThread.IsAlive && !mustClose && Main.threadCreateDocProcessRunning)
2088 ghuddy 339
         {
2106 ghuddy 340
            e.Cancel = true;
341
 
342
            DialogResult dlgRes = MessageBox.Show("Cancel Document Generation?", "Cancel", MessageBoxButtons.YesNo);
343
            if (dlgRes == DialogResult.Yes)
344
            {
345
               abortCreationThread = true;
346
               mustClose = true;
347
               Main.EA_Repository.WriteOutput(Main.GUI_OUTPUT_TAB_NAME, "Document Generation Aborting...Please Wait", -1);
348
            }
349
         }
350
         else if (WordApp != null)
351
         {
2088 ghuddy 352
            // try-catch just in case user closed the application themselves whilst viewing the
353
            // generated output document
354
            try 
355
            {
356
               object nothing = Type.Missing;
357
               object notTrue = false;
358
 
359
               WordApp.Application.Quit( ref notTrue, ref nothing, ref nothing);
360
            }
361
            catch (Exception createWordDoc_Closing_exception)
362
            {
363
               // dummy statement
364
               String s = createWordDoc_Closing_exception.Message;
365
            }
366
         }
367
      }
368
 
2106 ghuddy 369
 
2088 ghuddy 370
      #endregion
371
 
372
 
373
      #region word document generation code
374
 
375
 
376
 
2094 ghuddy 377
 
2088 ghuddy 378
      /// <summary>
379
      /// Displays progress of the document generation in the createWordDocument dialog
380
      /// </summary>
381
      /// <param name="prefix"></param>
382
      /// <param name="EA_string"></param>
383
      private void displayProgress(string prefix, string EA_string)
384
      {
2106 ghuddy 385
         //textBox_progress.AppendText( prefix + EA_string + "\r\n" );
2088 ghuddy 386
 
387
         // Display to the output tab as well - as a longer term record of what happened
2094 ghuddy 388
         StringBuilder sb = new StringBuilder("");
2104 ghuddy 389
 
2106 ghuddy 390
         DocSectionTracking.appendHeadingNumber(ref sb);
2104 ghuddy 391
 
2094 ghuddy 392
         while (sb.Length < 30)
393
            sb.Append(" ");
2088 ghuddy 394
 
2094 ghuddy 395
         sb.Append(prefix);
396
         sb.Append(EA_string);
397
 
2106 ghuddy 398
         Main.EA_Repository.WriteOutput( Main.GUI_OUTPUT_TAB_NAME, sb.ToString(), 0);
2088 ghuddy 399
      }
400
 
401
 
402
      /// <summary>
403
      /// This method takes the specified EA diagram element and puts the diagram image
404
      /// into the clipboard from where it can be pasted into the word document. After
405
      /// pasting it into the document, it sets the style and other aspects of the image.
406
      /// </summary>
407
      /// <param name="theDiagram"></param>
408
      private void appendAndSelectDiagramViaClipboard(EA.Diagram theDiagram)
409
      {
2104 ghuddy 410
         // NOTE: diagrams only use one stereotype, not a list of them, so dont use StereotypeEx field
2116 ghuddy 411
         if (  EA_DocGenOptions.optionValue(EA_DocGenOptions.boolean_options_e.CONSIDER_API_DIAGRAMS_ONLY)
2104 ghuddy 412
            && !theDiagram.Stereotype.Equals("API") )
413
         {
2132 ghuddy 414
            displayProgress( "SKIPPED DIAGRAM: ", theDiagram.Name );
2104 ghuddy 415
         }
2108 ghuddy 416
         else if (theDiagram.StyleEx != null && theDiagram.StyleEx.IndexOf("ExcludeRTF=1") >= 0)
417
         {
2132 ghuddy 418
            displayProgress( "EXCLUDED DIAGRAM: ", theDiagram.Name );
2108 ghuddy 419
         }
420
            // open the diagram in EA and copy it's image to the clipboard
2104 ghuddy 421
         else if (EA_Project.PutDiagramImageOnClipboard(theDiagram.DiagramGUID,0))
2088 ghuddy 422
         {
2094 ghuddy 423
            object startLocation;
424
            object endLocation;
425
 
2132 ghuddy 426
            if (theDiagram.Notes != null && theDiagram.Notes.Length > 0)
427
            {
428
               //@@@@
429
               //TextualContent.appendDescription( TextualContent.trimTrailingReturns(theDiagram.Notes) );
430
               TextParser.parse( TextualContent.trimTrailingReturns(theDiagram.Notes), theDiagram.DiagramID, EA_Constants.styleName_Body1, 0, false);
431
            }
2098 ghuddy 432
 
2088 ghuddy 433
            // create a range at the end of the document
434
            startLocation = WordDocument.Content.End;
435
            WordDocument.Content.InsertParagraphAfter();
436
            endLocation = WordDocument.Content.End;
2094 ghuddy 437
            Word.Range WordRange = WordDocument.Range(ref startLocation, ref endLocation);
2088 ghuddy 438
            object direction = Word.WdCollapseDirection.wdCollapseEnd;
439
            WordRange.Collapse(ref direction);  // collapse prevents existing content being replaced
440
 
441
            // Get ready for the diagram paste and the formatting we want to do on it with the
442
            // selection object.
2106 ghuddy 443
            TextualContent.SelectInsertionPointAtEndOfDocument();
2088 ghuddy 444
 
445
            // Paste the diagram into the document
446
            WordRange.Paste();           
447
 
448
            // Set style of the diagram to "Normal" so that it can occupy space all the way to the left margin
2094 ghuddy 449
            object l_style = EA_Constants.styleName_Normal;
2088 ghuddy 450
            endLocation = WordDocument.Content.End;
451
            WordRange = WordDocument.Range(ref startLocation, ref endLocation);
452
            WordRange.set_Style(ref l_style);
453
 
454
            // Center the diagram on the page
455
            object unit = Word.WdUnits.wdLine;
456
            object missing = Type.Missing;
457
            object count = 1;
458
            WordApp.Selection.MoveDown( ref unit, ref count, ref missing);
459
            WordApp.Selection.ParagraphFormat.Alignment = Word.WdParagraphAlignment.wdAlignParagraphCenter;
460
 
461
            // Add a caption
462
            WordDocument.Content.InsertParagraphAfter();
2106 ghuddy 463
            TextualContent.SelectInsertionPointAtEndOfDocument();         
2088 ghuddy 464
            object Label = "Figure";
465
            object Title = Type.Missing;
466
            object TitleAutoText = Type.Missing;
467
            object Position = Word.WdCaptionPosition.wdCaptionPositionAbove;
468
            object ExcludeLabel = 0;
469
            WordApp.Selection.InsertCaption( ref Label, ref Title, ref TitleAutoText, ref Position, ref ExcludeLabel);
2132 ghuddy 470
            WordApp.Selection.TypeText( ": " + theDiagram.Name);
2088 ghuddy 471
            WordApp.Selection.ParagraphFormat.Alignment = Word.WdParagraphAlignment.wdAlignParagraphCenter;
472
 
473
            // experimental code to create a bookmark for the figure caption
474
            //WordDocument.Paragraphs[ WordDocument.Paragraphs.Count ].Range.Select();
475
            //object lastParaRange = WordDocument.Paragraphs[ WordDocument.Paragraphs.Count ].Range;
476
            //string bookmarkName = theDiagram.Name;
477
            //bookmarkName = bookmarkName.Replace(' ', '_');
478
            //WordDocument.Bookmarks.Add( bookmarkName, ref lastParaRange );
479
 
480
            // Close the diagram in EA
2106 ghuddy 481
            Main.EA_Repository.CloseDiagram(theDiagram.DiagramID);
2104 ghuddy 482
 
2132 ghuddy 483
            displayProgress( "DIAGRAM: ", theDiagram.Name );
2088 ghuddy 484
         }
485
      }
486
 
487
 
2094 ghuddy 488
      #region special element processing functions (link elements, table and text elements, etc)
489
 
2088 ghuddy 490
      /// <summary>
491
      /// This function process a package link element, parsing each linked package by the
492
      /// parse_package() recursive function.
493
      /// </summary>
494
      /// <param name="theElement"></param>
495
      /// <param name="recurse_level"></param>
496
      private void processPackageLink(EA.Element theElement, int recurse_level)
497
      {
2132 ghuddy 498
         if (theElement.Notes != null && theElement.Notes.Length > 0)
499
         {
500
            string [] EA_DocGenPkgLnk = null;
501
            string delimStr = "\r\n";
502
            char [] delim = delimStr.ToCharArray();
503
            EA_DocGenPkgLnk = theElement.Notes.Split(delim,100);
504
            string linkedName = "";
2088 ghuddy 505
 
2132 ghuddy 506
            foreach(string s in EA_DocGenPkgLnk)
2088 ghuddy 507
            {
2132 ghuddy 508
               if (s.Length > 0 && s != "\n" && s != "\r")
2088 ghuddy 509
               {
2132 ghuddy 510
                  if (s == "skiproot")
2088 ghuddy 511
                  {
2132 ghuddy 512
                     oneShot_skipRootPackage = true;
2088 ghuddy 513
                  }
2132 ghuddy 514
                  else if (s[0] == '{')
515
                  {
516
                     EA.Package theFoundPackage = Main.EA_Repository.GetPackageByGuid(s);
517
                     if (theFoundPackage != null)
518
                     {
519
                        parse_package(theFoundPackage, recurse_level);
520
                     }
521
                     else
522
                     {
523
                        MessageBox.Show("WARNING - Could not find linked package : " + linkedName );
524
                     }
525
                  }
2088 ghuddy 526
                  else
527
                  {
2132 ghuddy 528
                     linkedName = s;
529
                  }            
2088 ghuddy 530
               }
531
            }
532
         }
533
      }
534
 
535
 
536
      /// <summary>
537
      /// This function process a diagram link element, using the appendAndSelectDiagramViaClipboard()
538
      /// for each linked diagram.
539
      /// </summary>
540
      /// <param name="theElement"></param>
541
      private void processDiagramLink(EA.Element theElement)
542
      {
2132 ghuddy 543
         if (theElement.Notes != null && theElement.Notes.Length > 0)
544
         {
545
            string [] EA_DocGenDiagLnk = null;
546
            string delimStr = "\r\n";
547
            char [] delim = delimStr.ToCharArray();
548
            EA_DocGenDiagLnk = theElement.Notes.Split(delim,100);
549
            string linkedName = "";
2088 ghuddy 550
 
2132 ghuddy 551
            foreach(string s in EA_DocGenDiagLnk)
2088 ghuddy 552
            {
2132 ghuddy 553
               if (s.Length > 0 && s != "\n" && s != "\r" )
2088 ghuddy 554
               {
2132 ghuddy 555
                  if (s[0] == '{')
2088 ghuddy 556
                  {
2132 ghuddy 557
                     EA.Diagram theFoundDiagram = (EA.Diagram)Main.EA_Repository.GetDiagramByGuid(s);
558
                     if (theFoundDiagram != null)
559
                     {
560
                        appendAndSelectDiagramViaClipboard( theFoundDiagram );
561
                     }
562
                     else 
563
                     {
564
                        MessageBox.Show("WARNING - Could not find linked diagram : " + linkedName );
565
                     }
2088 ghuddy 566
                  }
2132 ghuddy 567
                  else
2088 ghuddy 568
                  {
2132 ghuddy 569
                     linkedName = s;
570
                  }            
2088 ghuddy 571
               }
2132 ghuddy 572
            } 
573
         }
2088 ghuddy 574
      }
575
 
576
 
577
      /// <summary>
578
      /// This function process an element link element, parsing each linked element by the
579
      /// parse_element() recursive function.
580
      /// </summary>
581
      /// <param name="theElement"></param>
582
      /// <param name="recurse_level"></param>
583
      private void processElementLink(EA.Element theElement, int recurse_level )
584
      {
2132 ghuddy 585
         if (theElement.Notes != null && theElement.Notes.Length > 0)
586
         {
587
            string [] EA_DocGenEleLnk = null;
588
            string delimStr = "\r\n";
589
            char [] delim = delimStr.ToCharArray();
590
            EA_DocGenEleLnk = theElement.Notes.Split(delim,100);
591
            string linkedName = "";
2088 ghuddy 592
 
2132 ghuddy 593
            foreach(string s in EA_DocGenEleLnk)
2088 ghuddy 594
            {
2132 ghuddy 595
               if (s.Length > 0 && s != "\n" && s != "\r")
2088 ghuddy 596
               {
2132 ghuddy 597
                  if (s == "skiproot")
2088 ghuddy 598
                  {
2132 ghuddy 599
                     oneShot_skipRootElementHeading = true;
2088 ghuddy 600
                  }
2132 ghuddy 601
                  else if ( s[0] == '{')
2088 ghuddy 602
                  {
2132 ghuddy 603
                     EA.Element theFoundElement = Main.EA_Repository.GetElementByGuid(s);
604
                     if (theFoundElement != null)
605
                     {
606
                        parse_element( theFoundElement, recurse_level );
607
                     }
608
                     else 
609
                     {
610
                        MessageBox.Show("WARNING - Could not find linked element : " + linkedName );
611
                     }
2088 ghuddy 612
                  }
2132 ghuddy 613
                  else
614
                  {
615
                     linkedName = s;
616
                  }            
2088 ghuddy 617
               }
618
            }
2132 ghuddy 619
         }
2088 ghuddy 620
      }
621
 
622
 
623
      /// <summary>
2104 ghuddy 624
      /// This method is recursive and searches a model structure to find a match to any 
625
      /// of the names given in a list. Matched package structure is then parsed for
626
      /// document content generation.
2088 ghuddy 627
      /// </summary>
2104 ghuddy 628
      /// <param name="parentPackage"></param>
629
      /// <param name="thePackage"></param>
2088 ghuddy 630
      /// <param name="recurse_level"></param>
2104 ghuddy 631
      /// <param name="skipRoots"></param>
632
      /// <param name="names"></param>
633
      private void processNameLinkPackage(EA.Package parentPackage, EA.Package thePackage, int recurse_level, bool skipRoots, ref ArrayList names)
2088 ghuddy 634
      {
2104 ghuddy 635
         // search for the package name in the names[] list
636
         int i = 0;
637
         bool found = false;
638
         foreach (string name in names)
2088 ghuddy 639
         {
2104 ghuddy 640
            // users can specify parent\child in a name to help narrow down exactly what package they 
641
            // are looking for so deal with that, but the parent\ part is optional.
642
            int splitpos = name.IndexOf('\\',0);
643
            if (splitpos >= 0)
2088 ghuddy 644
            {
2104 ghuddy 645
               if (parentPackage != null)
2088 ghuddy 646
               {
2104 ghuddy 647
                  if (name.Substring(0,splitpos).Equals(parentPackage.Name))
2088 ghuddy 648
                  {
2104 ghuddy 649
                     if (name.Substring(splitpos+1).Equals(thePackage.Name))
650
                     {
651
                        found = true;
652
                        break;
653
                     }
2088 ghuddy 654
                  }
655
               }
2104 ghuddy 656
               else
2088 ghuddy 657
               {
2104 ghuddy 658
                  if (name.Substring(splitpos+1).Equals(thePackage.Name))
2088 ghuddy 659
                  {
2104 ghuddy 660
                     found = true;
2088 ghuddy 661
                     break;
662
                  }
663
               }
2104 ghuddy 664
            }
665
            else
666
            {
667
               if (name.Equals(thePackage.Name))
2088 ghuddy 668
               {
2104 ghuddy 669
                  found = true;
670
                  break;
2088 ghuddy 671
               }
2104 ghuddy 672
            }
673
            i++;
674
         }
2100 ghuddy 675
 
2104 ghuddy 676
         if (found)
677
         {
678
            // remove the found name, arm the skiproot mechanism if needed, and parse the package
679
            names.RemoveAt(i);
680
            if (skipRoots == true)
681
               oneShot_skipRootPackage = true;
2100 ghuddy 682
 
2104 ghuddy 683
            parse_package(thePackage, recurse_level);
684
         }
685
         else if (names.Count > 0)  // any names left to process?
686
         {
687
            // recurse for each of this packages sub-packages
688
            foreach(EA.Package subPackage in thePackage.Packages)
689
            {
690
               processNameLinkPackage(thePackage, subPackage, recurse_level, skipRoots, ref names);                        
691
            }         
692
         }
693
      }
2100 ghuddy 694
 
2104 ghuddy 695
      private void processNameLink(EA.Element theElement, int recurse_level )
696
      {
2132 ghuddy 697
         if (theElement.Notes != null && theElement.Notes.Length > 0)
698
         {
699
            string delimStr = "\r\n";
700
            char [] delim = delimStr.ToCharArray();
701
            string [] EA_DocGenNameLnk = theElement.Notes.Split(delim,100);
2100 ghuddy 702
 
2132 ghuddy 703
            string linkedName = "";
704
            bool gotLinkedName = false;
2104 ghuddy 705
 
2132 ghuddy 706
            ArrayList names = new ArrayList();
2104 ghuddy 707
 
2132 ghuddy 708
            EA.Package theFoundPackage = null;
2104 ghuddy 709
 
2132 ghuddy 710
            bool skipRoots = false;
2104 ghuddy 711
 
2132 ghuddy 712
            // search through the option strings
713
            foreach(string s in EA_DocGenNameLnk)
2104 ghuddy 714
            {
2132 ghuddy 715
               if (s.Length > 0 && s != "\n" && s != "\r")
2104 ghuddy 716
               {
2132 ghuddy 717
                  if (s == "skiproot")
718
                  {
719
                     skipRoots = true;
720
                  }
721
                  else if (s[0] == '{')  // is it a GUID?
722
                  {
723
                     // find the package by its GUID
724
                     theFoundPackage = Main.EA_Repository.GetPackageByGuid(s);
725
                  }
726
                  else if (s.StartsWith("package="))
727
                  {
728
                     // add the users named package to our list of names
729
                     names.Add( s.Substring(8, s.Length - 8) );
730
                  }
731
                  else if (gotLinkedName == false)
732
                  {
733
                     // capture name of package refered to by the GUID - this is only for diagnostic purposes
734
                     gotLinkedName = true;
735
                     linkedName = s;
736
                  }            
2100 ghuddy 737
               }
2132 ghuddy 738
            }  
2104 ghuddy 739
 
2132 ghuddy 740
            // If the GUID was resolved...
741
            if (theFoundPackage != null)
742
            {
743
               processNameLinkPackage(null, theFoundPackage, recurse_level, skipRoots, ref names);
2088 ghuddy 744
 
2132 ghuddy 745
               if (names.Count > 0)
2100 ghuddy 746
               {
2132 ghuddy 747
                  StringBuilder sb = new StringBuilder();
748
                  sb.Append("WARNING - Could not find named package(s)\n");
749
                  sb.Append("within name link: ");
750
                  sb.Append(linkedName);
751
                  sb.Append("\n\nProblem package= directives are:\n");
752
                  foreach(String s in names)
753
                  {
754
                     sb.Append("\n");
755
                     sb.Append(s);
756
                  }
757
                  MessageBox.Show(sb.ToString());
2100 ghuddy 758
               }
2088 ghuddy 759
            }
2132 ghuddy 760
            else
761
            {
762
               MessageBox.Show("WARNING - Could not find linked package : " + linkedName );
763
            }
2088 ghuddy 764
         }
765
      }
766
 
2122 ghuddy 767
 
2088 ghuddy 768
      /// <summary>
2104 ghuddy 769
      /// This function processes a name link element. These are elements that point
770
      /// (using a GUID) to a package, and the user has specified text names of sub-packages
771
      /// within the package that they wish to have processed for document generation.
772
      /// This is a useful way of getting content when you cannot be sure that the GUIDs
773
      /// of the packages you want will remain constant (eg. when re-using content from
774
      /// a reqpro import (for doc gen purposes)).
2094 ghuddy 775
      /// </summary>
776
      /// <param name="theElement"></param>
777
      /// <param name="recurse_level"></param>
778
      private void processTestLink(EA.Element theElement, int recurse_level )
779
      {
2132 ghuddy 780
         if (theElement.Notes != null && theElement.Notes.Length > 0)
781
         {
782
            string [] EA_DocGenEleLnk = null;
783
            string delimStr = "\r\n";
784
            char [] delim = delimStr.ToCharArray();
785
            EA_DocGenEleLnk = theElement.Notes.Split(delim,100);
786
            string linkedName = "";
2094 ghuddy 787
 
2132 ghuddy 788
            foreach(string s in EA_DocGenEleLnk)
2094 ghuddy 789
            {
2132 ghuddy 790
               if (s.Length > 0 && s != "\n" && s != "\r")
2094 ghuddy 791
               {
2132 ghuddy 792
                  if ( s[0] == '{')
2094 ghuddy 793
                  {
2132 ghuddy 794
                     try
2094 ghuddy 795
                     {
2132 ghuddy 796
                        // try to find the GUID as a package
797
                        EA.Package theFoundPackage = Main.EA_Repository.GetPackageByGuid(s);
798
                        if (theFoundPackage != null)
799
                           TextualContent.appendUnitTestSuite(theFoundPackage, recurse_level, ref classesWithUnitTests);
800
                        else 
801
                        {
802
                           // try to find the GUID as an element
803
                           EA.Element theFoundElement = Main.EA_Repository.GetElementByGuid(s);
804
                           if (theFoundElement != null)
805
                              TextualContent.appendUnitTestSuite(theFoundElement, recurse_level, ref classesWithUnitTests);
806
                           else 
807
                              MessageBox.Show("WARNING - Could not find linked element : " + linkedName );
808
                        }
809
                     }
810
                     catch 
811
                     {
2094 ghuddy 812
                        // try to find the GUID as an element
2106 ghuddy 813
                        EA.Element theFoundElement = Main.EA_Repository.GetElementByGuid(s);
2094 ghuddy 814
                        if (theFoundElement != null)
2106 ghuddy 815
                           TextualContent.appendUnitTestSuite(theFoundElement, recurse_level, ref classesWithUnitTests);
2094 ghuddy 816
                        else 
817
                           MessageBox.Show("WARNING - Could not find linked element : " + linkedName );
818
                     }
819
                  }
2132 ghuddy 820
                  else
2094 ghuddy 821
                  {
2132 ghuddy 822
                     linkedName = s;
823
                  }            
2094 ghuddy 824
               }
2132 ghuddy 825
            }   
826
         }
2094 ghuddy 827
      }
828
 
829
 
830
      private void processTestTraceability( EA.Element theElement, int recurse_level )
831
      {
2104 ghuddy 832
         if (classesNeedingUnitTests.Count > 0)
2094 ghuddy 833
         {
2124 ghuddy 834
            TextualContent.appendAndSelectText( theElement.Notes, EA_Constants.styleName_Body1);
835
 
2106 ghuddy 836
            int tableNum = TabularContent.Table_Create("Design Element to Unit Test Suite Traceability", true, 2, 2);
2094 ghuddy 837
            utTraceabilityTable = WordDocument.Tables[tableNum];
838
 
2106 ghuddy 839
            TabularContent.Table_SetTableColumnTitle(utTraceabilityTable, "Design Element (class)", 1);
840
            TabularContent.Table_SetTableColumnTitle(utTraceabilityTable, "Test Suite", 2);
2094 ghuddy 841
         }
842
      }
843
 
844
 
845
      private void completeTestTraceability()
846
      {
847
         if (utTraceabilityTable != null)
848
         {
2104 ghuddy 849
            int numClassesRemaining = classesNeedingUnitTests.Count;
2094 ghuddy 850
            int row = 2;
2104 ghuddy 851
            foreach(int elementId in classesNeedingUnitTests)
2094 ghuddy 852
            {
2106 ghuddy 853
               EA.Element theElement = Main.EA_Repository.GetElementByID( elementId );
2094 ghuddy 854
               if (theElement != null)
855
               {
856
                  utTraceabilityTable.Cell(row,1).Range.Text = theElement.Name;
857
 
858
                  if (classesWithUnitTests.Contains( elementId ))
859
                  {
2106 ghuddy 860
                     utTraceabilityTable.Cell(row,2).Range.Text = TextualContent.testSuiteName(theElement);
2094 ghuddy 861
                  }
862
                  else
863
                  {
864
                     utTraceabilityTable.Cell(row,2).Range.Text = "Missing tests!";
865
                     utTraceabilityTable.Cell(row,2).Range.Font.Color = Word.WdColor.wdColorRed;
866
                  }
867
               }
868
 
869
               numClassesRemaining--;
870
               if (numClassesRemaining > 0)
871
               {
2106 ghuddy 872
                  TabularContent.Table_InsertNewRowAfterThisRow(utTraceabilityTable, row);
2094 ghuddy 873
                  row++;
874
               }
2106 ghuddy 875
 
876
               if (abortCreationThread)
877
                  break;
2094 ghuddy 878
            }
879
         }
880
      }
881
 
882
      #endregion
883
 
884
      #region special section processing functions (references, terminology, etc)
2088 ghuddy 885
      /// <summary>
886
      /// This function processes elements as if they represented document references for
887
      /// the References section of a document.
888
      /// </summary>
889
      /// <param name="thePackage"></param>
890
      private void createReferencesSection(EA.Package thePackage)
891
      {
892
         foreach(EA.Element theElement in thePackage.Elements)
893
         {
2106 ghuddy 894
            if (abortCreationThread)
895
               return;
896
 
2088 ghuddy 897
            // Here we want to apply the special ERG template styles for each reference
898
            // item.
2124 ghuddy 899
            TextualContent.appendAndSelectText( theElement.Name, EA_Constants.styleName_RefListNum );
900
            TextualContent.appendAndSelectText( theElement.Notes, EA_Constants.styleName_RefListText );
2088 ghuddy 901
         }
902
      }
903
 
904
 
2104 ghuddy 905
      private void createTerminologySection(EA.Package thePackage, int recurse_level)
2088 ghuddy 906
      {
907
         // Use local package elements as source of glossary, but if none are present, resort to using
908
         // the project glossary in the repository 
909
         int numItems = thePackage.Elements.Count;
910
         if (numItems == 0)
911
         {
2106 ghuddy 912
            numItems = Main.EA_Repository.Terms.Count;
2094 ghuddy 913
 
2106 ghuddy 914
            // For some wierd reason, I have seen exceptions occur here when trying to get a sorted list of glossary
915
            // items, so I put a trap and retry loop in until such time as the exact cause can be determined.
916
            ArrayList glossary = null;
917
            bool done = false;
918
            int retries = 3;
919
            do
2088 ghuddy 920
            {
2106 ghuddy 921
               if (abortCreationThread)
922
                  return;
923
 
924
               try
925
               {
926
                  glossary = new ArrayList();
927
                  foreach(EA.Term theTerm in Main.EA_Repository.Terms)
928
                     glossary.Add(theTerm);
929
                  glossarySort sorter = new glossarySort();
930
                  glossary.Sort( sorter );
931
                  done = true;
932
               }
933
               catch (Exception e)
934
               {
935
                  Main.EA_Repository.WriteOutput(Main.GUI_OUTPUT_TAB_NAME, "Sorting Glossary, Exception" + e.Message, -1);
936
                  retries--;
937
               }
938
            } while (!done && retries > 0);
939
 
940
            if (done && glossary.Count > 0)
941
            {
942
               // Create a table
943
               int tableNum = TabularContent.Table_Create("Terminology", true, numItems+1, 2);
944
               Word.Table table = WordDocument.Tables[tableNum];
945
               object center = Word.WdParagraphAlignment.wdAlignParagraphCenter;
946
 
947
               TabularContent.Table_SetTableColumnTitle(table, "Term", 1);
948
               TabularContent.Table_SetTableColumnTitle(table, "Definition", 2);
949
               table.Columns[1].SetWidth(100, Word.WdRulerStyle.wdAdjustSameWidth );
950
               int row = 2;
951
               // inject the glossary into the table
952
               foreach(EA.Term theTerm in glossary)
953
               {
954
                  if (abortCreationThread)
955
                     return;
956
 
957
                  table.Cell(row,1).Range.Text = theTerm.Term;
958
                  table.Cell(row,2).Range.Text = theTerm.Meaning;
959
                  row++;
960
               }
2104 ghuddy 961
            }
962
         }
963
         else
964
         {
965
            // scan content of terminology package - allow user to specify tables, text, package links,
966
            // and diagram links.
967
            ArrayList infoItems = new ArrayList();
968
            foreach(EA.Element theElement in thePackage.Elements)
969
            {
2106 ghuddy 970
               if (abortCreationThread)
971
                  return;
972
 
2104 ghuddy 973
               if (theElement.Name.StartsWith(EA_Constants.EA_DocGenTable))
2088 ghuddy 974
               {
2106 ghuddy 975
                  TabularContent.processTableElement( theElement, recurse_level);
2088 ghuddy 976
               }
2104 ghuddy 977
               else if (theElement.Name.StartsWith(EA_Constants.EA_DocGenPackageLink))
978
               {
979
                  processingLink++;
980
                  processPackageLink( theElement, recurse_level );
981
                  processingLink--;
982
               }
983
               else if (theElement.Name.StartsWith(EA_Constants.EA_DocGenText))
984
               {
2106 ghuddy 985
                  TextualContent.appendAndSelectText( TextualContent.trimTrailingReturns(theElement.Notes), EA_Constants.styleName_Body1 );
2104 ghuddy 986
               }
987
               else if (theElement.Name.StartsWith(EA_Constants.EA_DocGenDiagramLink))
988
               {
989
                  processingLink++;
990
                  processDiagramLink( theElement );
991
                  processingLink--;
992
               }
993
               else if (theElement.Name.StartsWith(EA_Constants.EA_DocGenElementLink))
994
               {
995
                  processingLink++;
996
                  processElementLink( theElement, recurse_level );
997
                  processingLink--;
998
               }
999
               else if (!theElement.Name.StartsWith(EA_Constants.EA_DocGenBaseName)   // ignore all other special EA_DocGen elements
1000
                  || theElement.Name.Length == EA_Constants.EA_DocGenBaseName.Length) // allow EA_DocGen to be used as a term/acronym
1001
               {
1002
                  infoItems.Add( theElement );
1003
               }
2088 ghuddy 1004
            }
2104 ghuddy 1005
 
1006
            if (infoItems.Count > 0)
2088 ghuddy 1007
            {
2104 ghuddy 1008
               // Create a table
2106 ghuddy 1009
               int tableNum = TabularContent.Table_Create("Terminology", true, infoItems.Count+1, 2);
2104 ghuddy 1010
               Word.Table table = WordDocument.Tables[tableNum];
1011
               object center = Word.WdParagraphAlignment.wdAlignParagraphCenter;
2088 ghuddy 1012
 
2106 ghuddy 1013
               TabularContent.Table_SetTableColumnTitle(table, "Term", 1);
1014
               TabularContent.Table_SetTableColumnTitle(table, "Definition", 2);
2104 ghuddy 1015
               table.Columns[1].SetWidth(100, Word.WdRulerStyle.wdAdjustSameWidth );
1016
               int row = 2;
1017
 
2106 ghuddy 1018
               elementSortByName sorter = new elementSortByName();
1019
               infoItems.Sort(sorter);
1020
 
2104 ghuddy 1021
               foreach(EA.Element theElement in infoItems)
2088 ghuddy 1022
               {
2106 ghuddy 1023
                  if (abortCreationThread)
1024
                     return;
1025
 
2124 ghuddy 1026
                  table.Cell(row,1).Range.Text = theElement.Name;
1027
                  if (theElement.Notes != null && theElement.Notes.Length > 0)
1028
                     table.Cell(row,2).Range.Text = theElement.Notes;
2088 ghuddy 1029
                  row++;
1030
               }
1031
            }
1032
         }
1033
      }
1034
 
2094 ghuddy 1035
      #endregion
2088 ghuddy 1036
 
1037
      private bool generatePackageHeadingAndDescription( EA.Package thePackage, int recurse_level )
1038
      {
2104 ghuddy 1039
         bool processLowerLevelContent = true;  // return value for this function
2088 ghuddy 1040
 
1041
         // The package name is a heading, and the package notes are paragraphs 
1042
         // directly under that heading
1043
 
2132 ghuddy 1044
         TextualContent.appendAndSelectHeadingText( thePackage.Name, recurse_level );
1045
         displayProgress( "PACKAGE: ", thePackage.Name );
2088 ghuddy 1046
 
1047
         // Special handling for package called "Terminology" 
1048
         if (thePackage.Name == "Terminology")
1049
         {
2106 ghuddy 1050
            TextualContent.appendAndSelectText( TextualContent.trimTrailingReturns(thePackage.Notes), EA_Constants.styleName_Body1 );
2104 ghuddy 1051
            createTerminologySection(thePackage, recurse_level);
1052
            processLowerLevelContent = false;
2088 ghuddy 1053
         }
1054
 
2104 ghuddy 1055
         else if (thePackage.Name == "References")
2088 ghuddy 1056
         {
2106 ghuddy 1057
            TextualContent.appendAndSelectText( TextualContent.trimTrailingReturns(thePackage.Notes), EA_Constants.styleName_Body1 );
2088 ghuddy 1058
            createReferencesSection(thePackage);
2104 ghuddy 1059
            processLowerLevelContent = false;
2088 ghuddy 1060
         }
2104 ghuddy 1061
         else
1062
         {
2132 ghuddy 1063
            if (thePackage.Notes != null && thePackage.Notes.Length > 0)
1064
            {
1065
               // use the package notes as body text and indicate to caller that package elements 
1066
               // have not been consumed
1067
 
1068
               // @@@@
1069
               //TextualContent.appendAndSelectText( TextualContent.trimTrailingReturns(thePackage.Notes), EA_Constants.styleName_Body1 ); 
1070
               TextParser.parse( TextualContent.trimTrailingReturns(thePackage.Notes), thePackage.PackageID, EA_Constants.styleName_Body1, 0, false);
1071
            }
2104 ghuddy 1072
         }
1073
 
1074
         return processLowerLevelContent;
2088 ghuddy 1075
      }
1076
 
1077
 
1078
      private void generatePackageDiagrams( EA.Package thePackage )
1079
      {
1080
         // default handling of diagrams
1081
         foreach(EA.Diagram theDiagram in thePackage.Diagrams)
1082
         {
2106 ghuddy 1083
            if (abortCreationThread)
1084
               return;
1085
 
2102 ghuddy 1086
            if (theDiagram.ParentID == 0 || thePackage.PackageID == theDiagram.ParentID)
1087
            {
1088
               appendAndSelectDiagramViaClipboard( theDiagram );
1089
            }
2088 ghuddy 1090
         }
1091
      }
1092
 
2104 ghuddy 1093
 
2102 ghuddy 1094
      private void generateElementDiagrams( EA.Element theElement )
1095
      {
1096
         // default handling of diagrams
1097
         foreach(EA.Diagram theDiagram in theElement.Diagrams)
1098
         {
2106 ghuddy 1099
            if (abortCreationThread)
1100
               return;
1101
 
2102 ghuddy 1102
            if (theDiagram.ParentID == 0 || theElement.ElementID == theDiagram.ParentID)
1103
            {
1104
               appendAndSelectDiagramViaClipboard( theDiagram );
1105
            }
1106
         }
1107
      }
1108
 
2104 ghuddy 1109
 
2094 ghuddy 1110
      private void generateMethodContent( EA.Element theElement, int recurse_level )
2088 ghuddy 1111
      {
1112
         recurse_level++;
2094 ghuddy 1113
 
1114
         // Get all the methods into an array list and sort them by their position in the class's
1115
         // method list (ie. sort order is determined by the Pos value in each method).
1116
         ArrayList theMethods = new ArrayList();
1117
         foreach(EA.Method theMethod in theElement.Methods)
1118
            theMethods.Add( theMethod );
1119
         methodSortByPos sorter = new methodSortByPos();
1120
         theMethods.Sort( sorter );
1121
 
1122
         // filter out methods with certain characteristics?
1123
         // eg. Users may only want to document public and protected methods.
1124
         int numMethodsRemaining = 0;
1125
         foreach(EA.Method theMethod in theMethods)
1126
         {
2106 ghuddy 1127
            if (abortCreationThread)
1128
               return;
1129
 
2116 ghuddy 1130
            if (EA_DocGenOptions.optionValue(EA_DocGenOptions.boolean_options_e.SUPPRESS_PRIVATE_METHODS) == false
2094 ghuddy 1131
               || !theMethod.Visibility.StartsWith("Private"))
1132
               numMethodsRemaining++;
1133
         }
1134
 
1135
         Word.Range wr;
1136
         StringBuilder sb;
1137
 
1138
         if (numMethodsRemaining > 0)
1139
         {
1140
            // Print the "<Class Name> Operations" headings
1141
            sb = new StringBuilder();
1142
            sb.Append( theElement.Name );
1143
            sb.Append( " Operations" );
2106 ghuddy 1144
            TextualContent.appendAndSelectHeadingText(sb.ToString(), recurse_level);
2094 ghuddy 1145
 
1146
            // Iterate through the class's methods
1147
            foreach(EA.Method theMethod in theMethods)
1148
            {
2106 ghuddy 1149
               if (abortCreationThread)
1150
                  return;
1151
 
2094 ghuddy 1152
               sb = new StringBuilder();
1153
 
2116 ghuddy 1154
               if (EA_DocGenOptions.optionValue(EA_DocGenOptions.boolean_options_e.SUPPRESS_PRIVATE_METHODS) == false
2094 ghuddy 1155
                  || !theMethod.Visibility.StartsWith("Private"))
1156
               {
1157
                  // Print the Method name as a sub heading, and its description
2106 ghuddy 1158
                  TextualContent.appendAndSelectHeadingText(theMethod.Name , recurse_level + 1);
1159
                  TextualContent.appendDescription(TextualContent.trimTrailingReturns(theMethod.Notes));
2094 ghuddy 1160
 
1161
                  // Get a list of the method's parameters and sort them by the position field setup 
1162
                  // in EA by the designer
1163
                  ArrayList theParams = new ArrayList();
1164
                  foreach(EA.Parameter theParam in theMethod.Parameters)
1165
                     theParams.Add( theParam );
1166
                  parameterSortByPos paramSorter = new parameterSortByPos();
1167
                  theParams.Sort( paramSorter );
1168
 
1169
                  // Print the prototype heading
2106 ghuddy 1170
                  wr = TextualContent.appendAndSelectText("\nPrototype:", EA_Constants.styleName_Body1_Left_2_5cm_Italic);
2094 ghuddy 1171
 
1172
                  // begin to build the prototype string
1173
                  sb = new StringBuilder();
1174
                  sb.Append( theMethod.ReturnType );
1175
                  sb.Append( " " );
1176
                  sb.Append( theMethod.Name );
1177
                  sb.Append( "(" );
1178
 
1179
                  if (theParams.Count > 0)
1180
                  {
1181
                     int numParamsRemaining = theParams.Count;
1182
 
1183
                     // print what we have so far constructed for the prototype
2106 ghuddy 1184
                     wr = TextualContent.appendAndSelectText(sb.ToString(), EA_Constants.styleName_Body1_Left_3_5cm);
2094 ghuddy 1185
 
1186
                     // Now form a new string for the params
1187
                     sb = new StringBuilder();
1188
                     foreach(EA.Parameter theParam in theParams)
1189
                     {
2106 ghuddy 1190
                        if (abortCreationThread)
1191
                           return;
1192
 
2094 ghuddy 1193
                        // each parameter is   "[in|out|inout] type name [= default-value]"
1194
                        // where the default value is optional
1195
                        sb.Append( "[" );
1196
                        sb.Append( theParam.Kind );
1197
                        sb.Append( "] " );
1198
                        sb.Append( theParam.Type );
1199
                        sb.Append( " " );
1200
                        sb.Append( theParam.Name );
1201
                        if (theParam.Default.Length > 0)
1202
                        {
1203
                           sb.Append( " = " );
1204
                           sb.Append( theParam.Default );
1205
                        }
1206
 
1207
                        // if there are more parameters after this one, add a comma and newline
1208
                        if (numParamsRemaining > 1)
1209
                           sb.Append( ",\n" );
1210
 
1211
                        numParamsRemaining--;
1212
                     }
1213
 
1214
                     // complete the prototype and print it.
1215
                     sb.Append( ")" );
2106 ghuddy 1216
                     wr = TextualContent.appendAndSelectText(sb.ToString(), EA_Constants.styleName_Body1_Left_4_5cm);
2094 ghuddy 1217
                  }
1218
                  else
1219
                  {
1220
                     // complete the prototype and print it.
1221
                     sb.Append( ")" );
2106 ghuddy 1222
                     wr = TextualContent.appendAndSelectText(sb.ToString(), EA_Constants.styleName_Body1_Left_3_5cm);
2094 ghuddy 1223
                  }
1224
 
1225
 
2116 ghuddy 1226
                  if (EA_DocGenOptions.optionValue(EA_DocGenOptions.boolean_options_e.SUPPRESS_METHOD_CHARACTERISTICS) == false)
1227
                  {
1228
                     // Prototype Attributes/Characteristics
1229
                     sb = new StringBuilder();
1230
                     sb.Append( theMethod.Visibility );
2094 ghuddy 1231
 
2116 ghuddy 1232
                     if (theMethod.IsStatic)
1233
                        sb.Append("\nStatic");
2094 ghuddy 1234
 
2116 ghuddy 1235
                     if (theMethod.Abstract)
1236
                        sb.Append("\nAbstract");
2094 ghuddy 1237
 
2116 ghuddy 1238
                     if (theMethod.IsPure)
1239
                        sb.Append("\nPure (c++)");
2094 ghuddy 1240
 
2116 ghuddy 1241
                     if (theMethod.IsSynchronized)
1242
                        sb.Append("\nSynchronised");
2094 ghuddy 1243
 
2116 ghuddy 1244
                     if (theMethod.Concurrency != null && theMethod.Concurrency.Length > 0 && !theMethod.Concurrency.StartsWith("Sequential") )
1245
                     {
1246
                        sb.Append("\n");
1247
                        sb.Append(theMethod.Concurrency);
1248
                     }
2094 ghuddy 1249
 
2116 ghuddy 1250
                     if (theMethod.IsConst)
1251
                        sb.Append("\nConst");
2094 ghuddy 1252
 
2116 ghuddy 1253
                     if (theMethod.IsQuery)
1254
                        sb.Append("\nIs Querry (does not alter class variables)");
2094 ghuddy 1255
 
2116 ghuddy 1256
                     if (theMethod.IsLeaf)
1257
                        sb.Append("\nIs Leaf (cannot be overriden)");
2094 ghuddy 1258
 
2116 ghuddy 1259
                     if (theMethod.ReturnIsArray)
1260
                        sb.Append( "\nReturn value is an array" );
2094 ghuddy 1261
 
2116 ghuddy 1262
                     if (theMethod.Throws != null && theMethod.Throws.Length > 0)
1263
                     {
1264
                        sb.Append("\n");
1265
                        sb.Append( theMethod.Throws );
1266
                     }
2094 ghuddy 1267
 
2116 ghuddy 1268
                     if (sb.Length > 0)
1269
                     {
1270
                        wr = TextualContent.appendAndSelectText("Characteristics:", EA_Constants.styleName_Body1_Left_2_5cm_Italic);
2094 ghuddy 1271
 
2116 ghuddy 1272
                        wr = TextualContent.appendAndSelectText(sb.ToString(), EA_Constants.styleName_Body1_Left_3_5cm);
1273
                     }
2094 ghuddy 1274
                  }
1275
 
1276
                  // Parameter Descriptions
1277
                  if (theParams.Count > 0)
1278
                  {
2106 ghuddy 1279
                     wr = TextualContent.appendAndSelectText("Parameters:", EA_Constants.styleName_Body1_Left_2_5cm_Italic);
2094 ghuddy 1280
 
1281
                     foreach(EA.Parameter theParam in theParams)
1282
                     {
2106 ghuddy 1283
                        wr = TextualContent.appendAndSelectText( theParam.Name + "\t", EA_Constants.stylename_Parameter_Description);
2098 ghuddy 1284
                        // do notes in seperate step since we want to call the appendDescription() method which 
1285
                        // automatically alerts us to missing descriptions in the generated document.
2106 ghuddy 1286
                        wr = TextualContent.appendDescription( TextualContent.trimTrailingReturns(theParam.Notes), EA_Constants.stylename_Parameter_Description, true);
1287
 
1288
                        if (abortCreationThread)
1289
                           return;
2094 ghuddy 1290
                     }
1291
                  }
1292
               }
1293
            }
1294
         }
1295
      }
1296
 
1297
 
1298
      /// <summary>
1299
      /// This method serialises a class's attributes to the document. 
1300
      /// </summary>
1301
      /// <param name="theElement"></param>
1302
      /// <param name="recurse_level"></param>
1303
      private void generateAttributeContent( EA.Element theElement, int recurse_level )
1304
      {
1305
         recurse_level++;
1306
 
1307
         // Get all the attributes into an array list and sort them by their position in the class's
1308
         // attribute list (ie. sort order is determined by the Pos value in each attribute).
1309
         ArrayList theAttrs = new ArrayList();
1310
         foreach(EA.Attribute theAttr in theElement.Attributes)
1311
            theAttrs.Add( theAttr );
1312
         attributeSortByPos sorter = new attributeSortByPos();
1313
         theAttrs.Sort( sorter );
1314
 
1315
         // TODO
1316
         // filter out attributes with certain characteristics?
1317
         // eg. Users may only want to document public and protected attributes.
1318
 
1319
         int numAttrsRemaining = 0;
1320
         foreach(EA.Attribute theAttr in theAttrs)
1321
         {
2106 ghuddy 1322
            if (abortCreationThread)
1323
               return;
1324
 
2116 ghuddy 1325
            if (EA_DocGenOptions.optionValue(EA_DocGenOptions.boolean_options_e.SUPPRESS_PRIVATE_ATTRIBUTES) == false
2094 ghuddy 1326
               || !theAttr.Visibility.StartsWith("Private"))
1327
               numAttrsRemaining++;
1328
         }
1329
 
1330
         if (numAttrsRemaining > 0)
1331
         {
1332
            StringBuilder sb = new StringBuilder();
1333
 
1334
            sb.Append( theElement.Name );
1335
            sb.Append( " Attributes" );
2106 ghuddy 1336
            TextualContent.appendAndSelectHeadingText(sb.ToString(), recurse_level);
2094 ghuddy 1337
 
1338
            // serialise the attributes to the document.
1339
            foreach(EA.Attribute theAttr in theAttrs)
1340
            {
2106 ghuddy 1341
               if (abortCreationThread)
1342
                  return;
1343
 
2116 ghuddy 1344
               if (EA_DocGenOptions.optionValue(EA_DocGenOptions.boolean_options_e.SUPPRESS_PRIVATE_ATTRIBUTES) == false
2094 ghuddy 1345
                  || !theAttr.Visibility.StartsWith("Private"))
1346
               {
1347
                  // Begin to build content string for the "Attribute" table column 
1348
                  sb = new StringBuilder();
1349
 
1350
                  // <type> <name>
1351
                  sb.Append("\n");
1352
                  sb.Append(theAttr.Type);
1353
                  sb.Append(" ");
1354
                  sb.Append(theAttr.Name);
2106 ghuddy 1355
                  Word.Range wr = TextualContent.appendAndSelectText(sb.ToString(), EA_Constants.styleName_Body1);
2110 ghuddy 1356
                  if (wr.Characters.Last.Text.Equals("\r"))
1357
                     wr.End = wr.End - 1;   // Dont boldise the \r paragraph marker
2094 ghuddy 1358
                  wr.Font.Bold = 1;
1359
 
2106 ghuddy 1360
                  wr = TextualContent.appendDescription(TextualContent.trimTrailingReturns(theAttr.Notes));
2094 ghuddy 1361
                  wr.ParagraphFormat.LeftIndent = WordApp.CentimetersToPoints((float)3.5);
1362
 
2116 ghuddy 1363
                  if (EA_DocGenOptions.optionValue(EA_DocGenOptions.boolean_options_e.SUPPRESS_ATTRIBUTE_CHARACTERISTICS) == false)
1364
                  {
1365
                     // The approach here is to display as much of the attribute as we can but try to keep the output
1366
                     // uncluttered by omitting items the user has not set via the EA GUI.
2094 ghuddy 1367
 
2116 ghuddy 1368
                     // Begin to build content string for the attribute characteristics
1369
                     sb = new StringBuilder();
2094 ghuddy 1370
 
2116 ghuddy 1371
                     sb.Append(theAttr.Visibility);
1372
                     sb.Append("\n");
2094 ghuddy 1373
 
2116 ghuddy 1374
                     if (theAttr.IsConst)
1375
                        sb.Append("Constant\n");
2094 ghuddy 1376
 
2116 ghuddy 1377
                     if (theAttr.IsStatic)
1378
                        sb.Append("Static\n");
2094 ghuddy 1379
 
2116 ghuddy 1380
                     if (theAttr.IsDerived)
1381
                        sb.Append("Derived\n");
2094 ghuddy 1382
 
2116 ghuddy 1383
                     if (theAttr.IsOrdered)
1384
                     {
1385
                        sb.Append("Is Ordered\n");
1386
                     }
2094 ghuddy 1387
 
2116 ghuddy 1388
                     if (theAttr.IsCollection)
1389
                     {
1390
                        sb.Append("Is A Collection\n");
1391
                     }
2094 ghuddy 1392
 
2116 ghuddy 1393
                     if (theAttr.Length.Length > 0 && System.Convert.ToInt32(theAttr.Length) > 0)
1394
                     {
1395
                        sb.Append("Length = ");
1396
                        sb.Append(theAttr.Length);
1397
                        sb.Append("\n");
1398
                     }
2094 ghuddy 1399
 
2116 ghuddy 1400
                     if (!theAttr.Containment.StartsWith("Not Specified"))
1401
                     {
1402
                        sb.Append("Containment =");
1403
                        sb.Append(theAttr.Containment);
1404
                        sb.Append("\n");
1405
                     }
2094 ghuddy 1406
 
2116 ghuddy 1407
                     if (theAttr.Container.Length > 0)
1408
                     {
1409
                        sb.Append("Container Type = ");
1410
                        sb.Append(theAttr.Container);
1411
                        sb.Append("\n");
1412
                     }
2094 ghuddy 1413
 
2116 ghuddy 1414
                     if (theAttr.Style.Length > 0)
1415
                     {
1416
                        sb.Append("Style = ");
1417
                        sb.Append(theAttr.Style);
1418
                        sb.Append("\n");
1419
                     }
2094 ghuddy 1420
 
2116 ghuddy 1421
                     if (  System.Convert.ToInt32(theAttr.LowerBound) > 1
1422
                        || System.Convert.ToInt32(theAttr.UpperBound) > 1)
1423
                     {
1424
                        sb.Append("Multiplicity [");
1425
                        sb.Append(theAttr.LowerBound);
1426
                        sb.Append("..");
1427
                        sb.Append(theAttr.UpperBound);
1428
                        sb.Append("]\n");
1429
                     }
2094 ghuddy 1430
 
2116 ghuddy 1431
                     if (theAttr.Scale.Length > 0 && System.Convert.ToInt32(theAttr.Scale) > 0)
1432
                     {
1433
                        sb.Append("Scale = ");
1434
                        sb.Append(theAttr.Scale);
1435
                        sb.Append( "\n" );
1436
                     }
1437
                     if (theAttr.Precision.Length > 0 && System.Convert.ToInt32(theAttr.Precision) > 0)
1438
                     {
1439
                        sb.Append("Precision = ");
1440
                        sb.Append(theAttr.Precision);
1441
                        sb.Append( "\n" );
1442
                     }
2094 ghuddy 1443
 
2116 ghuddy 1444
                     if (theAttr.Default.Length > 0)
1445
                     {
1446
                        sb.Append("Default Value = ");
1447
                        sb.Append(theAttr.Default);
1448
                        sb.Append( "\n" );
1449
                     }
2094 ghuddy 1450
 
2116 ghuddy 1451
                     // Now look at the constraint and tagged value collections and add any found info to the
1452
                     // right hand column
1453
                     short i;
1454
                     for(i=0; i<theAttr.Constraints.Count; i++)
1455
                     {
1456
                        if (abortCreationThread)
1457
                           return;
2106 ghuddy 1458
 
2116 ghuddy 1459
                        EA.AttributeConstraint theCons = (EA.AttributeConstraint)theAttr.Constraints.GetAt(i);
1460
                        sb.Append( theCons.Type );
1461
                        sb.Append( ": {" );
1462
                        sb.Append( theCons.Name );
1463
                        sb.Append( "}\n" );
2124 ghuddy 1464
                        //if (theCons.Notes != null && theCons.Notes.Length > 0)
1465
                        //{
1466
                        //   sb.Append( theCons.Notes  );
1467
                        //   sb.Append( "\n" );
1468
                        //}
2116 ghuddy 1469
                     }
2094 ghuddy 1470
 
2116 ghuddy 1471
                     for(i=0; i<theAttr.TaggedValues.Count; i++)
1472
                     {
1473
                        if (abortCreationThread)
1474
                           return;
2106 ghuddy 1475
 
2116 ghuddy 1476
                        EA.AttributeTag theTag = (EA.AttributeTag)theAttr.TaggedValues.GetAt(i);
1477
                        sb.Append( "[" );
1478
                        sb.Append( theTag.Name );
1479
                        sb.Append( "="  );
1480
                        sb.Append( theTag.Value );
1481
                        sb.Append( "]\n" );
2124 ghuddy 1482
                        //if (theTag.Notes != null && theTag.Notes.Length > 0)
1483
                        //   sb.Append( theTag.Notes );
1484
                        //   sb.Append( "\n" );
1485
                        //}
2116 ghuddy 1486
                     }
2094 ghuddy 1487
 
2116 ghuddy 1488
                     if (sb.Length > 0)
1489
                     {
1490
                        // remove the trailing "\n"
1491
                        sb.Remove( sb.ToString().Length - 1, 1);
2094 ghuddy 1492
 
2116 ghuddy 1493
                        wr = TextualContent.appendAndSelectText("Characteristics:", EA_Constants.styleName_Body1_Left_3_5cm_Italic);
2094 ghuddy 1494
 
2116 ghuddy 1495
                        wr = TextualContent.appendAndSelectText(sb.ToString(), EA_Constants.styleName_Body1_Left_4_5cm);
1496
                     }
2094 ghuddy 1497
                  }
1498
 
1499
                  numAttrsRemaining--;
1500
               }
1501
            }
1502
         }
1503
      }
1504
 
1505
 
1506
      private void generateClassCharacteristics( EA.Element theElement, int recurse_level )
1507
      {
2116 ghuddy 1508
         StringBuilder sb = null;
1509
         Word.Range wr = null;
2094 ghuddy 1510
 
2116 ghuddy 1511
         // CHARACTERISTICS
1512
         if (EA_DocGenOptions.optionValue(EA_DocGenOptions.boolean_options_e.SUPPRESS_CLASS_CHARACTERISTICS) == false)
2104 ghuddy 1513
         {
2116 ghuddy 1514
            sb = new StringBuilder();
2094 ghuddy 1515
 
2116 ghuddy 1516
            sb.Append( "Characteristics:" );
1517
            wr = TextualContent.appendAndSelectText(sb.ToString(), EA_Constants.styleName_Body1_Left_2_5cm_Italic);
1518
 
1519
            sb = new StringBuilder();
1520
            // VISIBILITY
1521
            sb.Append( theElement.Visibility );
1522
            // ABSTRACT
1523
            if (System.Convert.ToInt32(theElement.Abstract) == 1)
1524
               sb.Append( "\nAbstract" );
1525
            // STEREOTYPES
1526
            if (theElement.StereotypeEx.Length > 0)
1527
            {
1528
               sb.Append("\nStereotypes: ");
1529
               sb.Append(theElement.StereotypeEx);
1530
            }
1531
            // MULTIPLICITY
1532
            if (theElement.Multiplicity.Length > 0)
1533
            {
1534
               sb.Append("\nMultiplicity: ");
1535
               sb.Append(theElement.Multiplicity);
1536
            }
1537
            // IS ACTIVE
1538
            if (theElement.IsActive)
1539
               sb.Append("\nClass is active (has its own thread of control)\n");
1540
            // IS SPEC
1541
            if (theElement.IsSpec)
1542
               sb.Append("\nClass is a specification\n");
2104 ghuddy 1543
 
2116 ghuddy 1544
            wr = TextualContent.appendAndSelectText(sb.ToString(), EA_Constants.styleName_Body1_Left_3_5cm);
2094 ghuddy 1545
         }
2116 ghuddy 1546
 
1547
         // BASE CLASSES
1548
         if (EA_DocGenOptions.optionValue(EA_DocGenOptions.boolean_options_e.SUPPRESS_CLASS_BASE_CLASSES) == false)
2094 ghuddy 1549
         {
2116 ghuddy 1550
            sb = new StringBuilder();
1551
            foreach(EA.Element baseClass in theElement.BaseClasses)
1552
            {
1553
               sb.Append( baseClass.Name);
1554
            }
1555
            if (sb.Length > 0)
1556
            {
1557
               wr = TextualContent.appendAndSelectText("Base Class(es):", EA_Constants.styleName_Body1_Left_2_5cm_Italic);
2088 ghuddy 1558
 
2116 ghuddy 1559
               wr = TextualContent.appendAndSelectText(sb.ToString(), EA_Constants.styleName_Body1_Left_3_5cm);
1560
            }
2094 ghuddy 1561
         }
1562
 
2116 ghuddy 1563
         // REALISES
1564
         if (EA_DocGenOptions.optionValue(EA_DocGenOptions.boolean_options_e.SUPPRESS_CLASS_REALISES) == false)
2094 ghuddy 1565
         {
2116 ghuddy 1566
            sb = new StringBuilder();
1567
            foreach(EA.Element intf in theElement.Realizes)
1568
            {
1569
               sb.Append( intf.Name);
1570
            }
1571
            if (sb.Length > 0)
1572
            {
1573
               wr = TextualContent.appendAndSelectText("Realises:", EA_Constants.styleName_Body1_Left_2_5cm_Italic);
2094 ghuddy 1574
 
2116 ghuddy 1575
               wr = TextualContent.appendAndSelectText(sb.ToString(), EA_Constants.styleName_Body1_Left_3_5cm);
1576
            }
2094 ghuddy 1577
         }
1578
      }
1579
 
1580
 
1581
      private void generateClassRequirements( EA.Element theElement, int recurse_level )
1582
      {
2116 ghuddy 1583
         if (EA_DocGenOptions.optionValue(EA_DocGenOptions.boolean_options_e.SUPPRESS_CLASS_REQUIREMENTS) == false)
1584
         {
1585
            StringBuilder sb = new StringBuilder();
2094 ghuddy 1586
 
2116 ghuddy 1587
            sb.Append( "Requirements:" );
1588
            Word.Range wr = TextualContent.appendAndSelectText(sb.ToString(), EA_Constants.styleName_Body1_Left_2_5cm_Italic);
2094 ghuddy 1589
 
2116 ghuddy 1590
            foreach(EA.Requirement theReq in theElement.Requirements)
1591
            {
1592
               if (abortCreationThread)
1593
                  return;
2106 ghuddy 1594
 
2116 ghuddy 1595
               sb = new StringBuilder();
1596
               sb.Append( theReq.Name );
1597
               wr = TextualContent.appendAndSelectText(sb.ToString(), EA_Constants.styleName_Body1_Left_3_5cm);
2124 ghuddy 1598
 
1599
               if (theReq.Notes != null && theReq.Notes.Length > 0)
2116 ghuddy 1600
               {
2124 ghuddy 1601
                  sb = new StringBuilder();
1602
                  sb.Append( theReq.Notes );
2116 ghuddy 1603
                  wr = TextualContent.appendAndSelectText(sb.ToString(), EA_Constants.styleName_Body1_Left_4_5cm);
1604
               }
2088 ghuddy 1605
            }
2094 ghuddy 1606
         }
1607
      }
1608
 
1609
 
1610
      private void generateClassConstraints( EA.Element theElement, int recurse_level )
1611
      {
2116 ghuddy 1612
         if (EA_DocGenOptions.optionValue(EA_DocGenOptions.boolean_options_e.SUPPRESS_CLASS_CONSTRAINTS) == false)
1613
         {
1614
            StringBuilder sb = new StringBuilder();
2094 ghuddy 1615
 
2116 ghuddy 1616
            sb.Append( "Constraints:" );
1617
            Word.Range wr = TextualContent.appendAndSelectText(sb.ToString(), EA_Constants.styleName_Body1_Left_2_5cm_Italic);
2094 ghuddy 1618
 
2116 ghuddy 1619
            foreach(EA.Constraint theCons in theElement.Constraints)
1620
            {
1621
               if (abortCreationThread)
1622
                  return;
2106 ghuddy 1623
 
2116 ghuddy 1624
               sb = new StringBuilder();
1625
               sb.Append( theCons.Type );
1626
               sb.Append( ": {" );
1627
               sb.Append( theCons.Name );
1628
               sb.Append( "}" );
2094 ghuddy 1629
 
2116 ghuddy 1630
               wr = TextualContent.appendAndSelectText(sb.ToString(), EA_Constants.styleName_Body1_Left_3_5cm);
2094 ghuddy 1631
 
2124 ghuddy 1632
               if (theCons.Notes != null && theCons.Notes.Length > 0)
2116 ghuddy 1633
               {
1634
                  sb = new StringBuilder();
1635
                  sb.Append( theCons.Notes );
1636
                  wr = TextualContent.appendAndSelectText(sb.ToString(), EA_Constants.styleName_Body1_Left_4_5cm);
1637
               }
2094 ghuddy 1638
            }
1639
         }
1640
      }
1641
 
1642
 
2104 ghuddy 1643
      private bool generateElementContent( EA.Element theElement, int recurse_level )
2094 ghuddy 1644
      {
2104 ghuddy 1645
         bool allowSubElementParsing = true;  // return value for the function
1646
 
2094 ghuddy 1647
         // track recursion level to control heading style formatting requirements
1648
         if (oneShot_skipRootElementHeading == false)
1649
            recurse_level++;
1650
 
2106 ghuddy 1651
         if (EA_DocGenOptions.elementTypeFoundInEA_DocGen( theElement.Type ))
2094 ghuddy 1652
         {
1653
            // pass the element to the requirement element serialisation function. It
1654
            // will tell us if it did anything with it. If not, then carry out the default
1655
            // element serialisation.
2106 ghuddy 1656
            if (false == TextualContent.generateRequirementText(theElement))
2094 ghuddy 1657
            {
1658
               bool isClass = theElement.Type.StartsWith("Class");
1659
 
2104 ghuddy 1660
               if (   (   true == isClass
2116 ghuddy 1661
                       && true == EA_DocGenOptions.optionValue(EA_DocGenOptions.boolean_options_e.SUPPRESS_PRIVATE_CLASSES) 
2104 ghuddy 1662
                       && true == theElement.Visibility.StartsWith("Private"))
2116 ghuddy 1663
                   || (   true == EA_DocGenOptions.optionValue(EA_DocGenOptions.boolean_options_e.CONSIDER_API_ELEMENTS_ONLY) 
2104 ghuddy 1664
                       && 0 > theElement.StereotypeEx.IndexOf("API"))
1665
                  )
2088 ghuddy 1666
               {
2094 ghuddy 1667
                  // do nothing
2106 ghuddy 1668
                  DocSectionTracking.trackDocSection(recurse_level);
2104 ghuddy 1669
                  displayProgress( "SKIPPED: ", theElement.Name );
1670
                  allowSubElementParsing = false;
2088 ghuddy 1671
               }
1672
               else
2094 ghuddy 1673
               {
1674
                  // disarm the one-shot element (heading) skipping feature if it was armed, and 
1675
                  // by-pass the code to generate a new heading level for the element
1676
                  if (oneShot_skipRootElementHeading == false)
1677
                  {
1678
                     // Default element serialisation
2106 ghuddy 1679
                     TextualContent.appendAndSelectHeadingText( theElement.Name, recurse_level );
2094 ghuddy 1680
                  }
1681
                  else
1682
                  {
1683
                     oneShot_skipRootElementHeading = false;
1684
                  }
1685
 
2104 ghuddy 1686
                  processedElements.Add(theElement.ElementID);
1687
                  displayProgress( "ELEMENT: ", theElement.Name );
1688
 
2132 ghuddy 1689
                  if (theElement.Notes != null && theElement.Notes.Length > 0)
1690
                  {
1691
                     // @@@@
1692
                     //TextualContent.appendDescription( TextualContent.trimTrailingReturns(theElement.Notes) );
1693
                     TextParser.parse( TextualContent.trimTrailingReturns(theElement.Notes), theElement.ElementID, EA_Constants.styleName_Body1, 0, false);
1694
                  }
2094 ghuddy 1695
 
2102 ghuddy 1696
                  generateElementDiagrams(theElement);
1697
 
2094 ghuddy 1698
                  if (true == isClass)
1699
                  {
2104 ghuddy 1700
                     // accumulate unit testable classes.
1701
                     if (   theElement.StereotypeEx.IndexOf("API") >= 0
1702
                         && !theElement.Visibility.StartsWith("Private"))
2094 ghuddy 1703
                     {
2104 ghuddy 1704
                        classesNeedingUnitTests.Add( theElement.ElementID );
2094 ghuddy 1705
                     }
1706
 
2106 ghuddy 1707
                     if (!abortCreationThread)
1708
                        generateClassCharacteristics(theElement, recurse_level);
2094 ghuddy 1709
                  }
1710
 
1711
                  // Requirement collection
2106 ghuddy 1712
                  if (!abortCreationThread && theElement.Requirements.Count > 0)
2094 ghuddy 1713
                  {
1714
                     generateClassRequirements(theElement, recurse_level);
1715
                  }
1716
 
1717
                  // Constraint collection
2106 ghuddy 1718
                  if (!abortCreationThread && theElement.Constraints.Count > 0)
2094 ghuddy 1719
                  {
1720
                     generateClassConstraints(theElement, recurse_level);
1721
                  }
1722
 
2106 ghuddy 1723
                  if (!abortCreationThread && theElement.Issues.Count > 0)
2094 ghuddy 1724
                  {
1725
                  }
1726
 
1727
                  // Attribute collection
2106 ghuddy 1728
                  if (!abortCreationThread && theElement.Attributes.Count > 0)
2094 ghuddy 1729
                  {
1730
                     generateAttributeContent(theElement, recurse_level);
1731
                  }
1732
 
1733
                  // Method collection
2106 ghuddy 1734
                  if (!abortCreationThread && theElement.Methods.Count > 0)
2094 ghuddy 1735
                  {
1736
                     generateMethodContent(theElement, recurse_level);
1737
                  }
1738
               }
2088 ghuddy 1739
            }
2094 ghuddy 1740
            else
1741
            {
2104 ghuddy 1742
               processedElements.Add(theElement.ElementID);
2106 ghuddy 1743
               DocSectionTracking.trackDocSection(recurse_level);
2094 ghuddy 1744
               displayProgress( "ELEMENT: ", theElement.Name );
1745
            }
2088 ghuddy 1746
         }
1747
         else
1748
         {
2106 ghuddy 1749
            DocSectionTracking.trackDocSection(recurse_level);
2088 ghuddy 1750
            displayProgress( "FILTERED: ", theElement.Type );
1751
         }
1752
         // TODO
1753
         // We will probably have to put special code in here at some point for attributes
1754
         // of, and collections of things within elements. This will become apparent once
1755
         // someone tries to produce a design document where such things need to be included
1756
         // in the generated document. Lots of work needed here eventually.
1757
 
2094 ghuddy 1758
         // disarm element heading skip control
1759
         oneShot_skipRootElementHeading = false;
2104 ghuddy 1760
 
1761
         return allowSubElementParsing;
2088 ghuddy 1762
      }
1763
 
2094 ghuddy 1764
 
2088 ghuddy 1765
      /// <summary>
1766
      /// This function searches for the old content in the document in order to remove it
1767
      /// prior to adding in the new content from the latest EA model data.
1768
      /// </summary>
1769
      private void removeExistingDocumentContent()
1770
      {
1771
         //WordApp.Visible = true;  // enable this when debugging this horrible function
1772
         Word.Selection aSelection;
2106 ghuddy 1773
         object findStyle = StyleContent.getStyle( EA_Constants.styleName_Heading1 );
2088 ghuddy 1774
 
1775
         WordApp.Selection.WholeStory();
1776
         aSelection = WordApp.Selection;
1777
 
1778
         aSelection.Find.ClearFormatting();
1779
         aSelection.Find.set_Style( ref findStyle );
1780
         aSelection.Find.Text = "Introduction";
1781
         aSelection.Find.Replacement.Text = "";
1782
         aSelection.Find.Forward = true;
1783
         aSelection.Find.MatchCase = false;
1784
         aSelection.Find.MatchWholeWord = false;
1785
         aSelection.Find.MatchWildcards = false;
1786
         aSelection.Find.MatchSoundsLike = false;
1787
         aSelection.Find.MatchAllWordForms = false;
1788
 
1789
         object missingValue = Type.Missing;
1790
         if (aSelection.Find.Execute(ref missingValue, ref missingValue, 
1791
            ref missingValue, ref missingValue, ref missingValue, 
1792
            ref missingValue, ref missingValue, ref missingValue, 
1793
            ref missingValue, ref missingValue, ref missingValue, 
1794
            ref missingValue, ref missingValue, ref missingValue, 
1795
            ref missingValue)) 
1796
         { 
1797
            // found Introduction with Heading 1 style so we are now at the point in the 
1798
            // document where everything here on must be deleted in readiness for the newly
1799
            // generated content. Extend the range to the end of the document and cut out the
1800
            // old content.
1801
            Word.Range range = aSelection.Range;
1802
            range.End = WordDocument.Content.End;
1803
            range.Cut();
2092 ghuddy 1804
            // try and ensure that no heading style is left in place following the removal
2094 ghuddy 1805
            object style = EA_Constants.styleName_Body1;
2092 ghuddy 1806
            range.set_Style(ref style);
2088 ghuddy 1807
         }
1808
      }
1809
 
1810
 
1811
      /// <summary>
1812
      /// Parses an element (because elements can contain sub-elements).
1813
      /// This is also the function that identifies the occurrences of the special
1814
      /// EA_DocGenXXX elements.
1815
      /// </summary>
1816
      /// <param name="theElement"></param>
1817
      /// <param name="recurse_level"></param>
1818
      private void parse_element(EA.Element theElement, int recurse_level)
1819
      {
2106 ghuddy 1820
         if (abortCreationThread)
1821
            return;
1822
 
2088 ghuddy 1823
         // First look for and handle special elements that control the doc-gen process
1824
 
1825
         // The EA_DocGenPackageLink can contain a list of GUIDs in its notes section
1826
         // that point to model structure outside of the localised structure forming the
1827
         // document. This enables a document to grab content from other external models
1828
         // as long as they are loaded into the repository.
2094 ghuddy 1829
         if (theElement.Name.StartsWith(EA_Constants.EA_DocGenPackageLink))
2088 ghuddy 1830
         {
2104 ghuddy 1831
            processingLink++;
2088 ghuddy 1832
            processPackageLink( theElement, recurse_level );
2104 ghuddy 1833
            processingLink--;
2088 ghuddy 1834
         }
1835
 
1836
            // The EA_DocGenDiagramLink can contain a list of GUIDs in its notes section
1837
            // that point to diagram elements anywhere in the repository.
2094 ghuddy 1838
         else if (theElement.Name.StartsWith(EA_Constants.EA_DocGenDiagramLink))
2088 ghuddy 1839
         {
2104 ghuddy 1840
            processingLink++;
2088 ghuddy 1841
            processDiagramLink( theElement );
2104 ghuddy 1842
            processingLink--;
2088 ghuddy 1843
         }
1844
 
1845
            // The EA_DocGenDiagramLink can contain a list of GUIDs in its notes section
1846
            // that point to diagram elements anywhere in the repository.
2094 ghuddy 1847
         else if (theElement.Name.StartsWith(EA_Constants.EA_DocGenElementLink))
2088 ghuddy 1848
         {
2104 ghuddy 1849
            processingLink++;
2088 ghuddy 1850
            processElementLink( theElement, recurse_level );
2104 ghuddy 1851
            processingLink--;
2088 ghuddy 1852
         }
1853
 
1854
            // The EA_DocGenTable element can contain table content in its notes section
1855
            // and must be dealt with in a special way.
2094 ghuddy 1856
         else if (theElement.Name.StartsWith(EA_Constants.EA_DocGenTable))
2088 ghuddy 1857
         {
2106 ghuddy 1858
            TabularContent.processTableElement(theElement, recurse_level);
2088 ghuddy 1859
         }
1860
 
1861
            // The EA_DocGenText element can contain text content in its notes section
1862
            // that must be appended to the doc in Body 1 style within the current
1863
            // section.
2094 ghuddy 1864
         else if (theElement.Name.StartsWith(EA_Constants.EA_DocGenText))
2088 ghuddy 1865
         {
2132 ghuddy 1866
            if (theElement.Notes != null && theElement.Notes.Length > 0)
1867
            {
1868
               //@@@@
1869
               //TextualContent.appendAndSelectText( TextualContent.trimTrailingReturns(theElement.Notes), EA_Constants.styleName_Body1 );
1870
               TextParser.parse( TextualContent.trimTrailingReturns(theElement.Notes), theElement.ElementID, EA_Constants.styleName_Body1, 0, false);
1871
            }
2088 ghuddy 1872
         }
1873
 
2094 ghuddy 1874
         else if (theElement.Name.StartsWith(EA_Constants.EA_DocGenRelationshipMatrix))
2088 ghuddy 1875
         {
2106 ghuddy 1876
            EA_RelationshipMatrix.initialise(processedElements);
1877
            if (EA_RelationshipMatrix.processRelationshipMatrixOptions( theElement ))
2104 ghuddy 1878
            {
2106 ghuddy 1879
               EA_RelationshipMatrix.processRelationshipMatrixElement( theElement, recurse_level );
2104 ghuddy 1880
            }
2088 ghuddy 1881
         }
1882
 
2094 ghuddy 1883
         else if (theElement.Name.StartsWith(EA_Constants.EA_DocGenTestLink))
2088 ghuddy 1884
         {
2104 ghuddy 1885
            processingLink++;
2094 ghuddy 1886
            processTestLink( theElement, recurse_level );
2104 ghuddy 1887
            processingLink--;
2094 ghuddy 1888
         }
1889
 
1890
         else if (theElement.Name.StartsWith(EA_Constants.EA_DocGenTestTraceability))
1891
         {
1892
            processTestTraceability( theElement, recurse_level );
1893
         }
1894
 
2104 ghuddy 1895
         else if (theElement.Name.StartsWith(EA_Constants.EA_DocGenNameLink))
1896
         {
1897
            processingLink++;
1898
            processNameLink( theElement, recurse_level );
1899
            processingLink--;
1900
         }
2094 ghuddy 1901
 
2104 ghuddy 1902
            // we are aware of the other ERG EA add-in, EA_ReqPro! That add-in creates 
2094 ghuddy 1903
            // ReqProDB stereotyped elements. Never consume them in the document generation process.
2104 ghuddy 1904
         else if (0 > theElement.StereotypeEx.IndexOf(EA_Constants.stereotype_ReqProDB))
2094 ghuddy 1905
         {
2104 ghuddy 1906
            bool allowSubElementParsing = generateElementContent( theElement, recurse_level );
1907
            if (allowSubElementParsing)
1908
            {
1909
               // Look at this elements sub-elements
1910
               foreach(EA.Element subElement in theElement.Elements)
1911
               {
2106 ghuddy 1912
                  if (abortCreationThread)
1913
                     return;
1914
 
2104 ghuddy 1915
                  parse_element(subElement, recurse_level+1);
1916
               }
1917
            }
2102 ghuddy 1918
         }   
2088 ghuddy 1919
      }
1920
 
1921
 
1922
      /// <summary>
1923
      /// Parses the package and all of its content, extracting information as needed, and
1924
      /// adding it to the word document. This method is recursive, since recursion is the
1925
      /// easiest way to walk thru' the package levels in the model.
1926
      /// </summary>
1927
      /// <param name="parentPackage"></param>
1928
      /// <param name="recurse_level"></param>
1929
      private void parse_package(EA.Package thePackage, int recurse_level)
1930
      {
2106 ghuddy 1931
         if (abortCreationThread)
1932
            return;
1933
 
2088 ghuddy 1934
         // track recursion level to control heading style formatting requirements
1935
         // The one-shot skiproot feature of the EA_DocGenPackageLink element handling has an effect
1936
         // here, as you can see. 
1937
         bool rootPackageWasSkipped = !oneShot_skipRootPackage;
1938
         if (oneShot_skipRootPackage == false)
1939
         {
1940
            recurse_level++;
1941
         }
1942
 
2104 ghuddy 1943
         // determine if the package has an API stereotype
1944
         bool packageHasAPIStereotype = false;
1945
         if (0 <= thePackage.StereotypeEx.IndexOf("API") )
1946
            packageHasAPIStereotype = true;
2088 ghuddy 1947
 
2104 ghuddy 1948
         // only process the package if it the stereotype allows, or sensitivity to the stereotype is disabled
2116 ghuddy 1949
         if (  !EA_DocGenOptions.optionValue(EA_DocGenOptions.boolean_options_e.CONSIDER_API_PACKAGES_ONLY)
1950
            || (   EA_DocGenOptions.optionValue(EA_DocGenOptions.boolean_options_e.CONSIDER_API_PACKAGES_ONLY)
1951
                && EA_DocGenOptions.optionValue(EA_DocGenOptions.boolean_options_e.RESTRICT_FOR_LINKED_PACKAGES_ONLY) && processingLink == 0)
1952
            || (EA_DocGenOptions.optionValue(EA_DocGenOptions.boolean_options_e.CONSIDER_API_PACKAGES_ONLY) 
1953
                && packageHasAPIStereotype) 
2104 ghuddy 1954
            )
2094 ghuddy 1955
         {
2104 ghuddy 1956
 
1957
            bool processLowerLevelContent = true;
2094 ghuddy 1958
 
2104 ghuddy 1959
            // disarm the one-shot package skipping feature if it was armed
1960
            if (oneShot_skipRootPackage == true)
2102 ghuddy 1961
            {
2104 ghuddy 1962
               oneShot_skipRootPackage = false;
2102 ghuddy 1963
            }
2104 ghuddy 1964
            else
1965
            {
1966
               // Generate heading and description for the package. This function also takes care of some
1967
               // specially handled packages (terminology, references).
1968
               processLowerLevelContent = generatePackageHeadingAndDescription( thePackage, recurse_level );
1969
            }
2102 ghuddy 1970
 
2104 ghuddy 1971
            // generate package heading and description. This may, depending on the package name,
1972
            // consume the elements in the package. If it does not, then consume them (and any diagrams)
1973
            // locally here.
1974
            if (true == processLowerLevelContent)
1975
            {
1976
               // consume diagrams
1977
               generatePackageDiagrams( thePackage );
2088 ghuddy 1978
 
2104 ghuddy 1979
               foreach(EA.Element subElement in thePackage.Elements)
1980
               {
2106 ghuddy 1981
                  if (abortCreationThread)
1982
                     return;
1983
 
2104 ghuddy 1984
                  if (subElement.ParentID == 0 || thePackage.PackageID == subElement.ParentID)
1985
                     parse_element(subElement, recurse_level);
1986
               }
2088 ghuddy 1987
 
2104 ghuddy 1988
               // Scan through the sub-packages within this package.
1989
               foreach(EA.Package subPackage in thePackage.Packages)
1990
               {
2106 ghuddy 1991
                  if (abortCreationThread)
1992
                     return;
1993
 
2104 ghuddy 1994
                  // recurse
1995
                  parse_package(subPackage, recurse_level);
1996
               }
1997
            }
2088 ghuddy 1998
         }
2104 ghuddy 1999
         else
2088 ghuddy 2000
         {
2104 ghuddy 2001
            // disarm the one-shot package skipping feature if it was armed
2002
            if (oneShot_skipRootPackage == true)
2003
            {
2004
               oneShot_skipRootPackage = false;
2005
            }         
2088 ghuddy 2006
         }
2007
      }
2008
 
2009
 
2010
      /// <summary>
2011
      /// This is the overall generate document method. It creates a word document from 
2012
      /// an input template, sets various characteristics of the document, schedules the
2013
      /// EA parsing function, before finally saving the document to the output file name.
2014
      /// </summary>
2015
      private void createTheWordDoc()
2016
      {
2106 ghuddy 2017
         docGenCompletedNormally = false;
2018
         abortCreationThread = false;
2019
 
2020
         Main.threadCreateDocProcessRunning = true;
2021
 
2022
         // capture initial security settings
2092 ghuddy 2023
         MsoAutomationSecurity  securityBefore = WordApp.AutomationSecurity;
2024
 
2106 ghuddy 2025
         button_generate.Enabled = false;
2026
         button_browse_output_file.Enabled = false;
2027
         button_browse_template.Enabled = false;
2028
         textBox_output_file.Enabled = false;
2029
         textBox_template.Enabled = false;
2030
         checkBox_WordVisibility.Enabled = false;
2031
 
2088 ghuddy 2032
         try 
2033
         {
2034
            object template       = this.textBox_template.Text;
2035
            object newTemplate    = Type.Missing;
2036
            object outputFilename = this.textBox_output_file.Text;
2037
 
2038
            object docType = Type.Missing;
2039
            object visible = Type.Missing;
2040
            object nothing = Type.Missing;
2041
            object notTrue = false;
2042
 
2106 ghuddy 2043
            Main.EA_Repository.WriteOutput( Main.GUI_OUTPUT_TAB_NAME, "", 0);
2044
            Main.EA_Repository.WriteOutput( Main.GUI_OUTPUT_TAB_NAME, 
2088 ghuddy 2045
                                       String.Format( "Generating Document {0}", this.textBox_output_file.Text), 0 );
2046
 
2122 ghuddy 2047
            // control word visibility based on checkbox user can modify
2088 ghuddy 2048
            WordApp.Visible = this.checkBox_WordVisibility.Checked;
2092 ghuddy 2049
 
2050
            // disable VB macros from running in the document
2051
            WordApp.AutomationSecurity = MsoAutomationSecurity.msoAutomationSecurityForceDisable;
2052
            WordApp.DisplayAlerts = Word.WdAlertLevel.wdAlertsNone;
2053
 
2088 ghuddy 2054
            // Create a document from the input template
2106 ghuddy 2055
            Main.EA_Repository.WriteOutput(Main.GUI_OUTPUT_TAB_NAME, "Creating new document based on template", -1);
2088 ghuddy 2056
            WordDocument = WordApp.Documents.Add(ref template, ref newTemplate, ref docType, ref visible);
2106 ghuddy 2057
 
2088 ghuddy 2058
 
2059
            // Remove all old content from the input document/template. Note that this assumes
2060
            // that content will begin at section 1 with the title "Introduction" and it will have
2061
            // "Heading 1" style.
2106 ghuddy 2062
            if (!abortCreationThread)
2063
            {
2064
               Main.EA_Repository.WriteOutput(Main.GUI_OUTPUT_TAB_NAME, "Removing existing content (if any)", -1);
2065
               removeExistingDocumentContent();
2066
            }
2088 ghuddy 2067
 
2068
            // turn off grammar and spell checking
2069
            WordDocument.GrammarChecked = false;
2070
            WordDocument.SpellingChecked = false;
2071
 
2094 ghuddy 2072
            // arm the public class list accumulator.
2104 ghuddy 2073
            classesNeedingUnitTests = new ArrayList();
2094 ghuddy 2074
            classesWithUnitTests = new ArrayList();
2075
 
2104 ghuddy 2076
            processingLink = 0;
2077
 
2078
            processedElements = new ArrayList();
2079
 
2092 ghuddy 2080
            // If the input template does not contain the styles needed for requirement documents, 
2081
            // programmatically create them just in case.
2106 ghuddy 2082
            if (!abortCreationThread)
2083
            {
2084
               Main.EA_Repository.WriteOutput(Main.GUI_OUTPUT_TAB_NAME, "Creating Requirement Styles", -1);
2085
               StyleContent.createRequirementStyles();
2086
            }
2087
            if (!abortCreationThread)
2088
            {
2089
               Main.EA_Repository.WriteOutput(Main.GUI_OUTPUT_TAB_NAME, "Creating Additional Heading Styles", -1);
2090
               StyleContent.createAdditionalHeadingLevelStyles();
2091
            }
2092
            if (!abortCreationThread)
2093
            {
2094
               Main.EA_Repository.WriteOutput(Main.GUI_OUTPUT_TAB_NAME, "Creating Element Detail Styles", -1);
2095
               StyleContent.createElementDetailsStyles();
2096
            }
2097
            if (!abortCreationThread)
2098
            {
2099
               Main.EA_Repository.WriteOutput(Main.GUI_OUTPUT_TAB_NAME, "Correcting known problems in ERG template styles", -1);
2100
               StyleContent.correctErrorsInTemplateStyles();
2101
            }
2132 ghuddy 2102
            if (EA_DocGenOptions.optionValue(EA_DocGenOptions.boolean_options_e.FORCE_HEADING_TABS_TO_2_5_CM))
2103
            {
2104
               Main.EA_Repository.WriteOutput(Main.GUI_OUTPUT_TAB_NAME, "Forcing Heading styles to use tab stop at 2.5cm only", -1);
2105
               StyleContent.forceHeadingsToUse2_5cmTabStops();
2106
            }
2098 ghuddy 2107
 
2088 ghuddy 2108
            // Parse EA_DocGen Document Model. The parent package is the document model itself
2109
            // and the packages within it are the top level packages only.
2110
            // Question: do we have to parse diagrams and elements at this top level? So far,
2111
            // this has been found to be unecessary, but you never know. For now, dont do it.
2106 ghuddy 2112
            if (!abortCreationThread)
2088 ghuddy 2113
            {
2106 ghuddy 2114
               Main.EA_Repository.WriteOutput(Main.GUI_OUTPUT_TAB_NAME, "Generating new content", -1);
2115
 
2116
               foreach(EA.Package thePackage in EA_ParentPackage.Packages)
2117
               {
2118
                  parse_package(thePackage, 0);
2119
                  if (abortCreationThread)
2120
                     break;
2121
               }
2088 ghuddy 2122
            }
2094 ghuddy 2123
            // for design docs, a user may have used the test traceability element in their document model,
2124
            // which means that now we are finished with parse 1 of the document, we can complete the traceability
2125
            // table (if any) that was begun when that special element was first encountered.
2106 ghuddy 2126
            if (!abortCreationThread)
2127
            {
2128
               completeTestTraceability();
2088 ghuddy 2129
 
2106 ghuddy 2130
               // Save the document to the output file before we try and update the fields. This is because
2131
               // I have seen Fields.Update() fail on a few occasions and it is very annoying
2132
               // to lose what has thus far been generated.
2133
               WordDocument.SaveAs( ref outputFilename, 
2134
                  ref nothing, ref nothing, ref nothing, ref nothing, 
2135
                  ref nothing, ref nothing, ref nothing, ref nothing,
2136
                  ref nothing, ref nothing, ref nothing, ref nothing,
2137
                  ref nothing, ref nothing, ref nothing);
2088 ghuddy 2138
 
2106 ghuddy 2139
               object noSave = Word.WdSaveOptions.wdDoNotSaveChanges;
2140
               object format = Word.WdOriginalFormat.wdWordDocument;
2141
               WordDocument.Close(ref noSave, ref format, ref nothing);
2094 ghuddy 2142
 
2106 ghuddy 2143
               if (!abortCreationThread)
2144
               {
2145
                  Main.EA_Repository.WriteOutput(Main.GUI_OUTPUT_TAB_NAME, "Updating Fields and Saving Document", -1);
2146
                  // Re-load the document to update the fields. For some as yet unknown reason, doing this 
2147
                  // sometimes fails, but by doing it in a re-loaded instance of the word document
2148
                  // the failures seem to be reduced.
2149
                  WordDocument = WordApp.Documents.Add(ref outputFilename, ref newTemplate, ref docType, ref visible);
2150
                  WordDocument.Fields.Update();
2151
                  WordDocument.SaveAs( ref outputFilename, 
2152
                     ref nothing, ref nothing, ref nothing, ref nothing, 
2153
                     ref nothing, ref nothing, ref nothing, ref nothing,
2154
                     ref nothing, ref nothing, ref nothing, ref nothing,
2155
                     ref nothing, ref nothing, ref nothing);
2088 ghuddy 2156
 
2106 ghuddy 2157
                  // Tell user the process completed ok
2158
                  Main.EA_Repository.WriteOutput(Main.GUI_OUTPUT_TAB_NAME, "Document Generation Complete", -1);
2159
                  docGenCompletedNormally = true;
2160
                  button_view_output.Enabled = true;
2161
               }
2162
            }
2163
            else
2164
            {
2165
               Main.EA_Repository.WriteOutput(Main.GUI_OUTPUT_TAB_NAME, "Document Generation Aborted", -1);
2166
               MessageBox.Show("Document Generation Aborted");
2167
            }
2098 ghuddy 2168
 
2088 ghuddy 2169
         }
2170
         catch (Exception createTheWordDoc_exception)
2171
         {
2110 ghuddy 2172
            Main.ShowException(createTheWordDoc_exception, "Document Generation Failed");
2088 ghuddy 2173
         }
2092 ghuddy 2174
 
2175
         // restore security settings
2176
         WordApp.AutomationSecurity = securityBefore;
2106 ghuddy 2177
 
2178
         // issue the generation complete message box as close to the end of the thread as possible so that
2179
         // there is less of a chance that a user pressing the close button will see a "cancel generation"
2180
         // warning box.
2181
         if (docGenCompletedNormally)
2182
            MessageBox.Show("Document Generation Complete");
2183
 
2184
         // we can mark the thread as not running since from now on we do not want to do anything with the 
2185
         // WordApp or WordDocument objects and their destruction wont cause any ill effects.
2186
         Main.threadCreateDocProcessRunning = false;
2187
 
2188
         if (mustClose)
2189
            this.Close();
2088 ghuddy 2190
      }
2191
 
2092 ghuddy 2192
 
2193
 
2194
 
2088 ghuddy 2195
      #endregion
2106 ghuddy 2196
 
2197
 
2198
 
2199
 
2088 ghuddy 2200
   }
2201
}