Macro to search for a Character Style

I need to find Character Styles from a macro script in a Writer document.
I can easily select any text attribute like this:

sub _SelectAttributes(SrchAttributes)
	oDoc = ThisComponent
	oSrch = oDoc.createSearchDescriptor
	with oSrch
		.searchAll=True
	end with
	oSrch.SetSearchAttributes(SrchAttributes())
	oFound = oDoc.findAll(oSrch)
	oDoc.CurrentController.select(oFound)
end sub

sub SelectBold()
	Dim SrchAttributes(0) As New com.sun.star.beans.PropertyValue	
 	SrchAttributes(0).Name = "CharWeight"
 	SrchAttributes(0).Value = com.sun.star.awt.FontWeight.BOLD
	_SelectAttributes(SrchAttributes)
end sub

In this case I am selecting all bold text (direct formatting).

But the following code does not work:

sub SelectCharStyleEmphasis()
	Dim SrchAttributes(0) As New com.sun.star.beans.PropertyValue	
 	SrchAttributes(0).Name = "CharStyleName"
 	SrchAttributes(0).Value = "Emphasis"
	_SelectAttributes(SrchAttributes)
end sub

Here is a test case:
bug demo.odt (19.4 KB)

Is it that a bug? Or should I file an enhancement request?

Thank you
Emanuele

I’m not giving a solution yet, I’m just wondering - where did you get the CharStyleName for the parameter name? Why not CharFontStyleName, for example?

This screenshot shows the CharStyleName property in the new developer inspector (bottom), and in the style inspector (right). Its value is indeed “Emphasis”. The CharFontStyleName property is something else, in this case it is an empty string.

Thanks, I saw

The next question is - why do you think that the built-in search engine processes this part of the text (character style)? Were you able to do this through the GUI?

No, to my knowledge the GUI has no provision for searching character styles.
I just wanted to be sure that I was missing nothing before opening a new Libreoffice issue.

The only (complex) alternative would be a macro that checks each paragraph text portion, tables, footnotes, headers and footers testing for the specific CharStyleName. This works, but it is definitely not very suitable for the casual user.

To better understand it, I searched the LO C++ source code for the the built-in searching algorithm, but I was not capable of finding it up to now.

Why? The casual user should not be interested in what technology you used to solve the problem. And the enumeration of text fragments is not the worst solution. What to do with all found fragments so that the user sees them selected? Perhaps this topic will give you an idea.

How would you loop on all text fragments everywhere in the document?
Including tables and subtables, sections, frames, indexes, tocs, …

Regarding the selection of all found fragments, it seems to me that current LO allows for the selection of multiple fragments. If you look at my code, this works with multiple selection:

oFound = oDoc.findAll(oSrch)
oDoc.CurrentController.select(oFound)

Try the SelectBold button of the example case I attached, and two text portions are selected.
Or do I miss something?

Look at Pitonyak’s book, where the word “enumeration” occurs many times in relation to different parts of a text document.

Yes, that’s right - the result of .FindAll() is com.sun.star.text.TextRanges and the .select() method does it well. But we cannot FindAll for the character style name. The trick in the topic I referred to above is to find the necessary fragments of text (enumerate and analize parts of text in loop), set any attribute for these charactes that is obviously not used in the document … Then search for this attribute (yes, in the same way as you do for Bold), highlight the search result, and reset the attribute for selections.

Thank you very much. I’ll take a look at the Pitonyak’s book for enumerations.
The temporary text attribute is a great trick indeed.

Anyway I am going to open an issue on the matter of searching character style names, I think we deserve a cleaner solution, both for macros and the search GUI.

If you please write a short summary of your ideas I will gladly accept it as answer.
And I am going to add the resulting looping macro asap.

It seems to me that it will be better if you get the macro to work and post it here as an answer to your question. :wink:

Ok, I just wanted to aknowledge your valuable contribution :wink: