From 2c8b91e305d21e888e66550601938c7b151af33e Mon Sep 17 00:00:00 2001 From: IRBorisov <8611739+IRBorisov@users.noreply.github.com> Date: Fri, 7 Jun 2024 20:07:08 +0300 Subject: [PATCH] Initial commit --- VBAMake.txt | 35 ++ VERSION | 1 + distr/!Руководство пользователя.docx | Bin 0 -> 64879 bytes script/manifest.txt | 97 ++++ skeleton/_Maket.dotm | Bin 0 -> 29738 bytes src/CD_Audit.bas | 288 +++++++++++ src/CD_AutoDesign.bas | 691 +++++++++++++++++++++++++++ src/CD_Colontitles.bas | 270 +++++++++++ src/CD_Layout.bas | 560 ++++++++++++++++++++++ src/CD_Paint.bas | 358 ++++++++++++++ src/CD_RedesignFonts.bas | 115 +++++ src/CD_SplitTable.bas | 307 ++++++++++++ src/CD_WordModule.bas | 122 +++++ src/Declarations.bas | 136 ++++++ src/DevHelper.bas | 21 + src/IconPicker.cls | 35 ++ src/InfoDocument.cls | 68 +++ src/ItemChapter.cls | 22 + src/ItemColontitles.cls | 23 + src/ItemFontScale.cls | 24 + src/Main.bas | 334 +++++++++++++ src/MainImpl.bas | 6 + src/dialogs/CDD_AddPict.frm | 152 ++++++ src/dialogs/CDD_AddPict.frx | Bin 0 -> 30232 bytes src/dialogs/CDD_AutoDesign.frm | 41 ++ src/dialogs/CDD_AutoDesign.frx | Bin 0 -> 3608 bytes src/dialogs/CDD_FontScaling.frm | 75 +++ src/dialogs/CDD_FontScaling.frx | Bin 0 -> 4120 bytes src/dialogs/CDD_HeaderFooter.frm | 103 ++++ src/dialogs/CDD_HeaderFooter.frx | Bin 0 -> 9752 bytes src/dialogs/CDD_Paint.frm | 51 ++ src/dialogs/CDD_Paint.frx | Bin 0 -> 3096 bytes src/dialogs/CDD_RunAudit.frm | 62 +++ src/dialogs/CDD_RunAudit.frx | Bin 0 -> 3608 bytes src/dialogs/CDD_TableColors.frm | 128 +++++ src/dialogs/CDD_TableColors.frx | Bin 0 -> 10264 bytes src/dialogs/CDD_TablePrototype.frm | 46 ++ src/dialogs/CDD_TablePrototype.frx | Bin 0 -> 3096 bytes src/z_UIMessages.bas | 70 +++ src/z_UIRibbon.bas | 31 ++ ui/.rels | 2 + ui/customUI.xml | 98 ++++ 42 files changed, 4372 insertions(+) create mode 100644 VBAMake.txt create mode 100644 VERSION create mode 100644 distr/!Руководство пользователя.docx create mode 100644 script/manifest.txt create mode 100644 skeleton/_Maket.dotm create mode 100644 src/CD_Audit.bas create mode 100644 src/CD_AutoDesign.bas create mode 100644 src/CD_Colontitles.bas create mode 100644 src/CD_Layout.bas create mode 100644 src/CD_Paint.bas create mode 100644 src/CD_RedesignFonts.bas create mode 100644 src/CD_SplitTable.bas create mode 100644 src/CD_WordModule.bas create mode 100644 src/Declarations.bas create mode 100644 src/DevHelper.bas create mode 100644 src/IconPicker.cls create mode 100644 src/InfoDocument.cls create mode 100644 src/ItemChapter.cls create mode 100644 src/ItemColontitles.cls create mode 100644 src/ItemFontScale.cls create mode 100644 src/Main.bas create mode 100644 src/MainImpl.bas create mode 100644 src/dialogs/CDD_AddPict.frm create mode 100644 src/dialogs/CDD_AddPict.frx create mode 100644 src/dialogs/CDD_AutoDesign.frm create mode 100644 src/dialogs/CDD_AutoDesign.frx create mode 100644 src/dialogs/CDD_FontScaling.frm create mode 100644 src/dialogs/CDD_FontScaling.frx create mode 100644 src/dialogs/CDD_HeaderFooter.frm create mode 100644 src/dialogs/CDD_HeaderFooter.frx create mode 100644 src/dialogs/CDD_Paint.frm create mode 100644 src/dialogs/CDD_Paint.frx create mode 100644 src/dialogs/CDD_RunAudit.frm create mode 100644 src/dialogs/CDD_RunAudit.frx create mode 100644 src/dialogs/CDD_TableColors.frm create mode 100644 src/dialogs/CDD_TableColors.frx create mode 100644 src/dialogs/CDD_TablePrototype.frm create mode 100644 src/dialogs/CDD_TablePrototype.frx create mode 100644 src/z_UIMessages.bas create mode 100644 src/z_UIRibbon.bas create mode 100644 ui/.rels create mode 100644 ui/customUI.xml diff --git a/VBAMake.txt b/VBAMake.txt new file mode 100644 index 0000000..88f525a --- /dev/null +++ b/VBAMake.txt @@ -0,0 +1,35 @@ +# == Properties Section == +# configuration properties +# use .ini format to define properties +# mandatory properties: name, artifact_home, source_home + +id = Concept-Maket +name = Концепт-Макетирование +description = Надстройка КОНЦЕПТ для макетирования отчетов +artifact_home = Концепт-Макетирование +source_home = Concept-Maket +install_home = \\fs1.concept.ru\projects\10 Автоматизация деятельности\02 Офисная автоматизация\81 Макетирование + +%% +# === 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 +copy distr\!Руководство пользователя.docx + +%% +# === Install section == +# Available commands: +# install LOCAL_ARTIFACT -> [INSTALL_PATH] +# add_template LOCAL_ARTIFACT -> [LOCAL_TEMPLATE] +# run LOCAL_ARTIFACT.bat <- [PARAMETERS] +# run APPLICATION <- [PARAMETERS] + +install _Maket.dotm +install _Maket.dotm -> \\fs1.concept.ru\Exchange\ConceptDistr\data\Add-ins\Word\_Maket.dotm + +install !Руководство пользователя.docx \ No newline at end of file diff --git a/VERSION b/VERSION new file mode 100644 index 0000000..9084fa2 --- /dev/null +++ b/VERSION @@ -0,0 +1 @@ +1.1.0 diff --git a/distr/!Руководство пользователя.docx b/distr/!Руководство пользователя.docx new file mode 100644 index 0000000000000000000000000000000000000000..4dca1f0d1b037286bbf292907477c5f2754617c7 GIT binary patch literal 64879 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

