[Solved] Setting an event listener when a frame size change?

Creating a macro - Writing a Script - Using the API (OpenOffice Basic, Python, BeanShell, JavaScript)
Post Reply
Alectrona
Posts: 17
Joined: Tue Mar 24, 2020 7:04 pm

[Solved] Setting an event listener when a frame size change?

Post by Alectrona »

In writer, I have frames with automatic height.

I want to run some code as soon as a frame current height changes, so as soon as thiscomponent.textframes.getByIndex(0).LayoutSize.Height value changes.

My first idea was doing an infinite loop, checking for my frame height every 50 milliseconds

Code: Select all

sub autogrow
   oDoc = thiscomponent
    oItem = oDoc.textframes.getByIndex(0)
      hgt = oItem.LayoutSize.Height
      Do
         updated_height = oItem.LayoutSize.Height 
         if not (updated_height = hgt) then
            hgt = updated_height
            msgbox "The height has changed!"
         end if
       Wait 50
      Loop Until 0=1
end sub
But this makes LibreOffice going nuts, my mouse cursor keeps turning into hourglass, my text caret stops blinking, LibreOffice freezes...

I guess the LayoutSize method consumes too much ressources to be run every 50 milliseconds. And I need to use myFrame.LayoutSize.Height over myFrame.height, because this last one gives me the minimal height of the frame instead of the current height of the frame on the screen.

-> Is there a way to add an event listenner on my frame, to run some code as soon as the layoutsize changes?

I have found this on the API doc but I am clueless about how to use it :
https://www.openoffice.org/api/docs/com ... tener.html
https://www.openoffice.org/api/docs/com ... aster.html
Last edited by Hagar Delest on Sat Mar 28, 2020 11:07 am, edited 1 time in total.
Reason: tagged solved
LibreOffice 6.2.8.2 on Windows 10
JeJe
Volunteer
Posts: 2780
Joined: Wed Mar 09, 2016 2:40 pm

Re: Setting an event listener when a frame size change?

Post by JeJe »

If you right click on the frame and choose the Frame options dialog there's a tab called Macro where you can set a macro to the resize event
Windows 10, Openoffice 4.1.11, LibreOffice 7.4.0.3 (x64)
Alectrona
Posts: 17
Joined: Tue Mar 24, 2020 7:04 pm

Re: Setting an event listener when a frame size change?

Post by Alectrona »

Unfortunately this size change event doesnt react when the frame height automatically grows while inputing text;

The size change event in the macro tab of a frame properties is linked to minimal size ; it only triggers when I set a higher minimal height, or when I manually resize the frame with the mouse.

Edit : This event listener only triggers when I click on the frame...

Image
LibreOffice 6.2.8.2 on Windows 10
JeJe
Volunteer
Posts: 2780
Joined: Wed Mar 09, 2016 2:40 pm

Re: Setting an event listener when a frame size change?

Post by JeJe »

Use the input of non-numeric/numeric characters events to call a sub that gets the layout size whenever anything is typed - that works I've just tested it.
Windows 10, Openoffice 4.1.11, LibreOffice 7.4.0.3 (x64)
Alectrona
Posts: 17
Joined: Tue Mar 24, 2020 7:04 pm

Re: Setting an event listener when a frame size change?

Post by Alectrona »

JeJe wrote:Use the input of non-numeric/numeric characters events to call a sub that gets the layout size whenever anything is typed - that works I've just tested it.
Problem is that this macro fires before any character is inserted, so before the layout changes

And in my case I may have a frame B inside a frame A. Anything typed into the frame B won't fire the input event of the frame A.

Image

So I would need to check the layout of every frame everytime I am typing something. It would be as much slow and buggy as with my loop idea, it will consume too much ressources for my poor Thinkpad

So I think my only hope is to study deeper the black magic of OpenOffice programmatic assignment of scripts to events
LibreOffice 6.2.8.2 on Windows 10
Alectrona
Posts: 17
Joined: Tue Mar 24, 2020 7:04 pm

Re: Setting an event listener when a frame size change?

Post by Alectrona »

My goal is to automatically adjust the size of braces, brackets, parenthesis to their content

Image Image
LibreOffice 6.2.8.2 on Windows 10
JeJe
Volunteer
Posts: 2780
Joined: Wed Mar 09, 2016 2:40 pm

Re: Setting an event listener when a frame size change?

