macro to add annotation to selected text range

Hi,

I am trying to add a really simple macro that I can bind to a key. I just
want ot be able ot add checkmarks to student papers veyr quickly, so I
would like to select a sentence or other text range, then press a key, and
have the ckeckmark appear in a new comment.

I can almost do htis, using code stolen from the web:

rem-------------------------------------------
rem -- misleadingly named macro adds a simple hceckmark at point, or in
response to highlighted text.
sub createComment
    rem create the annotation object
    oAnno =
ThisComponent.createInstance("com.sun.star.text.textfield.Annotation")
    rem Chr 10004 is the decimal for hex code 2714, "heavy checkmark"
    oAnno.Content = Chr(10004)
    oAnno.Author = "Matt Price"
    oText = ThisComponent.Text
    rem check to see if anything is selected
    oSels = ThisComponent.getCurrentSelection()
    If Not IsNull(oSels) Then
        rem I don't know what to put in here
    Else
        oVC = ThisComponent.CurrentController.ViewCursor
        oText.insertTextContent(oVC.Start, oAnno, False)
    End If
end sub

Hi :slight_smile:
The best documentation is at;
https://wiki.documentfoundation.org/Documentation/Publications
and the most recent full books are also on the official LibreOffice
website.

For macros i think the best book by far is Andrew Pitonyak's guide on
https://wiki.documentfoundation.org/Documentation/Other_Documentation_and_Resources#Programmers

I'm not sure they will help for this specific use-case but they might help
generally.
Regards from
Tom :slight_smile:

Thanks Tom,

I've just spent some time looking htrough Andrew Pitonyak's macro guide.
It helps a little but there doesn't seem to be any direct documentation of
hte functions. What I'm looking at is the second line reproduced below:

    oVC = ThisComponent.CurrentController.ViewCursor
    oText.insertTextContent(oVC.Start, oAnno, False)

I think oVC.Start needs to be replaced with something else, but I can't
figure out what. All of Andrew's examples with insertTextContent insert
the content at a single location, not at a text range, so maybe I need a
different function. If someone knows another method I'd appreciate the
advice.

Thanks,
Matt

Thanks Tom,

I've just spent some time looking htrough Andrew Pitonyak's macro guide.
It helps a little but there doesn't seem to be any direct documentation of
hte functions. What I'm looking at is the second line reproduced below:

     oVC = ThisComponent.CurrentController.ViewCursor
     oText.insertTextContent(oVC.Start, oAnno, False)

Matt,
I don't use Writer much and honestly I'm not sure what you expect to see. Try this. In the above two lines change Start to End and False to True and put those two lines right under your "rem I don't know what to put in here" line. Then select some text and run the macro.

Regards, Jim

So, I gues there is an API reference:
http://api.libreoffice.org/docs/idl/ref/index.html

But unfortunately it doesn't give direct documentation for Basic
functions. I found this document instead, which tells me where in the API
the actual function calls come from:

http://bernard.marcelly.perso.sfr.fr/index2.html

The useful macros are embedded in the "XRay Tool". It would sure be nice
to have something like this in the BASIC editor itself - -I am used to
having access to functions & documentation when I'm trying to program!

Hi :slight_smile:
On a linux command-line you can type whatever command and then add a
"--help" or "-h" tag to get a really neat quick-cheat-sheet, 2 examples;

ls --help
dir -h

Also can often type a command after "man" (short for manual) to get a much
more verbose, but still quite geeky, detail about what the command can do.
So;

man ls
man dir

Also just typing

help
info

often gives quite a bit of general help.

Is there anything like that for macros?
Regards from
Tom :slight_smile:

Jim,

That was it! Or, almost. I changed the line to:

oText.insertTextContent(oVC, oAnno, True)

And the annotation now gets attached to the whole range.

I wish I knew how to find the documentation for these functions! I don't
know what the various parameters actually d -- what is the final Boolean
doing there? How do you know?

But in any case, many thanks for solving htis problem, it's actually pretty
awesome to be able to do this with a single keystroke!

m

It is self documenting. Every object tells everything about itself. All
you need is a tool to browse the object hierarchy starting from a given
object:

http://extensions.libreoffice.org/extension-center/mri-uno-object-inspection-tool

OpenOffice tutorial on object inspection with MRI:

Thank you Andreas. Unfortunately I don't seem to be able to install either
version of the MRI tool -- the unreleased 1.1.4 appears not to be a valid
zipfile, whiel 1.1.2 throws this error:

