From 306e18c4f8f426ca3f94e2e93002d8c41905fdd0 Mon Sep 17 00:00:00 2001 From: IRBorisov <8611739+IRBorisov@users.noreply.github.com> Date: Fri, 7 Jun 2024 20:06:17 +0300 Subject: [PATCH] Initial commit --- VBAMake.txt | 38 +++ VERSION | 1 + distr/!Readme.docx | Bin 0 -> 18812 bytes distr/Пример входных данных.xlsx | Bin 0 -> 26405 bytes script/manifest.txt | 93 +++++++ skeleton/Иерархизатор.vsdm | Bin 0 -> 68178 bytes src/DataAccess.bas | 97 +++++++ src/Declarations.bas | 42 +++ src/DevHelper.bas | 21 ++ src/LayoutConstruction.cls | 201 ++++++++++++++ src/Main.bas | 278 +++++++++++++++++++ src/MainImpl.bas | 446 +++++++++++++++++++++++++++++++ src/MasterDlg.frm | 123 +++++++++ src/MasterDlg.frx | Bin 0 -> 5656 bytes src/ThisDocument.cls | 22 ++ src/VisioNode.cls | 20 ++ src/z_UIMessages.bas | 94 +++++++ src/z_UIRibbon.bas | 20 ++ ui/.rels | 2 + ui/customUI1.xml | 90 +++++++ 20 files changed, 1588 insertions(+) create mode 100644 VBAMake.txt create mode 100644 VERSION create mode 100644 distr/!Readme.docx create mode 100644 distr/Пример входных данных.xlsx create mode 100644 script/manifest.txt create mode 100644 skeleton/Иерархизатор.vsdm create mode 100644 src/DataAccess.bas create mode 100644 src/Declarations.bas create mode 100644 src/DevHelper.bas create mode 100644 src/LayoutConstruction.cls create mode 100644 src/Main.bas create mode 100644 src/MainImpl.bas create mode 100644 src/MasterDlg.frm create mode 100644 src/MasterDlg.frx create mode 100644 src/ThisDocument.cls create mode 100644 src/VisioNode.cls create mode 100644 src/z_UIMessages.bas create mode 100644 src/z_UIRibbon.bas create mode 100644 ui/.rels create mode 100644 ui/customUI1.xml diff --git a/VBAMake.txt b/VBAMake.txt new file mode 100644 index 0000000..88eecae --- /dev/null +++ b/VBAMake.txt @@ -0,0 +1,38 @@ +# == Properties Section == +# configuration properties +# use .ini format to define properties +# mandatory properties: name, artifact_home, source_home + +id = Concept-Hierarchy +name = Концепт-Иерархия +description = Технология визуализации и преобразования формы представления иерархий +artifact_home = Концепт-Иерархия +source_home = Concept-Hierarchy +install_home = \\fs1.concept.ru\projects\10 Автоматизация деятельности\01 Высокие технологии\Концепт-Иерархия + +%% +# === Build section === +# Available commands: +# build LOCAL_MANIFEST +# copy LOCAL_SOURCE -> [LOCAL_ARTIFACT] +# save_as LOCAL_ARTIFACT -> LOCAL_ARTIFACT +# run LOCAL_SOURCE.bat + +build script\manifest.txt +save_as Иерархизатор.vsdm -> 30 Иерархизатор.vstm +copy distr\!Readme.docx +copy distr\Пример входных данных.xlsx + +%% +# === Install section == +# Available commands: +# install LOCAL_ARTIFACT -> [INSTALL_PATH] +# add_template LOCAL_ARTIFACT -> [LOCAL_TEMPLATE] +# run LOCAL_ARTIFACT.bat <- [PARAMETERS] +# run APPLICATION <- [PARAMETERS] + +install Иерархизатор.vsdm +install !Readme.docx +install Пример входных данных.xlsx + +add_template 30 Иерархизатор.vstm \ No newline at end of file diff --git a/VERSION b/VERSION new file mode 100644 index 0000000..26aaba0 --- /dev/null +++ b/VERSION @@ -0,0 +1 @@ +1.2.0 diff --git a/distr/!Readme.docx b/distr/!Readme.docx new file mode 100644 index 0000000000000000000000000000000000000000..763ff4cc2c081e676d53d879013ed354831e75a7 GIT binary patch literal 18812 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 E4 " delimiter +# First component is a path relative to SourceHome\ui folders +# Second component is internal path inside project file + +.rels -> _rels\.rels +customUI1.xml -> visio\customUI\customUI1.xml + +%% +# === References Section === +# List dependencies in one of the formats +# global : GLOBAL_NAME +# guid : {REGISTERED_GUID} +# file : PATH_TO_LIBRARY + +global : MSForms +global : Shell32 +global : Scripting +global : Excel +global : Word \ No newline at end of file diff --git a/skeleton/Иерархизатор.vsdm b/skeleton/Иерархизатор.vsdm new file mode 100644 index 0000000000000000000000000000000000000000..f2843dea66301f58d02bc3f833ab64c73d8e91d0 GIT binary patch literal 68178 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 z�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

