[Solved] Search and Select Character Style

Creating a macro - Writing a Script - Using the API (OpenOffice Basic, Python, BeanShell, JavaScript)
Post Reply
User avatar
bassklampfe
Posts: 19
Joined: Thu Aug 17, 2017 1:18 pm

[Solved] Search and Select Character Style

Post by bassklampfe »

I want to write a macro to select a specific text with a specific style.
Now my problem is in search description I can set SearchStyles to True, then a style is searched. Or i can set it to False, then a text is searched, so search for style AND text is not possible
My Idea was to search for text and then sort out all but the correct style:

Code: Select all

	oDoc = ThisComponent
	' Prepare the Search-Descriptor
	oSearchDesc = oDoc.createsearchDescriptor()
	oSearchDesc.SearchRegularExpression = True
	oSearchDesc.SearchWords = True
	oSearchDesc.SearchCaseSensitive = True
	oSearchDesc.SearchString  = "[ABCDEFGH][♯♭b#]"
	oFoundall = oDoc.FindAll(oSearchDesc)

	' drop wrong style
	i = 0
	Do While i < oFoundall.Count
		oFound = oFoundall(i)
		If oFound.CharStyleName = "Placeholder" then
			i=i+1
		Else
			oFoundall.Remove(i)
		End If
	Loop

	' highlight match
	oDoc.getCurrentController().Select(oFoundall)
But oFoundall.Remove(i) throws an error,it seems that oFoundall is no collection. What is the right instruction remove one item from oFoundall?

Thanks and Regards
Last edited by bassklampfe on Sat Jul 20, 2019 9:01 am, edited 2 times in total.
LibreOffice 6.0 on xubuntu 18.04 LTS
User avatar
Villeroy
Volunteer
Posts: 31269
Joined: Mon Oct 08, 2007 1:35 am
Location: Germany

Re: Search for text AND style

Post by Villeroy »

Do it like you would do in the user interface. Search for one thing and then for the other thing within the first result.
menu:find>replace...
Search for whatever and hit [Find All]. Now you have a selection of all matching snippets. Now search within the current selection for something else.

Keep variable oFoundall, prepare another searchdescriptor and then call oFoundall.FindAll(new_descr)
Please, edit this topic's initial post and add "[Solved]" to the subject line if your problem has been solved.
Ubuntu 18.04 with LibreOffice 6.0, latest OpenOffice and LibreOffice
User avatar
bassklampfe
Posts: 19
Joined: Thu Aug 17, 2017 1:18 pm

Re: Search for text AND style

Post by bassklampfe »

Well, I didn't mention, but the Style im searching, is a Character Style, not a Paragraph Style. Sorry.
If didn't make FindAll to find a Character Style at all, maybe then I would find another solution based on this....
LibreOffice 6.0 on xubuntu 18.04 LTS
User avatar
Villeroy
Volunteer
Posts: 31269
Joined: Mon Oct 08, 2007 1:35 am
Location: Germany

Re: Search for text AND style

Post by Villeroy »

Each found snippet can include sections with more than one character style. You have to loop through the search results and through the uniquely formatted snippets of each result. I am not familiar with the Writer API but it may be possible to use something like

Code: Select all

e = oFound.createEnumeration()
while e.hasMoreElements()
  snip = e.nextElement()
  if snip.CharacterStyleName = someCharStyle then ...
wend
Please, edit this topic's initial post and add "[Solved]" to the subject line if your problem has been solved.
Ubuntu 18.04 with LibreOffice 6.0, latest OpenOffice and LibreOffice
User avatar
Zizi64
Volunteer
Posts: 11352
Joined: Wed May 26, 2010 7:55 am
Location: Budapest, Hungary

Re: Search for text AND style

Post by Zizi64 »

Fixed version:
Search style.odt
(14.89 KiB) Downloaded 183 times
Last edited by Zizi64 on Sun Jul 14, 2019 9:35 pm, edited 2 times in total.
Tibor Kovacs, Hungary; LO7.5.8 /Win7-10 x64Prof.
PortableApps/winPenPack: LO3.3.0-7.6.2;AOO4.1.14
Please, edit the initial post in the topic: add the word [Solved] at the beginning of the subject line - if your problem has been solved.
JeJe
Volunteer
Posts: 2763
Joined: Wed Mar 09, 2016 2:40 pm

