Subversion Repositories DevTools

Rev

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