Page 1 of 1

[Solved] Fail to remove layer on Draw page using BASIC API

Posted: Thu Jan 17, 2019 10:09 am
by irs
I am unable to remove a layer using BASIC to perform a LayerManager.remove() API call. Testing performed on AOO V4.1.6.

As background information: A new Draw page will have 5 Layers with the index from 0 to 4...

Code: Select all

oDoc = ThisComponent
oLM = oDoc.getLayerManager()
msgbox "Layer Count: " + str(oLM.Count) '<--- Layer Count: 5

'msgbox oLM.DBG_Properties
'msgbox oLM.DBG_Methods

aElementNames = oLM.getElementNames()
s = ""
For i = LBound(aElementNames) to UBound(aElementNames)
	s = s + str(i) + ": " + aElementNames(i) + chr(10)
Next i
msgbox s
' Msgbox displays...
' 0: layout
' 1: background
' 2: backgroundobjects
' 3: controls
' 4: measurelines

A Draw page displays three of these layers which are labelled as: Layout, Controls, and Dimension Lines.

The LayerManager allows inserting additional layers, as follows...

Code: Select all

oDoc = ThisComponent
oLM = oDoc.getLayerManager()
msgbox "Layer Count: " + str(oLM.Count) '<--- Layer Count: 5
oNewLayer = oLM.insertNewByIndex(oLM.Count)
oNewLayer.Name = "Layer" + str(oLM.Count - 1)
msgbox "Layer Count: " + str(oLM.Count) '<--- Layer Count: 6
The Draw page now displays the added layer tab as Layer 5. I use the following code to attempt to delete this newly added layer...

Code: Select all

