Subversion Repositories DevTools

Rev

Rev 2116 | Rev 2124 | 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
         {
813
            if (theElement.Notes.Length > 0)
814
            {
2106 ghuddy 815
               TextualContent.appendAndSelectText( theElement.Notes, EA_Constants.styleName_Body1);
2094 ghuddy 816
            }
2106 ghuddy 817
            int tableNum = TabularContent.Table_Create("Design Element to Unit Test Suite Traceability", true, 2, 2);
2094 ghuddy 818
            utTraceabilityTable = WordDocument.Tables[tableNum];
819
 
2106 ghuddy 820
            TabularContent.Table_SetTableColumnTitle(utTraceabilityTable, "Design Element (class)", 1);
821
            TabularContent.Table_SetTableColumnTitle(utTraceabilityTable, "Test Suite", 2);
2094 ghuddy 822
         }
823
      }
824
 
825
 
826
      private void completeTestTraceability()
827
      {
828
         if (utTraceabilityTable != null)
829
         {
2104 ghuddy 830
            int numClassesRemaining = classesNeedingUnitTests.Count;
2094 ghuddy 831
            int row = 2;
2104 ghuddy 832
            foreach(int elementId in classesNeedingUnitTests)
2094 ghuddy 833
            {
2106 ghuddy 834
               EA.Element theElement = Main.EA_Repository.GetElementByID( elementId );
2094 ghuddy 835
               if (theElement != null)
836
               {
837
                  utTraceabilityTable.Cell(row,1).Range.Text = theElement.Name;
838
 
839
                  if (classesWithUnitTests.Contains( elementId ))
840
                  {
2106 ghuddy 841
                     utTraceabilityTable.Cell(row,2).Range.Text = TextualContent.testSuiteName(theElement);
2094 ghuddy 842
                  }
843
                  else
844
                  {
845
                     utTraceabilityTable.Cell(row,2).Range.Text = "Missing tests!";
846
                     utTraceabilityTable.Cell(row,2).Range.Font.Color = Word.WdColor.wdColorRed;
847
                  }
848
               }
849
 
850
               numClassesRemaining--;
851
               if (numClassesRemaining > 0)
852
               {
2106 ghuddy 853
                  TabularContent.Table_InsertNewRowAfterThisRow(utTraceabilityTable, row);
2094 ghuddy 854
                  row++;
855
               }
2106 ghuddy 856
 
857
               if (abortCreationThread)
858
                  break;
2094 ghuddy 859
            }
860
         }
861
      }
862
 
863
      #endregion
864
 
865
      #region special section processing functions (references, terminology, etc)
2088 ghuddy 866
      /// <summary>
867
      /// This function processes elements as if they represented document references for
868
      /// the References section of a document.
869
      /// </summary>
870
      /// <param name="thePackage"></param>
871
      private void createReferencesSection(EA.Package thePackage)
872
      {
873
         foreach(EA.Element theElement in thePackage.Elements)
874
         {
2106 ghuddy 875
            if (abortCreationThread)
876
               return;
877
 
2088 ghuddy 878
            // Here we want to apply the special ERG template styles for each reference
879
            // item.
2106 ghuddy 880
            TextualContent.appendAndSelectText( theElement.Name.ToString(), EA_Constants.styleName_RefListNum );
881
            TextualContent.appendAndSelectText( theElement.Notes.ToString(), EA_Constants.styleName_RefListText );
2088 ghuddy 882
         }
883
      }
884
 
885
 
2104 ghuddy 886
      private void createTerminologySection(EA.Package thePackage, int recurse_level)
2088 ghuddy 887
      {
888
         // Use local package elements as source of glossary, but if none are present, resort to using
889
         // the project glossary in the repository 
890
         int numItems = thePackage.Elements.Count;
891
         if (numItems == 0)
892
         {
2106 ghuddy 893
            numItems = Main.EA_Repository.Terms.Count;
2094 ghuddy 894
 
2106 ghuddy 895
            // For some wierd reason, I have seen exceptions occur here when trying to get a sorted list of glossary
896
            // items, so I put a trap and retry loop in until such time as the exact cause can be determined.
897
            ArrayList glossary = null;
898
            bool done = false;
899
            int retries = 3;
900
            do
2088 ghuddy 901
            {
2106 ghuddy 902
               if (abortCreationThread)
903
                  return;
904
 
905
               try
906
               {
907
                  glossary = new ArrayList();
908
                  foreach(EA.Term theTerm in Main.EA_Repository.Terms)
909
                     glossary.Add(theTerm);
910
                  glossarySort sorter = new glossarySort();
911
                  glossary.Sort( sorter );
912
                  done = true;
913
               }
914
               catch (Exception e)
915
               {
916
                  Main.EA_Repository.WriteOutput(Main.GUI_OUTPUT_TAB_NAME, "Sorting Glossary, Exception" + e.Message, -1);
917
                  retries--;
918
               }
919
            } while (!done && retries > 0);
920
 
921
            if (done && glossary.Count > 0)
922
            {
923
               // Create a table
924
               int tableNum = TabularContent.Table_Create("Terminology", true, numItems+1, 2);
925
               Word.Table table = WordDocument.Tables[tableNum];
926
               object center = Word.WdParagraphAlignment.wdAlignParagraphCenter;
927
 
928
               TabularContent.Table_SetTableColumnTitle(table, "Term", 1);
929
               TabularContent.Table_SetTableColumnTitle(table, "Definition", 2);
930
               table.Columns[1].SetWidth(100, Word.WdRulerStyle.wdAdjustSameWidth );
931
               int row = 2;
932
               // inject the glossary into the table
933
               foreach(EA.Term theTerm in glossary)
934
               {
935
                  if (abortCreationThread)
936
                     return;
937
 
938
                  table.Cell(row,1).Range.Text = theTerm.Term;
939
                  table.Cell(row,2).Range.Text = theTerm.Meaning;
940
                  row++;
941
               }
2104 ghuddy 942
            }
943
         }
944
         else
945
         {
946
            // scan content of terminology package - allow user to specify tables, text, package links,
947
            // and diagram links.
948
            ArrayList infoItems = new ArrayList();
949
            foreach(EA.Element theElement in thePackage.Elements)
950
            {
2106 ghuddy 951
               if (abortCreationThread)
952
                  return;
953
 
2104 ghuddy 954
               if (theElement.Name.StartsWith(EA_Constants.EA_DocGenTable))
2088 ghuddy 955
               {
2106 ghuddy 956
                  TabularContent.processTableElement( theElement, recurse_level);
2088 ghuddy 957
               }
2104 ghuddy 958
               else if (theElement.Name.StartsWith(EA_Constants.EA_DocGenPackageLink))
959
               {
960
                  processingLink++;
961
                  processPackageLink( theElement, recurse_level );
962
                  processingLink--;
963
               }
964
               else if (theElement.Name.StartsWith(EA_Constants.EA_DocGenText))
965
               {
2106 ghuddy 966
                  TextualContent.appendAndSelectText( TextualContent.trimTrailingReturns(theElement.Notes), EA_Constants.styleName_Body1 );
2104 ghuddy 967
               }
968
               else if (theElement.Name.StartsWith(EA_Constants.EA_DocGenDiagramLink))
969
               {
970
                  processingLink++;
971
                  processDiagramLink( theElement );
972
                  processingLink--;
973
               }
974
               else if (theElement.Name.StartsWith(EA_Constants.EA_DocGenElementLink))
975
               {
976
                  processingLink++;
977
                  processElementLink( theElement, recurse_level );
978
                  processingLink--;
979
               }
980
               else if (!theElement.Name.StartsWith(EA_Constants.EA_DocGenBaseName)   // ignore all other special EA_DocGen elements
981
                  || theElement.Name.Length == EA_Constants.EA_DocGenBaseName.Length) // allow EA_DocGen to be used as a term/acronym
982
               {
983
                  infoItems.Add( theElement );
984
               }
2088 ghuddy 985
            }
2104 ghuddy 986
 
987
            if (infoItems.Count > 0)
2088 ghuddy 988
            {
2104 ghuddy 989
               // Create a table
2106 ghuddy 990
               int tableNum = TabularContent.Table_Create("Terminology", true, infoItems.Count+1, 2);
2104 ghuddy 991
               Word.Table table = WordDocument.Tables[tableNum];
992
               object center = Word.WdParagraphAlignment.wdAlignParagraphCenter;
2088 ghuddy 993
 
2106 ghuddy 994
               TabularContent.Table_SetTableColumnTitle(table, "Term", 1);
995
               TabularContent.Table_SetTableColumnTitle(table, "Definition", 2);
2104 ghuddy 996
               table.Columns[1].SetWidth(100, Word.WdRulerStyle.wdAdjustSameWidth );
997
               int row = 2;
998
 
2106 ghuddy 999
               elementSortByName sorter = new elementSortByName();
1000
               infoItems.Sort(sorter);
1001
 
2104 ghuddy 1002
               foreach(EA.Element theElement in infoItems)
2088 ghuddy 1003
               {
2106 ghuddy 1004
                  if (abortCreationThread)
1005
                     return;
1006
 
2104 ghuddy 1007
                  table.Cell(row,1).Range.Text = theElement.Name.ToString();
1008
                  table.Cell(row,2).Range.Text = theElement.Notes.ToString();
2088 ghuddy 1009
                  row++;
1010
               }
1011
            }
1012
         }
1013
      }
