Comment repérer les tableaux fondés sur un lien DDE ?

From The Document Foundation Wiki
< Macros‎ | Writer
Jump to: navigation, search

Description

Le menu Édition ▸ Liens permet de connaître les liens figurant dans un document :

  • Fichier source (Url)
  • Élément (plage)
  • Type (soffice)
  • Actualiser (automatique / manuel)

En revanche ni cette commande, ni le navigateur ne permettent de savoir quels sont les tableaux concernés (nom ou position dans le document).

L'objet du programme présenté ici est de repérer les tableaux créés par lien DDE[1]

Le programme insère dans la première cellule du tableau un commentaire comprenant :

  • la source (Url du classeur par exemple),
  • la plage utilisée dans la source.

La gestion des commentaires n'est pas détaillée ici. Se reporter à Comment insérer un commentaire par programme.

La collection TextFieldMasters permettrait de retrouver uniquement les informations affichées par le menu Édition ▸ Liens et TextTables ne nous renseigne pas davantage.

La connexion DDE des données des tables est contenue dans un élément <office:dde-source>[2].

Nous pouvons donc parcourir le fichier content.xml à la recherche de ces éléments. Le programme commence par vérifier que le document courant dispose bien de ce fichier puis il procède à sa lecture.

Nous utilisons pour cela le service com.sun.star.xml.sax.Parser.[3] associé à un listener com.sun.star.xml.sax.XDocumentHandler[4].

Code

En 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 oNomTable As String


' Procedure principale

' Contexte :  document Writer
' Objet    :  repérer les tableaux créés par lien DDE
' Fonction :  insérer un commentaire comprenant la source (Url classeur par ex.) et la plage

' Source pour l'utilisation UNO's XML sax parser via the API :
' http://www.oooforum.org/forum/viewtopic.phtml?t=4907

Sub CommenterTableauxDDE

    Dim oContenu As Object
    Dim oFlux As Object
    Dim oSaxParser As Object
    Dim oDocEventsHandler As Object
    Dim oInputSource As Object

    oDoc = ThisComponent

    ' Ne travaille que sur les documents texte...
    If oDoc.supportsService("com.sun.star.text.TextDocument") Or _
        oDoc.supportsService("com.sun.star.text.GlobalDocument") Then

        ' On veut lire le content.xml, donc verifie que thiscomponent fait reference à un
        ' objet disposant de ce fichier
        If oDoc.DocumentStorage.HasByName("content.xml") Then
        
            ' Test si le document a été modifié : on va lire le content.xml donc on demande
            ' l'enregistrement pour être sûr de travailler sur le contenu mis à jour
            If oDoc.ismodified Then
                MsgBox "Le document doit être enregistré", 64, "Commenter la source des tableaux DDE"
            Else 
                oContenu = oDoc.DocumentStorage.GetByName("content.xml")
                oFlux = oContenu.GetInputStream()   
                        
                ' Creation Sax parser Xml 
                oSaxParser = createUnoService( "com.sun.star.xml.sax.Parser" )
                
                ' Creation gestionnaire evenements
                ' Les procedures associees reprennent le nom donné ici suivi du nom des
                ' evenements de l'interface cf. :
                ' 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 )
                   
                ' Creation de la structure cf. :
                'http://api.libreoffice.org/common/ref/com/sun/star/xml/sax/InputSource.html

                oInputSource = createUnoStruct( "com.sun.star.xml.sax.InputSource" )
                oInputSource.aInputStream = oFlux
        
                ' Demarrer l'analyse syntaxique (parser) qui va lire le content.xml
                ' Les méthodes - cf. procedures DocHandler_ - seront appelées selon l'evenement correspondant
                oSaxParser.parseStream( oInputSource )
                oFlux.closeInput()
                        
                MsgBox "Fin du traitement" , 64, "Commenter la source des tableaux DDE"
            End If
        Else
            MsgBox "Ne peut travailler sur ce type de document" , 64, "Commenter la source des tableaux DDE"
        End If

        Else
        MsgBox "Ne peut travailler sur ce type de document" , 64, "Commenter la source des tableaux DDE"
    End If

End Sub ' CommenterTableauxDDE


' Ci-dessous les procedures du listener, correspondants aux evenements :
' 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 oCurseur As Object
    Dim oAnnot As Object

    Dim oDateHeure As New com.sun.star.util.DateTime

    ' Si l'element est un tableau, memorisation de son nom
    If cName = "table:table" Then
        oNomTable = oAttributes.getValueByName("table:name")
    End If   

    ' Cf. OASIS Open Document Format for Office Applications :
    ' http://docs.oasis-open.org/office/v1.2/os/OpenDocument-v1.2-os.html
    ' The DDE connection data 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.
    ' Donc test si tableau lien DDE...
    If cName = "office:dde-source" Then

        ' Acces au tableau
        oTable = oDoc.TextTables.getByName(oNomTable)

        ' Creation d'un curseur dans la premiere cellule du tableau
        oCurseur = oTable.getCellByPosition(0, 0).createTextCursor

        ' Creation d'un commentaire
        oAnnot = oDoc.createInstance("com.sun.star.text.textfield.Annotation")

        ' Recupere la date et heure courante         
        With oDateHeure
            .Minutes = minute(now)
            .Hours = hour(now)
            .Day = day(now)
            .Month = month(now)
            .Year = year(now)
        End With
         
        ' Renseigne le commentaire avec la source DDE et la plage 
        With oAnnot
            .Author = "Source : Lien DDE"
            .Content = oAttributes.getValueByName("office:dde-item") & chr(13) &_
                oAttributes.getValueByName("office:dde-topic")
            .DateTimeValue = oDateHeure
        End With

        ' Inserer effectivement le commentaire dans la cellle        
        oAnnot.attach(oCurseur.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", échange dynamique de données. DDE permet de lier les objets par référence au fichier, mais non de les incorporer.
  2. Cf.la norme OASIS Open Document Format for Office Applications l'usage de cet élément diffère entre le tableur et le traitement de textes. Pour les documents texte, l'élément est contenu directement à l'intérieur de l'élément <table:table>.
  3. Voir la documentation de l'API
  4. Voir la documentation de l'API