Subversion Repositories DevTools

Rev

Rev 2106 | Rev 2110 | 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);
2094 ghuddy 1332
                  wr.Font.Bold = 1;
1333
 
2106 ghuddy 1334
                  wr = TextualContent.appendDescription(TextualContent.trimTrailingReturns(theAttr.Notes));
2094 ghuddy 1335
                  wr.ParagraphFormat.LeftIndent = WordApp.CentimetersToPoints((float)3.5);
1336
 
1337
                  // The approach here is to display as much of the attribute as we can but try to keep the output
1338
                  // uncluttered by omitting items the user has not set via the EA GUI.
1339
 
1340
                  // Begin to build content string for the "Other Information" table cell
1341
                  sb = new StringBuilder();
1342
 
1343
                  sb.Append(theAttr.Visibility);
1344
                  sb.Append("\n");
1345
 
1346
                  if (theAttr.IsConst)
1347
                     sb.Append("Constant\n");
1348
 
1349
                  if (theAttr.IsStatic)
1350
                     sb.Append("Static\n");
1351
 
1352
                  if (theAttr.IsDerived)
1353
                     sb.Append("Derived\n");
1354
 
1355
                  if (theAttr.IsOrdered)
1356
                  {
1357
                     sb.Append("Is Ordered\n");
1358
                  }
1359
 
1360
                  if (theAttr.IsCollection)
1361
                  {
1362
                     sb.Append("Is A Collection\n");
1363
                  }
1364
 
1365
                  if (theAttr.Length.Length > 0 && System.Convert.ToInt32(theAttr.Length) > 0)
1366
                  {
1367
                     sb.Append("Length = ");
1368
                     sb.Append(theAttr.Length);
1369
                     sb.Append("\n");
1370
                  }
1371
 
1372
                  if (!theAttr.Containment.StartsWith("Not Specified"))
1373
                  {
1374
                     sb.Append("Containment =");
1375
                     sb.Append(theAttr.Containment);
1376
                     sb.Append("\n");
1377
                  }
1378
 
1379
                  if (theAttr.Container.Length > 0)
1380
                  {
1381
                     sb.Append("Container Type = ");
1382
                     sb.Append(theAttr.Container);
1383
                     sb.Append("\n");
1384
                  }
1385
 
1386
                  if (theAttr.Style.Length > 0)
1387
                  {
1388
                     sb.Append("Style = ");
1389
                     sb.Append(theAttr.Style);
1390
                     sb.Append("\n");
1391
                  }
1392
 
1393
                  if (  System.Convert.ToInt32(theAttr.LowerBound) > 1
1394
                     || System.Convert.ToInt32(theAttr.UpperBound) > 1)
1395
                  {
1396
                     sb.Append("Multiplicity [");
1397
                     sb.Append(theAttr.LowerBound);
1398
                     sb.Append("..");
1399
                     sb.Append(theAttr.UpperBound);
1400
                     sb.Append("]\n");
1401
                  }
1402
 
1403
                  if (theAttr.Scale.Length > 0 && System.Convert.ToInt32(theAttr.Scale) > 0)
1404
                  {
1405
                     sb.Append("Scale = ");
1406
                     sb.Append(theAttr.Scale);
1407
                     sb.Append( "\n" );
1408
                  }
1409
                  if (theAttr.Precision.Length > 0 && System.Convert.ToInt32(theAttr.Precision) > 0)
1410
                  {
1411
                     sb.Append("Precision = ");
1412
                     sb.Append(theAttr.Precision);
1413
                     sb.Append( "\n" );
1414
                  }
1415
 
1416
                  if (theAttr.Default.Length > 0)
1417
                  {
1418
                     sb.Append("Default Value = ");
1419
                     sb.Append(theAttr.Default);
1420
                     sb.Append( "\n" );
1421
                  }
1422
 
1423
                  // Now look at the constraint and tagged value collections and add any found info to the
1424
                  // right hand column
1425
                  short i;
1426
                  for(i=0; i<theAttr.Constraints.Count; i++)
1427
                  {
2106 ghuddy 1428
                     if (abortCreationThread)
1429
                        return;
1430
 
2094 ghuddy 1431
                     EA.AttributeConstraint theCons = (EA.AttributeConstraint)theAttr.Constraints.GetAt(i);
1432
                     sb.Append( theCons.Type );
1433
                     sb.Append( ": {" );
1434
                     sb.Append( theCons.Name );
1435
                     sb.Append( "}\n" );
1436
                     //sb.Append( theCons.Notes  );
1437
                     //sb.Append( "\n" );
1438
                  }
1439
 
1440
                  for(i=0; i<theAttr.TaggedValues.Count; i++)
1441
                  {
2106 ghuddy 1442
                     if (abortCreationThread)
1443
                        return;
1444
 
2094 ghuddy 1445
                     EA.AttributeTag theTag = (EA.AttributeTag)theAttr.TaggedValues.GetAt(i);
1446
                     sb.Append( "[" );
1447
                     sb.Append( theTag.Name );
1448
                     sb.Append( "="  );
1449
                     sb.Append( theTag.Value );
1450
                     sb.Append( "]\n" );
1451
                     //sb.Append( theTag.Notes );
1452
                     //sb.Append( "\n" );
1453
                  }
