Select multiple text ranges in Writer

Creating a macro - Writing a Script - Using the API (OpenOffice Basic, Python, BeanShell, JavaScript)
Post Reply
j.kornelsn
Posts: 14
Joined: Wed Oct 06, 2010 6:26 am

Select multiple text ranges in Writer

Post by j.kornelsn »

I am looking for an automated way to select more than one range of text at the same time. I would like to be able to do this:

Code: Select all

# select the first range
oVC = controller.getViewCursor()
oVC.goRight(4, True)
oSels = controller.getSelection()
oSel = oSels.getByIndex(0)
oCursor1 = oSel.getText().createTextCursorByRange(oSel)

# select the second range
oVC.goRight(1, False)
oVC.goRight(4, True)
oSels = controller.getSelection()
oSel = oSels.getByIndex(0)
oCursor2 = oSel.getText().createTextCursorByRange(oSel)

# select both ranges at the same time
textRanges = (oCursor1, oCursor2)
controller.select(textRanges)
It seems close to working, but apparently it does not create the textRanges object in a way that select() will accept as an argument. What does work is this:

Code: Select all

selsFound = document.findAll(search)
oVC.goRight(0, False)  # deselect
controller.select(selsFound)
The disadvantage here is that I am limited only to what I can search for, rather than being able to freely select various sections of text. The xray tool shows that the type of selsFound is SwXTextRanges. Has anyone managed to create an object of that type?

A solution in python would be preferred but Basic or Java is fine if I can figure out how to convert it.
LO / AOO on Ubuntu / Windows
User avatar
karolus
Volunteer
Posts: 1160
Joined: Sat Jul 02, 2011 9:47 am

Re: Select multiple text ranges in Writer

Post by karolus »

Hallo

I don't find something obviously - but - what's next? - why not work on the single Textportions?

Karolus
AOO4, Libreoffice 6.1 on Rasbian OS (on ARM)
Libreoffice 7.4 on Debian 12 (Bookworm) (on RaspberryPI4)
Libreoffice 7.6 flatpak on Debian 12 (Bookworm) (on RaspberryPI4)
User avatar
RoryOF
Moderator
Posts: 34618
Joined: Sat Jan 31, 2009 9:30 pm
Location: Ireland

Re: Select multiple text ranges in Writer

Post by RoryOF »

Why not use Find All?
Apache OpenOffice 4.1.15 on Xubuntu 22.04.4 LTS
B Marcelly
Volunteer
Posts: 1160
Joined: Mon Oct 08, 2007 1:26 am
Location: France, Paris area

Re: Select multiple text ranges in Writer

Post by B Marcelly »

I am looking for an automated way to select more than one range of text at the same time.
Why ?
The reason that you can manually select several ranges is to save you steps.
Since you are using macros you can do what you want, one range at a time. The computer will never get tired.
Bernard

OpenOffice.org 1.1.5 / Apache OpenOffice 4.1.1 / LibreOffice 5.0.5
MS-Windows 7 Home SP1
j.kornelsn
Posts: 14
Joined: Wed Oct 06, 2010 6:26 am

Re: Select multiple text ranges in Writer

Post by j.kornelsn »

Well, I am not sure this will make sense to you, but here is an attempt at an explanation as to why I want to do this:

I am using it as part of an automated test suite for a pyuno extension that responds to whatever the user has currently selected. So I need to simulate what a user would do, and they may want to select multiple text portions. Why would they want to select multiple text portions? In order to convert encodings or writing systems. For example they may want to convert certain words in a document from a legacy font encoding such as http://www.tscii.org to unicode encoding for a font such as Latha. These documents tend to use several different languages, so it is not unlikely that they may only select certain words that are using a particular language. Also each change requires the user to perform several steps for each word (some in an external application), so the ability to make more than one selection at a time may be important.

Let me reiterate that the extension itself is not the problem here. It already handles multiple selections. It's the test suite that is the problem.