1014
 
2094 ghuddy 1015
      #endregion
2088 ghuddy 1016
 
1017
      private bool generatePackageHeadingAndDescription( EA.Package thePackage, int recurse_level )
1018
      {
2104 ghuddy 1019
         bool processLowerLevelContent = true;  // return value for this function
2088 ghuddy 1020
 
1021
         // The package name is a heading, and the package notes are paragraphs 
1022
         // directly under that heading
1023
 
2106 ghuddy 1024
         TextualContent.appendAndSelectHeadingText( thePackage.Name.ToString(), recurse_level );
2104 ghuddy 1025
         displayProgress( "PACKAGE: ", thePackage.Name.ToString() );
2088 ghuddy 1026
 
1027
         // Special handling for package called "Terminology" 
1028
         if (thePackage.Name == "Terminology")
1029
         {
2106 ghuddy 1030
            TextualContent.appendAndSelectText( TextualContent.trimTrailingReturns(thePackage.Notes), EA_Constants.styleName_Body1 );
2104 ghuddy 1031
            createTerminologySection(thePackage, recurse_level);
1032
            processLowerLevelContent = false;
2088 ghuddy 1033
         }
1034
 
2104 ghuddy 1035
         else if (thePackage.Name == "References")
2088 ghuddy 1036
         {
2106 ghuddy 1037
            TextualContent.appendAndSelectText( TextualContent.trimTrailingReturns(thePackage.Notes), EA_Constants.styleName_Body1 );
2088 ghuddy 1038
            createReferencesSection(thePackage);
2104 ghuddy 1039
            processLowerLevelContent = false;
2088 ghuddy 1040
         }
2104 ghuddy 1041
         else
1042
         {
1043
            // use the package notes as body text and indicate to caller that package elements 
1044
            // have not been consumed
2106 ghuddy 1045
            TextualContent.appendAndSelectText( TextualContent.trimTrailingReturns(thePackage.Notes), EA_Constants.styleName_Body1 );      
2104 ghuddy 1046
         }
1047
 
1048
         return processLowerLevelContent;
2088 ghuddy 1049
      }
1050
 
1051
 
1052
      private void generatePackageDiagrams( EA.Package thePackage )
1053
      {
1054
         // default handling of diagrams
1055
         foreach(EA.Diagram theDiagram in thePackage.Diagrams)
1056
         {
2106 ghuddy 1057
            if (abortCreationThread)
1058
               return;
1059
 
2102 ghuddy 1060
            if (theDiagram.ParentID == 0 || thePackage.PackageID == theDiagram.ParentID)
1061
            {
1062
               appendAndSelectDiagramViaClipboard( theDiagram );
1063
            }
2088 ghuddy 1064
         }
1065
      }
1066
 
2104 ghuddy 1067
 
2102 ghuddy 1068
      private void generateElementDiagrams( EA.Element theElement )
1069
      {
1070
         // default handling of diagrams
1071
         foreach(EA.Diagram theDiagram in theElement.Diagrams)
1072
         {
2106 ghuddy 1073
            if (abortCreationThread)
1074
               return;
1075
 
2102 ghuddy 1076
            if (theDiagram.ParentID == 0 || theElement.ElementID == theDiagram.ParentID)
1077
            {
1078
               appendAndSelectDiagramViaClipboard( theDiagram );
1079
            }
1080
         }
1081
      }
1082
 
2104 ghuddy 1083
 
2094 ghuddy 1084
      private void generateMethodContent( EA.Element theElement, int recurse_level )
