Subversion Repositories DevTools

Rev

Rev 2102 | Rev 2106 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 2102 Rev 2104
Line 25... Line 25...
25
      private EA_Utilities EA_Utils = null;
25
      private EA_Utilities EA_Utils = null;
26
 
26
 
27
      private TabularContent TableUtils = null;
27
      private TabularContent TableUtils = null;
28
      private TextualContent TextUtils = null;
28
      private TextualContent TextUtils = null;
29
      private StyleContent   StyleUtils = null;
29
      private StyleContent   StyleUtils = null;
-
 
30
      private DocSectionTracking DocSectionTracker = null;
30
 
31
 
31
      private bool oneShot_skipRootPackage = false;
32
      private bool oneShot_skipRootPackage = false;
32
      private bool oneShot_skipRootElementHeading = false;
33
      private bool oneShot_skipRootElementHeading = false;
33
 
34
 
-
 
35
      private int processingLink = 0;
-
 
36
 
-
 
37
      private ArrayList processedElements = null;
-
 
38
 
34
      // This data is designed to support unit test traceability. As such, it is only of real use
39
      // This data is designed to support unit test traceability. As such, it is only of real use
35
      // when making s/w design documents. It allows all non-private classes to be collected into
40
      // when making s/w design documents. It allows all non-private classes to be collected into
36
      // a list in order to generate a design-to-unit-test traceability table.
41
      // a list in order to generate a design-to-unit-test traceability table.
37
      private bool recordingNonPrivateClasses = false;
-
 
38
      private ArrayList nonPrivateClasses = null;
42
      private ArrayList classesNeedingUnitTests = null;
39
      private ArrayList classesWithUnitTests = null;
43
      private ArrayList classesWithUnitTests = null;
40
      private Word.Table utTraceabilityTable = null;
44
      private Word.Table utTraceabilityTable = null;
41
 
45
 
42
      // MS-Office Word related data
46
      // MS-Office Word related data
43
      private Word.Application WordApp = null;
47
      private Word.Application WordApp = null;
44
      private Word.Document WordDocument = null;
48
      private Word.Document WordDocument = null;
45
 
49
 
46
      private int[] DocSection = null;
-
 
47
      private int   iDocSection = 0;
-
 
48
 
-
 
49
      private System.Windows.Forms.TextBox textBox_template;
50
      private System.Windows.Forms.TextBox textBox_template;
50
      private System.Windows.Forms.Button button_browse_template;
51
      private System.Windows.Forms.Button button_browse_template;
51
      private System.Windows.Forms.TextBox textBox_output_file;
52
      private System.Windows.Forms.TextBox textBox_output_file;
52
      private System.Windows.Forms.Button button_browse_output_file;
53
      private System.Windows.Forms.Button button_browse_output_file;
53
      private System.Windows.Forms.Button button_cancel;
54
      private System.Windows.Forms.Button button_cancel;
Line 74... Line 75...
74
         EA_ParentPackage = theParentPackage;
75
         EA_ParentPackage = theParentPackage;
75
         EA_Project       = EA_Repository.GetProjectInterface();
76
         EA_Project       = EA_Repository.GetProjectInterface();
76
 
77
 
77
         EA_Utils         = theEA_Utils;
78
         EA_Utils         = theEA_Utils;
78
 
79
 
79
         TableUtils       = new TabularContent(WordApp, WordDocument);
-
 
80
         TextUtils        = new TextualContent(WordApp, WordDocument);
-
 
81
         StyleUtils       = new StyleContent(WordApp, WordDocument);
80
         DocSectionTracker = new DocSectionTracking();
82
 
81
 
-
 
82
         TableUtils        = new TabularContent(WordApp, WordDocument, EA_Utils);
-
 
83
         TextUtils         = new TextualContent(WordApp, WordDocument, DocSectionTracker);
-
 
84
         StyleUtils        = new StyleContent(WordApp, WordDocument);
83
 
85
 
84
         DocSection = new int[12];
-
 
85
         for (int i=0; i<DocSection.Length; i++)
-
 
86
         {
-
 
87
            DocSection[i] = 0;
-
 
88
         }
86
         
89
 
87
 
90
         WordApp = new Word.Application();
88
         WordApp = new Word.Application();
91
      }
89
      }
92
 
90
 
93
 
91
 
Line 353... Line 351...
353
      #endregion
351
      #endregion
354
 
352
 
355
 
353
 
356
      #region word document generation code
354
      #region word document generation code
357
 
355
 
358
      /// <summary>
-
 
359
      /// This class is one derived from the EA_UtilitiesRecursionWorker base class so that
-
 
360
      /// an instance of it can be used as a parameter in the EA_Utilities.findAndProcessPackageElements
-
 
361
      /// method which recursively parses a given package. Thus, clients can parse EA model structure but
-
 
362
      /// specify their own functionality to be carried out on packages and elements found in the 
-
 
363
      /// parsing.
-
 
364
      /// This particular derived class is designed to collect a list of element names from the
-
 
365
      /// package, from elements that have a type that is acceptable.
-
 
366
      /// </summary>
-
 
367
      public class ElementAccumulator : EA_UtilitiesRecursionWorker
-
 
368
      {
-
 
369
         public ArrayList Elements = null;
-
 
370
 
356
 
371
         private ArrayList validElementTypes = null;
-
 
372
 
-
 
373
         private EA_Utilities EA_Utils = null;
-
 
374
 
-
 
375
         public ElementAccumulator(ArrayList elementTypeList, EA_Utilities theEA_Utils): base()
-
 
376
         {
-
 
377
            validElementTypes = elementTypeList;
-
 
378
            EA_Utils = theEA_Utils;
-
 
379
            Elements = new ArrayList();
-
 
380
         }
-
 
381
 
-
 
382
         public override void processElement( EA.Element theElement )
-
 
383
         {
-
 
384
            if (validElementTypes.Contains( theElement.Type ))
-
 
385
            {
-
 
386
               //if ( (theElement.Type == "Requirement") && (theElement.Status == "Rejected") )
-
 
387
               //   return;
-
 
388
 
-
 
389
               if (   0 == theElement.Type.CompareTo("Class")
-
 
390
                  && true == EA_Utils.options.opt_SuppressPrivateClasses
-
 
391
                  && true == theElement.Visibility.StartsWith("Private") )
-
 
392
               {
-
 
393
                  // do nothing
-
 
394
               }
-
 
395
               else
-
 
396
               {
-
 
397
                  Elements.Add( theElement );
-
 
398
               }
-
 
399
            }
-
 
400
         }
-
 
401
      }
-
 
402
 
-
 
403
 
-
 
404
      private void trackDocSection(int recurse_level)
-
 
405
      {
-
 
406
         iDocSection = recurse_level;
-
 
407
         DocSection[iDocSection]++;     
-
 
408
         for (int i=iDocSection+1; i<DocSection.Length; i++)
-
 
409
            DocSection[i] = 0;
-
 
410
      }
-
 
411
 
357
 
412
 
358
 
413
      /// <summary>
359
      /// <summary>
414
      /// Displays progress of the document generation in the createWordDocument dialog
360
      /// Displays progress of the document generation in the createWordDocument dialog
415
      /// </summary>
361
      /// </summary>