By the way, an odd thing with the hack is that calling select() for multiple items loses the first item selected, which is the one where the view cursor ends up. To get around this, I searched for an extra item. So for example if I needed 5 selections, I actually did findAll() for 6 because then it would end up selecting 5 of them. This was not an impossible problem to work around, but still... I would prefer a better solution.

Much of the suite is already working, but this is one piece that is not finished. If you do not have any ideas then I will stick with the "Find All" hack that part way worked.
Last edited by j.kornelsn on Mon Oct 12, 2015 6:07 pm, edited 1 time in total.
LO / AOO on Ubuntu / Windows
User avatar
RoryOF
Moderator
Posts: 34618
Joined: Sat Jan 31, 2009 9:30 pm
Location: Ireland

Re: Select multiple text ranges in Writer

Post by RoryOF »

You might investigate AltSearch, available from the Extensions repository.

AltSearch

It is written in Python and I think the code is available ~ I haven't checked. It may offer you many more facilities then you require, but you could perhaps copy the Find/Replace section and if necessary tweak any tendency to lose a Find item, if it exists in that extension.
Apache OpenOffice 4.1.15 on Xubuntu 22.04.4 LTS
j.kornelsn
Posts: 14
Joined: Wed Oct 06, 2010 6:26 am

Re: Select multiple text ranges in Writer

Post by j.kornelsn »

Actually AltSearch seems to be written in OO Basic. Awhile back I borrowed an idea from that code for searching for character styles. It may have something useful for multiple selections as well, but I have not yet found it. Unfortunately the comments are not written in a language that I can read. Can any of you read them?

For example: ' vraci odhadnutý datový typ pro atributy textu
Google thinks this is Czech, and it suggests a translation:
"estimated returns data type of text attributes"
Which perhaps makes sense, but it would be a painful way to look through all of the code.
LO / AOO on Ubuntu / Windows
User avatar
RoryOF
Moderator
Posts: 34618
Joined: Sat Jan 31, 2009 9:30 pm
Location: Ireland

Re: Select multiple text ranges in Writer

Post by RoryOF »

I have obviously misremembered the language in which it was written. For those who do not know there is a good downloadable help file on the Extensions repository page, although that is no help with the incode comments.

I have just tried with one of the routines. I cut and pasted it into Google translate and it translated all the Czech of the file into English, so you might not need to do the translation line by line.
Apache OpenOffice 4.1.15 on Xubuntu 22.04.4 LTS
User avatar
Ms Ruth
Posts: 3
Joined: Thu Mar 19, 2020 9:00 pm

Re: Select multiple text ranges in Writer

Post by Ms Ruth »

j.kornelsn wrote:By the way, an odd thing with the hack is that calling select() for multiple items loses the first item selected, which is the one where the view cursor ends up. To get around this, I searched for an extra item. So for example if I needed 5 selections, I actually did findAll() for 6 because then it would end up selecting 5 of them. This was not an impossible problem to work around, but still... I would prefer a better solution.
I realize this topic is from over four years ago, but I have repeatedly searched for the exact same solution to working with and manipulating a multiple selection. For years, this was the only post that really addressed using the TextRanges service for multiselection. (There is one more since July 2019.)

I, too, made do with the findAll method while seeking a better, more elegant process. I have ideas about avenues to try, but while doing so, encountered the same bug of losing the first selection. It seems the cursor behavior is counterintuitive. After searching forward with Find All in the UI, the cursor's direction is left, but when searching backward, the cursor's direction is right.

Realizing this strange pattern, I found a solution to re-selecting the original found and/or selected text ranges. It works after searching forward or backward. The following BASIC code is very basic, and should be easily modified as necessary.