2088 ghuddy 1085
      {
1086
         recurse_level++;
2094 ghuddy 1087
 
1088
         // Get all the methods into an array list and sort them by their position in the class's
1089
         // method list (ie. sort order is determined by the Pos value in each method).
1090
         ArrayList theMethods = new ArrayList();
1091
         foreach(EA.Method theMethod in theElement.Methods)
1092
            theMethods.Add( theMethod );
1093
         methodSortByPos sorter = new methodSortByPos();
1094
         theMethods.Sort( sorter );
1095
 
1096
         // filter out methods with certain characteristics?
1097
         // eg. Users may only want to document public and protected methods.
1098
         int numMethodsRemaining = 0;
1099
         foreach(EA.Method theMethod in theMethods)
1100
         {
2106 ghuddy 1101
            if (abortCreationThread)
1102
               return;
1103
 
2116 ghuddy 1104
            if (EA_DocGenOptions.optionValue(EA_DocGenOptions.boolean_options_e.SUPPRESS_PRIVATE_METHODS) == false
2094 ghuddy 1105
               || !theMethod.Visibility.StartsWith("Private"))
1106
               numMethodsRemaining++;
1107
         }
1108
 
1109
         Word.Range wr;
1110
         StringBuilder sb;
1111
 
1112
         if (numMethodsRemaining > 0)
1113
         {
1114
            // Print the "<Class Name> Operations" headings
1115
            sb = new StringBuilder();
1116
            sb.Append( theElement.Name );
1117
            sb.Append( " Operations" );
2106 ghuddy 1118
            TextualContent.appendAndSelectHeadingText(sb.ToString(), recurse_level);
2094 ghuddy 1119
 
1120
            // Iterate through the class's methods
1121
            foreach(EA.Method theMethod in theMethods)
1122
            {
2106 ghuddy 1123
               if (abortCreationThread)
1124
                  return;
1125
 
2094 ghuddy 1126
               sb = new StringBuilder();
1127
 
2116 ghuddy 1128
               if (EA_DocGenOptions.optionValue(EA_DocGenOptions.boolean_options_e.SUPPRESS_PRIVATE_METHODS) == false
2094 ghuddy 1129
                  || !theMethod.Visibility.StartsWith("Private"))
1130
               {
1131
                  // Print the Method name as a sub heading, and its description
2106 ghuddy 1132
                  TextualContent.appendAndSelectHeadingText(theMethod.Name , recurse_level + 1);
1133
                  TextualContent.appendDescription(TextualContent.trimTrailingReturns(theMethod.Notes));
2094 ghuddy 1134
 
1135
                  // Get a list of the method's parameters and sort them by the position field setup 
1136
                  // in EA by the designer
1137
                  ArrayList theParams = new ArrayList();
1138
                  foreach(EA.Parameter theParam in theMethod.Parameters)
1139
                     theParams.Add( theParam );
1140
                  parameterSortByPos paramSorter = new parameterSortByPos();
1141
                  theParams.Sort( paramSorter );
1142
 
1143
                  // Print the prototype heading
2106 ghuddy 1144
                  wr = TextualContent.appendAndSelectText("\nPrototype:", EA_Constants.styleName_Body1_Left_2_5cm_Italic);
2094 ghuddy 1145
 
1146
                  // begin to build the prototype string
1147
                  sb = new StringBuilder();
1148
                  sb.Append( theMethod.ReturnType );
1149
                  sb.Append( " " );
1150
                  sb.Append( theMethod.Name );
1151
                  sb.Append( "(" );
1152
 
1153
                  if (theParams.Count > 0)
1154
                  {
1155
                     int numParamsRemaining = theParams.Count;
1156
 
1157
                     // print what we have so far constructed for the prototype
2106 ghuddy 1158
                     wr = TextualContent.appendAndSelectText(sb.ToString(), EA_Constants.styleName_Body1_Left_3_5cm);
2094 ghuddy 1159
 
1160
                     // Now form a new string for the params
1161
                     sb = new StringBuilder();
1162
                     foreach(EA.Parameter theParam in theParams)
1163
                     {
2106 ghuddy 1164
                        if (abortCreationThread)
1165
                           return;
1166
 
2094 ghuddy 1167
                        // each parameter is   "[in|out|inout] type name [= default-value]"
1168
                        // where the default value is optional
1169
                        sb.Append( "[" );
1170
                        sb.Append( theParam.Kind );
1171
                        sb.Append( "] " );
1172
                        sb.Append( theParam.Type );
1173
                        sb.Append( " " );
1174
                        sb.Append( theParam.Name );
1175
                        if (theParam.Default.Length > 0)
1176
                        {
1177
                           sb.Append( " = " );
1178
                           sb.Append( theParam.Default );
1179
                        }
1180
 
1181
                        // if there are more parameters after this one, add a comma and newline
1182
                        if (numParamsRemaining > 1)
1183
                           sb.Append( ",\n" );
1184
 
1185
                        numParamsRemaining--;
1186
                     }
1187
 
1188
                     // complete the prototype and print it.
1189
                     sb.Append( ")" );
2106 ghuddy 1190
                     wr = TextualContent.appendAndSelectText(sb.ToString(), EA_Constants.styleName_Body1_Left_4_5cm);
2094 ghuddy 1191
                  }
1192
                  else
1193
                  {
1194
                     // complete the prototype and print it.
1195
                     sb.Append( ")" );
2106 ghuddy 1196
                     wr = TextualContent.appendAndSelectText(sb.ToString(), EA_Constants.styleName_Body1_Left_3_5cm);
2094 ghuddy 1197
                  }
1198
 
1199
 
2116 ghuddy 1200
                  if (EA_DocGenOptions.optionValue(EA_DocGenOptions.boolean_options_e.SUPPRESS_METHOD_CHARACTERISTICS) == false)
1201
                  {
1202
                     // Prototype Attributes/Characteristics
1203
                     sb = new StringBuilder();
1204
                     sb.Append( theMethod.Visibility );
2094 ghuddy 1205
 
2116 ghuddy 1206
                     if (theMethod.IsStatic)
1207
                        sb.Append("\nStatic");
2094 ghuddy 1208
 
2116 ghuddy 1209
                     if (theMethod.Abstract)
1210
                        sb.Append("\nAbstract");
2094 ghuddy 1211
 
2116 ghuddy 1212
                     if (theMethod.IsPure)
1213
                        sb.Append("\nPure (c++)");
2094 ghuddy 1214
 
2116 ghuddy 1215
                     if (theMethod.IsSynchronized)
1216
                        sb.Append("\nSynchronised");
2094 ghuddy 1217
 
2116 ghuddy 1218
                     if (theMethod.Concurrency != null && theMethod.Concurrency.Length > 0 && !theMethod.Concurrency.StartsWith("Sequential") )
1219
                     {
1220
                        sb.Append("\n");
1221
                        sb.Append(theMethod.Concurrency);
1222
                     }
2094 ghuddy 1223
 
2116 ghuddy 1224
                     if (theMethod.IsConst)
1225
                        sb.Append("\nConst");
2094 ghuddy 1226
 
2116 ghuddy 1227
                     if (theMethod.IsQuery)
1228
                        sb.Append("\nIs Querry (does not alter class variables)");
2094 ghuddy 1229
 
2116 ghuddy 1230
                     if (theMethod.IsLeaf)
1231
                        sb.Append("\nIs Leaf (cannot be overriden)");
2094 ghuddy 1232
 
2116 ghuddy 1233
                     if (theMethod.ReturnIsArray)
1234
                        sb.Append( "\nReturn value is an array" );
2094 ghuddy 1235
 
2116 ghuddy 1236
                     if (theMethod.Throws != null && theMethod.Throws.Length > 0)
1237
                     {
1238
                        sb.Append("\n");
1239
                        sb.Append( theMethod.Throws );
1240
                     }
2094 ghuddy 1241
 
2116 ghuddy 1242
                     if (sb.Length > 0)
1243
                     {
1244
                        wr = TextualContent.appendAndSelectText("Characteristics:", EA_Constants.styleName_Body1_Left_2_5cm_Italic);
2094 ghuddy 1245
 
2116 ghuddy 1246
                        wr = TextualContent.appendAndSelectText(sb.ToString(), EA_Constants.styleName_Body1_Left_3_5cm);
1247
                     }
2094 ghuddy 1248
                  }
1249
 
1250
                  // Parameter Descriptions
1251
                  if (theParams.Count > 0)
1252
                  {
2106 ghuddy 1253
                     wr = TextualContent.appendAndSelectText("Parameters:", EA_Constants.styleName_Body1_Left_2_5cm_Italic);
2094 ghuddy 1254
 
1255
                     foreach(EA.Parameter theParam in theParams)
1256
                     {
2106 ghuddy 1257
                        wr = TextualContent.appendAndSelectText( theParam.Name + "\t", EA_Constants.stylename_Parameter_Description);
2098 ghuddy 1258
                        // do notes in seperate step since we want to call the appendDescription() method which 
1259
                        // automatically alerts us to missing descriptions in the generated document.
2106 ghuddy 1260
                        wr = TextualContent.appendDescription( TextualContent.trimTrailingReturns(theParam.Notes), EA_Constants.stylename_Parameter_Description, true);
1261
 
1262
                        if (abortCreationThread)
1263
                           return;
2094 ghuddy 1264
                     }
1265
                  }
1266
               }
1267
            }
1268
         }
1269
      }
1270
 
1271
 
1272
      /// <summary>
1273
      /// This method serialises a class's attributes to the document. 
1274
      /// </summary>
1275
      /// <param name="theElement"></param>
1276
      /// <param name="recurse_level"></param>
1277
      private void generateAttributeContent( EA.Element theElement, int recurse_level )
