Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

Well, here is the code translated into Python. However, the while loop does not exit because done() never gets called. I believe the problem is that the spreadsheet is not getting the focus.

Often the solution for these kinds of LO-Python problems is to start an additional thread so that the interface does not lock up. For example, see my answer at https://ask.libreoffice.org/en/question/156160/base-macro-that-opens-a-newclean-record-in-another-form-using-python/?answer=156331#post-id-156331.

This was tested on Windows. It might work better on Linux because dialogs are less often modal.

import time

import uno
import unohelper
from com.sun.star.awt import XActionListener
from com.sun.star.beans import PropertyValue
from com.sun.star.sheet import XRangeSelectionListener

def showDlg(dummy_context=None):
    dlgRangeSelection.showDlg()
    dlgRangeSelection.setTextField("")
    dlgRangeSelection.dlgStart()

class DlgRangeSelection(
    XActionListener, XRangeSelectionListener, unohelper.Base):

    def __init__(self):
        self.sRangeSelection = ""
        self.bRangeSelecting = False
        self.ctx = XSCRIPTCONTEXT.getComponentContext()
        self.controller = (
            XSCRIPTCONTEXT.getDocument().getCurrentController())
        self.doc = XSCRIPTCONTEXT.getDocument()
        self.textfield = None
        self.dlgStart = None
        self.dlgClose = None
        self.dlgDispose = None

    def showDlg(self):
        smgr = self.ctx.getServiceManager()
        dlgprov = smgr.createInstanceWithArgumentsAndContext(
            "com.sun.star.awt.DialogProvider",
            (self.doc,), self.ctx)
        dlg = dlgprov.createDialog(
            "vnd.sun.star.script:Standard.Dialog1?location=document")
        self.textfield = dlg.getControl("TextField1")
        btnRangeSelect = dlg.getControl("CommandButton1")
        btnRangeSelect.setActionCommand("SelectRange")
        btnRangeSelect.addActionListener(self)
        self.dlgStart = dlg.execute
        self.dlgClose = dlg.endExecute
        self.dlgDispose = dlg.dispose

    def actionPerformed(self, event):
        """XActionListener event handler.  Handle which button was pressed."""
        if event.ActionCommand == "SelectRange":
            self.getRangeSelection()

    def getRangeSelection(self):
        self.dlgClose()
        self.dlgDispose()
        self.controller.addRangeSelectionListener(self)
        aProps = (
            createProp("InitialValue", "A1"),
            createProp("Title", "My Title"),
            createProp("CloseOnMouseRelease", True)
            )
        # This is required when calling from IDE or other frame in order to
        # avoid an endless loop.
        oFrame = self.controller.getFrame()
        oFrame.activate()
        oFrame.getContainerWindow().toFront()
        self.bRangeSelecting = True
        self.controller.startRangeSelection(aProps)
        while self.bRangeSelecting:
            time.sleep(1000)
        self.controller.removeRangeSelectionListener(oListener)
        self.showDlg()
        self.setTextField(sRangeSelection)
        self.dlgStart()

    def setTextField(self, s):
        self.textfield.setText(s)

    def done(self, oEv):
        self.sRangeSelection = oEv.RangeDescriptor
        self.bRangeSelecting = False

    def aborted(self, oEv):
        self.sRangeSelection = ""
        self.bRangeSelecting = False

dlgRangeSelection = DlgRangeSelection()

def createProp(name, value):
    """Creates an UNO property."""
    prop = PropertyValue()
    prop.Name = name
    prop.Value = value
    return prop

# Functions that can be called from Tools -> Macros -> Run Macro.
g_exportedScripts = showDlg,

Well, here is the code translated into Python. However, the while loop does not exit because done() never gets called. I believe the problem is that the spreadsheet is not getting the focus.

Often the solution for these kinds of LO-Python problems is to start an additional thread so that the interface does not lock up. For example, see my answer at https://ask.libreoffice.org/en/question/156160/base-macro-that-opens-a-newclean-record-in-another-form-using-python/?answer=156331#post-id-156331.https://ask.libreoffice.org/en/question/156160/base-macro-that-opens-a-newclean-record-in-another-form-using-python/?answer=156331#post-id-156331. In this case, I'd guess that the while loop needs to be run in its own thread, because getRangeSelection() needs to finish so that the spreadsheet can be interactive.

This was tested on Windows. It might work better on Linux because dialogs are less often modal.

import time

import uno
import unohelper
from com.sun.star.awt import XActionListener
from com.sun.star.beans import PropertyValue
from com.sun.star.sheet import XRangeSelectionListener

def showDlg(dummy_context=None):
    dlgRangeSelection.showDlg()
    dlgRangeSelection.setTextField("")
    dlgRangeSelection.dlgStart()

class DlgRangeSelection(
    XActionListener, XRangeSelectionListener, unohelper.Base):

    def __init__(self):
        self.sRangeSelection = ""
        self.bRangeSelecting = False
        self.ctx = XSCRIPTCONTEXT.getComponentContext()
        self.controller = (
            XSCRIPTCONTEXT.getDocument().getCurrentController())
        self.doc = XSCRIPTCONTEXT.getDocument()
        self.textfield = None
        self.dlgStart = None
        self.dlgClose = None
        self.dlgDispose = None

    def showDlg(self):
        smgr = self.ctx.getServiceManager()
        dlgprov = smgr.createInstanceWithArgumentsAndContext(
            "com.sun.star.awt.DialogProvider",
            (self.doc,), self.ctx)
        dlg = dlgprov.createDialog(
            "vnd.sun.star.script:Standard.Dialog1?location=document")
        self.textfield = dlg.getControl("TextField1")
        btnRangeSelect = dlg.getControl("CommandButton1")
        btnRangeSelect.setActionCommand("SelectRange")
        btnRangeSelect.addActionListener(self)
        self.dlgStart = dlg.execute
        self.dlgClose = dlg.endExecute
        self.dlgDispose = dlg.dispose

    def actionPerformed(self, event):
        """XActionListener event handler.  Handle which button was pressed."""
        if event.ActionCommand == "SelectRange":
            self.getRangeSelection()

    def getRangeSelection(self):
        self.dlgClose()
        self.dlgDispose()
        self.controller.addRangeSelectionListener(self)
        aProps = (
            createProp("InitialValue", "A1"),
            createProp("Title", "My Title"),
            createProp("CloseOnMouseRelease", True)
            )
        # This is required when calling from IDE or other frame in order to
        # avoid an endless loop.
        oFrame = self.controller.getFrame()
        oFrame.activate()
        oFrame.getContainerWindow().toFront()
        self.bRangeSelecting = True
        self.controller.startRangeSelection(aProps)
        while self.bRangeSelecting:
            time.sleep(1000)
        self.controller.removeRangeSelectionListener(oListener)
        self.showDlg()
        self.setTextField(sRangeSelection)
        self.dlgStart()

    def setTextField(self, s):
        self.textfield.setText(s)

    def done(self, oEv):
        self.sRangeSelection = oEv.RangeDescriptor
        self.bRangeSelecting = False

    def aborted(self, oEv):
        self.sRangeSelection = ""
        self.bRangeSelecting = False

dlgRangeSelection = DlgRangeSelection()

def createProp(name, value):
    """Creates an UNO property."""
    prop = PropertyValue()
    prop.Name = name
    prop.Value = value
    return prop

# Functions that can be called from Tools -> Macros -> Run Macro.
g_exportedScripts = showDlg,

Well, here Here is an example based on https://wiki.openoffice.org/wiki/Documentation/DevGuide/Spreadsheets/Range_Selection. As is often the code translated into Python. However, the while loop does not exit because done() never gets called. I believe the problem is that the spreadsheet is not getting the focus.