1454
 
1455
                  if (sb.Length > 0)
1456
                  {
1457
                     // remove the trailing "\n"
1458
                     sb.Remove( sb.ToString().Length - 1, 1);
1459
 
2106 ghuddy 1460
                     wr = TextualContent.appendAndSelectText("Characteristics:", EA_Constants.styleName_Body1_Left_3_5cm_Italic);
2094 ghuddy 1461
 
2106 ghuddy 1462
                     wr = TextualContent.appendAndSelectText(sb.ToString(), EA_Constants.styleName_Body1_Left_4_5cm);
2094 ghuddy 1463
                  }
1464
 
1465
                  numAttrsRemaining--;
1466
               }
1467
            }
1468
         }
1469
      }
1470
 
1471
 
1472
      private void generateClassCharacteristics( EA.Element theElement, int recurse_level )
1473
      {
1474
         StringBuilder sb = new StringBuilder();
1475
 
2104 ghuddy 1476
         ////////////////////////////////////////////////////////////////////////////////////////////////
2094 ghuddy 1477
         sb.Append( "Characteristics:" );
2106 ghuddy 1478
         Word.Range wr = TextualContent.appendAndSelectText(sb.ToString(), EA_Constants.styleName_Body1_Left_2_5cm_Italic);
2088 ghuddy 1479
 
2094 ghuddy 1480
         sb = new StringBuilder();
2104 ghuddy 1481
         // VISIBILITY
2094 ghuddy 1482
         sb.Append( theElement.Visibility );
2104 ghuddy 1483
         // ABSTRACT
2094 ghuddy 1484
         if (System.Convert.ToInt32(theElement.Abstract) == 1)
1485
            sb.Append( "\nAbstract" );
2104 ghuddy 1486
         // STEREOTYPES
1487
         if (theElement.StereotypeEx.Length > 0)
1488
         {
1489
            sb.Append("\nStereotypes: ");
1490
            sb.Append(theElement.StereotypeEx);
1491
         }
1492
         // MULTIPLICITY
1493
         if (theElement.Multiplicity.Length > 0)
1494
         {
1495
            sb.Append("\nMultiplicity: ");
1496
            sb.Append(theElement.Multiplicity);
1497
         }
1498
         // IS ACTIVE
1499
         if (theElement.IsActive)
1500
            sb.Append("\nClass is active (has its own thread of control)\n");
1501
         // IS SPEC
1502
         if (theElement.IsSpec)
1503
            sb.Append("\nClass is a specification\n");
2094 ghuddy 1504
 
2106 ghuddy 1505
         wr = TextualContent.appendAndSelectText(sb.ToString(), EA_Constants.styleName_Body1_Left_3_5cm);
2104 ghuddy 1506
 
1507
         ////////////////////////////////////////////////////////////////////////////////////////////////
2094 ghuddy 1508
         sb = new StringBuilder();
1509
         foreach(EA.Element baseClass in theElement.BaseClasses)
2088 ghuddy 1510
         {
2094 ghuddy 1511
            sb.Append( baseClass.Name);
1512
         }
1513
         if (sb.Length > 0)
1514
         {
2106 ghuddy 1515
            wr = TextualContent.appendAndSelectText("Base Class(es):", EA_Constants.styleName_Body1_Left_2_5cm_Italic);
2088 ghuddy 1516
 
2106 ghuddy 1517
            wr = TextualContent.appendAndSelectText(sb.ToString(), EA_Constants.styleName_Body1_Left_3_5cm);
2094 ghuddy 1518
         }
1519
 
2104 ghuddy 1520
         ////////////////////////////////////////////////////////////////////////////////////////////////
2094 ghuddy 1521
         sb = new StringBuilder();
1522
         foreach(EA.Element intf in theElement.Realizes)
1523
         {
1524
            sb.Append( intf.Name);
1525
         }
1526
         if (sb.Length > 0)
1527
         {
2106 ghuddy 1528
            wr = TextualContent.appendAndSelectText("Realises:", EA_Constants.styleName_Body1_Left_2_5cm_Italic);
2094 ghuddy 1529
 
2106 ghuddy 1530
            wr = TextualContent.appendAndSelectText(sb.ToString(), EA_Constants.styleName_Body1_Left_3_5cm);
2094 ghuddy 1531
         }
1532
      }
1533
 
1534
 
1535
      private void generateClassRequirements( EA.Element theElement, int recurse_level )