Post by JeJe »

Run startkeyhandler - this will give you a keyreleased event

Code: Select all

sub startkeyhandler
oXKeyHandler = CreateUnoListener("KeyHandler_", "com.sun.star.awt.XKeyHandler")
thiscomponent.CurrentController.AddKeyHandler(oXKeyHandler)
end sub
sub KeyHandler_Disposing(oEvent)
end sub
function KeyHandler_KeyPressed(oEvent) as boolean
End function

function KeyHandler_KeyReleased(oEvent) as boolean 
v= thiscomponent.currentcontroller.viewcursor
if isempty(v) = false then
if isempty(v.textframe) =false then
msgbox  v.textframe.LayoutSize.height
end if
end if
end function

Windows 10, Openoffice 4.1.11, LibreOffice 7.4.0.3 (x64)
Alectrona
Posts: 17
Joined: Tue Mar 24, 2020 7:04 pm

Re: Setting an event listener when a frame size change?

Post by Alectrona »

Ok, atm it doesnt freeze.

Since a frame may be inside another frame, I need to check the layout of the frame parents.

So I added a loop to your function KeyHandler_KeyReleased(oEvent), in order to check the layout of every parent frame, but then how do I recover my text cursor to its original location?

Code: Select all

function KeyHandler_KeyReleased(oEvent) as boolean
v= thiscomponent.currentcontroller.viewcursor
if isempty(v) = false then

if isempty(original_frame) =false then
msgbox  "The frame height is : " & v.textframe.LayoutSize.height

v.gotorange(v.textframe.Anchor, False)

Do While (isempty(v) = false) and (isempty(v.textframe) = false)
msgbox "The parent height is : " & v.textframe.LayoutSize.height

v.gotorange(v.textframe.Anchor, False)
Loop
end if
end if
end function
Last edited by Alectrona on Fri Mar 27, 2020 9:55 pm, edited 1 time in total.
LibreOffice 6.2.8.2 on Windows 10
JeJe
Volunteer
Posts: 2780
Joined: Wed Mar 09, 2016 2:40 pm

Re: Setting an event listener when a frame size change?

Post by JeJe »

Use a text cursor instead of the view cursor.

https://wiki.openoffice.org/wiki/Writer/API/Text_cursor
Windows 10, Openoffice 4.1.11, LibreOffice 7.4.0.3 (x64)
Alectrona
Posts: 17
Joined: Tue Mar 24, 2020 7:04 pm

Re: Setting an event listener when a frame size change?

Post by Alectrona »

But with a text cursor, this bugs, telling me the "object variable isnt defined", at the line Do While (isempty(tc) = false) and (isempty(tc.textframe) = false)

Code: Select all

tc = v.text.createTextCursorByRange(v.textframe.Anchor)

Do While (isempty(tc) = false) and (isempty(tc.textframe) = false)
msgbox "The parent height is : " & tc.textframe.LayoutSize.height

tc = v.text.createTextCursorByRange(tc.textframe.Anchor)
Loop
And when I try this :

Code: Select all

tc = v.text.createTextCursorByRange(v)
tc.gotorange(v.textframe.Anchor, False)

Do While (isempty(tc) = false) and (isempty(tc.textframe) = false)
msgbox "The parent height is : " & tc.textframe.LayoutSize.height

tc.gotorange(tc.textframe.Anchor, False)

Loop
I get a runtime error on the line tc.gotorange(v.textframe.Anchor, False), since text cursors cant move outside their current textrange.
A text cursor can only move within the text range of the text object in which it was created. Thus a text cursor that is created for the main document's text range can not move inside a table.
https://wiki.openoffice.org/wiki/Writer/API/Text_cursor
LibreOffice 6.2.8.2 on Windows 10
Alectrona
Posts: 17
Joined: Tue Mar 24, 2020 7:04 pm

Re: Setting an event listener when a frame size change?

Post by Alectrona »

Code: Select all

vanchor = v.textframe.anchor
tc = vanchor.text.createTextCursorByRange(vanchor)

Do While (isempty(tc) = false) and (isempty(tc.textframe) = false)
msgbox "The parent height is : " & tc.textframe.LayoutSize.height
vanchor = vanchor.textframe.anchor
tc = vanchor.text.createTextCursorByRange(vanchor)
Loop
This way it works mb
LibreOffice 6.2.8.2 on Windows 10
Post Reply