Line 419... Line 365...
419
      {
365
      {
420
         textBox_progress.AppendText( prefix + EA_string + "\r\n" );
366
         textBox_progress.AppendText( prefix + EA_string + "\r\n" );
421
 
367
 
422
         // Display to the output tab as well - as a longer term record of what happened
368
         // Display to the output tab as well - as a longer term record of what happened
423
         StringBuilder sb = new StringBuilder("");
369
         StringBuilder sb = new StringBuilder("");
424
         for (int i = 1; i<=iDocSection; i++)
-
 
425
         {
370
 
426
            if (i!=1)
-
 
427
               sb.Append(".");
-
 
428
            sb.Append(DocSection[i].ToString());
371
         DocSectionTracker.appendHeadingNumber(ref sb);
429
         }
372
 
430
         while (sb.Length < 30)
373
         while (sb.Length < 30)
431
            sb.Append(" ");
374
            sb.Append(" ");
432
 
375
 
433
         sb.Append(prefix);
376
         sb.Append(prefix);
434
         sb.Append(EA_string);
377
         sb.Append(EA_string);
Line 443... Line 386...
443
      /// pasting it into the document, it sets the style and other aspects of the image.
386
      /// pasting it into the document, it sets the style and other aspects of the image.
444
      /// </summary>
387
      /// </summary>
445
      /// <param name="theDiagram"></param>
388
      /// <param name="theDiagram"></param>
446
      private void appendAndSelectDiagramViaClipboard(EA.Diagram theDiagram)
389
      private void appendAndSelectDiagramViaClipboard(EA.Diagram theDiagram)
447
      {
390
      {
-
 
391
         // NOTE: diagrams only use one stereotype, not a list of them, so dont use StereotypeEx field
-
 
392
         if (  EA_Utils.options.opt_ConsiderAPIDiagramsOnly 
-
 
393
            && !theDiagram.Stereotype.Equals("API") )
-
 
394
         {
-
 
395
            displayProgress( "SKIPPED DIAGRAM: ", theDiagram.Name.ToString() );
-
 
396
         }
448
         // open the diagram in EA and copy it's image to the clipboard
397
         // open the diagram in EA and copy it's image to the clipboard
449
         if (EA_Project.PutDiagramImageOnClipboard(theDiagram.DiagramGUID,0))
398
         else if (EA_Project.PutDiagramImageOnClipboard(theDiagram.DiagramGUID,0))
450
         {
399
         {
451
            object startLocation;
400
            object startLocation;
452
            object endLocation;
401
            object endLocation;
453
 
402
 
454
            TextUtils.appendDescription( theDiagram.Notes, EA_Utils );
403
            TextUtils.appendDescription( theDiagram.Notes, EA_Utils );
Line 500... Line 449...
500
            //bookmarkName = bookmarkName.Replace(' ', '_');
449
            //bookmarkName = bookmarkName.Replace(' ', '_');
501
            //WordDocument.Bookmarks.Add( bookmarkName, ref lastParaRange );
450
            //WordDocument.Bookmarks.Add( bookmarkName, ref lastParaRange );
502
 
451
 
503
            // Close the diagram in EA
452
            // Close the diagram in EA
504
            EA_Repository.CloseDiagram(theDiagram.DiagramID);
453
            EA_Repository.CloseDiagram(theDiagram.DiagramID);
-
 
454
 
-
 
455
            displayProgress( "DIAGRAM: ", theDiagram.Name.ToString() );
505
         }
456
         }
506
      }
457
      }
507
 
458
 
508
 
459
 
509
      #region special element processing functions (link elements, table and text elements, etc)
460
      #region special element processing functions (link elements, table and text elements, etc)
Line 579... Line 530...
579
               if (s[0] == '{')
530
               if (s[0] == '{')
580
               {
531
               {
581
                  EA.Diagram theFoundDiagram = EA_Utils.EA_Finder.findDiagramInRepositoryByGUID(s);
532
                  EA.Diagram theFoundDiagram = EA_Utils.EA_Finder.findDiagramInRepositoryByGUID(s);
582
                  if (theFoundDiagram != null)
533
                  if (theFoundDiagram != null)
583
                  {
534
                  {
584
                     displayProgress( "DIAGRAM: ", theFoundDiagram.Name.ToString() );
-
 
585
                     appendAndSelectDiagramViaClipboard( theFoundDiagram );
535
                     appendAndSelectDiagramViaClipboard( theFoundDiagram );
586
                  }
536
                  }
587
                  else 
537
                  else 
588
                  {
538
                  {
589
                     MessageBox.Show("WARNING - Could not find linked diagram : " + linkedName );
539
                     MessageBox.Show("WARNING - Could not find linked diagram : " + linkedName );
Line 640... Line 590...
640
         }         
590
         }         
641
      }
591
      }
642
 
592
 
643
 
593
 
644
      /// <summary>
594
      /// <summary>
645
      /// This method creates a table from the content of an EA_DocGenTable element in the model.
595
      /// This method is recursive and searches a model structure to find a match to any 
646
      /// The elements notes section contains the table parameters and cell content.
596
      /// of the names given in a list. Matched package structure is then parsed for
647
      /// See the EA_Utilities::AddTableElement() method for the layout of this content.
597
      /// document content generation.
648
      /// </summary>
598
      /// </summary>
-
 
599
      /// <param name="parentPackage"></param>
649
      /// <param name="theElement"></param>
600
      /// <param name="thePackage"></param>
650
      /// <param name="recurse_level"></param>
601
      /// <param name="recurse_level"></param>
-
 
602
      /// <param name="skipRoots"></param>
-
 
603
      /// <param name="names"></param>
651
      private void processTableElement(EA.Element theElement, int recurse_level )
604
      private void processNameLinkPackage(EA.Package parentPackage, EA.Package thePackage, int recurse_level, bool skipRoots, ref ArrayList names)
652
      {
605
      {
653
         string [] EA_DocGenTable = null;
-
 
654
         string [] cells = null;
-
 
655
 
-
 
656
         string delimStr = "\r\n";
-
 
657
         char [] delim = delimStr.ToCharArray();
-
 
658
 
-
 
659
         string trimStr = " ";
-
 
660
         char [] trimChars = trimStr.ToCharArray();
606
         // search for the package name in the names[] list
661
 
-
 
662
         EA_DocGenTable = theElement.Notes.ToString().Split(delim,200);
-
 
663
 
-
 
664
         int columnCount = 0;
-
 
665
         int rowCount = 0;
607
         int i = 0;
666
         char seperator = ',';
-
 
667
         string tableTitle = "";
-
 
668
         bool gotSeperator = false;
-
 
669
         bool gotTitle = false;
608
         bool found = false;
670
        
-
 
671
         ArrayList colWidths = new ArrayList();
-
 
672
         int indent = 0;
-
 
673
 
-
 
674
         // Scan the notes content line by line looking for table parameters and counting
-
 
675
         // the number of table rows (which is not specified as an explicit table parameter).
-
 
676
         int s_ElementsConsumedByTableParams = 0;
-
 
677
         foreach(string s in EA_DocGenTable)
609
         foreach (string name in names)
678
         {
610
         {
-
 
611
            // users can specify parent\child in a name to help narrow down exactly what package they 
-
 
612
            // are looking for so deal with that, but the parent\ part is optional.
679
            if (s.Length > 0 && s != "\n" && s != "\r" )
613
            int splitpos = name.IndexOf('\\',0);
-
 
614
            if (splitpos >= 0)
680
            {
615
            {
681
               if (gotTitle == false && s.StartsWith("title"))
616
               if (parentPackage != null)
682
               {
617
               {
683
                  s_ElementsConsumedByTableParams++;
-
 
684
                  tableTitle = EA_Utils.options.getOptionValue(s, tableTitle);
618
                  if (name.Substring(0,splitpos).Equals(parentPackage.Name))
685
                  gotTitle = true;
-
 
686
                  if (tableTitle == "")
-
 
687
                  {
619
                  {
688
                     MessageBox.Show( "Table Element Serialisation Failed - Bad Title" );
620
                     if (name.Substring(splitpos+1).Equals(thePackage.Name))
-
 
621
                     {
-
 
622
                        found = true;
689
                     break;
623
                        break;
-
 
624
                     }
690
                  }
625
                  }
691
               }
626
               }
692
            
627
               else
693
               else if (columnCount == 0 && s.StartsWith("columns"))
-
 
694
               {
628
               {
695
                  s_ElementsConsumedByTableParams++;
-
 
696
                  columnCount = EA_Utils.options.getOptionValue(s, columnCount);
629
                  if (name.Substring(splitpos+1).Equals(thePackage.Name))
697
                  if (columnCount == 0)
-
 
698
                  {
630
                  {
699
                     MessageBox.Show( "Table Element Serialisation Failed - bad column count" );
631
                     found = true;
700
                     break;
632
                     break;
701
                  }
633
                  }
702
               }
634
               }
-
 
635
            }
-
 
636
            else
703
 
637
            {
704
               else if (gotSeperator == false && s.StartsWith("seperator"))
638
               if (name.Equals(thePackage.Name))
705
               {
639
               {
706
                  s_ElementsConsumedByTableParams++;
640
                  found = true;
707
                  seperator = EA_Utils.options.getOptionValue(s, seperator);
-
 
708
                  gotSeperator = true;
641
                  break;
709
               }
642
               }
-
 
643
            }
-
 
644
            i++;
-
 
645
         }
710
 
646
 
-
 
647
         if (found)
-
 
648
         {
-
 
649
            // remove the found name, arm the skiproot mechanism if needed, and parse the package
-
 
650
            names.RemoveAt(i);
-
 
651
            if (skipRoots == true)
711
               else if (s.StartsWith("widths"))
652
               oneShot_skipRootPackage = true;
-
 
653
 
-
 
654
            parse_package(thePackage, recurse_level);
-
 
655
         }
-
 
656
         else if (names.Count > 0)  // any names left to process?
712
               {
657
         {
713
                  s_ElementsConsumedByTableParams++;
658
            // recurse for each of this packages sub-packages
714
                  string optValStr = EA_Utils.options.getOptionValue(s, "");
659
            foreach(EA.Package subPackage in thePackage.Packages)
-
 
660
            {
-
 
661
               processNameLinkPackage(thePackage, subPackage, recurse_level, skipRoots, ref names);                        
-
 
662
            }         
-
 
663
         }
-
 
664
      }
715
 
665
 
-
 
666
      private void processNameLink(EA.Element theElement, int recurse_level )
-
 
667
      {
716
                  string width_delimStr = ",";
668
         string delimStr = "\r\n";
717
                  char [] width_delim = width_delimStr.ToCharArray();
669
         char [] delim = delimStr.ToCharArray();
-
 
670
         string [] EA_DocGenNameLnk = theElement.Notes.ToString().Split(delim,100);
718
 
671
 
-
 
672
         string linkedName = "";
719
                  string [] width_strings = optValStr.Split(width_delim, 50);
673
         bool gotLinkedName = false;
720
 
674
 
721
                  foreach (string ws in width_strings)
-
 
722
                  {
-
 
723
                     if (ws.Length > 0 && ws != "\n" && ws != "\r" )
-
 
724
                     {
-
 
725
                        colWidths.Add( System.Convert.ToDouble(ws) );
-
 
726
                     }
-
 
727
                  }
-
 
728
               }
-
 
729
               else if (s.StartsWith("indent"))
675
         ArrayList names = new ArrayList();
730
               {
-
 
731
                  s_ElementsConsumedByTableParams++;
-
 
732
                  indent = EA_Utils.options.getOptionValue(s, 0);
-
 
733
               }
-
 
734
               else
-
 
735
               {
-
 
736
                  rowCount++;
-
 
737
               }
-
 
738
            }
-
 
739
         }
-
 
740
 
676
 
-
 
677
         EA.Package theFoundPackage = null;
-
 
678
 
-
 
679
         bool skipRoots = false;
-
 
680
 
741
         if (gotTitle == true && gotSeperator == true && columnCount != 0)
681
         // search through the option strings
-
 
682
         foreach(string s in EA_DocGenNameLnk)
742
         {
683
         {
743
            if (rowCount < 2)
684
            if (s.Length > 0 && s != "\n" && s != "\r")
744
            {
-
 
745
               MessageBox.Show( "Table Element Serialisation Failed - Insufficient Rows" );
-
 
746
            }
-
 
747
            else
-
 
748
            {
685
            {
749
               // create the table in the word doc
-
 
750
               int tableNum = TableUtils.Table_Create( tableTitle, rowCount, columnCount );
-
 
751
               Word.Table table = WordDocument.Tables[tableNum];
-
 
752
               object center = Word.WdParagraphAlignment.wdAlignParagraphCenter;
-
 
753
 
-
 
754
               int col = 1;
686
               if (s == "skiproot")
755
               foreach (double d in colWidths)
-
 
756
               {
687
               {
757
                  if (col <= columnCount)
-
 
758
                     table.Columns[col].SetWidth( WordApp.CentimetersToPoints((float)d), Word.WdRulerStyle.wdAdjustNone );
-
 
759
                  col++;
688
                  skipRoots = true;
760
               }
689
               }
761
 
-
 
762
               if (indent > 0)
690
               else if (s[0] == '{')  // is it a GUID?
763
               {
691
               {
764
                  table.Select();
-
 
765
                  while (indent > 0)
692
                  // find the package by its GUID
766
                  {
-
 
767
                     WordApp.Selection.Paragraphs.Indent();
693
                  theFoundPackage = EA_Utils.EA_Finder.findPackageInRepositoryByGUID(s);
768
                     indent--;
-
 
769
                  }
-
 
770
               }
694
               }
771
 
-
 
772
               // scan the element notes again to extract the cell content and add it to the
-
 
773
               // table we just created.
-
 
774
               int row = 1;
-
 
775
               col = 0;
-
 
776
               foreach(string s in EA_DocGenTable)
695
               else if (s.StartsWith("package="))
777
               {
696
               {
-
 
697
                  // add the users named package to our list of names
778
                  if (s.Length > 0 && s != "\n" && s != "\r" )
698
                  names.Add( s.Substring(8, s.Length - 8) );
779
                  {
699
               }
780
                     if (s_ElementsConsumedByTableParams > 0)
700
               else if (gotLinkedName == false)
781
                     {
701
               {
-
 
702
                  // capture name of package refered to by the GUID - this is only for diagnostic purposes
782
                        s_ElementsConsumedByTableParams--;
703
                  gotLinkedName = true;
783
                     }
704
                  linkedName = s;
784
                     else
705
               }            
785
                     {
706
            }
-
 
707
         }  
-
 
708
 
786
                        delimStr = seperator.ToString();
709
         // If the GUID was resolved...
787
                        delim = delimStr.ToCharArray();
710
         if (theFoundPackage != null)
-
 
711
         {
788
                        cells = s.Split(delim,columnCount);
712
            processNameLinkPackage(null, theFoundPackage, recurse_level, skipRoots, ref names);
789
 
713
 
790
                        if (cells.Length != columnCount)
-
 
791
                        {
-
 
792
                           MessageBox.Show( "Table Element Serialisation Failed - Bad Row" );
-
 
793
                           break;
-
 
794
                        }
714
            if (names.Count > 0)
795
                        else
-
 
796
                        {
715
            {
797
                           // serialise table row
716
               StringBuilder sb = new StringBuilder();
798
                           for(col=1; col<=columnCount; col++)
-
 
799
                           {
-
 
800
                              cells[col-1].TrimStart( trimChars );
717
               sb.Append("WARNING - Could not find named package(s)\n");
801
                              cells[col-1].TrimEnd( trimChars );
-
 
802
 
-
 
803
                              table.Cell(row,col).Range.Text = cells[col-1];
-
 
804
 
-
 
805
                              // special handling for heading row
-
 
806
                              if (row == 1)
718
               sb.Append("within name link: ");
807
                              {
719
               sb.Append(linkedName);
808
                                 table.Cell(row,col).Range.ParagraphFormat.Alignment = Word.WdParagraphAlignment.wdAlignParagraphCenter;
-
 
809
                                 table.Cell(row,col).Range.Font.Bold = 1;
720
               sb.Append("\n\nProblem package= directives are:\n");
810
                              }
721
               foreach(String s in names)
811
                           }
722
               {
812
                           row++;
723
                  sb.Append("\n");
813
                        }                     
-
 
814
                     }
724
                  sb.Append(s);
815
                  }
-
 
816
               }
725
               }
-
 
726
               MessageBox.Show(sb.ToString());
817
            }
727
            }
818
         }
728
         }
819
         else
729
         else
820
         {
730
         {
821
            MessageBox.Show( "Table Element Serialisation Failed - Table Parameters Incomplete" );
731
            MessageBox.Show("WARNING - Could not find linked package : " + linkedName );
822
         }
732
         }
823
      }
733
      }
824
 
734
 
825
 
-
 
826
 
-
 
827
      /// <summary>
735
      /// <summary>
828
      /// This function processes a test link element
736
      /// This function processes a name link element. These are elements that point
-
 
737
      /// (using a GUID) to a package, and the user has specified text names of sub-packages
-
 
738
      /// within the package that they wish to have processed for document generation.
-
 
739
      /// This is a useful way of getting content when you cannot be sure that the GUIDs
-
 
740
      /// of the packages you want will remain constant (eg. when re-using content from
-
 
741
      /// a reqpro import (for doc gen purposes)).
829
      /// </summary>
742
      /// </summary>
830
      /// <param name="theElement"></param>
743
      /// <param name="theElement"></param>
831
      /// <param name="recurse_level"></param>
744
      /// <param name="recurse_level"></param>
832
      private void processTestLink(EA.Element theElement, int recurse_level )
745
      private void processTestLink(EA.Element theElement, int recurse_level )
833
      {
746
      {
Line 846... Line 759...
846
                  try
759
                  try
847
                  {
760
                  {
848
                     // try to find the GUID as a package
761
                     // try to find the GUID as a package
849
                     EA.Package theFoundPackage = EA_Utils.EA_Finder.findPackageInRepositoryByGUID(s);
762
                     EA.Package theFoundPackage = EA_Utils.EA_Finder.findPackageInRepositoryByGUID(s);
850
                     if (theFoundPackage != null)
763
                     if (theFoundPackage != null)
851
                        TextUtils.appendUnitTestSuite(theFoundPackage, recurse_level, ref classesWithUnitTests);
764
                        TextUtils.appendUnitTestSuite(theFoundPackage, recurse_level, ref classesWithUnitTests, ref EA_Utils);
852
                     else 
765
                     else 
853
                     {
766
                     {
854
                        // try to find the GUID as an element
767
                        // try to find the GUID as an element
855
                        EA.Element theFoundElement = EA_Utils.EA_Finder.findElementInRepositoryByGUID(s);
768
                        EA.Element theFoundElement = EA_Utils.EA_Finder.findElementInRepositoryByGUID(s);
856
                        if (theFoundElement != null)
769
                        if (theFoundElement != null)
857
                           TextUtils.appendUnitTestSuite(theFoundElement, recurse_level, ref classesWithUnitTests);
770
                           TextUtils.appendUnitTestSuite(theFoundElement, recurse_level, ref classesWithUnitTests, ref EA_Utils);
858
                        else 
771
                        else 
859
                           MessageBox.Show("WARNING - Could not find linked element : " + linkedName );
772
                           MessageBox.Show("WARNING - Could not find linked element : " + linkedName );
860
                     }
773
                     }
861
                  }
774
                  }
862
                  catch 
775
                  catch 
863
                  {
776
                  {
864
                     // try to find the GUID as an element
777
                     // try to find the GUID as an element
865
                     EA.Element theFoundElement = EA_Utils.EA_Finder.findElementInRepositoryByGUID(s);
778
                     EA.Element theFoundElement = EA_Utils.EA_Finder.findElementInRepositoryByGUID(s);
866
                     if (theFoundElement != null)
779
                     if (theFoundElement != null)
867
                        TextUtils.appendUnitTestSuite(theFoundElement, recurse_level, ref classesWithUnitTests);
780
                        TextUtils.appendUnitTestSuite(theFoundElement, recurse_level, ref classesWithUnitTests, ref EA_Utils);
868
                     else 
781
                     else 
869
                        MessageBox.Show("WARNING - Could not find linked element : " + linkedName );
782
                        MessageBox.Show("WARNING - Could not find linked element : " + linkedName );
870
                  }
783
                  }
871
               }
784
               }
872
               else
785
               else
Line 876... Line 789...
876
            }
789
            }