1278
      {
1279
         recurse_level++;
1280
 
1281
         // Get all the attributes into an array list and sort them by their position in the class's
1282
         // attribute list (ie. sort order is determined by the Pos value in each attribute).
1283
         ArrayList theAttrs = new ArrayList();
1284
         foreach(EA.Attribute theAttr in theElement.Attributes)
1285
            theAttrs.Add( theAttr );
1286
         attributeSortByPos sorter = new attributeSortByPos();
1287
         theAttrs.Sort( sorter );
1288
 
1289
         // TODO
1290
         // filter out attributes with certain characteristics?
1291
         // eg. Users may only want to document public and protected attributes.
1292
 
1293
         int numAttrsRemaining = 0;
1294
         foreach(EA.Attribute theAttr in theAttrs)
1295
         {
2106 ghuddy 1296
            if (abortCreationThread)
1297
               return;
1298
 
2116 ghuddy 1299
            if (EA_DocGenOptions.optionValue(EA_DocGenOptions.boolean_options_e.SUPPRESS_PRIVATE_ATTRIBUTES) == false
2094 ghuddy 1300
               || !theAttr.Visibility.StartsWith("Private"))
1301
               numAttrsRemaining++;
1302
         }
1303
 
1304
         if (numAttrsRemaining > 0)
1305
         {
1306
            StringBuilder sb = new StringBuilder();
1307
 
1308
            sb.Append( theElement.Name );
1309
            sb.Append( " Attributes" );
2106 ghuddy 1310
            TextualContent.appendAndSelectHeadingText(sb.ToString(), recurse_level);
2094 ghuddy 1311
 
1312
            // serialise the attributes to the document.
1313
            foreach(EA.Attribute theAttr in theAttrs)
1314
            {
2106 ghuddy 1315
               if (abortCreationThread)
1316
                  return;
1317
 
2116 ghuddy 1318
               if (EA_DocGenOptions.optionValue(EA_DocGenOptions.boolean_options_e.SUPPRESS_PRIVATE_ATTRIBUTES) == false
2094 ghuddy 1319
                  || !theAttr.Visibility.StartsWith("Private"))
1320
               {
1321
                  // Begin to build content string for the "Attribute" table column 
1322
                  sb = new StringBuilder();
1323
 
1324
                  // <type> <name>
1325
                  sb.Append("\n");
1326
                  sb.Append(theAttr.Type);
1327
                  sb.Append(" ");
1328
                  sb.Append(theAttr.Name);
2106 ghuddy 1329
                  Word.Range wr = TextualContent.appendAndSelectText(sb.ToString(), EA_Constants.styleName_Body1);
2110 ghuddy 1330
                  if (wr.Characters.Last.Text.Equals("\r"))
1331
                     wr.End = wr.End - 1;   // Dont boldise the \r paragraph marker
2094 ghuddy 1332
                  wr.Font.Bold = 1;
1333
 
2106 ghuddy 1334
                  wr = TextualContent.appendDescription(TextualContent.trimTrailingReturns(theAttr.Notes));
2094 ghuddy 1335
                  wr.ParagraphFormat.LeftIndent = WordApp.CentimetersToPoints((float)3.5);
1336
 
2116 ghuddy 1337
                  if (EA_DocGenOptions.optionValue(EA_DocGenOptions.boolean_options_e.SUPPRESS_ATTRIBUTE_CHARACTERISTICS) == false)
1338
                  {
1339
                     // The approach here is to display as much of the attribute as we can but try to keep the output
1340
                     // uncluttered by omitting items the user has not set via the EA GUI.
2094 ghuddy 1341
 
2116 ghuddy 1342
                     // Begin to build content string for the attribute characteristics
1343
                     sb = new StringBuilder();
2094 ghuddy 1344
 
2116 ghuddy 1345
                     sb.Append(theAttr.Visibility);
1346
                     sb.Append("\n");
2094 ghuddy 1347
 
2116 ghuddy 1348
                     if (theAttr.IsConst)
1349
                        sb.Append("Constant\n");
2094 ghuddy 1350
 
2116 ghuddy 1351
                     if (theAttr.IsStatic)
1352
                        sb.Append("Static\n");
2094 ghuddy 1353
 
2116 ghuddy 1354
                     if (theAttr.IsDerived)
1355
                        sb.Append("Derived\n");
2094 ghuddy 1356
 
2116 ghuddy 1357
                     if (theAttr.IsOrdered)
1358
                     {
1359
                        sb.Append("Is Ordered\n");
1360
                     }
2094 ghuddy 1361
 
2116 ghuddy 1362
                     if (theAttr.IsCollection)
1363
                     {
1364
                        sb.Append("Is A Collection\n");
1365
                     }
2094 ghuddy 1366
 
2116 ghuddy 1367
                     if (theAttr.Length.Length > 0 && System.Convert.ToInt32(theAttr.Length) > 0)
1368
                     {
1369
                        sb.Append("Length = ");
1370
                        sb.Append(theAttr.Length);
1371
                        sb.Append("\n");
1372
                     }
2094 ghuddy 1373
 
2116 ghuddy 1374
                     if (!theAttr.Containment.StartsWith("Not Specified"))
1375
                     {
1376
                        sb.Append("Containment =");
1377
                        sb.Append(theAttr.Containment);
1378
                        sb.Append("\n");
1379
                     }
2094 ghuddy 1380
 
2116 ghuddy 1381
                     if (theAttr.Container.Length > 0)
1382
                     {
1383
                        sb.Append("Container Type = ");
1384
                        sb.Append(theAttr.Container);
1385
                        sb.Append("\n");
1386
                     }
2094 ghuddy 1387
 
2116 ghuddy 1388
                     if (theAttr.Style.Length > 0)
1389
                     {
1390
                        sb.Append("Style = ");
1391
                        sb.Append(theAttr.Style);
1392
                        sb.Append("\n");
1393
                     }
2094 ghuddy 1394
 
2116 ghuddy 1395
                     if (  System.Convert.ToInt32(theAttr.LowerBound) > 1
1396
                        || System.Convert.ToInt32(theAttr.UpperBound) > 1)
1397
                     {
1398
                        sb.Append("Multiplicity [");
1399
                        sb.Append(theAttr.LowerBound);
1400
                        sb.Append("..");
1401
                        sb.Append(theAttr.UpperBound);
1402
                        sb.Append("]\n");
1403
                     }
2094 ghuddy 1404
 
2116 ghuddy 1405
                     if (theAttr.Scale.Length > 0 && System.Convert.ToInt32(theAttr.Scale) > 0)
1406
                     {
1407
                        sb.Append("Scale = ");
1408
                        sb.Append(theAttr.Scale);
1409
                        sb.Append( "\n" );
1410
                     }
1411
                     if (theAttr.Precision.Length > 0 && System.Convert.ToInt32(theAttr.Precision) > 0)
1412
                     {
1413
                        sb.Append("Precision = ");
1414
                        sb.Append(theAttr.Precision);
1415
                        sb.Append( "\n" );
1416
                     }
2094 ghuddy 1417
 
2116 ghuddy 1418
                     if (theAttr.Default.Length > 0)
1419
                     {
1420
                        sb.Append("Default Value = ");
1421
                        sb.Append(theAttr.Default);
1422
                        sb.Append( "\n" );
1423
                     }
2094 ghuddy 1424
 
2116 ghuddy 1425
                     // Now look at the constraint and tagged value collections and add any found info to the
1426
                     // right hand column
1427
                     short i;
1428
                     for(i=0; i<theAttr.Constraints.Count; i++)
1429
                     {
1430
                        if (abortCreationThread)
1431
                           return;
2106 ghuddy 1432
 
2116 ghuddy 1433
                        EA.AttributeConstraint theCons = (EA.AttributeConstraint)theAttr.Constraints.GetAt(i);
1434
                        sb.Append( theCons.Type );
1435
                        sb.Append( ": {" );
1436
                        sb.Append( theCons.Name );
1437
                        sb.Append( "}\n" );
1438
                        //sb.Append( theCons.Notes  );
1439
                        //sb.Append( "\n" );
1440
                     }
2094 ghuddy 1441
 
2116 ghuddy 1442
                     for(i=0; i<theAttr.TaggedValues.Count; i++)
1443
                     {
1444
                        if (abortCreationThread)
1445
                           return;
2106 ghuddy 1446
 
2116 ghuddy 1447
                        EA.AttributeTag theTag = (EA.AttributeTag)theAttr.TaggedValues.GetAt(i);
1448
                        sb.Append( "[" );
1449
                        sb.Append( theTag.Name );
1450
                        sb.Append( "="  );
1451
                        sb.Append( theTag.Value );
1452
                        sb.Append( "]\n" );
1453
                        //sb.Append( theTag.Notes );
1454
                        //sb.Append( "\n" );
1455
                     }
2094 ghuddy 1456
 
2116 ghuddy 1457
                     if (sb.Length > 0)
1458
                     {
1459
                        // remove the trailing "\n"
1460
                        sb.Remove( sb.ToString().Length - 1, 1);
2094 ghuddy 1461
 
2116 ghuddy 1462
                        wr = TextualContent.appendAndSelectText("Characteristics:", EA_Constants.styleName_Body1_Left_3_5cm_Italic);
2094 ghuddy 1463
 
2116 ghuddy 1464
                        wr = TextualContent.appendAndSelectText(sb.ToString(), EA_Constants.styleName_Body1_Left_4_5cm);
1465
                     }
2094 ghuddy 1466
                  }
1467
 
1468
                  numAttrsRemaining--;
1469
               }
1470
            }
1471
         }
1472
      }
1473
 
1474
 
1475
      private void generateClassCharacteristics( EA.Element theElement, int recurse_level )
