Search code examples
pythonmacroslibreofficeuno

How do I write a python macro in libreoffice writer to send a receive data


I am working in libreoffice writer and need to send a request to another program that I know to be listening on a TCP port, which will return data that needs to be inserted into the current Writer document. The macro needs to allow the data to be inserted as normal open text or into a cell within a table in which the cursor is presently positioned. The UNO documentation is spectacularly unclear and difficult to navigate.


Solution

  • def fs2ClientdataDoc(*args):
    #get the doc from the scripting context which is made available to all scripts
        desktop = XSCRIPTCONTEXT.getDesktop()                                      
        model = desktop.getCurrentComponent()
    #get the XText interface
        try:
            text = model.Text
        except AttributeError:
            raise Exception("This script is for Writer Documents only")
    
    #create an XTextRange at the end of the document
        tRange = text.End
        cursor = Desktop.getCurrentComponent().getCurrentController().getViewCursor()
    # your 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
    #and get the string from Footswitch2 via a TCP port
        import os, socket, time
        from configobj import ConfigObj
        configuration_dir = os.environ["HOME"]
        config_filename = configuration_dir + "/fs2.cfg"
        if os.access(config_filename, os.R_OK):
            pass
        else:
            return None
        cfg = ConfigObj(config_filename)
    #define values to use from the configuration file
        tcp_port = int(cfg["control"]["TCP_PORT"])
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock.settimeout(0.5)
        try:
            sock.connect(("localhost", tcp_port))
        except:
            return None
        sock.settimeout(5)
        try:
            sock.send(bytes('client\n', 'UTF-8'))
        except:
            return None
        try:
            time.sleep(1.0)
            s_list = sock.recv(4096).decode('UTF-8')
            s_list = s_list.split("\n")
        except:
            return None
        lines_in_response = len(s_list)
        if lines_in_response is None:
            return None
        for x in range(0,lines_in_response):
            insert_text = s_list[x]+"\n"
            if oCurCell == None: # Are we inserting into a table or not?
                text.insertString(cursor, insert_text, 0)
            else:
                insert_table = s_list[x].split("\n")
                parts = len(insert_table)
                for y in range(0,parts):
                    it = insert_table[y]
                    cell = oTable.getCellByName(oCurCell.CellName)
                    cellCursor = cell.createTextCursor() # use this cursor if you want the text inserted at the beginning of the cell
                    cell.insertString(cellCursor, it, False)
            #        cell.insertString(cursor, insert_text, False) # use the standard cursor to insert at the current position
                    cursor.goDown(1,False)
                    cursor = desktop.getCurrentComponent().getCurrentController().getViewCursor()
                    oTable = cursor.TextTable
                    oCurCell = cursor.Cell
        sock.close()
        return None