877
         }         
790
         }         
878
      }
791
      }
879
 
792
 
880
 
793
 
881
 
-
 
882
      /// <summary>
-
 
883
      /// This function process a text element. It is a simple wrapper for the 
-
 
884
      /// appendAndSelectText()function.
-
 
885
      /// </summary>
-
 
886
      /// <param name="theElement"></param>
-
 
887
      /// <param name="recurse_level"></param>
-
 
888
      private void processTextElement(EA.Element theElement, int recurse_level )
-
 
889
      {
-
 
890
         TextUtils.appendAndSelectText( theElement.Notes.ToString(), EA_Constants.styleName_Body1 );
-
 
891
      }
-
 
892
 
-
 
893
 
-
 
894
      /// <summary>
-
 
895
      /// This function will insert a relationship matrix table into the document, built from content
-
 
896
      /// specified in options that are provided in the notes section of the special element that
-
 
897
      /// has led to this function being called.
-
 
898
      /// </summary>
-
 
899
      /// <param name="theElement"></param>
-
 
900
      /// <param name="recurse_level"></param>
-
 
901
      private void processRelationshipMatrixElement( EA.Element theElement, int recurse_level )
-
 
902
      {
-
 
903
         int tableNum = 0;
-
 
904
         Word.Table table = null;
-
 
905
 
-
 
906
         // process the options for the relationship matrix
-
 
907
         EA_RelationshipMatrix EA_RelMatrix = new EA_RelationshipMatrix(EA_Utils);
-
 
908
         if (!EA_RelMatrix.processRelationshipMatrixOptions( theElement ))
-
 
909
         {
-
 
910
            return;  // must have been an error
-
 
911
         }
-
 
912
 
-
 
913
         // Scan the fromPackage to find all the "from elements".
-
 
914
         ElementAccumulator fromLister = new ElementAccumulator(EA_RelMatrix.fromElementTypes, EA_Utils);
-
 
915
         EA_Utils.findAndProcessPackageElements( EA_RelMatrix.fromPackage, fromLister, EA_RelMatrix.fromPackageRecursion );
-
 
916
 
-
 
917
         // Sort the "from elements"
-
 
918
         elementSortByName sorter = new elementSortByName();
-
 
919
         fromLister.Elements.Sort( sorter );
-
 
920
 
-
 
921
         // dictionary to support from-to table construction.
-
 
922
         ArrayList fromToDictionary = new ArrayList();
-
 
923
 
-
 
924
         // dictionary to support to-from table construction.
-
 
925
         ArrayList toFromDictionary = new ArrayList();
-
 
926
         
-
 
927
         bool needFromToTable = false;
-
 
928
         if (EA_RelMatrix.fromToTableTitle != null && EA_RelMatrix.fromToTableTitle.Length > 0)
-
 
929
            needFromToTable = true;
-
 
930
 
-
 
931
         bool needToFromTable = false;
-
 
932
         if (EA_RelMatrix.toFromTableTitle != null && EA_RelMatrix.toFromTableTitle.Length > 0)
-
 
933
            needToFromTable = true;
-
 
934
 
-
 
935
         // NOTE: this code has to execute even if no from-to table is needed, in order to support the
-
 
936
         // generation of a to-from table, assuming the user has requested one.
-
 
937
         int numberOfFromToRows = 0;
-
 
938
         
-
 
939
         foreach(EA.Element fromElement in fromLister.Elements)
-
 
940
         {
-
 
941
            // look at the elements connection collection to find references to the
-
 
942
            // destination elements
-
 
943
            bool foundToElement = false;
-
 
944
 
-
 
945
            EA.Collection conCollection = fromElement.Connectors;
-
 
946
            
-
 
947
            foreach (EA.Connector thisCon in conCollection)
-
 
948
            {
-
 
949
               EA.Element destE = EA_Repository.GetElementByID( thisCon.SupplierID );
-
 
950
               if (destE == null)
-
 
951
                  continue;
-
 
952
 
-
 
953
               // ignore self-referential connections
-
 
954
               if (fromElement.ElementID == thisCon.SupplierID)
-
 
955
                  continue;
-
 
956
 
-
 
957
               // if the destination element is of a type that the user has requested to include...
-
 
958
               if (!EA_RelMatrix.toElementTypes.Contains( destE.Type ))
-
 
959
                  continue;
-
 
960
 
-
 
961
               // Capture the from-to relationship in a dictionary where the key is the
-
 
962
               // "from element", and the value is the "to element".
-
 
963
               DictionaryEntry newFromToEntry = new DictionaryEntry(fromElement, destE);
-
 
964
               fromToDictionary.Add( newFromToEntry );
-
 
965
               foundToElement = true;
-
 
966
 
-
 
967
               // Capture the from-to relationship in a dictionary where the key is the
-
 
968
               // ID of the destination element, and the value is the from element name.
-
 
969
               // This dictionary will enable rapid construction of the to-from table if
-
 
970
               // the user has requested it, from the exact same relationship info used
-
 
971
               // to construct the from-to table.
-
 
972
               if (needToFromTable)
-
 
973
               {
-
 
974
                  DictionaryEntry newToFromEntry = new DictionaryEntry(destE.ElementID, fromElement.Name);
-
 
975
                  toFromDictionary.Add( newToFromEntry );
-
 
976
               }
-
 
977
            }
-
 
978
 
-
 
979
            // If we found a from-to relationship that table needs a new row.
-
 
980
            if (foundToElement)
-
 
981
            {
-
 
982
               numberOfFromToRows++;
-
 
983
            }
-
 
984
               // If we did not find a from-to relationship that table still needs a new row 
-
 
985
               // if the user wants all "from elements", even if some have no "to elements".
-
 
986
            else if (EA_RelMatrix.fromPackageTrimming == false)
-
 
987
            {
-
 
988
               DictionaryEntry newFromToEntry = new DictionaryEntry(fromElement, null);
-
 
989
               fromToDictionary.Add( newFromToEntry );
-
 
990
               numberOfFromToRows++;
-
 
991
            }
-
 
992
         }
-
 
993
 
-
 
994
         
-
 
995
         if (needFromToTable)
-
 
996
         {
-
 
997
            // Now we can actually serialise the table
-
 
998
 
-
 
999
            if (EA_RelMatrix.fromIntroText != null && EA_RelMatrix.fromIntroText.Length > 0)
-
 
1000
            {
-
 
1001
               TextUtils.appendAndSelectText( EA_RelMatrix.fromIntroText, EA_Constants.styleName_Body1 );
-
 
1002
            }
-
 
1003
 
-
 
1004
            // create the from-to table in the word doc
-
 
1005
            tableNum = TableUtils.Table_Create( EA_RelMatrix.fromToTableTitle, numberOfFromToRows + 1, 2 );
-
 
1006
            table = WordDocument.Tables[tableNum];
-
 
1007
            
-
 
1008
            TableUtils.Table_SetTableColumnTitle(table, EA_RelMatrix.fromColumnTitle, 1);
-
 
1009
            TableUtils.Table_SetTableColumnTitle(table, EA_RelMatrix.toColumnTitle, 2);
-
 
1010
 
-
 
1011
            int row = 1;
-
 
1012
            int lastFromElementId = -1;
-
 
1013
            bool firstFromToCon = true;
-
 
1014
            foreach (DictionaryEntry de in fromToDictionary)
-
 
1015
            {
-
 
1016
               if ( ((EA.Element)de.Key).ElementID != lastFromElementId )
-
 
1017
               {
-
 
1018
                  lastFromElementId = ((EA.Element)de.Key).ElementID;
-
 
1019
                  row++;
-
 
1020
                  table.Cell(row,1).Range.Text = ((EA.Element)de.Key).Name;
-
 
1021
                  firstFromToCon = true;
-
 
1022
               }
-
 
1023
 
-
 
1024
               if (((EA.Element)de.Value) != null)
-
 
1025
               {
-
 
1026
                  if (firstFromToCon)
-
 
1027
                  {
-
 
1028
                     firstFromToCon = false;
-
 
1029
                     table.Cell(row,2).Range.Text = ((EA.Element)de.Value).Name;
-
 
1030
                  }
-
 
1031
                  else
-
 
1032
                  {
-
 
1033
                     table.Cell(row,2).Range.Text += ((EA.Element)de.Value).Name;
-
 
1034
                  }
-
 
1035
               }
-
 
1036
               else
-
 
1037
               {
-
 
1038
                  table.Cell(row,2).Range.Text = "Un-allocated relationship!";
-
 
1039
                  table.Cell(row,2).Range.Font.Color = Word.WdColor.wdColorRed;
-
 
1040
               }
-
 
1041
            }
-
 
1042
         }
-
 
1043
 
-
 
1044
         // Does user want a to-from table ?
-
 
1045
         if (needToFromTable)
-
 
1046
         {
-
 
1047
            // re-use the fromToDictionary to prepare the to-from table content 
-
 
1048
            fromToDictionary.Clear();
-
 
1049
 
-
 
1050
            // find all elements for the left hand column of the to-from table.
-
 
1051
            ElementAccumulator toLister = new ElementAccumulator(EA_RelMatrix.toElementTypes, EA_Utils);
-
 
1052
            EA_Utils.findAndProcessPackageElements( EA_RelMatrix.toPackage, toLister, EA_RelMatrix.toPackageRecursion );
-
 
1053
 
-
 
1054
            // Sort the "to" elements
-
 
1055
            toLister.Elements.Sort( sorter );
-
 
1056
 
-
 
1057
 
-
 
1058
            // To make the to-from table, we use the dictionary that was built when making the from-to
-
 
1059
            // table. The dictionary will allow rapid determination of what "from" items belong to each
-
 
1060
            // "to" item, without us having to go back to EA and enquire on the database.
-
 
1061
            // We build a new fromToDictionary from the toFromDictionary, in advance of actually making 
-
 
1062
            // the table so that we can figure out how many rows the table needs to have.
-
 
1063
            numberOfFromToRows = 0;
-
 
1064
            
-
 
1065
            foreach(EA.Element toElement in toLister.Elements)
-
 
1066
            {
-
 
1067
               bool foundToElement = false;
-
 
1068
 
-
 
1069
               // right-column cell content
-
 
1070
               foreach (DictionaryEntry de in toFromDictionary)
-
 
1071
               {
-
 
1072
                  if ((int)de.Key == toElement.ElementID)
-
 
1073
                  {
-
 
1074
                     DictionaryEntry newFromToEntry = new DictionaryEntry(toElement, (string)de.Value);
-
 
1075
                     fromToDictionary.Add( newFromToEntry );
-
 
1076
                     foundToElement = true;
-
 
1077
                  }
-
 
1078
               }
-
 
1079
 
-
 
1080
               // If we found a from-to relationship that table needs a new row.
-
 
1081
               if (foundToElement)
-
 
1082
               {
-
 
1083
                  numberOfFromToRows++;
-
 
1084
               }
-
 
1085
                  // if user wants all "from elements", even if some have no "to elements", then add a dictionary
-
 
1086
                  // entry and bump row count.
-
 
1087
               else if (EA_RelMatrix.toPackageTrimming == false)
-
 
1088
               {
-
 
1089
                  DictionaryEntry newFromToEntry = new DictionaryEntry(toElement, "");
-
 
1090
                  fromToDictionary.Add( newFromToEntry );
-
 
1091
                  numberOfFromToRows++;
-
 
1092
               }
-
 
1093
            }
-
 
1094
 
-
 
1095
            // Now begin to add the to-from table to the word document
-
 
1096
            if (EA_RelMatrix.toIntroText != null && EA_RelMatrix.toIntroText.Length > 0)
-
 
1097
            {
-
 
1098
               TextUtils.appendAndSelectText( EA_RelMatrix.toIntroText, EA_Constants.styleName_Body1 );
-
 
1099
            }
-
 
1100
 
-
 
1101
            // create the table in the word doc
-
 
1102
            tableNum = TableUtils.Table_Create( EA_RelMatrix.toFromTableTitle, numberOfFromToRows + 1, 2 );
-
 
1103
            table = WordDocument.Tables[tableNum];
-
 
1104
            
-
 
1105
            TableUtils.Table_SetTableColumnTitle(table, EA_RelMatrix.toColumnTitle, 1);
-
 
1106
            TableUtils.Table_SetTableColumnTitle(table, EA_RelMatrix.fromColumnTitle, 2);
-
 
1107
 
-
 
1108
            int lastFromElementId = -1;
-
 
1109
            bool firstToFromCon = true;
-
 
1110
            int row = 1;
-
 
1111
            foreach (DictionaryEntry de in fromToDictionary)
-
 
1112
            {
-
 
1113
               if ( ((EA.Element)de.Key).ElementID != lastFromElementId )
-
 
1114
               {
-
 
1115
                  lastFromElementId = ((EA.Element)de.Key).ElementID;
-
 
1116
                  row++;
-
 
1117
                  table.Cell(row,1).Range.Text = ((EA.Element)de.Key).Name;
-
 
1118
                  firstToFromCon = true;
-
 
1119
               }
-
 
1120
               
-
 
1121
               if (((string)de.Value).Length > 0)
-
 
1122
               {
-
 
1123
                  if (firstToFromCon)
-
 
1124
                  {
-
 
1125
                     firstToFromCon = false;
-
 
1126
                     table.Cell(row,2).Range.Text = (string)de.Value;
-
 
1127
                  }
-
 
1128
                  else
-
 
1129
                  {
-
 
1130
                     table.Cell(row,2).Range.Text += (string)de.Value;
-
 
1131
                  }
-
 
1132
               }
-
 
1133
               else
-
 
1134
               {
-
 
1135
                  table.Cell(row,2).Range.Text = "Un-allocated relationship!";
-
 
1136
                  table.Cell(row,2).Range.Font.Color = Word.WdColor.wdColorRed;
-
 
1137
               }
-
 
1138
            }
-
 
1139
         }
-
 
1140
      }
