Subversion Repositories DevTools

Rev

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