1476
      {
2116 ghuddy 1477
         StringBuilder sb = null;
1478
         Word.Range wr = null;
2094 ghuddy 1479
 
2116 ghuddy 1480
         // CHARACTERISTICS
1481
         if (EA_DocGenOptions.optionValue(EA_DocGenOptions.boolean_options_e.SUPPRESS_CLASS_CHARACTERISTICS) == false)
2104 ghuddy 1482
         {
2116 ghuddy 1483
            sb = new StringBuilder();
2094 ghuddy 1484
 
2116 ghuddy 1485
            sb.Append( "Characteristics:" );
1486
            wr = TextualContent.appendAndSelectText(sb.ToString(), EA_Constants.styleName_Body1_Left_2_5cm_Italic);
1487
 
1488
            sb = new StringBuilder();
1489
            // VISIBILITY
1490
            sb.Append( theElement.Visibility );
1491
            // ABSTRACT
1492
            if (System.Convert.ToInt32(theElement.Abstract) == 1)
1493
               sb.Append( "\nAbstract" );
1494
            // STEREOTYPES
1495
            if (theElement.StereotypeEx.Length > 0)
1496
            {
1497
               sb.Append("\nStereotypes: ");
1498
               sb.Append(theElement.StereotypeEx);
1499
            }
1500
            // MULTIPLICITY
1501
            if (theElement.Multiplicity.Length > 0)
1502
            {
1503
               sb.Append("\nMultiplicity: ");
1504
               sb.Append(theElement.Multiplicity);
1505
            }
1506
            // IS ACTIVE
1507
            if (theElement.IsActive)
1508
               sb.Append("\nClass is active (has its own thread of control)\n");
1509
            // IS SPEC
1510
            if (theElement.IsSpec)
1511
               sb.Append("\nClass is a specification\n");
2104 ghuddy 1512
 
2116 ghuddy 1513
            wr = TextualContent.appendAndSelectText(sb.ToString(), EA_Constants.styleName_Body1_Left_3_5cm);
2094 ghuddy 1514
         }
2116 ghuddy 1515
 
1516
         // BASE CLASSES
1517
         if (EA_DocGenOptions.optionValue(EA_DocGenOptions.boolean_options_e.SUPPRESS_CLASS_BASE_CLASSES) == false)
2094 ghuddy 1518
         {
2116 ghuddy 1519
            sb = new StringBuilder();
1520
            foreach(EA.Element baseClass in theElement.BaseClasses)
1521
            {
1522
               sb.Append( baseClass.Name);
1523
            }
1524
            if (sb.Length > 0)
1525
            {
1526
               wr = TextualContent.appendAndSelectText("Base Class(es):", EA_Constants.styleName_Body1_Left_2_5cm_Italic);
2088 ghuddy 1527
 
2116 ghuddy 1528
               wr = TextualContent.appendAndSelectText(sb.ToString(), EA_Constants.styleName_Body1_Left_3_5cm);
1529
            }
2094 ghuddy 1530
         }
1531
 
2116 ghuddy 1532
         // REALISES
1533
         if (EA_DocGenOptions.optionValue(EA_DocGenOptions.boolean_options_e.SUPPRESS_CLASS_REALISES) == false)
2094 ghuddy 1534
         {
2116 ghuddy 1535
            sb = new StringBuilder();
1536
            foreach(EA.Element intf in theElement.Realizes)
1537
            {
1538
               sb.Append( intf.Name);
1539
            }
1540
            if (sb.Length > 0)
1541
            {
1542
               wr = TextualContent.appendAndSelectText("Realises:", EA_Constants.styleName_Body1_Left_2_5cm_Italic);
2094 ghuddy 1543
 
2116 ghuddy 1544
               wr = TextualContent.appendAndSelectText(sb.ToString(), EA_Constants.styleName_Body1_Left_3_5cm);
1545
            }
2094 ghuddy 1546
         }
1547
      }
1548
 
1549
 
1550
      private void generateClassRequirements( EA.Element theElement, int recurse_level )
1551
      {
2116 ghuddy 1552
         if (EA_DocGenOptions.optionValue(EA_DocGenOptions.boolean_options_e.SUPPRESS_CLASS_REQUIREMENTS) == false)
1553
         {
1554
            StringBuilder sb = new StringBuilder();
2094 ghuddy 1555
 
2116 ghuddy 1556
            sb.Append( "Requirements:" );
1557
            Word.Range wr = TextualContent.appendAndSelectText(sb.ToString(), EA_Constants.styleName_Body1_Left_2_5cm_Italic);
2094 ghuddy 1558
 
2116 ghuddy 1559
            foreach(EA.Requirement theReq in theElement.Requirements)
1560
            {
1561
               if (abortCreationThread)
1562
                  return;
2106 ghuddy 1563
 
2116 ghuddy 1564
               sb = new StringBuilder();
1565
               sb.Append( theReq.Name );
1566
               wr = TextualContent.appendAndSelectText(sb.ToString(), EA_Constants.styleName_Body1_Left_3_5cm);
1567
               sb = new StringBuilder();
1568
               sb.Append( theReq.Notes );
1569
               if (sb.Length > 0)
1570
               {
1571
                  wr = TextualContent.appendAndSelectText(sb.ToString(), EA_Constants.styleName_Body1_Left_4_5cm);
1572
               }
2088 ghuddy 1573
            }
2094 ghuddy 1574
         }
1575
      }
1576
 
1577
 
1578
      private void generateClassConstraints( EA.Element theElement, int recurse_level )
1579
      {
2116 ghuddy 1580
         if (EA_DocGenOptions.optionValue(EA_DocGenOptions.boolean_options_e.SUPPRESS_CLASS_CONSTRAINTS) == false)
1581
         {
1582
            StringBuilder sb = new StringBuilder();
2094 ghuddy 1583
 
2116 ghuddy 1584
            sb.Append( "Constraints:" );
1585
            Word.Range wr = TextualContent.appendAndSelectText(sb.ToString(), EA_Constants.styleName_Body1_Left_2_5cm_Italic);
2094 ghuddy 1586
 
2116 ghuddy 1587
            foreach(EA.Constraint theCons in theElement.Constraints)
1588
            {
1589
               if (abortCreationThread)
1590
                  return;
2106 ghuddy 1591
 
2116 ghuddy 1592
               sb = new StringBuilder();
1593
               sb.Append( theCons.Type );
1594
               sb.Append( ": {" );
1595
               sb.Append( theCons.Name );
1596
               sb.Append( "}" );
2094 ghuddy 1597
 
2116 ghuddy 1598
               wr = TextualContent.appendAndSelectText(sb.ToString(), EA_Constants.styleName_Body1_Left_3_5cm);
2094 ghuddy 1599
 
2116 ghuddy 1600
               if (theCons.Notes.Length > 0)
1601
               {
1602
                  sb = new StringBuilder();
1603
                  sb.Append( theCons.Notes );
1604
                  wr = TextualContent.appendAndSelectText(sb.ToString(), EA_Constants.styleName_Body1_Left_4_5cm);
1605
               }
2094 ghuddy 1606
            }
1607
         }
1608
      }
1609
 
1610
 
2104 ghuddy 1611
      private bool generateElementContent( EA.Element theElement, int recurse_level )