1536
      {
1537
         StringBuilder sb = new StringBuilder();
1538
 
1539
         sb.Append( "Requirements:" );
2106 ghuddy 1540
         Word.Range wr = TextualContent.appendAndSelectText(sb.ToString(), EA_Constants.styleName_Body1_Left_2_5cm_Italic);
2094 ghuddy 1541
 
1542
         foreach(EA.Requirement theReq in theElement.Requirements)
1543
         {
2106 ghuddy 1544
            if (abortCreationThread)
1545
               return;
1546
 
2094 ghuddy 1547
            sb = new StringBuilder();
1548
            sb.Append( theReq.Name );
2106 ghuddy 1549
            wr = TextualContent.appendAndSelectText(sb.ToString(), EA_Constants.styleName_Body1_Left_3_5cm);
2094 ghuddy 1550
            sb = new StringBuilder();
1551
            sb.Append( theReq.Notes );
1552
            if (sb.Length > 0)
2088 ghuddy 1553
            {
2106 ghuddy 1554
               wr = TextualContent.appendAndSelectText(sb.ToString(), EA_Constants.styleName_Body1_Left_4_5cm);
2088 ghuddy 1555
            }
2094 ghuddy 1556
         }
1557
      }
1558
 
1559
 
1560
      private void generateClassConstraints( EA.Element theElement, int recurse_level )
1561
      {
1562
         StringBuilder sb = new StringBuilder();
1563
 
1564
         sb.Append( "Constraints:" );
2106 ghuddy 1565
         Word.Range wr = TextualContent.appendAndSelectText(sb.ToString(), EA_Constants.styleName_Body1_Left_2_5cm_Italic);
2094 ghuddy 1566
 
1567
         foreach(EA.Constraint theCons in theElement.Constraints)
1568
         {
2106 ghuddy 1569
            if (abortCreationThread)
1570
               return;
1571
 
2094 ghuddy 1572
            sb = new StringBuilder();
1573
            sb.Append( theCons.Type );
1574
            sb.Append( ": {" );
1575
            sb.Append( theCons.Name );
1576
            sb.Append( "}" );
1577
 
2106 ghuddy 1578
            wr = TextualContent.appendAndSelectText(sb.ToString(), EA_Constants.styleName_Body1_Left_3_5cm);
2094 ghuddy 1579
 
1580
            if (theCons.Notes.Length > 0)
2088 ghuddy 1581
            {
2094 ghuddy 1582
               sb = new StringBuilder();
1583
               sb.Append( theCons.Notes );
2106 ghuddy 1584
               wr = TextualContent.appendAndSelectText(sb.ToString(), EA_Constants.styleName_Body1_Left_4_5cm);
2094 ghuddy 1585
            }
1586
         }
1587
      }
1588
 
1589
 
2104 ghuddy 1590
      private bool generateElementContent( EA.Element theElement, int recurse_level )