(com.sun.star.uno.RuntimeException) { { Message = "<class 'SyntaxError'>:
invalid syntax (MRI.py, line 21), traceback follows\X000a
/usr/lib/libreoffice/program/pythonloader.py:102 in function
getModuleFromUrl() [codeobject = compile( src, encfile(filename), \"exec\"
)]\X000a /usr/lib/libreoffice/program/pythonloader.py:149 in function
writeRegistryInfo() [mod = self.getModuleFromUrl( locationUrl
)]\X000a\X000a", Context = (com.sun.star.uno.XInterface) @0 } }

I suppose this could be a problem with python version? I'm not certain. In
any case, I'd really appreciate it if you could point me to a differnt
version or to some other tools. Much appreciated!

Matt

Matt,

It occurs to me that I might come off a bit arrogant in my response, but, my intention is to point you at a couple of places that contain the answer to one of your questions. So, please grant me some grace while reading and assume that I have the best of intentions. I have been having some stressful days lately and I have very little time.

Jim,

That was it! Or, almost. I changed the line to:

  oText.insertTextContent(oVC, oAnno, True)
And the annotation now gets attached to the whole range.

I wish I knew how to find the documentation for these functions! I don't
know what the various parameters actually d -- what is the final Boolean
doing there? How do you know?

The answer is well hidden, but I know where to look :slight_smile:

If you download this document (which has a bunch of macros so you will be warned that it has macros, you may tell it "no, do not enable macros" and it will still work fine, you just won't be able to click on all the buttons that run the macros from the document).

http://www.pitonyak.org/OOME_3_0.odt

Table 123 says the following:

insertTextContent(XTextRange, XTextContent, boolean)

Insert text content such as a text table, text frame, or text field. In general, the text content should be created by the text object. If the Boolean value is True, the text in the text range is overwritten; otherwise, the text content is inserted after the text range.

How did I now to put that into the document? I probably looked here:

AOO documentation here:
http://www.openoffice.org/api/docs/common/ref/com/sun/star/text/XText.html#insertTextContent

or here:

LO documentation here:
http://api.libreoffice.org/docs/idl/ref/interfacecom_1_1sun_1_1star_1_1text_1_1XText.html

On the web site, it reads as follows:

void insertTextContent ( [in] com::sun::star::text::XTextRange xRange,
         [in] com::sun::star::text::XTextContent xContent,
         [in] boolean bAbsorb
)

inserts a content, such as a text table, text frame or text field.

Which contents are accepted is implementation-specific. Some implementations may only accept contents which were created by the factory that supplied the same text or the document which contains the text.

Parameters
     xRange specifies the position of insertion.
     xContent the text content to be inserted.
     bAbsorb specifies whether the text spanned by xRange will be replaced. If TRUE then the content of xRange will be replaced by xContent, otherwise xContent will be inserted at the end of xRange.

No, if you are still reading, let me say that it was easy for me to find because I have spent literally thousands of hours working on this stuff and I knew exactly where to look and what to look for (especially since you had a snippet). I do not expect that you would have found it as fast as I and, it is also not clear that without more exposure that it would have been clear that it was what you needed to see.

I found the LO link by searching for

libreoffice API insertTextContent

on Google. While playing with macros, it is common for me inspect the objects in question (I wrote my own object inspector, many people use XRay). I then identify method names that look promising and then use a Google search to figure out how to use that method.

But in any case, many thanks for solving htis problem, it's actually pretty
awesome to be able to do this with a single keystroke!

Glad you figured it out.

So, I gues there is an API reference:
http://api.libreoffice.org/docs/idl/ref/index.html

I had trouble loading that page.

I usually use the OpenOffice one at:
  http://www.openoffice.org/api/docs/common/ref/index-files/index-1.html

But unfortunately it doesn't give direct documentation for Basic
functions. I found this document instead, which tells me where in the API
the actual function calls come from:

Yes, lack of more comprehensive documentation is a real pain. Hopefully someone with more knowledge than myself will comment on what I am about to write if I am wrong. With the exception of ThisComponent, what you refer to as Basic functions are not really Basic functions at all. Basic simply uses functions/methods supplied by Uno. I could write the same macro in Python but still use the same functions.

To me Uno is a huge complex beast that is sparsely documented and hard to use, but very powerful if you understand it.

  Regards, Jim

Sorry, I do not run any recent version of LibreOffice and this is one of
the reasons.
Install XRay instead. Nevertheless, it is inevitable to read some
hundred pages of documentation to get a clear view over the whole
architecture.
If macros are the most "natural" way how you operate an office suite, MS
Office may be one and only suite that will ever fit your needs. Macro
coding for Libre/OpenOffice is for (semi-)professional programmers.

Sorry, but the documentation is for *PROGRAMMERS*. It is not for VBA-coders.

Andreas ,

Thank you Andreas. Unfortunately I don't seem to be able to install either
version of the MRI tool -- the unreleased 1.1.4 appears not to be a valid
zipfile, whiel 1.1.2 throws this error:

(com.sun.star.uno.RuntimeException) { { Message = "<class 'SyntaxError'>:
invalid syntax (MRI.py, line 21), traceback follows\X000a
/usr/lib/libreoffice/program/pythonloader.py:102 in function
getModuleFromUrl() [codeobject = compile( src, encfile(filename), \"exec\"
)]\X000a /usr/lib/libreoffice/program/pythonloader.py:149 in function
writeRegistryInfo() [mod = self.getModuleFromUrl( locationUrl
)]\X000a\X000a", Context = (com.sun.star.uno.XInterface) @0 } }

I suppose this could be a problem with python version? I'm not certain. In
any case, I'd really appreciate it if you could point me to a differnt
version or to some other tools. Much appreciated!

Matt

Sorry, I do not run any recent version of LibreOffice and this is one of
the reasons.
Install XRay instead. Nevertheless, it is inevitable to read some
hundred pages of documentation to get a clear view over the whole
architecture.
If macros are the most "natural" way how you operate an office suite, MS
Office may be one and only suite that will ever fit your needs. Macro
coding for Libre/OpenOffice is for (semi-)professional programmers.

not realy, as soon you know thename off the "object" then you can Google tons off usefull examples

when googling "Openoffice ThisComponent.createInstance("com.sun.star.text.textfield.Annotation")"

you find several examples how to handle annotations in macro's

Greetz

Fernand

Andrew,

Thank you for the navigation help. Your book was the first place I looked,
but I was too many layers away to really understand how to get the help I
needed. Hopefully next time I will be able to do it on my own! Many
thanks also for all your work over the last decade!!

Matt