Python UNO rehoming a cursor

Creating a macro - Writing a Script - Using the API (OpenOffice Basic, Python, BeanShell, JavaScript)
Post Reply
jma
Posts: 7
Joined: Sun May 27, 2018 2:26 am

Python UNO rehoming a cursor

Post by jma »

LibreOffice 5.3, python 3.53, VOID Linux

This is more of an uno question than a python question. The code below does a simple update of 3 cells. 3 buttons configured on the sheet calling dowriteonce() dowritetwice() and dowritethrice(), and they all update and work like you might expect writing numbers and text to selected cells.

Where the problem comes in, is that when a cell is edited in the UI by a user, any subsequent update of that cell by means of executing the function is blocked. So simply clicking cell C4 in the calc UI, prevents the writethrice() function from updating cell C4. If I delete the content and click another cell in the UI, say C5, then everything works normally again and C4 updates when the button is clicked.

What I would like to do is relocate the UI edit-cursor to an unused cell prior to execution in order to prevent this. User copy-paste is going to leave the active cursor in unpredictable places and that will bork calculations if I can't isolate the cursor.

So the question is, how do I move the UI edit cursor to a named cell via the UNO API, with Python? Or if it is easier, just deactivate it temporarily.

Thanks in advance!

Code: Select all

import socket
import sys
import re
import uno
import unohelper

class ODSCursor(unohelper.Base):

    # predeclare class properties

    ctx=None
    desktop=None
    model=None
    activesheet=None
    counter=0 
    scooby="Scooby"

    # import namespaces

    def __init__(self):
        import socket
        import uno
        import unohelper
        import sys
        import re

    # initialize uno handle only once and get the first sheet

    @classmethod
    def sheet1(cls,*args):
        if cls.activesheet is not None:
                return (cls.activesheet)
        cls.ctx = uno.getComponentContext() 
        cls.desktop = cls.ctx.ServiceManager.createInstanceWithContext("com.sun.star.frame.Desktop", cls.ctx)
        cls.model = cls.desktop.getCurrentComponent()
        # cls.activesheet = cls.model.Sheets.getByName("Sheet1")
        cls.activesheet = cls.model.Sheets.getByIndex(0)
        return (cls.activesheet)

    @classmethod
    def writeonce(self,*args):
        self.counter += 1
        cell_b1 = self.activesheet.getCellRangeByName("B1") 
        cell_b1.String = self.counter

    @classmethod
    def writetwice(self,*args):
        self.counter += 1
        cell_b2 = self.activesheet.getCellRangeByName("B2") 
        cell_b2.String = self.counter 

    @classmethod
    def writescooby(self,*args):
        cell_c4 = self.activesheet.getCellRangeByName("C4") 
        cell_c4.String = self.scooby

### BUTTON BOUND FUNCTIONS ###

def dowriteonce(*args):
    Odc = ODSCursor()   # create the object
    Odc.sheet1()
    Odc.writeonce()

def dowritetwice(*args):
    Odc = ODSCursor() # create the object
    Odc.sheet1()
    Odc.writetwice()

def dowritethrice(*args):
    Odc = ODSCursor() # create the object
    Odc.sheet1()
    Odc.writescooby()
OpenOffice 4.1.1
VOID Linux
hubert lambert
Posts: 145
Joined: Mon Jun 13, 2016 10:50 am

Re: Python UNO rehoming a cursor

Post by hubert lambert »

Hello,

I don't know any api method to deselect the currently edited cell, but you can achieve this with a dispatcher call.
Append for example the two last lines to your "sheet1" function :

Code: Select all

    def sheet1(cls,*args):
        if cls.activesheet is not None:
                return (cls.activesheet)
        cls.ctx = uno.getComponentContext()
        cls.desktop = cls.ctx.ServiceManager.createInstanceWithContext("com.sun.star.frame.Desktop", cls.ctx)
        cls.model = cls.desktop.getCurrentComponent()
        # cls.activesheet = cls.model.Sheets.getByName("Sheet1")
        cls.activesheet = cls.model.Sheets.getByIndex(0)
        dispatcher = cls.ctx.ServiceManager.createInstanceWithContext("com.sun.star.frame.DispatchHelper", cls.ctx)
        dispatcher.executeDispatch(cls.model.CurrentController.Frame, ".uno:Deselect", "", 0, ())
        return (cls.activesheet) 
Regards.
AOOo 4.1.2 on Win7 | LibreOffice on various Linux systems
Post Reply