Macros/Writer/002/es

    From The Document Foundation Wiki
    < Macros‎ | Writer
    This page is a translated version of the page Macros/Writer/002 and the translation is 3% complete.


    Other languages:

    Description

    The menu Edit ▸ Links allows you to recognize the links present in a document, including:

    • File source (URL)
    • Element (range)
    • Type (soffice)
    • Refresh (automatic/manual)

    On the other hand, neither this approach, nor the navigator allows you to know which are the tables concerned (name or position in the document).

    The purpose of the below macro is to locate tables created by DDE links.[1]

    The macro inserts in the first cell of a table a comment consisting of:

    • source (URL of a Calc spreadsheet for example),
    • the range used in the source.

    (More on comment manipulation with macro in Macros/Writer/001.)

    Note that the collection TextFieldMasters would only retrieve the information displayed by the Edit ▸ Links menu and TextTables does not give us any more information.

    The DDE connection of table data is contained in an element <office:dde-source>[2].

    We can therefore browse the file content.xml to search for such elements. The program starts by checking that the current document has this file and then it proceeds to read it.

    For this we will make use of the service com.sun.star.xml.sax.Parser[3] associated with the listner com.sun.star.xml.sax.XDocumentHandler[4].

    Code

    In LibreOffice Basic:

    Option Explicit
    
    ' This library is Copyright (C) 2012 Pierre-Yves Samyn, except otherwise indicated
    ' Purpose: Frame the selection or create an empty frame if no selection
    
    ' This program is free software: you can redistribute it and/or modify
    ' it under the terms of the GNU General Public License as published by
    ' the Free Software Foundation, either version 3 of the License, or
    ' (at your option) any later version.
    ' This program is distributed in the hope that it will be useful,
    ' but WITHOUT ANY WARRANTY; without even the implied warranty of
    ' MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    ' GNU General Public License for more details.
    ' You should have received a copy of the GNU General Public License
    ' along with this program.  If not, see <http://www.gnu.org/licenses/>.
     
    Dim oDoc As Object
    Dim oDocHandler As Object
    Dim oTableName As String
    
    
    ' <div lang="en" dir="ltr" class="mw-content-ltr">
    Description of macro:
    </div>
    
    <div lang="en" dir="ltr" class="mw-content-ltr">
    ' Context    :  for LibreOffice Writer odt document
    ' Objective  :  identify the DDE-linked tables
    ' Function   :  insert a comment of the source (URL of spreadsheet for ex.), and the range
    </div>
    
    <div lang="en" dir="ltr" class="mw-content-ltr">
    ' Info about usage of UNO's XML sax parser via the API:
    </div>
    ' http://www.oooforum.org/forum/viewtopic.phtml?t=4907
    
    Sub Comment_DDE_Table()
    
        Dim oContent As Object
        Dim oFlux As Object
        Dim oSaxParser As Object
        Dim oDocEventsHandler As Object
        Dim oInputSource As Object
    
        oDoc = ThisComponent
    
        ' <span lang="en" dir="ltr" class="mw-content-ltr">Only perform macro if document is a TextDocument</span>
        If oDoc.supportsService("com.sun.star.text.TextDocument") Or _
            oDoc.supportsService("com.sun.star.text.GlobalDocument") Then
    
            ' <span lang="en" dir="ltr" class="mw-content-ltr">We want to read the content.xml file, so we check that ThisComponent makes reference to a object with such a file</span>
            If oDoc.DocumentStorage.HasByName("content.xml") Then
            
                ' <div lang="en" dir="ltr" class="mw-content-ltr">
    Test if the document has been modified:  we will read the content.xml file hence we
                ' ask for saving, to be sure to work on the most recent content
    </div>
                If oDoc.ismodified Then
                    MsgBox "<span lang="en" dir="ltr" class="mw-content-ltr">The document must be saved to latest version! (Ctrl+S)</span>", 64, "Comment_DDE_Table()"
                Else 
                    oContent = oDoc.DocumentStorage.GetByName("content.xml")
                    oFlux = oContent.GetInputStream()   
                            
                    ' <span lang="en" dir="ltr" class="mw-content-ltr">Create XML Sax parser</span>
                    oSaxParser = createUnoService( "com.sun.star.xml.sax.Parser" )
                    
                    ' <div lang="en" dir="ltr" class="mw-content-ltr">
    Create event manager.
                    ' The names given below reflect content in accordance with
    </div>
                    ' http://api.libreoffice.org/common/ref/com/sun/star/xml/sax/XDocumentHandler.html
                    oDocHandler = CreateUnoListener( "DocHandler_", "com.sun.star.xml.sax.XDocumentHandler" )
                    oSaxParser.setDocumentHandler( oDocHandler )
                       
                    ' <span lang="en" dir="ltr" class="mw-content-ltr">Creation of structure in accordance with:</span>
                    ' http://api.libreoffice.org/common/ref/com/sun/star/xml/sax/InputSource.html
    
                    oInputSource = createUnoStruct( "com.sun.star.xml.sax.InputSource" )
                    oInputSource.aInputStream = oFlux
            
                    ' <div lang="en" dir="ltr" class="mw-content-ltr">
    Tell parser to read the contents of content.xml
                    ' The functions (DocHandler_) will be called in accordance with event.
    </div>
                    oSaxParser.parseStream( oInputSource )
                    oFlux.closeInput()
                            
                    MsgBox "<span lang="en" dir="ltr" class="mw-content-ltr">End of treatment.</span>" , 64, "Comment_DDE_Table()"
                End If
            Else
                MsgBox "<span lang="en" dir="ltr" class="mw-content-ltr">This macro does not work for this type of document (needs to be odt Writer)</span>" , 64, "Comment_DDE_Table()"
            End If
    
            Else
            MsgBox "<span lang="en" dir="ltr" class="mw-content-ltr">This macro does not work for this type of document (needs to be odt Writer)</span>" , 64, "Comment_DDE_Table()"
        End If
    
    End Sub ' Comment_DDE_Table
    
    
    ' <span lang="en" dir="ltr" class="mw-content-ltr">Below, the functions of listener, corresponding to events:</span>
    ' http://api.libreoffice.org/common/ref/com/sun/star/xml/sax/XDocumentHandler.html
    
    Sub DocHandler_startDocument()
    End Sub
    
    Sub DocHandler_endDocument()
    End Sub
    
    Sub DocHandler_startElement( cName As String, oAttributes As com.sun.star.xml.sax.XAttributeList )
    
        Dim oTable As Object
        Dim oCursor As Object
        Dim oComment As Object
    
        Dim oDateHour As New com.sun.star.util.DateTime
    
        ' <span lang="en" dir="ltr" class="mw-content-ltr">If the element is a table, store its name</span>
        If cName = "table:table" Then
            oTableName = oAttributes.getValueByName("table:name")
        End If   
    
        ' <div lang="en" dir="ltr" class="mw-content-ltr">
    See OASIS Open Document Format for Office Applications:
        ' http://docs.oasis-open.org/office/v1.2/os/OpenDocument-v1.2-os.html
        ' The DDE data connection of tables is contained in an <office:dde-source> element.
        ' The usage of this element differs between spreadsheet and text document tables. 
        ' For text document tables, the element is contained within the table's <table:table> 
        ' element directly.
        ' Hence test if the table is DDE-linked:
    </div>
        If cName = "office:dde-source" Then
    
            ' <span lang="en" dir="ltr" class="mw-content-ltr">Access the table:</span>
            oTable = oDoc.TextTables.getByName(oTableName)
    
            ' <span lang="en" dir="ltr" class="mw-content-ltr">Create a cursor in the first cell of the table:</span>
            oCursor = oTable.getCellByPosition(0, 0).createTextCursor
    
            ' <span lang="en" dir="ltr" class="mw-content-ltr">Create a comment:</span>
            oComment = oDoc.createInstance("com.sun.star.text.textfield.Annotation")
    
            ' <span lang="en" dir="ltr" class="mw-content-ltr">Get time-stamp of right now:</span>
            With oDateHour
                .Minutes = minute(now)
                .Hours = hour(now)
                .Day = day(now)
                .Month = month(now)
                .Year = year(now)
            End With
             
            ' <span lang="en" dir="ltr" class="mw-content-ltr">Fill the comment with DDE source and range</span>
            With oComment
                .Author = "Source: DDE link"
                .Content = oAttributes.getValueByName("office:dde-item") & chr(13) &_
                    oAttributes.getValueByName("office:dde-topic")
                .DateTimeValue = oDateHour
            End With
    
            ' <span lang="en" dir="ltr" class="mw-content-ltr">Insert the comment in the cell</span>
            oComment.attach(oCursor.start)
        End If
    
    End Sub ' DocHandler_startElement
    
    
    Sub DocHandler_endElement( cName As String )
    End Sub
    
    Sub DocHandler_characters( cChars As String )
    End Sub
    
    Sub DocHandler_ignorableWhitespace( cWhitespace As String )
    End Sub
    
    Sub DocHandler_processingInstruction( cTarget As String, cData As String )
    End Sub
    
    Sub DocHandler_setDocumentLocator( oLocator As com.sun.star.xml.sax.XLocator )
    End Sub

    Notes

    1. DDE: "Dynamic Data Exchange", allows you to link objects by reference to the file, without embedding them.
    2. See the standard OASIS Open Document Format for Office Applications. The use of this element differs between spreadsheet and word processing. For text documents, the element is contained directly inside the element <table:table>.
    3. See the API documentation for com.sun.star.xml.sax.Parser
    4. See the API documentation for com.sun.star.xml.sax.XDocumentHandler