[Solved] Check the state of a toolbar and then execute code

Creating a macro - Writing a Script - Using the API (OpenOffice Basic, Python, BeanShell, JavaScript)
Post Reply
User avatar
Tommy
Posts: 251
Joined: Sun Dec 23, 2007 2:44 pm

[Solved] Check the state of a toolbar and then execute code

Post by Tommy »

I wanna execute some code inside a macro only if a specific custom toolbar called "test" is in "show" state.
otherwise if that toolbar is in "hidden" state no code should be executed

let's say something like:

if "private:resource/toolbar/custom_toolbar_test" is in show state then
print "toolbar open"
else
print "toolbar closed"
end if

so I don't need to change the "show/hide" state of that toolbar but just check if it's open or not and the execute code it it's open

would you please help me with this?
thanks
Last edited by Tommy on Thu Jan 21, 2016 8:15 am, edited 1 time in total.
-----
using latest X-LibreOffice release, made portable by winPenPack.com
http://www.winpenpack.com/main/download.php?view.1354
UnklDonald418
Volunteer
Posts: 1566
Joined: Wed Jun 24, 2015 12:56 am
Location: Colorado, USA

Re: Check the state of a specific toolbar and then execute c

Post by UnklDonald418 »

This might get you going in the right direction. I left one MRI call enabled because you will probably need to use MRI to get a working version. You should definitely set a breakpoint at the line

Code: Select all

 if oChildCtx.getAccessibleName() = "Test" then   
so you can use the debugger along with MRI to monitor what is happening.

The way the macro is set up it will display “Toolbar Closed” if the menu isn't visible or it doesn't find it.

Code: Select all

REM  *****  BASIC  *****
Sub TestMenuStatus

Dim oAccCtx as object

oAccCtx = ThisComponent.getCurrentController().getFrame().getComponentWindow().getAccessibleContext().getAccessibleParent().getAccessibleContext()

if MenuStatus(oAccCtx) then
 Print "toolbar open"
else
 Print "toolbar closed"
end if

End Sub   'TestMenuStatus

Function MenuStatus(oAccCtx as object) as Boolean

Dim tname as String, fname as String, cname(0,0) as String, xname as String
Dim i as Integer, n as Integer, x as Integer

 Globalscope.BasicLibraries.LoadLibrary( "MRILib" )
 oMRI = CreateUnoService( "mytools.Mri" )
 
MenuStatus = FALSE
n = oAccCtx.AccessibleChildCount           
'    oMri.inspect(oAccCtx)
For i = 0 to n-1       
    oChild = oAccCtx.getAccessibleChild(i)
    oChildCtx = oChild.getAccessibleContext()
    If oChildCtx.AccessibleChildCount > 0 then
'          oMri.inspect(oChildCtx)
      if MenuStatus(oChildCtx) then
         MenuStatus = TRUE
         Exit For
      end if
    end if
    if oChildCtx.getAccessibleRole() = com.sun.star.accessibility.AccessibleRole.MENU then ' role = 34
    ' or maybe com.sun.star.accessibility.AccessibleRole.MENU_BAR    ' role = 35
      oMri.inspect(oChildCtx)
      if oChildCtx.getAccessibleName() = "test" then
        if  oChildCtx.AccessibleStateSet.contains(com.sun.star.accessibility.AccessibleStateType.VISIBLE) then
           MenuStatus = TRUE
           Exit For 
        end if      
      end if
     end if
next i

End Function   'MenuStatus
the macro function MenuStatus() is recursive. So as you work your way through you you should close each MRI window after you have examined it so you don't end up with a pile of MRI windows.
It will find a bunch of menus.

Good Luck!
If your problem has been solved, please edit this topic's initial post and add "[Solved]" to the beginning of the subject line
Apache OpenOffice 4.1.14 & LibreOffice 7.6.2.1 (x86_64) - Windows 10 Professional- Windows 11
User avatar
Tommy
Posts: 251
Joined: Sun Dec 23, 2007 2:44 pm

Re: Check the state of a specific toolbar and then execute c

Post by Tommy »

thanks 4 your reply.

is the MRI scrictly necessary to operate the macro?

I tried to install MRI on my LibO 5.0.4.2 but installation aborted

so I have to do that without MRI
-----
using latest X-LibreOffice release, made portable by winPenPack.com
http://www.winpenpack.com/main/download.php?view.1354
User avatar
RoryOF
Moderator
Posts: 35064
Joined: Sat Jan 31, 2009 9:30 pm
Location: Ireland

Re: Check the state of a specific toolbar and then execute c