2094 ghuddy 1612
      {
2104 ghuddy 1613
         bool allowSubElementParsing = true;  // return value for the function
1614
 
2094 ghuddy 1615
         // track recursion level to control heading style formatting requirements
1616
         if (oneShot_skipRootElementHeading == false)
1617
            recurse_level++;
1618
 
2106 ghuddy 1619
         if (EA_DocGenOptions.elementTypeFoundInEA_DocGen( theElement.Type ))
2094 ghuddy 1620
         {
1621
            // pass the element to the requirement element serialisation function. It
1622
            // will tell us if it did anything with it. If not, then carry out the default
1623
            // element serialisation.
2106 ghuddy 1624
            if (false == TextualContent.generateRequirementText(theElement))
2094 ghuddy 1625
            {
1626
               bool isClass = theElement.Type.StartsWith("Class");
1627
 
2104 ghuddy 1628
               if (   (   true == isClass
2116 ghuddy 1629
                       && true == EA_DocGenOptions.optionValue(EA_DocGenOptions.boolean_options_e.SUPPRESS_PRIVATE_CLASSES) 
2104 ghuddy 1630
                       && true == theElement.Visibility.StartsWith("Private"))
2116 ghuddy 1631
                   || (   true == EA_DocGenOptions.optionValue(EA_DocGenOptions.boolean_options_e.CONSIDER_API_ELEMENTS_ONLY) 
2104 ghuddy 1632
                       && 0 > theElement.StereotypeEx.IndexOf("API"))
1633
                  )
2088 ghuddy 1634
               {
2094 ghuddy 1635
                  // do nothing
2106 ghuddy 1636
                  DocSectionTracking.trackDocSection(recurse_level);
2104 ghuddy 1637
                  displayProgress( "SKIPPED: ", theElement.Name );
1638
                  allowSubElementParsing = false;
2088 ghuddy 1639
               }
1640
               else
2094 ghuddy 1641
               {
1642
                  // disarm the one-shot element (heading) skipping feature if it was armed, and 
1643
                  // by-pass the code to generate a new heading level for the element
1644
                  if (oneShot_skipRootElementHeading == false)
1645
                  {
1646
                     // Default element serialisation
2106 ghuddy 1647
                     TextualContent.appendAndSelectHeadingText( theElement.Name, recurse_level );
2094 ghuddy 1648
                  }
1649
                  else
1650
                  {
1651
                     oneShot_skipRootElementHeading = false;
1652
                  }
1653
 
2104 ghuddy 1654
                  processedElements.Add(theElement.ElementID);
1655
                  displayProgress( "ELEMENT: ", theElement.Name );
1656
 
2106 ghuddy 1657
                  TextualContent.appendDescription( TextualContent.trimTrailingReturns(theElement.Notes) );
2094 ghuddy 1658
 
2102 ghuddy 1659
                  generateElementDiagrams(theElement);
1660
 
2094 ghuddy 1661
                  if (true == isClass)
1662
                  {
2104 ghuddy 1663
                     // accumulate unit testable classes.
1664
                     if (   theElement.StereotypeEx.IndexOf("API") >= 0
1665
                         && !theElement.Visibility.StartsWith("Private"))
2094 ghuddy 1666
                     {
2104 ghuddy 1667
                        classesNeedingUnitTests.Add( theElement.ElementID );
2094 ghuddy 1668
                     }
1669
 
2106 ghuddy 1670
                     if (!abortCreationThread)
1671
                        generateClassCharacteristics(theElement, recurse_level);
2094 ghuddy 1672
                  }
1673
 
1674
                  // Requirement collection
2106 ghuddy 1675
                  if (!abortCreationThread && theElement.Requirements.Count > 0)
2094 ghuddy 1676
                  {
1677
                     generateClassRequirements(theElement, recurse_level);
1678
                  }
1679
 
1680
                  // Constraint collection
2106 ghuddy 1681
                  if (!abortCreationThread && theElement.Constraints.Count > 0)
2094 ghuddy 1682
                  {
1683
                     generateClassConstraints(theElement, recurse_level);
1684
                  }
1685
 
2106 ghuddy 1686
                  if (!abortCreationThread && theElement.Issues.Count > 0)
2094 ghuddy 1687
                  {
1688
                  }
1689
 
1690
                  // Attribute collection
2106 ghuddy 1691
                  if (!abortCreationThread && theElement.Attributes.Count > 0)
2094 ghuddy 1692
                  {
1693
                     generateAttributeContent(theElement, recurse_level);
1694
                  }
1695
 
1696
                  // Method collection
2106 ghuddy 1697
                  if (!abortCreationThread && theElement.Methods.Count > 0)
2094 ghuddy 1698
                  {
1699
                     generateMethodContent(theElement, recurse_level);
1700
                  }
1701
               }
2088 ghuddy 1702
            }
2094 ghuddy 1703
            else
1704
            {
2104 ghuddy 1705
               processedElements.Add(theElement.ElementID);
2106 ghuddy 1706
               DocSectionTracking.trackDocSection(recurse_level);
2094 ghuddy 1707
               displayProgress( "ELEMENT: ", theElement.Name );
1708
            }
2088 ghuddy 1709
         }
1710
         else
1711
         {
2106 ghuddy 1712
            DocSectionTracking.trackDocSection(recurse_level);
2088 ghuddy 1713
            displayProgress( "FILTERED: ", theElement.Type );
1714
         }
1715
         // TODO
1716
         // We will probably have to put special code in here at some point for attributes
1717
         // of, and collections of things within elements. This will become apparent once
1718
         // someone tries to produce a design document where such things need to be included
1719
         // in the generated document. Lots of work needed here eventually.
1720
 
2094 ghuddy 1721
         // disarm element heading skip control
1722
         oneShot_skipRootElementHeading = false;
2104 ghuddy 1723
 
1724
         return allowSubElementParsing;
2088 ghuddy 1725
      }
1726
 
2094 ghuddy 1727
 
2088 ghuddy 1728
      /// <summary>
1729
      /// This function searches for the old content in the document in order to remove it
1730
      /// prior to adding in the new content from the latest EA model data.
1731
      /// </summary>
1732
      private void removeExistingDocumentContent()
1733
      {
1734
         //WordApp.Visible = true;  // enable this when debugging this horrible function
1735
         Word.Selection aSelection;
2106 ghuddy 1736
         object findStyle = StyleContent.getStyle( EA_Constants.styleName_Heading1 );
2088 ghuddy 1737
 
1738
         WordApp.Selection.WholeStory();
1739
         aSelection = WordApp.Selection;
1740
 
1741
         aSelection.Find.ClearFormatting();
1742
         aSelection.Find.set_Style( ref findStyle );
1743
         aSelection.Find.Text = "Introduction";
1744
         aSelection.Find.Replacement.Text = "";
1745
         aSelection.Find.Forward = true;
1746
         aSelection.Find.MatchCase = false;
1747
         aSelection.Find.MatchWholeWord = false;
1748
         aSelection.Find.MatchWildcards = false;
1749
         aSelection.Find.MatchSoundsLike = false;
1750
         aSelection.Find.MatchAllWordForms = false;
1751
 
1752
         object missingValue = Type.Missing;
1753
         if (aSelection.Find.Execute(ref missingValue, ref missingValue, 
1754
            ref missingValue, ref missingValue, ref missingValue, 
1755
            ref missingValue, ref missingValue, ref missingValue, 
1756
            ref missingValue, ref missingValue, ref missingValue, 
1757
            ref missingValue, ref missingValue, ref missingValue, 
1758
            ref missingValue)) 
1759
         { 
1760
            // found Introduction with Heading 1 style so we are now at the point in the 
1761
            // document where everything here on must be deleted in readiness for the newly
1762
            // generated content. Extend the range to the end of the document and cut out the
1763
            // old content.
1764
            Word.Range range = aSelection.Range;
1765
            range.End = WordDocument.Content.End;
1766
            range.Cut();
2092 ghuddy 1767
            // try and ensure that no heading style is left in place following the removal
2094 ghuddy 1768
            object style = EA_Constants.styleName_Body1;
2092 ghuddy 1769
            range.set_Style(ref style);
2088 ghuddy 1770
         }
1771
      }
1772
 
1773
 
1774
      /// <summary>
1775
      /// Parses an element (because elements can contain sub-elements).
1776
      /// This is also the function that identifies the occurrences of the special
1777
      /// EA_DocGenXXX elements.
1778
      /// </summary>
1779
      /// <param name="theElement"></param>
1780
      /// <param name="recurse_level"></param>
1781
      private void parse_element(EA.Element theElement, int recurse_level)
1782
      {
2106 ghuddy 1783
         if (abortCreationThread)
1784
            return;
1785
 
2088 ghuddy 1786
         // First look for and handle special elements that control the doc-gen process
1787
 
1788
         // The EA_DocGenPackageLink can contain a list of GUIDs in its notes section
1789
         // that point to model structure outside of the localised structure forming the
1790
         // document. This enables a document to grab content from other external models
1791
         // as long as they are loaded into the repository.
2094 ghuddy 1792
         if (theElement.Name.StartsWith(EA_Constants.EA_DocGenPackageLink))
2088 ghuddy 1793
         {
2104 ghuddy 1794
            processingLink++;
2088 ghuddy 1795
            processPackageLink( theElement, recurse_level );
2104 ghuddy 1796
            processingLink--;
2088 ghuddy 1797
         }
1798
 
1799
            // The EA_DocGenDiagramLink can contain a list of GUIDs in its notes section
1800
            // that point to diagram elements anywhere in the repository.
2094 ghuddy 1801
         else if (theElement.Name.StartsWith(EA_Constants.EA_DocGenDiagramLink))
2088 ghuddy 1802
         {
2104 ghuddy 1803
            processingLink++;
2088 ghuddy 1804
            processDiagramLink( theElement );
2104 ghuddy 1805
            processingLink--;
2088 ghuddy 1806
         }
1807
 
1808
            // The EA_DocGenDiagramLink can contain a list of GUIDs in its notes section
1809
            // that point to diagram elements anywhere in the repository.
2094 ghuddy 1810
         else if (theElement.Name.StartsWith(EA_Constants.EA_DocGenElementLink))
2088 ghuddy 1811
         {
2104 ghuddy 1812
            processingLink++;
2088 ghuddy 1813
            processElementLink( theElement, recurse_level );
2104 ghuddy 1814
            processingLink--;
2088 ghuddy 1815
         }
1816
 
1817
            // The EA_DocGenTable element can contain table content in its notes section
1818
            // and must be dealt with in a special way.
2094 ghuddy 1819
         else if (theElement.Name.StartsWith(EA_Constants.EA_DocGenTable))
2088 ghuddy 1820
         {
2106 ghuddy 1821
            TabularContent.processTableElement(theElement, recurse_level);
2088 ghuddy 1822
         }
1823
 
1824
            // The EA_DocGenText element can contain text content in its notes section
1825
            // that must be appended to the doc in Body 1 style within the current
1826
            // section.
2094 ghuddy 1827
         else if (theElement.Name.StartsWith(EA_Constants.EA_DocGenText))
2088 ghuddy 1828
         {
2106 ghuddy 1829
            TextualContent.appendAndSelectText( TextualContent.trimTrailingReturns(theElement.Notes), EA_Constants.styleName_Body1 );
2088 ghuddy 1830
         }
1831
 
2094 ghuddy 1832
         else if (theElement.Name.StartsWith(EA_Constants.EA_DocGenRelationshipMatrix))
2088 ghuddy 1833
         {
2106 ghuddy 1834
            EA_RelationshipMatrix.initialise(processedElements);
1835
            if (EA_RelationshipMatrix.processRelationshipMatrixOptions( theElement ))
2104 ghuddy 1836
            {
2106 ghuddy 1837
               EA_RelationshipMatrix.processRelationshipMatrixElement( theElement, recurse_level );
2104 ghuddy 1838
            }
2088 ghuddy 1839
         }
1840
 
2094 ghuddy 1841
         else if (theElement.Name.StartsWith(EA_Constants.EA_DocGenTestLink))
2088 ghuddy 1842
         {
2104 ghuddy 1843
            processingLink++;
2094 ghuddy 1844
            processTestLink( theElement, recurse_level );
2104 ghuddy 1845
            processingLink--;
2094 ghuddy 1846
         }
1847
 
1848
         else if (theElement.Name.StartsWith(EA_Constants.EA_DocGenTestTraceability))
1849
         {
1850
            processTestTraceability( theElement, recurse_level );
1851
         }
1852
 
2104 ghuddy 1853
         else if (theElement.Name.StartsWith(EA_Constants.EA_DocGenNameLink))
1854
         {
1855
            processingLink++;
1856
            processNameLink( theElement, recurse_level );
1857
            processingLink--;
1858
         }
2094 ghuddy 1859
 
2104 ghuddy 1860
            // we are aware of the other ERG EA add-in, EA_ReqPro! That add-in creates 
2094 ghuddy 1861
            // ReqProDB stereotyped elements. Never consume them in the document generation process.
2104 ghuddy 1862
         else if (0 > theElement.StereotypeEx.IndexOf(EA_Constants.stereotype_ReqProDB))
2094 ghuddy 1863
         {
2104 ghuddy 1864
            bool allowSubElementParsing = generateElementContent( theElement, recurse_level );
1865
            if (allowSubElementParsing)
1866
            {
1867
               // Look at this elements sub-elements
1868
               foreach(EA.Element subElement in theElement.Elements)
1869
               {
2106 ghuddy 1870
                  if (abortCreationThread)
1871
                     return;
1872
 
2104 ghuddy 1873
                  parse_element(subElement, recurse_level+1);
1874
               }
1875
            }
2102 ghuddy 1876
         }   
2088 ghuddy 1877
      }
