Subversion Repositories DevTools

Rev

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