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.Collections;
2104 ghuddy 3
using System.Text;
2088 ghuddy 4
using System.ComponentModel;
5
using System.Windows.Forms;
2136 brianf 6
using Microsoft.Office.Interop.Word;
2088 ghuddy 7
 
8
namespace EA_DocGen
9
{
10
	/// <summary>
11
	/// Summary description for EA_RelationshipMatrix.
12
	/// </summary>
13
	public class EA_RelationshipMatrix
14
	{
15
 
2122 ghuddy 16
      public struct RM_ColumnType
17
      {
18
         public string columnTitle;
2088 ghuddy 19
 
2122 ghuddy 20
         public string packageGUID;
21
         public string packageName;
22
 
23
         public ArrayList elementTypes;
24
 
25
         public bool packageRecursion;
26
         public bool packageTrimming;
27
         public bool elementNotes;
2124 ghuddy 28
         public bool reqTagSort;
2122 ghuddy 29
      };
30
 
31
      public struct RM_TableType
32
      {
33
         public string introText;
34
         public string title;
35
      };
36
 
37
      public struct RM_MatrixType
38
      {
39
         public int style;
40
         public RM_TableType fromToTable;
41
         public RM_TableType toFromTable;
42
         public RM_ColumnType from;
43
         public RM_ColumnType to;
44
      };
45
 
46
      // DATA
47
      private static RM_MatrixType RM_Matrix;
48
 
49
      private static EA.Element RM_Element = null;
50
 
2106 ghuddy 51
      private static EA.Package fromPackage = null;
52
      private static EA.Package toPackage = null;
2104 ghuddy 53
 
2122 ghuddy 54
      private static ArrayList processedElements = null;
2094 ghuddy 55
 
2106 ghuddy 56
      private static string [] options_string = null;
2088 ghuddy 57
 
2118 ghuddy 58
      private enum DictionaryValueType
59
      {
60
         DVT_EA_ELEMENT,
61
         DVT_STRING
62
      };
2088 ghuddy 63
 
2106 ghuddy 64
		public static void initialise(ArrayList processedElementsRef)
2088 ghuddy 65
		{
2104 ghuddy 66
         processedElements = processedElementsRef;
67
 
2122 ghuddy 68
         RM_Matrix.from.elementTypes = new ArrayList();
69
         RM_Matrix.to.elementTypes = new ArrayList();
2088 ghuddy 70
		}
71
 
2106 ghuddy 72
      private static void reset()
2088 ghuddy 73
      {
2122 ghuddy 74
         RM_Matrix.style = 1;
2104 ghuddy 75
 
2122 ghuddy 76
         RM_Matrix.fromToTable.introText = null;
77
         RM_Matrix.fromToTable.title = null;
78
 
79
         RM_Matrix.from.columnTitle = null;
80
         RM_Matrix.from.packageGUID = null;
81
         RM_Matrix.from.elementTypes.Clear();
82
         RM_Matrix.from.packageRecursion = true;
83
         RM_Matrix.from.packageTrimming = false;
84
         RM_Matrix.from.elementNotes = false;
85
         RM_Matrix.from.packageName = null;
2124 ghuddy 86
         RM_Matrix.from.reqTagSort = true;
2122 ghuddy 87
 
2088 ghuddy 88
         fromPackage = null;
2122 ghuddy 89
 
90
         RM_Matrix.toFromTable.introText = null;
91
         RM_Matrix.toFromTable.title = null;
92
 
93
         RM_Matrix.to.columnTitle = null;
94
         RM_Matrix.to.packageGUID = null;
95
         RM_Matrix.to.elementTypes.Clear();
96
         RM_Matrix.to.packageRecursion = true;
97
         RM_Matrix.to.packageTrimming = false;
98
         RM_Matrix.to.elementNotes = false;
99
         RM_Matrix.to.packageName = null;
2124 ghuddy 100
         RM_Matrix.to.reqTagSort = true;
2122 ghuddy 101
 
2088 ghuddy 102
         toPackage = null;
103
      }
104
 
105
 
2106 ghuddy 106
      public static bool processRelationshipMatrixOptions(EA.Element theElement)
2088 ghuddy 107
      {
2122 ghuddy 108
         RM_Element = theElement;
109
 
2088 ghuddy 110
         reset();
111
 
112
         // Extract the control options from the notes of the element
113
 
114
         string delimStr = "\n";
115
         char [] delim = delimStr.ToCharArray();
2132 ghuddy 116
         options_string = theElement.Notes.Split(delim,100);
2088 ghuddy 117
         int i = 0;
118
         foreach(string s in options_string)
119
         {
120
            options_string[i] = s.Trim();
121
            i++;
122
         }
123
 
124
         // scan the options string and assign values into the options variables as required
125
         foreach(string s in options_string)
126
         {
127
            if (s.Length > 0 && s != "\n" && s != "\r" && s[0] != '\\')
128
            {
2104 ghuddy 129
               if (s.StartsWith("style="))
130
               {
2122 ghuddy 131
                  RM_Matrix.style = EA_DocGenOptions.getOptionValue(s, RM_Matrix.style);
2104 ghuddy 132
               }
2118 ghuddy 133
                  // FROM items
2104 ghuddy 134
               else if (s.StartsWith("fromIntroText="))
2088 ghuddy 135
               {
2122 ghuddy 136
                  RM_Matrix.fromToTable.introText = EA_DocGenOptions.getOptionValue(s, null);
2088 ghuddy 137
               }
2104 ghuddy 138
               else if (s.StartsWith("fromToTableTitle=")) 
2088 ghuddy 139
               {
2122 ghuddy 140
                  RM_Matrix.fromToTable.title = EA_DocGenOptions.getOptionValue(s, null);
2088 ghuddy 141
               }
2104 ghuddy 142
               else if (s.StartsWith("fromColumnTitle=")) 
2088 ghuddy 143
               {
2122 ghuddy 144
                  RM_Matrix.from.columnTitle = EA_DocGenOptions.getOptionValue(s, RM_Matrix.from.columnTitle);
2088 ghuddy 145
               }
2104 ghuddy 146
               else if (s.StartsWith("fromPackageRecursion=")) 
2088 ghuddy 147
               {
2122 ghuddy 148
                  RM_Matrix.from.packageRecursion = EA_DocGenOptions.getOptionValue(s, RM_Matrix.from.packageRecursion);
2088 ghuddy 149
               }
2104 ghuddy 150
               else if (s.StartsWith("fromPackageTrimming="))
2094 ghuddy 151
               {
2122 ghuddy 152
                  RM_Matrix.from.packageTrimming = EA_DocGenOptions.getOptionValue(s, RM_Matrix.from.packageTrimming);
2094 ghuddy 153
               }
2104 ghuddy 154
               else if (s.StartsWith("fromPackage=")) 
2088 ghuddy 155
               {
2122 ghuddy 156
                  RM_Matrix.from.packageGUID = EA_DocGenOptions.getOptionValue(s, RM_Matrix.from.packageGUID);
2088 ghuddy 157
               }
2118 ghuddy 158
               else if (s.StartsWith("fromElementNotes="))
159
               {
2122 ghuddy 160
                  RM_Matrix.from.elementNotes = EA_DocGenOptions.getOptionValue(s, RM_Matrix.from.elementNotes);
2118 ghuddy 161
               }
2122 ghuddy 162
               else if (s.StartsWith("fromPackageName="))
163
               {
164
                  RM_Matrix.from.packageName = EA_DocGenOptions.getOptionValue(s, RM_Matrix.from.packageName);
165
               }
2104 ghuddy 166
               else if (s.StartsWith("fromElementType=")) 
2088 ghuddy 167
               {
2106 ghuddy 168
                  string et = EA_DocGenOptions.getOptionValue(s,null);
2088 ghuddy 169
                  if (et != null) 
170
                  {
2122 ghuddy 171
                     RM_Matrix.from.elementTypes.Add( et );
2088 ghuddy 172
                  }
173
               }
2124 ghuddy 174
               else if (s.StartsWith("fromUsesTagSort="))
175
               {
176
                  RM_Matrix.from.reqTagSort = EA_DocGenOptions.getOptionValue(s, RM_Matrix.from.reqTagSort);
177
               }
2088 ghuddy 178
 
179
                  // TO items
2104 ghuddy 180
               else if (s.StartsWith("toIntroText="))
2088 ghuddy 181
               {
2122 ghuddy 182
                  RM_Matrix.toFromTable.introText = EA_DocGenOptions.getOptionValue(s, null);
2088 ghuddy 183
               }
2104 ghuddy 184
               else if (s.StartsWith("toFromTableTitle=")) 
2088 ghuddy 185
               {
2122 ghuddy 186
                  RM_Matrix.toFromTable.title = EA_DocGenOptions.getOptionValue(s, null);
2088 ghuddy 187
               }
2104 ghuddy 188
               else if (s.StartsWith("toColumnTitle=")) 
2088 ghuddy 189
               {
2122 ghuddy 190
                  RM_Matrix.to.columnTitle = EA_DocGenOptions.getOptionValue(s, RM_Matrix.to.columnTitle);
2088 ghuddy 191
               }
2104 ghuddy 192
               else if (s.StartsWith("toPackageRecursion=")) 
2088 ghuddy 193
               {
2122 ghuddy 194
                  RM_Matrix.to.packageRecursion = EA_DocGenOptions.getOptionValue(s, RM_Matrix.to.packageRecursion);
2088 ghuddy 195
               }
2104 ghuddy 196
               else if (s.StartsWith("toPackageTrimming=")) 
2094 ghuddy 197
               {
2122 ghuddy 198
                  RM_Matrix.to.packageTrimming = EA_DocGenOptions.getOptionValue(s, RM_Matrix.to.packageTrimming);
2094 ghuddy 199
               }               
2104 ghuddy 200
               else if (s.StartsWith("toPackage=")) 
2088 ghuddy 201
               {
2122 ghuddy 202
                  RM_Matrix.to.packageGUID = EA_DocGenOptions.getOptionValue(s, RM_Matrix.to.packageGUID);
2088 ghuddy 203
               }
2118 ghuddy 204
               else if (s.StartsWith("toElementNotes="))
205
               {
2122 ghuddy 206
                  RM_Matrix.to.elementNotes = EA_DocGenOptions.getOptionValue(s, RM_Matrix.to.elementNotes);
2118 ghuddy 207
               }
2122 ghuddy 208
               else if (s.StartsWith("toPackageName="))
209
               {
210
                  RM_Matrix.to.packageName = EA_DocGenOptions.getOptionValue(s, RM_Matrix.to.packageName);
211
               }               
2104 ghuddy 212
               else if (s.StartsWith("toElementType=")) 
2088 ghuddy 213
               {
2106 ghuddy 214
                  string et = EA_DocGenOptions.getOptionValue(s,null);
2088 ghuddy 215
                  if (et != null) 
216
                  {
2122 ghuddy 217
                     RM_Matrix.to.elementTypes.Add( et );
2088 ghuddy 218
                  }
219
               }
2124 ghuddy 220
               else if (s.StartsWith("toUsesTagSort="))
221
               {
222
                  RM_Matrix.to.reqTagSort = EA_DocGenOptions.getOptionValue(s, RM_Matrix.to.reqTagSort);
223
               }
2088 ghuddy 224
            }
225
         }
226
 
227
         // Verify that we have all the necessary compulsory options
2122 ghuddy 228
         if (RM_Matrix.fromToTable.title == null && RM_Matrix.toFromTable.title == null)
2088 ghuddy 229
         {
230
            MessageBox.Show("Error in EA_DocGenRelationshipMatrix options list\n\n" +
231
               "Missing option: Must specify at least one table title");
232
            return false;
233
         }
234
 
235
         // FROM items
2122 ghuddy 236
         if (RM_Matrix.from.columnTitle == null)
2088 ghuddy 237
         {
238
            MessageBox.Show("Error in EA_DocGenRelationshipMatrix options list\n\n" +
239
               "Missing option: fromColumnTitle");
240
            return false;
241
         }
2122 ghuddy 242
         if (RM_Matrix.from.packageGUID == null)
2088 ghuddy 243
         {
244
            MessageBox.Show("Error in EA_DocGenRelationshipMatrix options list\n\n" +
245
               "Missing option: fromPackageGUID");
246
            return false;
247
         }
2122 ghuddy 248
         if (RM_Matrix.from.elementTypes.Count == 0)
2088 ghuddy 249
         {
250
            MessageBox.Show("Error in EA_DocGenRelationshipMatrix options list\n\n" +
251
               "Missing option(s): fromElementTypes");
252
            return false;
253
         }      
254
 
255
         // TO items
2122 ghuddy 256
         if (RM_Matrix.to.columnTitle == null)
2088 ghuddy 257
         {
258
            MessageBox.Show("Error in EA_DocGenRelationshipMatrix options list\n\n" +
259
               "Missing option: toColumnTitle");
260
            return false;
261
         }
2122 ghuddy 262
         if (RM_Matrix.to.packageGUID == null)
2088 ghuddy 263
         {
264
            MessageBox.Show("Error in EA_DocGenRelationshipMatrix options list\n\n" +
265
               "Missing option: toPackageGUID");
266
            return false;
267
         }
2122 ghuddy 268
         if (RM_Matrix.to.elementTypes.Count == 0)
2088 ghuddy 269
         {
270
            MessageBox.Show("Error in EA_DocGenRelationshipMatrix options list\n\n" +
271
               "Missing option(s): toElementTypes");
272
            return false;
273
         }   
274
 
275
         // Find GUID linked packages in the repository
2122 ghuddy 276
         fromPackage = Main.EA_Repository.GetPackageByGuid( RM_Matrix.from.packageGUID );
2088 ghuddy 277
         if (fromPackage == null)
278
         {
279
            MessageBox.Show("Error processing EA_DocGenRelationshipMatrix\n\n" +
280
               "could not locate fromPackage in Repository");
281
            return false;
282
         }
283
 
2122 ghuddy 284
         toPackage = Main.EA_Repository.GetPackageByGuid( RM_Matrix.to.packageGUID );
2088 ghuddy 285
         if (toPackage == null)
286
         {
287
            MessageBox.Show("Error processing EA_DocGenRelationshipMatrix\n\n" +
288
               "could not locate toPackage in Repository");
289
            return false;
290
         }
291
 
292
         return true;
293
      }
294
 
295
 
2104 ghuddy 296
      public static string optionTemplateForRelationshipMatrix(int style)
2088 ghuddy 297
      {
2104 ghuddy 298
         switch (style)
299
         {
300
            case 1:
301
               return
302
               "style=1\r\n"
303
               + "fromToTableTitle=\r\n"
304
               + "fromIntroText=\r\n"
305
               + "fromColumnTitle=\r\n"
306
               + "fromPackage=\r\n"
307
               + "fromElementType=\r\n"
308
               + "fromElementType=\r\n"
309
               + "fromPackageRecursion=true\r\n"
310
               + "fromPackageTrimming=false\r\n"
2124 ghuddy 311
               + "fromElementNotes=false\r\n"
312
               + "fromUsesTagSort=true\r\n"
2104 ghuddy 313
 
314
               + "toFromTableTitle=\r\n"
315
               + "toIntroText=\r\n"
316
               + "toColumnTitle=\r\n"
317
               + "toPackage=\r\n"
318
               + "toElementType=\r\n"
319
               + "toPackageRecursion=true\r\n"
2118 ghuddy 320
               + "toPackageTrimming=false\r\n"
2124 ghuddy 321
               + "toElementNotes=false\r\n"
322
               + "toUsesTagSort=true\r\n";
2104 ghuddy 323
            case 2:
324
               return
325
               "style=2\r\n"
326
               + "fromToTableTitle=Requirement Dependencies\r\n"
327
               + "fromIntroText=The following table identifies the source requirements (if any) for each requirement stated in this document.\r\n"
328
               + "fromColumnTitle=Requirement\r\n"
329
               + "fromPackage=\r\n"
330
               + "fromElementType=Requirement\r\n"
331
               + "fromPackageRecursion=true\r\n"
332
               + "fromPackageTrimming=false\r\n"
2118 ghuddy 333
               + "fromElementNotes=false\r\n"
2124 ghuddy 334
               + "fromUsesTagSort=true\r\n"
2104 ghuddy 335
 
336
               + "toPackageRecursion=true\r\n"
337
               + "toPackage=\r\n"
338
               + "toColumnTitle=Source Requirements\r\n"
339
               + "toElementType=Requirement\r\n";
340
            default:
341
               return "";
342
         }
2088 ghuddy 343
      }
344
 
2122 ghuddy 345
 
2104 ghuddy 346
      /// <summary>
347
      /// This function will insert one or more relationship matrix tables into the document, 
348
      /// built from content specified in options that are provided in the notes section of 
349
      /// the special element that has led to this function being called.
350
      /// </summary>
351
      /// <param name="theElement"></param>
352
      /// <param name="recurse_level"></param>
2106 ghuddy 353
      public static void processRelationshipMatrixElement( EA.Element theElement, int recurse_level )
2104 ghuddy 354
      {
2122 ghuddy 355
         RM_Element = theElement;
356
 
357
         if (RM_Matrix.from.packageName != null && fromPackage != null)
2104 ghuddy 358
         {
2122 ghuddy 359
            EA.Package newFromPackage = EA_Utilities.findNamedPackage(fromPackage, RM_Matrix.from.packageName);
360
            if (newFromPackage != null)
361
            {
362
               fromPackage = newFromPackage;
363
            }
364
            else
365
            {
366
               MessageBox.Show("Error processing EA_DocGenRelationshipMatrix\n\n" +
367
                  "could not locate fromPackageName in Repository");
368
               return;
369
            }
370
         }
371
 
372
         if (RM_Matrix.to.packageName != null && toPackage != null)
373
         {
374
            EA.Package newToPackage = EA_Utilities.findNamedPackage(toPackage, RM_Matrix.to.packageName);
375
            if (newToPackage != null)
376
            {
377
               toPackage = newToPackage;
378
            }
379
            else
380
            {
381
               MessageBox.Show("Error processing EA_DocGenRelationshipMatrix\n\n" +
382
                  "could not locate toPackageName in Repository");
383
               return;
384
            }
385
         }
386
 
387
         switch (RM_Matrix.style)
388
         {
2104 ghuddy 389
            case 1:
390
               processRelationshipMatrixElementStyle1();
391
               break;
2088 ghuddy 392
 
2104 ghuddy 393
            case 2:
394
               processRelationshipMatrixElementStyle2();
395
               break;
396
         }
397
      }
398
 
2122 ghuddy 399
 
2104 ghuddy 400
      /// <summary>
401
      /// This function will insert a relationship matrix table into the document, built from content
402
      /// specified in options that are provided in the notes section of the special element that
403
      /// has led to this function being called.
404
      /// 
405
      /// The style of these tables is that required for requirement to design traceability.
406
      /// </summary>
407
      /// <param name="EA_RelMatrix"></param>
2106 ghuddy 408
      private static void processRelationshipMatrixElementStyle1()
2104 ghuddy 409
      {
410
         int tableNum = 0;
2136 brianf 411
         Table table = null;
2104 ghuddy 412
 
413
         // Scan the fromPackage to find all the "from elements".
2124 ghuddy 414
         Main.WriteOutput("   Finding elements in fromPackage", -1);
2122 ghuddy 415
         ElementAccumulator fromLister = new ElementAccumulator(RM_Matrix.from.elementTypes);
416
         EA_Utilities.findAndProcessPackageElements( fromPackage, fromLister, RM_Matrix.from.packageRecursion );
2104 ghuddy 417
 
2106 ghuddy 418
         if (createWordDoc.abortCreationThread)
419
            return;
420
 
2120 ghuddy 421
         // Scan the toPackage to find all the "to elements".
2124 ghuddy 422
         Main.WriteOutput("   Finding elements in toPackage", -1);
2122 ghuddy 423
         ElementAccumulator toLister = new ElementAccumulator(RM_Matrix.to.elementTypes);
424
         EA_Utilities.findAndProcessPackageElements( toPackage, toLister, RM_Matrix.to.packageRecursion );
2120 ghuddy 425
 
426
         if (createWordDoc.abortCreationThread)
427
            return;
428
 
2104 ghuddy 429
         // Sort the "from elements"
2124 ghuddy 430
         Main.WriteOutput("   Sorting elements in fromPackage", -1);
431
         if (RM_Matrix.from.reqTagSort)
432
         {
433
            elementSortByTAG sorter = new elementSortByTAG();
434
            fromLister.Elements.Sort( sorter );
435
         }
436
         else
437
         {
438
            elementSortByName sorter = new elementSortByName();
439
            fromLister.Elements.Sort( sorter );
440
         }
2104 ghuddy 441
 
2120 ghuddy 442
         // Sort the "to" elements
2124 ghuddy 443
         Main.WriteOutput("   Sorting elements in toPackage", -1);
444
         if (RM_Matrix.to.reqTagSort)
445
         {
446
            elementSortByTAG sorter = new elementSortByTAG();
447
            toLister.Elements.Sort( sorter );
448
         }
449
         else
450
         {
451
            elementSortByName sorter = new elementSortByName();
452
            toLister.Elements.Sort( sorter );
453
         }
2120 ghuddy 454
 
2106 ghuddy 455
         if (createWordDoc.abortCreationThread)
456
            return;
457
 
2104 ghuddy 458
         // dictionary to support from-to table construction.
459
         ArrayList fromToDictionary = new ArrayList();
460
 
461
         // dictionary to support to-from table construction.
462
         ArrayList toFromDictionary = new ArrayList();
463
 
464
         bool needFromToTable = false;
2122 ghuddy 465
         if (RM_Matrix.fromToTable.title != null && RM_Matrix.fromToTable.title.Length > 0)
2104 ghuddy 466
            needFromToTable = true;
467
 
468
         bool needToFromTable = false;
2122 ghuddy 469
         if (RM_Matrix.toFromTable.title != null && RM_Matrix.toFromTable.title.Length > 0)
2104 ghuddy 470
            needToFromTable = true;
471
 
472
         // NOTE: this code has to execute even if no from-to table is needed, in order to support the
473
         // generation of a to-from table, assuming the user has requested one.
474
         int numberOfFromToRows = 0;
2124 ghuddy 475
 
476
         Main.WriteOutput("   Creating from-to Dictionary", -1);
2104 ghuddy 477
 
478
         foreach(EA.Element fromElement in fromLister.Elements)
479
         {
2106 ghuddy 480
            if (createWordDoc.abortCreationThread)
481
               return;
482
 
2104 ghuddy 483
            // look at the elements connection collection to find references to the
484
            // destination elements
485
            bool foundToElement = false;
486
 
487
            EA.Collection conCollection = fromElement.Connectors;
488
 
489
            foreach (EA.Connector thisCon in conCollection)
490
            {
2106 ghuddy 491
               if (createWordDoc.abortCreationThread)
492
                  return;
493
 
494
               EA.Element destE = Main.EA_Repository.GetElementByID( thisCon.SupplierID );
2104 ghuddy 495
               if (destE == null)
496
                  continue;
497
 
498
               // ignore self-referential connections
499
               if (fromElement.ElementID == thisCon.SupplierID)
500
                  continue;
501
 
502
               // if the destination element is of a type that the user has requested to include...
2122 ghuddy 503
               if (!RM_Matrix.to.elementTypes.Contains( destE.Type ))
2104 ghuddy 504
                  continue;
505
 
2120 ghuddy 506
               // if the destination element is in the "to list"...
507
               if ( !toLister.ElementIds.Contains(destE.ElementID) )
508
                  continue;
509
 
2104 ghuddy 510
               // Capture the from-to relationship in a dictionary where the key is the
511
               // "from element", and the value is the "to element".
512
               DictionaryEntry newFromToEntry = new DictionaryEntry(fromElement, destE);
513
               fromToDictionary.Add( newFromToEntry );
514
               foundToElement = true;
515
 
516
               // Capture the from-to relationship in a dictionary where the key is the
517
               // ID of the destination element, and the value is the from element name.
518
               // This dictionary will enable rapid construction of the to-from table if
519
               // the user has requested it, from the exact same relationship info used
520
               // to construct the from-to table.
521
               if (needToFromTable)
522
               {
523
                  DictionaryEntry newToFromEntry = new DictionaryEntry(destE.ElementID, fromElement.Name);
524
                  toFromDictionary.Add( newToFromEntry );
525
               }
526
            }
527
 
528
            // If we found a from-to relationship that table needs a new row.
529
            if (foundToElement)
530
            {
531
               numberOfFromToRows++;
532
            }
533
               // If we did not find a from-to relationship that table still needs a new row 
534
               // if the user wants all "from elements", even if some have no "to elements".
2122 ghuddy 535
            else if (RM_Matrix.from.packageTrimming == false)
2104 ghuddy 536
            {
537
               DictionaryEntry newFromToEntry = new DictionaryEntry(fromElement, null);
538
               fromToDictionary.Add( newFromToEntry );
539
               numberOfFromToRows++;
540
            }
541
         }
542
 
2106 ghuddy 543
         if (createWordDoc.abortCreationThread)
544
            return;
545
 
2104 ghuddy 546
         if (needFromToTable)
547
         {
548
            // Now we can actually serialise the table
549
 
2124 ghuddy 550
            Main.WriteOutput("   Creating from-to table", -1);
551
 
2122 ghuddy 552
            if (RM_Matrix.fromToTable.introText != null && RM_Matrix.fromToTable.introText.Length > 0)
2104 ghuddy 553
            {
2136 brianf 554
               Range wr = TextualContent.appendAndSelectText( RM_Matrix.fromToTable.introText, EA_Constants.styleName_Body1 );
2122 ghuddy 555
               object obj = string.Format("EA_DocGen Informational Comment - This table has been produced using the following options:\n\n{0}", RM_Element.Notes);
556
               createWordDoc.WordDocument.Comments.Add(wr, ref obj);
2104 ghuddy 557
            }
558
 
559
            // create the from-to table in the word doc
2122 ghuddy 560
            tableNum = TabularContent.Table_Create( RM_Matrix.fromToTable.title, true, numberOfFromToRows + 1, 2 );
2106 ghuddy 561
            table = createWordDoc.WordDocument.Tables[tableNum];
2104 ghuddy 562
 
2122 ghuddy 563
            TabularContent.Table_SetTableColumnTitle(table, RM_Matrix.from.columnTitle, 1);
564
            TabularContent.Table_SetTableColumnTitle(table, RM_Matrix.to.columnTitle, 2);
2104 ghuddy 565
 
2118 ghuddy 566
            fillInTable(fromToDictionary, table, DictionaryValueType.DVT_EA_ELEMENT);
2104 ghuddy 567
         }
568
 
2106 ghuddy 569
         if (createWordDoc.abortCreationThread)
570
            return;
571
 
2104 ghuddy 572
         // Does user want a to-from table ?
573
         if (needToFromTable)
574
         {
2124 ghuddy 575
            Main.WriteOutput("   Creating to-from Dictionary", -1);
576
 
2118 ghuddy 577
            // update fromElementNotes with toElementNotes setting
2122 ghuddy 578
            RM_Matrix.from.elementNotes = RM_Matrix.to.elementNotes;
2118 ghuddy 579
 
2104 ghuddy 580
            // re-use the fromToDictionary to prepare the to-from table content 
581
            fromToDictionary.Clear();
582
 
2120 ghuddy 583
            // We've already found all elements for the left hand column of the to-from table.
584
            // They are stored in the toLister
2104 ghuddy 585
 
2106 ghuddy 586
            if (createWordDoc.abortCreationThread)
587
               return;
588
 
2104 ghuddy 589
            // To make the to-from table, we use the dictionary that was built when making the from-to
590
            // table. The dictionary will allow rapid determination of what "from" items belong to each
591
            // "to" item, without us having to go back to EA and enquire on the database.
592
            // We build a new fromToDictionary from the toFromDictionary, in advance of actually making 
593
            // the table so that we can figure out how many rows the table needs to have.
594
            numberOfFromToRows = 0;
595
 
596
            foreach(EA.Element toElement in toLister.Elements)
597
            {
2106 ghuddy 598
               if (createWordDoc.abortCreationThread)
599
                  return;
600
 
2104 ghuddy 601
               bool foundToElement = false;
602
 
603
               // right-column cell content
604
               foreach (DictionaryEntry de in toFromDictionary)
605
               {
606
                  if ((int)de.Key == toElement.ElementID)
607
                  {
608
                     DictionaryEntry newFromToEntry = new DictionaryEntry(toElement, (string)de.Value);
609
                     fromToDictionary.Add( newFromToEntry );
610
                     foundToElement = true;
611
                  }
612
               }
613
 
2106 ghuddy 614
               if (createWordDoc.abortCreationThread)
615
                  return;
616
 
2104 ghuddy 617
               // If we found a from-to relationship that table needs a new row.
618
               if (foundToElement)
619
               {
620
                  numberOfFromToRows++;
621
               }
622
                  // if user wants all "from elements", even if some have no "to elements", then add a dictionary
623
                  // entry and bump row count.
2122 ghuddy 624
               else if (RM_Matrix.to.packageTrimming == false)
2104 ghuddy 625
               {
626
                  DictionaryEntry newFromToEntry = new DictionaryEntry(toElement, "");
627
                  fromToDictionary.Add( newFromToEntry );
628
                  numberOfFromToRows++;
629
               }
630
            }
631
 
2106 ghuddy 632
            if (createWordDoc.abortCreationThread)
633
               return;
634
 
2104 ghuddy 635
            // Now begin to add the to-from table to the word document
2124 ghuddy 636
            Main.WriteOutput("   Creating to-from table", -1);
637
 
2122 ghuddy 638
            if (RM_Matrix.toFromTable.introText != null && RM_Matrix.toFromTable.introText.Length > 0)
2104 ghuddy 639
            {
2136 brianf 640
               Range wr = TextualContent.appendAndSelectText( RM_Matrix.toFromTable.introText, EA_Constants.styleName_Body1 );
2122 ghuddy 641
 
642
               // add options comment only if user did not generate a from-to table, since there is no point in repeating
643
               // the options comment which applies to both from-to and to-from table pair.
644
               if (!needFromToTable)
645
               {
646
                  object obj = string.Format("EA_DocGen Informational Comment - This table has been produced using the following options:\n\n{0}", RM_Element.Notes);
647
                  createWordDoc.WordDocument.Comments.Add(wr, ref obj);
648
               }
2104 ghuddy 649
            }
650
 
651
            // create the table in the word doc
2122 ghuddy 652
            tableNum = TabularContent.Table_Create( RM_Matrix.toFromTable.title, true, numberOfFromToRows + 1, 2 );
2106 ghuddy 653
            table = createWordDoc.WordDocument.Tables[tableNum];
2104 ghuddy 654
 
2122 ghuddy 655
            TabularContent.Table_SetTableColumnTitle(table, RM_Matrix.to.columnTitle, 1);
656
            TabularContent.Table_SetTableColumnTitle(table, RM_Matrix.from.columnTitle, 2);
2104 ghuddy 657
 
2118 ghuddy 658
            fillInTable(fromToDictionary, table, DictionaryValueType.DVT_STRING);
2104 ghuddy 659
         }
660
      }
661
 
2122 ghuddy 662
 
2136 brianf 663
        private static void fillInTable(ArrayList fromToDictionary, Table table, DictionaryValueType valueType)
2104 ghuddy 664
      {
665
         int lastFromElementId = -1;
2118 ghuddy 666
         bool firstCellContent = true;
2104 ghuddy 667
         int row = 1;
668
         foreach (DictionaryEntry de in fromToDictionary)
669
         {
2106 ghuddy 670
            if (createWordDoc.abortCreationThread)
671
               return;
672
 
2104 ghuddy 673
            if ( ((EA.Element)de.Key).ElementID != lastFromElementId )
674
            {
675
               lastFromElementId = ((EA.Element)de.Key).ElementID;
676
               row++;
677
               table.Cell(row,1).Range.Text = ((EA.Element)de.Key).Name;
2118 ghuddy 678
               firstCellContent = true;
679
 
2122 ghuddy 680
               if (RM_Matrix.from.elementNotes)
2118 ghuddy 681
               {
2122 ghuddy 682
                  if (((EA.Element)de.Key).Notes != null && ((EA.Element)de.Key).Notes.Length > 0)
683
                  {
684
                     table.Cell(row,1).Range.Text += ((EA.Element)de.Key).Notes;
685
                  }
686
                  // Because we are including both the short description and the notes of the requirement
687
                  // in the cell, we need to discriminate them. We do this by bolding the short description,
688
                  // and reducing the font size of the notes to 8.
2136 brianf 689
                  Range wr = table.Cell(row,1).Range;
2122 ghuddy 690
                  wr.Sentences[1].Font.Bold = 1;
691
                  for(int i=2; i<=wr.Sentences.Count; i++)
692
                     wr.Sentences[i].Font.Size = 8;
2118 ghuddy 693
               }
2104 ghuddy 694
            }
2122 ghuddy 695
 
2118 ghuddy 696
            if ((valueType == DictionaryValueType.DVT_EA_ELEMENT) && (((EA.Element)de.Value) != null))
2104 ghuddy 697
            {
2118 ghuddy 698
               if (firstCellContent)
2104 ghuddy 699
               {
2118 ghuddy 700
                  firstCellContent = false;
701
                  table.Cell(row,2).Range.Text = ((EA.Element)de.Value).Name;
702
               }
703
               else
704
               {
705
                  table.Cell(row,2).Range.Text += ((EA.Element)de.Value).Name;
706
               }
707
            }
708
            else if ((valueType == DictionaryValueType.DVT_STRING) && (((string)de.Value).Length > 0))
709
            {
710
               if (firstCellContent)
711
               {
712
                  firstCellContent = false;
2104 ghuddy 713
                  table.Cell(row,2).Range.Text = (string)de.Value;
714
               }
715
               else
716
               {
717
                  table.Cell(row,2).Range.Text += (string)de.Value;
718
               }
719
            }
720
            else
721
            {
2116 ghuddy 722
               if (EA_DocGenOptions.optionValue(EA_DocGenOptions.boolean_options_e.SUPPRESS_UN_ALLOCATED_RELATIONSHIP_WARNINGS) == false)
2104 ghuddy 723
               {
724
                  table.Cell(row,2).Range.Text = "Un-allocated relationship!";
2136 brianf 725
                  table.Cell(row,2).Range.Font.Color = WdColor.wdColorRed;
2104 ghuddy 726
               }
727
            }
728
         }
729
      }
730
 
2122 ghuddy 731
 
2104 ghuddy 732
      /// <summary>
733
      /// This function will insert a relationship matrix table into the document, built from content
734
      /// specified in options that are provided in the notes section of the special element that
735
      /// has led to this function being called.
736
      /// 
737
      /// The style of this single table is that required for requirement to requirement traceability.
738
      /// Here, only a single table is generated, and the only elements in the left hand column will
739
      /// be those serialised to the document earlier on, and the content of the right hand column
740
      /// will be the parental requirements (all the way up to root requirements).
741
      /// </summary>
742
      /// <param name="EA_RelMatrix"></param>
2106 ghuddy 743
      private static void processRelationshipMatrixElementStyle2()
2104 ghuddy 744
      {
745
         int i;
746
         int tableNum = 0;
2136 brianf 747
         Table table = null;
2104 ghuddy 748
 
749
         // Scan the fromPackage to find all the "from elements".
2124 ghuddy 750
         Main.WriteOutput("   Finding elements in fromPackage", -1);
751
 
2122 ghuddy 752
         ElementAccumulator fromLister = new ElementAccumulator(RM_Matrix.from.elementTypes);
753
         EA_Utilities.findAndProcessPackageElements( fromPackage, fromLister, RM_Matrix.from.packageRecursion );
2104 ghuddy 754
 
2106 ghuddy 755
         if (createWordDoc.abortCreationThread)
756
            return;
757
 
2104 ghuddy 758
         // Remove all elements from the list that did not go to form content in the document
759
         // prior to this point in the document generation process.
760
         for (i=0; i<fromLister.Elements.Count; )
761
         {
2106 ghuddy 762
            if (createWordDoc.abortCreationThread)
763
               return;
764
 
2104 ghuddy 765
            if ( !processedElements.Contains( ((EA.Element)fromLister.Elements[i]).ElementID ) )
766
            {
767
               fromLister.Elements.RemoveAt(i);
768
               continue;
769
            }
770
            i++;
771
         }
772
 
2106 ghuddy 773
         if (createWordDoc.abortCreationThread)
774
            return;
775
 
2104 ghuddy 776
         // Sort the remaining "from elements"
2124 ghuddy 777
         Main.WriteOutput("   Sorting elements in fromPackage", -1);
2106 ghuddy 778
 
2124 ghuddy 779
         if (RM_Matrix.from.reqTagSort)
780
         {
781
            elementSortByTAG sorter = new elementSortByTAG();
782
            fromLister.Elements.Sort( sorter );
783
         }
784
         else
785
         {
786
            elementSortByName sorter = new elementSortByName();
787
            fromLister.Elements.Sort( sorter );
788
         }
789
 
2106 ghuddy 790
         if (createWordDoc.abortCreationThread)
791
            return;
792
 
2104 ghuddy 793
         // Scan the toPackage to find all the "to elements".
794
         // Extract their element IDs into a new list.
2124 ghuddy 795
         Main.WriteOutput("   Finding elements in toPackage", -1);
796
 
2122 ghuddy 797
         ElementAccumulator toLister = new ElementAccumulator(RM_Matrix.to.elementTypes);
798
         EA_Utilities.findAndProcessPackageElements( toPackage, toLister, RM_Matrix.to.packageRecursion );
2104 ghuddy 799
         ArrayList acceptableParents = new ArrayList();
800
         foreach(EA.Element ele in toLister.Elements)
801
         {
2106 ghuddy 802
            if (createWordDoc.abortCreationThread)
803
               return;
804
 
2104 ghuddy 805
            acceptableParents.Add( ele.ElementID);
806
         }
807
 
2106 ghuddy 808
         if (createWordDoc.abortCreationThread)
809
            return;
810
 
2104 ghuddy 811
         // The list of from elements dictates the number of rows in our table.
812
         int numberOfFromToRows = fromLister.Elements.Count;
813
 
2124 ghuddy 814
         Main.WriteOutput("   Creating from-to table", -1);
815
 
2122 ghuddy 816
         if (RM_Matrix.fromToTable.introText != null && RM_Matrix.fromToTable.introText.Length > 0)
2104 ghuddy 817
         {
2136 brianf 818
            Range wr = TextualContent.appendAndSelectText( RM_Matrix.fromToTable.introText, EA_Constants.styleName_Body1 );
2122 ghuddy 819
            object obj = string.Format("EA_DocGen Informational Comment - This table has been produced using the following options:\n\n{0}", RM_Element.Notes);
820
            createWordDoc.WordDocument.Comments.Add(wr, ref obj);
2104 ghuddy 821
         }
822
 
823
         // create the from-to table in the word doc
2122 ghuddy 824
         tableNum = TabularContent.Table_Create( RM_Matrix.fromToTable.title, true, numberOfFromToRows + 1, 2 );
2106 ghuddy 825
         table = createWordDoc.WordDocument.Tables[tableNum];
2104 ghuddy 826
 
2122 ghuddy 827
         TabularContent.Table_SetTableColumnTitle(table, RM_Matrix.from.columnTitle, 1);
828
         TabularContent.Table_SetTableColumnTitle(table, RM_Matrix.to.columnTitle, 2);
2104 ghuddy 829
 
830
         int row = 2;
831
         foreach(EA.Element ele in fromLister.Elements)
832
         {
2106 ghuddy 833
            if (createWordDoc.abortCreationThread)
834
               return;
835
 
2104 ghuddy 836
            table.Cell(row,1).Range.Text = ele.Name;
837
 
2122 ghuddy 838
            if (RM_Matrix.from.elementNotes && ele.Notes != null && ele.Notes.Length > 0)
2118 ghuddy 839
            {
840
               table.Cell(row,1).Range.Text += ele.Notes;
841
            }
842
 
2104 ghuddy 843
            StringBuilder sb = new StringBuilder();
844
 
845
            ArrayList parentsDiscovered = new ArrayList();
846
 
847
            // Find this requirement's parent (source) requirements
848
            elementParenthood(ele, ref acceptableParents, ref parentsDiscovered, ref sb);
849
 
850
            // if no source requirements found and user has opted for trimming, delete the table row
2122 ghuddy 851
            if (RM_Matrix.from.packageTrimming == true && sb.Length == 0)
2104 ghuddy 852
            {
2106 ghuddy 853
               TabularContent.Table_DeleteThisRow(table, row);
2104 ghuddy 854
               continue;
855
            }
856
 
857
            // fill in the right hand cell on this row of the table with the source requirement list
858
            table.Cell(row,2).Range.Text = sb.ToString();
859
            row++;
860
         }
861
 
862
      }
863
 
2122 ghuddy 864
 
2106 ghuddy 865
      private static void elementParenthood(EA.Element ele, ref ArrayList acceptableParents, ref ArrayList parentsDiscovered, ref StringBuilder sb)
2104 ghuddy 866
      {
867
         foreach(EA.Connector con in ele.Connectors)
868
         {
2106 ghuddy 869
            if (createWordDoc.abortCreationThread)
870
               return;
871
 
2104 ghuddy 872
            // ignore downwards direction, indicated by the client ID being equal to the element ID
873
            if (con.ClientID != ele.ElementID)
874
            {
875
               // if we have not already come across this upward path before...
876
               if (!parentsDiscovered.Contains(con.ClientID))
877
               {
878
                  parentsDiscovered.Add(con.ClientID);
879
 
2120 ghuddy 880
                  // if this parent is in the list of acceptable parents...
2104 ghuddy 881
                  if (acceptableParents.Contains(con.ClientID))
882
                  {
883
                     // get the parent element, add its name to our list, and ascend through the element
884
                     // using recursion.
2106 ghuddy 885
                     EA.Element client = Main.EA_Repository.GetElementByID(con.ClientID);
2104 ghuddy 886
                     if (client != null)
887
                     {
888
                        if (sb.Length > 0)
889
                           sb.Append("\n");
890
                        sb.Append(client.Name);
891
 
892
                        elementParenthood(client, ref acceptableParents, ref parentsDiscovered, ref sb);
893
                     }
894
                  }
895
               }
896
            }
897
         }
898
      }
899
 
2088 ghuddy 900
	}
901
}