Search code examples
pythonlibreofficeunolibreoffice-writer

How to insert a Libreoffice writer Annotation with a date using Python


Please note, this is a self answered question for reference.
Most of the references to com.sun.star.text.textfield.Annotation refer to Date as being a :: com :: sun :: star :: util :: reference but no end of fiddling about with the contents will actually create an annotation with a date.
Setting Date.Year, Date.Month and Date.Day will appear successful but the annotation itself still appears without a date i.e.

anno = model.createInstance("com.sun.star.text.textfield.Annotation")
anno.Content = "this is my annotation/comment"
anno.Author = doc.DocumentProperties.Author
anno.Date.Year = 2020
anno.Date.Month = 5
anno.Date.Day = 18

enter image description here


Solution

  • The documentation is not always complete, or is not obvious, depending upon where you look.
    For LibreOffice 6.0 https://api.libreoffice.org/docs/idl/ref/Annotation_8idl_source.html
    The Annotation.idl is described as:

     service  com::sun::star::text::TextField;
     [property]string Author;
     [optional, property]string Initials;
     [optional, property]string Name;
     [property]string Content;
     [property]com::sun::star::util::Date Date;
     [optional, property]com::sun::star::util::DateTime DateTimeValue;
    

    The key here is the optional DateTimeValue which it would appear is the item that needs to be set to provide the Annotation with a Date and Time.
    DateTimeValue structure is from com.sun.star.util.DateTime
    To create an annotation (with a date and time) in a writer document using a python script, use the following as a template.

    from uno import createUnoStruct
    import time
    
    def fs_Annotation(*args):
        #get the doc from the scripting context which is made available to all scripts
        desktop = XSCRIPTCONTEXT.getDesktop()
        model = desktop.getCurrentComponent()
        try:
            text = model.Text
        except:
            # The macro has been called externally but LibreOffice was not running at the time
            return None
        tRange = text.End
        cursor = desktop.getCurrentComponent().getCurrentController().getViewCursor()
        doc = XSCRIPTCONTEXT.getDocument()
        # you cannot insert simple text and text into a table with the same method
        # so we have to know if we are in a table or not.
        # oTable and oCurCell will be null if we are not in a table
        oTable = cursor.TextTable
        oCurCell = cursor.Cell
    
        anno = model.createInstance("com.sun.star.text.textfield.Annotation")
    
        anno.Content = "this is my annotation/comment"
        #Use documents author
        #anno.Author = doc.DocumentProperties.Author
        #Use hardcoded text
        anno.Author = "Joe Bloggs"
    
        t = time.localtime()
        dtv=createUnoStruct("com.sun.star.util.DateTime")
        dtv.Year = t.tm_year
        dtv.Month = t.tm_mon
        dtv.Day = t.tm_mday
        dtv.Hours = t.tm_hour
        dtv.Minutes= t.tm_min
        dtv.Seconds = t.tm_sec
        dtv.NanoSeconds = 0
        anno.DateTimeValue = dtv
    
        if oCurCell == None:    # Inserting into text
            text.insertTextContent(cursor, anno, True)
        else:                   # Inserting into a table
            oCurCell.insertTextContent(cursor, anno, False)
        return None
    

    enter image description here