QTGaOwuL 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 IZ+^b}KU0uX)&Kwi literal 0 HcmV?d00001 diff --git a/script/manifest.txt b/script/manifest.txt new file mode 100644 index 0000000..0de96ac --- /dev/null +++ b/script/manifest.txt @@ -0,0 +1,97 @@ +# == Properties Section == +# configuration properties +# use .ini format to define properties +# mandatory properties: name, artifact + +name = _Maket.dotm +artifact = _Maket.dotm + +%% +# === Imports Section === +# Hierarchy of folders and files +# Use Tabulator to mark next level in hierarchy +# All folders are nested into SharedHome path + +dev + DevTester.bas + +api + z_PastePictureAPI.bas + z_LoadPictureAPI.bas + ex_WinAPI.bas + API_WordWrapper.cls + API_XLWrapper.cls + API_UserInteraction.cls + +utility + ex_VBA.bas + ex_Collection.bas + ex_Color.bas + +word + ex_Word.bas + +ui + CSE_ProgressBar.frm + +%% +# === Source Code Section == +# Hierarchy of folders and files +# Use Tabulator to mark next level in hierarchy +# All folders are nested into SourceHome path + +src + DevHelper.bas + Declarations.bas + Main.bas + MainImpl.bas + z_UIMessages.bas + z_UIRibbon.bas + + CD_Audit.bas + CD_AutoDesign.bas + CD_Colontitles.bas + CD_Layout.bas + CD_Paint.bas + CD_RedesignFonts.bas + CD_SplitTable.bas + CD_WordModule.bas + + IconPicker.cls + + ItemFontScale.cls + ItemChapter.cls + ItemColontitles.cls + + InfoDocument.cls + + dialogs + CDD_AddPict.frm + CDD_AutoDesign.frm + CDD_FontScaling.frm + CDD_HeaderFooter.frm + CDD_Paint.frm + CDD_RunAudit.frm + CDD_TableColors.frm + CDD_TablePrototype.frm + +%% +# ===== UI Section ======= +# Pairs of path to UI elements, use " -> " delimiter +# First component is a path relative to SourceHome\ui folders +# Second component is internal path inside project file + +.rels -> _rels\.rels +customUI.xml -> customUI\customUI.xml + +%% +# === References Section === +# List dependencies in one of the formats +# global : GLOBAL_NAME +# guid : {REGISTERED_GUID} +# file : PATH_TO_LIBRARY + +global : Shell32 +global : Scripting +global : Excel +global : MSForms \ No newline at end of file diff --git a/skeleton/_Maket.dotm b/skeleton/_Maket.dotm new file mode 100644 index 0000000000000000000000000000000000000000..36d99910d06dc8a086a48486f618c9766b952f65 GIT binary patch literal 29738 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 s8T<|Y=VRP!^lKmYH~!T4|Kah 1 Then + Call theRange.Collapse(wdCollapseStart) + Call theRange.Comments.Add(theRange, DANG_LISTNUM) + CheckNumerList = CheckNumerList + 1 + End If + +NEXT_PARA: + Call CSE_ProgressBar.IncrementB + Next para + + Call CSE_ProgressBar.HideSecondBar + Call CSE_ProgressBar.IncrementA +End Function + +Private Function CheckPrevRangeList(prevRange As Word.Range, theLvl&) As Boolean + CheckPrevRangeList = False + + If prevRange Is Nothing Then _ + Exit Function + If IsHeader(prevRange) Or prevRange.ListFormat.List Is Nothing Then _ + Exit Function + + CheckPrevRangeList = theLvl <= prevRange.ListFormat.ListLevelNumber +End Function + +Private Function CheckHeaders(target As Word.Document) As Long + CSE_ProgressBar.Header = " ..." + Call CSE_ProgressBar.InitSecondBar(0, target.Range.End) + + Dim parRng As Word.Range: Set parRng = target.Paragraphs.First.Range + Do While Not parRng Is Nothing + If Not IsHeader(parRng) Or IsHeader(parRng, 1) Then _ + GoTo NEXT_PAR + + If IsFirstInColumn(parRng) Then + If parRng.ParagraphFormat.SpaceBefore <> 0 Then + Call parRng.Comments.Add(parRng, RUN_HEADER_RUN) + CheckHeaders = CheckHeaders + 1 + End If + ElseIf parRng.ParagraphFormat.SpaceBefore <> 0 Then + GoTo NEXT_PAR + ElseIf Not IsHeader(parRng.Previous(wdParagraph)) Then + Call parRng.Comments.Add(parRng, RUN_HEADER_RUN) + CheckHeaders = CheckHeaders + 1 + End If +NEXT_PAR: + Call CSE_ProgressBar.SetB(parRng.End) + Set parRng = parRng.Next(wdParagraph, 1) + Loop + + Call CSE_ProgressBar.HideSecondBar + Call CSE_ProgressBar.IncrementA +End Function + +Private Function CheckSpaces(target As Word.Document) As Long + CSE_ProgressBar.Header = " ..." + Call CSE_ProgressBar.InitSecondBar(0, target.Range.End) + + Dim parRng As Word.Range: Set parRng = target.Paragraphs.First.Range + Do While Not parRng Is Nothing + If Not IsHeader(parRng) Or IsHeader(parRng, 1) Then _ + GoTo NEXT_PAR + If IsFirstInColumn(parRng) Then _ + GoTo NEXT_PAR + + Dim tmpRng As Word.Range: Set tmpRng = parRng.Previous(wdParagraph) + ' + If IsHeader(tmpRng) And tmpRng.ParagraphFormat.SpaceAfter = 0 Then + Call parRng.Comments.Add(parRng, DANG_SPACES) + CheckSpaces = CheckSpaces + 1 + End If + + ' ?? + If Not IsHeader(tmpRng) And tmpRng.ParagraphFormat.SpaceAfter <> 0 Then + If tmpRng.ListFormat.List Is Nothing Then + Call parRng.Comments.Add(parRng, DANG_SPACES) + CheckSpaces = CheckSpaces + 1 + End If + End If + + ' ?? + Set tmpRng = parRng.Next(wdParagraph) + If tmpRng.ParagraphFormat.SpaceBefore <> 0 Then + Call parRng.Comments.Add(parRng, DANG_SPACES) + CheckSpaces = CheckSpaces + 1 + End If +NEXT_PAR: + Call CSE_ProgressBar.SetB(parRng.End) + Set parRng = parRng.Next(wdParagraph, 1) + Loop + + Call CSE_ProgressBar.HideSecondBar + Call CSE_ProgressBar.IncrementA +End Function + +Private Function CheckPict(target As Word.Document) As Long + CSE_ProgressBar.Header = " ..." + Call CSE_ProgressBar.InitSecondBar(0, target.Shapes.Count) + + Dim aShape As Word.Shape + For Each aShape In target.Shapes + If aShape.Type = msoTextBox Then + If GetColumn(aShape.Anchor) = T_COL_RIGHT And IsFirstInColumn(aShape.Anchor) Then + Call aShape.Anchor.Comments.Add(aShape.Anchor, DANG_PICT) + CheckPict = CheckPict + 1 + End If + End If + Call CSE_ProgressBar.IncrementB + Next aShape + + Call CSE_ProgressBar.HideSecondBar + Call CSE_ProgressBar.IncrementA +End Function + +Private Function CheckDashes(target As Word.Document) As Long + CSE_ProgressBar.Header = " ..." + Call CSE_ProgressBar.InitSecondBar(0, 3) + + Dim rFind As Word.Range: Set rFind = target.Range.Duplicate + Dim tempRange As Word.Range + With rFind.Find + .Text = Chr(45) + Do While .Execute + Set tempRange = rFind.Duplicate + Call tempRange.Collapse(wdCollapseStart) + Call tempRange.Select + If PointsToCentimeters(Selection.Information(wdHorizontalPositionRelativeToTextBoundary)) < 0.1 And _ + rFind.Comments.Count = 0 And rFind.Hyperlinks.Count = 0 And Not IsHeader(rFind) Then + Call rFind.Comments.Add(rFind, DANG_DASH) + CheckDashes = CheckDashes + 1 + GoTo skp1 + End If + + Set tempRange = rFind.Duplicate + Call tempRange.Collapse(wdCollapseEnd) + Call tempRange.Select + If (PointsToCentimeters(Selection.Information(wdHorizontalPositionRelativeToTextBoundary)) < 0.1 Or _ + PointsToCentimeters(Selection.Information(wdHorizontalPositionRelativeToTextBoundary)) > 7.4) And _ + rFind.Comments.Count = 0 And rFind.Hyperlinks.Count = 0 And Not IsHeader(rFind) Then + Call rFind.Comments.Add(rFind, DANG_DASH) + CheckDashes = CheckDashes + 1 + End If +skp1: + Loop + End With + Call CSE_ProgressBar.IncrementB + + Set rFind = target.Range.Duplicate + With rFind.Find + .Text = Chr(150) + Do While .Execute + Set tempRange = rFind.Duplicate + Call tempRange.Collapse(wdCollapseStart) + Call tempRange.Select + If PointsToCentimeters(Selection.Information(wdHorizontalPositionRelativeToTextBoundary)) < 0.1 And _ + rFind.Comments.Count = 0 And rFind.Hyperlinks.Count = 0 And Not IsHeader(rFind) Then + Call rFind.Comments.Add(rFind, DANG_DASH) + CheckDashes = CheckDashes + 1 + GoTo skp2 + End If + + Set tempRange = rFind.Duplicate + Call tempRange.Collapse(wdCollapseEnd) + Call tempRange.Select + If (PointsToCentimeters(Selection.Information(wdHorizontalPositionRelativeToTextBoundary)) < 0.1 Or _ + PointsToCentimeters(Selection.Information(wdHorizontalPositionRelativeToTextBoundary)) > 7.4) And _ + rFind.Comments.Count = 0 And rFind.Hyperlinks.Count = 0 And Not IsHeader(rFind) Then + Call rFind.Comments.Add(rFind, DANG_DASH) + CheckDashes = CheckDashes + 1 + End If +skp2: + Loop + End With + Call CSE_ProgressBar.IncrementB + + Set rFind = target.Range.Duplicate + With rFind.Find + .Text = Chr(151) + Do While .Execute + Set tempRange = rFind.Duplicate + Call tempRange.Collapse(wdCollapseStart) + Call tempRange.Select + If PointsToCentimeters(Selection.Information(wdHorizontalPositionRelativeToTextBoundary)) < 0.1 And _ + rFind.Comments.Count = 0 And rFind.Hyperlinks.Count = 0 And Not IsHeader(rFind) Then + Call rFind.Comments.Add(rFind, DANG_DASH) + CheckDashes = CheckDashes + 1 + GoTo skp3 + End If + + Set tempRange = rFind.Duplicate + Call tempRange.Collapse(wdCollapseEnd) + Call tempRange.Select + If (PointsToCentimeters(Selection.Information(wdHorizontalPositionRelativeToTextBoundary)) < 0.1 Or _ + PointsToCentimeters(Selection.Information(wdHorizontalPositionRelativeToTextBoundary)) > 7.4) And _ + rFind.Comments.Count = 0 And rFind.Hyperlinks.Count = 0 And Not IsHeader(rFind) Then + Call rFind.Comments.Add(rFind, DANG_DASH) + CheckDashes = CheckDashes + 1 + End If +skp3: + Loop + End With + Call CSE_ProgressBar.IncrementB + Call CSE_ProgressBar.HideSecondBar + Call CSE_ProgressBar.IncrementA +End Function + +Private Function CheckFields(target As Word.Document) As Long + Dim tmp As Boolean: tmp = target.TrackRevisions + target.TrackRevisions = False + + CSE_ProgressBar.Header = " ..." + Call CSE_ProgressBar.InitSecondBar(0, target.Fields.Count) + + Dim aField As Word.Field + For Each aField In target.Fields + If aField.Update = False Then + If aField.result.Font.Hidden = False Then + CheckFields = CheckFields + 1 + Call aField.result.Comments.Add(aField.result, DANG_FLD) + End If + End If + Call CSE_ProgressBar.IncrementB + Next aField + + Call CSE_ProgressBar.HideSecondBar + Call CSE_ProgressBar.IncrementA + + target.TrackRevisions = tmp +End Function diff --git a/src/CD_AutoDesign.bas b/src/CD_AutoDesign.bas new file mode 100644 index 0000000..dbef59c --- /dev/null +++ b/src/CD_AutoDesign.bas @@ -0,0 +1,691 @@ +Attribute VB_Name = "CD_AutoDesign" +Option Private Module +Option Explicit + +Private Const HEADS_UNQ_PREF = " _MKT_DLT_HEAD_" +Private Const LISTS_STARTS = " _MKT_DLT_LIST_" + +Private Const TABLE_WIDTH_LIMIT As Double = 8 +Private Const TABLE_HEADER_STYLE = " " + +Private Const STYLE_CONTRACT = "_ " +Private Const STYLE_THEME = "_ " +Private Const STYLE_REQUIREMENTS = "_ " + +Public Function RunAutoDesign(prefs As AutoDesignOptions) + Dim source As Word.Document: Set source = ActiveDocument + + Call CSE_ProgressBar.Init(" ", maxVal:=11 + prefs.Count) + Call CSE_ProgressBar.ShowModeless + + Dim proxyCount&: proxyCount = ADS_PrepareSource(source) + Dim target As Word.Document: Set target = ADS_CreateTarget + + Dim chapters As Collection: Set chapters = ADS_GenerateSections(target, source) + Dim listStyles As Collection: Set listStyles = ADS_FillSections(target, source, chapters) + + Call ADS_SetPageSettings(target) + + If prefs.fixObjects Then _ + Call ADS_TablesAndInlines(target) + If prefs.reapplyLists Then _ + Call ADS_ReapplyStyles(target, listStyles) + + Call ADS_FormatHeaders(target, source, proxyCount) + + If prefs.titlePage Then _ + Call ADS_TitlePage(target, source) + If prefs.generateColontitles Then _ + Call ADS_Colontitles(target) + + If prefs.doLayout Then _ + Call ADS_TextLayout(target) + + Call ADS_UpdateToc(target) + Call ADS_Paint(target) + + Call ADS_Finalize(target) + + Unload CSE_ProgressBar +End Function + +' ============== +Private Function ADS_UpdateToc(target As Word.Document) + CSE_ProgressBar.Header = " ..." + Dim toc As Word.TableOfContents + For Each toc In target.TablesOfContents + Call UpdateTableOfContents(toc) + Next toc + Call CSE_ProgressBar.IncrementA +End Function + +Private Function ADS_Paint(target As Word.Document) + Call RepaintText(target) + Call CSE_ProgressBar.IncrementA + + Call RepaintTextShapes(target) + Call CSE_ProgressBar.IncrementA + + Call RepaintToC(target) + Call CSE_ProgressBar.IncrementA + + Call RepaintHLinks(target) + Call CSE_ProgressBar.IncrementA +End Function + +Private Function ADS_PrepareSource(source As Word.Document) As Long + CSE_ProgressBar.Header = " ..." + ADS_PrepareSource = MarkListItems(source) + Call MarkListsBegin(source) + Call CSE_ProgressBar.IncrementA +End Function + +Private Function ADS_CreateTarget() As Word.Document + CSE_ProgressBar.Header = " ..." + + Dim wrapper As New API_WordWrapper + Dim target As Word.Document: Set target = wrapper.NewDocument("20 ", False) + target.AttachedTemplate = "" + target.UpdateStylesOnOpen = False + + Call RemoveSampleSections(target) + + Set ADS_CreateTarget = target + Call CSE_ProgressBar.IncrementA +End Function + +Private Function ADS_GenerateSections(target As Word.Document, source As Word.Document) As Collection + CSE_ProgressBar.Header = " ..." + Dim chapters As Collection: Set chapters = ScanChaptersInfo(source) + Dim intro As Word.Range: Set intro = target.Range(target.Sections(4).Range.Start, target.Sections(6).Range.End) + Call CopyPasteRepeat(intro, target.Sections(7).Range.Start, target, chapters.Count - 1) + + Call TransferChapterHeaders(chapters, target) + + Call CSE_ProgressBar.IncrementA + Set ADS_GenerateSections = chapters +End Function + +Private Function ADS_FillSections(target As Word.Document, source As Word.Document, chapters As Collection) As Collection + CSE_ProgressBar.Header = " ..." + + Dim listStyles As New Collection + Dim aStyle As Word.Style + For Each aStyle In source.Styles + Dim sLocal$: sLocal = aStyle.NameLocal + If WordStyleExists(target, sLocal) Then + If CheckListStyle(target.Styles(sLocal)) Then + Call listStyles.Add(sLocal) + End If + End If + Next aStyle + + Call TransferChapersBody(chapters, source, target) + + Call CSE_ProgressBar.IncrementA + Set ADS_FillSections = listStyles +End Function + +Private Function ADS_SetPageSettings(target As Word.Document) + CSE_ProgressBar.Header = " ..." + Call CSE_ProgressBar.InitSecondBar(0, target.Sections.Count - 3) + Dim i& + For i = 3 To target.Sections.Count - 1 + With target.Sections(i).PageSetup + .LeftMargin = CentimetersToPoints(FIELD_SIZE_CM) + .RightMargin = CentimetersToPoints(FIELD_SIZE_CM) + .TopMargin = CentimetersToPoints(FIELD_SIZE_CM) + .BottomMargin = CentimetersToPoints(FIELD_SIZE_CM) + + .DifferentFirstPageHeaderFooter = False + .HeaderDistance = CentimetersToPoints(1.25) + .FooterDistance = CentimetersToPoints(1.25) + .OddAndEvenPagesHeaderFooter = False + End With + Call CSE_ProgressBar.IncrementB + Next i + + target.Footnotes.Location = wdBeneathText + + Call CSE_ProgressBar.IncrementA + Call CSE_ProgressBar.HideSecondBar +End Function + +Private Function ADS_TablesAndInlines(target As Word.Document) + CSE_ProgressBar.Header = " ..." + Call CSE_ProgressBar.InitSecondBar(0, target.InlineShapes.Count + target.Tables.Count) + + Dim iShp As Word.InlineShape + For Each iShp In target.InlineShapes + Dim rShape As Word.Range: Set rShape = iShp.Range + If rShape.PageSetup.TextColumns.Count > 1 Then + If rShape.Paragraphs(1).Next.Range.Style = " " Then + Call rShape.MoveEnd(wdParagraph, 2) + Call InsertOneColomnSection(rShape) + End If + End If + + Call CSE_ProgressBar.IncrementB + Next iShp + + Dim aTable As Word.Table + For Each aTable In target.Tables + Dim rTable As Word.Range: Set rTable = aTable.Range + aTable.PreferredWidthType = wdPreferredWidthPoints + If rTable.PageSetup.TextColumns.Count > 1 And aTable.PreferredWidth >= CentimetersToPoints(TABLE_WIDTH_LIMIT) Then + aTable.PreferredWidthType = wdPreferredWidthPercent + aTable.PreferredWidth = 100 + If rTable.Paragraphs(1).Previous.Range.Style = TABLE_HEADER_STYLE Then + Call rTable.MoveStart(wdParagraph, -1) + Call InsertOneColomnSection(rTable) + End If + End If + + Call CSE_ProgressBar.IncrementB + Next aTable + + Call CSE_ProgressBar.IncrementA + Call CSE_ProgressBar.HideSecondBar +End Function + +Private Function ADS_ReapplyStyles(target As Word.Document, listStyles As Collection) + CSE_ProgressBar.Header = " ..." + + Call CSE_ProgressBar.InitSecondBar(0, listStyles.Count) + Dim aStyle As Variant + For Each aStyle In listStyles + Call ReApplyStyle(target, CStr(aStyle)) + Call CSE_ProgressBar.IncrementB + Next aStyle + + Call CSE_ProgressBar.IncrementA + Call CSE_ProgressBar.HideSecondBar +End Function + +Private Function ADS_FormatHeaders(target As Word.Document, source As Word.Document, proxyCount&) + CSE_ProgressBar.Header = " ..." + + Call FinalizeLists(source, True) + Call FinalizeLists(target, False) + + Call FixGapsStyle(target) + Call TransferHeaderFormats(target, source) + + Call RemoveListPoxy(source, proxyCount) + Call RemoveListPoxy(target, proxyCount) + + Call CSE_ProgressBar.IncrementA +End Function + +Private Function ADS_TitlePage(target As Word.Document, source As Word.Document) + CSE_ProgressBar.Header = " ..." + Call TransferTitlePage(source, target) + Call TransferWorkerList(source, target) + Call TransferRequirements(source, target) + Call CSE_ProgressBar.IncrementA +End Function + +Private Function ADS_TextLayout(target As Word.Document) + CSE_ProgressBar.Header = "..." + Call UpdateListsLayout(target) + Call UpdateTextLayout(target) + Call UpdateObjectFields(target) + Call CSE_ProgressBar.IncrementA +End Function + +Private Function ADS_Colontitles(target As Word.Document) + CSE_ProgressBar.Header = " ..." + + Dim docData As New InfoDocument: Call docData.Init(target) + Dim iColons As New ItemColontitles + With iColons + .mTopLeft = T_SOURCE_VOLUME + .mTopRight = T_SOURCE_BOOK + .mBottomLeft = T_SOURCE_CONCEPT + .mBottomRight = T_SOURCE_SECTION + .start_ = 3 + .finish_ = target.Sections.Count - 1 + + .doBottomRight = True + .doTopLeft = docData.IsValidNames + .doTopRight = .doTopLeft + End With + + Call CSE_ProgressBar.InitSecondBar(0, iColons.finish_ - iColons.start_ + 1) + Call CreateColontitles(target, docData, iColons, "IncrementB") + Call CSE_ProgressBar.HideSecondBar + Call CSE_ProgressBar.IncrementA +End Function + +Private Function ADS_Finalize(target As Word.Document) + CSE_ProgressBar.Header = "..." + Dim i% + For i = 3 To target.Sections.Count - 1 + With target.Sections(i) + Dim iComment As Word.Range: Set iComment = target.Range(.Range.Start, .Range.Start) + If .PageSetup.Orientation = wdOrientLandscape Then _ + Call iComment.Comments.Add(iComment, " ?") + End With + Next i + Call CSE_ProgressBar.IncrementA +End Function + +Private Function RemoveSampleSections(target As Word.Document) + Do While target.Sections.Count > 7 + Call target.Sections(target.Sections.Count - 1).Range.Delete + Loop +End Function + +Private Function FinalizeLists(target As Word.Document, justClear As Boolean) + Dim rFind As Word.Range: Set rFind = target.Range + rFind.Find.Text = LISTS_STARTS + Do While rFind.Find.Execute + Call rFind.MoveEnd(wdCharacter, 4) + Dim aTemplate As Word.ListTemplate: Set aTemplate = rFind.ListFormat.ListTemplate + aTemplate.ListLevels(1).StartAt = CLng(Right(rFind.Text, 4)) + If Not justClear Then + Call rFind.ListFormat.ApplyListTemplate(ListTemplate:=aTemplate, _ + ContinuePreviousList:=False, _ + ApplyTo:=wdListApplyToWholeList, _ + DefaultListBehavior:=wdWord10ListBehavior) + End If + rFind.Delete + Loop +End Function + +Private Function MarkListsBegin(target As Word.Document) + Dim tmpLst As Word.List, tmpLstRange As Word.Range + For Each tmpLst In target.Lists + If IsHeader(tmpLst.ListParagraphs(1).Range) Then _ + GoTo CONT_FOR + Set tmpLstRange = tmpLst.ListParagraphs(1).Range + + Call tmpLstRange.MoveEndUntil(Chr(13), wdBackward) + Call tmpLstRange.MoveEnd(wdCharacter, -1) + + If Right(tmpLstRange.ListFormat.ListString, 2) Like "#?" Then + Call tmpLstRange.InsertAfter(LISTS_STARTS & Format(tmpLstRange.ListFormat.ListValue, "0000")) + End If +CONT_FOR: + Next tmpLst +End Function + +Private Function MarkListItems(target As Word.Document) As Long + Dim hdNames As New Collection + Dim listItem As Word.Paragraph + For Each listItem In target.ListParagraphs + Dim tmpRng As Word.Range: Set tmpRng = listItem.Range + If Not InCollection(tmpRng.Text, hdNames) Then + Call hdNames.Add(tmpRng.Text, tmpRng.Text) + GoTo NEXT_ITEM + End If + + MarkListItems = MarkListItems + 1 + Call tmpRng.MoveEnd(wdCharacter, -1) + Dim sMark$: sMark = HEADS_UNQ_PREF & CStr(MarkListItems) + Call tmpRng.InsertAfter(sMark) + Call tmpRng.MoveEnd(wdCharacter, 1) +NEXT_ITEM: + Next listItem +End Function + +Private Function RemoveListPoxy(target As Word.Document, proxyCount&) + Dim nProxy& + For nProxy = 1 To proxyCount Step 1 + Dim rFind As Word.Range: Set rFind = target.Range + With rFind.Find + .ClearFormatting + .Text = "<" & Mid(HEADS_UNQ_PREF & nProxy, 3) & ">" + .MatchWildcards = True + + If .Execute Then + Call rFind.MoveStart(wdCharacter, -2) + rFind.Delete + End If + End With + Next nProxy +End Function + +Private Function CheckListStyle(target As Word.Style) As Boolean + CheckListStyle = Not target.NameLocal Like "[]*" + CheckListStyle = CheckListStyle And _ + (target.NameLocal Like "*[][]*" Or target.NameLocal Like "*[]*") +End Function + +Private Function TransferWorkerList(source As Word.Document, dest As Word.Document) + source.Sections(3).Range.Tables(1).Range.Copy + Dim insertPosition&: insertPosition = dest.Sections(2).Range.Tables(1).Range.Start + Call dest.Sections(2).Range.Tables(1).Delete + Call dest.Range(insertPosition&, insertPosition&).PasteAndFormat(wdUseDestinationStylesRecovery) +End Function + +Private Function TransferRequirements(source As Word.Document, dest As Word.Document) + If RequirementsPosition(source) = 0 Then _ + Exit Function + If RequirementsPosition(dest) = 0 Then _ + Exit Function + + Call source.Tables(source.Tables.Count).Range.Copy + Call dest.Tables(dest.Tables.Count).Delete + Call dest.Paragraphs.Last.Range.Paste +End Function + +Private Function TransferChapterHeaders(chapters As Collection, doc As Word.Document) + Call CSE_ProgressBar.InitSecondBar(0, chapters.Count) + + Dim ColorIndex&: ColorIndex = 0 + Dim i&, j&: j = 4 + For i = 1 To chapters.Count + Dim headerText$: headerText$ = chapters(i).text_ + headerText = Left(headerText$, Len(headerText$) - 1) + + Dim rPaste As Word.Range: Set rPaste = doc.Sections(j).Range.Duplicate + Call rPaste.MoveEnd(wdWord, -2) + rPaste.Text = headerText$ + + Dim clrID As WdThemeColorIndex + Select Case (i - 1 - ColorIndex) Mod 7 + Case 0 To 4: clrID = (i - 1 - ColorIndex) Mod 7 + 5 + Case 5: clrID = wdThemeColorBackground2 + Case 6: clrID = wdThemeColorText2 + End Select + + If InStr(UCase(headerText), "") + InStr(UCase(headerText), "") <> 0 Then + clrID = wdThemeColorAccent1 + ColorIndex = ColorIndex + 1 + End If + rPaste.Paragraphs.First.Range.Font.Color = DesignTheme(clrID) + j = j + 3 + + Call CSE_ProgressBar.IncrementB + Next i + + Call CSE_ProgressBar.HideSecondBar +End Function + +Private Function ReApplyStyle(target As Word.Document, aStyle$) + If Not WordStyleExists(target, aStyle) Then _ + Exit Function + + Dim rFind As Word.Range: Set rFind = target.Range + Dim lastEnd& + rFind.Find.Style = target.Styles(aStyle) + Do While rFind.Find.Execute + Dim resetRange As Word.Range: Set resetRange = rFind.Duplicate + resetRange.Start = IIf(Len(rFind) < 2, rFind.Start, rFind.End - 1) + resetRange.End = IIf(Len(rFind) < 2, rFind.End, rFind.End - 1) + resetRange.Style = target.Styles(aStyle) + + Call rFind.Collapse(wdCollapseEnd) + If rFind.Start >= target.Range.End - 1 Then _ + Exit Function + If rFind.Start = lastEnd Then _ + Call rFind.Move(wdCharacter, 1) + + lastEnd = rFind.End + Loop +End Function + +Private Function ScanChaptersInfo(target As Word.Document) As Collection + Dim result As New Collection + Dim para As Word.Paragraph + For Each para In target.Paragraphs + If IsHeader(para.Range, 1) Then + Dim info As New ItemChapter + info.start_ = para.Range.Start + info.finish_ = para.Range.End + + Dim lstStrng$: lstStrng = "" + If para.Range.ListParagraphs.Count <> 0 Then _ + lstStrng = para.Range.ListFormat.ListString + + info.text_ = lstStrng & _ + IIf(Left(para.Range, 1) = " ", "", _ + IIf(lstStrng = "", "", " ")) & para.Range + Call result.Add(info.Clone) + End If + Next para + Set ScanChaptersInfo = result +End Function + +Private Function TransferChapersBody(chapters As Collection, source As Word.Document, dest As Word.Document) + Call CSE_ProgressBar.InitSecondBar(0, chapters.Count) + + Dim aChapter As ItemChapter: Set aChapter = chapters(chapters.Count) + Dim lastFinish&: lastFinish = RequirementsPosition(source) + If aChapter.finish_ <= lastFinish Then + Call source.Range(aChapter.finish_, lastFinish).Copy + Call dest.Range(dest.Sections(chapters.Count * 3 + 2).Range.Start, dest.Sections(chapters.Count * 3 + 2).Range.Start).Paste + End If + Call CSE_ProgressBar.IncrementB + + Dim i& + For i = chapters.Count - 1 To 1 Step -1 + If chapters(i).finish_ <> chapters(i + 1).start_ Then + Call source.Range(chapters(i).finish_, chapters(i + 1).start_).Copy + Call dest.Range(dest.Sections(i * 3 + 2).Range.Start, dest.Sections(i * 3 + 2).Range.Start).Paste + End If + Call CSE_ProgressBar.IncrementB + Next i + + Call CSE_ProgressBar.HideSecondBar +End Function + +Private Function TransferHeaderFormats(target As Word.Document, source As Word.Document) + Call CSE_ProgressBar.InitSecondBar(0, target.ListParagraphs.Count) + + Dim listPrefixes As New Collection: Set listPrefixes = ExtractListPrefixes(source) + + Dim pCurrent As Word.Paragraph + For Each pCurrent In target.ListParagraphs + Dim rCurrent As Word.Range: Set rCurrent = pCurrent.Range + If rCurrent.ParagraphFormat.OutlineLevel <> wdOutlineLevelBodyText Then + Dim sPrefix$: sPrefix = listPrefixes(rCurrent.Text) + Dim sHeaderText$: sHeaderText = RemoveListPrefix(rCurrent.Text) + Call InsertHeader(rCurrent, sPrefix & " " & sHeaderText, rCurrent.ListFormat.ListLevelNumber) + End If + + Call CSE_ProgressBar.IncrementB + Next pCurrent + + For Each pCurrent In target.ListParagraphs + If pCurrent.Range.ParagraphFormat.OutlineLevel <> wdOutlineLevelBodyText Then _ + Call pCurrent.Range.Delete + Next pCurrent + + Call CSE_ProgressBar.HideSecondBar +End Function + +Private Function TransferTitlePage(source As Word.Document, target As Word.Document) + Dim titleData As TitlePageData: titleData = ExtractTitlePageData(source) + + Call TransferBook(target, titleData) + Call TransferVolume(target, titleData) + + If Not titleData.rContract Is Nothing Then _ + Call TransferContract(target, titleData.rContract) + If Not titleData.rCustomer Is Nothing Then _ + Call TransferCustomer(target, titleData.rCustomer) + If Not titleData.rTheme Is Nothing Then _ + Call TransferTheme(target, titleData.rTheme) +End Function + +Private Function CopyPasteRepeat(target As Word.Range, nPos&, doc As Word.Document, nCount&) + Call target.Copy + Dim i& + For i = 1 To nCount + Call doc.Range(nPos, nPos).PasteAndFormat(wdFormatOriginalFormatting) + Next i +End Function + +Private Function ExtractListPrefixes(target As Word.Document) As Collection + Dim result As New Collection + Dim listItem As Word.Paragraph + For Each listItem In target.ListParagraphs + If listItem.Range.ParagraphFormat.OutlineLevel <> wdOutlineLevelBodyText Then + Call result.Add(listItem.Range.ListFormat.ListString, listItem.Range.Text) + End If + Next listItem + Set ExtractListPrefixes = result +End Function + +Private Function RemoveListPrefix(listText$) As String + Dim result$: result = listText + Do While Asc(Right(result, 1)) <= 32 + result = Left(result, Len(result) - 1) + Loop + RemoveListPrefix = result +End Function + +Private Function RequirementsPosition(target As Word.Document) As Long + RequirementsPosition = target.Range.End + Dim rFind As Word.Range: Set rFind = target.Range + With rFind.Find + .Text = " " + .Style = STYLE_REQUIREMENTS + If Not .Execute Then _ + Exit Function + End With + RequirementsPosition = rFind.Start +End Function + +Private Function ExtractTitlePageData(target As Word.Document) As TitlePageData + Dim result As TitlePageData + + Dim rFind As Word.Range + Set rFind = target.Sections(2).Range + rFind.Find.Text = " " + rFind.Find.MatchCase = False + If rFind.Find.Execute Then + Set rFind = rFind.Next(wdWord, 1) + result.nBookID = CLng(rFind.Text) + + Call rFind.MoveEndUntil(CSET_SLETTERS & CSET_BLETTERS, wdForward) + Call rFind.Collapse(wdCollapseEnd) + Call rFind.MoveEndUntil(Chr(13), wdForward) + result.sBook = rFind.Text + End If + + Set rFind = target.Sections(2).Range + rFind.Find.Text = " " + rFind.Find.MatchCase = False + If rFind.Find.Execute Then + Set rFind = rFind.Next(wdWord, 1) + result.nVolumeID = CLng(rFind.Text) + + Call rFind.MoveEndUntil(CSET_SLETTERS & CSET_BLETTERS, wdForward) + Call rFind.Collapse(wdCollapseEnd) + Call rFind.MoveEndUntil(Chr(13)) + result.sVolume = rFind.Text + End If + + Set rFind = target.Sections(2).Range + rFind.Find.Text = " " + rFind.Find.Style = STYLE_CONTRACT + rFind.Find.Format = True + If rFind.Find.Execute Then + Set result.rContract = rFind.Paragraphs.First.Range.Duplicate + End If + + Set rFind = target.Sections(2).Range + rFind.Find.Text = ": " + rFind.Find.Style = STYLE_CONTRACT + rFind.Find.Format = True + If rFind.Find.Execute Then + Set result.rCustomer = rFind.Paragraphs.First.Range.Duplicate + End If + + Set rFind = target.Sections(2).Range + rFind.Find.Style = STYLE_THEME + rFind.Find.Format = True + If rFind.Find.Execute Then + Set result.rTheme = rFind.Paragraphs.First.Range.Duplicate + End If + + ExtractTitlePageData = result +End Function + +Private Function TransferBook(target As Word.Document, titleData As TitlePageData) + Dim rPaste As Word.Range: Set rPaste = target.Sections(1).Range + With rPaste.Find + .Text = " " + .Format = True + .MatchCase = False + End With + + If Not rPaste.Find.Execute Then _ + Exit Function + Set rPaste = rPaste.Next(wdWord, 1) + If titleData.nBookID <> 0 Then _ + rPaste.Text = titleData.nBookID + + If titleData.sBook = "" Then _ + Exit Function + Call rPaste.MoveEndUntil(CSET_SLETTERS & CSET_BLETTERS, wdForward) + Call rPaste.Collapse(wdCollapseEnd) + Call rPaste.MoveEndUntil(Chr(13), wdForward) + rPaste.Text = titleData.sBook +End Function + +Private Function TransferVolume(target As Word.Document, titleData As TitlePageData) + Dim rPaste As Word.Range: Set rPaste = target.Sections(1).Range + With rPaste.Find + .Text = " " + .Format = True + .MatchCase = False + End With + If Not rPaste.Find.Execute Then _ + Exit Function + + Set rPaste = rPaste.Next(wdWord, 1) + If titleData.nVolumeID <> 0 Then _ + rPaste.Text = titleData.nVolumeID + + If titleData.sVolume = "" Then _ + Exit Function + Call rPaste.MoveEndUntil(CSET_SLETTERS & CSET_BLETTERS, wdForward) + Call rPaste.Collapse(wdCollapseEnd) + Call rPaste.MoveEndUntil(Chr(13), wdForward) + rPaste.Text = titleData.sVolume +End Function + +Private Function TransferContract(target As Word.Document, rContract As Word.Range) + Dim rPaste As Word.Range: Set rPaste = target.Sections(1).Range + With rPaste.Find + .Text = " " + .Format = True + .Style = STYLE_CONTRACT + End With + If Not rPaste.Find.Execute Then _ + Exit Function + + Call rContract.Copy + Call rPaste.Paragraphs.First.Range.PasteAndFormat(wdUseDestinationStylesRecovery) +End Function + +Private Function TransferCustomer(target As Word.Document, rCustomer As Word.Range) + Dim rPaste As Word.Range: Set rPaste = target.Sections(1).Range + With rPaste.Find + .Text = " " + .Format = True + .Style = STYLE_CONTRACT + End With + If Not rPaste.Find.Execute Then _ + Exit Function + + Call rCustomer.Copy + Call rPaste.Paragraphs.First.Range.PasteAndFormat(wdUseDestinationStylesRecovery) +End Function + +Private Function TransferTheme(target As Word.Document, rTheme As Word.Range) + Dim rPaste As Word.Range: Set rPaste = target.Sections(1).Range + With rPaste.Find + .Format = True + .Style = STYLE_THEME + End With + If Not rPaste.Find.Execute Then _ + Exit Function + + Call rTheme.Copy + Call rPaste.Paragraphs.First.Range.PasteAndFormat(wdUseDestinationStylesRecovery) +End Function diff --git a/src/CD_Colontitles.bas b/src/CD_Colontitles.bas new file mode 100644 index 0000000..ffe1f72 --- /dev/null +++ b/src/CD_Colontitles.bas @@ -0,0 +1,270 @@ +Attribute VB_Name = "CD_Colontitles" +Option Private Module +Option Explicit + +Public Function CreateColontitles(target As Word.Document, docMeta As InfoDocument, _ + props As ItemColontitles, incrementCallback$) + Dim sPrevious$ + Dim nCurrent&: nCurrent = props.start_ + Do While nCurrent <= props.finish_ + Dim aSection As Word.Section: Set aSection = target.Sections(nCurrent) + Dim headRange As Word.Range: Set headRange = aSection.Range.Paragraphs.First.Range + If Not (IsHeader(headRange, 1) Or IsToCHeader(headRange)) Or VBA.Len(headRange.Text) <= 3 Then + Call ResetSection(aSection) + GoTo NEXT_SECTION + End If + + Call ProcessSection(aSection, docMeta, props, sPrevious, nCurrent = props.start_) + +NEXT_SECTION: + nCurrent = nCurrent + 1 + Call CallByName(CSE_ProgressBar, incrementCallback, VbMethod) + Loop +End Function + +' ============ +Private Function ResetSection(aSection As Word.Section) + aSection.PageSetup.DifferentFirstPageHeaderFooter = False + aSection.PageSetup.OddAndEvenPagesHeaderFooter = True + aSection.Headers(wdHeaderFooterPrimary).LinkToPrevious = True + aSection.Headers(wdHeaderFooterEvenPages).LinkToPrevious = True + aSection.Footers(wdHeaderFooterPrimary).LinkToPrevious = True + aSection.Footers(wdHeaderFooterEvenPages).LinkToPrevious = True +End Function + +Private Function ScanSection(target As Word.Section, ByRef sPrevious$) As SectionData + Dim aData As SectionData + + Dim headRange As Word.Range: Set headRange = target.Range.Paragraphs.First.Range + If headRange.Style = " " Then + Call headRange.MoveEnd(wdWord, -1) + aData.sChapter = headRange.Text + Else + aData.sName = headRange.Text + If IsUsualSecName(aData.sName, headRange) Then _ + aData.sName = " " & aData.sName + If IsToCHeader(aData.sName) Then _ + aData.sChapter = aData.sName + End If + + aData.bNewChapter = aData.sChapter = sPrevious And Not sPrevious = "" + sPrevious = aData.sChapter + ScanSection = aData +End Function + +Private Function ProcessSection(target As Word.Section, docMeta As InfoDocument, props As ItemColontitles, ByRef sPrevious$, bFrist As Boolean) + Dim sData As SectionData: sData = ScanSection(target, sPrevious) + Dim cPos As ColontitlePosition + + If props.doTopLeft Then + cPos.top_ = True + cPos.left_ = True + cPos.source_ = props.mTopLeft + Call ProcessTitle(target, docMeta, cPos, sData, Not bFrist And DoLink(cPos.source_, sData.bNewChapter)) + End If + + If props.doTopRight Then + cPos.top_ = True + cPos.left_ = False + cPos.source_ = props.mTopRight + Call ProcessTitle(target, docMeta, cPos, sData, Not bFrist And DoLink(cPos.source_, sData.bNewChapter)) + End If + + If props.doBottomLeft Then + cPos.top_ = False + cPos.left_ = True + cPos.source_ = props.mBottomLeft + Call ProcessTitle(target, docMeta, cPos, sData, Not bFrist And DoLink(cPos.source_, sData.bNewChapter)) + End If + + If props.doBottomRight Then + cPos.top_ = False + cPos.left_ = False + cPos.source_ = props.mBottomRight + Call ProcessTitle(target, docMeta, cPos, sData, Not bFrist And DoLink(cPos.source_, sData.bNewChapter)) + End If +End Function + +Private Function ProcessTitle(target As Word.Section, docMeta As InfoDocument, cPos As ColontitlePosition, sData As SectionData, linkToPrev As Boolean) + Dim oTitle As Word.HeaderFooter: Set oTitle = GetHeader(target, cPos) + oTitle.LinkToPrevious = linkToPrev + If linkToPrev Then _ + Exit Function + + Call ReplaceColontitle(oTitle, cPos, TitlesText(cPos.source_, sData, docMeta)) +End Function + +Private Function TitlesText(sMode As TSource, sData As SectionData, docMeta As InfoDocument) As String + Select Case sMode: + Case T_SOURCE_BOOK: TitlesText = docMeta.BookText + Case T_SOURCE_VOLUME: TitlesText = docMeta.VolumeText + Case T_SOURCE_DOCUMENT: TitlesText = docMeta.document_ + Case T_SOURCE_SECTION: TitlesText = sData.sName + Case T_SOURCE_CHAPTER: TitlesText = sData.sChapter + Case T_SOURCE_CONCEPT: + TitlesText = " """"" & ", " & CStr(Year(Date)) + End Select +End Function + +Private Function ReplaceColontitle(target As Word.HeaderFooter, cPos As ColontitlePosition, sText$) + If cPos.top_ Then + Call InsertHeader(target.Range, sText, cPos) + If cPos.source_ <> T_SOURCE_DOCUMENT And cPos.source_ <> T_SOURCE_CONCEPT Then _ + Call BoldHeaderPart(target.Range) + Call HeadersWrap(target.Range) + Else + If cPos.source_ = T_SOURCE_SECTION And InStr(UCase(sText), UCase("")) = 0 Then _ + sText = Mid(sText, InStr(sText, ".") + 1) + Call InsertFooter(target.Range, sText, cPos) + End If +End Function + +Private Function BoldHeaderPart(target As Word.Range) + target.Bold = False + Dim boldPart As Word.Range: Set boldPart = target.Words.First + If boldPart.MoveEndUntil(".", wdForward) Then + boldPart.End = boldPart.End + 1 + boldPart.Bold = True + End If +End Function + +Private Function InsertHeader(target As Word.Range, sText$, cPos As ColontitlePosition) + target.Text = sText + target.Style = " " + Call target.Words.Last.Delete +End Function + +Private Function InsertFooter(target As Word.Range, sText$, cPos As ColontitlePosition) + Call CleanFooter(target, cPos) + + If Len(sText) >= 2 Then + If Asc(Left(sText, 1)) < 33 Then sText = Mid(sText, 2) + If Asc(Right(sText, 1)) < 33 Then sText = Left(sText, Len(sText) - 1) + End If + + Call target.InsertBefore(UCase(sText)) + If cPos.left_ Then + Call FormatLeftFooter(target) + Else + Call FormatRightFooter(target) + End If +End Function + +Private Function FormatRightFooter(target As Word.Range) + Dim rDest As Word.Range: Set rDest = target.Duplicate + Call rDest.MoveEnd(wdWord, -2) + + If Len(rDest.Text) < 30 Then + Call rDest.InsertBefore(Chr(11)) + Else + Dim rSecondLine As Word.Range: Set rSecondLine = rDest.Duplicate + Call rSecondLine.Collapse(wdCollapseEnd) + Do + Call rDest.MoveEnd(wdWord, -1) + Call rSecondLine.MoveStart(wdWord, -1) + Loop Until Len(rDest.Text) + 2 < Len(rSecondLine.Text) + + Call rSecondLine.InsertBefore(Chr(11)) + Call target.Words.Last.Delete + End If +End Function + +Private Function FormatLeftFooter(target As Word.Range) + Dim rDest As Word.Range: Set rDest = target.Duplicate + Call rDest.MoveEnd(wdWord, IIf(rDest.Fields.Count = 1, -2, -1)) + + Dim oldText$ + If Len(rDest.Text) < 30 Then + oldText = rDest.Text + Call rDest.Delete + + Call target.InsertBefore(Chr(11)) + + Call target.InsertAfter(Chr(9)) + Call target.InsertAfter(oldText) + Call target.InsertBefore(Chr(9)) + rDest.End = target.End + rDest.Start = rDest.End + Call rDest.MoveStart(wdWord, -1) + Call rDest.Delete + Else + Dim rSecondLine As Word.Range: Set rSecondLine = rDest.Duplicate + Call rSecondLine.Collapse(wdCollapseEnd) + Do + Call rDest.MoveEnd(wdWord, -1) + Call rSecondLine.MoveStart(wdWord, -1) + Loop Until Len(rDest.Text) + 2 < Len(rSecondLine.Text) Or rDest.Text = " " + + Call target.InsertBefore(Chr(9)) + + oldText = rSecondLine.Text + Call rSecondLine.Delete + Call target.InsertAfter(Chr(9)) + Call target.InsertAfter(oldText) + Call rDest.InsertAfter(Chr(11)) + End If +End Function + +Private Function CleanFooter(target As Word.Range, cPos As ColontitlePosition) + target.Style = " " + + Dim hasField As Boolean: hasField = target.Fields.Count > 0 + If hasField Then + Call target.Fields(1).Cut + Call target.Delete + Call target.Paste + Else + Call target.Delete + End If + + If Not cPos.left_ And Not cPos.top_ Then _ + Call target.InsertBefore(Chr(9)) +End Function + +Private Function HeadersWrap(target As Word.Range) +' + Dim temprang1 As Word.Range, temprang2 As Word.Range + If Len(target.Text) < 70 Then + Call target.InsertBefore(Chr(11)) + Else + Set temprang2 = target.Duplicate + Set temprang1 = target.Duplicate + temprang1.End = temprang2.Start + Do + Call temprang2.MoveStart(wdWord, 1) + Call temprang1.MoveEnd(wdWord, 1) + Loop Until Len(temprang1.Text) > Len(temprang2.Text) + + Call temprang2.InsertBefore(Chr(11)) + End If +End Function + +Private Function GetHeader(target As Word.Section, cPos As ColontitlePosition) As Word.HeaderFooter + Dim colID As WdHeaderFooterIndex: colID = IIf(cPos.left_, wdHeaderFooterEvenPages, wdHeaderFooterPrimary) + If cPos.top_ Then + Set GetHeader = target.Headers(colID) + Else + Set GetHeader = target.Footers(colID) + End If +End Function + +Private Function DoLink(sMode As TSource, isNew As Boolean) As Boolean + DoLink = (sMode <> T_SOURCE_SECTION And sMode <> T_SOURCE_CHAPTER) Or (sMode = T_SOURCE_CHAPTER And isNew) +End Function + +Private Function IsUsualSecName(sName$, target As Word.Range) As Boolean + IsUsualSecName = Not (ContainsSubstr(target, "") + ContainsSubstr(target, "") _ + + ContainsSubstr(target, "") + IsToCHeader(sName)) +End Function + +Function ContainsSubstr(target As Word.Range, subText$) As Boolean + ContainsSubstr = False + If target.Words.Count < 2 Then _ + Exit Function + ContainsSubstr = InStr(UCase(target.Words.First), UCase(subText)) <> 0 +End Function + +Private Function IsToCHeader(ByVal secName$) As Boolean + secName = UCase(secName) + IsToCHeader = InStr(secName, "") + InStr(secName, "") +End Function diff --git a/src/CD_Layout.bas b/src/CD_Layout.bas new file mode 100644 index 0000000..048ae81 --- /dev/null +++ b/src/CD_Layout.bas @@ -0,0 +1,560 @@ +Attribute VB_Name = "CD_Layout" +Option Private Module +Option Explicit + +Public Function InsertOneColomnSection(target As Word.Range) + Dim nEnd&: nEnd = target.End + Call target.InsertBreak(wdSectionBreakContinuous) + Call target.Document.Range(nEnd + 1, nEnd + 1).InsertBreak(wdSectionBreakContinuous) + Call target.Sections(1).PageSetup.TextColumns.SetCount(1) +End Function + +Public Function InsertHeader(dest As Word.Range, headerName$, nLvl&) + Dim headerText$: headerText = Replace(headerName, Chr(11), " ") + headerText = Replace(headerText, " ", " ") + + Dim prefixPosition&: prefixPosition = 1 + Do While Not Mid(headerText, prefixPosition, 1) Like "[--a-zA-Z]" + prefixPosition = prefixPosition + 1 + Loop + + Dim headerPrefix$ + If prefixPosition > 1 Then headerPrefix = Left(headerText, prefixPosition - 2) + headerText = Right(headerText, Len(headerText) - prefixPosition + 1) + + Call dest.InsertAfter(headerText & vbNewLine) + Dim insRange As Word.Range: Set insRange = dest.Paragraphs.Last.Range + insRange.Font.Reset + insRange.Style = " " & Trim(Str(nLvl)) + insRange.Font.Color = GetSectionHeader(insRange.Start, dest.Document).Font.Color + + If prefixPosition = 1 Then _ + Exit Function + CreateEmptyField(insRange).TextFrame.TextRange.Text = headerPrefix +End Function + +Public Function InsertConceptSymbol(dest As Word.Range, symbol$) + If symbol = "" Then _ + Exit Function + + Dim txtShp As Word.Shape + Set txtShp = CreateEmptyField(dest) + With txtShp.TextFrame.TextRange + .Font.Spacing = 0 + .ParagraphFormat.LineSpacingRule = wdLineSpaceSingle + .Font.Size = CentimetersToPoints(1.08) + .Text = symbol + .Font.Color = GetSectionHeader(dest.Start, dest.Document).Font.Color + .Font.Name = "conceptpict" + End With + txtShp.TextFrame.AutoSize = True +End Function + +Public Function InsertNewPicture(sFile$, dest As Word.Range) + Dim tmpRange As Word.Range: Set tmpRange = dest.Application.Selection.Range + + Dim txtShp As Word.Shape: Set txtShp = CreateEmptyField(dest) + txtShp.TextFrame.TextRange.Select + Dim picShp As Word.InlineShape: Set picShp = Selection.InlineShapes.AddPicture(sFile) + If picShp Is Nothing Then + Call UserInteraction.ShowMessage(EM_CANNOT_INSERT_IMAGE) + Exit Function + End If + txtShp.TextFrame.TextRange.ParagraphFormat.LineSpacingRule = wdLineSpaceSingle + + picShp.LockAspectRatio = True + picShp.Width = CentimetersToPoints(1) + txtShp.TextFrame.AutoSize = True + + Dim sPictName$: sPictName = Replace(UserInteraction.PromptInput(" , :" & vbNewLine & "Pict_99"), " ", "_") + Dim sBookmark$: sBookmark = "pict_" & sPictName + + On Error GoTo INVALID_NAME +TRY_AGAIN: + Call dest.Document.Bookmarks.Add(sBookmark, txtShp.TextFrame.TextRange) + Call tmpRange.Select + Exit Function + +INVALID_NAME: + sBookmark = "pict_" & dest.Document.Bookmarks.Count + Call UserInteraction.ShowMessage(IM_FIX_BOOKMARK_NAME, sBookmark) + GoTo TRY_AGAIN +End Function + +Public Function InsertPictureRef(dest As Word.Range, bookmarkID$) + Dim txtShp As Word.Shape: Set txtShp = CreateEmptyField(dest) + With txtShp + With .TextFrame.TextRange + .ParagraphFormat.LineSpacingRule = wdLineSpaceSingle + Call .Fields.Add(txtShp.TextFrame.TextRange, Text:="REF " & bookmarkID) + End With + .TextFrame.AutoSize = True + End With +End Function + +Public Function InsertTextField(dest As Word.Range, insText$) + Call dest.Collapse(wdCollapseStart) + Call dest.MoveEnd(wdCharacter, 1) + CreateEmptyField(dest).TextFrame.TextRange.Text = insText +End Function + +Public Function InlineAsPNG(target As Word.InlineShape) + Dim isVisio As Boolean: isVisio = False + Dim prevW As Double: prevW = 0 + If Not target.OLEFormat Is Nothing Then + If InStr(UCase(target.OLEFormat.ClassType), "VISIO") <> 0 Then + isVisio = True + prevW = target.Width + + Dim formFactor As Double: formFactor = target.Height / target.Width + target.LockAspectRatio = msoFalse + target.Width = CentimetersToPoints(20) + target.Height = target.Width * formFactor + End If + End If + + Dim dest As Word.Range: Set dest = target.Range.Duplicate + target.Select + target.Application.Selection.Cut + With dest + Call .Collapse(wdCollapseEnd) + Call .PasteSpecial(Placement:=wdInLine, DataType:=IIf(isVisio, wdPasteEnhancedMetafile, 14)) + If isVisio Then + Call .MoveStart(wdCharacter, -1) + If .InlineShapes(1).Width < prevW Then + .InlineShapes(1).LockAspectRatio = msoTrue + .InlineShapes(1).Width = prevW + Call InlineAsPNG(.InlineShapes(1)) + Else + Call InlineAsPNG(.InlineShapes(1)) + Call .MoveEnd(wdCharacter, 1) + .InlineShapes(1).LockAspectRatio = msoTrue + .InlineShapes(1).Width = prevW + End If + End If + End With +End Function + +Public Function UpdateListsLayout(target As Word.Document) + Call CSE_ProgressBar.InitSecondBar(0, target.ListParagraphs.Count) + + Dim aParagraph As Word.Paragraph + For Each aParagraph In target.ListParagraphs + If aParagraph.Range = target.Paragraphs.Last.Range Then _ + GoTo NEXT_LIST + If aParagraph.Range.Tables.Count > 0 Then _ + GoTo NEXT_LIST + + Dim rNext As Word.Range: Set rNext = aParagraph.Next.Range + If InStr(rNext.Text, Chr(12)) Or InStr(rNext.Text, Chr(14)) Then _ + GoTo NEXT_LIST + If rNext.ListParagraphs.Count <> 0 Then _ + GoTo NEXT_LIST + + Dim rCurrent As Word.Range: Set rCurrent = aParagraph.Range + With rCurrent.ParagraphFormat + .SpaceAfter = .SpaceAfter - (Int(.SpaceAfter / .LineSpacing) - 1) * .LineSpacing + End With + +NEXT_LIST: + Call CSE_ProgressBar.IncrementB + Next aParagraph + Call CSE_ProgressBar.HideSecondBar +End Function + +Public Function UpdateTextLayout(target As Word.Document) + Call FixGapsStyle(target) + + Call CSE_ProgressBar.InitSecondBar(0, target.Range.End) + + Dim aRange As Word.Range: Set aRange = target.Paragraphs.First.Range + Do While Not aRange Is Nothing + If NeedsAlignment(aRange) Then + Dim firstOnPage As Boolean: firstOnPage = IsFirstInColumn(aRange) + Dim Headers As HeaderBlock: Headers = FixHeaderBlockSpacing(aRange, firstOnPage) + Set aRange = Headers.finishRng + Else + Set aRange = aRange.Next(wdParagraph, 1) + End If + If Not aRange Is Nothing Then _ + Call CSE_ProgressBar.SetB(aRange.End) + Loop + + Call CSE_ProgressBar.HideSecondBar +End Function + +Public Function FixGapsStyle(target As Word.Document) + Dim rFind As Word.Range: Set rFind = target.Range.Duplicate + With rFind.Find + .Text = Chr(12) + Do While .Execute + If rFind.Previous(wdCharacter, 1) <> Chr(13) Then + Call rFind.InsertBefore(Chr(13)) + If Not rFind.Start = rFind.Paragraphs.First.Range.Start Then _ + Call rFind.MoveStart(1) + End If + rFind.ParagraphFormat.Style = "" + Loop + End With +End Function + +Public Function CreateLayoutBlock(target As Word.Range) + If target.End = target.Document.Range.End Then _ + Exit Function + + Dim rStart As Word.Range: Set rStart = target.Duplicate + Dim rFinish As Word.Range: Set rFinish = target.Next(wdParagraph, 1).Duplicate + Call rStart.Collapse(wdCollapseStart) + Call rFinish.Collapse(wdCollapseStart) + + If rStart.Start = rFinish.Start Then _ + Exit Function + If GetColumn(rStart) <> GetColumn(rFinish) Then _ + Exit Function + + Dim isFirst As Boolean: isFirst = IsFirstInColumn(target) + If isFirst Then target.ParagraphFormat.SpaceBefore = 0 + + Dim prevAfter As Double: prevAfter = rStart.Previous(wdParagraph, 1).ParagraphFormat.SpaceAfter + Dim curBefore As Double: curBefore = rStart.ParagraphFormat.SpaceBefore + Dim curAfter As Double: curAfter = rFinish.Previous(wdParagraph, 1).ParagraphFormat.SpaceAfter + Dim nxtBefore As Double: nxtBefore = rFinish.ParagraphFormat.SpaceBefore + + Dim maxAfter As Double: maxAfter = IIf(curAfter > nxtBefore, curAfter, nxtBefore) + Dim maxBefore As Double: maxBefore = IIf(curBefore > prevAfter, curBefore, prevAfter) + + Call rFinish.Move(wdCharacter, -1) + Call rFinish.InsertAfter(Chr(13)) + Call rFinish.Move(wdCharacter, 1) + rFinish.Style = rFinish.Document.Styles(BASE_STYLE) + + Dim topPosition As Double: topPosition = rStart.Information(wdVerticalPositionRelativeToPage) + If IsBorderVisible(rStart, wdBorderTop) Then _ + topPosition = topPosition - BorderLinewidth(wdBorderTop, rStart) + rStart.Borders.DistanceFromTop + + Dim botPosition As Double: botPosition = rFinish.Information(wdVerticalPositionRelativeToPage) + botPosition = botPosition - rFinish.Previous(wdParagraph, 1).ParagraphFormat.SpaceAfter + + Dim defSpacing As Double: defSpacing = DefaultSpacing(target.Document) + Dim blockHeight As Double: blockHeight = botPosition - topPosition + Dim nLines&: nLines = Int((blockHeight + curBefore + curAfter) / defSpacing + 0.5) + Dim toAdd As Double: toAdd = (nLines + 1) * defSpacing - (curBefore + curAfter + blockHeight) + If Abs(toAdd - defSpacing) < 0.5 Then toAdd = 0 + + rFinish.Previous(wdParagraph, 1).ParagraphFormat.SpaceAfter = maxAfter + toAdd / IIf(isFirst, 1, 2) + rStart.ParagraphFormat.SpaceBefore = maxBefore + toAdd * IIf(isFirst, 0, 0.5) + If isFirst Then + rFinish.Previous(wdParagraph, 1).ParagraphFormat.SpaceAfter = _ + rFinish.Previous(wdParagraph, 1).ParagraphFormat.SpaceAfter + _ + rStart.ParagraphFormat.SpaceBefore + rStart.ParagraphFormat.SpaceBefore = 0 + End If + + rFinish.Delete + + Do While rStart.ParagraphFormat.SpaceBefore > 1.4 * defSpacing And _ + (rStart.Previous(wdParagraph, 1).ParagraphFormat.SpaceAfter > 1.4 * defSpacing Or _ + rStart.Previous(wdParagraph, 1).ParagraphFormat.SpaceAfter = 0) + + rStart.ParagraphFormat.SpaceBefore = _ + rStart.ParagraphFormat.SpaceBefore - defSpacing + If rStart.Previous(wdParagraph, 1).ParagraphFormat.SpaceAfter <> 0 Then _ + rStart.Previous(wdParagraph, 1).ParagraphFormat.SpaceAfter = _ + rStart.Previous(wdParagraph, 1).ParagraphFormat.SpaceAfter - defSpacing + Loop + + Do While target.Paragraphs.Last.SpaceAfter > 1.4 * defSpacing And _ + (target.Paragraphs.Last.Next.SpaceBefore > 1.4 * defSpacing Or _ + target.Paragraphs.Last.Next.SpaceBefore = 0) + + target.Paragraphs.Last.SpaceAfter = _ + target.Paragraphs.Last.SpaceAfter - defSpacing + If target.Paragraphs.Last.Next.SpaceBefore <> 0 Then _ + target.Paragraphs.Last.Next.SpaceBefore = _ + target.Paragraphs.Last.Next.SpaceBefore - defSpacing + Loop +End Function + +Public Function UpdateObjectFields(target As Word.Document) + Call CSE_ProgressBar.InitSecondBar(0, target.Shapes.Count) + + Dim aShape As Word.Shape + For Each aShape In target.Shapes + If IsEndSymbol(aShape) Then _ + GoTo NEXT_SHAPE + Dim ancRange As Word.Range: Set ancRange = aShape.Anchor.Paragraphs(1).Range + If Len(ancRange) < 3 Then _ + GoTo NEXT_SHAPE + + Dim isLeft As Boolean: isLeft = GetColumn(ancRange) = T_COL_LEFT + With aShape + ' + .RelativeVerticalPosition = wdRelativeVerticalPositionParagraph + .TextFrame.VerticalAnchor = msoAnchorBottom + .Top = ancRange.ParagraphFormat.SpaceBefore + If .TextFrame.TextRange.Font.Name = "conceptpict" Then + .Top = .Top - ancRange.ParagraphFormat.LineSpacing * 1.5 / 2# + .TextFrame.TextRange.ParagraphFormat.LineSpacing / 2# + Else + .TextFrame.TextRange.ParagraphFormat.LineSpacing = ancRange.ParagraphFormat.LineSpacing + End If + + Dim prevNormal As Word.Range: Set prevNormal = ancRange.Previous(wdParagraph) + Dim tmpMin As Double: tmpMin = Min(ancRange.ParagraphFormat.SpaceBefore, prevNormal.ParagraphFormat.SpaceAfter) + Dim tmpMax As Double: tmpMax = -Min(-ancRange.ParagraphFormat.SpaceBefore, 0) + .Top = .Top - IIf(ancRange.Sections.First.Range.Paragraphs.First.Range.Start = ancRange.Start, _ + tmpMin, IIf(IsFirstInColumn(ancRange) And isLeft, tmpMax, tmpMin)) + + ' + If .Type = msoTextBox Then + .RelativeHorizontalPosition = wdRelativeHorizontalPositionColumn + If isLeft Then + .Left = CentimetersToPoints(LEFT_POS_SHIFT) - .Width + .TextFrame.TextRange.ParagraphFormat.Alignment = wdAlignParagraphRight + Else + .Left = CentimetersToPoints(RIGHT_POS_SHIFT) + .TextFrame.TextRange.ParagraphFormat.Alignment = wdAlignParagraphLeft + End If + If IsHeader(ancRange) Then _ + .Top = .Top - .Height / 2# _ + + .TextFrame.TextRange.ParagraphFormat.LineSpacing / 2# _ + - .TextFrame.TextRange.Font.Size * (SPACING_SCALE - 1) / 2# + Else + .RelativeHorizontalPosition = IIf(isLeft, wdRelativeHorizontalPositionLeftMarginArea, wdRelativeHorizontalPositionRightMarginArea) + .Left = wdShapeCenter + End If + End With + +NEXT_SHAPE: + Call CSE_ProgressBar.IncrementB + Next aShape + Call CSE_ProgressBar.HideSecondBar +End Function + +Public Function UpdateTableOfContents(target As Word.TableOfContents) + Dim initPos As Word.Range: Set initPos = target.Application.Selection.Range + + Call target.Update + Dim aLink As Hyperlink + For Each aLink In target.Range.Hyperlinks + Call aLink.Follow + Dim rHeader As Word.Range: Set rHeader = target.Application.Selection.Range + If rHeader.ParagraphFormat.OutlineLevel = wdOutlineLevel1 Then _ + GoTo NXT_LNK + + Call rHeader.MoveStart(wdWord, -1) + Dim lineStart As Word.Range: Set lineStart = aLink.Range.Duplicate + Call lineStart.Collapse(wdCollapseStart) + If rHeader.ShapeRange.Count <> 0 Then + Dim rSource As Word.Range: Set rSource = rHeader.ShapeRange(1).TextFrame.TextRange + Call rSource.MoveEnd(wdCharacter, -1) + lineStart.Text = Chr(9) & rSource.Text & Chr(9) + Else + lineStart.Text = Chr(9) & Chr(9) + End If + + Call lineStart.Select + lineStart.ParagraphFormat.Style.BaseStyle = aLink.Range.ParagraphFormat.Style.BaseStyle +NXT_LNK: + Next aLink + + Call target.Range.Document.ActiveWindow.ScrollIntoView(initPos) +End Function + +' ========= +Private Function Min(i1 As Variant, i2 As Variant) As Variant + Min = IIf(i1 < i2, i1, i2) +End Function + +Private Function IsEndSymbol(aShape As Word.Shape) As Boolean + IsEndSymbol = False + If Abs(aShape.Width - 159.875) > 1 Then Exit Function + If Abs(aShape.Height - 36) > 1 Then Exit Function + IsEndSymbol = True +End Function + +Private Function FixHeaderBlockSpacing(target As Word.Range, firstOnPage As Boolean) As HeaderBlock + Call FixHeaderSpacing(target, firstOnPage) + Dim result As HeaderBlock: result = ScanHeaderBlock(target) + Dim kScale As Double: kScale = CalculateHeaderScaling(result, firstOnPage) + Call ScaleHeaderSpacing(result, kScale) + FixHeaderBlockSpacing = result +End Function + +Private Function ScanHeaderBlock(target As Word.Range) As HeaderBlock + Dim result As HeaderBlock + + Set result.startRng = target.Duplicate + result.yText = target.ParagraphFormat.LineSpacing * target.ComputeStatistics(wdStatisticLines) + result.yHeight = result.yText + target.ParagraphFormat.SpaceBefore + + Set result.finishRng = result.startRng.Next(wdParagraph, 1) + Do While Not result.finishRng Is Nothing + If Not IsHeader(result.finishRng) Then _ + Exit Do + If IsFirstInColumn(result.finishRng) Then _ + Exit Do + + Call FixHeaderSpacing(result.finishRng, True) + + Dim nextLineSpacing As Double: nextLineSpacing = result.finishRng.ParagraphFormat.LineSpacing + result.finishRng.Previous(wdParagraph, 1).ParagraphFormat.SpaceAfter = nextLineSpacing + + Dim textH As Double: textH = nextLineSpacing * result.finishRng.ComputeStatistics(wdStatisticLines) + result.yText = result.yText + textH + result.yHeight = result.yHeight + textH + nextLineSpacing + + Set result.finishRng = result.finishRng.Next(wdParagraph, 1) + Loop + result.finishRng.Previous(wdParagraph, 1).ParagraphFormat.SpaceAfter = result.finishRng.ParagraphFormat.LineSpacing + result.yHeight = result.yHeight + result.finishRng.ParagraphFormat.LineSpacing + + ScanHeaderBlock = result +End Function + +Private Function CalculateHeaderScaling(block As HeaderBlock, firstOnPage As Boolean) As Double + Dim defSpacing As Double: defSpacing = DefaultSpacing(block.startRng.Document) + Dim n&: n = CLng(block.yHeight / defSpacing + 0.5) ' TODO: probably should use Int istead of CLng, needs testing + If n = 3 And Not firstOnPage Then + n = n - 1 + End If + Dim newH As Double: newH = n * defSpacing + Dim k As Double: k = (newH - block.yText) / (block.yHeight - block.yText) + If k < 0 Then + Call UserInteraction.ShowMessage(EM_FIX_LINING_FAIL) + Exit Function + End If + CalculateHeaderScaling = k +End Function + +Private Function ScaleHeaderSpacing(block As HeaderBlock, kScale As Double) + Dim tmpRng As Word.Range: Set tmpRng = block.startRng.Duplicate + Do While Not tmpRng.Start = block.finishRng.Start + tmpRng.ParagraphFormat.SpaceBefore = kScale * tmpRng.ParagraphFormat.SpaceBefore + tmpRng.ParagraphFormat.SpaceAfter = kScale * tmpRng.ParagraphFormat.SpaceAfter + Set tmpRng = tmpRng.Next(wdParagraph, 1) + Loop +End Function + +Private Function SetHeaderBlockPosition(block As HeaderBlock, firstOnPage As Boolean) + Dim defSpacing As Double: defSpacing = DefaultSpacing(block.startRng.Document) + Dim prevSpc As Double: prevSpc = block.startRng.Previous(wdParagraph).ParagraphFormat.SpaceAfter + Dim curSpc As Double: curSpc = block.startRng.ParagraphFormat.SpaceBefore + If prevSpc <> 0 And Not firstOnPage Then _ + block.startRng.ParagraphFormat.SpaceBefore = prevSpc + ((curSpc * 1000) Mod (defSpacing * 1000)) / 1000 + + prevSpc = block.finishRng.Previous(wdParagraph, 1).ParagraphFormat.SpaceAfter + curSpc = block.finishRng.ParagraphFormat.SpaceBefore + If curSpc <> 0 Then _ + block.finishRng.Previous(wdParagraph, 1).ParagraphFormat.SpaceAfter = curSpc + ((1000 * prevSpc) Mod (defSpacing * 1000)) / 1000 +End Function + +Private Function FixHeaderSpacing(target As Word.Range, columnStart As Boolean) + With target + If Not .ParagraphFormat.LineSpacingRule = wdLineSpaceExactly Then + .ParagraphFormat.LineSpacingRule = wdLineSpaceExactly + .ParagraphFormat.LineSpacing = .ParagraphFormat.LineSpacing * SPACING_SCALE + End If + .ParagraphFormat.Alignment = IIf(GetColumn(target) = T_COL_RIGHT, wdAlignParagraphRight, wdAlignParagraphLeft) + .ParagraphFormat.SpaceBefore = IIf(columnStart, 0, .ParagraphFormat.LineSpacing) + End With +End Function + +Private Function BorderLinewidth(bordertype As WdBorderType, wdrange As Word.Range) As Double + BorderLinewidth = 0 + If wdrange.Borders(bordertype).Visible = False Then Exit Function + Select Case wdrange.Borders(bordertype).LineWidth + Case wdLineWidth025pt: BorderLinewidth = 0.25 + Case wdLineWidth050pt: BorderLinewidth = 0.5 + Case wdLineWidth075pt: BorderLinewidth = 0.75 + Case wdLineWidth100pt: BorderLinewidth = 1 + Case wdLineWidth150pt: BorderLinewidth = 1.5 + Case wdLineWidth225pt: BorderLinewidth = 2.25 + Case wdLineWidth300pt: BorderLinewidth = 3 + Case wdLineWidth450pt: BorderLinewidth = 4.5 + Case wdLineWidth600pt: BorderLinewidth = 6 + End Select +End Function + +Private Function IsBorderVisible(wdrange As Word.Range, wdBorder As WdBorderType) As Boolean + IsBorderVisible = wdrange.Borders.Item(wdBorder).Visible +End Function + +Private Function RemoveObjectsFrom(dest As Word.Range) + Dim i& + For i = 1 To dest.ShapeRange.Count + Dim aShape As Word.Shape: Set aShape = dest.ShapeRange(i) + If aShape.Type = msoTextBox And ((GetColumn(dest) = T_COL_RIGHT And aShape.Left = Int(20 * CentimetersToPoints(RIGHT_POS_SHIFT)) / 20) _ + Or (GetColumn(dest) = T_COL_LEFT And Abs(aShape.Left) = Int(20 * Abs(CentimetersToPoints(LEFT_POS_SHIFT) - aShape.Width)) / 20)) _ + Then + Call aShape.Delete + End If + Next i +End Function + +Private Function NeedsAlignment(target As Word.Range) As Boolean + NeedsAlignment = False + + Dim outLevel&: outLevel = target.ParagraphFormat.OutlineLevel + If IsHeader(target, 1) Or outLevel = wdOutlineLevel1 Then _ + Exit Function + If Not IsHeader(target) Then _ + Exit Function + If target.ParagraphFormat.Style = " " Then _ + Exit Function + + NeedsAlignment = True +End Function + +Private Function CreateEmptyField(dest As Word.Range) As Word.Shape + Dim selRange As Word.Range: Set selRange = dest.Application.Selection.Range + + Call RemoveObjectsFrom(dest) + + Dim txtShp As Word.Shape + Set txtShp = dest.Document.Shapes.AddTextbox(msoTextOrientationHorizontal, 0, 0, _ + CentimetersToPoints(FIELD_SIZE_CM), dest.ParagraphFormat.LineSpacing * 1.5, dest) + + If txtShp.Anchor.Start <> dest.Start Then + ' : + txtShp.Select + Selection.Cut + dest.Select + Selection.Paste + Set txtShp = dest.ShapeRange(1) + selRange.Select + If dest.Characters.First = " " Then _ + dest.Characters.First.Delete + ' End of + End If + + With txtShp + ' + With .TextFrame.TextRange + .Font = dest.Font + .ParagraphFormat.LineSpacingRule = wdLineSpaceExactly + .ParagraphFormat.LineSpacing = dest.ParagraphFormat.LineSpacing + .ParagraphFormat.SpaceBefore = 0 + .ParagraphFormat.SpaceAfter = 0 + End With + + ' + .RelativeVerticalPosition = wdRelativeVerticalPositionParagraph + .Top = dest.ParagraphFormat.SpaceBefore _ + - .Height / 2# _ + + .TextFrame.TextRange.ParagraphFormat.LineSpacing / 2# + + .RelativeHorizontalPosition = wdRelativeHorizontalPositionColumn + If GetColumn(dest) = T_COL_RIGHT Then + .Left = CentimetersToPoints(RIGHT_POS_SHIFT) + .TextFrame.TextRange.ParagraphFormat.Alignment = wdAlignParagraphLeft + Else + .Left = CentimetersToPoints(LEFT_POS_SHIFT) - .Width + .TextFrame.TextRange.ParagraphFormat.Alignment = wdAlignParagraphRight + End If + + ' + .Line.Visible = msoFalse + End With + Set CreateEmptyField = txtShp +End Function + diff --git a/src/CD_Paint.bas b/src/CD_Paint.bas new file mode 100644 index 0000000..8681544 --- /dev/null +++ b/src/CD_Paint.bas @@ -0,0 +1,358 @@ +Attribute VB_Name = "CD_Paint" +Option Private Module +Option Explicit + +Public Function RepaintText(target As Word.Document) + CSE_ProgressBar.Header = " ..." + Call CSE_ProgressBar.InitSecondBar(0, maxVal:=target.Range.End) + + Dim sectionHead As SectionHeader: Set sectionHead.rFind = target.Range.Duplicate + sectionHead.nStart = 0 + sectionHead.nFinish = -1 + sectionHead.cHeader = wdAuto + sectionHead.cText = wdAuto + With sectionHead.rFind.Find + .Text = "" + .Format = True + .ParagraphFormat.OutlineLevel = wdOutlineLevel1 + End With + + Do While IncrementHeader(sectionHead) + Call PaintBoldText(sectionHead) + Call PaintItalicText(sectionHead) + Call CSE_ProgressBar.SetB(sectionHead.nFinish) + Loop + + Call CSE_ProgressBar.HideSecondBar +End Function + +Public Function RepaintTextShapes(target As Word.Document) + CSE_ProgressBar.Header = " ..." + Call CSE_ProgressBar.InitSecondBar(0, maxVal:=target.Shapes.Count) + + Dim aShape As Word.Shape + For Each aShape In target.Shapes + If aShape.Type = msoTextBox Then + Dim ancRange As Word.Range: Set ancRange = aShape.Anchor.Paragraphs(1).Range + aShape.TextFrame.TextRange.Font.Color = GetSectionHeader(ancRange.Start, target).Font.Color + End If + Call CSE_ProgressBar.IncrementB + Next aShape + + Call CSE_ProgressBar.HideSecondBar +End Function + +Public Function RepaintHLinks(target As Word.Document) + CSE_ProgressBar.Header = " ..." + Call CSE_ProgressBar.InitSecondBar(0, maxVal:=target.Hyperlinks.Count) + + Dim initialPos As Word.Range: Set initialPos = target.ActiveWindow.Selection.Range + Dim aLink As Hyperlink + For Each aLink In target.Hyperlinks + If Not aLink.Address = "" Or aLink.SubAddress Like "_Toc*" Then _ + GoTo NEXT_LINK + + Call aLink.Follow + Dim linkTarget As Word.Range: Set linkTarget = target.ActiveWindow.Selection.Paragraphs(1).Range + If linkTarget.ParagraphFormat.OutlineLevel <> wdOutlineLevelBodyText Then _ + aLink.Range.Font.Color = linkTarget.Font.Color +NEXT_LINK: + Call CSE_ProgressBar.IncrementB + Next aLink + + Call target.ActiveWindow.ScrollIntoView(initialPos) + Call CSE_ProgressBar.HideSecondBar +End Function + +Public Function RepaintToC(target As Word.Document) + CSE_ProgressBar.Header = " ..." + Dim i& + For i = 1 To target.TablesOfContents.Count Step 1 + Call PaintToC(target.TablesOfContents(i)) + Next i +End Function + +Public Function PaintTable(target As Word.Table, mainColor&, props As TablePaintProps) + Dim colorFrame&: colorFrame = ColorAdjustLuma(mainColor, props.cGrid, True) + Dim colorHead&: colorHead = ColorAdjustLuma(mainColor, props.cHeading, True) + Dim colorSubhead&: colorSubhead = ColorAdjustLuma(mainColor, props.cSubHead, True) + Dim colorZebraBright&: colorZebraBright = 16777215 ' + Dim colorZebraDark&: colorZebraDark = ColorAdjustLuma(mainColor, props.cZebra, True) + + Dim greyColHead&: greyColHead = ColorGetLuma(colorHead) + Dim greyColSub&: greyColSub = ColorGetLuma(colorSubhead) + Dim greyColZebra&: greyColZebra = ColorGetLuma(colorZebraDark) + + With target + ' + .AllowPageBreaks = True + .AllowAutoFit = False + + .PreferredWidthType = wdPreferredWidthPercent + .PreferredWidth = 100 + + .Rows.HeightRule = wdRowHeightAuto + .Rows.Height = CentimetersToPoints(0) + + .TopPadding = CentimetersToPoints(props.textSpacing) + .BottomPadding = CentimetersToPoints(props.textSpacing) + .LeftPadding = CentimetersToPoints(props.textSpacing) + .RightPadding = CentimetersToPoints(props.textSpacing) + .Spacing = 0 + + ' + With .Borders(wdBorderLeft) + .LineStyle = wdLineStyleSingle + .LineWidth = TABLE_FRAME_THICKNESS + .Color = colorFrame + End With + With .Borders(wdBorderTop) + .LineStyle = wdLineStyleSingle + .LineWidth = TABLE_FRAME_THICKNESS + .Color = colorFrame + End With + With .Borders(wdBorderRight) + .LineStyle = wdLineStyleSingle + .LineWidth = TABLE_FRAME_THICKNESS + .Color = colorFrame + End With + With .Borders(wdBorderBottom) + .LineStyle = wdLineStyleSingle + .LineWidth = TABLE_FRAME_THICKNESS + .Color = colorFrame + End With + + With .Borders(wdBorderHorizontal) + .LineStyle = wdLineStyleSingle + .LineWidth = TABLE_CELL_THICKNESS + .Color = colorFrame + End With + With .Borders(wdBorderVertical) + .LineStyle = wdLineStyleSingle + .LineWidth = TABLE_CELL_THICKNESS + .Color = colorFrame + End With + + + With .Rows(1) + With .Borders(wdBorderBottom) + .LineStyle = wdLineStyleSingle + .LineWidth = TABLE_FRAME_THICKNESS + .Color = colorFrame + End With + + .Range.Font.ColorIndex = IIf(greyColHead < 127, wdWhite, wdBlack) + .Shading.BackgroundPatternColor = colorHead + End With + End With + + ' + Dim whiteFlag As Boolean: whiteFlag = True + Dim nRow As Integer: nRow = 2 + For nRow = 2 To target.Rows.Count + If target.Cell(nRow, 1).Range.Font.Bold = True Then + target.Rows(nRow).Range.Font.ColorIndex = IIf(greyColSub < 127, wdWhite, wdBlack) + target.Rows(nRow).Shading.BackgroundPatternColor = colorSubhead + whiteFlag = True + Else + If whiteFlag Then + target.Rows(nRow).Shading.BackgroundPatternColor = colorZebraBright + Else + target.Rows(nRow).Range.Font.ColorIndex = IIf(greyColZebra < 127, wdWhite, wdBlack) + target.Rows(nRow).Shading.BackgroundPatternColor = colorZebraDark + End If + whiteFlag = Not whiteFlag + End If + Next nRow +End Function + +Public Function PaintTableProto(target As Word.Table, proto As Word.Table) +' + Dim colorHead&: colorHead = proto.Cell(2, 1).Shading.BackgroundPatternColor + Dim colorBright&: colorBright = proto.Cell(3, 1).Shading.BackgroundPatternColor + Dim colorDark&: colorDark = proto.Cell(4, 1).Shading.BackgroundPatternColor + + ' + With target + With .Borders(wdBorderLeft) + .LineStyle = proto.Borders(wdBorderLeft).LineStyle + .LineWidth = proto.Borders(wdBorderLeft).LineWidth + .Color = proto.Borders(wdBorderLeft).Color + End With + With .Borders(wdBorderTop) + .LineStyle = proto.Borders(wdBorderTop).LineStyle + .LineWidth = proto.Borders(wdBorderTop).LineWidth + .Color = proto.Borders(wdBorderTop).Color + End With + With .Borders(wdBorderRight) + .LineStyle = proto.Borders(wdBorderRight).LineStyle + .LineWidth = proto.Borders(wdBorderRight).LineWidth + .Color = proto.Borders(wdBorderRight).Color + End With + With .Borders(wdBorderBottom) + .LineStyle = proto.Borders(wdBorderBottom).LineStyle + .LineWidth = proto.Borders(wdBorderBottom).LineWidth + .Color = proto.Borders(wdBorderBottom).Color + End With + + With .Borders(wdBorderHorizontal) + .LineStyle = proto.Borders(wdBorderVertical).LineStyle + .LineWidth = proto.Borders(wdBorderVertical).LineWidth + .Color = proto.Borders(wdBorderVertical).Color + End With + With .Borders(wdBorderVertical) + .LineStyle = proto.Borders(wdBorderVertical).LineStyle + .LineWidth = proto.Borders(wdBorderVertical).LineWidth + .Color = proto.Borders(wdBorderVertical).Color + End With + + .Borders(wdBorderDiagonalDown).LineStyle = proto.Borders(wdBorderDiagonalDown).LineStyle + .Borders(wdBorderDiagonalUp).LineStyle = proto.Borders(wdBorderDiagonalUp).LineStyle + .Borders.Shadow = proto.Borders.Shadow + End With + + With target + .AllowPageBreaks = proto.AllowPageBreaks + .AllowAutoFit = proto.AllowAutoFit + + .PreferredWidthType = wdPreferredWidthPoints + .PreferredWidth = CentimetersToPoints(15.92) + .Rows.HeightRule = wdRowHeightAuto + .Rows.Height = CentimetersToPoints(0) + + .TopPadding = proto.TopPadding + .BottomPadding = proto.BottomPadding + .LeftPadding = proto.LeftPadding + .RightPadding = proto.RightPadding + .Spacing = proto.Spacing + + With .Rows(1) + .Borders(wdBorderBottom).LineStyle = proto.Rows(1).Borders(wdBorderBottom).LineStyle + .Borders(wdBorderBottom).LineWidth = proto.Rows(1).Borders(wdBorderBottom).LineWidth + .Borders(wdBorderBottom).Color = proto.Rows(1).Borders(wdBorderBottom).Color + .Shading.BackgroundPatternColor = proto.Cell(1, 1).Shading.BackgroundPatternColor + End With + End With + + ' + Dim whiteFlag As Boolean: whiteFlag = True + Dim nRow&: nRow = 2 + For nRow = 2 To target.Rows.Count + If target.Cell(nRow, 1).Range.Font.Bold = True Then + target.Rows(nRow).Shading.BackgroundPatternColor = colorHead + whiteFlag = True + Else + If whiteFlag Then + target.Rows(nRow).Shading.BackgroundPatternColor = colorBright + Else + target.Rows(nRow).Shading.BackgroundPatternColor = colorDark + End If + whiteFlag = Not whiteFlag + End If + Next nRow +End Function + +' ========== +Private Function PaintToC(target As Word.TableOfContents) + Dim tocElement As Word.Range: Set tocElement = target.Range.Paragraphs.First.Range + Dim rHeader As Word.Range: Set rHeader = target.Range.Document.Range + With rHeader.Find + .Text = "" + .Format = True + .ParagraphFormat.OutlineLevel = wdOutlineLevel1 + End With + + On Error GoTo REPORT_ERROR + Dim theEnd&: theEnd = target.Range.End + Do While rHeader.Find.Execute + If Len(rHeader.Text) < 3 Then _ + GoTo NEXT_SECTION_HEADER + + Do While Not tocElement.Font.AllCaps = True + Set tocElement = tocElement.Next(wdParagraph, 1) + If tocElement.End > theEnd Then _ + GoTo REPORT_ERROR + Loop + tocElement.Font.Color = rHeader.Font.Color + Set tocElement = tocElement.Next(wdParagraph, 1) + +NEXT_SECTION_HEADER: + Call rHeader.Collapse(wdCollapseEnd) + Loop + Exit Function +REPORT_ERROR: + Call UserInteraction.ShowMessage(EM_INVALID_CONTENTS_TABLE) +End Function + +Private Function IncrementHeader(ByRef target As SectionHeader) As Boolean + IncrementHeader = False + If target.nFinish >= target.rFind.Document.Sections.Last.Range.Start - 1 Then _ + Exit Function + If Not target.rFind.Find.Execute Then _ + Exit Function + + Dim theHeader As Word.Range: Set theHeader = target.rFind.Duplicate + Dim lastSection As Boolean: lastSection = Not target.rFind.Find.Execute + Do While Len(target.rFind.Text) < 3 And Not lastSection + Call target.rFind.Collapse(wdCollapseEnd) + lastSection = Not target.rFind.Find.Execute + Loop + + Call target.rFind.Collapse(wdCollapseStart) + target.nStart = theHeader.End + 1 + target.nFinish = IIf(lastSection, target.rFind.Document.Sections.Last.Range.Start - 1, target.rFind.Start - 1) + target.cText = ColorGetRGB(theHeader.Font.Color, target.rFind.Document) + target.cHeader = ColorAdjustLuma(target.cText, 1000 * TEXT_BOLD_LUMSCALE, True) + + IncrementHeader = True +End Function + +Private Function PaintBoldText(target As SectionHeader) + Dim rFind As Word.Range: Set rFind = target.rFind.Document.Range(target.nStart, target.nStart) + With rFind + .Find.Text = "" + .Find.Format = True + .Find.Font.Bold = True + + Do While .Find.Execute And .End < target.nFinish + If .OMaths.Count > 0 Or .Tables.Count > 0 Then _ + GoTo NEXT_RANGE + If .Style Like "**" Then _ + GoTo NEXT_RANGE + If Not .CharacterStyle Is Nothing Then + If .CharacterStyle Like "**" Then _ + GoTo NEXT_RANGE + End If + + .Font.Color = IIf(.ParagraphFormat.OutlineLevel = wdOutlineLevelBodyText, target.cText, target.cHeader) + +NEXT_RANGE: + Call .Collapse(wdCollapseEnd) + Loop + End With +End Function + +Private Function PaintItalicText(target As SectionHeader) + Dim rFind As Word.Range: Set rFind = target.rFind.Document.Range(target.nStart, target.nStart) + With rFind + .Find.Text = "" + .Find.Format = True + .Find.Font.Italic = True + + Do While .Find.Execute And .End < target.nFinish + If .OMaths.Count > 0 Or .Tables.Count > 0 Then _ + GoTo NEXT_RANGE + If .Style Like "**" Then _ + GoTo NEXT_RANGE + If Not .CharacterStyle Is Nothing Then + If .CharacterStyle Like "**" Then _ + GoTo NEXT_RANGE + End If + + .Font.Color = IIf(.ParagraphFormat.OutlineLevel = wdOutlineLevelBodyText, target.cText, target.cHeader) + +NEXT_RANGE: + Call .Collapse(wdCollapseEnd) + Loop + End With +End Function diff --git a/src/CD_RedesignFonts.bas b/src/CD_RedesignFonts.bas new file mode 100644 index 0000000..1ba8a3d --- /dev/null +++ b/src/CD_RedesignFonts.bas @@ -0,0 +1,115 @@ +Attribute VB_Name = "CD_RedesignFonts" +Option Private Module +Option Explicit + +Public Function ExecuteRedesign(target As Word.Document, props As ItemFontScale) + target.Styles(BASE_STYLE).ParagraphFormat.LineSpacing = props.lineSpacing_ + target.Styles(BASE_STYLE).Font.Size = props.textSize_ + + Call CSE_ProgressBar.Init(" ", maxVal:=3) + Call CSE_ProgressBar.ShowModeless + + Call RedesignHeader(target, props) + Call CSE_ProgressBar.IncrementA + + Call RedesignRegularStyles(target, props) + Call CSE_ProgressBar.IncrementA + + Call RedesignText(target, props) + Call CSE_ProgressBar.IncrementA + + Unload CSE_ProgressBar +End Function + +' =========== +Private Function RedesignHeader(target As Word.Document, props As ItemFontScale) + CSE_ProgressBar.Header = " " + Call CSE_ProgressBar.InitSecondBar(0, target.Styles.Count) + Dim aStyle As Word.Style + For Each aStyle In target.Styles + If Not IsStyleMajor(aStyle) Then _ + GoTo NEXT_STYLE + + aStyle.Font.Size = aStyle.Font.Size * props.fontMultiplier_ + + If Not RequiresSpacingFix(aStyle) Then _ + GoTo NEXT_STYLE + + Dim oldScale As Double: oldScale = GetStyleScale(aStyle, props.fontFactor_) + With aStyle.ParagraphFormat + .LineSpacing = .LineSpacing * props.fontMultiplier_ * props.spacing_ / oldScale + .SpaceAfter = .SpaceAfter * props.fontMultiplier_ * props.spacing_ / oldScale + .SpaceBefore = .SpaceBefore * props.fontMultiplier_ * props.spacing_ / oldScale + End With +NEXT_STYLE: + Call CSE_ProgressBar.IncrementB + Next aStyle + + Call CSE_ProgressBar.HideSecondBar +End Function + +Private Function RedesignRegularStyles(target As Word.Document, props As ItemFontScale) + CSE_ProgressBar.Header = " " + Call CSE_ProgressBar.InitSecondBar(0, target.Styles.Count) + + Dim aStyle As Word.Style + For Each aStyle In target.Styles + If Not RequiresRegularFix(aStyle) Then _ + GoTo NEXT_STYLE + With aStyle.ParagraphFormat + .SpaceAfter = .SpaceAfter * props.fontMultiplier_ * props.spacing_ + .SpaceBefore = .SpaceBefore * props.fontMultiplier_ * props.spacing_ + End With +NEXT_STYLE: + Call CSE_ProgressBar.IncrementB + Next aStyle + + Call CSE_ProgressBar.HideSecondBar +End Function + +Private Function RedesignText(target As Word.Document, props As ItemFontScale) + CSE_ProgressBar.Header = " " + Call CSE_ProgressBar.InitSecondBar(0, target.ListParagraphs.Count) + + Dim para As Word.Paragraph + For Each para In target.ListParagraphs + If Not IsHeader(para.Range) And para.SpaceAfter <> 0 Then _ + para.SpaceAfter = props.lineSpacing_ + CSE_ProgressBar.IncrementB + Next para + + Call CSE_ProgressBar.HideSecondBar +End Function + +Private Function IsStyleMajor(aStyle As Word.Style) As Boolean + IsStyleMajor = _ + aStyle.NameLocal Like "[]*" Or _ + aStyle.NameLocal Like "[] []" Or _ + aStyle.NameLocal Like "[] " Or _ + aStyle.NameLocal Like "[] #" Or _ + aStyle.NameLocal Like "[]*" +End Function + +Private Function RequiresSpacingFix(aStyle As Word.Style) + RequiresSpacingFix = _ + aStyle.NameLocal Like "[] #" Or _ + aStyle.NameLocal Like "[]*" +End Function + +Private Function RequiresRegularFix(aStyle As Word.Style) + RequiresRegularFix = _ + UCase(aStyle.NameLocal) Like "! " Or _ + UCase(aStyle.NameLocal) Like "! " Or _ + UCase(aStyle.NameLocal) Like "" +End Function + +Private Function GetStyleScale(aStyle As Word.Style, fontFactor As Double) As Double + Dim spacingType As WdLineSpacing: spacingType = aStyle.ParagraphFormat.LineSpacingRule + Select Case (spacingType) + Case wdLineSpace1pt5: GetStyleScale = 1.5 + Case wdLineSpaceDouble: GetStyleScale = 2 + Case wdLineSpaceMultiple: GetStyleScale = aStyle.ParagraphFormat.LineSpacing + Case wdLineSpaceExactly: GetStyleScale = aStyle.ParagraphFormat.LineSpacing / aStyle.Font.Size / fontFactor + Case Else: GetStyleScale = 1 + End Select +End Function diff --git a/src/CD_SplitTable.bas b/src/CD_SplitTable.bas new file mode 100644 index 0000000..467cab6 --- /dev/null +++ b/src/CD_SplitTable.bas @@ -0,0 +1,307 @@ +Attribute VB_Name = "CD_SplitTable" +Option Private Module +Option Explicit + +Public Function PrepareTableForSplit(target As Word.Table) + Call SetupPageBeforeSlice(target) + Call InsertSplittingMarker(target) +End Function + +Public Function RemoveSplitMarkerFrom(target As Word.Table) + On Error Resume Next + target.Cell(1, 1).Range.ShapeRange.Delete +End Function + +Public Function SliceTable(target As Word.Table) As Collection + Dim startingRows As Collection: Set startingRows = PrepareStartingRows(target) + + Dim slices As New Collection + Dim nIndex& + For nIndex = startingRows.Count To 2 Step -1 + Call target.Rows(1).Select + target.Application.Selection.Copy + Dim rPaste As Word.Range: Set rPaste = target.Range + Call rPaste.Collapse(wdCollapseEnd) + Call rPaste.InsertBreak(wdSectionBreakNextPage) + Call rPaste.Paste + + Dim rowStart&: rowStart = startingRows(nIndex) + Dim rowFinish&: rowFinish = target.Rows.Count + 1 + target.Rows(rowStart).Select + Dim k& + For k = 1 To rowFinish - rowStart - 1 + Call Selection.MoveDown(wdLine, Extend:=wdExtend) + Next k + + target.Application.Selection.Copy + Call rPaste.Collapse(wdCollapseEnd) + Call rPaste.Paste + target.Application.Selection.Rows.Delete + + Call slices.Add(rPaste.Sections.First.Range.Tables(1)) + Next nIndex + Call slices.Add(target) + + Set SliceTable = slices +End Function + +Public Function SplitSlices(slices As Collection) + Call CSE_ProgressBar.InitSecondBar(0, slices.Count) + Dim tablePart As Variant + For Each tablePart In slices + Call tablePart.Select + Call SplitTable(tablePart.Application.Selection.Tables(1)) + CSE_ProgressBar.IncrementB + Next tablePart + CSE_ProgressBar.HideSecondBar +End Function + +' ============ +Private Function SplitTable(target As Word.Table) + If target.Rows(1).Cells.Count = 0 Then + Call UserInteraction.ShowMessage(EM_TABLE_MERGED_CELLS) + Exit Function + End If + + Dim horiz As Double, vert As Double + Dim tmpRange As Word.Range + Set tmpRange = target.Application.Selection.Document.Range(target.Range.End - 1, target.Range.End - 1) + horiz = tmpRange.Information(wdHorizontalPositionRelativeToPage) + vert = tmpRange.Information(wdVerticalPositionRelativeToPage) + + Dim runner As Variant + If target.Rows(1).Cells.Count < 2 Then + Call UserInteraction.ShowMessage(EM_INVALID_TABLE_COLUMNS) + Exit Function + End If + + For Each runner In target.Rows(1).Cells + Set tmpRange = runner.Range + Call tmpRange.Collapse(wdCollapseStart) + If PointsToCentimeters(tmpRange.Information(wdHorizontalPositionRelativeToPage)) > TABLE_CRITICAL_WIDTH Then + runner.Select + GoTo SELECT_MOVE + End If + Next runner + +SELECT_MOVE: + Set tmpRange = target.Application.Selection.Range + Call tmpRange.Collapse(wdCollapseEnd) + + Do While tmpRange.Information(wdHorizontalPositionRelativeToPage) <> horiz + Call target.Application.Selection.MoveRight(wdCharacter, Extend:=wdExtend) + Set tmpRange = target.Application.Selection.Range + Call tmpRange.Collapse(wdCollapseEnd) + Loop + + Do While tmpRange.Information(wdVerticalPositionRelativeToPage) <> vert Or tmpRange.End <> target.Range.End - 1 + Call Selection.MoveDown(wdLine, Extend:=wdExtend) + Set tmpRange = target.Application.Selection.Range + Call tmpRange.Collapse(wdCollapseEnd) + Loop + + Do While tmpRange.Information(wdHorizontalPositionRelativeToPage) <> horiz + Call target.Application.Selection.MoveRight(wdCharacter, Extend:=wdExtend) + Set tmpRange = target.Application.Selection.Range + Call tmpRange.Collapse(wdCollapseEnd) + Loop + + Set tmpRange = target.Range + Call tmpRange.Collapse(wdCollapseEnd) + + Call tmpRange.Collapse(wdCollapseEnd) + Call tmpRange.InsertBreak(wdSectionBreakNextPage) + tmpRange.Collapse (wdCollapseEnd) + + Dim nmeRng As Word.Range + Set nmeRng = target.Range.Document.Range(target.Range.Sections(1).Range.Start, target.Range.Start) + + Dim beforeTable As Double: beforeTable = TabNameHeight(target) + If beforeTable > 0 Then + Call nmeRng.Copy + tmpRange.Paste + tmpRange.Collapse (wdCollapseEnd) + nmeRng.Font.ColorIndex = wdWhite + End If + + target.Application.Selection.Copy + tmpRange.Paste + target.Application.Selection.Columns.Delete + + Dim curSec As Word.Section, nextSec As Word.Section + Set curSec = target.Range.Sections.First + Set nextSec = tmpRange.Sections.First + + Call DoPortraitPageSetup(curSec.PageSetup) + Call DoPortraitPageSetup(nextSec.PageSetup) + + target.PreferredWidthType = wdPreferredWidthPoints + target.PreferredWidth = CentimetersToPoints(21 - 2 * FIELD_SIZE_CM) + + Dim victim As Word.Table + Set victim = nextSec.Range.Tables(1) + victim.PreferredWidthType = wdPreferredWidthPoints + victim.PreferredWidth = CentimetersToPoints(21 - 2 * FIELD_SIZE_CM) + + Dim tSecBot As Double, vSecBot As Double + tSecBot = target.Range.Sections(1).PageSetup.BottomMargin + vSecBot = victim.Range.Sections(1).PageSetup.BottomMargin + + target.Range.Sections(1).PageSetup.BottomMargin = tSecBot / 4 + victim.Range.Sections(1).PageSetup.BottomMargin = vSecBot / 4 + Dim i As Integer, tH As Double, vH As Double + For i = 1 To target.Rows.Count Step 1 + tH = Badheight(target.Rows(i)) + vH = Badheight(victim.Rows(i)) + target.Rows(i).HeightRule = wdRowHeightExactly + victim.Rows(i).HeightRule = wdRowHeightExactly + target.Rows(i).Height = IIf(tH > vH, tH, vH) - 3 + victim.Rows(i).Height = IIf(tH > vH, tH, vH) - 3 + Next i + + target.Range.Sections(1).PageSetup.BottomMargin = tSecBot + victim.Range.Sections(1).PageSetup.BottomMargin = vSecBot + + If target.Cell(1, 1).Range.Information(wdActiveEndPageNumber) <> _ + target.Rows.Last.Cells(1).Range.Information(wdActiveEndPageNumber) Then + target.Rows.Last.HeightRule = wdRowHeightAuto + End If + + If victim.Cell(1, 1).Range.Information(wdActiveEndPageNumber) <> _ + victim.Rows.Last.Cells(1).Range.Information(wdActiveEndPageNumber) Then + victim.Rows.Last.HeightRule = wdRowHeightAuto + End If +End Function + +Private Function RowHeight(wdrow As Word.Row) As Double + Dim tmpCell As Variant + Dim jumper As Word.Range, strt As Double, ent As Double, tmpMax As Double + Dim bln As Boolean: bln = Application.ScreenUpdating + Application.ScreenUpdating = False + For Each tmpCell In wdrow.Cells + Set jumper = tmpCell.Range + Set jumper = jumper.Document.Range(jumper.End - 1, jumper.End - 1) + jumper.InsertAfter (Chr(11)) + + Set jumper = tmpCell.Range + Set jumper = jumper.Document.Range(jumper.Start, jumper.Start) + strt = jumper.Information(wdVerticalPositionRelativeToPage) + Set jumper = tmpCell.Range + Set jumper = jumper.Document.Range(jumper.End - 1, jumper.End - 1) + ent = jumper.Information(wdVerticalPositionRelativeToPage) + + Set jumper = tmpCell.Range + Set jumper = jumper.Document.Range(jumper.End - 2, jumper.End - 1) + jumper.Delete + tmpMax = IIf(tmpMax > ent - strt + jumper.ParagraphFormat.SpaceAfter, tmpMax, ent - strt + jumper.ParagraphFormat.SpaceAfter) + Next tmpCell + Application.ScreenUpdating = bln + RowHeight = tmpMax +End Function + +Private Function Badheight(wdrow As Word.Row) As Double + Dim strt As Double, ent As Double + strt = wdrow.Cells(1).Range.Information(wdVerticalPositionRelativeToPage) + ent = InsertFictiveAfter(wdrow) + Badheight = IIf(ent > strt, ent - strt, CentimetersToPoints(TABLE_CRITICAL_HEIGHT) - strt) +End Function + +Private Function InsertFictiveAfter(wdrow As Word.Row) As Double + wdrow.Select + With wdrow.Application.Selection + .InsertRowsBelow (1) + .Font.Size = 1 + .Font.Scaling = 1 + .Rows.HeightRule = wdRowHeightExactly + .Rows.Height = 0 + InsertFictiveAfter = .Range.Information(wdVerticalPositionRelativeToPage) + Selection.Rows.Delete + End With +End Function + +Private Function TabNameHeight(wdTable As Word.Table) As Double + If wdTable.Range.Start = wdTable.Range.Sections.First.Range.Start Then + TabNameHeight = -1 + Exit Function + End If + + Dim nameRange As Word.Range + With wdTable.Range + Set nameRange = .Document.Range(.Sections.First.Range.Start, .Start) + End With + + Dim tmpRange As Word.Range + Dim cumHeight As Double + With nameRange + + Set tmpRange = .Duplicate + Call tmpRange.Collapse(wdCollapseStart) + cumHeight = tmpRange.Information(wdVerticalPositionRelativeToPage) - tmpRange.ParagraphFormat.SpaceBefore + + Set tmpRange = .Duplicate + Call tmpRange.Collapse(wdCollapseEnd) + cumHeight = tmpRange.Information(wdVerticalPositionRelativeToPage) _ + - tmpRange.ParagraphFormat.SpaceBefore - cumHeight - 3 + End With + + TabNameHeight = IIf(cumHeight < 0, 0, cumHeight) +End Function + +' ============ +Private Function SetupPageBeforeSlice(target As Word.Table) + Call DoPortraitPageSetup(target.Range.Sections.First.PageSetup) + With target.Range.Sections.First.PageSetup + .PageWidth = 2 * .PageWidth - 2 * .LeftMargin + target.PreferredWidthType = wdPreferredWidthPoints + target.PreferredWidth = .PageWidth - .LeftMargin - .RightMargin + End With +End Function + +Private Function DoPortraitPageSetup(ByRef pSetup As PageSetup) + With pSetup + .Orientation = wdOrientPortrait + .PageHeight = CentimetersToPoints(29.7) + .PageWidth = CentimetersToPoints(21) + .TopMargin = CentimetersToPoints(FIELD_SIZE_CM) + .BottomMargin = .TopMargin + .LeftMargin = CentimetersToPoints(FIELD_SIZE_CM) + .RightMargin = .LeftMargin + End With +End Function + +Private Function PrepareStartingRows(target As Word.Table) As Collection + Dim startingRows As New Collection + Dim previousY As Double: previousY = -1 + Dim nRow& + For nRow = 1 To target.Rows.Count + Dim currentY As Double: currentY = target.Rows(nRow).Cells(1).Range.Information(wdVerticalPositionRelativeToPage) + If currentY < previousY Or Badheight(target.Rows(nRow - 1)) > CentimetersToPoints(TABLE_CRITICAL_HEIGHT) Then + Call startingRows.Add(nRow) + End If + previousY = currentY + Next nRow + + Set PrepareStartingRows = startingRows +End Function + +Private Function InsertSplittingMarker(target As Word.Table) + Dim pSetup As PageSetup: Set pSetup = target.Range.Sections.First.PageSetup + Dim center As Double: center = (pSetup.PageWidth - 2 * pSetup.TopMargin) / 2 + Dim firstCell As Word.Cell: Set firstCell = target.Cell(1, 1) + + Call firstCell.Select + Dim sMarker As Word.Shape + Set sMarker = target.Parent.Shapes.AddShape(msoShapeDownArrow, center - 15, 0, 30, 60) + sMarker.Fill.ForeColor.RGB = RGB(112, 48, 160) + sMarker.Select + target.Application.Selection.Cut + Call firstCell.Range.Characters.First.Paste + + Dim markerAncore As Word.ShapeRange: Set markerAncore = firstCell.Range.ShapeRange + With markerAncore + .RelativeHorizontalPosition = wdRelativeHorizontalPositionPage + .RelativeVerticalPosition = wdRelativeVerticalPositionPage + .Left = center - 15 + .Top = -pSetup.TopMargin + End With +End Function diff --git a/src/CD_WordModule.bas b/src/CD_WordModule.bas new file mode 100644 index 0000000..5950dda --- /dev/null +++ b/src/CD_WordModule.bas @@ -0,0 +1,122 @@ +Attribute VB_Name = "CD_WordModule" +Option Private Module +Option Explicit + +Public Function GetSectionHeader(aPos&, theDoc As Word.Document) As Word.Range +' , + Dim rFind As Word.Range: Set rFind = theDoc.Range(aPos, aPos) + With rFind.Find + .Text = "" + .Format = True + .Forward = False + .ParagraphFormat.OutlineLevel = wdOutlineLevel1 + + If .Execute = False Then _ + Exit Function + + Do While Len(rFind.Text) < 3 + rFind.Collapse Direction:=wdCollapseStart + If .Execute = False Then _ + Exit Function + Loop + End With + If rFind.Start <= aPos Then _ + Set GetSectionHeader = rFind +End Function + +Public Function DefaultSpacing(theDoc As Word.Document) As Double + DefaultSpacing = theDoc.Styles(BASE_STYLE).ParagraphFormat.LineSpacing +End Function + +Public Function GetColumn(aRange As Word.Range) As TColumn +' + Call CleanBeginning(aRange) + Dim wordX As Double: wordX = aRange.Information(wdHorizontalPositionRelativeToPage) + If wordX > SECOND_COL_POS Then + GetColumn = T_COL_RIGHT + Else + GetColumn = T_COL_LEFT + End If +End Function + +Public Function IsHeader(aRange As Word.Range, Optional uplim As Integer = 9) As Boolean +' + IsHeader = True + + If aRange.Tables.Count <> 0 Or aRange.Hyperlinks.Count <> 0 Then _ + GoTo RETURN_FALSE + + If Not aRange.Style Is Nothing Then + If aRange.Style Like "[] #*" Then + If CInt(Mid(aRange.Style, 11, 1)) <= uplim Then + Exit Function + ElseIf uplim < 9 Then + GoTo RETURN_FALSE + End If + End If + End If + + If aRange.ParagraphFormat.OutlineLevel <= uplim Then + Exit Function + ElseIf uplim < 9 Then + GoTo RETURN_FALSE + End If + + If Not aRange.Style Is Nothing Then _ + If aRange.Style Like "*[]*" Then _ + Exit Function + +RETURN_FALSE: + IsHeader = False +End Function + +Public Function IsFirstInColumn(aRange As Word.Range) As Boolean +' + IsFirstInColumn = True + If aRange.Characters.First Like "[" & Chr(12) & Chr(14) & "]" Then + Call CleanBeginning(aRange) + Exit Function + End If + + Dim prevRange As Word.Range: Set prevRange = aRange.Previous(wdParagraph, 1) + If prevRange Is Nothing Then _ + Exit Function + + If prevRange.PageSetup.TextColumns.Count < 2 Then _ + Exit Function + If Not GetColumn(aRange) = GetColumn(prevRange.Words.Last) Then _ + Exit Function + If prevRange.Information(wdActiveEndPageNumber) <> aRange.Information(wdActiveEndPageNumber) Then _ + Exit Function + + IsFirstInColumn = False +End Function + +Public Function FontLineSpacing(wdFont As Word.Font) As Double + Dim wdrange As Word.Range: Set wdrange = ActiveDocument.Range.Duplicate + Call wdrange.Collapse(wdCollapseEnd) + wdrange.InsertBreak (0) + Call wdrange.InsertAfter(Chr(13) & Chr(13) & Chr(13) & Chr(13)) + + wdrange.Font = wdFont + With wdrange.ParagraphFormat + .SpaceBefore = 0 + .SpaceAfter = 0 + .LineSpacingRule = wdLineSpaceSingle + End With + + Dim upper As Double, lower As Double + lower = wdrange.Paragraphs(3).Range.Information(wdVerticalPositionRelativeToPage) + upper = wdrange.Paragraphs(1).Range.Information(wdVerticalPositionRelativeToPage) + FontLineSpacing = (lower - upper) / 2 / wdFont.Size + FontLineSpacing = Int(FontLineSpacing / 0.05 + 0.5) * 0.05 * wdFont.Size + FontLineSpacing = Int(FontLineSpacing / 0.05 + 0.5) * 0.05 + + Call wdrange.MoveStart(wdCharacter, -2) + wdrange.Delete +End Function + +' ========== +Private Function CleanBeginning(target As Word.Range) + Call target.MoveStartWhile(Chr(12) & Chr(14)) +End Function diff --git a/src/Declarations.bas b/src/Declarations.bas new file mode 100644 index 0000000..0d5617b --- /dev/null +++ b/src/Declarations.bas @@ -0,0 +1,136 @@ +Attribute VB_Name = "Declarations" +Option Explicit + +' TODO: refactor this whole mess +Public Const FOOTER_SYMBOL_BREAK = 30 + +Public Const CSET_SLETTERS = "abcdefghijklmnopqrstuvwxyz" +Public Const CSET_BLETTERS = "ŨABCDEFGHIJKLMNOPQRSTUVWXYZ" + +Public Const BASE_STYLE = "! " + +Public Const FIELD_SIZE_CM As Double = 2.54 + +' +Public Const TEXT_BOLD_LUMSCALE = -0.2 + +' +Public Const TABLE_FRAME_LUMSCALE = -0.35 +Public Const TABLE_HEAD_LUMSCALE = 0.2 +Public Const TABLE_SUBHEAD_LUMSCALE = 0.3 +Public Const TABLE_ZEBRA_LUMSCALE = 0.8 +Public Const TABLE_FRAME_THICKNESS = 18 +Public Const TABLE_CELL_THICKNESS = 12 + +Public Const SECOND_COL_POS = 300 + +Public Const TABLE_CRITICAL_WIDTH As Double = 16 +Public Const TABLE_CRITICAL_HEIGHT As Double = 22 + +Public Const RIGHT_POS_SHIFT = 8# +Public Const LEFT_POS_SHIFT = -0.25 + +' +Public Const SPACING_SCALE = 1.15 ' Times New Roman + +' (-) +Public Enum TColumn + T_COL_LEFT + T_COL_RIGHT +End Enum + +' +Public Enum TSource + T_SOURCE_BOOK + T_SOURCE_VOLUME + T_SOURCE_SECTION + T_SOURCE_DOCUMENT + T_SOURCE_CHAPTER + T_SOURCE_CONCEPT +End Enum + +' +Public Type ColontitlePosition + top_ As Boolean + left_ As Boolean + source_ As TSource +End Type + +' +Public Type TablePaintProps + cGrid As Long + cHeading As Long + cSubHead As Long + cZebra As Long + sectionColor As Long + textSpacing As Double +End Type + +' +Public Type HeaderBlock + yText As Double + yHeight As Double + startRng As Word.Range + finishRng As Word.Range +End Type + +' +Public Type AutoDesignOptions + reapplyLists As Boolean + fixObjects As Boolean + titlePage As Boolean + doLayout As Boolean + generateColontitles As Boolean + + Count As Integer +End Type + +' +Public Type TitlePageData + sVolume As String + nVolumeID As Long + sBook As String + nBookID As Long + + rContract As Word.Range + rCustomer As Word.Range + rTheme As Word.Range +End Type + +' +Public Type SectionHeader + rFind As Word.Range + nStart As Long + nFinish As Long + cText As Long + cHeader As Long +End Type + +Public Type SectionData + sName As String + sChapter As String + bNewChapter As Boolean +End Type + +Public Function DesignTheme(ThemeColorIndex As WdThemeColorIndex) As Long + Select Case ThemeColorIndex: + Case wdThemeColorMainDark1: DesignTheme = Format("&HD000FFFF") + Case wdThemeColorMainLight1: DesignTheme = Format("&HD100FFFF") + Case wdThemeColorMainDark2: DesignTheme = Format("&HD200FFFF") + Case wdThemeColorMainLight2: DesignTheme = Format("&HD300FFFF") + Case wdThemeColorAccent1: DesignTheme = Format("&HD400FFFF") + Case wdThemeColorAccent2: DesignTheme = Format("&HD500FFFF") + Case wdThemeColorAccent3: DesignTheme = Format("&HD600FFFF") + Case wdThemeColorAccent4: DesignTheme = Format("&HD700FFFF") + Case wdThemeColorAccent5: DesignTheme = Format("&HD800FFFF") + Case wdThemeColorAccent6: DesignTheme = Format("&HD900FFFF") + Case wdThemeColorHyperlink: DesignTheme = Format("&HDA00FFFF") + Case wdThemeColorHyperlinkFollowed: DesignTheme = Format("&HDB00FFFF") + Case wdThemeColorBackground1: DesignTheme = Format("&HDC00FFFF") + Case wdThemeColorText1: DesignTheme = Format("&HDD00FFFF") + Case wdThemeColorBackground2: DesignTheme = Format("&HDE00FFFF") + Case wdThemeColorText2: DesignTheme = Format("&HDF00FFFF") + Case Else: + End Select +End Function + diff --git a/src/DevHelper.bas b/src/DevHelper.bas new file mode 100644 index 0000000..40b83c6 --- /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_RunTestDebug(sSuite, sTest) + Debug.Print sMsg + Call MsgBox(sMsg) +End Function + +Public Function Dev_GetTestSuite(sName$) As Object + Select Case sName + ' Case "s_TextEdit": Set Dev_GetTestSuite = New s_TextEdit + End Select +End Function diff --git a/src/IconPicker.cls b/src/IconPicker.cls new file mode 100644 index 0000000..c0459cd --- /dev/null +++ b/src/IconPicker.cls @@ -0,0 +1,35 @@ +VERSION 1.0 CLASS +BEGIN + MultiUse = -1 'True +END +Attribute VB_Name = "IconPicker" +Attribute VB_GlobalNameSpace = False +Attribute VB_Creatable = False +Attribute VB_PredeclaredId = False +Attribute VB_Exposed = False +Option Explicit + +Private m_Form As CDD_AddPict +Private WithEvents m_Picto As MSForms.Label +Attribute m_Picto.VB_VarHelpID = -1 +Private WithEvents m_Name As MSForms.Label +Attribute m_Name.VB_VarHelpID = -1 + +Public Sub AssignControls(crtForm As CDD_AddPict, topLbl As MSForms.Label, nmeLbl As MSForms.Label) + Set m_Form = crtForm + Set m_Picto = topLbl + Set m_Name = nmeLbl +End Sub + +Private Sub m_Name_DblClick(ByVal Cancel As MSForms.ReturnBoolean) + execPicto +End Sub + +Private Sub m_Picto_DblClick(ByVal Cancel As MSForms.ReturnBoolean) + execPicto +End Sub + +Private Sub execPicto() + m_Form.Choice = m_Picto + m_Form.Hide +End Sub diff --git a/src/InfoDocument.cls b/src/InfoDocument.cls new file mode 100644 index 0000000..637a734 --- /dev/null +++ b/src/InfoDocument.cls @@ -0,0 +1,68 @@ +VERSION 1.0 CLASS +BEGIN + MultiUse = -1 'True +END +Attribute VB_Name = "InfoDocument" +Attribute VB_GlobalNameSpace = False +Attribute VB_Creatable = False +Attribute VB_PredeclaredId = False +Attribute VB_Exposed = False +Option Explicit + +Public volume_ As String +Public volumeNo_ As Long +Public book_ As String +Public bookNo_ As Long +Public document_ As String + +Public Function Init(theDoc As Word.Document) + document_ = theDoc.Name + document_ = Left(document_, IIf(InStr(document_, ".") - 1 < 0, 0, InStr(document_, ".") - 1)) + + Dim rFind As Word.Range + Set rFind = theDoc.Sections(1).Range + With rFind.Find + .Text = " " + .Format = True + .MatchCase = False + ' .Style = "_ " + End With + If rFind.Find.Execute Then + Set rFind = rFind.Next(wdWord, 1) + bookNo_ = CLng(rFind.Text) + + Call rFind.MoveEndUntil(CSET_SLETTERS & CSET_BLETTERS, wdForward) + rFind.Start = rFind.End + Call rFind.MoveEndUntil(Chr(13), wdForward) + book_ = rFind + End If + + Set rFind = theDoc.Sections(1).Range + With rFind.Find + .Text = " " + .Format = True + .MatchCase = False + ' .Style = "_ " + End With + If rFind.Find.Execute Then + Set rFind = rFind.Next(wdWord, 1) + volumeNo_ = CLng(rFind.Text) + + Call rFind.MoveEndUntil(CSET_SLETTERS & CSET_BLETTERS, wdForward) + rFind.Start = rFind.End + Call rFind.MoveEndUntil(Chr(13)) + volume_ = rFind + End If +End Function + +Public Function IsValidNames() As Boolean + IsValidNames = volume_ <> "" And book_ <> "" +End Function + +Public Property Get BookText() As String + BookText = " " & Trim(Str(bookNo_)) & ". " & book_ +End Property + +Public Property Get VolumeText() As String + VolumeText = " " & Trim(Str(volumeNo_)) & ". " & volume_ +End Property diff --git a/src/ItemChapter.cls b/src/ItemChapter.cls new file mode 100644 index 0000000..ded34e7 --- /dev/null +++ b/src/ItemChapter.cls @@ -0,0 +1,22 @@ +VERSION 1.0 CLASS +BEGIN + MultiUse = -1 'True +END +Attribute VB_Name = "ItemChapter" +Attribute VB_GlobalNameSpace = False +Attribute VB_Creatable = False +Attribute VB_PredeclaredId = False +Attribute VB_Exposed = False +Option Explicit + +Public start_ As Long +Public finish_ As Long +Public text_ As String + +Public Function Clone() As ItemChapter + Dim aClone As New ItemChapter + aClone.start_ = start_ + aClone.finish_ = finish_ + aClone.text_ = text_ + Set Clone = aClone +End Function diff --git a/src/ItemColontitles.cls b/src/ItemColontitles.cls new file mode 100644 index 0000000..166f5db --- /dev/null +++ b/src/ItemColontitles.cls @@ -0,0 +1,23 @@ +VERSION 1.0 CLASS +BEGIN + MultiUse = -1 'True +END +Attribute VB_Name = "ItemColontitles" +Attribute VB_GlobalNameSpace = False +Attribute VB_Creatable = False +Attribute VB_PredeclaredId = False +Attribute VB_Exposed = False +Option Explicit + +Public start_ As Long +Public finish_ As Long + +Public doTopLeft As Boolean +Public doTopRight As Boolean +Public doBottomLeft As Boolean +Public doBottomRight As Boolean + +Public mTopLeft As TSource +Public mTopRight As TSource +Public mBottomLeft As TSource +Public mBottomRight As TSource diff --git a/src/ItemFontScale.cls b/src/ItemFontScale.cls new file mode 100644 index 0000000..87eddc1 --- /dev/null +++ b/src/ItemFontScale.cls @@ -0,0 +1,24 @@ +VERSION 1.0 CLASS +BEGIN + MultiUse = -1 'True +END +Attribute VB_Name = "ItemFontScale" +Attribute VB_GlobalNameSpace = False +Attribute VB_Creatable = False +Attribute VB_PredeclaredId = False +Attribute VB_Exposed = False +Option Explicit + +Public lineSpacing_ As Double +Public fontMultiplier_ As Double +Public textSize_ As Double +Public spacing_ As Double +Public fontFactor_ As Double + +Private Sub Class_Initialize() + lineSpacing_ = -1 + fontMultiplier_ = 1 + textSize_ = 11 + spacing_ = 1 + fontFactor_ = 1.15 +End Sub diff --git a/src/Main.bas b/src/Main.bas new file mode 100644 index 0000000..492a43d --- /dev/null +++ b/src/Main.bas @@ -0,0 +1,334 @@ +Attribute VB_Name = "Main" +Option Explicit + +Public Sub CDA_AutoDesign() + Call CDD_AutoDesign.Show + If Not CDD_AutoDesign.isCancelled_ Then _ + Call RunAutoDesign(CDD_AutoDesign.Preferences) + + Call Unload(CDD_AutoDesign) + Call UserInteraction.ShowMessage(IM_AUTODESIGN_OK) +End Sub + +Public Sub CDA_FixLines() + Dim theDoc As Word.Document: Set theDoc = ActiveDocument + + Call CSE_ProgressBar.Init("", " ...", maxVal:=3) + Call CSE_ProgressBar.ShowModeless + + ' , + Call UpdateListsLayout(theDoc) + Call CSE_ProgressBar.IncrementA + + Call UpdateTextLayout(theDoc) + Call CSE_ProgressBar.IncrementA + + ' + Call UpdateObjectFields(theDoc) + Call CSE_ProgressBar.IncrementA + + Call Unload(CSE_ProgressBar) + Call UserInteraction.ShowMessage(IM_FIX_LINES_OK) +End Sub + +Public Sub CDA_Repaint() + Dim theDoc As Word.Document: Set theDoc = ActiveDocument + + Call CDD_Paint.Init + Call CDD_Paint.Show + If CDD_Paint.isCancelled_ Then _ + Exit Sub + + Dim wordUI As New API_WordWrapper: Call wordUI.SetDocument(theDoc) + Call wordUI.PauseUI + + Call CSE_ProgressBar.Init("", maxVal:=CDD_Paint.Count) + Call CSE_ProgressBar.ShowModeless + + If CDD_Paint.DoText Then + Call RepaintText(theDoc) + Call CSE_ProgressBar.IncrementA + End If + + If CDD_Paint.DoFields Then + Call RepaintTextShapes(theDoc) + Call CSE_ProgressBar.IncrementA + End If + + If CDD_Paint.DoToC Then + Call RepaintToC(theDoc) + Call CSE_ProgressBar.IncrementA + End If + + If CDD_Paint.DoLinks Then + Call RepaintHLinks(theDoc) + Call CSE_ProgressBar.IncrementA + End If + + Call Unload(CSE_ProgressBar) + Call wordUI.ResumeUI + Call UserInteraction.ShowMessage(IM_REPAINT_OK) +End Sub + +Public Sub CDA_FooterHeader() + Dim theDoc As Word.Document: Set theDoc = ActiveDocument + Dim docMeta As New InfoDocument: Call docMeta.Init(theDoc) + + Call CDD_HeaderFooter.Init(theDoc, docMeta.IsValidNames) + Call CDD_HeaderFooter.Show + If CDD_HeaderFooter.isCancelled_ Then _ + Exit Sub + + Dim props As ItemColontitles: Set props = CDD_HeaderFooter.Data + Call Unload(CDD_HeaderFooter) + + Call CSE_ProgressBar.Init(" ", sHeader:="...", maxVal:=props.finish_ - props.start_ + 1) + Call CSE_ProgressBar.ShowModeless + + Call CreateColontitles(theDoc, docMeta, props, "IncrementA") + + Call Unload(CSE_ProgressBar) + Call UserInteraction.ShowMessage(IM_FOOTER_OK) +End Sub + +Public Sub CDA_InsertBreak() + Dim theDoc As Word.Document: Set theDoc = ActiveDocument + Dim theRange As Word.Range: Set theRange = theDoc.ActiveWindow.Selection.Range + If Selection.Range.Start = Selection.Range.End Then + Set theRange = Selection.Paragraphs(1).Range + End If + + Call InsertOneColomnSection(theRange) +End Sub + +Public Sub CDA_InsertHeader() + Dim theDoc As Word.Document: Set theDoc = ActiveDocument + + Dim sHeader$: sHeader = UserInteraction.PromptInput(" ") + If sHeader = vbNullString Then _ + Exit Sub + Dim nLevel&: nLevel = Int(UserInteraction.PromptInput(" ")) + If nLevel < 2 And nLevel > 5 Then _ + Exit Sub + + Dim theRange As Word.Range: Set theRange = theDoc.ActiveWindow.Selection.Range + If theRange.Paragraphs.Count < 2 Then + Set theRange = theRange.Paragraphs(1).Range + End If + + Call InsertHeader(theRange, sHeader, nLevel) +End Sub + +Public Sub CDA_UpdateToC() + Dim theDoc As Word.Document: Set theDoc = ActiveDocument + + Dim wordUI As New API_WordWrapper: Call wordUI.SetDocument(theDoc) + Call wordUI.PauseUI + + Dim toc As Word.TableOfContents + For Each toc In theDoc.TablesOfContents + Call UpdateTableOfContents(toc) + Call RepaintToC(toc) + Next toc + + Call wordUI.ResumeUI +End Sub + +Public Sub CDA_TSAlign() + If ActiveDocument.ActiveWindow.Selection.Tables.Count <> 1 Then + Call UserInteraction.ShowMessage(EM_TABLE_NOT_SELECTED) + Exit Sub + End If + Call PrepareTableForSplit(ActiveDocument.ActiveWindow.Selection.Tables(1)) +End Sub + +Public Sub CDA_TSSlice() + If ActiveDocument.ActiveWindow.Selection.Tables.Count <> 1 Then + Call UserInteraction.ShowMessage(EM_TABLE_NOT_SELECTED) + Exit Sub + End If + + Dim target As Word.Table: Set target = ActiveDocument.ActiveWindow.Selection.Tables(1) + If target.Rows(1).Cells.Count = 0 Then + Call UserInteraction.ShowMessage(EM_TABLE_MERGED_CELLS) + Exit Sub + End If + + Call RemoveSplitMarkerFrom(target) + ActiveWindow.ActivePane.View.Zoom.PageFit = wdPageFitFullPage + target.Rows.AllowBreakAcrossPages = False + + Call CSE_ProgressBar.Init(" ", maxVal:=2) + Call CSE_ProgressBar.ShowModeless + + Dim wordUI As New API_WordWrapper: Call wordUI.SetDocument(ActiveDocument) + Call wordUI.PauseUI + + CSE_ProgressBar.Description = " ..." + Dim slices As New Collection: Set slices = SliceTable(target) + Call CSE_ProgressBar.IncrementA + + CSE_ProgressBar.Description = " ..." + Call SplitSlices(slices) + Call CSE_ProgressBar.IncrementA + + With ActiveWindow.ActivePane.View.Zoom + .PageColumns = 2 + .PageRows = 1 + End With + + Call wordUI.ResumeUI + Call Unload(CSE_ProgressBar) +End Sub + +Public Sub CDA_TSPaint() +' + Dim theDoc As Word.Document: Set theDoc = ActiveDocument + Dim target As Word.Range: Set target = theDoc.Application.Selection.Range + If target.Tables.Count < 1 Then + Call UserInteraction.ShowMessage(EM_TABLE_NOT_SELECTED) + Exit Sub + End If + + Call CDD_TablePrototype.Init(theDoc.Tables.Count) + Call CDD_TablePrototype.Show + If CDD_TablePrototype.isCancelled_ Then _ + Exit Sub + + Dim nPrototype&: nPrototype = CDD_TablePrototype.GetPickedID + Dim applyToAll As Boolean: applyToAll = CDD_TablePrototype.applyToAll + Call Unload(CDD_TablePrototype) + + If nPrototype = 0 Then _ + Exit Sub + + Call RunPaintTableProto(target, IIf(applyToAll, target.Tables.Count, 1), theDoc.Tables(nPrototype)) + Call UserInteraction.ShowMessage(IM_REPAINT_OK) +End Sub + +Public Sub CDA_PaintTable() + Dim theDoc As Word.Document: Set theDoc = ActiveDocument + Dim rSelection As Word.Range: Set rSelection = theDoc.Application.Selection.Range + Dim tableCount&: tableCount = rSelection.Tables.Count + If rSelection.Tables.Count < 1 Then + Call UserInteraction.ShowMessage(EM_TABLE_NOT_SELECTED) + Exit Sub + End If + + Dim headRange As Word.Range: Set headRange = GetSectionHeader(rSelection.Start, theDoc) + If headRange Is Nothing Then + Call UserInteraction.ShowMessage(EM_TABLE_OUTSIDE_SECTION) + Exit Sub + End If + + Call CDD_TableColors.Init(ColorGetRGB(headRange.Font.Color, theDoc)) + Call CDD_TableColors.Show + If CDD_TableColors.isCancelled_ Then _ + Exit Sub + Dim props As TablePaintProps: props = CDD_TableColors.TableProperties + Call Unload(CDD_TableColors) + + Call RunPaintTable(rSelection, tableCount, props) + + Call UserInteraction.ShowMessage(IM_REPAINT_OK) +End Sub + +Public Sub CDA_InlineFields() + Dim theDoc As Word.Document: Set theDoc = ActiveDocument + Dim aField As Word.Field + For Each aField In theDoc.Fields + If aField.Type = wdFieldRef Then + aField.Copy + Call aField.Select + Call theDoc.Application.Selection.Range.PasteAndFormat(wdFormatPlainText) + End If + Next aField +End Sub + +Public Sub CDA_InsertObject() + Dim target As Word.Range: Set target = ActiveDocument.ActiveWindow.Selection.Range.Paragraphs.First.Range + Call CDD_AddPict.Show + Select Case CDD_AddPict.Flag + Case 0: Call InsertConceptSymbol(target, CDD_AddPict.Choice) + Case 1: Call InsertPictureRef(target, CDD_AddPict.Bookmark) + Case 2: Call InsertNewPicture(CDD_AddPict.PicAdd, target) + Case 3: Call InsertTextField(target, CDD_AddPict.LighterText) + End Select +End Sub + +Public Sub CDA_InlineObjects() + Dim target As Word.Range: Set target = ActiveDocument.ActiveWindow.Selection.Paragraphs.First.Range.Duplicate + Dim nShape& + For nShape = 1 To target.InlineShapes.Count Step 1 + Call InlineAsPNG(target.InlineShapes(nShape)) + Next nShape +End Sub + +Public Sub CDA_CreateBlocking() + Dim target As Word.Range: Set target = ActiveDocument.ActiveWindow.Selection.Range + If target.Start = target.End Then _ + Exit Sub + Call CreateLayoutBlock(target) +End Sub + +Public Sub CDA_ScaleFont() + Dim theDoc As Word.Document: Set theDoc = ActiveDocument + + Call CDD_FontScaling.Init + Call CDD_FontScaling.Show + + If Not CDD_FontScaling.isCancelled_ Then _ + Call ExecuteRedesign(theDoc, CDD_FontScaling.SumUp) + + Call Unload(CDD_FontScaling) +End Sub + +Public Sub CDA_Help() + MsgBox "TODO" +End Sub + +' ======= +Private Function RunPaintTableProto(target As Word.Range, tableCount&, proto As Word.Table) + Call CSE_ProgressBar.Init(" ", sHeader:="...", maxVal:=tableCount, canInterrupt:=True) + Call CSE_ProgressBar.ShowModeless + + Dim nTable& + For nTable = 1 To tableCount Step 1 + Dim aTable As Word.Table: Set aTable = target.Tables(nTable) + If aTable.Range.Start = proto.Range.Start Then _ + GoTo NEXT_TABLE + + Call PaintTableProto(aTable, proto) + +NEXT_TABLE: + Call CSE_ProgressBar.IncrementA + If CSE_ProgressBar.Interrupted Then _ + nTable = tableCount + Next nTable + + Call Unload(CSE_ProgressBar) +End Function + +Private Function RunPaintTable(target As Word.Range, tableCount&, props As TablePaintProps) + Dim tablCount&: tablCount = Selection.Tables.Count + + Call CSE_ProgressBar.Init(" ", sHeader:=" ...", maxVal:=tablCount, canInterrupt:=True) + Call CSE_ProgressBar.ShowModeless + + Dim nTable& + For nTable = 1 To tableCount Step 1 + Dim aTable As Word.Table: Set aTable = target.Tables(nTable) + Dim headRange As Word.Range: Set headRange = GetSectionHeader(aTable.Range.Start, target.Document) + If headRange Is Nothing Then _ + GoTo NEXT_TABLE + + Call PaintTable(aTable, headRange.Font.Color, props) + +NEXT_TABLE: + Call CSE_ProgressBar.IncrementA + If CSE_ProgressBar.Interrupted Then _ + nTable = tableCount + Next nTable + + Call Unload(CSE_ProgressBar) +End Function diff --git a/src/MainImpl.bas b/src/MainImpl.bas new file mode 100644 index 0000000..b769195 --- /dev/null +++ b/src/MainImpl.bas @@ -0,0 +1,6 @@ +Attribute VB_Name = "MainImpl" +Option Explicit + + +' ============= + diff --git a/src/dialogs/CDD_AddPict.frm b/src/dialogs/CDD_AddPict.frm new file mode 100644 index 0000000..2571820 --- /dev/null +++ b/src/dialogs/CDD_AddPict.frm @@ -0,0 +1,152 @@ +VERSION 5.00 +Begin {C62A69F0-16DC-11CE-9E98-00AA00574A4F} CDD_AddPict + Caption = " " + ClientHeight = 7530 + ClientLeft = 120 + ClientTop = 465 + ClientWidth = 10155 + OleObjectBlob = "CDD_AddPict.frx":0000 + StartUpPosition = 1 'CenterOwner +End +Attribute VB_Name = "CDD_AddPict" +Attribute VB_GlobalNameSpace = False +Attribute VB_Creatable = False +Attribute VB_PredeclaredId = True +Attribute VB_Exposed = False +Option Explicit + +' TODO: isCancelled_ and extract logic + +Private m_NewPict As String +Private m_chsnSymb As String +Private m_icnCells As Collection + +Private Const INIT_POS_BG As Integer = 0 +Private Const INIT_POS_BK As Integer = -90 +Private Const INIT_POS_G As Integer = 12 + +Public Property Get Flag() As Integer + Flag = Selector.Value +End Property + +Public Property Get Bookmark() As String + Bookmark = Me.ListBox.Value +End Property + +Public Property Get LighterText() As String + LighterText = LighterBox.Text +End Property + +Public Property Get PicAdd() As String + PicAdd = m_NewPict +End Property + +Public Property Get Choice() As String + Choice = m_chsnSymb +End Property + +Public Property Let Choice(retVal$) + m_chsnSymb = retVal +End Property + +Private Sub CmdADD_Click() + Me.Hide +End Sub + +Private Sub cmdAddEx_Click() + Me.Hide +End Sub + +Private Sub CmdLighter_Click() + Me.Hide +End Sub + +Private Sub ListBox_Change() + Dim tmp As Word.Range: Set tmp = Selection.Range + Dim oper As Word.InlineShape: Set oper = ActiveDocument.Bookmarks(ListBox.Value).Range.InlineShapes(1) + Dim x As Double, y As Double, bln As Boolean + With oper + x = oper.Height + y = oper.Width + bln = Application.ScreenUpdating + Application.ScreenUpdating = False + oper.Height = CentimetersToPoints(6) * x / y + oper.Width = CentimetersToPoints(6) + Call oper.Select + Call Selection.CopyAsPicture + oper.Height = x + oper.Width = y + Application.ScreenUpdating = bln + End With + Set Me.PrevEx.Picture = PastePicture(xlBitmap) + Call tmp.Select +End Sub + +Private Sub ListBox_DblClick(ByVal Cancel As MSForms.ReturnBoolean) + If ListBox.ListIndex <> -1 Then Me.Hide +End Sub + +Private Sub Srch_Click() + m_NewPict = UserInteraction.PromptFile("") + Set PrevNew.Picture = LoadPictureGDI(m_NewPict) + Me.AddressBox.Text = m_NewPict +End Sub + +Private Sub UserForm_Initialize() + Selector.Value = 0 + Set m_icnCells = New Collection + Call LabelsFill + Call ListFill +End Sub + +Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer) + End +End Sub + +Private Function ListFill() + Dim curDoc As Word.Document: Set curDoc = ActiveDocument + Call Me.ListBox.Clear + + Dim tmpMrk As Word.Bookmark + For Each tmpMrk In curDoc.Bookmarks + If Left(tmpMrk.Name, 5) = "pict_" Then _ + Me.ListBox.AddItem (tmpMrk.Name) + Next tmpMrk +End Function + +Private Function LabelsFill() + Dim i% + Dim tmpCell As IconPicker + Dim tmpTop As MSForms.Label + Dim tmpNme As MSForms.Label + + For i = 1 To 250 + On Error Resume Next + + Set tmpTop = Me.FramePict.Controls("Label" & 2 * i - 1) + If tmpTop.Parent.Parent.Name <> Selector.Pages.Item(0).Name Then GoTo SKP_NCELL + Set tmpNme = Me.FramePict.Controls("Label" & 2 * i) + If tmpNme.Parent.Parent.Name <> Selector.Pages.Item(0).Name Then GoTo SKP_NCELL + If Err.Number <> 0 Then GoTo SKP_NCELL + + Select Case i + Case Is <= 50: tmpTop.Caption = chrW(96 + i) + Case Is <= 100: tmpTop.Caption = chrW(64 + i - 50) + Case Is <= 150: + tmpTop.Font.Charset = 204 + tmpTop.Caption = chrW(val("&H" & 429 + i - 100)) '!!! + Case Is <= 200: tmpTop.Caption = chrW(val("&H" & 250 + i - 150)) + Case Is <= 250: tmpTop.Caption = chrW(val("&H" & 530 + i - 200)) + End Select + + tmpTop.Font.Name = "conceptpict" + + Set tmpCell = New IconPicker + Call tmpCell.AssignControls(Me, tmpTop, tmpNme) + Call m_icnCells.Add(tmpCell) + +SKP_NCELL: + Err.Clear + Next i + On Error GoTo 0 +End Function diff --git a/src/dialogs/CDD_AddPict.frx b/src/dialogs/CDD_AddPict.frx new file mode 100644 index 0000000000000000000000000000000000000000..5133e068bf72346f73aa624d46391a3429584c29 GIT binary patch literal 30232 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 literal 0 HcmV?d00001 diff --git a/src/dialogs/CDD_AutoDesign.frm b/src/dialogs/CDD_AutoDesign.frm new file mode 100644 index 0000000..8e6e5f4 --- /dev/null +++ b/src/dialogs/CDD_AutoDesign.frm @@ -0,0 +1,41 @@ +VERSION 5.00 +Begin {C62A69F0-16DC-11CE-9E98-00AA00574A4F} CDD_AutoDesign + Caption = " " + ClientHeight = 3180 + ClientLeft = 120 + ClientTop = 465 + ClientWidth = 3585 + OleObjectBlob = "CDD_AutoDesign.frx":0000 + StartUpPosition = 1 'CenterOwner +End +Attribute VB_Name = "CDD_AutoDesign" +Attribute VB_GlobalNameSpace = False +Attribute VB_Creatable = False +Attribute VB_PredeclaredId = True +Attribute VB_Exposed = False +Option Explicit + +Public isCancelled_ As Boolean + +Private Sub UserForm_Initialize() + isCancelled_ = True +End Sub + +Public Function Init() + isCancelled_ = True +End Function + +Private Sub cmdAutoDesing_Click() + isCancelled_ = False + Me.Hide +End Sub + +Public Property Get Preferences() As AutoDesignOptions + Preferences.reapplyLists = Me.ckReStyleNum.Value + Preferences.fixObjects = Me.ckInline.Value + Preferences.doLayout = Me.ckAlign.Value + Preferences.generateColontitles = Me.ckColont.Value + Preferences.titlePage = Me.ckTitle.Value + Preferences.Count = Abs(Me.ckInline.Value + Me.ckAlign.Value _ + + Me.ckColont.Value + Me.ckTitle.Value + Me.ckReStyleNum.Value) +End Property diff --git a/src/dialogs/CDD_AutoDesign.frx b/src/dialogs/CDD_AutoDesign.frx new file mode 100644 index 0000000000000000000000000000000000000000..36c7f155e4b26397821f33a6ddb28bcfa00acecd GIT binary patch literal 3608 zcmeHJO-xfk5T4gAC{l&i*kBLli5v(qq!2L(;ioMS1QZ2~a`4cf2R>}y!~U2MHS|Ed zsy8p1n3$M&)7Zo#Cr<=Cn0WCZAs)P8^eXk6?N2K4B~SE1(rIRA-tO%D?d)tPf(MC? zP#L~~&jH_WxIaI8<=ZST6q$Z<(oVjPYAY5L@Qe}~i5y_~dncdI7bc0oR$(7y;3s_L z^J5e^#G2xH?xPT@uKq&?rpUxEO)3qO0h*+x(p9!ay{MRydF}_>dfU5C-gWoW$Mlk} zj!jl7@w?B2!nZ#vPE4+Hu>s}^WY42O7b@9jYFE*Gv5}c}H(1EQzQU?FCcE}IPtSP( zC=^2e6SPQ^6rqK}cYFNp zWo3=%p)wRysCFiN!%T#!@OOc0>OK!G^aTW^l;y8Qsl`Xpn}N7KZ_o=&Cdn~GBg*Ou zuc4;0sHH5|A=a|e5AYlC;STOgN7HQ1E&QSv*e3!)rGN;ELD4UIa1C3i3$jPCZxeJ4 z@)Mb;9t*3}VI!qpG4!Yz({kjvW@)bt`xwghz=&J|-UaL37*z^_21Q7E z1cSDHu#VX)J^0-RAAINq_Q6)k-Z&@8o;~E|l4Z=zyX}P|+6mDi#t>f*?2RMJZW*Z` zv%RoCf;ro^rH`!;=N{p~&H)(<=PxKGpl2EZHy8C~Aj9Xk4Z7xV{^|UnZ`3jtANDbn z&(AxXJ1KL~=QDabuASvNKgH&Xa%ihr zZn1nH98xZ1#!Vy5a;w~HE96-HU7%CSoj2mTp|RWt7NgVhexZG5xm8~R3UX645esC} z=8%@sjrnDg_v||Nd}@{QXyaMF?rC6+)H|h3rAH*kM9(E7(MUJZJ{tKgIHQ^^#xc|Bn>TsLfh#u{c)6`4W)_Qxaf3V!;sEA=nN1v z#qN=KX=l}jldSHjBh)E_csIIe;51ZgO8rRwX#uN#1X-Axecv#8xGeJJ7~-0LhsAv za=G#m;BtNZj~MuaSQS5sVGvs=in-p`$D_}{6axO0;9(2}&Wku-E9Hjfc4kbCCG~@Q zx!vFV+#t4L8@c>td}Q|Qk4}Ui6V=8tU$3x+wP6>k`Pba2iD7}|2rAQ> zpY-pj2kK0X`j_iz{R4-C5n{;W6ef|u$;!tjo?F*&{_V71sQM6gT?>L!U;i8U&Km=5 zluZ;~6^K$EqdZP|f}$P~ z<89!F7g!&4zZoJ^w>Mw8bR%}{Hf#IHXUCi+;IcECbkI6Idm_lsR?_4r<&x&woES7QZcU#X#%)zR)W^g_54qSb<8UG#}Cvk!9(U}VO5O%1#yv|%FXbx4Jq=mnu`t`c3MIn1JBHadm@gD`uzKM9y%-!>buXG5wdW| z++_pasmAQ~;CD`nJFzFa`B2=yV3MrjlX^{z9WqbHs#QiURJEv9LyE&%Wr3(vE!C%W zFJKq$P*-)W3`kR4Y{#fSe?0f5zwh%Mz@#?n^yET%5$csP6Vik9>h1B^VGDJ-D2A7k zl#ZXu6=t5V={>+moEGCK=N4j|FO(L9@h0CTwe!fPAnQC?N-K49g_6I>6Maf9-_yOu zv+F!$I@EP1oEwPK>InqfgRnlVtCZIjw~<(1l}&+V$b`3|Tj5CQ Gfj 57 Then KeyAscii = 0 +End Sub + +Private Sub TextBoxBegin_KeyPress(ByVal KeyAscii As MSForms.ReturnInteger) + If KeyAscii < 48 Or KeyAscii > 57 Then KeyAscii = 0 +End Sub + +Private Function FillCombo(cmbBox As control, doCreds As Boolean) + With cmbBox + Call .Clear + If cmbBox.Name = "ComboLU" Or cmbBox.Name = "ComboRU" Then + If doCreds Then + Call .AddItem("") + Call .AddItem("") + End If + Call .AddItem("") + End If + + Call .AddItem("") + Call .AddItem("") + Call .AddItem("") + End With +End Function + +Private Function TextToType(aText$) As TSource + Select Case aText + Case "": TextToType = T_SOURCE_BOOK + Case "": TextToType = T_SOURCE_VOLUME + Case "": TextToType = T_SOURCE_DOCUMENT + Case "": TextToType = T_SOURCE_SECTION + Case "": TextToType = T_SOURCE_CHAPTER + Case "": TextToType = T_SOURCE_CONCEPT + End Select +End Function + +Public Property Get Data() As ItemColontitles + Set Data = New ItemColontitles + With Data + .mTopLeft = TextToType(ComboLU.Value) + .mTopRight = TextToType(ComboRU.Value) + .mBottomLeft = TextToType(ComboLD.Value) + .mBottomRight = TextToType(ComboRD.Value) + + .doTopLeft = ckLU.Value + .doTopRight = ckLD.Value + .doBottomLeft = ckRU.Value + .doBottomRight = ckRD.Value + + .start_ = CLng(TextBegin.Value) + .finish_ = CLng(TextEnd.Value) + End With +End Property diff --git a/src/dialogs/CDD_HeaderFooter.frx b/src/dialogs/CDD_HeaderFooter.frx new file mode 100644 index 0000000000000000000000000000000000000000..5a380738f9a0390d887fc84e9b328141890e807f GIT binary patch literal 9752 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 literal 0 HcmV?d00001 diff --git a/src/dialogs/CDD_TablePrototype.frm b/src/dialogs/CDD_TablePrototype.frm new file mode 100644 index 0000000..0c6b291 --- /dev/null +++ b/src/dialogs/CDD_TablePrototype.frm @@ -0,0 +1,46 @@ +VERSION 5.00 +Begin {C62A69F0-16DC-11CE-9E98-00AA00574A4F} CDD_TablePrototype + Caption = " " + ClientHeight = 1620 + ClientLeft = 120 + ClientTop = 465 + ClientWidth = 3525 + OleObjectBlob = "CDD_TablePrototype.frx":0000 + StartUpPosition = 1 'CenterOwner +End +Attribute VB_Name = "CDD_TablePrototype" +Attribute VB_GlobalNameSpace = False +Attribute VB_Creatable = False +Attribute VB_PredeclaredId = True +Attribute VB_Exposed = False +Option Explicit + +Public isCancelled_ As Boolean + +Private Sub UserForm_Initialize() + isCancelled_ = True +End Sub + +Public Function Init(nId&) + isCancelled_ = True + TextBox1.Text = Trim(Str(nId)) +End Function + +Public Property Get applyToAll() As Boolean + applyToAll = CheckBox1.Value +End Property + +Public Property Get GetPickedID() As Long + GetPickedID = CLng(TextBox1.Text) +End Property + +Private Sub okBTN_Click() + isCancelled_ = False + Me.Hide +End Sub + +Private Sub CancelBtn_Click() + isCancelled_ = True + Me.Hide +End Sub + diff --git a/src/dialogs/CDD_TablePrototype.frx b/src/dialogs/CDD_TablePrototype.frx new file mode 100644 index 0000000000000000000000000000000000000000..3e3d5dd750be4d8457aa48ecec459961c0bd66a4 GIT binary patch literal 3096 zcmeHJPe>GD6#vcar)6&CO8Kv{B|2Dy?25ux{#kcbM7Op?=-Tc&=IX9f>lQ{tbLm{& zx)^lm(jll2ItD>>5bF@sp+hO%h3c5w@6Ajy2Et+|#cz1ud*7S)z4yI;-%KL58}MUo z%3N}%7O+PRpp%gGYN=Fmm;lM0v4tY=n`f2$ z2`D$0Tj=;ZNBz$TjKJhmL=gR$CNALS-&QUQ*P&vq=jA?F$)0@srEW3s=pmls(ooW? z#CrEKp1Sc#^N|^qiDTSBo1PVKA#VuERn+5NWM;V=HjtxzO;m|Ha*hqe*0Ci{Mc2ND zIOCtkRV0zd7PXu3znY4tUFC8Neg^FGOaE68s1>cESLYAyL2|5CZr=~MTE>@HhT!Ma>V$QEgvx=!s)uFmnNcFQQlhRar z1FjRX9<3GP1>Hvlxoo3kV`*svD2;LxCTO6=T{hNPViBF4db zLcBnpHeJw$3(kUxK+*|MH2tDhYKdPcC;(8IGKM57Y8P(0XP4&{Z zPMaE5?WE7zzILf$ayPb51A55zvzg=(>XH~msi%i?H*E++R1c#DTw#-X{i)y?-*BJ! z(_6@&CF=H&4Oivn_ WBKDGJi?zz!8phAlFRqcdjmIC}l1WDZ literal 0 HcmV?d00001 diff --git a/src/z_UIMessages.bas b/src/z_UIMessages.bas new file mode 100644 index 0000000..761ffd5 --- /dev/null +++ b/src/z_UIMessages.bas @@ -0,0 +1,70 @@ +Attribute VB_Name = "z_UIMessages" +' Messaging module +Option Private Module +Option Explicit + +Public Enum MsgCode + EM_TABLE_NOT_SELECTED + EM_TABLE_MERGED_CELLS + EM_TABLE_OUTSIDE_SECTION + EM_INVALID_CONTENTS_TABLE + EM_CANNOT_INSERT_IMAGE + EM_FIX_LINING_FAIL + EM_INVALID_TABLE_COLUMNS + + IM_AUTODESIGN_OK + IM_FIX_LINES_OK + IM_REPAINT_OK + IM_FOOTER_OK + IM_FIX_BOOKMARK_NAME +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_TABLE_NOT_SELECTED: Call MsgBox(" !", vbExclamation) + Case EM_TABLE_MERGED_CELLS: Call MsgBox(" ", vbCritical) + Case EM_TABLE_OUTSIDE_SECTION: Call MsgBox(" ", vbExclamation) + Case EM_INVALID_CONTENTS_TABLE: Call MsgBox(" ! !", vbExclamation) + Case EM_CANNOT_INSERT_IMAGE: Call MsgBox(" !", vbCritical) + Case EM_FIX_LINING_FAIL: Call MsgBox(" , !", vbCritical) + Case EM_INVALID_TABLE_COLUMNS: Call MsgBox(" 2 ", vbCritical) + + Case IM_AUTODESIGN_OK: Call MsgBox(" ", vbInformation) + Case IM_FIX_LINES_OK: Call MsgBox(" ", vbInformation) + Case IM_REPAINT_OK: Call MsgBox(" !", vbInformation) + Case IM_FOOTER_OK: Call MsgBox(" !", vbInformation) + Case IM_FIX_BOOKMARK_NAME: Call MsgBox(Fmt(" , {1}", unwrapped), vbInformation) + + Case Else: Call MsgBox(" ", 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(" ", 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..f6c06a0 --- /dev/null +++ b/src/z_UIRibbon.bas @@ -0,0 +1,31 @@ +Attribute VB_Name = "z_UIRibbon" +Option Explicit + +Sub CCD_OnRibbonBtn(iControl As IRibbonControl) + Select Case iControl.ID + Case "AutoDesign": Call CDA_AutoDesign + Case "FixLines": Call CDA_FixLines + Case "ColorAll": Call CDA_Repaint + Case "PaintTable": Call CDA_PaintTable + Case "AddPict": Call CDA_InsertObject + + Case "FooterHeaderMaster": Call CDA_FooterHeader + Case "IntBlock": Call CDA_CreateBlocking + Case "UpdTOC": Call CDA_UpdateToC + + Case "InsertHeader": Call CDA_InsertHeader + Case "InsertPageBreak": Call CDA_InsertBreak + + Case "InlinePNG": Call CDA_InlineObjects + Case "InlineFields": Call CDA_InlineFields + Case "ScaleFont": Call CDA_ScaleFont + + Case "TS_Align": Call CDA_TSAlign + Case "TS_Slice": Call CDA_TSSlice + Case "TS_Paint": Call CDA_TSPaint + + Case "AuditDesign": Call CDA_Audit + + Case "Help": Call CDA_Help + End Select +End Sub diff --git a/ui/.rels b/ui/.rels new file mode 100644 index 0000000..2b00f63 --- /dev/null +++ b/ui/.rels @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/ui/customUI.xml b/ui/customUI.xml new file mode 100644 index 0000000..475ea64 --- /dev/null +++ b/ui/customUI.xml @@ -0,0 +1,98 @@ + + + + + + +