Post by RoryOF »

The MRI is merely for helpful debugging information until you have the code running as expected.
Apache OpenOffice 4.1.15 on Xubuntu 22.04.5 LTS
User avatar
Tommy
Posts: 251
Joined: Sun Dec 23, 2007 2:44 pm

Re: Check the state of a specific toolbar and then execute c

Post by Tommy »

I see it cited many times inside that macro.
I suppose I have to remove those lines to make it work if I don't have MRI installed
-----
using latest X-LibreOffice release, made portable by winPenPack.com
http://www.winpenpack.com/main/download.php?view.1354
User avatar
RoryOF
Moderator
Posts: 35064
Joined: Sat Jan 31, 2009 9:30 pm
Location: Ireland

Re: Check the state of a specific toolbar and then execute c

Post by RoryOF »

I'd simple comment out the lines, perhaps with a conditional "If debugflag then MRIlines endif" (You need to insert this carefully surrounding the MRIlines).

Then if you need to debug, you only have to reverse the state of debugflag
Apache OpenOffice 4.1.15 on Xubuntu 22.04.5 LTS
UnklDonald418
Volunteer
Posts: 1566
Joined: Wed Jun 24, 2015 12:56 am
Location: Colorado, USA

Re: Check the state of a specific toolbar and then execute c

Post by UnklDonald418 »

Yes, as RoryOF said
The MRI is merely for helpful debugging information
I would probably change "merely for" in his statement to "extremely". But you can comment out or delete the lines referencing MRI, which you would do anyway once everything is working.

You could then try the macro without breakpoints, it might work without modification.

Otherwise, in the debugger you should set your cursor on one instance of “oChildCtx” and “Enable Watch” (F7) also be sure to set the breakpoint I recommended in my original post. If you expand the “oChildCtx” reference in the Watch Window you can watch the values of AccessibleName as you step through the elements. Hopefully you will eventually see your “test” menu name.
It will take some patience because there will be dozens of menus in your document.

The Developers Guide likens it to inspecting each leaf on a tree, or in some instances a forest!
Last edited by UnklDonald418 on Wed Jan 20, 2016 1:21 am, edited 1 time in total.
If your problem has been solved, please edit this topic's initial post and add "[Solved]" to the beginning of the subject line
Apache OpenOffice 4.1.14 & LibreOffice 7.6.2.1 (x86_64) - Windows 10 Professional- Windows 11
UnklDonald418
Volunteer
Posts: 1566
Joined: Wed Jun 24, 2015 12:56 am
Location: Colorado, USA

Re: Check the state of a specific toolbar and then execute c

Post by UnklDonald418 »

I had a little time to play with this and discovered that I used the wrong flag for AccsssibleRole

When I changed the line

Code: Select all

    if oChildCtx.getAccessibleRole() =  com.sun.star.accessibility.AccessibleRole.MENU then
to

Code: Select all

    if oChildCtx.getAccessibleRole() =  com.sun.star.accessibility.AccessibleRole.TOOL_BAR then
it worked. It turns out we are only looking for branches rather than leaves so there are a lot fewer of them.
Here is a version that is a little more reusable and has all the debugging stuff removed. I have tested it on a Writer document and a Base form.

Code: Select all

REM  *****  BASIC  *****
Sub TestMenuStatus

Dim oAccCtx as object

oAccCtx = ThisComponent.getCurrentController().getFrame().getComponentWindow().getAccessibleContext().getAccessibleParent().getAccessibleContext()

if MenuStatus(oAccCtx, "test") then
 Print "toolbar open"
else
 Print "toolbar closed"
end if

End Sub   'TestMenuStatus
REM ==========================================================================
Function MenuStatus(oAccCtx as object, bname as string) as Boolean

Dim i as Integer, n as Integer, x as Integer

MenuStatus = FALSE
n = oAccCtx.AccessibleChildCount           
For i = 0 to n-1       
    oChild = oAccCtx.getAccessibleChild(i)
    oChildCtx = oChild.getAccessibleContext()
    If oChildCtx.AccessibleChildCount > 0 then
      if MenuStatus(oChildCtx,bname) then
         MenuStatus = TRUE
         Exit For
      end if
    end if
    if oChildCtx.getAccessibleRole() =  com.sun.star.accessibility.AccessibleRole.TOOL_BAR then ' role = 34  CHECK_MENU_ITEM = 5
      if oChildCtx.getAccessibleName() = bname then
        if  oChildCtx.AccessibleStateSet.contains(com.sun.star.accessibility.AccessibleStateType.VISIBLE) then
           MenuStatus = TRUE
           Exit For 
        end if      
      end if
     end if