Re: Search for text AND style

Post by JeJe »

You can easily create an array with the ranges wanted,

Code: Select all


dim ofoundnew() 

for i = 0 to oFoundall.Count -1
If oFoundall(i).CharStyleName = "Placeholder" then
redim preserve ofoundnew(c)
ofoundnew(c) = oFoundall(i)
c=c+1
End If
next
   


Windows 10, Openoffice 4.1.11, LibreOffice 7.4.0.3 (x64)
User avatar
bassklampfe
Posts: 19
Joined: Thu Aug 17, 2017 1:18 pm

Re: Search for text AND style

Post by bassklampfe »

Zizi64 wrote:
Search style.odt
For the first: I'd never execute Macros from downloaded files.
So, I renamed it to .ZIP, extracted and examined the content.
You code

Code: Select all

  '  drop wrong style
   i = 0
   Print oFoundall.Count
   Do While i < oFoundall.Count
      oFound = oFoundall.getByIndex(i)
      If oFound.CharStyleName = "Placeholder" then         
         Print "The character ' " & oFound.getString & "'  has character style ' Placeholder' . It will not be removed"
      Else
         The Print "The character ' " & oFound.getString & "'  will be removed"   
         oFound.setString("")
      End If
      i=i+1
   Loop
Has one big issue: oFound.setString("") destroys the document content. I want to modify the found content lateron, but keep all other text.

But anyway, thanks for the try.
LibreOffice 6.0 on xubuntu 18.04 LTS
User avatar
bassklampfe
Posts: 19
Joined: Thu Aug 17, 2017 1:18 pm

Re: Search for text AND style

Post by bassklampfe »

JeJe wrote:You can easily create an array with the ranges wanted,
Thank you for your code. I already tried something similar, but

Code: Select all

	' highlight match
	oDoc.getCurrentController().Select(ofoundnew)
Does not work then
LibreOffice 6.0 on xubuntu 18.04 LTS
User avatar
Villeroy
Volunteer
Posts: 31269
Joined: Mon Oct 08, 2007 1:35 am
Location: Germany

Re: Search for text AND style

Post by Villeroy »

Because ofoundnew is a StarBasic type of array. It may be possible to create a new instance of an UNO object (c.s.s.text.TextRanges?) and append snippets to it.
The Calc component can produce an UNO collection of multiple ranges from scratch:

Code: Select all

oBasket = createUnoService("com.sun.star.sheet.SheetCellRanges")
for each range in someRanges()
  oBasket.addRangeAddress(range.getRangeAddress())
next
oController.select(oBasket)
Please, edit this topic's initial post and add "[Solved]" to the subject line if your problem has been solved.
Ubuntu 18.04 with LibreOffice 6.0, latest OpenOffice and LibreOffice
JeJe
Volunteer
Posts: 2763
Joined: Wed Mar 09, 2016 2:40 pm

Re: Search for text AND style

Post by JeJe »

If there's an attribute like overlining that you don't use in your document, mark the found result with that and do another find for it:

Code: Select all

for i = 0 to oFoundall.Count -1
If oFoundall(i).CharStyleName = "Placeholder" then
oFoundall(i).charoverline = 2
end if
next


Dim sAttributes(0) As New com.sun.star.beans.PropertyValue

SAttributes(0).Name = "CharOverline"
SAttributes(0).Value =2

oSearchDesc.SetSearchAttributes(SAttributes()) 
oSearchDesc.SearchString  =""
oFoundall = oDoc.FindAll(oSearchDesc)

oDoc.getCurrentController().Select(oFoundall) 
for i = 0 to oFoundall.Count -1
oFoundall(i).charoverline = 0
next
  
(its clunky but...)
Last edited by JeJe on Sun Jul 14, 2019 4:25 pm, edited 1 time in total.
Windows 10, Openoffice 4.1.11, LibreOffice 7.4.0.3 (x64)
User avatar
Zizi64
Volunteer
Posts: 11352
Joined: Wed May 26, 2010 7:55 am
Location: Budapest, Hungary

Re: Search for text AND style

Post by Zizi64 »

For the first: I'd never execute Macros from downloaded files.
So, I renamed it to .ZIP, extracted and examined the content.
Set the macro security to medium, and just open the file without enabling the macros. Then you can check the macro code with the built-in IDE.