1878
 
1879
 
1880
      /// <summary>
1881
      /// Parses the package and all of its content, extracting information as needed, and
1882
      /// adding it to the word document. This method is recursive, since recursion is the
1883
      /// easiest way to walk thru' the package levels in the model.
1884
      /// </summary>
1885
      /// <param name="parentPackage"></param>
1886
      /// <param name="recurse_level"></param>
1887
      private void parse_package(EA.Package thePackage, int recurse_level)
1888
      {
2106 ghuddy 1889
         if (abortCreationThread)
1890
            return;
1891
 
2088 ghuddy 1892
         // track recursion level to control heading style formatting requirements
1893
         // The one-shot skiproot feature of the EA_DocGenPackageLink element handling has an effect
1894
         // here, as you can see. 
1895
         bool rootPackageWasSkipped = !oneShot_skipRootPackage;
1896
         if (oneShot_skipRootPackage == false)
1897
         {
1898
            recurse_level++;
1899
         }
1900
 
2104 ghuddy 1901
         // determine if the package has an API stereotype
1902
         bool packageHasAPIStereotype = false;
1903
         if (0 <= thePackage.StereotypeEx.IndexOf("API") )
1904
            packageHasAPIStereotype = true;
2088 ghuddy 1905
 
2104 ghuddy 1906
         // only process the package if it the stereotype allows, or sensitivity to the stereotype is disabled
2116 ghuddy 1907
         if (  !EA_DocGenOptions.optionValue(EA_DocGenOptions.boolean_options_e.CONSIDER_API_PACKAGES_ONLY)
1908
            || (   EA_DocGenOptions.optionValue(EA_DocGenOptions.boolean_options_e.CONSIDER_API_PACKAGES_ONLY)
1909
                && EA_DocGenOptions.optionValue(EA_DocGenOptions.boolean_options_e.RESTRICT_FOR_LINKED_PACKAGES_ONLY) && processingLink == 0)
1910
            || (EA_DocGenOptions.optionValue(EA_DocGenOptions.boolean_options_e.CONSIDER_API_PACKAGES_ONLY) 
1911
                && packageHasAPIStereotype) 
2104 ghuddy 1912
            )
2094 ghuddy 1913
         {
2104 ghuddy 1914
 
1915
            bool processLowerLevelContent = true;
2094 ghuddy 1916
 
2104 ghuddy 1917
            // disarm the one-shot package skipping feature if it was armed
1918
            if (oneShot_skipRootPackage == true)
2102 ghuddy 1919
            {
2104 ghuddy 1920
               oneShot_skipRootPackage = false;
2102 ghuddy 1921
            }
2104 ghuddy 1922
            else
1923
            {
1924
               // Generate heading and description for the package. This function also takes care of some
1925
               // specially handled packages (terminology, references).
1926
               processLowerLevelContent = generatePackageHeadingAndDescription( thePackage, recurse_level );
1927
            }
2102 ghuddy 1928
 
2104 ghuddy 1929
            // generate package heading and description. This may, depending on the package name,
1930
            // consume the elements in the package. If it does not, then consume them (and any diagrams)
1931
            // locally here.
1932
            if (true == processLowerLevelContent)
1933
            {
1934
               // consume diagrams
1935
               generatePackageDiagrams( thePackage );
2088 ghuddy 1936
 
2104 ghuddy 1937
               foreach(EA.Element subElement in thePackage.Elements)
1938
               {
2106 ghuddy 1939
                  if (abortCreationThread)
1940
                     return;
1941
 
2104 ghuddy 1942
                  if (subElement.ParentID == 0 || thePackage.PackageID == subElement.ParentID)
1943
                     parse_element(subElement, recurse_level);
1944
               }
2088 ghuddy 1945
 
2104 ghuddy 1946
               // Scan through the sub-packages within this package.
1947
               foreach(EA.Package subPackage in thePackage.Packages)
1948
               {
2106 ghuddy 1949
                  if (abortCreationThread)
1950
                     return;
1951
 
2104 ghuddy 1952
                  // recurse
1953
                  parse_package(subPackage, recurse_level);
1954
               }
1955
            }
2088 ghuddy 1956
         }
2104 ghuddy 1957
         else
2088 ghuddy 1958
         {
2104 ghuddy 1959
            // disarm the one-shot package skipping feature if it was armed
1960
            if (oneShot_skipRootPackage == true)
1961
            {
1962
               oneShot_skipRootPackage = false;
1963
            }         
2088 ghuddy 1964
         }
1965
      }
1966
 
1967
 
1968
      /// <summary>
1969
      /// This is the overall generate document method. It creates a word document from 
1970
      /// an input template, sets various characteristics of the document, schedules the
1971
      /// EA parsing function, before finally saving the document to the output file name.
1972
      /// </summary>
1973
      private void createTheWordDoc()