oDoc = ThisComponent
oLM = oDoc.getLayerManager()
msgbox "Layer Count: " + str(oLM.Count) '<--- Layer Count: 6
oLatestLayer = oLM.getByIndex(oLM.Count - 1)
oLM.remove(oLatestLayer)
msgbox "Layer Count: " + str(oLM.Count) '<--- Layer Count: 6 <--- huh?
My understanding from the reference manual ( https://www.openoffice.org/api/docs/com ... nager.html ) is that oLM.remove(oLatestLayer) should have deleted the Layer 5. The oLM.DBG_Methods describes SbxVOID remove (SbxOBJECT). The code executes without error, but the layer still remains.

What I'm wondering is if oLM.remove(oLatestLayer) is this the correct code? If not, can someone supply the code that will perform the removal a layer?

Note that using a mouse I can right-click on the newly created Layer 5 tab, and from the drop down menu Delete Layer... will function OK and remove the layer. However I wish to do this under program control.

Thanks and regards, Ian.

PS: On checking the remove_layer_demo.odg file it already had two layers that I had created. I have replaced the file so it is representative of a new Draw document with only the default layers present.
remove_layer_demo.odg
Draw doc with BASIC code to demo failure
(10.53 KiB) Downloaded 244 times

Re: Fail to remove layer on Draw page using BASIC API call.

Posted: Thu Jan 17, 2019 11:06 am
by Villeroy
Works for me with LibreOffice 6 and OpenOffice 4.1.6 on Ubuntu

Re: Fail to remove layer on Draw page using BASIC API call.

Posted: Thu Jan 17, 2019 12:03 pm
by Lupp
Strange 1 (concerning the forum): I downloaded the demo attached to the question, and obviously Villeroy also did, but there is still shown "Not downloaded yet". Did the questioner delete and replace the original attachment later? Yes. He did.

Strange 2 (concerning the question and Villeroy's answer): The attempt to remove an added layer failed with LibO V 6.1.4. (under Win 10)
In fact I could inspect the layer object, but not assign a new values to its simple Boolean property .IsVisible. It showed False for the watched variable originally and remaied False even if an asignment .IsVisible = True was made and did not throw an error. An assignment to the string property .Name is working, however.

Strange 3: If I force refreshing of the watch for the layer object, the .IsVisible = False holds. If I use the same layer's context menu item 'Modify' subsequently it shows Visible = True (enabled).

All the observations are unchanged with LibO V 6.2.0.0.beta1. with its independent user profile.

Strange 4: I would thus suppose we have a "legacy bug" - but this suspicion is incompatible with Villeroy's statement. (I cannot imagine an influence of the OS insofar.)

By the way: oLayerObject.dipose also does not throw an error, but has no effect.

Re: Fail to remove layer on Draw page using BASIC API call.

Posted: Thu Jan 17, 2019 12:26 pm
by Villeroy
It still works for me when I simply run the macro via Ctrl+F11 Alt+F11, select and [Run]. It fails in the described manner when I run it from Basic IDE.

Re: Fail to remove layer on Draw page using BASIC API call.

Posted: Thu Jan 17, 2019 1:36 pm
by Lupp
OK. That's "Strange 5", I suppose.
It's a mess, I'm sure.

Re: Fail to remove layer on Draw page using BASIC API call.

Posted: Fri Jan 18, 2019 1:43 am
by irs
Hi Villeroy and Lupp,

Many thanks for taking the time to analyse this problem and write your response posts.

My summary is: The LayerManager.remove(oLayer) will delete the oLayer OK in the BASIC run-time environment, but will not delete the oLayer or throw any error, when running BASIC from the development environment.

I'm not sure if this is a feature or a bug, however for all I know it may be a feature of many other API calls I have not used up to now. It would be nice if the reference manual provided an indication that the call only works in the run-time environment, or when the call fails in the developer environment there was a message to warn you.

Villeroy states he runs the macro via Ctrl+F11. My PC seems to ignore Ctrl+F11. However I am able to get the program to run and remove the layer OK using the following method. On the menu bar, click on Tools --> Macros --> Run Macro --> which opens the Macro Selector dialog. Click on remove_layer_demo.odg --> Standard --> Module1 --> Main. Now click on "Run".

Attached below is the Draw file remove_layer_demo_v2.odg

This file is much the same as my previous file, except I've added a command button to the Draw page and given it the execute action of running the BASIC macro Main. On clicking the button it will insert and remove the layer OK.

I've also added a second command button labelled Layer Demo. It runs the macro circle_layers. For many layers, it will generate a layer and place a circle on it. I then use a loop to toggle the IsVisible feature of each layer. This then provides simple animation of the circles. Upon completion a loop runs LayerManager.remove(), and all the additional layers that I created are deleted.

Once again, thanks for your assistance, and I will move this to Solved.
cheers, Ian.

Re: [Solved] Fail to remove layer on Draw page using BASIC A

Posted: Fri Jan 18, 2019 8:16 am
by Zizi64
Villeroy states he runs the macro via Ctrl+F11. My PC seems to ignore Ctrl+F11.
It not work for me on HUN Win7x64 and LO 6.1.4. The shortcut associations somtimes depend on the locale settings of the Op.Sys or the LO.


My summary is: The LayerManager.remove(oLayer) will delete the oLayer OK in the BASIC run-time environment, but will not delete the oLayer or throw any error, when running BASIC from the development environment.
The resunlt of Thisbomponent depends on the circumstance, where the macro was launched.
Check the Thiscomponent with an object inspection tool like the Xray or the MRI. You can use the Xray in your code

Code: Select all

oDoc = Thiscomponent
Xray oDoc

Re: [Solved] Fail to remove layer on Draw page using BASIC A

Posted: Fri Jan 18, 2019 5:01 pm
by Villeroy
Sorry, Ctrl+F11 Alt+F11 or menu:Tools>Macros>Organize>Basic... or Tools>Macros>Run... or any other method to run a macro from the view of a document, a button, a hyperlink, a user-defined shortcut, menu entry or toolbar button or from an event.

Re: [Solved] Fail to remove layer on Draw page using BASIC A

Posted: Sat Jan 19, 2019 1:35 am
by Zizi64
Yes, the ALT-F11 works in my LO and AOO too

Re: [Solved] Fail to remove layer on Draw page using BASIC A

Posted: Sat Jan 19, 2019 10:03 pm
by irs
Villeroy: Thanks. The Alt+F11 is a handy to know.

Zizi: According to https://wiki.openoffice.org/wiki/Curren ... e_document it seems that using ThisComponent is generally preferred. I tired using StarDesktop.CurrentComponent, but without success. I think the work-around is to avoid running code using the run icon in the development environment. Placing a button on the Draw page to run the macro is suitable to quickly test code that you are developing.

For anyone interested in experimenting with adding Layers. The following is a summary from my experiments so far...

It appears that you can add layers into the thousands, however the usable upper limit seems to be the layer with an index of 254. If layer 255 is created it seems to function in parallel with layer 0 which is labelled "Layout". If you create, say, 500 Layers and commence inserting a shape into each layer, then once you go above layer 255, all additional shapes that you create do not go into their respective layers, but go into layer 255. If you manually toggle the Visible checkbox for layer 255 then all shapes for layer 255 through to layer 500 are displayed or hidden. Also if you toggle the Visible for layer 0, then all shapes for layers 255 to 500 are displayed and hidden.

I assume the above, of using layers above 254, is above the upper limit specification and therefore produces unpredictable results.

My conclusions for adding Layers are: Avoid layers 0 to 4 as they are reserved. Start at the layer with an index of 5. Add up to 250 layers. The 250th layer added will have an index of 254. Shapes can be added OK to these layers from 5 to 254. Under program control you can toggle the IsVisibile = True / False and determine which layers from 5 to 254 are to be displayed / hidden.

I have attached two Draw.odg documents. the file circles 500 - show limitation.odg creates 500 layers and in theory each layer contains a circle. However you can toggle layer 255 and find that 250 circle shapes have been placed into this layer. Other unpredictable events also occur.

The second Draw document circles 250.odg is limited to an additional 250 layers, which have an index in the range from 5 to 254. Manipulation of these layers appears to function as expected.

After opening either of these Draw documents, commence by clicking on "Create Circles" button.
cheers, Ian.

Re: [Solved] Fail to remove layer on Draw page using BASIC A

Posted: Mon Jan 21, 2019 8:46 pm
by Villeroy
Why all those layers? I never use them because I have no idea how. When I remove one of your circles from any layer, the circle disappears from all layers.

Re: [Solved] Fail to remove layer on Draw page using BASIC A

Posted: Thu Jan 24, 2019 11:38 pm
by irs
Villeroy:

> Why all those layers?

I recently delivered a presentation on simple animation. I am sure you will be familiar with a flip book, (https://en.wikipedia.org/wiki/Flip_book). Flip book's are a mechanical way of generating simple animation. Using the layers with a Draw document I attempt to make an electronic equivalent of a flip book.

I've attached a Draw document with 200 layers. When you run the embedded BASIC code, then the circles appear to move in a spiral outwards as the program flicks through the visibility of each layer.

I also made a Draw document in which, when I flick through the layers, a wheel appears to rotate. I can play also around with which layers I display and I am able to generate a similar effect that you observe when watching a western movie and observe on a horse drawn cart the cartwheels appearing to stop or rotate backwards.

From my presentation to our local Linux Users Group, I have posted in their github repository a description of this animation technique using Draw and seven demonstration Draw files. It provides a better explanation of my experimenting with layers. Please follow this link... https://github.com/WLUG/meetings/tree/m ... animations

cheers, Ian.

Note: The files I attached to my previous posts above, circles 250.odg and circles 500 - show limitation.odg, do not demonstrate animation. I posted them to highlight a design limitation of the Layer Manager. The file attached below demo 5 - 200 circles spiral.odg performs animation. Alternatively, go to the github link above and the files demo3 to demo7 are available to demonstrate performing of animation.