H73PI4|ll!mBcr0#H58fxe)|^;=*K_{I6F zbA7Rh{oJCZ2|yj|8_;Ni_8R~IKnnbYa51wsvT<>EsiwuVvf?E5Kyt$X(5Ux&&%kN=eZyJh>kG#Tj0lD{JV*G%-EwE+eF T$7w{Mk2T2P7zG23LV*7Vf)GBA literal 0 HcmV?d00001 diff --git a/src/DataAccess.bas b/src/DataAccess.bas new file mode 100644 index 0000000..a976024 --- /dev/null +++ b/src/DataAccess.bas @@ -0,0 +1,97 @@ +Attribute VB_Name = "DataAccess" +Option Explicit + +Public Function MainPage() As Visio.Page + Set MainPage = Application.ActiveDocument.Pages(1) +End Function + +Public Function GetRankMaster(nRank&) As Visio.Master + Dim iMaster As Visio.Master: Set iMaster = FindMaster(ThisDocument, MASTER_RANK & nRank) + If iMaster Is Nothing Then + Set GetRankMaster = GetRankMaster(nRank - 1) + Else + Set GetRankMaster = iMaster + End If +End Function + +Public Function GetConnectionMaster(nMode As TLayout) As Visio.Master + Select Case nMode + Case T_LAYOUT_HORIZONTAL: Set GetConnectionMaster = FindMaster(ThisDocument, MASTER_CONNECT_HOR) + Case T_LAYOUT_VERTICAL: Set GetConnectionMaster = FindMaster(ThisDocument, MASTER_CONNECT_VERT) + Case T_LAYOUT_COLUMN_LEFT: Set GetConnectionMaster = FindMaster(ThisDocument, MASTER_CONNECT_HOR) + Case T_LAYOUT_COLUMN_RIGHT: Set GetConnectionMaster = FindMaster(ThisDocument, MASTER_CONNECT_HOR) + Case Else: Set GetConnectionMaster = FindMaster(ThisDocument, MASTER_CONNECT_VERT) + End Select +End Function + +Public Function GetRankWidth(nRank&) As Double + GetRankWidth = GetRankMaster(nRank).Shapes(1).CellsU("Width") +End Function + +Public Function GetRanksBaseY() As Scripting.Dictionary + Dim iBases As New Scripting.Dictionary + Dim nRank& + Dim baseY As Double: baseY = 0 + For nRank = 1 To TREE_MAX_RANK Step 1 + Dim iPrototype As Visio.Shape: Set iPrototype = GetRankMaster(nRank).Shapes(1) + If Not iPrototype Is Nothing Then + iBases(nRank) = baseY - iPrototype.CellsU("Height") / 2# + baseY = baseY - iPrototype.CellsU("Height") - GAP_RANK + End If + Next nRank + Set GetRanksBaseY = iBases +End Function + +Public Function GetChildrenOf(target As Visio.Shape) As Collection + Set GetChildrenOf = New Collection + Dim cnt As Visio.Connect + For Each cnt In target.FromConnects + Dim connector As Visio.Shape: Set connector = cnt.FromSheet + If connector.Connects(1).ToSheet Is target And connector.Connects.Count = 2 Then _ + Call GetChildrenOf.Add(connector.Connects(2).ToSheet) + Next cnt +End Function + +Public Function ExrtactXLPayload(iSource As Excel.Worksheet, nRow&) As VisioNode + Dim iPayload As New VisioNode + iPayload.text_ = iSource.Cells(nRow, 2) + If iSource.Cells(nRow, 1).Interior.ColorIndex <> -4142 Then _ + iPayload.color_ = iSource.Cells(nRow, 1).Interior.Color + Set ExrtactXLPayload = iPayload +End Function + +Public Function ExtractWordPayload(iSource As Word.Range) As VisioNode + Dim sText$: sText = TrimWhitespace(iSource.Text) + If sText = vbNullString Then _ + Exit Function + + Dim nColor&: nColor = iSource.Shading.BackgroundPatternColor + nColor = IIf(nColor = wdColorAutomatic, COLOR_DEFAULT, ColorGetRGB(iSource.Font.Shading.BackgroundPatternColor, iSource.Document)) + + Dim iPayload As New VisioNode + iPayload.text_ = sText + iPayload.color_ = nColor + Set ExtractWordPayload = iPayload +End Function + +Public Function ExtractVsoPayload(target As Visio.Shape) As VisioNode + Dim iPayload As New VisioNode + iPayload.text_ = target.Text + iPayload.color_ = ConvertStringToRGB(target.CellsU("FillForegnd").ResultStrU("")) + Set iPayload.shape_ = target + Set ExtractVsoPayload = iPayload +End Function + +Public Function WordStyleForRank(wordDoc As Word.Document, nRank As Integer) As String + WordStyleForRank = "" + If nRank < 1 Or nRank > WORD_HEADING_MAX_LEVEL Then _ + Exit Function + + Dim sStyle$: sStyle = " " & nRank & " " + If WordStyleExists(wordDoc, sStyle) Then + WordStyleForRank = sStyle + Else + WordStyleForRank = " " & nRank + End If +End Function + diff --git a/src/Declarations.bas b/src/Declarations.bas new file mode 100644 index 0000000..da5623a --- /dev/null +++ b/src/Declarations.bas @@ -0,0 +1,42 @@ +Attribute VB_Name = "Declarations" +Option Explicit + +Public Const TREE_MAX_RANK As Integer = 30 + +Public Const COLOR_DEFAULT = -1 + +Public Const FLOAT_ACCURACY As Double = 0.001 + +Public Const GAP_VERTICAL = 5# / 25.4 +Public Const GAP_HORIZONTAL = 5# / 25.4 +Public Const GAP_VERT_ADJUSTMENT_TO_HOR = 10# / 25.4 +Public Const GAP_RANK = 10# / 25.4 + +Public Const MASTER_CONNECT_HOR = " " +Public Const MASTER_CONNECT_VERT = " " +Public Const MASTER_RANK = "" + +Public Const SHAPE_RANK_MASTER = "#Lvl" + +Public Const PREFIX_NODE = "#N" +Public Const PREFIX_CONNECTOR = "#C" + +' Layout modes +Public Enum TLayout + T_LAYOUT_VERTICAL ' y-based + T_LAYOUT_HORIZONTAL ' x-based + T_LAYOUT_RADIAL ' distance based + T_LAYOUT_COLUMN_RIGHT ' right column + T_LAYOUT_COLUMN_LEFT ' left column +End Enum + +' Input / output modes for conversion +Public Enum IOMode + MODE_EXCEL + MODE_WORD + MODE_VISIO +End Enum + +' ========== Word declarations ========== +Public Const WORD_HEADING_MAX_LEVEL = 9 +Public Const EXPORT_TEMPLATE_PATH = "\Microsoft\\01 .dotx" diff --git a/src/DevHelper.bas b/src/DevHelper.bas new file mode 100644 index 0000000..d5b4a6e --- /dev/null +++ b/src/DevHelper.bas @@ -0,0 +1,21 @@ +Attribute VB_Name = "DevHelper" +Option Private Module +Option Explicit + +Public Function Dev_PrepareSkeleton() + ' Do nothing +End Function + +Public Function Dev_ManualRunTest() + Dim sSuite$: sSuite = "s_UndoWrapper" + Dim sTest$: sTest = "t_BasicUndo" + Dim sMsg$: sMsg = Dev_RunTest(sSuite, sTest) + Debug.Print sMsg + Call MsgBox(sMsg) +End Function + +Public Function Dev_GetTestSuite(sName$) As Object + Select Case sName +' Case "s_UndoWrapper": Set Dev_GetTestSuite = New s_UndoWrapper + End Select +End Function diff --git a/src/LayoutConstruction.cls b/src/LayoutConstruction.cls new file mode 100644 index 0000000..458cf1a --- /dev/null +++ b/src/LayoutConstruction.cls @@ -0,0 +1,201 @@ +VERSION 1.0 CLASS +BEGIN + MultiUse = -1 'True +END +Attribute VB_Name = "LayoutConstruction" +Attribute VB_GlobalNameSpace = False +Attribute VB_Creatable = False +Attribute VB_PredeclaredId = False +Attribute VB_Exposed = False +Option Explicit + +Private page_ As Visio.Page +Private data_ As CDS_StaticHierarchy +Private autoVertical_ As Boolean + +Private width_ As Scripting.Dictionary + +Private Const SIZING_FACTOR_LIMIT = 1.3 + +Public Function Init(iPage As Visio.Page, ByRef iData As CDS_StaticHierarchy, bAutoVertical As Boolean) + Set page_ = iPage + Set data_ = iData + autoVertical_ = bAutoVertical +End Function + +Public Function ConstructHNodes() + Dim ranksLast As New Scripting.Dictionary + Dim ranksY As Scripting.Dictionary: Set ranksY = GetRanksBaseY + Dim lastInsert As Visio.Shape + + Dim iNode As CDS_NodeSH + Dim iParent As Visio.Shape + For Each iNode In data_.nodes_ + Dim nRank&: nRank = iNode.rank_ + Dim nLayout As TLayout: nLayout = GetLayoutFor(iNode.parent_) + Dim iNewShape As Visio.Shape: Set iNewShape = CreateNodeShape(iNode) + Set iNode.data_.shape_ = iNewShape + + If iNode.parent_ Is Nothing Then + Set iParent = Nothing + Else + Set iParent = iNode.parent_.data_.shape_ + End If + + If nLayout = T_LAYOUT_HORIZONTAL Then + If Not ranksLast.Exists(nRank) Then + iNewShape.CellsU("PinY") = ranksY(nRank) - iNewShape.CellsU("Height") / 2# + Else + Call MoveShapeAfterHorizontal(iNewShape, ranksLast(nRank)) + End If + Set ranksLast(nRank) = iNewShape + Set lastInsert = Nothing + Else + If lastInsert Is Nothing Then + Call MoveShapeAfterVertical(iNewShape, iParent, GAP_RANK) + Else + Call MoveShapeAfterVertical(iNewShape, lastInsert, GAP_VERTICAL) + End If + Set lastInsert = iNewShape + End If + + If iNode.children_.Count = 0 Then _ + Call TryOptimizeHeight(iNewShape, iNode.rank_, nLayout) + + If Not iParent Is Nothing Then _ + Call ConnectNodes(iParent, iNewShape, nLayout) + + Call CSE_ProgressBar.IncrementA + Next iNode +End Function + +Public Function CalculateWidth() + Set width_ = New Scripting.Dictionary + Call GetWidthFor(data_.nodes_(1)) +End Function + +Public Function RepositionAll() + Call SetPositionFor(data_.nodes_(1), dBaseX:=0) +End Function + +' ============== +Private Function GetWidthFor(iNode As CDS_NodeSH) As Double + If width_.Exists(iNode.id_) Then + GetWidthFor = width_(iNode.id_) + Else + width_(iNode.id_) = CalculateWidthFor(iNode) + GetWidthFor = width_(iNode.id_) + End If +End Function + +Private Function CalculateWidthFor(iNode As CDS_NodeSH) As Double + Dim dChildWidth As Double + Dim iChild As CDS_NodeSH + Dim dNodeWidth As Double: dNodeWidth = iNode.data_.shape_.CellsU("Width") + If iNode.children_.Count = 0 Then + CalculateWidthFor = dNodeWidth + ElseIf GetLayoutFor(iNode) = T_LAYOUT_VERTICAL Then + dNodeWidth = dNodeWidth + For Each iChild In iNode.children_ + dChildWidth = GetWidthFor(iChild) + If dNodeWidth < dChildWidth Then _ + dNodeWidth = dChildWidth + Next iChild + CalculateWidthFor = dNodeWidth + GAP_VERT_ADJUSTMENT_TO_HOR + Else + Dim dAccumulated As Double: dAccumulated = -GAP_HORIZONTAL + For Each iChild In iNode.children_ + dAccumulated = dAccumulated + GAP_HORIZONTAL + GetWidthFor(iChild) + Next iChild + + Dim dRankWidth As Double: dRankWidth = GetRankWidth(iNode.rank_) + If dAccumulated < dRankWidth Then _ + dAccumulated = dRankWidth + If dAccumulated < dNodeWidth Then _ + dAccumulated = dNodeWidth + CalculateWidthFor = dAccumulated + End If +End Function + +Private Function SetPositionFor(iNode As CDS_NodeSH, dBaseX As Double) + Dim iTarget As Visio.Shape: Set iTarget = iNode.data_.shape_ + Dim dNodeWidth As Double: dNodeWidth = width_(iNode.id_) + Dim iChild As CDS_NodeSH + + Call CSE_ProgressBar.IncrementA + If iNode.children_.Count = 0 Then + iTarget.CellsU("PinX") = dBaseX + dNodeWidth / 2# + ElseIf GetLayoutFor(iNode) = T_LAYOUT_VERTICAL Then + iTarget.CellsU("PinX") = dBaseX + iTarget.CellsU("Width") / 2# + GAP_VERT_ADJUSTMENT_TO_HOR + For Each iChild In iNode.children_ + iChild.data_.shape_.CellsU("PinX") = dBaseX + iChild.data_.shape_.CellsU("Width") / 2# + GAP_VERT_ADJUSTMENT_TO_HOR + Next iChild + Call CSE_ProgressBar.IncrementA(iNode.children_.Count) + Else ' Horizontal + Dim newX As Double: newX = dBaseX + If iNode.children_.Count = 1 And dNodeWidth > width_(iNode.children_(1).id_) Then _ + newX = dBaseX + dNodeWidth / 2# - width_(iNode.children_(1).id_) / 2# + For Each iChild In iNode.children_ + Call SetPositionFor(iChild, newX) + newX = newX + width_(iChild.id_) + GAP_HORIZONTAL + Next iChild + iTarget.CellsU("PinX") = iNode.children_(1).data_.shape_.CellsU("PinX") / 2# _ + + iNode.children_(iNode.children_.Count).data_.shape_.CellsU("PinX") / 2# + End If +End Function + +Private Function MoveShapeAfterVertical(sh1 As Visio.Shape, sh2 As Visio.Shape, dGap As Double) + Dim dPinx As Double: dPinx = sh2.CellsU("PinX") - sh1.CellsU("Width") / 2# + sh2.CellsU("Width") / 2# + Dim dPiny As Double: dPiny = sh2.CellsU("PinY") - dGap - sh2.CellsU("Height") / 2# - sh1.CellsU("Height") / 2# + Call sh1.SetCenter(dPinx, dPiny) +End Function + +Private Function MoveShapeAfterHorizontal(sh1 As Visio.Shape, sh2 As Visio.Shape) + Dim dPinx As Double: dPinx = sh2.CellsU("PinX") + GAP_HORIZONTAL + sh2.CellsU("Width") / 2# + sh1.CellsU("Width") / 2# + Dim dPiny As Double: dPiny = sh2.CellsU("PinY") + sh2.CellsU("Height") / 2# - sh1.CellsU("Height") / 2# + Call sh1.SetCenter(dPinx, dPiny) +End Function + +Private Function GetLayoutFor(iNode As CDS_NodeSH) As TLayout + If iNode Is Nothing Then + GetLayoutFor = T_LAYOUT_HORIZONTAL + ElseIf iNode.parent_ Is Nothing Then + GetLayoutFor = T_LAYOUT_HORIZONTAL + ElseIf iNode.children_.Count <= 1 Then + GetLayoutFor = T_LAYOUT_HORIZONTAL + ElseIf Not autoVertical_ And iNode.rank_ + 1 <> data_.MaxDepth Then + GetLayoutFor = T_LAYOUT_HORIZONTAL + ElseIf iNode.descendantsCount_ = iNode.children_.Count Then + GetLayoutFor = T_LAYOUT_VERTICAL + Else + GetLayoutFor = T_LAYOUT_HORIZONTAL + End If +End Function + +Private Function CreateNodeShape(ByRef iNode As CDS_NodeSH) As Visio.Shape + Dim iShape As Visio.Shape: Set iShape = page_.Drop(GetRankMaster(iNode.rank_), 0, 0) + With iShape + .Text = iNode.data_.text_ + .Name = PREFIX_NODE & iNode.id_ + .CellsSRC(visSectionObject, visRowLock, visLockDelete).FormulaU = "0" + If iNode.data_.color_ <> COLOR_DEFAULT Then _ + .CellsSRC(visSectionObject, visRowFill, visFillForegnd).FormulaU = ConvertRGBtoString(iNode.data_.color_) + End With + Set CreateNodeShape = iShape +End Function + +Private Function TryOptimizeHeight(iShape As Visio.Shape, nRank&, nLayout As TLayout) + Dim dGap As Double: dGap = IIf(nLayout = T_LAYOUT_HORIZONTAL, GAP_RANK, GAP_VERTICAL) + Dim iPrototype As Visio.Master: Set iPrototype = GetRankMaster(nRank) + Dim kFactor As Double: kFactor = VBA.Sqr(iShape.CellsU("Width") / iPrototype.Shapes(1).CellsU("Width")) + If kFactor < SIZING_FACTOR_LIMIT Then _ + Exit Function + + Dim dLeft As Double: dLeft = iShape.CellsU("PinX") - iShape.CellsU("Width") / 2# + Dim dTop As Double: dTop = iShape.CellsU("PinY") + iShape.CellsU("Height") / 2# + kFactor = VBA.Int(kFactor) + 1 + iShape.CellsU("Height") = iPrototype.Shapes(1).CellsU("Height") * kFactor + dGap * (kFactor - 1) + iShape.CellsU("PinY") = dTop - iShape.CellsU("Height") / 2# + If nLayout = T_LAYOUT_HORIZONTAL Then _ + iShape.CellsU("PinX") = dLeft + iShape.CellsU("Width") / 2# +End Function diff --git a/src/Main.bas b/src/Main.bas new file mode 100644 index 0000000..f9df025 --- /dev/null +++ b/src/Main.bas @@ -0,0 +1,278 @@ +Attribute VB_Name = "Main" +Option Explicit + +Public Const PRODUCT_VERSION = "1.2.0" +Public Const PRODUCT_NAME = "Concept-Hierarchy" + +Public g_VersionTimer As Long + +Public Sub StartVersionCheck() + g_VersionTimer = SetTimer(0, 0, CP_VERSION_MSG_DELAY, AddressOf OnVersionCheck) +End Sub + +Public Function OnVersionCheck(ByVal nHwnd As Long, ByVal uMsg As Long, ByVal nEvent As Long, ByVal nTime As Long) + Call KillTimer(0, g_VersionTimer) + Call VersionValidate(PRODUCT_NAME, PRODUCT_VERSION) +End Function + +Public Sub RunGotoLinkBegin() +Attribute RunGotoLinkBegin.VB_ProcData.VB_Invoke_Func = "Q" + Call CC_GotoLinkBegin +End Sub + +Public Sub RunGotoLinkEnd() + Call CC_GotoLinkEnd +End Sub + +Public Sub RunImportWord() + Dim sFile$: sFile = UserInteraction.PromptFileFilter( _ + sInitialPath:=Visio.ActiveDocument.Path, _ + sDescription:=" , ", _ + sFilter:="*.docx;*.doc;*.docm", _ + sTitle:=" Word", _ + bNewApplication:=True) + If sFile = vbNullString Then _ + Exit Sub + Dim iData As CDS_StaticHierarchy: Set iData = ScanHierarchy(sFile, MODE_WORD) + If iData Is Nothing Then _ + Exit Sub + + Call OutputHierarchy(iData, MODE_VISIO) +End Sub + +Public Sub RunImportXL() + Dim sFile$: sFile = UserInteraction.PromptFileFilter( _ + sInitialPath:=Visio.ActiveDocument.Path, _ + sDescription:=" , ", _ + sFilter:="*.xlsx;*.xls;*.xlsm", _ + sTitle:=" Excel", _ + bNewApplication:=True) + If sFile = vbNullString Then _ + Exit Sub + Dim iData As CDS_StaticHierarchy: Set iData = ScanHierarchy(sFile, MODE_EXCEL) + If iData Is Nothing Then _ + Exit Sub + + Call OutputHierarchy(iData, MODE_VISIO) +End Sub + +Public Sub RunMaster() + Call MasterDlg.Show + If MasterDlg.bCanceled Then _ + Exit Sub + + Dim iMode As IOMode: iMode = MasterDlg.InputMode + Dim oMode As IOMode: oMode = MasterDlg.OutputMode + Dim iLayout As TLayout: iLayout = MasterDlg.InputLayout + Dim sFileName$: sFileName = MasterDlg.InputFile + + If iMode <> MODE_VISIO And sFileName = vbNullString Then + Call UserInteraction.ShowMessage(EM_FILENAME_EMPTY) + Exit Sub + End If + + Dim iData As CDS_StaticHierarchy: Set iData = ScanHierarchy(sFileName, iMode, iLayout) + If iData Is Nothing Then _ + Exit Sub + + Call OutputHierarchy(iData, MasterDlg.OutputMode) +End Sub + +Public Sub RunClearScheme() +Attribute RunClearScheme.VB_Description = " " +Attribute RunClearScheme.VB_ProcData.VB_Invoke_Func = "X" + Call GlobalUndo.BeginScope(" ") + + Call ClearGeneratedShapes(MainPage) + Call VsoShowWholePage(MainPage) + + Call GlobalUndo.EndScope +End Sub + +Public Sub RunRename() +Attribute RunRename.VB_Description = "" + Dim sel As Visio.Selection: Set sel = Visio.Application.ActiveWindow.Selection + If sel.Count <> 1 Then + Call UserInteraction.ShowMessage(EM_INVALID_SELECTION) + Exit Sub + End If + + Call GlobalUndo.BeginScope(" ") + + Call GenerateNamesFor(sel.Item(1)) + + Call GlobalUndo.EndScope +End Sub + +Public Sub RunTransform() +Attribute RunTransform.VB_ProcData.VB_Invoke_Func = "Z" + Dim sel As Visio.Selection: Set sel = Visio.Application.ActiveWindow.Selection + If sel.Count <> 1 Then + Call UserInteraction.ShowMessage(EM_INVALID_SELECTION) + Exit Sub + End If + + Call GlobalUndo.BeginScope(" ") + + Call TransformNodeLayout(sel.Item(1)) + + Call GlobalUndo.EndScope +End Sub + +Public Sub RunConnectColumns() + Dim sel As Visio.Selection: Set sel = Visio.Application.ActiveWindow.Selection + If sel.Count <> 1 Then + Call UserInteraction.ShowMessage(EM_INVALID_SELECTION) + Exit Sub + End If + + Call GlobalUndo.BeginScope(" ") + + Call ConnectColumns(sel.Item(1)) + + Call GlobalUndo.EndScope +End Sub + +Public Sub RunNewRankTemplate() + Dim iMaster As Visio.Master + Set iMaster = AddNewRankTemplate + If Not iMaster Is Nothing Then _ + Call UserInteraction.ShowMessage(IM_NEW_TEMPLATE, iMaster.Name) +End Sub + +' ======= +Private Function ScanHierarchy(sFileName$, iMode As IOMode, Optional nLayout As TLayout = T_LAYOUT_HORIZONTAL) As CDS_StaticHierarchy + Dim iData As CDS_StaticHierarchy + Select Case iMode + Case MODE_EXCEL: Set iData = ProcessExcel(sFileName) + Case MODE_WORD: Set iData = ProcessWord(sFileName) + Case MODE_VISIO: Set iData = ProcessVisio(VsoGetSelectedShapes(ThisDocument.Application), nLayout) + End Select + If iData Is Nothing Then _ + Exit Function + If Not ValidateHierarchy(iData) Then + Call UserInteraction.ShowMessage(EM_INVALID_STRUCTURE) + Exit Function + End If + Set ScanHierarchy = iData +End Function + +Private Function OutputHierarchy(iData As CDS_StaticHierarchy, oMode As IOMode) + Select Case oMode + Case MODE_EXCEL: Call GenerateExcel(iData, Not MasterDlg.XLExportAsTree) + Case MODE_WORD: Call GenerateWord(iData, MasterDlg.WordExportAsString) + Case MODE_VISIO: Call GenerateVisio(MainPage, iData, MasterDlg.AutoLayout) + End Select +End Function + +Private Function ProcessVisio(iShapes As Collection, nLayout As TLayout) As CDS_StaticHierarchy + If iShapes.Count <> 1 Then + Call UserInteraction.ShowMessage(EM_INVALID_SELECTION) + Exit Function + End If + Set ProcessVisio = ScanVisioNode(iShapes(1), nLayout) +End Function + +Private Function ProcessExcel(sFileName$) As CDS_StaticHierarchy + Dim xlApp As New API_XLWrapper + If xlApp.OpenDocument(sFileName, bReadOnly:=True) Is Nothing Then + Call UserInteraction.ShowMessage(EM_ERROR_LOADING_FILE) + Exit Function + End If + + Dim iSource As Excel.Worksheet: Set iSource = xlApp.Document.Worksheets(1) + Call CSE_ProgressBar.Init(" ", maxVal:=iSource.UsedRange.Rows.Count, curVal:=1) + Call CSE_ProgressBar.ShowModeless + + Set ProcessExcel = ScanExcel(iSource) + If ProcessExcel Is Nothing Then _ + Call UserInteraction.ShowMessage(EM_INVALID_FORMAT, xlApp.Document.Name) + + Call Unload(CSE_ProgressBar) + Call xlApp.ReleaseDocument +End Function + +Private Function ProcessWord(sFileName$) As CDS_StaticHierarchy + Dim wordApp As New API_WordWrapper + If wordApp.OpenDocument(sFileName, bReadOnly:=True) Is Nothing Then + Call UserInteraction.ShowMessage(EM_ERROR_LOADING_FILE) + Exit Function + End If + + Call CSE_ProgressBar.Init(" ", maxVal:=wordApp.Document.Paragraphs.Count, curVal:=0) + Call CSE_ProgressBar.ShowModeless + + Set ProcessWord = ScanWord(wordApp.Document) + If ProcessWord Is Nothing Then _ + Call UserInteraction.ShowMessage(EM_INVALID_FORMAT, wordApp.Document.Name) + + Call Unload(CSE_ProgressBar) + Call wordApp.ReleaseDocument +End Function + +Private Function GenerateWord(iData As CDS_StaticHierarchy, bAsString As Boolean) + If Not bAsString And iData.MaxDepth > WORD_HEADING_MAX_LEVEL Then + Call UserInteraction.ShowMessage(EM_WORD_MAX_LEVELS) + Exit Function + End If + + Dim sTemplate$: sTemplate = VBA.Environ("AppData") & EXPORT_TEMPLATE_PATH + Dim wordApp As New API_WordWrapper + Dim iOutput As Word.Document: Set iOutput = wordApp.NewDocument(sTemplate) + Call iOutput.Range.Delete + + Call wordApp.PauseUI + If Not bAsString Then + Call Hierarchy2Word(iData, iOutput) + Else + Call CSE_ProgressBar.Init(" ...", maxVal:=iData.Size, curVal:=1) + Call CSE_ProgressBar.ShowModeless + + Call Hierarchy2WordString(iData, iOutput) + + Call Unload(CSE_ProgressBar) + End If + Call UserInteraction.ShowMessage(IM_EXPORT_OK, iData.Size, iData.MaxDepth) + Call wordApp.ResumeUI +End Function + +Private Function GenerateExcel(iData As CDS_StaticHierarchy, bFlatData As Boolean) + Dim xlApp As New API_XLWrapper + Dim xlOut As Excel.Workbook: Set xlOut = xlApp.NewDocument + + Call xlApp.PauseUI + Call Hierarchy2XL(iData, xlOut.Worksheets(1), bFlatData) + Call UserInteraction.ShowMessage(IM_EXPORT_OK, iData.Size, iData.MaxDepth) + Call xlApp.ResumeUI +End Function + +Private Function GenerateVisio(iPage As Visio.Page, iData As CDS_StaticHierarchy, Optional bAutoVertical As Boolean = True) + Call ClearGeneratedShapes(iPage) + Dim iLayout As New LayoutConstruction: Call iLayout.Init(iPage, iData, bAutoVertical) + + Dim vsoApp As New API_VsoWrapper: Call vsoApp.SetDocument(ThisDocument) + Call vsoApp.PauseUI + Call GlobalUndo.BeginScope(" ") + + Call CSE_ProgressBar.Init(" ", maxVal:=iData.Size, curVal:=1) + Call CSE_ProgressBar.ShowModeless + + Call iLayout.ConstructHNodes + DoEvents + + Call CSE_ProgressBar.Init(" ", maxVal:=iData.Size) + Call iLayout.CalculateWidth + Call iLayout.RepositionAll + + Call Unload(CSE_ProgressBar) + + Call GlobalUndo.EndScope + Call vsoApp.ResumeUI + + Call iPage.ResizeToFitContents + Call VsoShowWholePage(iPage) + + Dim nWidth&: nWidth = iPage.PageSheet.CellsU("PageWidth").Result("mm") + Dim nHeight&: nHeight = iPage.PageSheet.CellsU("PageHeight").Result("mm") + Call UserInteraction.ShowMessage(IM_IMPORT_OK, iData.Size, iData.MaxDepth, nWidth, nHeight) +End Function diff --git a/src/MainImpl.bas b/src/MainImpl.bas new file mode 100644 index 0000000..6e0f348 --- /dev/null +++ b/src/MainImpl.bas @@ -0,0 +1,446 @@ +Attribute VB_Name = "MainImpl" +Option Explicit + +Public Function ClearGeneratedShapes(target As Visio.Page) + Dim nItem&: nItem = 1 + Do While Not nItem > target.Shapes.Count + Dim vsoShape As Shape: Set vsoShape = target.Shapes(nItem) + Dim shpName$: shpName = vsoShape.Name + If Left(shpName, 2) = "#N" Or Left(shpName, 2) = "#C" Then + vsoShape.Delete + nItem = 1 + Else + nItem = nItem + 1 + End If + Loop + Call target.ResizeToFitContents +End Function + +Public Function ValidateHierarchy(target As CDS_StaticHierarchy) As Boolean + ValidateHierarchy = False + If target.nodes_.Count = 0 Then _ + Exit Function + If target.nodes_(1).rank_ <> 1 Then _ + Exit Function + + Dim iNode As CDS_NodeSH + For Each iNode In target.nodes_ + If iNode.id_ <> 1 And iNode.rank_ <= 1 Then _ + Exit Function + Next iNode + + ValidateHierarchy = True +End Function + +Public Function ConnectNodes(shape1 As Visio.Shape, shape2 As Visio.Shape, nLayout As TLayout) As Boolean + Dim iConnector As Visio.Shape: Set iConnector = CreateConnector(shape1, shape2, nLayout) + iConnector.CellsSRC(visSectionObject, visRowLock, visLockDelete).FormulaU = "0" + iConnector.Name = PREFIX_CONNECTOR & shape1.ID & "-" & shape2.ID +End Function + +Public Function CreateConnector(sh1 As Visio.Shape, sh2 As Visio.Shape, nMode As TLayout) As Visio.Shape + Dim iPage As Visio.Page: Set iPage = sh1.ContainingPage + Dim prototype As Visio.Master: Set prototype = GetConnectionMaster(nMode) + + Call sh1.AutoConnect(sh2, visAutoConnectDirNone, prototype) + Dim connector As Visio.Shape: Set connector = iPage.Shapes(iPage.Shapes.Count) + Select Case nMode + Case T_LAYOUT_HORIZONTAL + Call connector.CellsU("BeginX").GlueTo(sh1.CellsSRC(7, 0, 0)) + Call connector.CellsU("EndX").GlueTo(sh2.CellsSRC(7, 1, 0)) + + Case T_LAYOUT_COLUMN_LEFT + Call connector.CellsU("BeginX").GlueTo(sh1.CellsSRC(7, 0, 0)) + Call connector.CellsU("EndX").GlueTo(sh2.CellsSRC(7, 3, 0)) + + Case T_LAYOUT_COLUMN_RIGHT + Call connector.CellsU("BeginX").GlueTo(sh1.CellsSRC(7, 0, 0)) + Call connector.CellsU("EndX").GlueTo(sh2.CellsSRC(7, 2, 0)) + + Case Else + Call connector.CellsU("BeginX").GlueTo(sh1.CellsSRC(7, 2, 0)) + Call connector.CellsU("EndX").GlueTo(sh2.CellsSRC(7, 2, 0)) + End Select + With connector + .CellsSRC(visSectionObject, visRowShapeLayout, visSLORouteStyle).FormulaU = 8 + .CellsSRC(visSectionObject, visRowShapeLayout, visSLORouteStyle).FormulaU = _ + prototype.Shapes(1).CellsSRC(visSectionObject, visRowShapeLayout, visSLORouteStyle).FormulaU + End With + Set CreateConnector = connector +End Function + +Public Function ScanExcel(iSource As Excel.Worksheet) As CDS_StaticHierarchy + Dim iData As New CDS_StaticHierarchy + If iSource.Cells(1, 1) = vbNullString Then _ + Exit Function + + Dim nRow& + For nRow = 1 To iSource.UsedRange.Rows.Count Step 1 + Dim iNode As CDS_NodeSH: Set iNode = iData.PushItem(iSource.Cells(nRow, 1)) + If iNode Is Nothing Then _ + Exit Function + Set iNode.data_ = ExrtactXLPayload(iSource, nRow) + Call CSE_ProgressBar.IncrementA + Next nRow + + Set ScanExcel = iData +End Function + +Public Function ScanWord(iSource As Word.Document) As CDS_StaticHierarchy +' Scan word file to create DB + Dim iData As New CDS_StaticHierarchy + Dim iRoot As CDS_NodeSH: Set iRoot = iData.PushItem(1) + Set iRoot.data_ = New VisioNode + iRoot.data_.text_ = iSource.Name + + Dim aPar As Word.Paragraph + Dim pars As Word.Paragraphs: Set pars = iSource.Paragraphs + Dim nColor& + For Each aPar In pars + Dim nRank&: nRank = aPar.OutlineLevel + If nRank = wdOutlineLevelBodyText Then _ + GoTo NEXT_PAR + Dim iPayload As VisioNode: Set iPayload = ExtractWordPayload(aPar.Range) + If iPayload Is Nothing Then _ + GoTo NEXT_PAR + + Dim iNode As CDS_NodeSH: Set iNode = iData.PushItem(nRank + 1) + If iNode Is Nothing Then _ + Exit Function + Set iNode.data_ = iPayload + +NEXT_PAR: + Call CSE_ProgressBar.IncrementA + Next aPar + + Set ScanWord = iData +End Function + +Public Function ScanVisioNode(iRoot As Visio.Shape, iLayout As TLayout) As CDS_StaticHierarchy + Dim iData As New CDS_StaticHierarchy + Call ScanShapeRecur(iRoot, iData, iLayout) + Set ScanVisioNode = iData +End Function + +Public Function Hierarchy2XL(iData As CDS_StaticHierarchy, ByRef iOut As Excel.Worksheet, bFlatData As Boolean) + Dim iNode As CDS_NodeSH + Dim nRow&: nRow = 1 + For Each iNode In iData.nodes_ + If bFlatData Then + iOut.Cells(nRow, 1) = iNode.rank_ + iOut.Cells(nRow, 2) = iNode.data_.text_ + If iNode.data_.color_ <> COLOR_DEFAULT Then _ + iOut.Cells(nRow, 2).Interior.Color = iNode.data_.color_ + Else + iOut.Cells(nRow, iNode.rank_) = iNode.data_.text_ + If iNode.data_.color_ <> COLOR_DEFAULT Then _ + iOut.Cells(nRow, iNode.rank_).Interior.Color = iNode.data_.color_ + End If + nRow = nRow + 1 + Next iNode +End Function + +Public Function Hierarchy2Word(iData As CDS_StaticHierarchy, ByRef target As Word.Document) + If target Is Nothing Then _ + Exit Function + + Dim iNode As CDS_NodeSH + Dim iInsert As Word.Range: Set iInsert = target.Range + For Each iNode In iData.nodes_ + Dim nColor&: nColor = iNode.data_.color_ + Set iInsert = WordAddLine(iNode.data_.text_, iInsert, WordStyleForRank(target, iNode.rank_)) + If nColor = COLOR_DEFAULT Then + iInsert.Font.Shading.BackgroundPatternColor = wdColorAutomatic + Else + iInsert.Font.Shading.BackgroundPatternColor = nColor + End If + Next iNode +End Function + +Public Function Hierarchy2WordString(iData As CDS_StaticHierarchy, ByRef target As Word.Document) + Const SYMBOL_MASK_TOTAL = "[@#]" + Const SYMBOL_MASK_BREAK = "@" + + Dim iStack As New Collection + Call iStack.Add(iData.nodes_(1)) + + Dim childrenIDs As New Collection + Dim curChild& + Do While iStack.Count > 0 + Dim iNode As CDS_NodeSH: Set iNode = iStack.Item(iStack.Count) + Dim sLastChar$: sLastChar = IIf(VBA.Len(iNode.data_.text_) > 0, VBA.Right(iNode.data_.text_, 1), "") + If sLastChar Like SYMBOL_MASK_TOTAL Or iNode.children_.Count = 0 Then + ' Terminal + Call WordAddLine(StackToString(iStack), target.Range, "") + Call iStack.Remove(iStack.Count) + Call CSE_ProgressBar.IncrementA + If sLastChar Like SYMBOL_MASK_BREAK Then _ + Exit Do + ElseIf childrenIDs.Count < iStack.Count Then + ' Moving down + Call iStack.Add(iNode.children_(1)) + Call childrenIDs.Add(1) + Else + curChild = childrenIDs.Item(childrenIDs.Count) + If curChild < iNode.children_.Count Then + ' Move to next child + Call childrenIDs.Remove(childrenIDs.Count) + Call iStack.Add(iNode.children_(curChild + 1)) + Call childrenIDs.Add(curChild + 1) + Else + ' Moving up + Call childrenIDs.Remove(childrenIDs.Count) + Call iStack.Remove(iStack.Count) + End If + End If + Loop +End Function + +Public Function GenerateNamesFor(tRoot As Visio.Shape) + Dim oldName$: oldName = tRoot.Text + If oldName Like "#* *" Then + Call NameTheNode(VBA.Left(oldName, VBA.InStr(1, oldName, " ") - 1), tRoot) + Else + Call NameTheNode("", tRoot) + End If +End Function + +Public Function TransformNodeLayout(rootShape As Visio.Shape) + Dim iData As CDS_StaticHierarchy: Set iData = ScanVisioNode(rootShape, T_LAYOUT_HORIZONTAL) + If iData Is Nothing Then + Call UserInteraction.ShowMessage(EM_INVALID_STRUCTURE) + Exit Function + End If + + If Not iData.MaxDepth >= 2 Then + Call UserInteraction.ShowMessage(EM_CANNOT_TRANSFORM_DEEP) + Exit Function + End If + + Dim rootNode As CDS_NodeSH: Set rootNode = iData.nodes_(1) + Dim nChildrenCount&: nChildrenCount = rootNode.children_.Count + If nChildrenCount < 2 Then _ + Exit Function + + Dim oChildren As New Collection + Dim aNode As CDS_NodeSH + For Each aNode In rootNode.children_ + Call oChildren.Add(aNode.data_.shape_) + Next aNode + + Dim theLayout As TLayout: theLayout = T_LAYOUT_HORIZONTAL + If oChildren(1).CellsU("PinY") - oChildren(2).CellsU("PinY") < FLOAT_ACCURACY Then _ + theLayout = T_LAYOUT_VERTICAL + + Call SetLayout(rootShape, oChildren, theLayout) +End Function + +Public Function AddNewRankTemplate() As Visio.Master + Dim nRank&: nRank = 1 + Do While Not FindMaster(ThisDocument, MASTER_RANK & nRank) Is Nothing + nRank = nRank + 1 + Loop + Dim iMaster As Visio.Master: Set iMaster = ThisDocument.Masters.Add + iMaster.Name = MASTER_RANK & nRank + Dim iShape As Visio.Shape: Set iShape = iMaster.Drop(GetRankMaster(nRank - 1), 0, 0) + iShape.Name = SHAPE_RANK_MASTER & nRank + iShape.Text = " " & nRank + Set AddNewRankTemplate = iMaster +End Function + +Public Function ConnectColumns(rootShape As Visio.Shape) + Dim iData As CDS_StaticHierarchy: Set iData = ScanVisioNode(rootShape, T_LAYOUT_VERTICAL) + If iData Is Nothing Then + Call UserInteraction.ShowMessage(EM_INVALID_STRUCTURE) + Exit Function + End If + + Dim dMidX As Double: dMidX = rootShape.CellsU("PinX") + + Dim iChild As Visio.Shape + Dim iConnect As Visio.Connect + Dim aNode As CDS_NodeSH + For Each aNode In iData.nodes_(1).children_ + Set iChild = aNode.data_.shape_ + For Each iConnect In iChild.FromConnects + If iConnect.FromSheet.Connects(1).ToSheet Is rootShape Then _ + Call iConnect.FromSheet.Delete + Next iConnect + + If iChild.CellsU("PinX") > dMidX Then + Call ConnectNodes(rootShape, iChild, T_LAYOUT_COLUMN_RIGHT) + Else + Call ConnectNodes(rootShape, iChild, T_LAYOUT_COLUMN_LEFT) + End If + Next aNode +End Function + +' ======== +Private Function NameTheNode(sID$, target As Visio.Shape) + Dim oldName$: oldName = target.Text + If VBA.IsNumeric(VBA.Left(oldName, 1)) Then _ + oldName = VBA.Right(oldName, VBA.Len(oldName) - VBA.InStr(1, oldName, " ")) + If sID <> vbNullString Then _ + target.Text = sID & " " & oldName + + Dim oChildren As New Collection: Set oChildren = GetChildrenOf(target) + If oChildren.Count = 0 Then _ + Exit Function + + Dim nIndex() As Long: nIndex = SortChildrenCount(oChildren) + + Dim nItem&: nItem = 1 + Dim iChild As Visio.Shape + For Each iChild In oChildren + If sID = vbNullString Then + Call NameTheNode(nIndex(nItem) & ".", iChild) + Else + Call NameTheNode(sID & nIndex(nItem) & ".", iChild) + End If + nItem = nItem + 1 + Next iChild +End Function + +Private Function SortChildrenCount(oChildren As Collection) As Long() + ' using CountSort algorithm + Dim nIndicies() As Long + ReDim nIndicies(1 To oChildren.Count) + + Dim sibling1 As Visio.Shape + Dim nItem1&: nItem1 = 1 + For Each sibling1 In oChildren + nIndicies(nItem1) = 1 + Dim dLeftX As Double: dLeftX = sibling1.CellsU("PinX") - sibling1.CellsU("Width") / 2# + Dim dTopY As Double: dTopY = sibling1.CellsU("PinY") + sibling1.CellsU("Height") / 2# + + Dim nItem2&: nItem2 = 1 + Dim sibling2 As Visio.Shape + For Each sibling2 In oChildren + If nItem1 = nItem2 Then _ + GoTo NEXT_2 + + Dim dLeftX2 As Double: dLeftX2 = sibling2.CellsU("PinX") - sibling2.CellsU("Width") / 2# + Dim dTopY2 As Double: dTopY2 = sibling2.CellsU("PinY") + sibling2.CellsU("Height") / 2# + + If dTopY + FLOAT_ACCURACY < dTopY2 Then + nIndicies(nItem1) = nIndicies(nItem1) + 1 + ElseIf Abs(dTopY - dTopY2) < FLOAT_ACCURACY And dLeftX - FLOAT_ACCURACY > dLeftX2 Then + nIndicies(nItem1) = nIndicies(nItem1) + 1 + End If +NEXT_2: + nItem2 = nItem2 + 1 + Next sibling2 + nItem1 = nItem1 + 1 + Next sibling1 + SortChildrenCount = nIndicies +End Function + +Public Function SetLayout(theRoot As Visio.Shape, oChildren As Collection, theLayout As TLayout) + Dim baseXPos As Double: baseXPos = theRoot.CellsU("PinX") + Dim baseYPos As Double: baseYPos = theRoot.CellsU("PinY") - theRoot.CellsU("Height") / 2# + + Dim iChild As Visio.Shape + If theLayout = T_LAYOUT_HORIZONTAL Then + For Each iChild In oChildren + baseXPos = baseXPos - GAP_HORIZONTAL / 2# - iChild.CellsU("Width") / 2# + Next iChild + End If + + Dim cnt As Visio.Connect + For Each iChild In oChildren + Dim dWidth As Double: dWidth = iChild.CellsU("Width") + Dim dHeight As Double: dHeight = iChild.CellsU("Height") + For Each cnt In iChild.FromConnects + If cnt.FromSheet.Connects(1).ToSheet Is theRoot Then _ + Call cnt.FromSheet.Delete + Next cnt + + iChild.CellsU("PinY") = baseYPos - GAP_VERTICAL - dHeight / 2# + If theLayout = T_LAYOUT_VERTICAL Then + iChild.CellsU("PinX") = baseXPos - theRoot.CellsU("Width") / 2# + dWidth / 2# + baseYPos = baseYPos - GAP_VERTICAL - dHeight + Else + iChild.CellsU("PinX") = baseXPos + GAP_HORIZONTAL + dWidth / 2# + baseXPos = baseXPos + GAP_HORIZONTAL + dWidth + End If + + Call ConnectNodes(theRoot, iChild, theLayout) + Next iChild +End Function + +Private Function ScanShapeRecur(target As Visio.Shape, ByRef iData As CDS_StaticHierarchy, _ + aLayout As TLayout, Optional iParent As CDS_NodeSH = Nothing) + If target Is Nothing Then _ + Exit Function + Dim nRank&: nRank = 1 + If Not iParent Is Nothing Then _ + nRank = iParent.rank_ + 1 + + Dim iNode As CDS_NodeSH: Set iNode = iData.PushItem(nRank) + Set iNode.data_ = ExtractVsoPayload(target) + + Dim oChildren As Collection: Set oChildren = GetChildrenOf(target) + If oChildren.Count = 0 Then _ + Exit Function + + Dim nIndicies() As Long: nIndicies = SortChildrenLayout(oChildren, target, aLayout) + Dim n& + For n = 1 To oChildren.Count + Call ScanShapeRecur(oChildren(nIndicies(n)), iData, aLayout, iNode) + Next n +End Function + +Private Function SortChildrenLayout(oChildren As Collection, aParent As Visio.Shape, iLayout As TLayout) As Long() + ' using bubble sort algorithm + Dim nCount&: nCount = oChildren.Count + Dim nIndicies() As Long + ReDim nIndicies(1 To nCount) + Dim n& + For n = 1 To nCount Step 1 + nIndicies(n) = n + Next n + If nCount = 1 Then + SortChildrenLayout = nIndicies + Exit Function + End If + + Dim k& + For n = 1 To nCount - 1 Step 1 + For k = n + 1 To nCount + If CompareChildren(aParent, oChildren(nIndicies(n)), oChildren(nIndicies(k)), iLayout) Then + nIndicies(n) = nIndicies(n) + nIndicies(k) + nIndicies(k) = nIndicies(n) - nIndicies(k) + nIndicies(n) = nIndicies(n) - nIndicies(k) + End If + Next k + Next n + SortChildrenLayout = nIndicies +End Function + +Private Function CompareChildren(aParent As Visio.Shape, child1 As Visio.Shape, child2 As Visio.Shape, iLayout As TLayout) As Boolean + Select Case iLayout + Case T_LAYOUT_RADIAL + CompareChildren = _ + aParent.DistanceFrom(child1, visSpatialIncludeDataGraphics) _ + - aParent.DistanceFrom(child2, visSpatialIncludeDataGraphics) _ + > FLOAT_ACCURACY + Case T_LAYOUT_HORIZONTAL + CompareChildren = child1.CellsU("PinX") - child2.CellsU("PinX") > FLOAT_ACCURACY + Case T_LAYOUT_VERTICAL + CompareChildren = child2.CellsU("PinY") - child1.CellsU("PinY") > FLOAT_ACCURACY + End Select +End Function + +Private Function StackToString(iStack As Collection) As String + Dim theString$: theString = "" + Dim bFirst As Boolean: bFirst = True + Dim iNode As CDS_NodeSH + For Each iNode In iStack + If Not bFirst Then _ + theString = theString & " " + bFirst = False + theString = theString & iNode.data_.text_ + Next iNode + StackToString = theString +End Function + diff --git a/src/MasterDlg.frm b/src/MasterDlg.frm new file mode 100644 index 0000000..a11b135 --- /dev/null +++ b/src/MasterDlg.frm @@ -0,0 +1,123 @@ +VERSION 5.00 +Begin {C62A69F0-16DC-11CE-9E98-00AA00574A4F} MasterDlg + ClientHeight = 5925 + ClientLeft = 120 + ClientTop = 465 + ClientWidth = 5250 + OleObjectBlob = "MasterDlg.frx":0000 + StartUpPosition = 1 'CenterOwner +End +Attribute VB_Name = "MasterDlg" +Attribute VB_GlobalNameSpace = False +Attribute VB_Creatable = False +Attribute VB_PredeclaredId = True +Attribute VB_Exposed = False +Option Explicit + +Public bCanceled As Boolean + +Private Sub UserForm_Initialize() + bCanceled = True + Me.StartUpPosition = visCenter + UpdateState +End Sub + +Public Property Get InputMode() As IOMode +' Get Input mode + InputMode = MODE_EXCEL + If btnInputOpt1.Value = True Then InputMode = MODE_WORD + If btnInputOpt3.Value = True Then InputMode = MODE_VISIO +End Property + +Public Property Get OutputMode() As IOMode +' Get output mode + OutputMode = MODE_EXCEL + If btnOutputOpt1.Value = True Then OutputMode = MODE_WORD + If btnOutputOpt3.Value = True Then OutputMode = MODE_VISIO +End Property + +Public Property Get InputLayout() As TLayout + InputLayout = T_LAYOUT_RADIAL + If btnModeX.Value = True Then InputLayout = T_LAYOUT_HORIZONTAL + If btnModeY.Value = True Then InputLayout = T_LAYOUT_VERTICAL +End Property + +Public Property Get AutoLayout() As Boolean + AutoLayout = CheckBox1.Value +End Property + +Public Property Get WordExportAsString() As Boolean + WordExportAsString = CheckBox2.Value +End Property + +Public Property Get XLExportAsTree() As Boolean + XLExportAsTree = CBExcel.Value +End Property + +Public Property Get InputFile() As String + InputFile = textInput.Text +End Property + +Private Sub btnInput_Click() + If InputMode = MODE_VISIO Then + Call UserInteraction.ShowMessage(EM_VISIO_INPUT) + Exit Sub + End If + + Dim sFile$: sFile = UserInteraction.PromptFile(ActiveDocument.Path, " ", bNewApplication:=True) + If sFile = vbNullString Then _ + Exit Sub + + textInput.Text = sFile +End Sub + +Private Sub btnInputOpt1_Click() + UpdateState +End Sub + +Private Sub btnInputOpt2_Click() + UpdateState +End Sub + +Private Sub btnInputOpt3_Click() + UpdateState +End Sub + +Private Sub btnOutputOpt1_Click() + UpdateState +End Sub + +Private Sub btnOutputOpt2_Click() + UpdateState +End Sub + +Private Sub btnOutputOpt3_Click() + UpdateState +End Sub + +Private Function UpdateState() + CheckBox2.Visible = btnOutputOpt1.Value + CheckBox1.Visible = btnOutputOpt3.Value + CBExcel.Visible = btnOutputOpt2.Value + + lblLevel.Visible = btnInputOpt3.Value + btnModeX.Visible = btnInputOpt3.Value + btnModeY.Visible = btnInputOpt3.Value + btnModeRad.Visible = btnInputOpt3.Value +End Function + +Private Sub UserForm_Activate() + bCanceled = True +End Sub + +Private Sub OkBtn_Click() + bCanceled = False + Me.Hide +End Sub + +Private Sub CancelBtn_Click() + bCanceled = True + Me.Hide +End Sub + + diff --git a/src/MasterDlg.frx b/src/MasterDlg.frx new file mode 100644 index 0000000000000000000000000000000000000000..41dbd8321083e21211f6b895386a4ee4843a9112 GIT binary patch literal 5656 zcmeI0O>9(E6vxlBkB>ruwiKvj0r2hW*%`lH9(+)K;(eRr8-22`; z@1Ar2=i}bn{@7BpwRY#4Tw^x=fZ4a#s(=3A)AiTyyvTJ9Sh?Mvsj$U?7a{tByQ<8} z=;;3T%*>4c(2VZ=>p#T6U)U=D2_8;d1myE2fQYdQpm+DL|0e^-EzMuX!q#i!w3Bub zkC%R}C1Uc-s27c*@`W{s% zuU~DcLo89SbEW-e!N2GasRn9JrRo#ts|e)k5s-S@?lp(|#ug?eHkTYO?*Bt16ZyZ?Q~ z(pw6wt@bMoOG;LE$J{X0mN*;Bj3fIo4{usolk>BS39rj*^$vIu+9q!gy(n$W>-Sce zVsI6KcT|Iy)!7scYgG0Y?Uk}}iw~qm2Pa2)x6zHKSlz_89gMi2QS@zM-fvIX!O)k^ zSmHZNTxYc&VrN$NX(BgBgy%@$CiK-};XW^((-HH+c9LA4v|+Mj8F*rRVk*OX*{ir@ zUCn+(dxh`wgjrdSvsau)i0rV{czrO?3I}c2-^!>_uNO@%%;SK!m-`;tF0_i9S4bS$ z6XfK&(-Gw4SkZYYHy6n+2-Y|e=Cy^9BVIfD57N`hFl|GYv=s2?)IQIg`itsQO$h2! z4%fQbw&LvrXnV>=?L0{5bhXZ-Yi^&3^U{4rj7(*4+FU+UjLprb^K*_*&96A0d42zk z&!E1@rLjxJ`1I#CAD@R@JnqKs=A!Y~H%CO8l@^n}o;LKf6w%X3^r;dkhhy~mh>j?~ zel|3f82h!x0-Z&TZ8((Od5r+PoXZ#Gq-uztFBYgFb&dlq(Oc2Kmt6RUpq-s(pY#6i z+Vhf&dmd|jboE1Ps_Mrxw0l?pU5?SOBHClbyPw5v-s8-%n`+YLGCb-sBF5c5^tV$1 z_cL$hejFZD7gg2zxo-&M%XU|H7<|rplPPNBVLn|0KeDljg1!sw-Cn1wHmYt>hc+sa zUzPMEf7juv({4A5n5)}i>vmpKjePM^ahsG+&la^waTv6zmihaY!q=_Zp1>|&R~%h2 zDz2g?Shwcmq!9Dbdy2(;B$gWUbJq>xEl`I?(wkj9)LgpxQ?w*txy?K3sSfuKTue`8 ziu0;D7q7$mS3ppo*0XvSS6$>++<98M_7K3O>6(9Tcj_>@>xpXlQGSvSJDtz80+gap zF>}gPJ9+>&7IrKtR@;H%P}VC>^~}$-ee@K=dZJ9~plv7fnsThB*pzBhlIK*l!O!tP zZE*SuKlSQ1xP49q;;JkiAjHNvJ}^F%OtII2&L7zy-wepIJ;`b}k^yCGjt4X2Ze>kO zWFj(Qi|PjB{y|^mUANli4uf(w+5H29$rO9v@3|N9HfY>M+)V)Q?s22-?A`O@YF{Q< z#%5X9l6;p9&403g_homwx$$WhI-I?WeOZ4sk-?M!*}P4Aem3bETkvrKY2;~c}YIt)A~5_0=mrH_t63d2hLo%f-*@Z}0|p<~jAU&O!X%(BvX?8MWmNix})W9FNAD{XA8bUoEpoS ztxig_|97FY>ygo+$@Ka3=}h=wdUEW1INI3cdhYPsJ2sdc9!?I26N6`xLm5TAIk86l SHb(6Cy`P<1uxbCwhkpYCIvL~u literal 0 HcmV?d00001 diff --git a/src/ThisDocument.cls b/src/ThisDocument.cls new file mode 100644 index 0000000..8d5a8b6 --- /dev/null +++ b/src/ThisDocument.cls @@ -0,0 +1,22 @@ +VERSION 1.0 CLASS +BEGIN + MultiUse = -1 'True +END +Attribute VB_Name = "ThisDocument" +Attribute VB_GlobalNameSpace = False +Attribute VB_Creatable = False +Attribute VB_PredeclaredId = True +Attribute VB_Exposed = True +Option Explicit + +Private Sub Document_DocumentOpened(ByVal iDoc As IVDocument) + If iDoc.ID <> ThisDocument.ID Then _ + Exit Sub + + Dim sCmd$: sCmd = OfficeCommandLine + If VBA.InStr(1, sCmd, "/automation", vbTextCompare) <> 0 Then _ + Exit Sub + + Call StartVersionCheck +End Sub + diff --git a/src/VisioNode.cls b/src/VisioNode.cls new file mode 100644 index 0000000..974adda --- /dev/null +++ b/src/VisioNode.cls @@ -0,0 +1,20 @@ +VERSION 1.0 CLASS +BEGIN + MultiUse = -1 'True +END +Attribute VB_Name = "VisioNode" +Attribute VB_GlobalNameSpace = False +Attribute VB_Creatable = False +Attribute VB_PredeclaredId = False +Attribute VB_Exposed = False +'------------ Visio hierarchy node --------------- +Option Explicit + +Public text_ As String +Public color_ As Long + +Public shape_ As Visio.Shape + +Private Sub Class_Initialize() + color_ = COLOR_DEFAULT +End Sub diff --git a/src/z_UIMessages.bas b/src/z_UIMessages.bas new file mode 100644 index 0000000..7494436 --- /dev/null +++ b/src/z_UIMessages.bas @@ -0,0 +1,94 @@ +Attribute VB_Name = "z_UIMessages" +' Messaging module +Option Private Module +Option Explicit + +Public Enum MsgCode + MSG_OK = 0 + + EM_VISIO_INPUT + EM_FILENAME_EMPTY + EM_INVALID_SELECTION + EM_ERROR_LOADING_FILE + EM_INVALID_FILE_FORMAT + EM_WORD_MAX_LEVELS + EM_INVALID_STRUCTURE + EM_CANNOT_TRANSFORM_DEEP + EM_INVALID_FORMAT + + IM_EXPORT_OK + IM_IMPORT_OK + IM_NEW_TEMPLATE + + ' QM_CODE_DELETE_CONFIRM +End Enum + +Private g_UI As API_UserInteraction + +Public Function UserInteraction() As API_UserInteraction + If g_UI Is Nothing Then _ + Set g_UI = New API_UserInteraction + Set UserInteraction = g_UI +End Function + +Public Function SetUserInteraction(newUI As API_UserInteraction) + Set g_UI = newUI +End Function + +Public Function UIShowMessage(theCode As MsgCode, ParamArray params() As Variant) + Dim unwrapped As Variant: unwrapped = params + unwrapped = FixForwardedParams(unwrapped) + + Select Case theCode + Case EM_VISIO_INPUT + Call MsgBox(" Visio ", vbInformation) + Case EM_FILENAME_EMPTY + Call MsgBox(" ", vbExclamation) + Case EM_INVALID_SELECTION + Call MsgBox(" ", vbExclamation) + Case EM_ERROR_LOADING_FILE + Call MsgBox(" ", vbExclamation) + Case EM_INVALID_FILE_FORMAT + Call MsgBox(" !" & vbNewLine & _ + " ", vbExclamation) + Case EM_WORD_MAX_LEVELS + Call MsgBox(" Word 9 !", vbCritical) + Case EM_INVALID_STRUCTURE + Call MsgBox(" ", vbCritical) + Case EM_CANNOT_TRANSFORM_DEEP + Call MsgBox(" """"", vbCritical) + Case EM_INVALID_FORMAT + Call MsgBox(Fmt(" {1} ", unwrapped), vbExclamation) + + Case IM_EXPORT_OK + Call MsgBox(Fmt(" !" & vbNewLine & _ + " : {1}" & vbNewLine & _ + " : {2}", unwrapped), vbInformation) + Case IM_IMPORT_OK + Call MsgBox(Fmt(" !" & vbNewLine & _ + " : {1}" & vbNewLine & _ + " : {2}" & vbNewLine & _ + " : {3} x {4}", unwrapped), vbInformation) + Case IM_NEW_TEMPLATE + Call MsgBox(Fmt(" : {1}", unwrapped), vbInformation) + + + Case Else + Call MsgBox("Invalid message code", vbCritical) + End Select +End Function + +Public Function UIAskQuestion(theCode As MsgCode, ParamArray params() As Variant) As Boolean + Dim unwrapped As Variant: unwrapped = params + unwrapped = FixForwardedParams(unwrapped) + + Dim answer&: answer = vbNo + Select Case theCode + ' Case QM_CODE_DELETE_CONFIRM + ' answer = MsgBox("Are you sure you want to delete ALL macros from target file?", vbYesNo + vbQuestion) + + Case Else + Call MsgBox("Invalid message code", vbCritical) + End Select + UIAskQuestion = answer = vbYes +End Function diff --git a/src/z_UIRibbon.bas b/src/z_UIRibbon.bas new file mode 100644 index 0000000..1f5550d --- /dev/null +++ b/src/z_UIRibbon.bas @@ -0,0 +1,20 @@ +Attribute VB_Name = "z_UIRibbon" +Option Explicit + +Public Sub OnAction(iControl As IRibbonControl) + Select Case iControl.ID + Case "LoadExcel": Call RunImportXL + Case "LoadWord": Call RunImportWord + Case "Clear": Call RunClearScheme + Case "MasterIO": Call RunMaster + + Case "Transform": Call RunTransform + Case "ConnectColumns": Call RunConnectColumns + Case "AutoName": Call RunRename + + Case "ContextTransform": Call RunTransform + Case "NewRankTemplate": Call RunNewRankTemplate + + Case Else: Call CC_DispatchCommand(iControl.ID) + End Select +End Sub diff --git a/ui/.rels b/ui/.rels new file mode 100644 index 0000000..5ecfe27 --- /dev/null +++ b/ui/.rels @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/ui/customUI1.xml b/ui/customUI1.xml new file mode 100644 index 0000000..6c77c6e --- /dev/null +++ b/ui/customUI1.xml @@ -0,0 +1,90 @@ + + + + + + +