Often the solution for these kinds of LO-Python problems is to start an additional case with Python-UNO, a separate thread so that the interface does not lock up. For example, see my answer at https://ask.libreoffice.org/en/question/156160/base-macro-that-opens-a-newclean-record-in-another-form-using-python/?answer=156331#post-id-156331. In this case, I'd guess that the while loop needs to be run in its own thread, because getRangeSelection() needs to finish started so that the spreadsheet can be interactive.

This was tested on Windows. It might work better on Linux because dialogs are less often modal.interface doesn't lock up.

import threading
import time

import uno
import unohelper
from com.sun.star.awt import XActionListener
from com.sun.star.beans import PropertyValue
from com.sun.star.sheet import XRangeSelectionListener

def showDlg(dummy_context=None):
    dlgRangeSelection.showDlg()
    dlgRangeSelection.setTextField("")
    dlgRangeSelection.dlgStart()
getRange(dummy_context=None):
    controller = XSCRIPTCONTEXT.getDocument().getCurrentController()
    xRngSel = controller
    aListener = ExampleRangeListener()
    xRngSel.addRangeSelectionListener(aListener)
    aArguments = (
        createProp("Title", "Please select a range"),
        createProp("CloseOnMouseRelease", False)
        )
    xRngSel.startRangeSelection(aArguments)
    t1 = WaiterThread(xRngSel, aListener)
    t1.start()