-
 
1141
 
-
 
1142
 
-
 
1143
      private void processTestTraceability( EA.Element theElement, int recurse_level )
794
      private void processTestTraceability( EA.Element theElement, int recurse_level )
1144
      {
795
      {
1145
         if (nonPrivateClasses.Count > 0)
796
         if (classesNeedingUnitTests.Count > 0)
1146
         {
797
         {
1147
            if (theElement.Notes.Length > 0)
798
            if (theElement.Notes.Length > 0)
1148
            {
799
            {
1149
               TextUtils.appendAndSelectText( theElement.Notes, EA_Constants.styleName_Body1);
800
               TextUtils.appendAndSelectText( theElement.Notes, EA_Constants.styleName_Body1);
1150
            }
801
            }
Line 1159... Line 810...
1159
 
810
 
1160
      private void completeTestTraceability()
811
      private void completeTestTraceability()
1161
      {
812
      {
1162
         if (utTraceabilityTable != null)
813
         if (utTraceabilityTable != null)
1163
         {
814
         {
1164
            int numClassesRemaining = nonPrivateClasses.Count;
815
            int numClassesRemaining = classesNeedingUnitTests.Count;
1165
            int row = 2;
816
            int row = 2;
1166
            foreach(int elementId in nonPrivateClasses)
817
            foreach(int elementId in classesNeedingUnitTests)
1167
            {
818
            {
1168
               EA.Element theElement = EA_Repository.GetElementByID( elementId );
819
               EA.Element theElement = EA_Repository.GetElementByID( elementId );
1169
               if (theElement != null)
820
               if (theElement != null)
1170
               {
821
               {
1171
                  utTraceabilityTable.Cell(row,1).Range.Text = theElement.Name;
822
                  utTraceabilityTable.Cell(row,1).Range.Text = theElement.Name;
Line 1209... Line 860...
1209
            TextUtils.appendAndSelectText( theElement.Notes.ToString(), EA_Constants.styleName_RefListText );
860
            TextUtils.appendAndSelectText( theElement.Notes.ToString(), EA_Constants.styleName_RefListText );
1210
         }
861
         }
1211
      }
862
      }
1212
 
863
 
1213
 
864
 
1214
      private void createTerminologySection(EA.Package thePackage)
865
      private void createTerminologySection(EA.Package thePackage, int recurse_level)
1215
      {
866
      {
1216
         // Use local package elements as source of glossary, but if none are present, resort to using
867
         // Use local package elements as source of glossary, but if none are present, resort to using
1217
         // the project glossary in the repository 
868
         // the project glossary in the repository 
1218
         int numItems = thePackage.Elements.Count;
869
         int numItems = thePackage.Elements.Count;
1219
         if (numItems == 0)
870
         if (numItems == 0)
1220
         {
871
         {
1221
            numItems = EA_Repository.Terms.Count;
872
            numItems = EA_Repository.Terms.Count;
1222
         }
-
 
1223
 
-
 
1224
         if (numItems > 0)
-
 
1225
         {
-
 
1226
            // Create a table
873
            // Create a table
1227
            int tableNum = TableUtils.Table_Create("Terminology", numItems+1, 2);
874
            int tableNum = TableUtils.Table_Create("Terminology", numItems+1, 2);
1228
            Word.Table table = WordDocument.Tables[tableNum];
875
            Word.Table table = WordDocument.Tables[tableNum];
1229
            object center = Word.WdParagraphAlignment.wdAlignParagraphCenter;
876
            object center = Word.WdParagraphAlignment.wdAlignParagraphCenter;
1230
 
877
 
1231
            TableUtils.Table_SetTableColumnTitle(table, "Term", 1);
878
            TableUtils.Table_SetTableColumnTitle(table, "Term", 1);
1232
            TableUtils.Table_SetTableColumnTitle(table, "Definition", 2);
879
            TableUtils.Table_SetTableColumnTitle(table, "Definition", 2);
1233
            table.Columns[1].SetWidth(100, Word.WdRulerStyle.wdAdjustSameWidth );
880
            table.Columns[1].SetWidth(100, Word.WdRulerStyle.wdAdjustSameWidth );
1234
            int row = 2;
881
            int row = 2;
-
 
882
            // inject the glossary into the table
-
 
883
            foreach(EA.Term theTerm in EA_Repository.Terms)
-
 
884
            {
-
 
885
               table.Cell(row,1).Range.Text = theTerm.Term;
-
 
886
               table.Cell(row,2).Range.Text = theTerm.Meaning;
-
 
887
               row++;
-
 
888
            }
1235
 
889
         }
-
 
890
         else
-
 
891
         {
-
 
892
            // scan content of terminology package - allow user to specify tables, text, package links,
1236
            if (thePackage.Elements.Count > 0)
893
            // and diagram links.
-
 
894
            ArrayList infoItems = new ArrayList();
-
 
895
            foreach(EA.Element theElement in thePackage.Elements)
1237
            {
896
            {
1238
               // The advantage of using the package content is that the elements come out alphabetically
-
 
1239
               // sorted already (assuming user has not over-riden the sort order in the project browser).
-
 
1240
               // Also, the glossary content can be exactly tailored to what the document requires.
-
 
1241
               foreach(EA.Element theElement in thePackage.Elements)
897
               if (theElement.Name.StartsWith(EA_Constants.EA_DocGenTable))
1242
               {
898
               {
1243
                  table.Cell(row,1).Range.Text = theElement.Name.ToString();
899
                  TableUtils.processTableElement( theElement, recurse_level);
-
 
900
               }
-
 
901
               else if (theElement.Name.StartsWith(EA_Constants.EA_DocGenPackageLink))
-
 
902
               {
-
 
903
                  processingLink++;
1244
                  table.Cell(row,2).Range.Text = theElement.Notes.ToString();
904
                  processPackageLink( theElement, recurse_level );
-
 
905
                  processingLink--;
-
 
906
               }
-
 
907
               else if (theElement.Name.StartsWith(EA_Constants.EA_DocGenText))
-
 
908
               {
-
 
909
                  TextUtils.appendAndSelectText( theElement.Notes.ToString(), EA_Constants.styleName_Body1 );
-
 
910
               }
-
 
911
               else if (theElement.Name.StartsWith(EA_Constants.EA_DocGenDiagramLink))
-
 
912
               {
-
 
913
                  processingLink++;
-
 
914
                  processDiagramLink( theElement );
-
 
915
                  processingLink--;
-
 
916
               }
-
 
917
               else if (theElement.Name.StartsWith(EA_Constants.EA_DocGenElementLink))
-
 
918
               {
1245
                  row++;
919
                  processingLink++;
-
 
920
                  processElementLink( theElement, recurse_level );
-
 
921
                  processingLink--;
-
 
922
               }
-
 
923
               else if (!theElement.Name.StartsWith(EA_Constants.EA_DocGenBaseName)   // ignore all other special EA_DocGen elements
-
 
924
                  || theElement.Name.Length == EA_Constants.EA_DocGenBaseName.Length) // allow EA_DocGen to be used as a term/acronym
-
 
925
               {
-
 
926
                  infoItems.Add( theElement );
1246
               }
927
               }
1247
            }
928
            }
-
 
929
 
1248
            else // default to using the project glossary in the repository
930
            if (infoItems.Count > 0)
1249
            {
931
            {
1250
               // TODO 
932
               // Create a table
1251
               // 1. Alphabetically Sort the glossary terms before adding them to the table
933
               int tableNum = TableUtils.Table_Create("Terminology", infoItems.Count+1, 2);
-
 
934
               Word.Table table = WordDocument.Tables[tableNum];
1252
               //    The Repository glossary seems to be provided in non-sorted order unfortunately.
935
               object center = Word.WdParagraphAlignment.wdAlignParagraphCenter;
1253
 
936
 
-
 
937
               TableUtils.Table_SetTableColumnTitle(table, "Term", 1);
-
 
938
               TableUtils.Table_SetTableColumnTitle(table, "Definition", 2);
-
 
939
               table.Columns[1].SetWidth(100, Word.WdRulerStyle.wdAdjustSameWidth );
1254
               // inject the glossary into the table
940
               int row = 2;
-
 
941
 
1255
               foreach(EA.Term theTerm in EA_Repository.Terms)
942
               foreach(EA.Element theElement in infoItems)
1256
               {
943
               {
1257
                  table.Cell(row,1).Range.Text = theTerm.Term;
944
                  table.Cell(row,1).Range.Text = theElement.Name.ToString();
1258
                  table.Cell(row,2).Range.Text = theTerm.Meaning;
945
                  table.Cell(row,2).Range.Text = theElement.Notes.ToString();
1259
                  row++;
946
                  row++;
1260
               }
947
               }
1261
            }
948
            }
1262
         }
949
         }
1263
      }
950
      }
1264
 
951
 
1265
      #endregion
952
      #endregion
1266
 
953
 
1267
      private bool generatePackageHeadingAndDescription( EA.Package thePackage, int recurse_level )
954
      private bool generatePackageHeadingAndDescription( EA.Package thePackage, int recurse_level )
1268
      {
955
      {
1269
         // disarm the one-shot package skipping feature if it was armed, and exit the function.
956
         bool processLowerLevelContent = true;  // return value for this function
1270
         if (oneShot_skipRootPackage == true)
-
 
1271
         {
-
 
1272
            oneShot_skipRootPackage = false;
-
 
1273
            return false;
-
 
1274
         }
-
 
1275
 
957
 
1276
         // The package name is a heading, and the package notes are paragraphs 
958
         // The package name is a heading, and the package notes are paragraphs 
1277
         // directly under that heading
959
         // directly under that heading
1278
         displayProgress( "PACKAGE: ", thePackage.Name.ToString() );
-
 
1279
 
960
 
1280
         TextUtils.appendAndSelectHeadingText( thePackage.Name.ToString(), recurse_level );
961
         TextUtils.appendAndSelectHeadingText( thePackage.Name.ToString(), recurse_level );
-
 
962
         displayProgress( "PACKAGE: ", thePackage.Name.ToString() );
1281
 
963
 
1282
         // Special handling for package called "Terminology" 
964
         // Special handling for package called "Terminology" 
1283
         if (thePackage.Name == "Terminology")
965
         if (thePackage.Name == "Terminology")
1284
         {
966
         {
1285
            TextUtils.appendAndSelectText( thePackage.Notes.ToString(), EA_Constants.styleName_Body1 );
967
            TextUtils.appendAndSelectText( thePackage.Notes.ToString(), EA_Constants.styleName_Body1 );
1286
            createTerminologySection(thePackage);
968
            createTerminologySection(thePackage, recurse_level);
1287
            return true;
969
            processLowerLevelContent = false;
1288
         }
970
         }
1289
 
971
 
1290
         if (thePackage.Name == "References")
972
         else if (thePackage.Name == "References")
1291
         {
973
         {
1292
            TextUtils.appendAndSelectText( thePackage.Notes.ToString(), EA_Constants.styleName_Body1 );
974
            TextUtils.appendAndSelectText( thePackage.Notes.ToString(), EA_Constants.styleName_Body1 );
1293
            createReferencesSection(thePackage);
975
            createReferencesSection(thePackage);
1294
            return true;
976
            processLowerLevelContent = false;
1295
         }
977
         }
-
 
978
         else
1296
         
979
         {
1297
         // use the package notes as body text and indicate to caller that package elements 
980
            // use the package notes as body text and indicate to caller that package elements 
1298
         // have not been consumed
981
            // have not been consumed
1299
         TextUtils.appendAndSelectText( thePackage.Notes.ToString(), EA_Constants.styleName_Body1 );      
982
            TextUtils.appendAndSelectText( thePackage.Notes.ToString(), EA_Constants.styleName_Body1 );      
-
 
983
         }
-
 
984
 
1300
         return false;
985
         return processLowerLevelContent;
1301
      }
986
      }
1302
 
987
 
1303
  
988
  
1304
      private void generatePackageDiagrams( EA.Package thePackage )
989
      private void generatePackageDiagrams( EA.Package thePackage )
1305
      {
990
      {
1306
         // default handling of diagrams
991
         // default handling of diagrams
1307
         foreach(EA.Diagram theDiagram in thePackage.Diagrams)
992
         foreach(EA.Diagram theDiagram in thePackage.Diagrams)
1308
         {
993
         {
1309
            if (theDiagram.ParentID == 0 || thePackage.PackageID == theDiagram.ParentID)
994
            if (theDiagram.ParentID == 0 || thePackage.PackageID == theDiagram.ParentID)
1310
            {
995
            {
1311
               displayProgress( "DIAGRAM: ", theDiagram.Name.ToString() );
-
 
1312
 
-
 
1313
               appendAndSelectDiagramViaClipboard( theDiagram );
996
               appendAndSelectDiagramViaClipboard( theDiagram );
1314
            }
997
            }
1315
         }
998
         }
1316
      }
999
      }
1317
 
1000
 
-
 
1001
 
1318
      private void generateElementDiagrams( EA.Element theElement )
1002
      private void generateElementDiagrams( EA.Element theElement )
1319
      {
1003
      {
1320
         // default handling of diagrams
1004
         // default handling of diagrams
1321
         foreach(EA.Diagram theDiagram in theElement.Diagrams)
1005
         foreach(EA.Diagram theDiagram in theElement.Diagrams)
1322
         {
1006
         {
1323
            if (theDiagram.ParentID == 0 || theElement.ElementID == theDiagram.ParentID)
1007
            if (theDiagram.ParentID == 0 || theElement.ElementID == theDiagram.ParentID)
1324
            {
1008
            {
1325
               displayProgress( "DIAGRAM: ", theDiagram.Name.ToString() );
-
 
1326
 
-
 
1327
               appendAndSelectDiagramViaClipboard( theDiagram );
1009
               appendAndSelectDiagramViaClipboard( theDiagram );
1328
            }
1010
            }
1329
         }
1011
         }
1330
      }
1012
      }
1331
 
1013
 
-
 
1014
 
1332
      private void generateMethodContent( EA.Element theElement, int recurse_level )
1015
      private void generateMethodContent( EA.Element theElement, int recurse_level )
1333
      {
1016
      {
1334
         recurse_level++;
1017
         recurse_level++;
1335
         if (recurse_level > EA_Constants.MAX_HEADING_LEVEL - 1)  // -1 because this function generates two heading levels 
-
 
1336
         {
-
 
1337
            throw new System.StackOverflowException(EA_Constants.maxRecursionDepthException );
-
 
1338
         }
-
 
1339
 
1018
 
1340
         // Get all the methods into an array list and sort them by their position in the class's
1019
         // Get all the methods into an array list and sort them by their position in the class's
1341
         // method list (ie. sort order is determined by the Pos value in each method).
1020
         // method list (ie. sort order is determined by the Pos value in each method).
1342
         ArrayList theMethods = new ArrayList();
1021
         ArrayList theMethods = new ArrayList();
1343
         foreach(EA.Method theMethod in theElement.Methods)
1022
         foreach(EA.Method theMethod in theElement.Methods)
Line 1512... Line 1191...
1512
      /// <param name="theElement"></param>
1191
      /// <param name="theElement"></param>
1513
      /// <param name="recurse_level"></param>
1192
      /// <param name="recurse_level"></param>
1514
      private void generateAttributeContent( EA.Element theElement, int recurse_level )
1193
      private void generateAttributeContent( EA.Element theElement, int recurse_level )
1515
      {
1194
      {
1516
         recurse_level++;
1195
         recurse_level++;
1517
         if (recurse_level > EA_Constants.MAX_HEADING_LEVEL)
-
 
1518
         {
-
 
1519
            throw new System.StackOverflowException(EA_Constants.maxRecursionDepthException );
-
 
1520
         }
-
 
1521
      
1196
      
1522
         // Get all the attributes into an array list and sort them by their position in the class's
1197
         // Get all the attributes into an array list and sort them by their position in the class's
1523
         // attribute list (ie. sort order is determined by the Pos value in each attribute).
1198
         // attribute list (ie. sort order is determined by the Pos value in each attribute).
1524
         ArrayList theAttrs = new ArrayList();
1199
         ArrayList theAttrs = new ArrayList();
1525
         foreach(EA.Attribute theAttr in theElement.Attributes)
1200
         foreach(EA.Attribute theAttr in theElement.Attributes)
Line 1698... Line 1373...
1698
 
1373
 
1699
      private void generateClassCharacteristics( EA.Element theElement, int recurse_level )
1374
      private void generateClassCharacteristics( EA.Element theElement, int recurse_level )
1700
      {
1375
      {
1701
         StringBuilder sb = new StringBuilder();
1376
         StringBuilder sb = new StringBuilder();
1702
 
1377
 
-
 
1378
         ////////////////////////////////////////////////////////////////////////////////////////////////
1703
         sb.Append( "Characteristics:" );
1379
         sb.Append( "Characteristics:" );
1704
         Word.Range wr = TextUtils.appendAndSelectText(sb.ToString(), EA_Constants.styleName_Body1_Left_2_5cm_Italic);
1380
         Word.Range wr = TextUtils.appendAndSelectText(sb.ToString(), EA_Constants.styleName_Body1_Left_2_5cm_Italic);
1705
         
1381
         
1706
         sb = new StringBuilder();
1382
         sb = new StringBuilder();
-
 
1383
         // VISIBILITY
1707
         sb.Append( theElement.Visibility );
1384
         sb.Append( theElement.Visibility );
1708
 
-
 
-
 
1385
         // ABSTRACT
1709
         if (System.Convert.ToInt32(theElement.Abstract) == 1)
1386
         if (System.Convert.ToInt32(theElement.Abstract) == 1)
1710
            sb.Append( "\nAbstract" );
1387
            sb.Append( "\nAbstract" );
-
 
1388
         // STEREOTYPES
-
 
1389
         if (theElement.StereotypeEx.Length > 0)
-
 
1390
         {
-
 
1391
            sb.Append("\nStereotypes: ");
-
 
1392
            sb.Append(theElement.StereotypeEx);
-
 
1393
         }
-
 
1394
         // MULTIPLICITY
-
 
1395
         if (theElement.Multiplicity.Length > 0)
-
 
1396
         {
-
 
1397
            sb.Append("\nMultiplicity: ");
-
 
1398
            sb.Append(theElement.Multiplicity);
-
 
1399
         }
-
 
1400
         // IS ACTIVE
-
 
1401
         if (theElement.IsActive)
-
 
1402
            sb.Append("\nClass is active (has its own thread of control)\n");
-
 
1403
         // IS SPEC
-
 
1404
         if (theElement.IsSpec)
-
 
1405
            sb.Append("\nClass is a specification\n");
1711
 
1406
 
1712
         wr = TextUtils.appendAndSelectText(sb.ToString(), EA_Constants.styleName_Body1_Left_3_5cm);
1407
         wr = TextUtils.appendAndSelectText(sb.ToString(), EA_Constants.styleName_Body1_Left_3_5cm);
1713
         
1408
 
-
 
1409
         ////////////////////////////////////////////////////////////////////////////////////////////////
1714
         sb = new StringBuilder();
1410
         sb = new StringBuilder();
1715
         foreach(EA.Element baseClass in theElement.BaseClasses)
1411
         foreach(EA.Element baseClass in theElement.BaseClasses)
1716
         {
1412
         {
1717
            sb.Append( baseClass.Name);
1413
            sb.Append( baseClass.Name);
1718
         }
1414
         }
Line 1721... Line 1417...
1721
            wr = TextUtils.appendAndSelectText("Base Class(es):", EA_Constants.styleName_Body1_Left_2_5cm_Italic);
1417
            wr = TextUtils.appendAndSelectText("Base Class(es):", EA_Constants.styleName_Body1_Left_2_5cm_Italic);
1722
 
1418
 
1723
            wr = TextUtils.appendAndSelectText(sb.ToString(), EA_Constants.styleName_Body1_Left_3_5cm);
1419
            wr = TextUtils.appendAndSelectText(sb.ToString(), EA_Constants.styleName_Body1_Left_3_5cm);
1724
         }
1420
         }
1725
 
1421
 
-
 
1422
         ////////////////////////////////////////////////////////////////////////////////////////////////
1726
         sb = new StringBuilder();
1423
         sb = new StringBuilder();
1727
         foreach(EA.Element intf in theElement.Realizes)
1424
         foreach(EA.Element intf in theElement.Realizes)
1728
         {
1425
         {
1729
            sb.Append( intf.Name);
1426
            sb.Append( intf.Name);
1730
         }
1427
         }
Line 1784... Line 1481...
1784
            }
1481
            }
1785
         }
1482
         }
1786
      }
1483
      }
1787
 
1484
 
1788
 
1485
 
1789
      private void generateElementContent( EA.Element theElement, int recurse_level )
1486
      private bool generateElementContent( EA.Element theElement, int recurse_level )
1790
      {
1487
      {
-
 
1488
         bool allowSubElementParsing = true;  // return value for the function
-
 
1489
 
1791
         // track recursion level to control heading style formatting requirements
1490
         // track recursion level to control heading style formatting requirements
1792
         if (oneShot_skipRootElementHeading == false)
1491
         if (oneShot_skipRootElementHeading == false)
1793
            recurse_level++;
1492
            recurse_level++;
1794
 
1493
 
1795
         if (EA_Utils.options.elementTypeFoundInEA_DocGen( theElement.Type ))
1494
         if (EA_Utils.options.elementTypeFoundInEA_DocGen( theElement.Type ))
Line 1799... Line 1498...
1799
            // element serialisation.
1498
            // element serialisation.
1800
            if (false == TextUtils.generateRequirementText(theElement, EA_Utils))
1499
            if (false == TextUtils.generateRequirementText(theElement, EA_Utils))
1801
            {
1500
            {
1802
               bool isClass = theElement.Type.StartsWith("Class");
1501
               bool isClass = theElement.Type.StartsWith("Class");
1803
 
1502
 
1804
               if (  true == isClass
1503
               if (   (   true == isClass
1805
                  && true == EA_Utils.options.opt_SuppressPrivateClasses
1504
                       && true == EA_Utils.options.opt_SuppressPrivateClasses 
1806
                  && true == theElement.Visibility.StartsWith("Private") )
1505
                       && true == theElement.Visibility.StartsWith("Private"))
-
 
1506
                   || (   true == EA_Utils.options.opt_ConsiderAPIElementsOnly 
-
 
1507
                       && 0 > theElement.StereotypeEx.IndexOf("API"))
-
 
1508
                  )
1807
               {
1509
               {
1808
                  // do nothing
1510
                  // do nothing
-
 
1511
                  DocSectionTracker.trackDocSection(recurse_level);
-
 
1512
                  displayProgress( "SKIPPED: ", theElement.Name );
-
 
1513
                  allowSubElementParsing = false;
1809
               }
1514
               }
1810
               else
1515
               else
1811
               {
1516
               {
1812
                  if (recurse_level > EA_Constants.MAX_HEADING_LEVEL)
-
 
1813
                  {
-
 
1814
                     throw new System.StackOverflowException(EA_Constants.maxRecursionDepthException);
-
 
1815
                  }
-
 
1816
 
-
 
1817
                  trackDocSection(recurse_level);
-
 
1818
                  displayProgress( "ELEMENT: ", theElement.Name );
-
 
1819
 
-
 
1820
                  // Determine if element is filtered out by a NO_DOC tagged value
-
 
1821
                  // Having written this code, I realised it might be a bad idea to let users filter out
-
 
1822
                  // elements by tagged values. The reason is, if that content is not in a document model
-
 
1823
                  // but in a design model, then it might be used by >1 document model made by different
-
 
1824
                  // users, so one users choice of filtering might not suit another users. The only way we 
-
 
1825
                  // could get this to work is if the tagged values were somehow made specific to a document
-
 
1826
                  // model, but how do you do this? GUIDs are the only safe way to key to something but we
-
 
1827
                  // dont want every tagged value key to contain a GUID do we?
-
 
1828
//                  bool noDocGen = false;
-
 
1829
//                  string str_noDocGen = EA_Utils.ReadTag(theElement, "NO_DOC");
-
 
1830
//                  if (str_noDocGen.Length > 0)
-
 
1831
//                  {
-
 
1832
//                     str_noDocGen = str_noDocGen.ToLower();
-
 
1833
//                     if (str_noDocGen.CompareTo("true"))
-
 
1834
//                     {
-
 
1835
//                        noDocGen = true;
-
 
1836
//                        displayProgress( "FILTERED: ", theElement.Type );
-
 
1837
//                        oneShot_skipRootElementHeading = false;
-
 
1838
//                        return;
-
 
1839
//                     }
-
 
1840
//                  }                     
-
 
1841
 
-
 
1842
                  // disarm the one-shot element (heading) skipping feature if it was armed, and 
1517
                  // disarm the one-shot element (heading) skipping feature if it was armed, and 
1843
                  // by-pass the code to generate a new heading level for the element
1518
                  // by-pass the code to generate a new heading level for the element
1844
                  if (oneShot_skipRootElementHeading == false)
1519
                  if (oneShot_skipRootElementHeading == false)
1845
                  {
1520
                  {
1846
                     // Default element serialisation
1521
                     // Default element serialisation
1847
                     if (  EA_Utils.options.opt_ElementHeadingTransitionLevel > 0
-
 
1848
                        && EA_Utils.options.opt_ElementHeadingTransitionLevel <= recurse_level )
-
 
1849
                        TextUtils.appendAndSelectNumParaText( theElement.Name, recurse_level );
-
 
1850
                     else
-
 
1851
                        TextUtils.appendAndSelectHeadingText( theElement.Name, recurse_level );
1522
                     TextUtils.appendAndSelectHeadingText( theElement.Name, recurse_level );
1852
                  }
1523
                  }
1853
                  else
1524
                  else
1854
                  {
1525
                  {
1855
                     oneShot_skipRootElementHeading = false;
1526
                     oneShot_skipRootElementHeading = false;
1856
                  }
1527
                  }
1857
 
1528
 
-
 
1529
                  processedElements.Add(theElement.ElementID);
-
 
1530
                  displayProgress( "ELEMENT: ", theElement.Name );
-
 
1531
 
1858
                  TextUtils.appendDescription( theElement.Notes, EA_Utils );
1532
                  TextUtils.appendDescription( theElement.Notes, EA_Utils );
1859
 
1533
 
1860
                  generateElementDiagrams(theElement);
1534
                  generateElementDiagrams(theElement);
1861
 
1535
 
1862
                  if (true == isClass)
1536
                  if (true == isClass)
1863
                  {
1537
                  {
1864
                     // If accumulation of non-private classes is enabled, then do so.
1538
                     // accumulate unit testable classes.
1865
                     if (recordingNonPrivateClasses)
1539
                     if (   theElement.StereotypeEx.IndexOf("API") >= 0
-
 
1540
                         && !theElement.Visibility.StartsWith("Private"))
1866
                     {
1541
                     {
1867
                        if (!theElement.Visibility.StartsWith("Private"))
-
 
1868
                        {
-
 
1869
                           nonPrivateClasses.Add( theElement.ElementID );
1542
                        classesNeedingUnitTests.Add( theElement.ElementID );
1870
                        }
-
 
1871
                     }
1543
                     }
1872
 
1544
 
1873
                     generateClassCharacteristics(theElement, recurse_level);
1545
                     generateClassCharacteristics(theElement, recurse_level);
1874
                  }
1546
                  }
1875
 
1547
 
Line 1902... Line 1574...
1902
                  }
1574
                  }
1903
               }
1575
               }
1904
            }
1576
            }
1905
            else
1577
            else
1906
            {
1578
            {
-
 
1579
               processedElements.Add(theElement.ElementID);
1907
               trackDocSection(recurse_level);
1580
               DocSectionTracker.trackDocSection(recurse_level);
1908
               displayProgress( "ELEMENT: ", theElement.Name );
1581
               displayProgress( "ELEMENT: ", theElement.Name );
1909
            }
1582
            }
1910
         }
1583
         }
1911
         else
1584
         else
1912
         {
1585
         {
-
 
1586
            DocSectionTracker.trackDocSection(recurse_level);
1913
            displayProgress( "FILTERED: ", theElement.Type );
1587
            displayProgress( "FILTERED: ", theElement.Type );
1914
         }
1588
         }
1915
         // TODO
1589
         // TODO
1916
         // We will probably have to put special code in here at some point for attributes
1590
         // We will probably have to put special code in here at some point for attributes
1917
         // of, and collections of things within elements. This will become apparent once
1591
         // of, and collections of things within elements. This will become apparent once
1918
         // someone tries to produce a design document where such things need to be included
1592
         // someone tries to produce a design document where such things need to be included
1919
         // in the generated document. Lots of work needed here eventually.
1593
         // in the generated document. Lots of work needed here eventually.
1920
         
1594
         
1921
         // disarm element heading skip control
1595
         // disarm element heading skip control
1922
         oneShot_skipRootElementHeading = false;
1596
         oneShot_skipRootElementHeading = false;
-
 
1597
 
-
 
1598
         return allowSubElementParsing;
1923
      }
1599
      }
1924
 
1600
 
1925
 
1601
 
1926
      /// <summary>
1602
      /// <summary>
1927
      /// This function searches for the old content in the document in order to remove it
1603
      /// This function searches for the old content in the document in order to remove it
Line 1976... Line 1652...
1976
      /// </summary>
1652
      /// </summary>
1977
      /// <param name="theElement"></param>
1653
      /// <param name="theElement"></param>
1978
      /// <param name="recurse_level"></param>
1654
      /// <param name="recurse_level"></param>
1979
      private void parse_element(EA.Element theElement, int recurse_level)
1655
      private void parse_element(EA.Element theElement, int recurse_level)
1980
      {
1656
      {
1981
 
-
 
1982
         // First look for and handle special elements that control the doc-gen process
1657
         // First look for and handle special elements that control the doc-gen process
1983
 
1658
 
1984
         // The EA_DocGenPackageLink can contain a list of GUIDs in its notes section
1659
         // The EA_DocGenPackageLink can contain a list of GUIDs in its notes section
1985
         // that point to model structure outside of the localised structure forming the
1660
         // that point to model structure outside of the localised structure forming the
1986
         // document. This enables a document to grab content from other external models
1661
         // document. This enables a document to grab content from other external models
1987
         // as long as they are loaded into the repository.
1662
         // as long as they are loaded into the repository.
1988
         if (theElement.Name.StartsWith(EA_Constants.EA_DocGenPackageLink))
1663
         if (theElement.Name.StartsWith(EA_Constants.EA_DocGenPackageLink))
1989
         {
1664
         {
-
 
1665
            processingLink++;
1990
            processPackageLink( theElement, recurse_level );
1666
            processPackageLink( theElement, recurse_level );
-
 
1667
            processingLink--;
1991
         }
1668
         }
1992
 
1669
 
1993
            // The EA_DocGenDiagramLink can contain a list of GUIDs in its notes section
1670
            // The EA_DocGenDiagramLink can contain a list of GUIDs in its notes section
1994
            // that point to diagram elements anywhere in the repository.
1671
            // that point to diagram elements anywhere in the repository.
1995
         else if (theElement.Name.StartsWith(EA_Constants.EA_DocGenDiagramLink))
1672
         else if (theElement.Name.StartsWith(EA_Constants.EA_DocGenDiagramLink))
1996
         {
1673
         {
-
 
1674
            processingLink++;
1997
            processDiagramLink( theElement );
1675
            processDiagramLink( theElement );
-
 
1676
            processingLink--;
1998
         }
1677
         }
1999
 
1678
 
2000
            // The EA_DocGenDiagramLink can contain a list of GUIDs in its notes section
1679
            // The EA_DocGenDiagramLink can contain a list of GUIDs in its notes section
2001
            // that point to diagram elements anywhere in the repository.
1680
            // that point to diagram elements anywhere in the repository.
2002
         else if (theElement.Name.StartsWith(EA_Constants.EA_DocGenElementLink))
1681
         else if (theElement.Name.StartsWith(EA_Constants.EA_DocGenElementLink))
2003
         {
1682
         {
-
 
1683
            processingLink++;
2004
            processElementLink( theElement, recurse_level );
1684
            processElementLink( theElement, recurse_level );
-
 
1685
            processingLink--;
2005
         }
1686
         }
2006
 
1687
 
2007
            // The EA_DocGenTable element can contain table content in its notes section
1688
            // The EA_DocGenTable element can contain table content in its notes section
2008
            // and must be dealt with in a special way.
1689
            // and must be dealt with in a special way.
2009
         else if (theElement.Name.StartsWith(EA_Constants.EA_DocGenTable))
1690
         else if (theElement.Name.StartsWith(EA_Constants.EA_DocGenTable))
2010
         {
1691
         {
2011
            processTableElement( theElement, recurse_level );
1692
            TableUtils.processTableElement(theElement, recurse_level);
2012
         }
1693
         }
2013
 
1694
 
2014
            // The EA_DocGenText element can contain text content in its notes section
1695
            // The EA_DocGenText element can contain text content in its notes section
2015
            // that must be appended to the doc in Body 1 style within the current
1696
            // that must be appended to the doc in Body 1 style within the current
2016
            // section.
1697
            // section.
2017
         else if (theElement.Name.StartsWith(EA_Constants.EA_DocGenText))
1698
         else if (theElement.Name.StartsWith(EA_Constants.EA_DocGenText))
2018
         {
1699
         {
2019
            processTextElement( theElement, recurse_level );
1700
            TextUtils.appendAndSelectText( theElement.Notes.ToString(), EA_Constants.styleName_Body1 );
2020
         }
1701
         }
2021
 
1702
 
2022
         else if (theElement.Name.StartsWith(EA_Constants.EA_DocGenRelationshipMatrix))
1703
         else if (theElement.Name.StartsWith(EA_Constants.EA_DocGenRelationshipMatrix))
2023
         {
1704
         {
-
 
1705
            EA_RelationshipMatrix EA_RelMatrix = new EA_RelationshipMatrix(EA_Repository, TableUtils, TextUtils, EA_Utils, WordDocument, processedElements);
-
 
1706
            if (EA_RelMatrix.processRelationshipMatrixOptions( theElement ))
-
 
1707
            {
2024
            processRelationshipMatrixElement( theElement, recurse_level );
1708
               EA_RelMatrix.processRelationshipMatrixElement( theElement, recurse_level );
-
 
1709
            }
2025
         }
1710
         }
2026
 
1711
 
2027
         else if (theElement.Name.StartsWith(EA_Constants.EA_DocGenTestLink))
1712
         else if (theElement.Name.StartsWith(EA_Constants.EA_DocGenTestLink))
2028
         {
1713
         {
-
 
1714
            processingLink++;
2029
            processTestLink( theElement, recurse_level );
1715
            processTestLink( theElement, recurse_level );
-
 
1716
            processingLink--;
2030
         }
1717
         }
2031
 
1718
 
2032
         else if (theElement.Name.StartsWith(EA_Constants.EA_DocGenTestTraceability))
1719
         else if (theElement.Name.StartsWith(EA_Constants.EA_DocGenTestTraceability))
2033
         {
1720
         {
2034
            processTestTraceability( theElement, recurse_level );
1721
            processTestTraceability( theElement, recurse_level );
2035
         }
1722
         }
2036
 
1723
 
-
 
1724
         else if (theElement.Name.StartsWith(EA_Constants.EA_DocGenNameLink))
-
 
1725
         {
-
 
1726
            processingLink++;
-
 
1727
            processNameLink( theElement, recurse_level );
-
 
1728
            processingLink--;
-
 
1729
         }
2037
 
1730
 
2038
            // we are aware of the other ERG EA add-in, EA_ReqPro! That other add-in creates 
1731
            // we are aware of the other ERG EA add-in, EA_ReqPro! That add-in creates 
2039
            // ReqProDB stereotyped elements. Never consume them in the document generation process.
1732
            // ReqProDB stereotyped elements. Never consume them in the document generation process.
2040
         else if ( theElement.Stereotype != EA_Constants.stereotype_ReqProDB )    
1733
         else if (0 > theElement.StereotypeEx.IndexOf(EA_Constants.stereotype_ReqProDB))
2041
         {
1734
         {
-
 
1735
            bool allowSubElementParsing = generateElementContent( theElement, recurse_level );
-
 
1736
            if (allowSubElementParsing)
-
 
1737
            {
-
 
1738
               // Look at this elements sub-elements
-
 
1739
               foreach(EA.Element subElement in theElement.Elements)
-
 
1740
               {
2042
            generateElementContent( theElement, recurse_level );
1741
                  parse_element(subElement, recurse_level+1);
-
 
1742
               }
-
 
1743
            }
2043
         }   
1744
         }   
2044
   
-
 
2045
         // Look at this elements sub-elements
-
 
2046
         foreach(EA.Element subElement in theElement.Elements)
-
 
2047
         {
-
 
2048
            parse_element(subElement, recurse_level+1);
-
 
2049
         }
-
 
2050
      }
1745
      }
2051
 
1746
 
2052
 
1747
 
2053
      /// <summary>
1748
      /// <summary>
2054
      /// Parses the package and all of its content, extracting information as needed, and
1749
      /// Parses the package and all of its content, extracting information as needed, and
Line 2064... Line 1759...
2064
         // here, as you can see. 
1759
         // here, as you can see. 
2065
         bool rootPackageWasSkipped = !oneShot_skipRootPackage;
1760
         bool rootPackageWasSkipped = !oneShot_skipRootPackage;
2066
         if (oneShot_skipRootPackage == false)
1761
         if (oneShot_skipRootPackage == false)
2067
         {
1762
         {
2068
            recurse_level++;
1763
            recurse_level++;
2069
            trackDocSection(recurse_level);
-
 
2070
         }
1764
         }
2071
 
1765
 
-
 
1766
         // determine if the package has an API stereotype
-
 
1767
         bool packageHasAPIStereotype = false;
-
 
1768
         if (0 <= thePackage.StereotypeEx.IndexOf("API") )
-
 
1769
            packageHasAPIStereotype = true;
-
 
1770
 
-
 
1771
         // only process the package if it the stereotype allows, or sensitivity to the stereotype is disabled
2072
         if (recurse_level > EA_Constants.MAX_HEADING_LEVEL)
1772
         if (  !EA_Utils.options.opt_ConsiderAPIPackagesOnly
-
 
1773
            || (EA_Utils.options.opt_ConsiderAPIPackagesOnly && EA_Utils.options.opt_RestrictForLinkedPackagesOnly && processingLink == 0)
-
 
1774
            || (EA_Utils.options.opt_ConsiderAPIPackagesOnly && packageHasAPIStereotype) 
-
 
1775
            )
2073
         {
1776
         {
2074
            throw new System.StackOverflowException(EA_Constants.maxRecursionDepthException );
-
 
2075
         }
1777
            
2076
 
-
 
2077
         // If we have reached a "Detailed Design" section, we should begin to capture in a list, all public 
-
 
2078
         // classes so that we know later on what classes need to be considered in the unit testing section
-
 
2079
         // of the document, assuming that this is a s/w design document being generated ofcoarse. 
-
 
2080
         bool nameStartedWithDetailedDesign = false;
-
 
2081
         if (recordingNonPrivateClasses == false && thePackage.Name.StartsWith("Detailed Design"))
-
 
2082
         {
-
 
2083
            recordingNonPrivateClasses = true;
1778
            bool processLowerLevelContent = true;
2084
            nameStartedWithDetailedDesign = true;
-
 
2085
         }
-
 
2086
 
-
 
2087
         // generate package heading and description. This may, depending on the package name,
-
 
2088
         // consume the elements in the package. If it does not, then consume them (and any diagrams)
-
 
2089
         // locally here.
-
 
2090
         if (false == generatePackageHeadingAndDescription( thePackage, recurse_level ))
-
 
2091
         {
-
 
2092
            // consume diagrams
-
 
2093
            generatePackageDiagrams( thePackage );
-
 
2094
 
1779
 
-
 
1780
            // disarm the one-shot package skipping feature if it was armed
2095
            foreach(EA.Element subElement in thePackage.Elements)
1781
            if (oneShot_skipRootPackage == true)
2096
            {
1782
            {
-
 
1783
               oneShot_skipRootPackage = false;
-
 
1784
            }
-
 
1785
            else
-
 
1786
            {
2097
               if (subElement.ParentID == 0 || thePackage.PackageID == subElement.ParentID)
1787
               // Generate heading and description for the package. This function also takes care of some
2098
                  parse_element(subElement, recurse_level);
1788
               // specially handled packages (terminology, references).
-
 
1789
               processLowerLevelContent = generatePackageHeadingAndDescription( thePackage, recurse_level );
2099
            }
1790
            }
2100
 
1791
 
2101
            // consume elements - we have to use a special sorting class here because of peculiarties
1792
            // generate package heading and description. This may, depending on the package name,
2102
            // in the way EA holds the elements in the collections. 
-
 
2103
            //EA_ElementSorter elementSorter = new EA_ElementSorter(thePackage);
1793
            // consume the elements in the package. If it does not, then consume them (and any diagrams)
2104
            //EA.Element theElement = null;
1794
            // locally here.
2105
            //int theElementsRelativeLevel = 0;
1795
            if (true == processLowerLevelContent)
2106
            //if (true == elementSorter.getFirst(ref theElement, ref theElementsRelativeLevel))
-
 
2107
           // {
1796
            {
2108
           //    do
1797
               // consume diagrams
2109
           //    {
-
 
2110
           //       int theElementsRecurseLevel = recurse_level + theElementsRelativeLevel;
1798
               generatePackageDiagrams( thePackage );
2111
 
1799
 
-
 
1800
               foreach(EA.Element subElement in thePackage.Elements)
-
 
1801
               {
-
 
1802
                  if (subElement.ParentID == 0 || thePackage.PackageID == subElement.ParentID)
2112
           //       parse_element( theElement, theElementsRecurseLevel );
1803
                     parse_element(subElement, recurse_level);
-
 
1804
               }
2113
 
1805
 
-
 
1806
               // Scan through the sub-packages within this package.
-
 
1807
               foreach(EA.Package subPackage in thePackage.Packages)
-
 
1808
               {
-
 
1809
                  // recurse
2114
           //    } while (true == elementSorter.getNext(ref theElement, ref theElementsRelativeLevel));
1810
                  parse_package(subPackage, recurse_level);
-
 
1811
               }
2115
           // }
1812
            }
2116
         }
1813
         }
2117
 
-
 
2118
         // Scan through the packages within this package.
1814
         else
2119
         foreach(EA.Package lowerLevelPackage in thePackage.Packages)
-
 
2120
         {
1815
         {
-
 
1816
            // disarm the one-shot package skipping feature if it was armed
-
 
1817
            if (oneShot_skipRootPackage == true)
2121
            // recurse
1818
            {
2122
            parse_package(lowerLevelPackage, recurse_level);
1819
               oneShot_skipRootPackage = false;
-
 
1820
            }         
2123
         }
1821
         }
2124
 
-
 
2125
         // If appropriate, turn off non-private class accumulation.
-
 
2126
         if (nameStartedWithDetailedDesign)
-
 
2127
            recordingNonPrivateClasses = false;
-
 
2128
      }
1822
      }
