如何从python宏中读取LibreOffice writer注释的内容

时间:2017-06-22 15:20:47

标签: python macros uno libreoffice-writer

LibreOffice编写器允许用户在文本中插入注释(注释/注释)。

我的问题是我无法找到访问行特定注释内容的方法 以下python代码查找选定/突出显示的文本,然后删除除格式化时间代码(例如01:10:23或11:10)之外的所有内容,并将其转换为秒。
如果未选择任何文本,则会选择整个当前行并尝试查找时间码。但是,时间码可以在注释中。

我已经设法获得了文档中所有注释的列表,在代码开头注释掉,但对我来说没用。

我一直无法找到一种占卜方法

a)当前行是否有注释或
b)如何访问其内容。

如果有人设法实现这一点,我会感激任何指示。

def fs2_GoToTimestamp(*args):
#get the doc from the scripting context which is made available to all scripts
    desktop = XSCRIPTCONTEXT.getDesktop()
    model = desktop.getCurrentComponent()
    oSelected = model.getCurrentSelection()
#access annotations for the whole document
#    oEnum = model.getTextFields().createEnumeration()
#    cursor = desktop.getCurrentComponent().getCurrentController().getViewCursor()
#    while oEnum.hasMoreElements():
#        oField = oEnum.nextElement()
#        cursor.gotoRange(oField,False)
#        print (cursor.getPosition())
#        if oField.supportsService('com.sun.star.text.TextField.Annotation'):
#            print (oField.Content)
#            x = oField.getAnchor()
#            print (dir(x))
    oText = ""
    try: #Grab the text selected/highlighted
        oSel = oSelected.getByIndex(0)
        oText= oSel.getString()
    except:pass
    try:
        if oText == "": # Nothing selected grab the whole line
            cursor = desktop.getCurrentComponent().getCurrentController().getViewCursor()
            cursor.gotoStartOfLine(False) #move cursor to start without selecting (False)
            cursor.gotoEndOfLine(True) #now move cursor to end of line selecting all (True)
            oSelected = model.getCurrentSelection()
            oSel = oSelected.getByIndex(0)
            oText= oSel.getString()
            # Deselect line to avoid inadvertently deleting it on next keystroke
            cursor.gotoStartOfLine(False)
    except:pass
    time = str(oText)
    valid_chars=('0123456789:')
    time = ''.join(char for char in time if char in valid_chars)
    if time.count(":") == 1:
        oM, oS = time.split(":")
        oH = "00"
    elif time.count(":") == 2:
        oH,oM,oS = time.split(":")
    else:
        return None
    if len(oS) != 2:
        oS=oS[:2]
    try:
        secs = int(oS)
        secs = secs + int(oM) * 60
        secs = secs + int(oH) *3600
    except:
        return None
    seek_instruction = 'seek'+str(secs)+'\n'
    #Now do something with the seek instruction 

2 个答案:

答案 0 :(得分:1)

枚举annotations并使用getAnchor()找出每个人的位置。此答案基于https://wiki.openoffice.org/wiki/Documentation/DevGuide/Text/Editing_Text#Text_Contents_Other_Than_Strings

您的代码即将开始运作。

while oEnum.hasMoreElements():
    oField = oEnum.nextElement()
    if oField.supportsService('com.sun.star.text.TextField.Annotation'):
        xTextRange = oField.getAnchor()
        cursor.gotoRange(xTextRange, False)

而不是print (dir(x)),XrayTool或MRI等内省工具将提供更好的信息。它使API文档更易于理解。

答案 1 :(得分:0)

Jim K 的帮助下,我们会在下面发布自我回答。我已经评论了我认为最有帮助的地方。

#!/usr/bin/python
from com.sun.star.awt.MessageBoxButtons import BUTTONS_OK
from com.sun.star.awt.MessageBoxType import INFOBOX
def fs2_GoToTimestamp(*args):
    desktop = XSCRIPTCONTEXT.getDesktop()
    model = desktop.getCurrentComponent()
    oSelected = model.getCurrentSelection()
    doc = XSCRIPTCONTEXT.getDocument()
    parentwindow = doc.CurrentController.Frame.ContainerWindow
    cursor = desktop.getCurrentComponent().getCurrentController().getViewCursor()
    try:
        CursorPos = cursor.getText().createTextCursorByRange(cursor)#Store original cursor position
    except:# The cursor has been placed in the annotation not the text
        mess = "Position cursor in the text\nNot the comment box"
        heading = "Positioning Error"
        MessageBox(parentwindow, mess, heading, INFOBOX, BUTTONS_OK)
        return None
    oText = ""
    try: #Grab the text selected/highlighted
        oSel = oSelected.getByIndex(0)
        oText= oSel.getString()
    except:pass
    try:
        if oText == "": # Nothing selected grab the whole line
            store_position = 0
            cursor.gotoStartOfLine(False) #move cursor to start without selecting (False)
            cursor.gotoEndOfLine(True) #now move cursor to end of line selecting all (True)
            oSelected = model.getCurrentSelection()
            oSel = oSelected.getByIndex(0)
            oText= oSel.getString()
            y = cursor.getPosition()
            store_position = y.value.Y
            # Deselect line to avoid inadvertently deleting it on next user keystroke
            cursor.gotoStartOfLine(False)

            if oText.count(":") == 0:
            # Still nothing found check for an annotation at this location
            #enumerate through annotations for the whole document
                oEnum = model.getTextFields().createEnumeration()
                while oEnum.hasMoreElements():
                    oField = oEnum.nextElement()
                    if oField.supportsService('com.sun.star.text.TextField.Annotation'):
                        anno_at = oField.getAnchor()
                        cursor.gotoRange(anno_at,False)
                        pos = cursor.getPosition()
                        if pos.value.Y == store_position: # Found an annotation at this location
                            oText = oField.Content
                            break
                # Re-set cursor to original position after enumeration & deselect
                cursor.gotoRange(CursorPos,False)
    except:pass

    time = str(oText)
    valid_chars=('0123456789:')
    time = ''.join(char for char in time if char in valid_chars) #Strip out all invalid characters
    if time.count(":") == 1: # time 00:00
        oM, oS = time.split(":")
        oH = "00"
    elif time.count(":") == 2: # time 00:00:00
        oH,oM,oS = time.split(":")
    else:
        return None
    if len(oS) != 2: # in case time includes tenths 00:00.0 reduce to whole seconds
        oS=oS[:2]
    try:
        secs = int(oS)
        secs = secs + int(oM) * 60
        secs = secs + int(oH) *3600
    except:
        return None
    seek_instruction = 'seek'+str(secs)+'\n'
    print("Seconds",str(secs))
    # Do something with seek_instruction

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()