2017-06-22 120 views
1

LibreOffice作家允许用户在文本中插入注释(注释/注释)。如何从python宏读取LibreOffice作家注释的内容

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

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

我一直无法发现占卜

的方法)当前行是否有一个注释或
二)如何访问其内容。

如果有人设法做到这一点,我会很感激任何指针。

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=(':') 
    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 
+0

枚举注释和用[getAnchor()](https://www.openoffice.org/api/docs/common/ref/com/sun/star/text/XTextContent.html#getAnchor)至找出每个所在的位置。请参阅https://wiki.openoffice.org/wiki/Documentation/DevGuide/Text/Editing_Text#Text_Contents_Other_Than_Strings。 –

+0

感谢您的回复。也许是我,但我无法找到从oField或oField.getAnchor()返回的任何方法,当我枚举oEnum,提供文档中的注释位置。如果我创建一个游标并尝试“gotoRange(oField,False)”,它声称没有这样的接口。我在这个问题上加入了我的错误尝试,希望你能发现明显的错误。我承认会在API文档上苦苦挣扎,就像游泳在糖果上一样 –

回答

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文档更容易理解。

+0

只有几毫米的距离最终与数英里之外相同。感谢您的正确方向。我已经发布了(最终)版本的自我回答,以供其他任何人通过这类事情参与其中。 - –

0

来自的急需帮助Jim K a self answer is posted below。我已经评论了我认为最有帮助的地方。

#!/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=(':') 
    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()