Concept-Subjects/src/ShapeCreator.cls

130 lines
4.0 KiB
OpenEdge ABL
Raw Normal View History

2024-06-07 20:13:55 +03:00
VERSION 1.0 CLASS
BEGIN
MultiUse = -1 'True
END
Attribute VB_Name = "ShapeCreator"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = False
Attribute VB_Exposed = False
Option Explicit
Private problemIndex_ As Long
Private frontIndex_ As Long
Private data_ As CDS_StaticHierarchy
Private storage_ As API_ShapeStorage
Private destination_ As Visio.Page
Public Function Init(iData As CDS_StaticHierarchy, iDestination As Visio.Page)
problemIndex_ = 0
frontIndex_ = 0
Set data_ = iData
Set destination_ = iDestination
Set storage_ = New API_ShapeStorage
Call storage_.Init(0, iDestination.PageSheet.Cells("PageHeight"))
End Function
Public Function CreateAllShapes() As API_ShapeStorage
Dim iNode As CDS_NodeSH
For Each iNode In data_.nodes_
If iNode.rank_ = 1 Then _
Call CreateRecursive(iNode)
Next iNode
Set CreateAllShapes = storage_
End Function
' ========
Private Function CreateRecursive(target As CDS_NodeSH)
Call CreateItemShape(target)
Call storage_.Store(target.data_.shape_)
Call CSE_ProgressBar.IncrementA
If target.children_.Count = 0 Then _
Exit Function
Dim iChild As CDS_NodeSH
Dim iChildren As Collection: Set iChildren = OrderChildren(target)
For Each iChild In iChildren
Call CreateRecursive(iChild)
Next iChild
End Function
Private Function CreateItemShape(ByRef target As CDS_NodeSH)
Dim iShape As Visio.Shape: Set iShape = destination_.Drop(GetMasterFor(target.data_.type_), 0, 0)
Set target.data_.shape_ = iShape
iShape.Text = target.data_.text_
If target.data_.type_ = T_ITEM_PROBLEM Then
Call AddProblemPrefix(target, iShape)
iShape.Shapes(2).CellsU("Width") = iShape.Shapes(2).CellsU("Width")
ElseIf target.data_.type_ = T_ITEM_FRONT Then
Call AddFrontPrefix(target, iShape)
iShape.Shapes(2).CellsU("Width") = iShape.Shapes(2).CellsU("Width")
Else
Call CellsSetValue(iShape, CELLSU_POSTYPE, target.data_.position_)
iShape.CellsU("Width") = iShape.CellsU("Width")
End If
End Function
Private Function AddProblemPrefix(iNode As CDS_NodeSH, ByRef iShape As Visio.Shape)
problemIndex_ = problemIndex_ + 1
Dim sPrefix$: sPrefix = Fmt("{1} {2}. ", PROBLEM_PREFIX, problemIndex_)
iShape.Text = sPrefix & iShape.Text
Dim cCursor As Visio.Characters: Set cCursor = iShape.Shapes(2).Characters
cCursor.Begin = 0
cCursor.End = VBA.Len(sPrefix)
cCursor.CharProps(visCharacterStyle) = visBold
End Function
Private Function AddFrontPrefix(iNode As CDS_NodeSH, ByRef iShape As Visio.Shape)
frontIndex_ = frontIndex_ + 1
Dim sPrefix$: sPrefix = Fmt("{1} {2}. ", FRONT_PREFIX, frontIndex_)
iShape.Text = sPrefix & iShape.Text
Dim cCursor As Visio.Characters: Set cCursor = iShape.Shapes(2).Characters
cCursor.Begin = 0
cCursor.End = VBA.Len(sPrefix)
cCursor.CharProps(visCharacterStyle) = visBold
End Function
Private Function OrderChildren(ByRef target As CDS_NodeSH) As Collection
If target.data_.type_ = T_ITEM_FRONT Then _
Set target.children_ = OrderByDescendants(target.children_) ' Note: Modifying graph!!
Set OrderChildren = target.children_
End Function
Private Function OrderByDescendants(iInput As Collection) As Collection
Dim iDescCounts As New Scripting.Dictionary
Dim iOut As New Collection
Dim iNode As CDS_NodeSH
Dim nDescendants&
Dim nIndex&
Dim aKey As Variant
For Each iNode In iInput
nDescendants = iNode.descendantsCount_
If iDescCounts.Count = 0 Then
Call iOut.Add(iNode, CStr(iNode.id_))
Call iDescCounts.Add(iNode.id_, nDescendants)
Else
nIndex = 1
For Each aKey In iDescCounts
If iDescCounts(aKey) <= nDescendants Then _
nIndex = nIndex + 1
Next aKey
Call iDescCounts.Add(iNode.id_, nDescendants)
If nIndex > iOut.Count Then
Call iOut.Add(iNode, CStr(iNode.id_))
Else
Call iOut.Add(iNode, CStr(iNode.id_), Before:=nIndex)
End If
End If
Next iNode
Set OrderByDescendants = iOut
End Function