2094 ghuddy 1591
      {
2104 ghuddy 1592
         bool allowSubElementParsing = true;  // return value for the function
1593
 
2094 ghuddy 1594
         // track recursion level to control heading style formatting requirements
1595
         if (oneShot_skipRootElementHeading == false)
1596
            recurse_level++;
1597
 
2106 ghuddy 1598
         if (EA_DocGenOptions.elementTypeFoundInEA_DocGen( theElement.Type ))
2094 ghuddy 1599
         {
1600
            // pass the element to the requirement element serialisation function. It
1601
            // will tell us if it did anything with it. If not, then carry out the default
1602
            // element serialisation.
2106 ghuddy 1603
            if (false == TextualContent.generateRequirementText(theElement))
2094 ghuddy 1604
            {
1605
               bool isClass = theElement.Type.StartsWith("Class");
1606
 
2104 ghuddy 1607
               if (   (   true == isClass
2106 ghuddy 1608
                       && true == EA_DocGenOptions.opt_SuppressPrivateClasses 
2104 ghuddy 1609
                       && true == theElement.Visibility.StartsWith("Private"))
2106 ghuddy 1610
                   || (   true == EA_DocGenOptions.opt_ConsiderAPIElementsOnly 
2104 ghuddy 1611
                       && 0 > theElement.StereotypeEx.IndexOf("API"))
1612
                  )
2088 ghuddy 1613
               {
2094 ghuddy 1614
                  // do nothing
2106 ghuddy 1615
                  DocSectionTracking.trackDocSection(recurse_level);
2104 ghuddy 1616
                  displayProgress( "SKIPPED: ", theElement.Name );
1617
                  allowSubElementParsing = false;
2088 ghuddy 1618
               }
1619
               else
2094 ghuddy 1620
               {
1621
                  // disarm the one-shot element (heading) skipping feature if it was armed, and 
1622
                  // by-pass the code to generate a new heading level for the element
1623
                  if (oneShot_skipRootElementHeading == false)
1624
                  {
1625
                     // Default element serialisation
2106 ghuddy 1626
                     TextualContent.appendAndSelectHeadingText( theElement.Name, recurse_level );
2094 ghuddy 1627
                  }
1628
                  else
1629
                  {
1630
                     oneShot_skipRootElementHeading = false;
1631
                  }
1632
 
2104 ghuddy 1633
                  processedElements.Add(theElement.ElementID);
1634
                  displayProgress( "ELEMENT: ", theElement.Name );
1635
 
2106 ghuddy 1636
                  TextualContent.appendDescription( TextualContent.trimTrailingReturns(theElement.Notes) );
2094 ghuddy 1637
 
2102 ghuddy 1638
                  generateElementDiagrams(theElement);
1639
 
2094 ghuddy 1640
                  if (true == isClass)
1641
                  {
2104 ghuddy 1642
                     // accumulate unit testable classes.
1643
                     if (   theElement.StereotypeEx.IndexOf("API") >= 0
1644
                         && !theElement.Visibility.StartsWith("Private"))
2094 ghuddy 1645
                     {
2104 ghuddy 1646
                        classesNeedingUnitTests.Add( theElement.ElementID );
2094 ghuddy 1647
                     }
1648
 
2106 ghuddy 1649
                     if (!abortCreationThread)
1650
                        generateClassCharacteristics(theElement, recurse_level);
2094 ghuddy 1651
                  }
1652
 
1653
                  // Requirement collection
2106 ghuddy 1654
                  if (!abortCreationThread && theElement.Requirements.Count > 0)
2094 ghuddy 1655
                  {
1656
                     generateClassRequirements(theElement, recurse_level);
1657
                  }
1658
 
1659
                  // Constraint collection
2106 ghuddy 1660
                  if (!abortCreationThread && theElement.Constraints.Count > 0)
2094 ghuddy 1661
                  {
1662
                     generateClassConstraints(theElement, recurse_level);
1663
                  }
1664
 
2106 ghuddy 1665
                  if (!abortCreationThread && theElement.Issues.Count > 0)
2094 ghuddy 1666
                  {
1667
                  }
1668
 
1669
                  // Attribute collection
2106 ghuddy 1670
                  if (!abortCreationThread && theElement.Attributes.Count > 0)
2094 ghuddy 1671
                  {
1672
                     generateAttributeContent(theElement, recurse_level);
1673
                  }
1674
 
1675
                  // Method collection
2106 ghuddy 1676
                  if (!abortCreationThread && theElement.Methods.Count > 0)
2094 ghuddy 1677
                  {
1678
                     generateMethodContent(theElement, recurse_level);
1679
                  }
1680
               }
2088 ghuddy 1681
            }
2094 ghuddy 1682
            else
1683
            {
2104 ghuddy 1684
               processedElements.Add(theElement.ElementID);
2106 ghuddy 1685
               DocSectionTracking.trackDocSection(recurse_level);
2094 ghuddy 1686
               displayProgress( "ELEMENT: ", theElement.Name );
1687
            }
2088 ghuddy 1688
         }
1689
         else
1690
         {
2106 ghuddy 1691
            DocSectionTracking.trackDocSection(recurse_level);
2088 ghuddy 1692
            displayProgress( "FILTERED: ", theElement.Type );
1693
         }
1694
         // TODO
1695
         // We will probably have to put special code in here at some point for attributes
1696
         // of, and collections of things within elements. This will become apparent once
1697
         // someone tries to produce a design document where such things need to be included
1698
         // in the generated document. Lots of work needed here eventually.
1699
 
2094 ghuddy 1700
         // disarm element heading skip control
1701
         oneShot_skipRootElementHeading = false;
2104 ghuddy 1702
 
1703
         return allowSubElementParsing;
2088 ghuddy 1704
      }
1705
 
2094 ghuddy 1706
 
2088 ghuddy 1707
      /// <summary>
1708
      /// This function searches for the old content in the document in order to remove it
1709
      /// prior to adding in the new content from the latest EA model data.
1710
      /// </summary>
1711
      private void removeExistingDocumentContent()
1712
      {
1713
         //WordApp.Visible = true;  // enable this when debugging this horrible function
1714
         Word.Selection aSelection;
2106 ghuddy 1715
         object findStyle = StyleContent.getStyle( EA_Constants.styleName_Heading1 );
2088 ghuddy 1716
 
1717
         WordApp.Selection.WholeStory();
1718
         aSelection = WordApp.Selection;
1719
 
1720
         aSelection.Find.ClearFormatting();
1721
         aSelection.Find.set_Style( ref findStyle );
1722
         aSelection.Find.Text = "Introduction";
1723
         aSelection.Find.Replacement.Text = "";
1724
         aSelection.Find.Forward = true;
1725
         aSelection.Find.MatchCase = false;
1726
         aSelection.Find.MatchWholeWord = false;
1727
         aSelection.Find.MatchWildcards = false;
1728
         aSelection.Find.MatchSoundsLike = false;
1729
         aSelection.Find.MatchAllWordForms = false;
1730
 
1731
         object missingValue = Type.Missing;
1732
         if (aSelection.Find.Execute(ref missingValue, ref missingValue, 
1733
            ref missingValue, ref missingValue, ref missingValue, 
1734
            ref missingValue, ref missingValue, ref missingValue, 
1735
            ref missingValue, ref missingValue, ref missingValue, 
1736
            ref missingValue, ref missingValue, ref missingValue, 
1737
            ref missingValue)) 
1738
         { 
1739
            // found Introduction with Heading 1 style so we are now at the point in the 
1740
            // document where everything here on must be deleted in readiness for the newly
1741
            // generated content. Extend the range to the end of the document and cut out the
1742
            // old content.
1743
            Word.Range range = aSelection.Range;
1744
            range.End = WordDocument.Content.End;
1745
            range.Cut();
2092 ghuddy 1746
            // try and ensure that no heading style is left in place following the removal
2094 ghuddy 1747
            object style = EA_Constants.styleName_Body1;
2092 ghuddy 1748
            range.set_Style(ref style);
2088 ghuddy 1749
         }
1750
      }
