Page 1 of 1

[Solved] Retrieving view cursor - currentComponent

Posted: Mon Aug 14, 2017 11:15 am
by ElFlamencoLoco
Hi folks,

My project in Writer treats text documents with a very simple structure: only a body text and a header. The header is protected, so the user cannot edit it. Only the body text is "editable".

Problem
However, the header is "selectable": i.e. by clicking upon it, the view cursor moves to the header. Which raises (in some macros) a problem:

Code: Select all

dim oViewCursor as object, oCursor as object
oViewCursor = oDoc.getCurrentController.getViewCursor

'Error if view cursor in header instead of in body text
oCursor = oDoc.Text.createTextCursorByRange(oViewCursor)
How to solve?
1. My first solution is intercepting the error and putting a message box asking the user to reposition the cursor in the body text before continuing. This is of course not very elegant, but for now it's okay.

2. A better solution is to re-select the body text as the "CurrentComponent". Anybody an idea how to achieve this?

3. The best solution is to make the header "unselectable", so the user cannot put the view cursor there, even when clicking upon it, maintaining the body text as the only possible "CurrentComponent". Any ideas?

Thanks in advance.

Re: Retrieving view cursor - currentComponent

Posted: Mon Aug 14, 2017 9:08 pm
by FJCC
Here is a possible path towards your #1. You can compare the position of the view cursor to the Start of either the text body or the header. If the view cursor is in the text body, comparing to the location of HeaderText.Start throws an error. Having the view cursor in the header causes an error upon comparison to the Text.Start.

Code: Select all

oStyleFamilies = ThisComponent.getStyleFamilies()
oObj1 = oStyleFamilies.getByName("PageStyles")
oObj2 = oObj1.getByName("Standard")
oHdrText = oObj2.HeaderText
  
oText = ThisComponent.Text 'body text
 
oVC = ThisComponent.CurrentController.ViewCursor
 
'Following line throws an error if oVC is in the text body
'Status = oHdrText.compareRegionStarts(oHdrText.Start, oVC)
 
'Following line throws an error if oVC is in the Header
Status = oText.compareRegionStarts(oText.Start, oVC)
print Status
You should be able to catch and handle those errors.

I am not sure what you mean by #2.

Re: Retrieving view cursor - currentComponent

Posted: Mon Aug 14, 2017 10:15 pm
by ElFlamencoLoco
FJCC wrote:Here is a possible path towards your #1 etc...
Actually I did allready implement solution #1, as I mentioned. Your misunderstanding might be due to my rather bad English. Sorry for that.

Here my implementation:

Code: Select all

oViewCursor = oDoc.getCurrentController.getViewCursor
on error goto USER_MUST_REPOSITION_CURSOR
oCursor = oDoc.Text.createTextCursorByRange(oViewCursor)
goto OKAY
USER_MUST_REPOSITION_CURSOR:
MsgBox("Please, click somewhere in the body text.")
END 'Macro terminates here
OKAY:
'Macro continues here
FJCC wrote:I am not sure what you mean by #2.
What I mean: the view cursor is retrieved from the current controller. The current controller in my case can be:
  • the header controller
  • the body text controller
depending on whether the view cursor is located into the header or the body text.

So, if the current controller controls the body text, there is no problem. However, if it controls the header, the view cursor gives access to the header instead of to the body text.

Concerning solution #2, my question is this. If the current controller concerns the header instead of the body text, is there a way to "reselect" the body text (without bothering the user with a message box)? So retrieving the view cursor will always give access to the body text.

And, of course, solution #3 might be the most elegant one by not even allowing the user to put the cursor (accidentilly) into the header. But that's another story...

For now, thanks very much anyway. ;)

Re: Retrieving view cursor - currentComponent

Posted: Wed Aug 16, 2017 3:33 pm
by hubert lambert
hello,
ElFlamencoLoco wrote:

Code: Select all

'Error if view cursor in header instead of in body text
oCursor = oDoc.Text.createTextCursorByRange(oViewCursor)
This code fails because the text of the header is not the same object as the document main text (i.e. "oDoc.Text").
ElFlamencoLoco wrote:2. A better solution is to re-select the body text as the "CurrentComponent". Anybody an idea how to achieve this?
Try something like this :

Code: Select all

if not EqualUnoObjects(oViewCursor.Text, oDoc.Text) then
    oDoc.getCurrentController.select(oDoc.Text.Start)
end if
ElFlamencoLoco wrote:3. The best solution is to make the header "unselectable", so the user cannot put the view cursor there, even when clicking upon it, maintaining the body text as the only possible "CurrentComponent". Any ideas?
I don't know if this is even possible...

Regards.

Re: Retrieving view cursor - currentComponent

Posted: Wed Aug 16, 2017 8:10 pm
by ElFlamencoLoco
Thank you verry much, Hubert. I 've simply added this line:

Code: Select all

oDoc.getCurrentController.select(oDoc.Text.Start)
So, retrieving the view cursor garantees it is always in the text body.

Even checking whether the view cursor is elsewhere is not necessary. One simple line of code makes life easier.

Re: Retrieving view cursor - currentComponent

Posted: Wed Aug 16, 2017 8:20 pm
by Lupp
(Editing: Sorry. Once more posts crossed.)

I don't think you actually worry about the ViewCursor. You want to get a TextCursor for working on the TextBody.
What about

Code: Select all

Sub Test
oDoc = ThisComponent
oText= oDoc.Text                             REM Will never contain the header.
oDoc.CurrentController.Select(oText)
oVC  = oDoc.CurrentController.GetViewCursor
oTC  = oDoc.Text.createTextCursorByRange(oVC)
End Sub
I may have misunderstood something. Not much experience with programming for 'Writer'.
See also attached demo. (I also tried with a protected section defined for the header.)