Page 1 of 1

[Solved] [C#] Get text between two ranges

PostPosted: Thu Jan 28, 2021 4:11 pm
by Lumberjack
Hi
I have small problem . I'd like copy (get) text between two strings in document. This text should by insert at the end of second string.
This is my code.
Code: Select all   Expand viewCollapse view

XSearchDescriptor xSearchDecriptor0 = ((unoidl.com.sun.star.util.XSearchable)oDoc).createSearchDescriptor();
  xSearchDecriptor0.setSearchString("<el:strony>");

XSearchDescriptor xSearchDecriptor1 = ((unoidl.com.sun.star.util.XSearchable)oDoc).createSearchDescriptor();
  xSearchDecriptor1.setSearchString("</el:strony>");

  XTextRange  objAdresatStr = ((XTextRange)((unoidl.com.sun.star.util.XSearchable)oDoc).findFirst(xSearchDecriptor0)).getEnd();
  XTextRange  objAdresatStop = ((XTextRange)((unoidl.com.sun.star.util.XSearchable)oDoc).findFirst(xSearchDecriptor1)).getStart();

    XText xPos = (objAdresatStr).getText();

xPos.insertString(objAdresatStop , "[text between <el:strony> and </el:strony> ]" , false);



<el:strony> and </el:strony> are this two string. I what get formated text between <el:strony> and </el:strony> and insert at the and of </el:strony> string.

How can i do this?
 Edit: Topic moved from Writer forum to Macros and UNO API 

Re: Get text between two ranges

PostPosted: Thu Jan 28, 2021 6:14 pm
by FJCC
Here is a simple Basic macro that finds the text between the two markers and copies it to a position just after the second marker. The original text is not deleted and the formatting is not copied. I do not see a way to copy the formatting if it has been applied manually. If you know that the formatting has been set with a character or paragraph style, that style could be applied to the text in the new position.
Code: Select all   Expand viewCollapse view
Desc = ThisComponent.createSearchDescriptor()
Desc.searchString = "<el:strony>"
Rng1 = ThisComponent.findFirst(Desc)

Desc.searchString = "</el:strony>"
Rng2 = ThisComponent.findFirst(Desc)

oCurs = ThisComponent.Text.createTextCursorByRange(Rng1.End)
oCurs.gotoRange(Rng2.Start, TRUE)

CursString = oCurs.getString()
oCurs.gotoRange(Rng2.End, FALSE)
oCurs.setString(CursString)

Re: Get text between two ranges

PostPosted: Thu Jan 28, 2021 7:49 pm
by Villeroy

Re: Get text between two ranges

PostPosted: Thu Jan 28, 2021 9:16 pm
by JeJe
Select the range and use gettransferable to copy it, then move the cursor to where you want it and use inserttransferable

This, in basic, copies the current selection, collapses the selection, and inserts a 2nd copy after it

Code: Select all   Expand viewCollapse view
trans =thiscomponent.currentcontroller.gettransferable

thiscomponent.currentcontroller.viewcursor.collapsetoend

thiscomponent.currentcontroller.inserttransferable trans


Re: Get text between two ranges

PostPosted: Fri Jan 29, 2021 9:46 am
by Lumberjack
Thanks for replied. Text is copied. Is this any way to copy formated text , for example with bold font.
Now i use insertString , mayby i should use insertTextContent.

Re: Get text between two ranges

PostPosted: Fri Jan 29, 2021 11:54 am
by Lumberjack
Now i try to use get getTransferable(). How can i get CurrentController for XComponent?

Re: Get text between two ranges

PostPosted: Fri Jan 29, 2021 1:16 pm
by Villeroy

Re: Get text between two ranges

PostPosted: Fri Feb 26, 2021 10:52 am
by Lumberjack
Hi
Now i try to use getTransfarable() ( c# ) , no success. I Where is the problem? Cursor is set correct. Value of 'CurString' object is ok. But value is not copy below CurString position. Mayby selection
Code: Select all   Expand viewCollapse view
((unoidl.com.sun.star.view.XSelectionSupplier)xControler).select(anySel);
works wrong. I try to copy object with formated text.
I have text :

strona 1

i expect :

strona 1
strona 1

Code: Select all   Expand viewCollapse view
                       XText xText = ((unoidl.com.sun.star.text.XTextDocument)oDoc).getText();
                        XTextCursor oCurs = (XTextCursor)xText.createTextCursorByRange(objAdresatStr);
                        oCurs.gotoRange(objAdresatStop, true);

             string CursString = oCurs.getString();
                        XController xControler = ((unoidl.com.sun.star.frame.XModel)oDoc).getCurrentController();
                        uno.Any anySel = new uno.Any(oCurs.GetType(), oCurs);
                  
                        bool iSelect = ((unoidl.com.sun.star.view.XSelectionSupplier)xControler).select(anySel);
                        uno.Any selectedAny = ((unoidl.com.sun.star.view.XSelectionSupplier)xControler).getSelection();

                        unoidl.com.sun.star.datatransfer.XTransferable selectedContent = ((unoidl.com.sun.star.datatransfer.XTransferableSupplier)xControler).getTransferable();
                       
                        ((unoidl.com.sun.star.datatransfer.XTransferableSupplier)xControler).insertTransferable(selectedContent);

Re: Get text between two ranges

PostPosted: Fri Feb 26, 2021 11:17 am
by JeJe
Here's a simple example in Basic that copies the document text
Code: Select all   Expand viewCollapse view
Sub Main
c=thiscomponent.currentcontroller
c.select thiscomponent.gettext
trans = c.gettransferable
c.viewcursor.collapsetoend
c.inserttransferable trans
End Sub

Re: Get text between two ranges

PostPosted: Mon Mar 01, 2021 4:09 pm
by Lumberjack
Thanks. Its work. Below is my code :

Code: Select all   Expand viewCollapse view
  XSearchDescriptor xSearchDecriptor1 = ((unoidl.com.sun.star.util.XSearchable)oDoc).createSearchDescriptor();
                        xSearchDecriptor1.setSearchString("<el:strony>");
                        XTextRange objAdresatStr = ((XTextRange)((unoidl.com.sun.star.util.XSearchable)oDoc).findFirst(xSearchDecriptor1)).getEnd();

                        xSearchDecriptor1 = ((unoidl.com.sun.star.util.XSearchable)oDoc).createSearchDescriptor();
                        xSearchDecriptor1.setSearchString("</el:strony>");
                        XTextRange objAdresatStop = ((XTextRange)((unoidl.com.sun.star.util.XSearchable)oDoc).findFirst(xSearchDecriptor1)).getStart();

                        XText xText = ((unoidl.com.sun.star.text.XTextDocument)oDoc).getText();
                        XTextCursor oCurs = (XTextCursor)xText.createTextCursorByRange(objAdresatStr);
                        oCurs.gotoRange(objAdresatStop, true);

                        XController xControler = ((unoidl.com.sun.star.frame.XModel)oDoc).getCurrentController();

                      //  ((unoidl.com.sun.star.frame.XModel)oDoc).
                        string s = oCurs.getString();
                     
;                        uno.Any anySel = new uno.Any(oCurs.GetType(), oCurs);
                        bool iSelect = ((unoidl.com.sun.star.view.XSelectionSupplier)xControler).select(anySel);
                        uno.Any selectedAny = ((unoidl.com.sun.star.view.XSelectionSupplier)xControler).getSelection();
                        bool b = selectedAny.hasValue();

                     
                     //   XReplaceDescriptor replaceSelec = ((XReplaceable)oCurs).createReplaceDescriptor();
                      //  replaceSelec.setSearchString("<el:imie />");
                      //  replaceSelec.setReplaceString("<el:imie />_1");

                     //   ((XReplaceable)oCurs).replaceAll(replaceSelec);

                        unoidl.com.sun.star.datatransfer.XTransferable selectedContent = ((unoidl.com.sun.star.datatransfer.XTransferableSupplier)xControler).getTransferable();
                        oCurs.collapseToEnd();
                 
                        ((unoidl.com.sun.star.datatransfer.XTransferableSupplier)xControler).insertTransferable(selectedContent);


But i have the question.
Is the any way to replace text from one to another in selection only (not in all document). From '"<el:imie />"' to "<el:imie />_1" but only in selection range. How can i do it? I want to keep formated text after replace. If '"<el:imie />"' is bold , "<el:imie />_1" should by bold .

Re: Get text between two ranges

PostPosted: Mon Mar 01, 2021 11:39 pm
by JeJe
Not sure what your asking. Are you asking how to do a search operation just on the selected text? If so I think you have to either use the dispatchhelper (the macro record will produce some code in BASIC for that which you'll have to translate) or go through each result and compare the range of what's found to the selection using XTextRangeCompare

https://www.openoffice.org/api/docs/com ... mpare.html

Re: Get text between two ranges

PostPosted: Tue Mar 02, 2021 7:35 am
by Lumberjack
It is possible i want to search and replace text in selected range. Now i use code to replace text in all document in success. This code replace 'text1' to 'text2' but in whole document (oDoc is all document).
I want use similar code to replace but in selection.

Code: Select all   Expand viewCollapse view
XComponent oDoc = null;
     
oDoc = oDesk.loadComponentFromURL(fileName, fileName, 0, propVals);
         
XReplaceDescriptor replace = ((XReplaceable)oDoc).createReplaceDescriptor();
 
replace.setSearchString("text1");
replace.setReplaceString("text2");

((XReplaceable)oDoc).replaceAll(replace);

Re: Get text between two ranges

PostPosted: Tue Mar 02, 2021 12:26 pm
by JeJe
Record a macro and translate it into your language - I'm pretty sure you have to do that and you can't do it another way. Search in selection isn't an option in the searchdescriptor API method.