next i

End Function   'MenuStatus
If your problem has been solved, please edit this topic's initial post and add "[Solved]" to the beginning of the subject line
Apache OpenOffice 4.1.14 & LibreOffice 7.6.2.1 (x86_64) - Windows 10 Professional- Windows 11
User avatar
Tommy
Posts: 251
Joined: Sun Dec 23, 2007 2:44 pm

Re: Check the state of a specific toolbar and then execute c

Post by Tommy »

hi there. thanks for giving it another try.
in my setup there's an issue though...
the macro always show "toolbar closed" message even if the "test" toolbar is open

I think that this code line has an error:
if MenuStatus(oAccCtx, "test") then

probably we are not giving the exact name of the toolbar...

I have another macro that simply shows the toolbar if it's in hidden state with this code:
ThisComponent.CurrentController.Frame.LayoutManager.showElement("private:resource/toolbar/custom_toolbar_test")

I tried several combinations in your macro like:

if MenuStatus(oAccCtx, "private:resource/toolbar/custom_toolbar_test") then

or

if MenuStatus(oAccCtx, "/toolbar/custom_toolbar_test") then

etc. etc.

but I never get the "toolbar open" message

what I'm doing wrong?
-----
using latest X-LibreOffice release, made portable by winPenPack.com
http://www.winpenpack.com/main/download.php?view.1354
UnklDonald418
Volunteer
Posts: 1566
Joined: Wed Jun 24, 2015 12:56 am
Location: Colorado, USA

Re: Check the state of a specific toolbar and then execute c

Post by UnklDonald418 »

I tried your line of code

Code: Select all

ThisComponent.CurrentController.Frame.LayoutManager.showElement("private:resource/toolbar/custom_toolbar_test")
and yes it always returns False. When I examined the Elements I discovered that apparently "showElement" doesn't use the toolbar name "test" you entered for your custom toolbar.
Based on what I saw here is a new macro to try

Code: Select all

REM  *****  BASIC  *****

Sub TestToolBarStatus

Dim oAccCtx as object


if ToolBarStatus(ThisComponent.CurrentController.Frame.LayoutManager) then 
 Print "toolbar open"
else
 Print "toolbar closed"
end if

End Sub   'TestMenuStatus

REM ====================================================================================
Function ToolBarStatus(oLayout as object) as boolean

Dim oElements() as object
Dim turl as string

turl = GetToolBarURL(oLayout)
ToolBarStatus = oLayout.isElementVisible(turl) 

end Function 'ToolBarStatus
REM ================================================================
Function GetToolBarURL(oLayout as object) as string
Dim oElements() as object

GetToolBarURL = ""
oElements = oLayout.getElements()
n = Ubound(oElements)
for i = 0 to n-1
 if instr(oElements(i).ResourceURL,"custom_toolbar")  then 
   print  oElements(i).ResourceURL
   GetToolBarURL =  oElements(i).ResourceURL
 end if
next i
end function 'GetToolBarURL
So far this passed all my tests. It will display the actual string (URL) you need to pass to "showElement" in your code. It turns out that "showElement" isn't what you need. That is used with "hideElement" to turn the toolbar on and off. What I used is "isElementVisible" in this macro.

You could use the macro above if you comment out the line

Code: Select all

 print  oElements(i).ResourceURL  
but if there are multiple custom_toolbars you may need to get the URL for the target toolbar anyway.
In that case you could edit the line

Code: Select all

turl = GetToolBarURL(oLayout)
and enter your toolbar URL something like

Code: Select all

turl = "private:resource/toolbar/custom_toolbar_6f9b"
or probably just use something like

Code: Select all

ThisComponent.CurrentController.Frame.LayoutManager.isElementVisible( "private:resource/toolbar/custom_toolbar_6f9b")

By the way, different documents return different URL's regardless of the name you give the toolbar.
If your problem has been solved, please edit this topic's initial post and add "[Solved]" to the beginning of the subject line
Apache OpenOffice 4.1.14 & LibreOffice 7.6.2.1 (x86_64) - Windows 10 Professional- Windows 11
User avatar
Tommy
Posts: 251
Joined: Sun Dec 23, 2007 2:44 pm

Re: [solved] Check the state of a toolbar and then execute c

Post by Tommy »

thank you very much
this one works fine.
thanks for all your help.
-----
using latest X-LibreOffice release, made portable by winPenPack.com
http://www.winpenpack.com/main/download.php?view.1354
Post Reply