1974
      {
2106 ghuddy 1975
         docGenCompletedNormally = false;
1976
         abortCreationThread = false;
1977
 
1978
         Main.threadCreateDocProcessRunning = true;
1979
 
1980
         // capture initial security settings
2092 ghuddy 1981
         MsoAutomationSecurity  securityBefore = WordApp.AutomationSecurity;
1982
 
2106 ghuddy 1983
         button_generate.Enabled = false;
1984
         button_browse_output_file.Enabled = false;
1985
         button_browse_template.Enabled = false;
1986
         textBox_output_file.Enabled = false;
1987
         textBox_template.Enabled = false;
1988
         checkBox_WordVisibility.Enabled = false;
1989
 
2088 ghuddy 1990
         try 
1991
         {
1992
            object template       = this.textBox_template.Text;
1993
            object newTemplate    = Type.Missing;
1994
            object outputFilename = this.textBox_output_file.Text;
1995
 
1996
            object docType = Type.Missing;
1997
            object visible = Type.Missing;
1998
            object nothing = Type.Missing;
1999
            object notTrue = false;
2000
 
2106 ghuddy 2001
            Main.EA_Repository.WriteOutput( Main.GUI_OUTPUT_TAB_NAME, "", 0);
2002
            Main.EA_Repository.WriteOutput( Main.GUI_OUTPUT_TAB_NAME, 
2088 ghuddy 2003
                                       String.Format( "Generating Document {0}", this.textBox_output_file.Text), 0 );
2004
 
2122 ghuddy 2005
            // control word visibility based on checkbox user can modify
2088 ghuddy 2006
            WordApp.Visible = this.checkBox_WordVisibility.Checked;
2092 ghuddy 2007
 
2008
            // disable VB macros from running in the document
2009
            WordApp.AutomationSecurity = MsoAutomationSecurity.msoAutomationSecurityForceDisable;
2010
            WordApp.DisplayAlerts = Word.WdAlertLevel.wdAlertsNone;
2011
 
2088 ghuddy 2012
            // Create a document from the input template
2106 ghuddy 2013
            Main.EA_Repository.WriteOutput(Main.GUI_OUTPUT_TAB_NAME, "Creating new document based on template", -1);
2088 ghuddy 2014
            WordDocument = WordApp.Documents.Add(ref template, ref newTemplate, ref docType, ref visible);
2106 ghuddy 2015
 
2088 ghuddy 2016
 
2017
            // Remove all old content from the input document/template. Note that this assumes
2018
            // that content will begin at section 1 with the title "Introduction" and it will have
2019
            // "Heading 1" style.
2106 ghuddy 2020
            if (!abortCreationThread)
2021
            {
2022
               Main.EA_Repository.WriteOutput(Main.GUI_OUTPUT_TAB_NAME, "Removing existing content (if any)", -1);
2023
               removeExistingDocumentContent();
2024
            }
2088 ghuddy 2025
 
2026
            // turn off grammar and spell checking
2027
            WordDocument.GrammarChecked = false;
2028
            WordDocument.SpellingChecked = false;
2029
 
2094 ghuddy 2030
            // arm the public class list accumulator.
2104 ghuddy 2031
            classesNeedingUnitTests = new ArrayList();
2094 ghuddy 2032
            classesWithUnitTests = new ArrayList();
2033
 
2104 ghuddy 2034
            processingLink = 0;
2035
 
2036
            processedElements = new ArrayList();
2037
 
2092 ghuddy 2038
            // If the input template does not contain the styles needed for requirement documents, 
2039
            // programmatically create them just in case.
2106 ghuddy 2040
            if (!abortCreationThread)
2041
            {
2042
               Main.EA_Repository.WriteOutput(Main.GUI_OUTPUT_TAB_NAME, "Creating Requirement Styles", -1);
2043
               StyleContent.createRequirementStyles();
2044
            }
2045
            if (!abortCreationThread)
2046
            {
2047
               Main.EA_Repository.WriteOutput(Main.GUI_OUTPUT_TAB_NAME, "Creating Additional Heading Styles", -1);
2048
               StyleContent.createAdditionalHeadingLevelStyles();
2049
            }
2050
            if (!abortCreationThread)
2051
            {
2052
               Main.EA_Repository.WriteOutput(Main.GUI_OUTPUT_TAB_NAME, "Creating Element Detail Styles", -1);
2053
               StyleContent.createElementDetailsStyles();
2054
            }
2055
            if (!abortCreationThread)
2056
            {
2057
               Main.EA_Repository.WriteOutput(Main.GUI_OUTPUT_TAB_NAME, "Correcting known problems in ERG template styles", -1);
2058
               StyleContent.correctErrorsInTemplateStyles();
2059
            }
2098 ghuddy 2060
 
2088 ghuddy 2061
            // Parse EA_DocGen Document Model. The parent package is the document model itself
2062
            // and the packages within it are the top level packages only.
2063
            // Question: do we have to parse diagrams and elements at this top level? So far,
2064
            // this has been found to be unecessary, but you never know. For now, dont do it.
2106 ghuddy 2065
            if (!abortCreationThread)
2088 ghuddy 2066
            {
2106 ghuddy 2067
               Main.EA_Repository.WriteOutput(Main.GUI_OUTPUT_TAB_NAME, "Generating new content", -1);
2068
 
2069
               foreach(EA.Package thePackage in EA_ParentPackage.Packages)
2070
               {
2071
                  parse_package(thePackage, 0);
2072
                  if (abortCreationThread)
2073
                     break;
2074
               }
2088 ghuddy 2075
            }
2094 ghuddy 2076
            // for design docs, a user may have used the test traceability element in their document model,
2077
            // which means that now we are finished with parse 1 of the document, we can complete the traceability
2078
            // table (if any) that was begun when that special element was first encountered.
2106 ghuddy 2079
            if (!abortCreationThread)
2080
            {
2081
               completeTestTraceability();
2088 ghuddy 2082
 
2106 ghuddy 2083
               // Save the document to the output file before we try and update the fields. This is because
2084
               // I have seen Fields.Update() fail on a few occasions and it is very annoying
2085
               // to lose what has thus far been generated.
2086
               WordDocument.SaveAs( ref outputFilename, 
2087
                  ref nothing, ref nothing, ref nothing, ref nothing, 
2088
                  ref nothing, ref nothing, ref nothing, ref nothing,
2089
                  ref nothing, ref nothing, ref nothing, ref nothing,
2090
                  ref nothing, ref nothing, ref nothing);
2088 ghuddy 2091
 
2106 ghuddy 2092
               object noSave = Word.WdSaveOptions.wdDoNotSaveChanges;
2093
               object format = Word.WdOriginalFormat.wdWordDocument;
2094
               WordDocument.Close(ref noSave, ref format, ref nothing);
2094 ghuddy 2095
 
2106 ghuddy 2096
               if (!abortCreationThread)
2097
               {
2098
                  Main.EA_Repository.WriteOutput(Main.GUI_OUTPUT_TAB_NAME, "Updating Fields and Saving Document", -1);
2099
                  // Re-load the document to update the fields. For some as yet unknown reason, doing this 
2100
                  // sometimes fails, but by doing it in a re-loaded instance of the word document
2101
                  // the failures seem to be reduced.
2102
                  WordDocument = WordApp.Documents.Add(ref outputFilename, ref newTemplate, ref docType, ref visible);
2103
                  WordDocument.Fields.Update();
2104
                  WordDocument.SaveAs( ref outputFilename, 
2105
                     ref nothing, ref nothing, ref nothing, ref nothing, 
2106
                     ref nothing, ref nothing, ref nothing, ref nothing,
2107
                     ref nothing, ref nothing, ref nothing, ref nothing,
2108
                     ref nothing, ref nothing, ref nothing);
2088 ghuddy 2109
 
2106 ghuddy 2110
                  // Tell user the process completed ok
2111
                  Main.EA_Repository.WriteOutput(Main.GUI_OUTPUT_TAB_NAME, "Document Generation Complete", -1);
2112
                  docGenCompletedNormally = true;
2113
                  button_view_output.Enabled = true;
2114
               }
2115
            }
2116
            else
2117
            {
2118
               Main.EA_Repository.WriteOutput(Main.GUI_OUTPUT_TAB_NAME, "Document Generation Aborted", -1);
2119
               MessageBox.Show("Document Generation Aborted");
2120
            }
2098 ghuddy 2121
 
2088 ghuddy 2122
         }
2123
         catch (Exception createTheWordDoc_exception)
2124
         {
2110 ghuddy 2125
            Main.ShowException(createTheWordDoc_exception, "Document Generation Failed");
2088 ghuddy 2126
         }
2092 ghuddy 2127
 
2128
         // restore security settings
2129
         WordApp.AutomationSecurity = securityBefore;
2106 ghuddy 2130
 
2131
         // issue the generation complete message box as close to the end of the thread as possible so that
2132
         // there is less of a chance that a user pressing the close button will see a "cancel generation"
2133
         // warning box.
2134
         if (docGenCompletedNormally)
2135
            MessageBox.Show("Document Generation Complete");
2136
 
2137
         // we can mark the thread as not running since from now on we do not want to do anything with the 
2138
         // WordApp or WordDocument objects and their destruction wont cause any ill effects.
2139
         Main.threadCreateDocProcessRunning = false;
2140
 
2141
         if (mustClose)
2142
            this.Close();
2088 ghuddy 2143
      }
2144
 
2092 ghuddy 2145
 
2146
 
2147
 
2088 ghuddy 2148
      #endregion
2106 ghuddy 2149
 
2150
 
2151
 
2152
 
2088 ghuddy 2153
   }
2154
}