libreofficelibreoffice-basiclibreoffice-macros

Insert image into LibreOffice as Link using API/Macro


Starting from Pitonyak, I adapted some code that will insert a picture into a Writer/Draw/Impress/Calc document

import uno
from com.sun.star.awt import Point, Size
furl = 'https://upload.wikimedia.org/wikipedia/commons/1/1a/Blank_US_Map_%28states_only%29.svg'
oDoc= XSCRIPTCONTEXT.getDocument()
oShape = oDoc.createInstance("com.sun.star.drawing.GraphicObjectShape")

oShape.GraphicURL = furl
oDoc.getDrawPages().getByIndex(0).add(oShape)
oShape.setSize(oShape.Graphic.Size100thMM)
oShape.setPosition(Point(1*2540, 1*2540))

This is Python code, but I could probably adapt working StarBasic or Java code.

I cannot figure out how to use the API to insert the image as a link. I've poked around with MRI to try to find some methods or properties to try.

I've inspected a manually inserted linked image. It has GraphicsURL.OriginURL and Graphic.OriginURL properties that are set to the right path. I cannot figure out how to set those properties in code.


Solution

  • The behavior of GraphicURL was changed in LibreOffice 6.1. Apparently, the statement from Pitonyak that "Graphic objects inserted using the API are inserted as links" is no longer true. In fact, the code below pops up a dialog asking whether to keep the link or not.

    Pitonyak Listing 5.27 shows the AsLink property with the dispatcher, so we can write the code this way.

    import uno
    
    def insertLinkedImage():
        ctx = XSCRIPTCONTEXT.getComponentContext()
        smgr = ctx.ServiceManager
        oDisp = smgr.createInstanceWithContext(
            "com.sun.star.frame.DispatchHelper", ctx)
        oDoc = XSCRIPTCONTEXT.getDocument()
        oFrame = oDoc.getCurrentController().getFrame()
        furl = 'https://upload.wikimedia.org/wikipedia/commons/1/1a/Blank_US_Map_%28states_only%29.svg'
        props = (
            createProp("FileName", furl),
            createProp("AsLink", True)
        )
        oDisp.executeDispatch(oFrame, ".uno:InsertGraphic", "", 0, props)
    
    def createProp(name, value):
        """Creates an UNO property."""
        prop = uno.createUnoStruct("com.sun.star.beans.PropertyValue")
        prop.Name = name
        prop.Value = value
        return prop
    

    A discussion on setting image properties after inserting with the dispatcher is at https://forum.openoffice.org/en/forum/viewtopic.php?t=25505:

    oDrawPageObj = oDrawPage.getByIndex(oDrawPage.Count - 1)

    The new way to embed a graphic with the API is shown at LibreOffice Calc C# SDK: program to insert images into cells, stuck trying to create XGraphic. I didn't see any obvious way to insert as link with that interface.

    oProvider = smgr.createInstanceWithContext(
        "com.sun.star.graphic.GraphicProvider", ctx)
    props = (createProp("URL", furl),)
    oShape.Graphic = oProvider.queryGraphic(props)