2129
 
1823
 
2130
 
1824
 
2131
      /// <summary>
1825
      /// <summary>
2132
      /// This is the overall generate document method. It creates a word document from 
1826
      /// This is the overall generate document method. It creates a word document from 
Line 2175... Line 1869...
2175
            // turn off grammar and spell checking
1869
            // turn off grammar and spell checking
2176
            WordDocument.GrammarChecked = false;
1870
            WordDocument.GrammarChecked = false;
2177
            WordDocument.SpellingChecked = false;
1871
            WordDocument.SpellingChecked = false;
2178
        
1872
        
2179
            // arm the public class list accumulator.
1873
            // arm the public class list accumulator.
2180
            recordingNonPrivateClasses = false;
-
 
2181
            nonPrivateClasses = new ArrayList();
1874
            classesNeedingUnitTests = new ArrayList();
2182
            classesWithUnitTests = new ArrayList();
1875
            classesWithUnitTests = new ArrayList();
2183
 
1876
 
-
 
1877
            processingLink = 0;
-
 
1878
 
-
 
1879
            processedElements = new ArrayList();
-
 
1880
 
2184
            // If the input template does not contain the styles needed for requirement documents, 
1881
            // If the input template does not contain the styles needed for requirement documents, 
2185
            // programmatically create them just in case.
