Subversion Repositories DevTools

Rev

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