class DlgRangeSelection(
    XActionListener, XRangeSelectionListener, ExampleRangeListener(XRangeSelectionListener, unohelper.Base):
     def __init__(self):
        self.sRangeSelection = ""
        self.bRangeSelecting = False
        self.ctx = XSCRIPTCONTEXT.getComponentContext()
        self.controller = (
            XSCRIPTCONTEXT.getDocument().getCurrentController())
        self.doc self.aResult = "not yet"

    def done(self, aEvent):
        self.aResult = aEvent.RangeDescriptor

    def aborted(self, dummy_aEvent):
        self.aResult = "nothing"

    def disposing(self, dummy_aEvent):
        pass

class WaiterThread(threading.Thread):
    def __init__(self, xRngSel, aListener):
        threading.Thread.__init__(self)
        self.xRngSel = xRngSel
        self.aListener = aListener

    def run(self):
        for dummy in range(120):  # don't wait more than 60 seconds
            if self.aListener.aResult != "not yet":
                break
            time.sleep(0.5)
        self.xRngSel.removeRangeSelectionListener(self.aListener)
        doc = XSCRIPTCONTEXT.getDocument()
        self.textfield = None
        self.dlgStart = None
        self.dlgClose = None
        self.dlgDispose = None

    def showDlg(self):
        smgr = self.ctx.getServiceManager()
        dlgprov = smgr.createInstanceWithArgumentsAndContext(
            "com.sun.star.awt.DialogProvider",
            (self.doc,), self.ctx)
        dlg = dlgprov.createDialog(
            "vnd.sun.star.script:Standard.Dialog1?location=document")
        self.textfield = dlg.getControl("TextField1")
        btnRangeSelect = dlg.getControl("CommandButton1")
        btnRangeSelect.setActionCommand("SelectRange")
        btnRangeSelect.addActionListener(self)
        self.dlgStart = dlg.execute
        self.dlgClose = dlg.endExecute
        self.dlgDispose = dlg.dispose

    def actionPerformed(self, event):
        """XActionListener event handler.  Handle which button was pressed."""
        if event.ActionCommand == "SelectRange":
            self.getRangeSelection()

    def getRangeSelection(self):
        self.dlgClose()
        self.dlgDispose()
        self.controller.addRangeSelectionListener(self)
        aProps = (
            createProp("InitialValue", "A1"),
            createProp("Title", "My Title"),
            createProp("CloseOnMouseRelease", True)
            )
        # This is required when calling from IDE or other frame in order to
        # avoid an endless loop.
        oFrame = self.controller.getFrame()
        oFrame.activate()
        oFrame.getContainerWindow().toFront()
        self.bRangeSelecting = True
        self.controller.startRangeSelection(aProps)
        while self.bRangeSelecting:
            time.sleep(1000)
        self.controller.removeRangeSelectionListener(oListener)
        self.showDlg()
        self.setTextField(sRangeSelection)
        self.dlgStart()

    def setTextField(self, s):
        self.textfield.setText(s)

    def done(self, oEv):
        self.sRangeSelection = oEv.RangeDescriptor
        self.bRangeSelecting = False

    def aborted(self, oEv):
        self.sRangeSelection = ""
        self.bRangeSelecting = False

dlgRangeSelection = DlgRangeSelection()

def createProp(name, value):
    """Creates an UNO property."""
    prop = PropertyValue()
    prop.Name = name
    prop.Value = value
    return prop

# Functions that can be called from Tools -> Macros -> Run Macro.
g_exportedScripts = showDlg,
sheet = doc.getSheets().getByIndex(0)
        cell = sheet.getCellByPosition(0,0)
        cell.setString(self.aListener.aResult)

Here is an example based on https://wiki.openoffice.org/wiki/Documentation/DevGuide/Spreadsheets/Range_Selection. As is often the case with Python-UNO, a separate thread needs to be started so that the spreadsheet interface doesn't lock up.

import threading
import time

import uno
import unohelper
from com.sun.star.beans import PropertyValue
from com.sun.star.sheet import XRangeSelectionListener

def getRange(dummy_context=None):
    controller = XSCRIPTCONTEXT.getDocument().getCurrentController()
    xRngSel = controller
    aListener = ExampleRangeListener()
    xRngSel.addRangeSelectionListener(aListener)
    aArguments = (
        createProp("Title", "Please select a range"),
        createProp("CloseOnMouseRelease", False)
        )
    xRngSel.startRangeSelection(aArguments)
    t1 = WaiterThread(xRngSel, aListener)
    t1.start()

class ExampleRangeListener(XRangeSelectionListener, unohelper.Base):
    def __init__(self):
        self.aResult = "not yet"

    def done(self, aEvent):
        self.aResult = aEvent.RangeDescriptor

    def aborted(self, dummy_aEvent):
        self.aResult = "nothing"

    def disposing(self, dummy_aEvent):
        pass

class WaiterThread(threading.Thread):
    def __init__(self, xRngSel, aListener):
        threading.Thread.__init__(self)
        self.xRngSel = xRngSel
        self.aListener = aListener

    def run(self):
        for dummy in range(120):  # don't wait more than 60 seconds
            if self.aListener.aResult != "not yet":
                break
            time.sleep(0.5)
        self.xRngSel.removeRangeSelectionListener(self.aListener)
        doc = XSCRIPTCONTEXT.getDocument()
        sheet = doc.getSheets().getByIndex(0)
        cell = sheet.getCellByPosition(0,0)
        cell.setString(self.aListener.aResult)

def createProp(name, value):
    """Creates an UNO property."""
    prop = PropertyValue()
    prop.Name = name
    prop.Value = value
    return prop

Here is an a range selection example based on https://wiki.openoffice.org/wiki/Documentation/DevGuide/Spreadsheets/Range_Selection. As is often the case with Python-UNO, a separate thread needs to be started so that the spreadsheet interface doesn't lock up.

import threading
import time

import uno
import unohelper
from com.sun.star.beans import PropertyValue
from com.sun.star.sheet import XRangeSelectionListener

def getRange(dummy_context=None):
    controller = XSCRIPTCONTEXT.getDocument().getCurrentController()
    xRngSel = controller
    aListener = ExampleRangeListener()
    xRngSel.addRangeSelectionListener(aListener)
    aArguments = (
        createProp("Title", "Please select a range"),
        createProp("CloseOnMouseRelease", False)
        )
    xRngSel.startRangeSelection(aArguments)
    t1 = WaiterThread(xRngSel, aListener)
    t1.start()

class ExampleRangeListener(XRangeSelectionListener, unohelper.Base):
    def __init__(self):
        self.aResult = "not yet"

    def done(self, aEvent):
        self.aResult = aEvent.RangeDescriptor

    def aborted(self, dummy_aEvent):
        self.aResult = "nothing"

    def disposing(self, dummy_aEvent):
        pass

class WaiterThread(threading.Thread):
    def __init__(self, xRngSel, aListener):
        threading.Thread.__init__(self)
        self.xRngSel = xRngSel
        self.aListener = aListener

    def run(self):
        for dummy in range(120):  # don't wait more than 60 seconds
            if self.aListener.aResult != "not yet":
                break
            time.sleep(0.5)
        self.xRngSel.removeRangeSelectionListener(self.aListener)
        doc = XSCRIPTCONTEXT.getDocument()
        sheet = doc.getSheets().getByIndex(0)
        cell = sheet.getCellByPosition(0,0)
        cell.setString(self.aListener.aResult)

def createProp(name, value):
    """Creates an UNO property."""
    prop = PropertyValue()
    prop.Name = name
    prop.Value = value
    return prop

Here is a range selection example based on https://wiki.openoffice.org/wiki/Documentation/DevGuide/Spreadsheets/Range_Selection. It can be run in an empty sheet.

As is often the case with Python-UNO, a separate thread needs to be started so that the spreadsheet interface doesn't lock up.

import threading
import time

import uno
import unohelper
from com.sun.star.beans import PropertyValue
from com.sun.star.sheet import XRangeSelectionListener

def getRange(dummy_context=None):
    controller = XSCRIPTCONTEXT.getDocument().getCurrentController()
    xRngSel = controller
    aListener = ExampleRangeListener()
    xRngSel.addRangeSelectionListener(aListener)
    aArguments = (
        createProp("Title", "Please select a range"),
        createProp("CloseOnMouseRelease", False)
        )
    xRngSel.startRangeSelection(aArguments)
    t1 = WaiterThread(xRngSel, aListener)
    t1.start()

class ExampleRangeListener(XRangeSelectionListener, unohelper.Base):
    def __init__(self):
        self.aResult = "not yet"

    def done(self, aEvent):
        self.aResult = aEvent.RangeDescriptor

    def aborted(self, dummy_aEvent):
        self.aResult = "nothing"

    def disposing(self, dummy_aEvent):
        pass

class WaiterThread(threading.Thread):
    def __init__(self, xRngSel, aListener):
        threading.Thread.__init__(self)
        self.xRngSel = xRngSel
        self.aListener = aListener

    def run(self):
        for dummy in range(120):  # don't wait more than 60 seconds
            if self.aListener.aResult != "not yet":
                break
            time.sleep(0.5)
        self.xRngSel.removeRangeSelectionListener(self.aListener)
        doc = XSCRIPTCONTEXT.getDocument()
        sheet = doc.getSheets().getByIndex(0)
        cell = sheet.getCellByPosition(0,0)
        cell.setString(self.aListener.aResult)

def createProp(name, value):
    """Creates an UNO property."""
    prop = PropertyValue()
    prop.Name = name
    prop.Value = value
    return prop

Here is a range selection example based on https://wiki.openoffice.org/wiki/Documentation/DevGuide/Spreadsheets/Range_Selection. It can be run in an empty sheet.a newly created spreadsheet.

As is often the case with Python-UNO, a separate thread needs to be started so that the spreadsheet interface doesn't lock up.

import threading
import time

import uno
import unohelper
from com.sun.star.beans import PropertyValue
from com.sun.star.sheet import XRangeSelectionListener

def getRange(dummy_context=None):
    controller = XSCRIPTCONTEXT.getDocument().getCurrentController()
    xRngSel = controller
    aListener = ExampleRangeListener()
    xRngSel.addRangeSelectionListener(aListener)
    aArguments = (
        createProp("Title", "Please select a range"),
        createProp("CloseOnMouseRelease", False)
        )
    xRngSel.startRangeSelection(aArguments)
    t1 = WaiterThread(xRngSel, aListener)
    t1.start()

class ExampleRangeListener(XRangeSelectionListener, unohelper.Base):
    def __init__(self):
        self.aResult = "not yet"

    def done(self, aEvent):
        self.aResult = aEvent.RangeDescriptor

    def aborted(self, dummy_aEvent):
        self.aResult = "nothing"

    def disposing(self, dummy_aEvent):
        pass

class WaiterThread(threading.Thread):
    def __init__(self, xRngSel, aListener):
        threading.Thread.__init__(self)
        self.xRngSel = xRngSel
        self.aListener = aListener

    def run(self):
        for dummy in range(120):  # don't wait more than 60 seconds
            if self.aListener.aResult != "not yet":
                break
            time.sleep(0.5)
        self.xRngSel.removeRangeSelectionListener(self.aListener)
        doc = XSCRIPTCONTEXT.getDocument()
        sheet = doc.getSheets().getByIndex(0)
        cell = sheet.getCellByPosition(0,0)
        cell.setString(self.aListener.aResult)

def createProp(name, value):
    """Creates an UNO property."""
    prop = PropertyValue()
    prop.Name = name
    prop.Value = value
    return prop

Here is a range selection example based on https://wiki.openoffice.org/wiki/Documentation/DevGuide/Spreadsheets/Range_Selection. It can be run in a newly created new spreadsheet.

As is often the case with Python-UNO, a separate thread needs to be started so that the spreadsheet interface doesn't lock up.

import threading
import time

import uno
import unohelper
from com.sun.star.beans import PropertyValue
from com.sun.star.sheet import XRangeSelectionListener

def getRange(dummy_context=None):
    controller = XSCRIPTCONTEXT.getDocument().getCurrentController()
    xRngSel = controller
    aListener = ExampleRangeListener()
    xRngSel.addRangeSelectionListener(aListener)
    aArguments = (
        createProp("Title", "Please select a range"),
        createProp("CloseOnMouseRelease", False)
        )
    xRngSel.startRangeSelection(aArguments)
    t1 = WaiterThread(xRngSel, aListener)
    t1.start()

class ExampleRangeListener(XRangeSelectionListener, unohelper.Base):
    def __init__(self):
        self.aResult = "not yet"

    def done(self, aEvent):
        self.aResult = aEvent.RangeDescriptor

    def aborted(self, dummy_aEvent):
        self.aResult = "nothing"

    def disposing(self, dummy_aEvent):
        pass

class WaiterThread(threading.Thread):
    def __init__(self, xRngSel, aListener):
        threading.Thread.__init__(self)
        self.xRngSel = xRngSel
        self.aListener = aListener

    def run(self):
        for dummy in range(120):  # don't wait more than 60 seconds
            if self.aListener.aResult != "not yet":
                break
            time.sleep(0.5)
        self.xRngSel.removeRangeSelectionListener(self.aListener)
        doc = XSCRIPTCONTEXT.getDocument()
        sheet = doc.getSheets().getByIndex(0)
        cell = sheet.getCellByPosition(0,0)
        cell.setString(self.aListener.aResult)

def createProp(name, value):
    """Creates an UNO property."""
    prop = PropertyValue()
    prop.Name = name
    prop.Value = value
    return prop

Here is a range selection example based on https://wiki.openoffice.org/wiki/Documentation/DevGuide/Spreadsheets/Range_Selection. It can be run in a new spreadsheet.

As is often the case with Python-UNO, the code starts a separate thread needs to be started so that the spreadsheet interface doesn't lock up.

import threading
import time

import uno
import unohelper
from com.sun.star.beans import PropertyValue
from com.sun.star.sheet import XRangeSelectionListener

def getRange(dummy_context=None):
    controller = XSCRIPTCONTEXT.getDocument().getCurrentController()
    xRngSel = controller
    aListener = ExampleRangeListener()
    xRngSel.addRangeSelectionListener(aListener)
    aArguments = (
        createProp("Title", "Please select a range"),
        createProp("CloseOnMouseRelease", False)
        )
    xRngSel.startRangeSelection(aArguments)
    t1 = WaiterThread(xRngSel, aListener)
    t1.start()

class ExampleRangeListener(XRangeSelectionListener, unohelper.Base):
    def __init__(self):
        self.aResult = "not yet"

    def done(self, aEvent):
        self.aResult = aEvent.RangeDescriptor

    def aborted(self, dummy_aEvent):
        self.aResult = "nothing"

    def disposing(self, dummy_aEvent):
        pass

class WaiterThread(threading.Thread):
    def __init__(self, xRngSel, aListener):
        threading.Thread.__init__(self)
        self.xRngSel = xRngSel
        self.aListener = aListener

    def run(self):
        for dummy in range(120):  # don't wait more than 60 seconds
            if self.aListener.aResult != "not yet":
                break
            time.sleep(0.5)
        self.xRngSel.removeRangeSelectionListener(self.aListener)
        doc = XSCRIPTCONTEXT.getDocument()
        sheet = doc.getSheets().getByIndex(0)
        cell = sheet.getCellByPosition(0,0)
        cell.setString(self.aListener.aResult)

def createProp(name, value):
    """Creates an UNO property."""
    prop = PropertyValue()
    prop.Name = name
    prop.Value = value
    return prop

Here is a range selection example based on https://wiki.openoffice.org/wiki/Documentation/DevGuide/Spreadsheets/Range_Selection. It can be run in a new spreadsheet.

As is often the case with Python-UNO, the code starts a separate thread so that the spreadsheet interface doesn't lock up.up. For reasons I do not understand, separate threads do not seem to be necessary for Basic or Java macros.

import threading
import time

import uno
import unohelper
from com.sun.star.beans import PropertyValue
from com.sun.star.sheet import XRangeSelectionListener

def getRange(dummy_context=None):
    controller = XSCRIPTCONTEXT.getDocument().getCurrentController()
    xRngSel = controller
    aListener = ExampleRangeListener()
    xRngSel.addRangeSelectionListener(aListener)
    aArguments = (
        createProp("Title", "Please select a range"),
        createProp("CloseOnMouseRelease", False)
        )
    xRngSel.startRangeSelection(aArguments)
    t1 = WaiterThread(xRngSel, aListener)
    t1.start()

class ExampleRangeListener(XRangeSelectionListener, unohelper.Base):
    def __init__(self):
        self.aResult = "not yet"

    def done(self, aEvent):
        self.aResult = aEvent.RangeDescriptor

    def aborted(self, dummy_aEvent):
        self.aResult = "nothing"

    def disposing(self, dummy_aEvent):
        pass

class WaiterThread(threading.Thread):
    def __init__(self, xRngSel, aListener):
        threading.Thread.__init__(self)
        self.xRngSel = xRngSel
        self.aListener = aListener

    def run(self):
        for dummy in range(120):  # don't wait more than 60 seconds
            if self.aListener.aResult != "not yet":
                break
            time.sleep(0.5)
        self.xRngSel.removeRangeSelectionListener(self.aListener)
        doc = XSCRIPTCONTEXT.getDocument()
        sheet = doc.getSheets().getByIndex(0)
        cell = sheet.getCellByPosition(0,0)
        cell.setString(self.aListener.aResult)

def createProp(name, value):
    """Creates an UNO property."""
    prop = PropertyValue()
    prop.Name = name
    prop.Value = value
    return prop

Here is a range selection example based on https://wiki.openoffice.org/wiki/Documentation/DevGuide/Spreadsheets/Range_Selection. It can be run in a new spreadsheet.

As is often the case with Python-UNO, the code starts a separate thread so that the spreadsheet interface doesn't lock up. For reasons I do not understand, separate Separate threads do not seem to be necessary for Basic or Java macros.macros, presumably because those interpreters do not block the main LO graphics thread while the Python interpreter does for some reason.

import threading
import time

import uno
import unohelper
from com.sun.star.beans import PropertyValue
from com.sun.star.sheet import XRangeSelectionListener

def getRange(dummy_context=None):
    controller = XSCRIPTCONTEXT.getDocument().getCurrentController()
    xRngSel = controller
    aListener = ExampleRangeListener()
    xRngSel.addRangeSelectionListener(aListener)
    aArguments = (
        createProp("Title", "Please select a range"),
        createProp("CloseOnMouseRelease", False)
        )
    xRngSel.startRangeSelection(aArguments)
    t1 = WaiterThread(xRngSel, aListener)
    t1.start()

class ExampleRangeListener(XRangeSelectionListener, unohelper.Base):
    def __init__(self):
        self.aResult = "not yet"

    def done(self, aEvent):
        self.aResult = aEvent.RangeDescriptor

    def aborted(self, dummy_aEvent):
        self.aResult = "nothing"

    def disposing(self, dummy_aEvent):
        pass

class WaiterThread(threading.Thread):
    def __init__(self, xRngSel, aListener):
        threading.Thread.__init__(self)
        self.xRngSel = xRngSel
        self.aListener = aListener

    def run(self):
        for dummy in range(120):  # don't wait more than 60 seconds
            if self.aListener.aResult != "not yet":
                break
            time.sleep(0.5)
        self.xRngSel.removeRangeSelectionListener(self.aListener)
        doc = XSCRIPTCONTEXT.getDocument()
        sheet = doc.getSheets().getByIndex(0)
        cell = sheet.getCellByPosition(0,0)
        cell.setString(self.aListener.aResult)

def createProp(name, value):
    """Creates an UNO property."""
    prop = PropertyValue()
    prop.Name = name
    prop.Value = value
    return prop

Here is a range selection example based on https://wiki.openoffice.org/wiki/Documentation/DevGuide/Spreadsheets/Range_Selection. It can be run in a new spreadsheet.

As is often the case with Python-UNO, the code starts a separate thread so that the spreadsheet interface doesn't lock up. Separate threads do not seem to be necessary for Basic or Java macros, presumably because those interpreters do not block the main LO graphics thread while thread, whereas the Python interpreter does for some reason.

import threading
import time

import uno
import unohelper
from com.sun.star.beans import PropertyValue
from com.sun.star.sheet import XRangeSelectionListener

def getRange(dummy_context=None):
    controller = XSCRIPTCONTEXT.getDocument().getCurrentController()
    xRngSel = controller
    aListener = ExampleRangeListener()
    xRngSel.addRangeSelectionListener(aListener)
    aArguments = (
        createProp("Title", "Please select a range"),
        createProp("CloseOnMouseRelease", False)
        )
    xRngSel.startRangeSelection(aArguments)
    t1 = WaiterThread(xRngSel, aListener)
    t1.start()

class ExampleRangeListener(XRangeSelectionListener, unohelper.Base):
    def __init__(self):
        self.aResult = "not yet"

    def done(self, aEvent):
        self.aResult = aEvent.RangeDescriptor

    def aborted(self, dummy_aEvent):
        self.aResult = "nothing"

    def disposing(self, dummy_aEvent):
        pass

class WaiterThread(threading.Thread):
    def __init__(self, xRngSel, aListener):
        threading.Thread.__init__(self)
        self.xRngSel = xRngSel
        self.aListener = aListener

    def run(self):
        for dummy in range(120):  # don't wait more than 60 seconds
            if self.aListener.aResult != "not yet":
                break
            time.sleep(0.5)
        self.xRngSel.removeRangeSelectionListener(self.aListener)
        doc = XSCRIPTCONTEXT.getDocument()
        sheet = doc.getSheets().getByIndex(0)
        cell = sheet.getCellByPosition(0,0)
        cell.setString(self.aListener.aResult)

def createProp(name, value):
    """Creates an UNO property."""
    prop = PropertyValue()
    prop.Name = name
    prop.Value = value
    return prop