epublishing/ePublishing/Endnotes.xba

466 lines
No EOL
17 KiB
XML

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE script:module PUBLIC "-//OpenOffice.org//DTD OfficeDocument 1.0//EN" "module.dtd">
<script:module xmlns:script="http://openoffice.org/2000/script" script:name="Endnotes" script:language="StarBasic" script:moduleType="normal">Global Const endnoteFieldPrefix = &quot;custom_endnote_&quot;
Global Const endnoteInTextAnchorSuffix = &quot;-text_anchor&quot;
Global Const endnoteInBodyAnchorSuffix = &quot;-body_anchor&quot;
Sub convertEndnotesExecution
Dim oSelections As Object
Dim oAnchor1 As Object
Dim oAnchor2 As Object
Dim oAnchor1Name As String
Dim oAnchor2Name As String
Dim foundEndNotes() As Object
Dim textSelection As Object
Dim nativeEndnotesCounter As Integer
Dim customEndnotesCounter As Integer
If IsNull(ThisComponent) Then
MsgBox getTranslation(&quot;something weird happened error text&quot;)
Exit Sub
End If
oSelections = ThisComponent.getCurrentSelection()
If NOT oSelections.supportsService(&quot;com.sun.star.text.TextRanges&quot;) Then
MsgBox getTranslation(&quot;EndnotesNotFound&quot;)
Exit Sub
End If
objectsCount = oSelections.getCount()
If objectsCount &gt; 1 Then
MsgBox getTranslation(&quot;too much selections&quot;)
Exit Sub
End If
textSelection = oSelections.getByIndex(0)
foundEndNotes() = findEndNotesInSelection(textSelection)
nativeEndnotesCounter = UBound(foundEndNotes(0))
customEndnotesCounter = UBound(foundEndNotes(1))
If (nativeEndnotesCounter = -1 And customEndnotesCounter = -1 ) Then
MsgBox getTranslation(&quot;EndnotesNotFound&quot;)
Exit Sub
EndIf
If ( customEndnotesCounter = -1 ) Then
&apos;only native found window convert to custom?
&apos;Window Select paragraph for endnotes output or cancel
runEndnotesConversionDialog(foundEndNotes(0))
Exit Sub
EndIf
If (nativeEndnotesCounter = -1 ) Then
&apos;only custom endnotes found. Window convert to native?
runEndnotesCustomToNativeDialog(foundEndNotes(1))
Exit Sub
EndIf
&apos;both custom and native endnotes found
&apos;convert to custom all or
&apos;convert to native
runDualEndnotesDialog(foundEndNotes(0),foundEndNotes(1))
End Sub
Sub runDualEndnotesDialog(nativeEndNotes() As Object,customEndnotes() As Object)
Dim dialog As Object
waitingForDialog = true
dialog = notModalDialog(&quot;EndnotesConversion&quot;)
dialog.getControl(&quot;found&quot;).SetText(getTranslation(&quot;EndnotesNativeDialogFound&quot;) &amp; CStr(UBound(nativeEndNotes)+1))
dialog.getControl(&quot;found2&quot;).SetText(getTranslation(&quot;EndnotesCustomDialogFound&quot;) &amp; CStr(UBound(customEndnotes)+1))
dialog.getControl(&quot;found2&quot;).Model.EnableVisible = TRUE
dialog.getControl(&quot;description&quot;).SetText(getTranslation(&quot;EndnotesConversionTwoOptions&quot;))
dialog.getControl(&quot;cancel&quot;).Label = getTranslation(&quot;buttonCancel&quot;)
dialog.getControl(&quot;start&quot;).Label = getTranslation(&quot;toNativeEndnotes&quot;)
dialog.getControl(&quot;option2&quot;).Label = getTranslation(&quot;toCustomEndnotes&quot;)
dialog.getControl(&quot;option2&quot;).Model.EnableVisible = TRUE
dialog.setvisible(true)
Do While waitingForDialog
If dialog.getControl(&quot;cancel&quot;).model.state = 1 then
exit Do
EndIf
If dialog.getControl(&quot;start&quot;).model.state = 1 then
convertCustomEndnotesToNative(customEndnotes)
exit Do
EndIf
If dialog.getControl(&quot;option2&quot;).model.state = 1 then
convertEndnotesToCustom(nativeEndNotes)
exit Do
EndIf
wait (100)
Loop
dialog.dispose
End Sub
Sub runEndnotesCustomToNativeDialog(customEndnotes() As Object)
Dim dialog As Object
waitingForDialog = true
dialog = notModalDialog(&quot;EndnotesConversion&quot;)
dialog.getControl(&quot;found&quot;).SetText(getTranslation(&quot;EndnotesCustomDialogFound&quot;) &amp; CStr(UBound(customEndnotes)+1))
dialog.getControl(&quot;description&quot;).SetText(getTranslation(&quot;EndnotesCustomConversionOption&quot;))
dialog.getControl(&quot;cancel&quot;).Label = getTranslation(&quot;buttonCancel&quot;)
dialog.getControl(&quot;start&quot;).Label = getTranslation(&quot;buttonOk&quot;)
dialog.setvisible(true)
Do While waitingForDialog
If dialog.getControl(&quot;cancel&quot;).model.state = 1 then
exit Do
EndIf
If dialog.getControl(&quot;start&quot;).model.state = 1 then
convertCustomEndnotesToNative(customEndnotes)
exit Do
EndIf
wait (100)
Loop
dialog.dispose
End Sub
Sub convertCustomEndnotesToNative(foundEndnotes() As Object)
Dim i As Long
Dim bodyAnchorName As String
Dim textAnchorName As String
Dim bookmarksName As String
Dim bookmarks As Object
bookmarksName = ThisComponent.Links.ElementNames(6)
bookmarks = ThisComponent.Links.getByName(bookmarksName)
For i = LBound(foundEndnotes) To UBound(foundEndnotes)
bodyAnchorName = getBodyAnchorName(foundEndnotes(i))
textAnchorName = getTextAnchorName(bodyAnchorName)
If bookmarks.hasByName(bodyAnchorName) And bookmarks.hasByName(textAnchorName) Then
convertLinksToEndnote(bodyAnchorName,textAnchorName)
EndIf
Next i
End Sub
Function getBodyAnchorName(textRange As Object) As String
getBodyAnchorName = &quot;&quot;
If (Len(textRange.HyperLinkURL) &gt; 0) Then
getBodyAnchorName = Right(textRange.HyperLinkURL,Len(textRange.HyperLinkURL)-1)
EndIf
End Function
Function getTextAnchorName(bodyAnchorName As String) As String
getTextAnchorName = &quot;&quot;
If Len(bodyAnchorName) &gt; Len(endnoteInBodyAnchorSuffix) Then
getTextAnchorName = Left(bodyAnchorName,Len(bodyAnchorName)-Len(endnoteInBodyAnchorSuffix)) &amp; endnoteInTextAnchorSuffix
EndIf
End Function
Sub convertLinksToEndnote(forwardLink As String,backwardLink As String)
Dim bookMarkName As String
bookmarkName = ThisComponent.Links.ElementNames(6)
Dim bookmarks As Object
bookmarks = ThisComponent.Links.getByName(bookmarkName)
Dim forward As Object
Dim backward As Object
Dim oViewCursor As Object
Dim footNoteSign As String
oViewCursor = ThisComponent.CurrentController.getViewCursor()
Dim oTextCursor As Object
If NOT bookmarks.hasByName(forwardLink) OR NOT bookmarks.hasByName(backwardLink) Then
exit sub
EndIf
forward = bookmarks.getByName(forwardLink)
backward = bookmarks.getByName(backwardLink)
footNoteSign = forward.Anchor.String
oViewCursor.goToRange(forward.Anchor,false)
SendRM
SendRM
oTextCursor = oViewCursor.Text.createTextCursorByRange(oViewCursor)
goToEndOfEndnoteBody(oTextCursor)
oTextCursor.goToRange(oViewCursor,true)
oViewCursor.goToRange(oTextCursor,true)
unoCut()
SendRM
oViewCursor.goToRange(backward.Anchor,false)
removeEndnoteSignInText()
createEndnote
unoPaste()
oViewCursor.getText.setLabel(footNoteSign)
forward.dispose()
backward.dispose()
End Sub
Sub goToEndOfEndnoteBody(oTextCursor As Object)
Dim position As Object
position = oTextCursor.End
oTextCursor.goToEndOfParagraph(false)
oTextCursor.goRight(1,false)
If oTextCursor.ParaStyleName &lt;&gt; &quot;Endnote&quot; OR oTextCursor.CharStyleName = &quot;Endnote Symbol&quot; Then
oTextCursor.goLeft(1,false)
Exit Sub
EndIf
&apos;Got to the end of the document
If oTextCursor.Text.compareRegionEnds(position,oTextCursor.End) = 0 Then
Exit Sub
EndIf
goToEndOfEndnoteBody(oTextCursor)
End Sub
Sub removeEndnoteSignInText()
Dim oViewCursor As Object
Dim character As String
oViewCursor = ThisComponent.CurrentController.getViewCursor()
oViewCursor.String = &quot;&quot;
oViewCursor.HyperLinkURL=&quot;&quot;
End Sub
sub createEndnote
dim document as object
dim dispatcher as object
rem ----------------------------------------------------------------------
rem get access to the document
document = ThisComponent.CurrentController.Frame
dispatcher = createUnoService(&quot;com.sun.star.frame.DispatchHelper&quot;)
dispatcher.executeDispatch(document, &quot;.uno:InsertEndnote&quot;, &quot;&quot;, 0, Array())
end Sub
Sub runEndnotesConversionDialog(foundEndNotes As Variant)
Dim dialog As Object
waitingForDialog = true
dialog = notModalDialog(&quot;EndnotesConversion&quot;)
dialog.getControl(&quot;found&quot;).SetText(getTranslation(&quot;EndnotesNativeDialogFound&quot;) &amp; CStr(UBound(foundEndNotes)+1))
dialog.getControl(&quot;description&quot;).SetText(getTranslation(&quot;EndnotesNativeDialogDescriptionSelect&quot;))
dialog.getControl(&quot;cancel&quot;).Label = getTranslation(&quot;buttonCancel&quot;)
dialog.getControl(&quot;start&quot;).Label = getTranslation(&quot;buttonOk&quot;)
dialog.setvisible(true)
Do While waitingForDialog
If dialog.getControl(&quot;cancel&quot;).model.state = 1 then
exit Do
EndIf
If dialog.getControl(&quot;start&quot;).model.state = 1 then
convertEndnotesToCustom(foundEndNotes)
exit Do
EndIf
wait (100)
Loop
dialog.dispose
End Sub
Sub convertEndnotesToCustom(foundEndNotes As Variant)
Dim oViewCursor As Object
Dim outputPosition As Object
Dim endnoteSigns() As String
Dim fieldPrefix As String
Dim i As Integer
oViewCursor = ThisComponent.CurrentController.getViewCursor()
oViewCursor.goToStartOfLine(false)
outputPosition = oViewCursor.Text.createTextCursorByRange(oViewCursor)
endnoteSigns = getEndnoteSigns(foundEndNotes)
fieldPrefix = createEndnoteFieldPrefix()
For i = LBound(foundEndNotes) To Ubound(foundEndNotes)
convertNativeEndnoteToCustom(endnoteSigns(i), foundEndNotes(i),outputPosition,fieldPrefix, i)
Next i
End Sub
Function createEndnoteFieldPrefix As String
Dim names() As String
Dim prefix As String
names = ThisComponent.getTextFieldMasters().getElementNames()
prefix = endnoteFieldPrefix &amp; RND_String() &amp; &quot;_&quot;
If NOT startsWithInArray(prefix, names) Then
createEndnoteFieldPrefix = prefix
Exit Function
EndIf
createEndnoteFieldPrefix = prefix
End Function
Function startsWithInArray(prefix As String, names As Variant) As Boolean
Dim i As Long
For i = LBound(names) To Ubound(names)
If InStr(names(i), &quot;com.sun.star.text.fieldmaster.User.&quot; &amp; prefix) = 1 Then
startsWithInArray = true
Exit Function
EndIf
Next i
startsWithInArray = false
End Function
Sub convertNativeEndnoteToCustom(sign As String, nativeEndNoteTextRange As Object,outputPosition As Object, fieldPrefix As String, num As Integer)
&apos;Globalscope.BasicLibraries.LoadLibrary( &quot;MRILib&quot; )
Dim oViewCursor As Object
Dim oTextCursor As Object
Dim endNote As Object
Dim anchorInBody As Object
Dim anchorInText As Object
Dim bodyAnchorName As String
Dim textAnchorName As String
endNote = nativeEndNoteTextRange.Footnote
oViewCursor = ThisComponent.CurrentController.getViewCursor()
oViewCursor.goToRange(nativeEndNoteTextRange.Footnote.Text.Start,false)
oViewCursor.goToRange(nativeEndNoteTextRange.Footnote.Text.End,true)
If oViewCursor.String = &quot;&quot; Then
oViewCursor.String = &quot; &quot;
EndIf
unoCut()
oViewCursor.goToRange(outputPosition,false)
getEndnotePara()
oViewCursor.ParaStyleName = &quot;Endnote&quot;
anchorInBody = createEndnoteSign(outputPosition, sign, fieldPrefix &amp; num, true)
addEndnoteSpacer(fieldPrefix)
unoPaste()
outputPosition = oViewCursor.End
oViewCursor.goToRange(nativeEndNoteTextRange,false)
endNote.dispose()
anchorInText = createEndnoteSign(oViewCursor, sign, fieldPrefix &amp; num, false)
bodyAnchorName = fieldPrefix &amp; num &amp; endnoteInBodyAnchorSuffix
textAnchorName = fieldPrefix &amp; num &amp; endnoteInTextAnchorSuffix
anchorInBody.goRight(1,true)
anchorInText.goRight(1,true)
createAnchor(anchorInBody, bodyAnchorName )
createAnchor(anchorInText,textAnchorName )
createLink(anchorInBody,anchorInBody.String, textAnchorName)
createLink(anchorInText,anchorInText.String, bodyAnchorName)
End Sub
Sub getEndnotePara()
Dim oViewCursor As Object
Dim oTextCursor As Object
oViewCursor = ThisComponent.CurrentController.getViewCursor()
oTextCursor = oViewCursor.Text.createTextCursorByRange(oViewCursor.Start)
oTextCursor.gotoStartOfParagraph(false)
oTextCursor.gotoEndOfParagraph(true)
If Len(oTextCursor.String) &gt; 0 Then
oViewCursor.Text.insertControlCharacter(oViewCursor.End,com.sun.star.text.ControlCharacter.PARAGRAPH_BREAK,False)
EndIf
End Sub
Function createEndnoteSign(cursor As Object,sign As String,fieldName As String, inBody As Boolean) As Object
Dim oField As Object &apos;Field to insert
Dim oFieldMaster As Object
Dim oTextCursor As Object
Dim oMasters As Object
oTextCursor = cursor.Text.createTextCursorByRange(cursor.Start)
If inBody Then
oTextCursor.CharStyleName = &quot;Endnote Symbol&quot;
Else
oTextCursor.CharStyleName = &quot;Endnote anchor&quot;
EndIf
oField = ThisComponent.createInstance(&quot;com.sun.star.text.textfield.User&quot;)
oMasters = ThisComponent.getTextFieldMasters()
If oMasters.hasByName(&quot;com.sun.star.text.FieldMaster.User&quot; &amp; &quot;.&quot; &amp; fieldName) Then
oFieldMaster = oMasters.getByName(&quot;com.sun.star.text.FieldMaster.User&quot; &amp; &quot;.&quot; &amp; fieldName)
oFieldMaster.Name = fieldName
oFieldMaster.Content = sign
Else
oFieldMaster = ThisComponent.createInstance(&quot;com.sun.star.text.FieldMaster.User&quot;)
oFieldMaster.Name = fieldName
oFieldMaster.Content = sign
EndIf
oField.attachTextFieldMaster(oFieldMaster)
oTextCursor.Text.insertTextContent(oTextCursor, oField, False)
oTextCursor.CharStyleName = &quot;Standard&quot;
oTextCursor.goLeft(1,false)
createEndnoteSign = oTextCursor
End Function
Sub addEndnoteSpacer(fieldPrefix As String)
Dim oViewCursor As Object
oViewCursor = ThisComponent.CurrentController.getViewCursor()
insertUserField(oViewCursor,fieldPrefix &amp; &quot;spacer&quot;,&quot; &quot;)
End Sub
Function getEndnoteSigns(foundEndNotes As Variant) As Variant
Dim i As Integer
Dim signs() As String
For i = LBound(foundEndNotes) To Ubound(foundEndNotes)
AddToArray(signs, foundEndNotes(i).String)
Next i
getEndnoteSigns = signs
End Function
Function notModalDialog(dialogName As String) As Variant
Dim windowProvider As Object
Dim containerWindow As Object
Dim handler As Object
Dim dialogUrl As String
Dim dialog As Object
containerWindow = ThisComponent.getCurrentController().getFrame().getContainerWindow()
dialogUrl = &quot;vnd.sun.star.script:ePublishing.&quot; &amp; dialogName &amp; &quot;?location=application&quot;
windowProvider = CreateUnoService(&quot;com.sun.star.awt.ContainerWindowProvider&quot;)
dialog = windowProvider.createContainerWindow(dialogUrl, &quot;&quot;, containerWindow, handler)
notModalDialog = dialog
End Function
Function findEndNotesInSelection(textSelection) As Variant
Dim nativeEndNotes() As Object
Dim customEndNotes() As Object
Dim outerArray() As Object
findEndNotesInSelection = Array()
Dim enum1Element As Object
Dim cellEnumElement As Object
Dim enum1 As Object
Dim enum2 As Object
Dim curNum As Integer
Dim i As Integer
Dim cell As Object
Dim cellEnum As Object
enum1 = textSelection.createEnumeration
While enum1.hasMoreElements
enum1Element = enum1.nextElement
If enum1Element.supportsService(&quot;com.sun.star.text.Paragraph&quot;) Then
findEndNotesInParagraph(enum1Element, nativeEndNotes, customEndNotes)
ElseIf enum1Element.supportsService(&quot;com.sun.star.text.TextTable&quot;) Then
cellNames = enum1Element.cellNames
For i = LBound(cellNames) To Ubound(cellNames)
cell = enum1Element.getCellByName(cellNames(i))
cellEnum = cell.getText().createEnumeration()
While cellEnum.hasMoreElements
cellEnumElement = cellEnum.nextElement
If cellEnumElement.supportsService(&quot;com.sun.star.text.Paragraph&quot;) Then
findEndNotesInParagraph(cellEnumElement, nativeEndNotes, customEndNotes)
EndIf
Wend
Next i
EndIf
Wend
addToArray(outerArray, nativeEndNotes)
addToArray(outerArray, customEndNotes)
findEndNotesInSelection = outerArray
End Function
Sub findEndNotesInParagraph(enum1Element As Object,nativeEndNotes As Variant, customEndNotes As Variant)
Dim textPortions As Object
Dim thisPortion As Object
Dim footnoteText As Object
Dim label As String
Dim labelNum As Long
Dim bookmarkName As String
If enum1Element.OutlineLevel = level Then
curNum = 1
EndIf
textPortions = enum1Element.createEnumeration
While textPortions.hasMoreElements
thisPortion = textPortions.nextElement
If isTargetNote(thisPortion,1) Then
AddToArray(nativeEndNotes, thisPortion)
ElseIf isCustomEndnote(thisPortion) Then
AddToArray(customEndNotes, thisPortion)
EndIf
Wend
End Sub
Function isCustomEndnote(portion As Object) As Boolean
If InStr(portion.HyperLinkURL, &quot;#&quot; &amp; endnoteFieldPrefix) = 1 And portion.String &lt;&gt; &quot;&quot; Then
If InStr(portion.HyperLinkURL, endnoteInBodyAnchorSuffix) &gt; 0 Then
isCustomEndnote = true
Exit Function
EndIf
EndIf
isCustomEndnote = false
End Function
</script:module>