1882
            // programmatically create them just in case.
2186
            StyleUtils.createRequirementStylesIfNecessary();
1883
            StyleUtils.createRequirementStyles();
2187
 
-
 
-
 
1884
            StyleUtils.createAdditionalHeadingLevelStyles();
2188
            StyleUtils.createElementDetailsStyles();
1885
            StyleUtils.createElementDetailsStyles();
-
 
1886
            StyleUtils.correctErrorsInTemplateStyles();
2189
 
1887
 
2190
            // Parse EA_DocGen Document Model. The parent package is the document model itself
1888
            // Parse EA_DocGen Document Model. The parent package is the document model itself
2191
            // and the packages within it are the top level packages only.
1889
            // and the packages within it are the top level packages only.
2192
            // Question: do we have to parse diagrams and elements at this top level? So far,
1890
            // Question: do we have to parse diagrams and elements at this top level? So far,
2193
            // this has been found to be unecessary, but you never know. For now, dont do it.
1891
            // this has been found to be unecessary, but you never know. For now, dont do it.
Line 2239... Line 1937...
2239
         // restore security settings
1937
         // restore security settings
2240
         WordApp.AutomationSecurity = securityBefore;
1938
         WordApp.AutomationSecurity = securityBefore;
2241
      }
1939
      }