Has one big issue: oFound.setString("") destroys the document content. I want to modify the found content lateron, but keep all other text.
A part of your code:
oFoundall.Remove(i)
Do you want to remove the searched characters, those have not the character style "Placeholder", does not?
Tibor Kovacs, Hungary; LO7.5.8 /Win7-10 x64Prof.
PortableApps/winPenPack: LO3.3.0-7.6.2;AOO4.1.14
Please, edit the initial post in the topic: add the word [Solved] at the beginning of the subject line - if your problem has been solved.
User avatar
Zizi64
Volunteer
Posts: 11352
Joined: Wed May 26, 2010 7:55 am
Location: Budapest, Hungary

Re: Search for text AND style

Post by Zizi64 »

There is a bug in my code:

Code: Select all

The Print "The character ' " & oFound.getString & "'  will be removed"
Use this:

Code: Select all

Print "The character ' " & oFound.getString & "'  will be removed"

And install and use an object inspesction tool like the Xray.
Tibor Kovacs, Hungary; LO7.5.8 /Win7-10 x64Prof.
PortableApps/winPenPack: LO3.3.0-7.6.2;AOO4.1.14
Please, edit the initial post in the topic: add the word [Solved] at the beginning of the subject line - if your problem has been solved.
User avatar
Zizi64
Volunteer
Posts: 11352
Joined: Wed May 26, 2010 7:55 am
Location: Budapest, Hungary

Re: Search for text AND style

Post by Zizi64 »

oFound.setString("") destroys the document content.
The oFound.setString("") will remove one character only. Tested in my LibreOffice 6.1.6
Tibor Kovacs, Hungary; LO7.5.8 /Win7-10 x64Prof.
PortableApps/winPenPack: LO3.3.0-7.6.2;AOO4.1.14
Please, edit the initial post in the topic: add the word [Solved] at the beginning of the subject line - if your problem has been solved.
User avatar
bassklampfe
Posts: 19
Joined: Thu Aug 17, 2017 1:18 pm

Re: Search for text AND style

Post by bassklampfe »

Zizi64 wrote:
A part of your code:
oFoundall.Remove(i)
Do you want to remove the searched characters, those have not the character style "Placeholder", does not?
This shall not remove the found text from the document, but the found item from the list of found items. But it seems, the list of found Items cannot be manipulated or reconstructed.

Just to give you an idea, the whole workflow of the script shall be as follows:
  • build a list (with FindAll or on an other way) of items matching specific criteria
  • Highlight all matching items using select()
  • Show a dialog to ask the user, what to do with the selected items
  • Depending on the choice in the dialog do different things with the selected items
I'm busy this week, I will come back when I make progress

Thanks for you help anyway
LibreOffice 6.0 on xubuntu 18.04 LTS
User avatar
bassklampfe
Posts: 19
Joined: Thu Aug 17, 2017 1:18 pm

Re: Search for text AND style

Post by bassklampfe »

I'm back again :-)
I developed some strategies, but im still struggling with the methods available.
oFoundall is of type com.sun.star.text.TextRanges. But I don't manage to create an empty, new TextRanges object.
My attempt was

Code: Select all

Dim foundChords As New com.sun.star.text.TextRanges
but this gives only error.

Second strategy was to manipulate oFoundall. From my understanding this is documented in https://www.openoffice.org/api/docs/com ... anges.html
I would like to use the methods removeByIndex and insertByIndex from https://www.openoffice.org/api/docs/com ... ainer.html, but I find no way to do it.
LibreOffice 6.0 on xubuntu 18.04 LTS
JeJe
Volunteer
Posts: 2763
Joined: Wed Mar 09, 2016 2:40 pm

Re: Search for text AND style

Post by JeJe »

To slightly extend my solution, you'd make note of the existing attribute/attributes (overlining if that is chosen) for each item and reaply them at the end. You just need a unique attribute or combination of attributes that you won't find in your document.

An alternative would be instead of selecting the ranges, to just mark them in some other obvious way - such as underlining (as the spellchecker does), overlining, or background color.
Windows 10, Openoffice 4.1.11, LibreOffice 7.4.0.3 (x64)
musikai
Volunteer
Posts: 294
Joined: Wed Nov 11, 2015 12:19 am

Re: Search for text AND style

