Subversion Repositories DevTools

Rev

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