0

The following python libreoffice Uno macro works but only with the try..except statement.
The macro allows you to select text in a writer document and send it to a search engine in your default browser.
The issue, is that if you select a single piece of text,oSelected.getByIndex(0) is populated but if you select multiple pieces of text oSelected.getByIndex(0) is not populated. In this case the data starts at oSelected.getByIndex(1) and oSelected.getByIndex(0) is left blank.
I have no idea why this should be and would love to know if anyone can explain this strange behaviour.

#!/usr/bin/python    
import os
import webbrowser
from configobj import ConfigObj
from com.sun.star.awt.MessageBoxButtons import BUTTONS_OK, BUTTONS_OK_CANCEL, BUTTONS_YES_NO, BUTTONS_YES_NO_CANCEL, BUTTONS_RETRY_CANCEL, BUTTONS_ABORT_IGNORE_RETRY
from com.sun.star.awt.MessageBoxButtons import DEFAULT_BUTTON_OK, DEFAULT_BUTTON_CANCEL, DEFAULT_BUTTON_RETRY, DEFAULT_BUTTON_YES, DEFAULT_BUTTON_NO, DEFAULT_BUTTON_IGNORE

from com.sun.star.awt.MessageBoxType import MESSAGEBOX, INFOBOX, WARNINGBOX, ERRORBOX, QUERYBOX

def fs3Browser(*args):
#get the doc from the scripting context which is made available to all scripts
    desktop = XSCRIPTCONTEXT.getDesktop()
    model = desktop.getCurrentComponent()
    doc = XSCRIPTCONTEXT.getDocument()
    parentwindow = doc.CurrentController.Frame.ContainerWindow

    oSelected = model.getCurrentSelection()
    oText = ""
    try:
        for i in range(0,4,1):
            print ("Index No ", str(i))
            try:
                oSel = oSelected.getByIndex(i)
                print (str(i), oSel.getString())
                oText += oSel.getString()+" "
            except:
                break
    except AttributeError:
        mess = "Do not select text from more than one table cell"
        heading = "Processing error"
        MessageBox(parentwindow, mess, heading, INFOBOX, BUTTONS_OK)
        return

    lookup = str(oText)
    special_c =str.maketrans("","",'!|@#"$~%&/()=?+*][}{-;:,.<>')
    lookup = lookup.translate(special_c)
    lookup = lookup.strip()
    configuration_dir = os.environ["HOME"]+"/fs3"
    config_filename = configuration_dir + "/fs3.cfg"
    if  os.access(config_filename, os.R_OK):
        cfg = ConfigObj(config_filename)

    #define search engine from the configuration file
    try:
        searchengine = cfg["control"]["ENGINE"]
    except:
        searchengine = "https://duckduckgo.com"
    if 'duck' in searchengine:
        webbrowser.open_new('https://www.duckduckgo.com//?q='+lookup+'&kj=%23FFD700 &k7=%23C9C4FF &ia=meanings')
    else:
        webbrowser.open_new('https://www.google.com/search?/&q='+lookup)
    return None
def MessageBox(ParentWindow, MsgText, MsgTitle, MsgType, MsgButtons):
    ctx = XSCRIPTCONTEXT.getComponentContext()
    sm = ctx.ServiceManager
    si = sm.createInstanceWithContext("com.sun.star.awt.Toolkit", ctx) 
    mBox = si.createMessageBox(ParentWindow, MsgType, MsgButtons, MsgTitle, MsgText)
    mBox.execute()    
Rolf of Saxony
  • 21,661
  • 5
  • 39
  • 60
  • Can I propose that a new tag is created `python-uno`. The documentation for using uno with python is notoriously bad and a quick way to find Q&A's on SO would be helpful. – Rolf of Saxony Sep 05 '15 at 09:59
  • I agree that the documentation isn't very good. That's too bad because Python and UNO can be a powerful combination when used properly. Maybe SO can help. – Jim K Sep 12 '15 at 18:29
  • Such a tag already exists: [pyuno](http://stackoverflow.com/tags/pyuno/info). – Jim K Nov 27 '15 at 20:31
  • @JimK Yep! Found it after my comment but sadly with only 5 followers – Rolf of Saxony Nov 28 '15 at 09:13

1 Answers1

1

Your code is missing something. This works without needing an extra try/except clause:

selected_strings = []
try:
    for i in range(oSelected.getCount()):
        oSel = oSelected.getByIndex(i)
        if oSel.getString():
            selected_strings.append(oSel.getString())
except AttributeError:
    # handle exception...
    return
result = " ".join(selected_strings)

To answer your question about the "strange behaviour," it seems pretty straightforward to me. If the 0th element is empty, then there are multiple selections which may need to be handled differently.

Jim K
  • 12,824
  • 2
  • 22
  • 51
  • I appreciate your input and yes this does indeed get rid of the try statement but at the same time it also has to compensate for the lack of data in position zero by adding an if statement. Your point about element zero being blank means that there are multiple selections, might well be true but as with so much with Uno and python I haven't found it documented anywhere. I assume that for future reference we shall just have to bear this in mind. For the simplest solution, I have simply stopped caring about element 0 and include it in the whole string, as in the end it is only ever spaces. – Rolf of Saxony Sep 13 '15 at 08:48
  • Might I ask you to put back your suspicion about the lack of data in position zero, which you edited out. Whilst none of us can know whether it is germane or not, it is worth having on record, so that it can be borne in mind by others with a similar issue – Rolf of Saxony Sep 13 '15 at 15:01
  • I don't worry too much about such things as an extra if statement needed for Python UNO. For bigger projects, it's easy to abstract away the statement in some sort of custom iterator class. However it's good to have this behavior recorded. – Jim K Sep 14 '15 at 16:25