1751
 
1752
 
1753
      /// <summary>
1754
      /// Parses an element (because elements can contain sub-elements).
1755
      /// This is also the function that identifies the occurrences of the special
1756
      /// EA_DocGenXXX elements.
1757
      /// </summary>
1758
      /// <param name="theElement"></param>
1759
      /// <param name="recurse_level"></param>
1760
      private void parse_element(EA.Element theElement, int recurse_level)
1761
      {
2106 ghuddy 1762
         if (abortCreationThread)
1763
            return;
1764
 
2088 ghuddy 1765
         // First look for and handle special elements that control the doc-gen process
1766
 
1767
         // The EA_DocGenPackageLink can contain a list of GUIDs in its notes section
1768
         // that point to model structure outside of the localised structure forming the
1769
         // document. This enables a document to grab content from other external models
1770
         // as long as they are loaded into the repository.
2094 ghuddy 1771
         if (theElement.Name.StartsWith(EA_Constants.EA_DocGenPackageLink))
2088 ghuddy 1772
         {
2104 ghuddy 1773
            processingLink++;
2088 ghuddy 1774
            processPackageLink( theElement, recurse_level );
2104 ghuddy 1775
            processingLink--;
2088 ghuddy 1776
         }
1777
 
1778
            // The EA_DocGenDiagramLink can contain a list of GUIDs in its notes section
1779
            // that point to diagram elements anywhere in the repository.
2094 ghuddy 1780
         else if (theElement.Name.StartsWith(EA_Constants.EA_DocGenDiagramLink))
2088 ghuddy 1781
         {
2104 ghuddy 1782
            processingLink++;
2088 ghuddy 1783
            processDiagramLink( theElement );
2104 ghuddy 1784
            processingLink--;
2088 ghuddy 1785
         }
1786
 
1787
            // The EA_DocGenDiagramLink can contain a list of GUIDs in its notes section
1788
            // that point to diagram elements anywhere in the repository.
2094 ghuddy 1789
         else if (theElement.Name.StartsWith(EA_Constants.EA_DocGenElementLink))
2088 ghuddy 1790
         {
2104 ghuddy 1791
            processingLink++;
2088 ghuddy 1792
            processElementLink( theElement, recurse_level );
2104 ghuddy 1793
            processingLink--;
2088 ghuddy 1794
         }
1795
 
1796
            // The EA_DocGenTable element can contain table content in its notes section
1797
            // and must be dealt with in a special way.
2094 ghuddy 1798
         else if (theElement.Name.StartsWith(EA_Constants.EA_DocGenTable))
2088 ghuddy 1799
         {
2106 ghuddy 1800
            TabularContent.processTableElement(theElement, recurse_level);
2088 ghuddy 1801
         }
1802
 
1803
            // The EA_DocGenText element can contain text content in its notes section
1804
            // that must be appended to the doc in Body 1 style within the current
1805
            // section.
2094 ghuddy 1806
         else if (theElement.Name.StartsWith(EA_Constants.EA_DocGenText))
2088 ghuddy 1807
         {
2106 ghuddy 1808
            TextualContent.appendAndSelectText( TextualContent.trimTrailingReturns(theElement.Notes), EA_Constants.styleName_Body1 );
2088 ghuddy 1809
         }
1810
 
2094 ghuddy 1811
         else if (theElement.Name.StartsWith(EA_Constants.EA_DocGenRelationshipMatrix))
2088 ghuddy 1812
         {
2106 ghuddy 1813
            EA_RelationshipMatrix.initialise(processedElements);
1814
            if (EA_RelationshipMatrix.processRelationshipMatrixOptions( theElement ))
2104 ghuddy 1815
            {
2106 ghuddy 1816
               EA_RelationshipMatrix.processRelationshipMatrixElement( theElement, recurse_level );
2104 ghuddy 1817
            }
2088 ghuddy 1818
         }
1819
 
2094 ghuddy 1820
         else if (theElement.Name.StartsWith(EA_Constants.EA_DocGenTestLink))
2088 ghuddy 1821
         {
2104 ghuddy 1822
            processingLink++;
2094 ghuddy 1823
            processTestLink( theElement, recurse_level );
2104 ghuddy 1824
            processingLink--;
2094 ghuddy 1825
         }
1826
 
1827
         else if (theElement.Name.StartsWith(EA_Constants.EA_DocGenTestTraceability))
1828
         {
1829
            processTestTraceability( theElement, recurse_level );
1830
         }
1831
 
2104 ghuddy 1832
         else if (theElement.Name.StartsWith(EA_Constants.EA_DocGenNameLink))
1833
         {
1834
            processingLink++;
1835
            processNameLink( theElement, recurse_level );
1836
            processingLink--;
1837
         }
2094 ghuddy 1838
 
2104 ghuddy 1839
            // we are aware of the other ERG EA add-in, EA_ReqPro! That add-in creates 
2094 ghuddy 1840
            // ReqProDB stereotyped elements. Never consume them in the document generation process.
2104 ghuddy 1841
         else if (0 > theElement.StereotypeEx.IndexOf(EA_Constants.stereotype_ReqProDB))
2094 ghuddy 1842
         {
2104 ghuddy 1843
            bool allowSubElementParsing = generateElementContent( theElement, recurse_level );
1844
            if (allowSubElementParsing)
1845
            {
1846
               // Look at this elements sub-elements
1847
               foreach(EA.Element subElement in theElement.Elements)
1848
               {
2106 ghuddy 1849
                  if (abortCreationThread)
1850
                     return;
1851
 
2104 ghuddy 1852
                  parse_element(subElement, recurse_level+1);
1853
               }
1854
            }
2102 ghuddy 1855
         }   
2088 ghuddy 1856
      }
