bluetooth/btdocs/Designs/generate-bnep-document.ebs
branchRCL_3
changeset 13 16aa830c86c8
parent 12 9b6d3ca0c601
child 14 f8503e232b0c
equal deleted inserted replaced
12:9b6d3ca0c601 13:16aa830c86c8
     1 ' Generate-report.ebs
       
     2 '
       
     3 ' This is a RoseScript utility with which a user can traverse a 
       
     4 ' Rational Rose model and generate a Microsoft Word Document
       
     5 ' from the template "Formal.dot"
       
     6 '
       
     7 ' A lot of the early versions of this script were derived from
       
     8 ' work previously published on the Rational Developer's Network
       
     9 ' and made freely available.
       
    10 '
       
    11 ' TBD:
       
    12 '       3. Provide cleaning subroutine or external utility to curb growth of %TEMP%
       
    13 '               with rosedXXX.wmf files of rendered diagrams.
       
    14 '       4. Provide a package selection drop-down on the Dialog so that many projects can 
       
    15 '               coexist in the same model (bonus - reduces the probability of a 
       
    16 '               mook accidentally choosing to document the EPOC32 "include" package).
       
    17 '
       
    18 Const DefaultTool$ = "ReportGen"
       
    19 Const PRODUCTDEFAULTWORDDOCFILENAME     = 103
       
    20 '
       
    21 ' Different report type specs
       
    22 '
       
    23 Const RepAnalysisType = 0
       
    24 Const RepDesignType = 1
       
    25 Const RepAnalysisNDesignType = 2
       
    26 Const RepTestType = 3
       
    27 '
       
    28 ' Model verification options
       
    29 '
       
    30 Const RepVerifyNot = 0
       
    31 Const RepVerifySection = 1
       
    32 Const RepVerifyEmbed = 2
       
    33 '
       
    34 ' There is a state machine in here and these are the states
       
    35 '
       
    36 Const RPh_StartUp = 0
       
    37 Const RPh_Dynamic = 1
       
    38 Const RPh_Static = 2
       
    39 Const RPh_TailBoiler = 3
       
    40 Const RPh_Crosscheck = 4
       
    41 '
       
    42 ' For proofreading purposes
       
    43 '
       
    44 Const MissingTextStr$ = "ATTENTION: Do You Need Documentation For This Item?"
       
    45 '
       
    46 ' Useful type declaraions
       
    47 '
       
    48 '
       
    49 ' Told you there was a state machine in here
       
    50 '
       
    51 Type GeneratorStateType
       
    52     Phase As Integer
       
    53 End Type
       
    54 '
       
    55 ' Configurability - if this was Python, I'd serialise it
       
    56 ' and make it a config file
       
    57 '
       
    58 Type ReportOptionsType
       
    59     Title As String
       
    60     FileName As String
       
    61     Template As String
       
    62     Generate As Boolean
       
    63     WhiteBlock As Boolean
       
    64     ClassDiagrams As Boolean
       
    65     ScenarioDiagrams As Boolean
       
    66     StateDiagrams As Boolean
       
    67     UseCaseDiagrams As Boolean
       
    68     CppSyntax As Boolean
       
    69     PublicOnly As Boolean
       
    70 	FEBoiler As Boolean
       
    71 	BEBoiler As Boolean
       
    72 	SupportSubheadingTags As Boolean
       
    73     HighlightDocGaps As Boolean
       
    74     DocType As Integer
       
    75     VerifyType As Integer
       
    76 End Type
       
    77 '
       
    78 ' When verifying the model, we need to establish relationships
       
    79 ' between scenario/sequence diagrams and their title. Also, on each iteration, we need to 
       
    80 ' check that we don't create duplicate entries where a method is used
       
    81 ' more than once in the same context.
       
    82 '
       
    83 Type DiagEntry
       
    84     FigureTitle As String
       
    85     Diagram As ScenarioDiagram
       
    86     SeenBefore As Boolean
       
    87 End Type
       
    88 '
       
    89 ' Globals - don't we just lurve Basic?
       
    90 '
       
    91 Private ReportOptions As ReportOptionsType
       
    92 Private GeneratorState As GeneratorStateType
       
    93 '
       
    94 ' An array of DiagEntry
       
    95 '
       
    96 Public GlobalDiagList() As DiagEntry
       
    97 '
       
    98 ' So, the documentation doesn't explain how one would elicit the
       
    99 ' size of a dynamic array, so the counts have to be externalised.
       
   100 ' Just exactly how crap is that?
       
   101 '
       
   102 Public DiagListCount As Integer
       
   103 Public GlobalDiagListSize As Integer
       
   104 
       
   105 Public LicensedRoseApplication As Application
       
   106 Private resIFace As Object
       
   107 
       
   108 Public RWU_DiagramCount As Integer
       
   109 '
       
   110 ' Sort of like an Application Constructor - yech!
       
   111 '
       
   112 Sub WordUtilInit()
       
   113     Let RWU_DiagramCount = 1
       
   114     Let DiagListCount = 0
       
   115     Let GlobalDiagListSize = 0
       
   116     ReDim GlobalDiagList(0)
       
   117 End Sub
       
   118 
       
   119 '
       
   120 ' Helper function
       
   121 '
       
   122 Sub Para(WordApp As Object)
       
   123     WordApp.InsertPara
       
   124 End Sub
       
   125 '
       
   126 ' For banging in a huge bunch of whitespace
       
   127 '
       
   128 Sub WhiteBlock(WordApp As Object)
       
   129     Para WordApp
       
   130     Para WordApp
       
   131     Para WordApp
       
   132     Para WordApp
       
   133     Para WordApp
       
   134 End Sub
       
   135 '
       
   136 ' Helper for page breaks
       
   137 '
       
   138 Sub Break(WordApp As Object)
       
   139     WordApp.InsertPageBreak
       
   140 End Sub
       
   141 '
       
   142 ' This is to overcome the limitations of Word as a programmable application
       
   143 ' and all I can say is that the details are nasty.
       
   144 '
       
   145 Sub ReplaceFinalParagraphKludge (WordApp As Object)
       
   146     WordApp.linedown
       
   147     WordApp.charright 1, 1  ' go right one character and select
       
   148     WordApp.insertpara      ' overwrite the selected para marker with a new one
       
   149     WordApp.lineup
       
   150 End Sub
       
   151 '
       
   152 ' Will need to reset the state on these objects regularly
       
   153 '
       
   154 Sub ResetGlobalDiagList
       
   155     For i% = 0 To GlobalDiagListSize-1
       
   156         GlobalDiagList(i).SeenBefore = False
       
   157     Next i
       
   158 End Sub
       
   159 '
       
   160 ' We need this for extracting diagrams and rendering them
       
   161 ' on the file system before inserting them into a Word
       
   162 ' document. Note that this does not clean up after itself
       
   163 ' which means that you are likely to accumulate rosedXXX.wmf
       
   164 ' files in your %TEMP% directory. The good news is that it
       
   165 ' transparently reuses files on each run, so this is not inevitable
       
   166 ' and unrestrained growth.
       
   167 '
       
   168 Function GetTmpFileName
       
   169     Dim tmpFileName As String
       
   170     Dim tmpPathName As String
       
   171     
       
   172     tmpPathName = Environ("TEMP")
       
   173     If tmpPathName = ""     Then
       
   174         tmpPathName = CurDir
       
   175     End If
       
   176     Do
       
   177         tmpFileName = tmpPathName + "\rosed" & RWU_DiagramCount & ".wmf"
       
   178         If Not Dir(tmpFileName)="" Then
       
   179             Kill(tmpFileName)
       
   180         End If
       
   181     Loop Until (Dir(tmpFileName)="")
       
   182     RWU_DiagramCount = RWU_DiagramCount + 1
       
   183     GetTmpFileName = tmpFileName
       
   184 End Function
       
   185 
       
   186 '----------------------------------------------------------------------------
       
   187 '
       
   188 ' Specialist Word-related subroutines
       
   189 '
       
   190 '
       
   191 ' Generic Diagram insertion
       
   192 '
       
   193 Sub WordInsertDiagram(fileName As String, WordApp As Object)
       
   194     'ReplaceFinalParagraphKludge WordApp
       
   195     WordApp.CenterPara
       
   196     WordApp.InsertPicture fileName, false, false
       
   197     Para WordApp
       
   198 	ReplaceFinalParagraphKludge WordApp
       
   199 End Sub
       
   200 '
       
   201 ' Each diagram type is literally a different type in the object model, so
       
   202 ' since Basic has no polymorphic facilities, we have to resort to
       
   203 ' coding up a subroutine for each type. Yawn!
       
   204 '
       
   205 Sub WordInsertScenarioDiagram(aDiagram As ScenarioDiagram, WordApp As Object)
       
   206     Dim tmpFileName As String
       
   207     Let tmpFileName = GetTmpFileName
       
   208     aDiagram.RenderEnhanced tmpFileName
       
   209     WordInsertDiagram tmpFileName, WordApp
       
   210 End Sub
       
   211 
       
   212 Sub WordInsertStateDiagram(aDiagram As StateDiagram, WordApp As Object)
       
   213     Dim tmpFileName As String
       
   214     Let tmpFileName = GetTmpFileName
       
   215     aDiagram.RenderEnhanced tmpFileName
       
   216     WordInsertDiagram tmpFileName, WordApp
       
   217 End Sub
       
   218 
       
   219 Sub WordInsertClassDiagram(aDiagram As ClassDiagram, WordApp As Object)
       
   220     Dim tmpFileName As String
       
   221     Let tmpFileName = GetTmpFileName
       
   222     aDiagram.RenderEnhanced tmpFileName
       
   223     WordInsertDiagram tmpFileName, WordApp
       
   224 End Sub
       
   225 
       
   226 '
       
   227 ' So we want to be able to translate our "depth" in the model into the
       
   228 ' appropriate heading style in Word.
       
   229 '
       
   230 Function GetWordHeadingStyleName(HeadingNumber As Integer) As String
       
   231     GetWordHeadingStyleName = "Heading " & CStr(HeadingNumber)
       
   232 End Function
       
   233 '
       
   234 ' Generalised heading insertion by number
       
   235 '
       
   236 Sub WordInsertHeading(aLevel As Integer, aString As String, WordApp As Object)
       
   237         ' If you do not do it, it will not run.
       
   238     ReplaceFinalParagraphKludge WordApp
       
   239         ' Here's the real code that actually does something
       
   240     WordApp.FormatStyle GetWordHeadingStyleName(aLevel)      
       
   241     WordApp.Insert aString
       
   242     Para WordApp
       
   243     WordApp.FormatStyle "Normal"
       
   244 End Sub
       
   245 
       
   246 Sub WordInsertDocumentation(HeadingLevel As Integer, Documentation As String, WordApp As Object)
       
   247 	'
       
   248 	' It was requested that the script support the insertion of
       
   249 	' an HTML-like tag in the object documentation that would force the 
       
   250 	' insertion of a subheading in the output text.
       
   251 	' This will interefere with the real HTML generation capabilities
       
   252 	' of Rose, so it was originally only supported as a variant on the 
       
   253 	' script. This presents boring maintenance duplication issues, however, so it
       
   254 	' was reincorporated as a configurable option. Unfortunately, it does change 
       
   255 	' the signature of this method such that it requires a HeadingLevel even when it 
       
   256 	' doesn't use one. 
       
   257 	'
       
   258 	Dim Astr As String
       
   259 	Dim Bstr As String
       
   260 	Dim Cstr As String
       
   261 
       
   262     If Documentation <> "" Then
       
   263 		If ReportOptions.SupportSubheadingTags Then
       
   264 			Astr = Trim(Documentation)
       
   265 			Print "Astr: ", Astr
       
   266 			x% = InStr(1,Astr,"<h>",1)
       
   267 			y% = InStr(1,Astr,"</h>",1)
       
   268 			While x% <> 0 And y% <> 0
       
   269 				Cstr = Left(Astr,x%-1)
       
   270 				Print "Cstr : ", Cstr
       
   271         		WordApp.FormatStyle "Normal"
       
   272         		WordApp.Insert Trim(Cstr)
       
   273         		Para WordApp
       
   274 
       
   275 				Bstr = Mid(Astr,x%+3,y%-(x%+3))
       
   276 				Print "Bstr : ", Bstr
       
   277 				WordInsertHeading HeadingLevel,Trim(Bstr),WordApp
       
   278 
       
   279 				Astr = Right(Astr,Len(Astr)-(y%+3))
       
   280 				Print "Astr : ",Astr
       
   281 				x% = InStr(1,Astr,"<h>",1)
       
   282 				y% = InStr(1,Astr,"</h>",1)
       
   283 			Wend
       
   284         	WordApp.FormatStyle "Normal"
       
   285         	WordApp.Insert Trim(Astr)
       
   286         	Para WordApp
       
   287 		Else
       
   288         	WordApp.FormatStyle "Normal"
       
   289         	WordApp.Insert Trim(Documentation)
       
   290         	Para WordApp
       
   291 		End If
       
   292     Else
       
   293         ' Oh no - we seem to have missed out a piece of documentation.
       
   294         ' Another proofreading setting will highlight this lacuna for
       
   295         ' you in lucky red text.
       
   296         If ReportOptions.HighlightDocGaps Then
       
   297             WordApp.FormatStyle "Body Text"
       
   298             WordApp.Insert MissingTextStr
       
   299             Para WordApp
       
   300         End If
       
   301     End If
       
   302 	'
       
   303     ' To assist in the proofreading phases, it seemed useful
       
   304     ' to have a mode in which large chunks of whitespace were
       
   305     ' inserted into the document at every point where the hard working
       
   306     ' editor might wish to scribble notes and comments during the development
       
   307     ' of the text. Run the script with this set and print out the resultant document
       
   308     ' and you have a doc that facilitates the inveterate scribbler.
       
   309     ' I'm a great believer in appropriate technology.
       
   310 	'
       
   311     If ReportOptions.WhiteBlock Then
       
   312         WhiteBlock WordApp
       
   313     End If
       
   314 
       
   315 End Sub
       
   316 '
       
   317 ' Of course we want each of our diagrams to be numbered and titled.
       
   318 ' It's the done thing, and it's the thing that gets done here.
       
   319 '
       
   320 Sub WordInsertFigureName(aFigureName As String, WordApp As Object)
       
   321     WordApp.FormatStyle "Centered"
       
   322     WordApp.Insert "Figure " + CStr(RWU_DiagramCount-1) & ": " & aFigureName
       
   323     Para WordApp
       
   324     WordApp.FormatStyle "Normal"
       
   325 End Sub
       
   326 '
       
   327 ' Unfortunately, we have to operate slightly differently for scenarios, because of
       
   328 ' the verifications we may wish to run.
       
   329 '
       
   330 Sub WordInsertScenarioFigureName(aFigureName As String, WordApp As Object, XCEntry As DiagEntry)
       
   331     Dim tstr$
       
   332     tstr = "Figure " + CStr(RWU_DiagramCount-1) & ": " & aFigureName
       
   333     WordApp.FormatStyle "Centered"
       
   334     'WordApp.Insert "Figure " + CStr(RWU_DiagramCount-1) & ": " & aFigureName
       
   335     WordApp.Insert tstr
       
   336     Para WordApp
       
   337     WordApp.FormatStyle "Normal"
       
   338         ' Need  to keep track of titles applied to scenario diagrams.
       
   339     XCEntry.FigureTitle = tstr
       
   340     Let GlobalDiagList(DiagListCount) = XCEntry
       
   341     DiagListCount = DiagListCount + 1
       
   342 End Sub
       
   343 
       
   344 
       
   345 '---------------------------------------------------------------------------
       
   346 '
       
   347 ' Some handy utility muffins.
       
   348 '
       
   349 
       
   350 Public Function GetResourceString(resourceID As Long) As String
       
   351     
       
   352     If (resIFace Is Nothing) then
       
   353         Set resIFace = CreateObject("rvsreportgenres.rvsrepgeninterface")
       
   354     End If
       
   355     
       
   356     GetResourceString = resIFace.GetString(resourceID)
       
   357 End Function
       
   358 
       
   359 
       
   360 Function GetLicensedRoseApplication() As Application
       
   361     Set GetLicensedRoseApplication = RoseApp.GetLicensedApplication("{A567222E-CBBE-11D0-BC0B-00A024C67143}")
       
   362 End Function
       
   363 
       
   364 Function ReportDialogLoop(controlname$, action%, suppvalue%) As Integer
       
   365     If controlname$ = "Browse" Then
       
   366         FileName$ = SaveFilename$ ("Create a Word document",  "Word Documents:*.DOC")
       
   367         If FileName$ <> "" Then
       
   368             DlgText "FileName", FileName$
       
   369         End If
       
   370         ReportDialogLoop = 1
       
   371     End If
       
   372 End Function
       
   373 
       
   374 Function EnclosingDirPath(FileName As String)
       
   375     ' Extracts the enclosing directory path from a file name
       
   376     Dim Pos1, Pos2, Pos3
       
   377     On Error GoTo EnclosingDirPath_exception
       
   378     
       
   379     Pos3 = 255
       
   380     Pos2 = 1
       
   381     Pos1 = 1
       
   382     Do
       
   383         Pos3 = InStr(Pos2 + 1, FileName, "\")
       
   384         If Pos3 <> 0 Then
       
   385             Pos1 = Pos2
       
   386             Pos2 = Pos3
       
   387         Else
       
   388             Exit Do
       
   389         End If
       
   390     Loop
       
   391     
       
   392     EnclosingDirPath = Left(FileName, Pos2 - 1)
       
   393     Exit Function
       
   394     
       
   395 EnclosingDirPath_exception:
       
   396     Resume EnclosingDirPath_end
       
   397 EnclosingDirPath_end:
       
   398     'Exit with the full path
       
   399     EnclosingDirPath = FileName
       
   400 End Function
       
   401 
       
   402 Function GetAllOfClasses(aCategory As Category) As ClassCollection
       
   403     
       
   404     Dim theCatClassCollection As New ClassCollection
       
   405     Dim theCatClass As Class, theCatInnerClass As Class
       
   406     Dim I As Integer, J As Integer
       
   407     
       
   408     For I = 1 To aCategory.Classes.Count
       
   409         Set theCatClass =  aCategory.Classes.GetAt(I)
       
   410         theCatClassCollection.Add theCatClass
       
   411         For J = 1 To theCatClass.GetAllNestedClasses.Count
       
   412             Set theCatInnerClass = theCatClass.GetAllNestedClasses.GetAt(J)
       
   413             theCatClassCollection.Add theCatInnerClass
       
   414         Next J
       
   415     Next I
       
   416     
       
   417     Set GetAllOfClasses = theCatClassCollection
       
   418 End Function
       
   419 
       
   420 Function MakeFileName (Path As String, FileName As String) As String
       
   421     ' Check to see if the last character is a separator
       
   422     If Instr ("\/", Right$(Path, 1)) Then
       
   423         MakeFileName$ = Path & FileName
       
   424     Else
       
   425         MakeFileName$ = Path & "\" & FileName
       
   426     End If
       
   427 End Function
       
   428 
       
   429 Function ChangeFileExtension (FullFileName As String, NewExtension As String) As String
       
   430     FilePath$ = FileParse$ (FullFileName, 2)
       
   431     FileRoot$ = FileParse$ (FullFileName, 4)
       
   432     ChangeFileExtension$ = MakeFileName$ (FilePath$, FileRoot$ & "." & NewExtension$)
       
   433 End Function
       
   434 
       
   435 '------------------------------------------------------------------------------
       
   436 '
       
   437 ' Rose collections are unsorted. This is not considered sightly.
       
   438 '
       
   439 
       
   440 Sub sortalpha( aCategory As Category, myAlpha() As String)
       
   441     Dim theCatClassCollection As ClassCollection
       
   442     Set theCatClassCollection = GetAllOfClasses(aCategory)
       
   443     
       
   444     For ike = 1 To theCatClassCollection.count
       
   445         myAlpha(ike) = theCatClassCollection.GetAt(ike).Name
       
   446     Next ike
       
   447     arraysort myAlpha
       
   448     
       
   449     Set theCatClassCollection = Nothing
       
   450 End Sub
       
   451 
       
   452 Sub sortalphaclassdiagrams( aCategory As Category, myAlpha() As String)
       
   453     Dim classDiagrams As ClassDiagramCollection
       
   454     Set classDiagrams = aCategory.ClassDiagrams
       
   455     
       
   456     For ike = 1 To classDiagrams.count
       
   457         myAlpha(ike) = classDiagrams.GetAt(ike).Name
       
   458     Next ike
       
   459     arraysort myAlpha
       
   460     
       
   461     Set classDiagrams = Nothing
       
   462 End Sub
       
   463 
       
   464 Sub sortalphascenariodiagrams( aCategory As Category, myAlpha() As String)
       
   465     Dim scenarioDiagrams As ScenarioDiagramCollection
       
   466     Set scenarioDiagrams = aCategory.ScenarioDiagrams
       
   467     
       
   468     For ike = 1 To ScenarioDiagrams.count
       
   469         myAlpha(ike) = ScenarioDiagrams.GetAt(ike).Name
       
   470     Next ike
       
   471     arraysort myAlpha
       
   472     
       
   473     Set ScenarioDiagrams = Nothing
       
   474 End Sub
       
   475 
       
   476 
       
   477 '------------------------------------------------------------------------------
       
   478 '
       
   479 ' These higher level procedures pretty much do what their names say they do.
       
   480 '
       
   481 Sub SearchForClassDiagramsInPackage(WordApp As Object, aCategory As Category, HeadingNumber As Integer)
       
   482     
       
   483     Dim classDiagrams As ClassDiagramCollection
       
   484     Dim aClassDiagram As ClassDiagram
       
   485     Dim Alpha() As String
       
   486 
       
   487     Set classDiagrams = aCategory.ClassDiagrams
       
   488     ReDim Alpha(classDiagrams.Count)
       
   489     SortAlphaClassDiagrams aCategory, alpha
       
   490 
       
   491     If classDiagrams.Count Then
       
   492         'Dim theClass As Class
       
   493         'Dim NestedClasses As ClassCollection
       
   494         
       
   495         For CLSID = 1 To classDiagrams.Count
       
   496             Ike = classDiagrams.FindFirst(Alpha(CLSID))
       
   497             Set aClassDiagram = classDiagrams.GetAt(Ike)
       
   498         	If Not (aClassDiagram.IsUseCaseDiagram) Then
       
   499 				WordInsertHeading HeadingNumber, aClassDiagram.Name, WordApp
       
   500             	WordInsertClassDiagram aClassDiagram, WordApp
       
   501             	WordInsertFigureName aClassDiagram.Name, WordApp
       
   502             	WordInsertDocumentation HeadingNumber+1, aClassDiagram.Documentation, WordApp
       
   503         	End If
       
   504         Next CLSID
       
   505     End If
       
   506 
       
   507 
       
   508     'For clsID = 1 To classDiagrams.Count
       
   509      '   Set aClassDiagram=classDiagrams.GetAt(clsID)
       
   510      '   If Not (aClassDiagram.IsUseCaseDiagram) Then
       
   511 	 '		WordInsertHeading HeadingNumber, aClassDiagram.Name, WordApp
       
   512      '       WordInsertClassDiagram aClassDiagram, WordApp
       
   513      '       WordInsertFigureName aClassDiagram.Name, WordApp
       
   514      '       WordInsertDocumentation HeadingNumber+1, aClassDiagram.Documentation, WordApp
       
   515       '  End If
       
   516     'Next clsID
       
   517 End Sub
       
   518 
       
   519 Sub SearchForSeqAndCollabDiagramsInPackage(WordApp As Object, aCategory As Category, HeadingNumber As Integer)
       
   520     
       
   521     Dim ScenarioDiagrams As ScenarioDiagramCollection
       
   522     Dim aScenarioDiagram As ScenarioDiagram
       
   523     Dim Alpha() As String
       
   524     
       
   525     Set ScenarioDiagrams = aCategory.ScenarioDiagrams
       
   526     ReDim Alpha(ScenarioDiagrams.Count)
       
   527     SortAlphaScenarioDiagrams aCategory, alpha
       
   528 
       
   529     Dim XCEntry As DiagEntry
       
   530     GlobalDiagListSize = GlobalDiagListSize + ScenarioDiagrams.Count
       
   531     ReDim Preserve GlobalDiagList(GlobalDiagListSize)
       
   532     For ScenID = 1 To ScenarioDiagrams.Count
       
   533 		Ike = ScenarioDiagrams.FindFirst(Alpha(ScenID))
       
   534         Set aScenarioDiagram=ScenarioDiagrams.GetAt(Ike)
       
   535 		WordInsertHeading HeadingNumber, aScenarioDiagram.Name, WordApp
       
   536         WordInsertScenarioDiagram aScenarioDiagram, WordApp
       
   537         Set XCEntry.Diagram = aScenarioDiagram
       
   538         WordInsertScenarioFigureName aScenarioDiagram.Name, WordApp, XCEntry
       
   539         WordInsertDocumentation HeadingNumber+1, aScenarioDiagram.Documentation, WordApp
       
   540     Next ScenID
       
   541 End Sub
       
   542 
       
   543 Sub SearchForClassDiagramsInUseCase(WordApp As Object, aUseCase As UseCase, HeadingNumber As Integer)
       
   544     
       
   545     Dim classDiagrams As ClassDiagramCollection
       
   546     Dim aClassDiagram As ClassDiagram
       
   547     
       
   548     Set classDiagrams = aUseCase.ClassDiagrams
       
   549     
       
   550     For clsID = 1 To classDiagrams.Count
       
   551         Set aClassDiagram=classDiagrams.GetAt(clsID)
       
   552         If Not (aClassDiagram.IsUseCaseDiagram) Then
       
   553 			WordInsertHeading HeadingNumber, aClassDiagram.Name, WordApp			
       
   554             WordInsertClassDiagram aClassDiagram, WordApp
       
   555             WordInsertFigureName aClassDiagram.Name, WordApp
       
   556             WordInsertDocumentation HeadingNumber+1, aClassDiagram.Documentation, WordApp
       
   557         Else
       
   558             If (aClassDiagram.IsUseCaseDiagram) And (ReportOptions.UseCaseDiagrams) Then
       
   559 				WordInsertHeading HeadingNumber, aClassDiagram.Name, WordApp
       
   560                 WordInsertClassDiagram aClassDiagram, WordApp
       
   561                 WordInsertFigureName aClassDiagram.Name, WordApp
       
   562                 WordInsertDocumentation HeadingNumber+1, aClassDiagram.Documentation, WordApp
       
   563             End If
       
   564         End If
       
   565     Next clsID
       
   566 End Sub
       
   567 
       
   568 
       
   569 Sub SearchForSeqAndCollabDiagramsInUseCase(WordApp As Object, aUseCase As UseCase, HeadingNumber As Integer)
       
   570     
       
   571     Dim ScenarioDiagrams As ScenarioDiagramCollection
       
   572     Dim aScenarioDiagram As ScenarioDiagram
       
   573     
       
   574     Set ScenarioDiagrams = aUseCase.ScenarioDiagrams
       
   575     Dim XCEntry As DiagEntry
       
   576     GlobalDiagListSize = GlobalDiagListSize + ScenarioDiagrams.Count
       
   577     ReDim Preserve GlobalDiagList(GlobalDiagListSize)
       
   578     For ScenID = 1 To ScenarioDiagrams.Count
       
   579         Set aScenarioDiagram=ScenarioDiagrams.GetAt(ScenID)
       
   580 		WordInsertHeading HeadingNumber, aScenarioDiagram.Name, WordApp
       
   581         WordInsertScenarioDiagram aScenarioDiagram, WordApp
       
   582         Set XCEntry.Diagram = aScenarioDiagram
       
   583         WordInsertScenarioFigureName aScenarioDiagram.Name, WordApp, XCEntry
       
   584         WordInsertDocumentation HeadingNumber+1, aScenarioDiagram.Documentation, WordApp
       
   585     Next ScenID
       
   586 End Sub
       
   587 
       
   588 
       
   589 
       
   590 Sub SearchForStateDiagramsInPackage(WordApp As Object, aCategory As Category, HeadingNumber As Integer)
       
   591     Dim aStateMachineOwner As StateMachineOwner
       
   592     Dim aStateMachineCollection As StateMachineCollection
       
   593     Dim aStateMachine As StateMachine
       
   594     Dim aStateDiagram As StateDiagram
       
   595     Dim aStateDiagramCollection As StateDiagramCollection
       
   596     Dim aStateCollection As StateCollection
       
   597     Dim aState As State
       
   598     
       
   599     Set aStateMachineOwner = aCategory.StateMachineOwner
       
   600     Set aStateMachineCollection = aStateMachineOwner.StateMachines
       
   601     If aStateMachineCollection.Count Then
       
   602         For SMID = 1 To aStateMachineCollection.Count
       
   603             Set aStateMachine = aStateMachineCollection.GetAt(SMID)
       
   604             Set aStateDiagramCollection = aStateMachine.Diagrams
       
   605             WordInsertHeading HeadingNumber, aStateMachine.Name, WordApp
       
   606             If aStateDiagramCollection.Count Then
       
   607                 For SDID = 1 To aStateDiagramCollection.Count
       
   608                     Set aStateDiagram = aStateDiagramCollection.GetAt(SDID)
       
   609 					WordInsertHeading HeadingNumber, aStateDiagram.Name, WordApp
       
   610                     WordInsertStateDiagram aStateDiagram, WordApp
       
   611                     WordInsertFigureName aStateDiagram.Name, WordApp
       
   612                     WordInsertDocumentation HeadingNumber+1, aStateDiagram.Documentation, WordApp
       
   613                 Next SDID
       
   614             End If
       
   615             Set aStateCollection = aStateMachine.States
       
   616             If aStateCollection.Count Then
       
   617                 For STID = 1 To aStateCollection.Count
       
   618                     Set aState = AstateCollection.GetAt(STID)
       
   619                     WordInsertHeading HeadingNumber+1, aState.Name, WordApp
       
   620                     WordInsertDocumentation HeadingNumber+1, aState.Documentation, WordApp
       
   621                 Next STID
       
   622             End If
       
   623         Next SMID
       
   624     End If
       
   625 End Sub
       
   626 '
       
   627 ' Cunningly, we find that Use Case diagrams are not a distinct type,
       
   628 ' but are a specialised state of ClassDiagram
       
   629 ' Ho ho, go figure.
       
   630 '
       
   631 Sub SearchForUseCaseDiagramsInPackage(WordApp As Object, aCategory As Category, HeadingNumber As Integer)
       
   632     Dim ClassDiagrams As ClassDiagramCollection
       
   633     Dim aClassDiagram As ClassDiagram
       
   634 
       
   635     Set ClassDiagrams = aCategory.ClassDiagrams
       
   636     For ClsID = 1 To ClassDiagrams.Count
       
   637         Set aClassDiagram = ClassDiagrams.GetAt(ClsID)
       
   638         If aClassDiagram.IsUseCaseDiagram Then
       
   639 			WordInsertHeading HeadingNumber, aClassDiagram.Name, WordApp
       
   640             WordInsertClassDiagram aClassDiagram, WordApp
       
   641             WordInsertFigureName aClassDiagram.Name, WordApp
       
   642             WordInsertDocumentation HeadingNumber+1, aClassDiagram.Documentation, WordApp
       
   643         End If
       
   644     Next ClsID
       
   645 End Sub
       
   646 
       
   647 
       
   648 '------------------------------------------------------------------------------
       
   649 '
       
   650 ' We live in a C++ world, so we need to be able to show our attributes
       
   651 ' in a way familiar to code monkeys.
       
   652 '
       
   653 Sub GenerateAttribute(WordApp As Object, anAttribute As Attribute, HeadingNumber As Integer)
       
   654     Dim theAttribute As String
       
   655     
       
   656     If ReportOptions.CppSyntax Then
       
   657         Select Case anAttribute.ExportControl
       
   658             Case rsPublicAccess
       
   659                 theAttribute = "Public:   "
       
   660             Case rsProtectedAccess
       
   661                 theAttribute = "Protected:   "
       
   662             Case rsPrivateAccess
       
   663                 theAttribute = "Private:   "
       
   664         End Select
       
   665         theAttribute = theAttribute & anAttribute.Type & " "
       
   666     End If
       
   667     
       
   668     theAttribute = theAttribute & anAttribute.Name
       
   669     If ReportOptions.CppSyntax Then
       
   670         If Len(anAttribute.InitValue) > 0 Then
       
   671             theAttribute = theAttribute & " = " & anAttribute.InitValue
       
   672         End If
       
   673     End If
       
   674     
       
   675     WordInsertHeading HeadingNumber, theAttribute, WordApp
       
   676     WordInsertDocumentation HeadingNumber+1, anAttribute.Documentation, WordApp
       
   677 End Sub
       
   678 '
       
   679 ' We like our attributes grouped according to their access specification, of course
       
   680 '
       
   681 Sub GenerateClassAttributeAccessGroup(WordApp As Object, attColl As AttributeCollection, HeadingNumber As Integer)
       
   682     If attColl.Count Then
       
   683         For AttrID = 1 To attColl.Count
       
   684             GenerateAttribute WordApp, attColl.GetAt(AttrID), HeadingNumber
       
   685         Next AttrID
       
   686     End If
       
   687 End Sub
       
   688 '
       
   689 ' So this procedure iterates across the lot and groups them accordingly.
       
   690 ' However, I'm pretty sure we would frown on any public class attributes, wouldn't we? 
       
   691 ' And I always think that protected class attributes have to be well justified. 
       
   692 ' Generally they are used to get round analysis errors, otherwise.
       
   693 '
       
   694 Sub GenerateClassAttributes(WordApp As Object, aClass As Class, HeadingNumber As Integer)
       
   695     Dim PublicAttributes As New AttributeCollection
       
   696     Dim ProtectedAttributes As New AttributeCollection
       
   697     Dim PrivateAttributes As New AttributeCollection
       
   698     Dim anAttribute As Attribute
       
   699     
       
   700     If aClass.Attributes.Count Then
       
   701         For AttrID = 1 To aClass.Attributes.Count
       
   702             Set anAttribute = aClass.Attributes.GetAt(AttrID)
       
   703             Select Case anAttribute.ExportControl
       
   704                 Case rsPublicAccess
       
   705                     PublicAttributes.Add anAttribute
       
   706                 Case rsProtectedAccess
       
   707                     ProtectedAttributes.Add anAttribute
       
   708                 Case rsPrivateAccess
       
   709                     PrivateAttributes.Add anAttribute
       
   710             End Select
       
   711         Next AttrID
       
   712         WordInsertHeading HeadingNumber, aClass.Name & " Attributes", WordApp
       
   713         GenerateClassAttributeAccessGroup WordApp, PublicAttributes, HeadingNumber+1
       
   714         If Not ReportOptions.PublicOnly Then
       
   715             GenerateClassAttributeAccessGroup WordApp, ProtectedAttributes, HeadingNumber+1
       
   716             GenerateClassAttributeAccessGroup WordApp, PrivateAttributes, HeadingNumber+1
       
   717         End If
       
   718     End If
       
   719 End Sub
       
   720 
       
   721 '------------------------------------------------------------------------------
       
   722 ' 
       
   723 ' So here we go, doing the same with operations as we did with attributes.
       
   724 '
       
   725 Function GenerateParameter (aParameter As Parameter) As String
       
   726     Code$ = aParameter.Name + ":" + aParameter.Type
       
   727     GenerateParameter = Code$
       
   728 End Function
       
   729 
       
   730 Sub GenerateOperation(WordApp As Object, anOperation As Operation, HeadingNumber As Integer)
       
   731     Dim theOperation As String
       
   732     
       
   733     If ReportOptions.CppSyntax Then
       
   734         Select Case anOperation.ExportControl
       
   735             Case rsPublicAccess
       
   736                 theOperation = "Public:   "
       
   737             Case rsProtectedAccess
       
   738                 theOperation = "Protected:   "
       
   739             Case rsPrivateAccess
       
   740                 theOperation = "Private:   "
       
   741         End Select
       
   742     End If
       
   743     
       
   744     theOperation = theOperation + anOperation.Name
       
   745     
       
   746     If ReportOptions.CppSyntax Then
       
   747         Params$ = ""
       
   748         If anOperation.Parameters.Count Then
       
   749             For OperID = 1 To anOperation.Parameters.Count - 1
       
   750                 Params$ = Params$ + GenerateParameter(anOperation.Parameters.GetAt(OperID))
       
   751                 Params$ = Params$ + ", "
       
   752             Next OperID
       
   753             Params$ = Params$ + GenerateParameter(anOperation.Parameters.GetAt(anOperation.Parameters.Count))
       
   754         End If
       
   755         theOperation = theOperation & "( " & Params$ & ")"
       
   756     End If
       
   757     WordInsertHeading HeadingNumber, theOperation, WordApp
       
   758     WordInsertDocumentation HeadingNumber+1, anOperation.Documentation, WordApp
       
   759         If ReportOptions.VerifyType = RepVerifyEmbed Then
       
   760                 GenerateMethodUsageEntry anOperation, WordApp
       
   761         End If
       
   762 
       
   763 End Sub
       
   764 
       
   765 Sub GenerateClassOperationAccessGroup(WordApp As Object, attColl As OperationCollection, HeadingNumber As Integer)
       
   766     If attColl.Count Then
       
   767         For AttrID = 1 To attColl.Count
       
   768             GenerateOperation WordApp, attColl.GetAt(AttrID), HeadingNumber
       
   769         Next AttrID
       
   770     End If
       
   771 End Sub
       
   772 
       
   773 
       
   774 Sub GenerateClassOperations(WordApp As Object, aClass As Class, HeadingNumber As Integer)
       
   775     Dim PublicOperations As New OperationCollection
       
   776     Dim ProtectedOperations As New OperationCollection
       
   777     Dim PrivateOperations As New OperationCollection
       
   778     Dim anOperation As Operation
       
   779     
       
   780 	WordApp.FormatStyle "Normal"
       
   781 	If ReportOptions.VerifyType = RepVerifyEmbed Then
       
   782 		Para WordApp
       
   783 		WordApp.FormatFont Bold:=True
       
   784 		WordApp.Insert aClass.Name
       
   785 		WordApp.FormatFont Bold:=False
       
   786 
       
   787     	If aClass.Operations.Count = 0 Then
       
   788 			WordApp.Insert " has no operations defined in this model."
       
   789 			'Para WordApp
       
   790 		Else
       
   791 			WordApp.Insert " has " 
       
   792 			WordApp.Insert CStr(aClass.Operations.Count)
       
   793 			WordApp.Insert " operations defined in this model:"
       
   794 			'Para WordApp
       
   795 	 	End If
       
   796 	 End If
       
   797 	 If aClass.Operations.Count <> 0 Then
       
   798         For OperID = 1 To aClass.Operations.Count
       
   799             Set anOperation = aClass.Operations.GetAt(OperID)
       
   800             Select Case anOperation.ExportControl
       
   801                 Case rsPublicAccess
       
   802                     PublicOperations.Add anOperation
       
   803                 Case rsProtectedAccess
       
   804                     ProtectedOperations.Add anOperation
       
   805                 Case rsPrivateAccess
       
   806                     PrivateOperations.Add anOperation
       
   807             End Select
       
   808         Next OperID
       
   809         'WordInsertHeading HeadingNumber, aClass.Name & " Operations", WordApp
       
   810         GenerateClassOperationAccessGroup WordApp, PublicOperations, HeadingNumber
       
   811         If Not ReportOptions.PublicOnly Then
       
   812             GenerateClassOperationAccessGroup WordApp, ProtectedOperations, HeadingNumber
       
   813             GenerateClassOperationAccessGroup WordApp, PrivateOperations, HeadingNumber
       
   814         End If
       
   815     End If
       
   816 End Sub
       
   817 
       
   818 '------------------------------------------------------------------------------
       
   819 
       
   820 
       
   821 Sub GenerateTheClassBody(WordApp As Object, aClass As Class, HeadingNumber As Integer)
       
   822     WordInsertDocumentation HeadingNumber+1, aClass.Documentation, WordApp
       
   823     If aClass.Persistence Then
       
   824         WordApp.Insert "Persistent Class"
       
   825         Para WordApp
       
   826     End If
       
   827     
       
   828     Dim SuperClasses As ClassCollection
       
   829     Dim theSuperClass As Class
       
   830     Set SuperClasses = aClass.GetSuperClasses
       
   831     If SuperClasses.Count Then
       
   832         ClassList$ = ""
       
   833         For CLSID = 1 To SuperClasses.Count
       
   834             Set theSuperClass = SuperClasses.GetAt(CLSID)
       
   835             If ClassList$ <> "" Then
       
   836                 ClassList$ = ClassList$ & ", "
       
   837             End If
       
   838             ClassList$ = ClassList$ & theSuperClass.Name
       
   839         Next CLSID
       
   840         WordApp.Insert "Derived from " & ClassList$
       
   841         Para WordApp
       
   842     End If
       
   843     
       
   844     GenerateClassAttributes WordApp, aClass, HeadingNumber+1
       
   845     GenerateClassOperations WordApp, aClass, HeadingNumber+1
       
   846 End Sub
       
   847 '
       
   848 ' For each class in the category
       
   849 '
       
   850 Sub GenerateLogicalClass(WordApp As Object, aClass As Class, HeadingNumber As Integer)
       
   851     On Error Resume Next
       
   852     
       
   853     WordInsertHeading HeadingNumber, aClass.Name, WordApp
       
   854     GenerateTheClassBody WordApp, aClass, HeadingNumber
       
   855 End Sub
       
   856 
       
   857 Sub PrintClassesForCategory (WordApp As Object, aCategory As Category, HeadingNumber As Integer, myAlpha() As String)
       
   858     Dim lastNoNameClassIndex As Integer
       
   859     Dim theCatClassCollection As ClassCollection
       
   860     Set theCatClassCollection = GetAllOfClasses(aCategory)
       
   861     
       
   862     If theCatClassCollection.Count Then
       
   863         Dim theClass As Class
       
   864         Dim NestedClasses As ClassCollection
       
   865         
       
   866         For CLSID = 1 To theCatClassCollection.Count
       
   867             If(myAlpha(CLSID) = "") Then
       
   868                 If (lastNoNameClassIndex = 0) Then
       
   869                     Ike = theCatClassCollection.FindFirst("")
       
   870                     lastNoNameClassIndex  = Ike
       
   871                 Else
       
   872                     Ike = theCatClassCollection.FindNext(lastNoNameClassIndex,"")
       
   873                     lastNoNameClassIndex  = Ike
       
   874                 End If
       
   875             Else
       
   876                 Ike = theCatClassCollection.FindFirst(myAlpha(CLSID))
       
   877             End If
       
   878             Set theClass = theCatClassCollection.GetAt(Ike)
       
   879             GenerateLogicalClass WordApp, theClass, HeadingNumber+1
       
   880         Next CLSID
       
   881     End If
       
   882     Set theClassCollection = Nothing
       
   883 End Sub
       
   884 
       
   885 
       
   886 Sub PrintCategoryClasses(WordApp As Object, aCategory As Category, HeadingNumber As Integer)
       
   887     Dim Alpha() As String
       
   888     Dim theCatClassCollection As ClassCollection
       
   889     
       
   890 	If HeadingNumber > 1 Then
       
   891     	WordInsertHeading HeadingNumber, aCategory.Name, WordApp
       
   892 	End If
       
   893     WordInsertDocumentation HeadingNumber+1, aCategory.Documentation, WordApp
       
   894     
       
   895     Set theCatClassCollection = GetAllOfClasses(aCategory)
       
   896     ReDim Alpha(theCatClassCollection.Count)
       
   897     SortAlpha aCategory, alpha
       
   898     
       
   899     If ReportOptions.ClassDiagrams Then
       
   900         SearchForClassDiagramsInPackage WordApp, aCategory, (HeadingNumber+1)
       
   901     End If
       
   902     
       
   903     If ReportOptions.StateDiagrams Then
       
   904         SearchForStateDiagramsInPackage WordApp, aCategory, (HeadingNumber+1)
       
   905     End If
       
   906         
       
   907     If ReportOptions.UseCaseDiagrams Then
       
   908         SearchForUseCaseDiagramsInPackage WordApp, aCategory, (HeadingNumber+1)
       
   909     End If
       
   910     
       
   911     If ReportOptions.ScenarioDiagrams Then
       
   912         SearchForSeqAndCollabDiagramsInPackage WordApp, aCategory, (HeadingNumber+1)
       
   913     End If
       
   914 
       
   915 	'PrintClassesForCategory WordApp, aCategory, HeadingNumber, Alpha
       
   916     
       
   917 End Sub
       
   918 
       
   919 Sub GenerateUseCase (WordApp As Object, aUseCase As UseCase, HeadingNumber As Integer)
       
   920     WordInsertHeading HeadingNumber, aUseCase.Name, WordApp
       
   921     WordInsertDocumentation HeadingNumber+1, aUseCase.Documentation, WordApp
       
   922     If ReportOptions.ClassDiagrams Then
       
   923         SearchForClassDiagramsInUseCase WordApp, aUseCase, (HeadingNumber+1)
       
   924     End If
       
   925     If ReportOptions.ScenarioDiagrams Then
       
   926         SearchForSeqAndCollabDiagramsInUseCase WordApp, aUseCase, (HeadingNumber+1)
       
   927     End If
       
   928 End Sub
       
   929 
       
   930 Sub PrintCategoryUseCases(WordApp As Object, aCategory As Category, HeadingNumber As Integer)
       
   931     Dim Alpha() As String
       
   932     Dim theCatClassCollection As ClassCollection
       
   933     
       
   934 	If HeadingNumber > 1 Then
       
   935     	WordInsertHeading HeadingNumber, aCategory.Name, WordApp
       
   936 	End If
       
   937     WordInsertDocumentation HeadingNumber+1, aCategory.Documentation, WordApp
       
   938     
       
   939     SearchForClassDiagramsInPackage WordApp, aCategory, (HeadingNumber+1)
       
   940     SearchForStateDiagramsInPackage WordApp, aCategory, (HeadingNumber+1)
       
   941     SearchForUseCaseDiagramsInPackage WordApp, aCategory, (HeadingNumber+1)
       
   942     SearchForSeqAndCollabDiagramsInPackage WordApp, aCategory, (HeadingNumber+1)
       
   943     
       
   944     If aCategory.UseCases.Count Then
       
   945         Dim theUseCase As UseCase
       
   946         Dim numberOfApplicableUseCases As Integer
       
   947         Dim UseCaseNames$()
       
   948         numberOfApplicableUseCases = 0
       
   949         For ucID = 1 To aCategory.UseCases.Count
       
   950             Set theUseCase = aCategory.UseCases.GetAt(ucID)
       
   951             ReDim Preserve UseCaseNames$(numberOfApplicableUseCases +1)
       
   952             UseCaseNames$(numberOfApplicableUseCases) = theUseCase.Name
       
   953             numberOfApplicableUseCases = numberOfApplicableUseCases +1
       
   954         Next ucID
       
   955         
       
   956         ArraySort UseCaseNames$()
       
   957         
       
   958         For i% = 1 To numberOfApplicableUseCases
       
   959             ucID = aCategory.UseCases.FindFirst(UseCaseNames$(i%))
       
   960             Set theUseCase = aCategory.UseCases.GetAt(ucID)
       
   961             If theUseCase Is Nothing Then
       
   962             Else
       
   963                 GenerateUseCase WordApp, theUseCase, (HeadingNumber +1)
       
   964             End If
       
   965         Next i%
       
   966     End If
       
   967     
       
   968 End Sub
       
   969 
       
   970 
       
   971 Sub PrintCategory(WordApp As Object, aCategory As Category, HeadingNumber As Integer)
       
   972     Dim Beta() As String
       
   973     If aCategory.Name <> "Undocument" Then
       
   974     Select Case GeneratorState.Phase
       
   975         Case RPh_Dynamic
       
   976 			If HeadingNumber = 1 Then
       
   977 				WordInsertHeading HeadingNumber, "Analysis", WordApp
       
   978 			End If
       
   979             Call PrintCategoryUseCases(WordApp, aCategory, HeadingNumber)
       
   980 			Call PrintCategoryClasses(WordApp, aCategory, HeadingNumber)
       
   981         Case RPh_Static
       
   982 			If HeadingNumber = 1 Then
       
   983 				WordInsertHeading HeadingNumber, "Design", WordApp
       
   984 			End If
       
   985             Call PrintCategoryClasses(WordApp, aCategory, HeadingNumber)
       
   986         Case RPh_StartUp
       
   987         Case RPh_TailBoiler
       
   988         Case RPh_Crosscheck
       
   989     End Select
       
   990     ReDim Beta(aCategory.Categories.Count)
       
   991     For Ike = 1 To aCategory.Categories.Count
       
   992         Beta(Ike) = aCategory.Categories.GetAt(Ike).Name
       
   993     Next Ike
       
   994     ArraySort Beta
       
   995     For CatID = 1 To aCategory.Categories.Count
       
   996         Ike = aCategory.Categories.FindFirst(Beta(CatID))
       
   997         Call PrintCategory(WordApp, aCategory.Categories.GetAt(Ike), HeadingNumber+1)
       
   998     Next CatID
       
   999 	End If 
       
  1000 End Sub
       
  1001 
       
  1002 Sub GenerateBehaviouralAnalysisSection(WordApp As Object)
       
  1003     Break WordApp
       
  1004     'WordInsertHeading 1, "Behavioural Analysis", WordApp
       
  1005     GeneratorState.Phase = RPh_Dynamic
       
  1006     PrintCategory WordApp, LicensedRoseApplication.CurrentModel.RootUseCaseCategory, 1
       
  1007 End Sub
       
  1008 
       
  1009 Sub GenerateStaticRelationshipSection(WordApp As Object)
       
  1010     Break WordApp
       
  1011     'WordInsertHeading 1, "Static Relationships", WordApp
       
  1012     GeneratorState.Phase = RPh_Static
       
  1013     PrintCategory WordApp, LicensedRoseApplication.CurrentModel.RootCategory, 1
       
  1014 End Sub
       
  1015 
       
  1016 
       
  1017 Sub GenerateMethodUsageEntry(Op As Operation, WordApp As Object)
       
  1018     ResetGlobalDiagList
       
  1019     Dim Mc As MessageCollection
       
  1020     Dim Used As Boolean
       
  1021     Used = False
       
  1022 	WordApp.FormatStyle "Normal"
       
  1023     For i% = 0 To GlobalDiagListSize-1
       
  1024         Set Mc = GlobalDiagList(i).Diagram.GetMessages
       
  1025         For j% = 1 To Mc.Count
       
  1026             If Mc.GetAt(j).GetOperation Is Not Nothing Then
       
  1027                 If Mc.GetAt(j).GetOperation.GetUniqueId = Op.GetUniqueId Then
       
  1028                     Used = True
       
  1029                     If GlobalDiagList(i).SeenBefore = False Then
       
  1030                         WordApp.Insert "Used in "
       
  1031                         WordApp.Insert GlobalDiagList(i).FigureTitle
       
  1032                         Para WordApp
       
  1033                         GlobalDiagList(i).SeenBefore = True
       
  1034                     End If
       
  1035                 End If
       
  1036             End If
       
  1037         Next j
       
  1038     Next i
       
  1039     If Used = False Then
       
  1040         WordApp.Insert "Not used in any Sequence or Collaboration in this view of the model."
       
  1041         Para WordApp
       
  1042     End If
       
  1043 End Sub
       
  1044 
       
  1045 Sub GenerateScenarioCrosscheckSection(WordApp As Object)
       
  1046     Break WordApp
       
  1047     GeneratorState.Phase = RPh_Crosscheck
       
  1048     
       
  1049     WordInsertHeading 1, "Model Verification and Checking", WordApp
       
  1050     
       
  1051     Dim AllClasses As ClassCollection
       
  1052     Dim Op2 As Operation
       
  1053     Dim Ops As OperationCollection
       
  1054     Dim Used As Boolean
       
  1055     Set AllClasses = LicensedRoseApplication.CurrentModel.GetAllClasses
       
  1056     
       
  1057     For i% = 1 To AllClasses.Count
       
  1058         Dim UsedClassOps As New OperationCollection
       
  1059         Dim UnusedClassOps As New OperationCollection
       
  1060         WordInsertHeading 2,AllClasses.GetAt(i).Name,WordApp
       
  1061         
       
  1062         Set Ops = AllClasses.GetAt(i).Operations
       
  1063         For j% = 1 To Ops.Count
       
  1064             Set Op2 = Ops.GetAt(j)
       
  1065             WordApp.FormatFont Bold:=True
       
  1066             WordApp.Insert Op2.Name
       
  1067             WordApp.FormatFont Bold:=False    
       
  1068             Para WordApp
       
  1069             GenerateMethodUsageEntry Op2, WordApp
       
  1070         Next j
       
  1071     Next i 
       
  1072 End Sub
       
  1073 
       
  1074 Sub GenerateTailEndBoilerPlate(WordApp As Object)
       
  1075     GeneratorState.Phase = RPh_TailBoiler
       
  1076     Break WordApp
       
  1077     WordInsertHeading 1, "Further Information", WordApp
       
  1078     WordInsertHeading 2, "People", WordApp
       
  1079     WordInsertHeading 2, "References", WordApp
       
  1080     WordInsertHeading 2, "Open Issues", WordApp
       
  1081     WordInsertHeading 2, "Glossary", WordApp
       
  1082     WordInsertHeading 2, "Document History", WordApp
       
  1083     WordInsertHeading 2, "Document Review Date", WordApp
       
  1084 End Sub
       
  1085 
       
  1086 Sub GenerateReport(WordApp As Object)
       
  1087 Dim UsedOperations As New OperationCollection
       
  1088     WordApp.EndOfDocument
       
  1089 	If ReportOptions.FEBoiler = True Then
       
  1090     	WordInsertHeading 1, "Introduction", WordApp
       
  1091     	WordInsertHeading 2, "Overview", WordApp
       
  1092     	WordInsertHeading 2, "Purpose and Scope", WordApp
       
  1093 	End If
       
  1094     
       
  1095     Select Case ReportOptions.DocType
       
  1096         Case RepAnalysisType
       
  1097             GenerateBehaviouralAnalysisSection WordApp
       
  1098         Case RepDesignType
       
  1099             GenerateStaticRelationshipSection WordApp
       
  1100         Case RepAnalysisNDesignType
       
  1101             GenerateBehaviouralAnalysisSection WordApp
       
  1102             GenerateStaticRelationshipSection WordApp
       
  1103         Case RepTestType
       
  1104     End Select
       
  1105     
       
  1106     If ReportOptions.VerifyType = RepVerifySection Then
       
  1107         GenerateScenarioCrosscheckSection WordApp
       
  1108     End If
       
  1109 
       
  1110 	If ReportOptions.BEBoiler = True Then
       
  1111     	GenerateTailEndBoilerPlate WordApp
       
  1112 	End If
       
  1113 End Sub
       
  1114 
       
  1115 Begin Dialog ReportDialog ,,224,320,"Generate Symbian Documentation",.ReportDialogLoop
       
  1116 
       
  1117 	Text 8,4,148,8,"Report &Title",.TitleText
       
  1118 	TextBox 12,16,202,12,.Title
       
  1119 
       
  1120 	Text 8,32,112,8,"&Template File Name:",.TemplateFileNameText
       
  1121 	TextBox 12,44,202,12,.TemplateFileName
       
  1122 
       
  1123 	Text 8,60,112,8,"&Report File Name:",.FileNameText
       
  1124 	TextBox 12,72,202,12,.FileName
       
  1125 
       
  1126 	PushButton 174,87,44,14,"Browse",.Browse
       
  1127 
       
  1128 	GroupBox 8,102,92,60,"Report Document Type",.ReportTypeGroup
       
  1129 	OptionGroup .ReportType
       
  1130 	OptionButton 12,114,80,8,"Analysis",.AnalysisReport
       
  1131 	OptionButton 12,126,80,8,"Design",.DesignReport
       
  1132 	OptionButton 12,138,80,8,"Analysis and Design",.AnalysisNDesignReport
       
  1133 	OptionButton 12,150,80,8,"Test",.TestReport
       
  1134 
       
  1135 	GroupBox 102,102,116,60,"Usage Verification",.VerifyTypeGroup
       
  1136 	OptionGroup .VerifyType
       
  1137 	OptionButton 106,114,80,8,"None",.NoVerify
       
  1138 	OptionButton 106,126,80,8,"Added Section",.SectionVerify
       
  1139 	OptionButton 106,138,80,8,"Embedded in Text",.EmbedVerify
       
  1140 
       
  1141 	GroupBox 8,170,212,30,"Proofreading Options",.Proofing
       
  1142 	CheckBox 12,182,92,8,"Expanded Whitespace",.WhiteBlock
       
  1143 	CheckBox 106,182,92,8,"Highlight Gaps",.HighlightDocGaps
       
  1144 
       
  1145 	GroupBox 8,205,212,80,"Content Options",.Content
       
  1146 	CheckBox 12,220,92,8,"Class Diagrams",.ClassDiagrams
       
  1147 	CheckBox 12,232,92,8,"Scenario Diagrams",.ScenarioDiagrams
       
  1148 	CheckBox 12,244,92,8,"State Diagrams",.StateDiagrams
       
  1149 	CheckBox 12,256,92,8,"Use Case Diagrams",.UseCaseDiagrams
       
  1150 	CheckBox 12,268,92,8,"C++ Syntax",.CppSyntax
       
  1151 
       
  1152 	CheckBox 106,220,92,8,"Public Items Only",.PublicOnly
       
  1153 	CheckBox 106,232,92,8,"Front-end Boilerplate",.FEBoiler
       
  1154 	CheckBox 106,244,92,8,"Back-end Boilerplate",.BEBoiler
       
  1155 	CheckBox 106,256,92,8,"Use <h>Subhead</h>",.SubTag
       
  1156 
       
  1157 	PushButton 8,292,76,14,"&Generate",.Generate
       
  1158 	CancelButton 144,292,76,14
       
  1159 End Dialog
       
  1160 
       
  1161 
       
  1162 Sub Main
       
  1163     Dim MyDialog As ReportDialog
       
  1164     
       
  1165     Set LicensedRoseApplication = GetLicensedRoseApplication()
       
  1166     LicensedRoseApplication.CurrentModel.DefaultTool = DefaultTool$
       
  1167     'NewDirectory$ = EnclosingDirPath(LicensedRoseApplication.ApplicationPath)
       
  1168     NewDirectory$ = CurDir$
       
  1169     
       
  1170     If NewDirectory$ <> "" Then
       
  1171         If Mid$(NewDirectory$, 2, 1) = ":" Then
       
  1172             ChDrive NewDirectory$
       
  1173         End If
       
  1174         ChDir NewDirectory$
       
  1175     Else
       
  1176         MsgBox "Error: Directory not found."
       
  1177         Exit Sub
       
  1178     End If
       
  1179     
       
  1180 	'
       
  1181 	' Right, let's set some sensible default values
       
  1182 	'
       
  1183     DefaultFileName$ = GetResourceString(PRODUCTDEFAULTWORDDOCFILENAME)
       
  1184     ModelName$ = LicensedRoseApplication.CurrentModel.GetFileName()
       
  1185     If ModelName$ = "" Then
       
  1186         MyDialog.FileName$ = MakeFileName$(NewDirectory$, DefaultFileName$)
       
  1187         MyDialog.Title$ = FileParse$(DefaultFileName, 4)
       
  1188     Else
       
  1189         MyDialog.FileName$ = ChangeFileExtension$(ModelName$, "doc")
       
  1190         MyDialog.Title$ = FileParse$(ModelName$, 4)
       
  1191     End If
       
  1192 	MyDialog.TemplateFileName$ = ChangeFileExtension$(ModelName$, "dot")
       
  1193     '
       
  1194 	' Let's assume we're not proofreading at the moment
       
  1195 	'
       
  1196     MyDialog.WhiteBlock = False
       
  1197     MyDialog.HighlightDocGaps = False
       
  1198 	'
       
  1199 	' I think we want all the diagrams we can get
       
  1200 	'
       
  1201     MyDialog.ClassDiagrams = True
       
  1202     MyDialog.ScenarioDiagrams = True
       
  1203     MyDialog.StateDiagrams = True
       
  1204     MyDialog.UseCaseDiagrams = True
       
  1205 	'
       
  1206 	' We are a C++ shop, after all
       
  1207 	'
       
  1208     MyDialog.CppSyntax = True
       
  1209 	'
       
  1210 	' We can see everything for now
       
  1211 	'
       
  1212     MyDialog.PublicOnly = False
       
  1213 	'
       
  1214 	' The options to generate boilerplate and tagged headings are turned off
       
  1215 	'
       
  1216 	MyDialog.FEBoiler = False
       
  1217 	MyDialog.BEBoiler = False
       
  1218 	MyDialog.SubTag = False
       
  1219 	'
       
  1220 	' Let's assume that we want to run across the entire model for the time being
       
  1221 	'
       
  1222     MyDialog.ReportType = RepAnalysisNDesignType
       
  1223 	'
       
  1224 	' The default is to verify in the body of the document
       
  1225 	'
       
  1226     MyDialog.VerifyType = RepVerifyEmbed
       
  1227 
       
  1228     '
       
  1229 	' Right let's give the user a chance to set some preferences, in case
       
  1230 	' they differ from these eminently sensible ones.
       
  1231 	'
       
  1232     Result = Dialog (MyDialog)
       
  1233     If Result = 0 Then 
       
  1234         Exit Sub
       
  1235     End If
       
  1236 	' 
       
  1237 	' I suppose that if we give them the UI to change them, we ought to actually
       
  1238 	' take notice of them
       
  1239 	'
       
  1240     If Result = 2 Then
       
  1241         ReportOptions.Generate = TRUE
       
  1242         ReportOptions.Title = MyDialog.Title
       
  1243         ReportOptions.FileName = MyDialog.FileName
       
  1244 		ReportOptions.Template = MyDialog.TemplateFileName
       
  1245         ReportOptions.WhiteBlock = MyDialog.WhiteBlock
       
  1246         ReportOptions.HighlightDocGaps = MyDialog.HighlightDocGaps
       
  1247         ReportOptions.ClassDiagrams = MyDialog.ClassDiagrams
       
  1248         ReportOptions.ScenarioDiagrams = MyDialog.ScenarioDiagrams
       
  1249         ReportOptions.StateDiagrams = MyDialog.StateDiagrams
       
  1250         ReportOptions.UseCaseDiagrams = MyDialog.UseCaseDiagrams
       
  1251         ReportOptions.CppSyntax = MyDialog.CppSyntax
       
  1252         ReportOptions.PublicOnly = MyDialog.PublicOnly
       
  1253 		ReportOptions.FEBoiler = MyDialog.FEBoiler
       
  1254 		ReportOptions.BEBoiler = MyDialog.BEBoiler
       
  1255 		ReportOptions.SupportSubheadingTags = MyDialog.SubTag
       
  1256         
       
  1257         ReportOptions.DocType = MyDialog.ReportType
       
  1258         ReportOptions.VerifyType = MyDialog.VerifyType
       
  1259         
       
  1260         GeneratorState.Phase = RPh_StartUp
       
  1261         RoseAppDirectory$ = EnclosingDirPath(LicensedRoseApplication.ApplicationPath)
       
  1262 		If Not FileExists (ReportOptions.Template) Then
       
  1263         	ReportOptions.Template = RoseAppDirectory$ &"\Formal.dot"
       
  1264         	If Not FileExists (ReportOptions.Template) Then
       
  1265             	MsgBox "Error: Missing file [" & ReportOptions.Template & "]"
       
  1266             	Exit Sub
       
  1267         	End If
       
  1268 		End If
       
  1269     End If
       
  1270     
       
  1271 	'
       
  1272 	' Crack open MS Word then
       
  1273 	'
       
  1274     Dim WordApplication As Object
       
  1275     Dim WordApp As Object
       
  1276     WordUtilInit
       
  1277     
       
  1278     Set WordApplication = CreateObject("Word.Application")
       
  1279     
       
  1280 	'
       
  1281 	' This is a very lazy thing to do, and difficult to obtain 
       
  1282 	' documentation on now that Micro$oft have deprecated the interface
       
  1283 	'
       
  1284     Set WordApp = WordApplication.WordBasic
       
  1285     ' 
       
  1286 	' But it makes some parts of life so easy
       
  1287 	'
       
  1288     WordApp.AppMaximize
       
  1289    	'
       
  1290 	' Create a new document based on our template
       
  1291 	'
       
  1292     WordApp.FileNew ReportOptions.Template
       
  1293     '
       
  1294 	' Rush to the end of the new document
       
  1295 	'
       
  1296     WordApp.EndOfDocument
       
  1297     '
       
  1298 	' Generate the filling
       
  1299 	'
       
  1300     GenerateReport(WordApp)
       
  1301     '
       
  1302 	' Finalise the Table of Contents
       
  1303 	'
       
  1304     WordApp.EditSelectAll
       
  1305     WordApp.UpdateFields
       
  1306 	'
       
  1307 	' Save it all away
       
  1308 	'
       
  1309     WordApp.FileSaveAs ReportOptions.FileName
       
  1310     '
       
  1311 	' Night night
       
  1312 	'   
       
  1313     WordApp.FileExit
       
  1314     
       
  1315 End Sub