Code: Select all

   Dim Doc As Object ' I have other declarations. These are the relevant ones.
   DocVw As Object, VwCursor As Object, StoreSel As Object, FoundAll As Object
   ' relevant snippets of code

    Doc = ThisComponent

   ' variable definitions

   ' This is the text I want to manipulate.
    Found = Doc.findAll(TxtSearch) ' TextRanges

    DocVw = Doc.CurrentController ' TextView

   ' Note: Can't use a TextCursor for multiselections.
    VwCursor = DocVw.ViewCursor ' TextViewCursor

   ' This is the current multiselection. It has no relevance to the procedure,
   ' but after the macro's execution, I want it restored to its current state.
   ' HERE'S THE TRICK.
   ' Correct the cursor/selection direction
   ' so it won't drop the first text range when recalled.
    VwCursor.gotoRange(Doc.CurrentSelection(0).Start, True)

   ' Now save the current multiselection for recall.
    StoreSel = DocVw.Selection ' TextRanges

   ' If needed, follow the same steps for the Found TextRanges. If you step through
   ' the macro and check the document here, the selection appears to have dropped
   ' the first text range. There is still a range, but it has collapsed to its end.
    DocVw.select(Found)

   ' Repeat the trick. Now all the full ranges of Found are selected.
    VwCursor.gotoRange(Found(0).Start, True) ' success

   ' Save the multiselection for recall, if needed.
   ' I renamed these TextRanges because I want to manipulate the Found TextRanges.
    FoundAll = DocVw.Selection ' TextRanges

   ' Restore the selection to its initial state.
    DocVw.select(StoreSel)

   ' The first range is collapsed, so repeat the trick.
    VwCursor.gotoRange(StoreSel(0).Start, True) ' success

   ' multiple lines of irrelevant program code

   ' Either or both of the saved TextRanges can be recalled for manipulation.
    DocVw.select(FoundAll)

    VwCursor.gotoRange(FoundAll(0).Start, True) ' success
   ' For example, the entire FoundAll could be formatted here.

   ' Restore the initial selection.
    DocVw.select(StoreSel)

   ' Repeat the trick.
    VwCursor.gotoRange(StoreSel(0).Start, True) ' success

   ' final lines of code for error-handling and End macro
Apache OpenOffice 4.1.11
LibreOffice 7.1.8 (x64)
Windows 10
JeJe
Volunteer
Posts: 2784
Joined: Wed Mar 09, 2016 2:40 pm

Re: Select multiple text ranges in Writer

Post by JeJe »

Ms Ruth - thanks that's a useful tip. I'm sure we can all write this, but here's some code for setting multiple selections using a temporary character property such as charflash

Code: Select all

sub multipleselect
'note no stupidity checks, assumes results for found etc

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

on error goto hr
thiscomponent.lockcontrollers
Doc = ThisComponent

'1 just for this example make two selections and set a property you don't use in the document like charflash or charoverline perhaps
'Don't know how stable charflash is though as I never use (which is the reason to use it here)

vc = thiscomponent.currentcontroller.viewcursor
vc.gotorange(thiscomponent.text.start,false)
vc.goright(5,true): vc.charflash = true
'vc.goright(5,true): vc.charOverline =1
vc.goright(5,false)
vc.goright(5,true): vc.charflash = true
'vc.goright(5,true): vc.charoverline = 1
vc.gotorange(thiscomponent.text.start,false)


'2 do a find for that property
SrchAttributes(0).Name = "CharFlash": SrchAttributes(0).Value =true
'SrchAttributes(0).Name = "CharOverline": SrchAttributes(0).Value =1
txtsearch = doc.createsearchdescriptor
txtsearch.setSearchAttributes SrchAttributes
txtsearch.setvaluesearch(false)
Found = Doc.findAll(TxtSearch)

'3 include the first selection using  Ms Ruth's trick
thiscomponent.currentcontroller.select(Found)
VC.gotoRange(Found(0).Start, True) 

'4 undo the property change leaving the selection
VC.charflash = false
'VC.charOverline = 0

hr:
thiscomponent.unlockcontrollers
end sub


Windows 10, Openoffice 4.1.11, LibreOffice 7.4.0.3 (x64)
Post Reply