Post by musikai »

The Extension "Alt-Search and Replace" can find and select the combination by entering this regular Expresssion:

Code: Select all

[:::CharStyleName=Placeholder::][ABCDEFGH]

As with all macro code searches, the first found item always gets deselected here in LO4.4.7.2

But you can try your luck and perhaps find sth useful in the code of Alt-Search&Replace.
Last edited by musikai on Thu Jul 18, 2019 7:53 pm, edited 1 time in total.
Win7 Pro, Lubuntu 15.10, LO 4.4.7, OO 4.1.3
Free Project: LibreOffice Songbook Architect (LOSA)
http://struckkai.blogspot.de/2015/04/li ... itect.html
User avatar
bassklampfe
Posts: 19
Joined: Thu Aug 17, 2017 1:18 pm

Re: Search for text AND style

Post by bassklampfe »

Just to inform you, I now do an attribute search (CharColor is the unique Style of the CharacterStyle in question) and get exactly what I need.
This is the starting of my code:

Code: Select all

Sub SelectPlaceholder

	'
	' set global vars
	'
	Dim oDoc As Object
	oDoc = ThisComponent
	
	'
	' find the character style Placeholder
	'
	Dim oStyleFamilies,oCharStyles,oCharStylePlaceholder as object
	oStyleFamilies = oDoc.getStyleFamilies()
	oCharStyles = oStyleFamilies.getByName("CharacterStyles")
	oCharStylePlaceholder=oCharStyles.getByName("Placeholder")

	'
	' build the seach
	'	
	Dim oSearchDesc As Object
	Dim srchAttributes(0) As New com.sun.star.beans.PropertyValue
	oSearchDesc = oDoc.createsearchDescriptor()
	srchAttributes(0).Name = "CharColor"
	srchAttributes(0).Value = oCharStylePlaceholder.CharColor
	oSearchDesc.SearchStyles = True
	oSearchDesc.SetSearchAttributes(srchAttributes)

	'
	' do the search
	'
	Dim oFoundall As Object
	oFoundall = oDoc.FindAll(oSearchDesc)
   
	'
	' highlight match
	'
	oDoc.getCurrentController().Select(oFoundall)

	'
	' do further processing
	'
	....

end sub
The only issue left is, the FIRST element found is NOT highlighted by oDoc.getCurrentController().Select(oFoundall) this seems to be a bug in OO?
Any solution/workaround for this?

Thanks all for your suggestions.
LibreOffice 6.0 on xubuntu 18.04 LTS
musikai
Volunteer
Posts: 294
Joined: Wed Nov 11, 2015 12:19 am

Re: Search for text AND style

Post by musikai »

bassklampfe wrote:
The only issue left is, the FIRST element found is NOT highlighted by oDoc.getCurrentController().Select(oFoundall) this seems to be a bug in OO?
Any solution/workaround for this?
Seems to be a bug in all versions of OO and LO I could test.

As the cursor always collapses to the end of the first item (if the Foundall has more than 1 item) we could move the Viewcursor to the left by the length of the first item:

Code: Select all

    oVC = oDoc.CurrentController.getViewCursor
    if oFoundall.count>1 then oVC.goleft(len(oFoundall(0).string),true)
Win7 Pro, Lubuntu 15.10, LO 4.4.7, OO 4.1.3
Free Project: LibreOffice Songbook Architect (LOSA)
http://struckkai.blogspot.de/2015/04/li ... itect.html
User avatar
bassklampfe
Posts: 19
Joined: Thu Aug 17, 2017 1:18 pm

Re: Search for text AND style

Post by bassklampfe »

musikai wrote:

Code: Select all

    oVC = oDoc.CurrentController.getViewCursor
    if oFoundall.count>1 then oVC.goleft(len(oFoundall(0).string),true)
Yeah man! Thank you,now everything is fine
Regards to all the people getting me on the right way
LibreOffice 6.0 on xubuntu 18.04 LTS
User avatar
bassklampfe
Posts: 19
Joined: Thu Aug 17, 2017 1:18 pm

Re: [Solved] Search and Select Character Style

Post by bassklampfe »

I rename the title from "Search for text AND style" to "Search and Select Character Style" to make it more accessible by search topic
LibreOffice 6.0 on xubuntu 18.04 LTS
Post Reply