1857
 
1858
 
1859
      /// <summary>
1860
      /// Parses the package and all of its content, extracting information as needed, and
1861
      /// adding it to the word document. This method is recursive, since recursion is the
1862
      /// easiest way to walk thru' the package levels in the model.
1863
      /// </summary>
1864
      /// <param name="parentPackage"></param>
1865
      /// <param name="recurse_level"></param>
1866
      private void parse_package(EA.Package thePackage, int recurse_level)
1867
      {
2106 ghuddy 1868
         if (abortCreationThread)
1869
            return;
1870
 
2088 ghuddy 1871
         // track recursion level to control heading style formatting requirements
1872
         // The one-shot skiproot feature of the EA_DocGenPackageLink element handling has an effect
1873
         // here, as you can see. 
1874
         bool rootPackageWasSkipped = !oneShot_skipRootPackage;
1875
         if (oneShot_skipRootPackage == false)
1876
         {
1877
            recurse_level++;
1878
         }
1879
 
2104 ghuddy 1880
         // determine if the package has an API stereotype
1881
         bool packageHasAPIStereotype = false;
1882
         if (0 <= thePackage.StereotypeEx.IndexOf("API") )
1883
            packageHasAPIStereotype = true;
2088 ghuddy 1884
 
2104 ghuddy 1885
         // only process the package if it the stereotype allows, or sensitivity to the stereotype is disabled
2106 ghuddy 1886
         if (  !EA_DocGenOptions.opt_ConsiderAPIPackagesOnly
1887
            || (EA_DocGenOptions.opt_ConsiderAPIPackagesOnly && EA_DocGenOptions.opt_RestrictForLinkedPackagesOnly && processingLink == 0)
1888
            || (EA_DocGenOptions.opt_ConsiderAPIPackagesOnly && packageHasAPIStereotype) 
2104 ghuddy 1889
            )
2094 ghuddy 1890
         {
2104 ghuddy 1891
 
1892
            bool processLowerLevelContent = true;
2094 ghuddy 1893
 
2104 ghuddy 1894
            // disarm the one-shot package skipping feature if it was armed
1895
            if (oneShot_skipRootPackage == true)
2102 ghuddy 1896
            {
2104 ghuddy 1897
               oneShot_skipRootPackage = false;
2102 ghuddy 1898
            }
2104 ghuddy 1899
            else
1900
            {
1901
               // Generate heading and description for the package. This function also takes care of some
1902
               // specially handled packages (terminology, references).
1903
               processLowerLevelContent = generatePackageHeadingAndDescription( thePackage, recurse_level );
1904
            }
2102 ghuddy 1905
 
2104 ghuddy 1906
            // generate package heading and description. This may, depending on the package name,
1907
            // consume the elements in the package. If it does not, then consume them (and any diagrams)
1908
            // locally here.
1909
            if (true == processLowerLevelContent)
1910
            {
1911
               // consume diagrams
1912
               generatePackageDiagrams( thePackage );
2088 ghuddy 1913
 
2104 ghuddy 1914
               foreach(EA.Element subElement in thePackage.Elements)
1915
               {
2106 ghuddy 1916
                  if (abortCreationThread)
1917
                     return;
1918
 
2104 ghuddy 1919
                  if (subElement.ParentID == 0 || thePackage.PackageID == subElement.ParentID)
1920
                     parse_element(subElement, recurse_level);
1921
               }
2088 ghuddy 1922
 
2104 ghuddy 1923
               // Scan through the sub-packages within this package.
1924
               foreach(EA.Package subPackage in thePackage.Packages)
1925
               {
2106 ghuddy 1926
                  if (abortCreationThread)
1927
                     return;
1928
 
2104 ghuddy 1929
                  // recurse
1930
                  parse_package(subPackage, recurse_level);
1931
               }
1932
            }
2088 ghuddy 1933
         }
2104 ghuddy 1934
         else
2088 ghuddy 1935
         {
2104 ghuddy 1936
            // disarm the one-shot package skipping feature if it was armed
1937
            if (oneShot_skipRootPackage == true)
1938
            {
1939
               oneShot_skipRootPackage = false;
1940
            }         
2088 ghuddy 1941
         }
1942
      }
1943
 
1944
 
1945
      /// <summary>
1946
      /// This is the overall generate document method. It creates a word document from 