2242
 
1940
 
2243
 
1941
 
2244
      /// <summary>
-
 
2245
      /// Class to sort EA elements alphabetically, in a case insensitive way.
-
 
2246
      /// This is used by the processRelationshipMatrixElement method.
-
 
2247
      /// </summary>
-
 
2248
      public class elementSortByName : IComparer
-
 
2249
      {
-
 
2250
         int IComparer.Compare( object x, object y)
-
 
2251
         {
-
 
2252
            if (x!=null & y!= null)
-
 
2253
               return (new CaseInsensitiveComparer()).Compare( ((EA.Element)x).Name, ((EA.Element)y).Name );
-
 
2254
            else
-
 
2255
               return 0;
-
 
2256
         }
-
 
2257
      }
-
 
2258
 
-
 
2259
 
-
 
2260
      public class attributeSortByPos : IComparer
-
 
2261
      {
-
 
2262
         int IComparer.Compare( object x, object y)
-
 
2263
         {
-
 
2264
            if (x!=null & y!= null)
-
 
2265
               return ((EA.Attribute)x).Pos - ((EA.Attribute)y).Pos;
-
 
2266
            else
-
 
2267
               return 0;
-
 
2268
         }
-
 
2269
      }
-
 
2270
 
-
 
2271
 
-
 
2272
      public class methodSortByPos : IComparer
-
 
2273
      {
-
 
2274
         int IComparer.Compare( object x, object y)
-
 
2275
         {
-
 
2276
            if (x!=null & y!= null)
-
 
2277
               return ((EA.Method)x).Pos - ((EA.Method)y).Pos;
-
 
2278
            else
-
 
2279
               return 0;
-
 
2280
         }
-
 
2281
      }
-
 
2282
  
-
 
2283
 
-
 
2284
      public class parameterSortByPos : IComparer
-
 
2285
      {
-
 
2286
         int IComparer.Compare( object x, object y)
-
 
2287
         {
-
 
2288
            if (x!=null & y!= null)
-
 
2289
               return ((EA.Parameter)x).Position - ((EA.Parameter)y).Position;
-
 
2290
            else
-
 
2291
               return 0;
-
 
2292
         }
-
 
2293
      }
-
 
2294
 
1942
 
2295
 
1943
 
2296
      #endregion
1944
      #endregion
2297
   }
1945
   }
2298
}
1946
}