1947
      /// an input template, sets various characteristics of the document, schedules the
1948
      /// EA parsing function, before finally saving the document to the output file name.
1949
      /// </summary>
1950
      private void createTheWordDoc()
1951
      {
2106 ghuddy 1952
         docGenCompletedNormally = false;
1953
         abortCreationThread = false;
1954
 
1955
         Main.threadCreateDocProcessRunning = true;
1956
 
1957
         // capture initial security settings
2092 ghuddy 1958
         MsoAutomationSecurity  securityBefore = WordApp.AutomationSecurity;
1959
 
2106 ghuddy 1960
         button_generate.Enabled = false;
1961
         button_browse_output_file.Enabled = false;
1962
         button_browse_template.Enabled = false;
1963
         textBox_output_file.Enabled = false;
1964
         textBox_template.Enabled = false;
1965
         checkBox_WordVisibility.Enabled = false;
1966
 
2088 ghuddy 1967
         try 
1968
         {
1969
            object template       = this.textBox_template.Text;
1970
            object newTemplate    = Type.Missing;
1971
            object outputFilename = this.textBox_output_file.Text;
1972
 
1973
            object docType = Type.Missing;
1974
            object visible = Type.Missing;
1975
            object nothing = Type.Missing;
1976
            object notTrue = false;
1977
 
2106 ghuddy 1978
            Main.EA_Repository.WriteOutput( Main.GUI_OUTPUT_TAB_NAME, "", 0);
1979
            Main.EA_Repository.WriteOutput( Main.GUI_OUTPUT_TAB_NAME, 
2088 ghuddy 1980
                                       String.Format( "Generating Document {0}", this.textBox_output_file.Text), 0 );
1981
 
2092 ghuddy 1982
            // tell word not to show itself unless user has checked the option to say otherwise
2088 ghuddy 1983
            WordApp.Visible = this.checkBox_WordVisibility.Checked;
2092 ghuddy 1984
 
1985
            // disable VB macros from running in the document
1986
            WordApp.AutomationSecurity = MsoAutomationSecurity.msoAutomationSecurityForceDisable;
1987
            WordApp.DisplayAlerts = Word.WdAlertLevel.wdAlertsNone;
1988
 
2088 ghuddy 1989
            // Create a document from the input template
2106 ghuddy 1990
            Main.EA_Repository.WriteOutput(Main.GUI_OUTPUT_TAB_NAME, "Creating new document based on template", -1);
2088 ghuddy 1991
            WordDocument = WordApp.Documents.Add(ref template, ref newTemplate, ref docType, ref visible);
2106 ghuddy 1992
 
2088 ghuddy 1993
 
1994
            // Remove all old content from the input document/template. Note that this assumes
1995
            // that content will begin at section 1 with the title "Introduction" and it will have
1996
            // "Heading 1" style.
2106 ghuddy 1997
            if (!abortCreationThread)
1998
            {
1999
               Main.EA_Repository.WriteOutput(Main.GUI_OUTPUT_TAB_NAME, "Removing existing content (if any)", -1);
2000
               removeExistingDocumentContent();
2001
            }
2088 ghuddy 2002
 
2003
            // turn off grammar and spell checking
2004
            WordDocument.GrammarChecked = false;
2005
            WordDocument.SpellingChecked = false;
2006
 
2094 ghuddy 2007
            // arm the public class list accumulator.
2104 ghuddy 2008
            classesNeedingUnitTests = new ArrayList();
2094 ghuddy 2009
            classesWithUnitTests = new ArrayList();
2010
 
2104 ghuddy 2011
            processingLink = 0;
2012
 
2013
            processedElements = new ArrayList();
2014
 
2092 ghuddy 2015
            // If the input template does not contain the styles needed for requirement documents, 
2016
            // programmatically create them just in case.
2106 ghuddy 2017
            if (!abortCreationThread)
2018
            {
2019
               Main.EA_Repository.WriteOutput(Main.GUI_OUTPUT_TAB_NAME, "Creating Requirement Styles", -1);
2020
               StyleContent.createRequirementStyles();
2021
            }
2022
            if (!abortCreationThread)
2023
            {
2024
               Main.EA_Repository.WriteOutput(Main.GUI_OUTPUT_TAB_NAME, "Creating Additional Heading Styles", -1);
2025
               StyleContent.createAdditionalHeadingLevelStyles();
2026
            }
2027
            if (!abortCreationThread)
2028
            {
2029
               Main.EA_Repository.WriteOutput(Main.GUI_OUTPUT_TAB_NAME, "Creating Element Detail Styles", -1);
2030
               StyleContent.createElementDetailsStyles();
2031
            }
2032
            if (!abortCreationThread)
2033
            {
2034
               Main.EA_Repository.WriteOutput(Main.GUI_OUTPUT_TAB_NAME, "Correcting known problems in ERG template styles", -1);
2035
               StyleContent.correctErrorsInTemplateStyles();
2036
            }
2098 ghuddy 2037
 
2088 ghuddy 2038
            // Parse EA_DocGen Document Model. The parent package is the document model itself
2039
            // and the packages within it are the top level packages only.
2040
            // Question: do we have to parse diagrams and elements at this top level? So far,
2041
            // this has been found to be unecessary, but you never know. For now, dont do it.
2106 ghuddy 2042
            if (!abortCreationThread)
2088 ghuddy 2043
            {
2106 ghuddy 2044
               Main.EA_Repository.WriteOutput(Main.GUI_OUTPUT_TAB_NAME, "Generating new content", -1);
2045
 
2046
               foreach(EA.Package thePackage in EA_ParentPackage.Packages)
2047
               {
2048
                  parse_package(thePackage, 0);
2049
                  if (abortCreationThread)
2050
                     break;
2051
               }
2088 ghuddy 2052
            }
2094 ghuddy 2053
            // for design docs, a user may have used the test traceability element in their document model,
2054
            // which means that now we are finished with parse 1 of the document, we can complete the traceability
2055
            // table (if any) that was begun when that special element was first encountered.
2106 ghuddy 2056
            if (!abortCreationThread)
2057
            {
2058
               completeTestTraceability();
2088 ghuddy 2059
 
2106 ghuddy 2060
               // Save the document to the output file before we try and update the fields. This is because
2061
               // I have seen Fields.Update() fail on a few occasions and it is very annoying
2062
               // to lose what has thus far been generated.
2063
               WordDocument.SaveAs( ref outputFilename, 
2064
                  ref nothing, ref nothing, ref nothing, ref nothing, 
2065
                  ref nothing, ref nothing, ref nothing, ref nothing,
2066
                  ref nothing, ref nothing, ref nothing, ref nothing,
2067
                  ref nothing, ref nothing, ref nothing);
2088 ghuddy 2068
 
2106 ghuddy 2069
               object noSave = Word.WdSaveOptions.wdDoNotSaveChanges;
2070
               object format = Word.WdOriginalFormat.wdWordDocument;
2071
               WordDocument.Close(ref noSave, ref format, ref nothing);
2094 ghuddy 2072
 
2106 ghuddy 2073
               if (!abortCreationThread)
2074
               {
2075
                  Main.EA_Repository.WriteOutput(Main.GUI_OUTPUT_TAB_NAME, "Updating Fields and Saving Document", -1);
2076
                  // Re-load the document to update the fields. For some as yet unknown reason, doing this 
2077
                  // sometimes fails, but by doing it in a re-loaded instance of the word document
2078
                  // the failures seem to be reduced.
2079
                  WordDocument = WordApp.Documents.Add(ref outputFilename, ref newTemplate, ref docType, ref visible);
2080
                  WordDocument.Fields.Update();
2081
                  WordDocument.SaveAs( ref outputFilename, 
2082
                     ref nothing, ref nothing, ref nothing, ref nothing, 
2083
                     ref nothing, ref nothing, ref nothing, ref nothing,
2084
                     ref nothing, ref nothing, ref nothing, ref nothing,
2085
                     ref nothing, ref nothing, ref nothing);
2088 ghuddy 2086
 
2106 ghuddy 2087
                  // Tell user the process completed ok
2088
                  Main.EA_Repository.WriteOutput(Main.GUI_OUTPUT_TAB_NAME, "Document Generation Complete", -1);
2089
                  docGenCompletedNormally = true;
2090
                  button_view_output.Enabled = true;
2091
               }
2092
            }
2093
            else
2094
            {
2095
               Main.EA_Repository.WriteOutput(Main.GUI_OUTPUT_TAB_NAME, "Document Generation Aborted", -1);
2096
               MessageBox.Show("Document Generation Aborted");
2097
            }
2098 ghuddy 2098
 
2088 ghuddy 2099
         }
2100
         catch (Exception createTheWordDoc_exception)
2101
         {
2106 ghuddy 2102
            Main.EA_Repository.WriteOutput(Main.GUI_OUTPUT_TAB_NAME, "Document Generation Failed : " + createTheWordDoc_exception.Message, -1);
2088 ghuddy 2103
            MessageBox.Show("Document Generation Failed\n\n" + createTheWordDoc_exception.Message);
2104
         }
2092 ghuddy 2105
 
2106
         // restore security settings
2107
         WordApp.AutomationSecurity = securityBefore;
2106 ghuddy 2108
 
2109
         // issue the generation complete message box as close to the end of the thread as possible so that
2110
         // there is less of a chance that a user pressing the close button will see a "cancel generation"
2111
         // warning box.
2112
         if (docGenCompletedNormally)
2113
            MessageBox.Show("Document Generation Complete");
2114
 
2115
         // we can mark the thread as not running since from now on we do not want to do anything with the 
2116
         // WordApp or WordDocument objects and their destruction wont cause any ill effects.
2117
         Main.threadCreateDocProcessRunning = false;
2118
 
2119
         if (mustClose)
2120
            this.Close();
2088 ghuddy 2121
      }
2122
 
2092 ghuddy 2123
 
2124
 
2125
 
2088 ghuddy 2126
      #endregion
2106 ghuddy 2127
 
2128
 
2129
 
2130
 
2088 ghuddy 2131
   }
2132
}