How to read Settings for commands

I have been trying to figure out if it is possible to read Menu Names from configuration.
For instance CalcCommands.xcu contains the commands and the labels.

I have not had any success trying to read these values or access the configuration via the API.

<node oor:name="Commands">
	<node oor:name=".uno:InsertObjectStarMath" oor:op="replace">
		<prop oor:name="Label" oor:type="xs:string">
			<value xml:lang="en-US">~Formula Object...</value>
		</prop>
		<prop oor:name="TooltipLabel" oor:type="xs:string">
			<value xml:lang="en-US">Insert Formula Object</value>
		</prop>
		<prop oor:name="Properties" oor:type="xs:int">
			<value>1</value>
		</prop>
	</node>
</node>

The setting I am looking to access are visible in the Expert Configuration.

I tried using com.sun.star.configuration.ConfigurationProvider and com.sun.star.configuration.ConfigurationAccess with no luck.

I tired with com.sun.star.comp.framework.ModuleUIConfigurationManager but I don’t this works as it does not seem to be resoure URL as seen in CalcWindowState.xcu.

I am working on dynamic popup menus for OOO Development Tools and I thougt it would be a nice feature to look up a menu lable from a command.

These are dispatch commands triggered by menues, buttons, shortcuts.

Sub _testDispatch()
url = ".uno:InsertObjectStarMath"
dispatch(url, Array())
End Sub
Sub dispatch(url, args())
frame  = ThisComponent.CurrentController.Frame
dispatcher = createUnoService("com.sun.star.frame.DispatchHelper")
dispatcher.executeDispatch(frame, url,"",0,args())
End Sub

Yes, I understand they are dispatch commands. There are configuration files that allow looking up of disptach command and getting the menu label. CalcWindowState.xcu CalcCommands.xcu is one such configuration file. I am trying to find a way to access it via the API to make building dynamic menus a little more dynamic.

Edit:
Sorry I meant CalcCommands.xcu not CalcWindowState.xcu

Below is a macro that displays information about the uno commands of all LO modules.
The macro is taken from the famous book by A. Pitonyak OOME_4_1.odt and slightly expanded (details in the comments in the functions).
This is what the command information looks like on the sheet sheet.SpreadsheetDocument:

Command Label Name Popup Property Module HotKey Global HotKey
.uno:InsertObjectStarMath ~Formula Object… Formula Object 0 0 Alt+Shift+E
Option Explicit
Option Compatible

Dim arrKeys    ' for enum com.sun.star.awt.Key

'' ----------------------------------------------------
' lang:en
' Displays a description of the .uno: commands of all LO modules.
' Modified version of Print_All_Commands macro from A.Pitonyak's book [OOME_4_0.odt](https://www.pitonyak.org/OOME_4_0.odt).
' Changes:
' - Added display of module and application hotkeys.
' - Sheet names are formed without the com.sun.star prefix.
Sub Print_All_Commands_2
  ' Create a new Calc document to hold the dispatch commands
  Dim oDoc As Object
  Dim oSheets As Object, oSheet As Object, oRange As Object
  Dim oUICommandDescription As Object, oModuleIdentifier As Object, oModuleUICommandDescription As Object
  Dim oGlobalShortCut As Object, oModuleConfigManagerSupplier As Object, ModUICfg As Object, oFilterDesc As Object
  Dim oColumns as Object, oMap As Object
  Dim aModules, aCommand, aCommands() As String, n As Long, i As Long 
  Dim sLabel As String, sName As String, bPopup as Boolean, nProperty As Long, k As Long, j As Long
  Dim arr(), aCmd(), v, arr2, fName As String, locale
  
  oDoc = StarDesktop.loadComponentFromURL("private:factory/scalc", "_default", 0, Array())
  oSheets = oDoc.getSheets()
  oMap=com.sun.star.container.EnumerableMap.create("string", "any")

  'The UICommandDescription service provides access to the user interface commands that are 
  'part of OpenOffice.org modules, like Writer or Calc. 
  oUICommandDescription = CreateUnoService("com.sun.star.frame.UICommandDescription")

  'Identify office modules and provide read access to the configuration of office modules.
  oModuleIdentifier = CreateUnoService("com.sun.star.frame.ModuleManager")
  
  oGlobalShortCut=CreateUnoService("com.sun.star.ui.GlobalAcceleratorConfiguration")
  oModuleConfigManagerSupplier = createUnoService( "com.sun.star.ui.ModuleUIConfigurationManagerSupplier" ) 
    
  ' Get a list of module names such as "com.sun.star.presentation.PresentationDocument"
  ' Create a sheet for each module.
  aModules = oModuleIdentifier.getElementNames()
  For n = 0 To UBound(aModules)
  
    ModUICfg=oModuleConfigManagerSupplier.getUIConfigurationManager(aModules(n))      
    oModuleUICommandDescription = oUICommandDescription.getByName(aModules(n))
    
    ' Get the commands supported by this module.
    ReDim aCommands$()
    aCommands = oModuleUICommandDescription.getElementNames()
	
	fName=Replace(aModules(n), "com.sun.star.", "")
    If n <= UBound(oSheets.getElementNames()) Then
      oSheets.getByIndex(n).setName(fName)
    Else
      oSheets.insertNewByName(fName,n)
    End If
    
    ReDim arr(20000)
    ReDim aCmd(20000)
    Arr(0)=Array("Command", "Label", "Name", "Popup", "Property", "Module HotKey", "Global HotKey")
		
    For i = 0 To UBound(aCommands)
      If aCommands(i)<>"" Then 
        aCommand = oModuleUICommandDescription.getByName(aCommands(i))
        For k = 0 To UBound(aCommand)
          If aCommand(k).Name = "Label" Then
            sLabel = aCommand(k).Value
          ElseIf aCommand(k).Name = "Name" Then
            sName = aCommand(k).Value
          ElseIf aCommand(k).Name = "Popup" Then
            bPopup = aCommand(k).Value
          ElseIf aCommand(k).Name = "Property" Then
            nProperty = aCommand(k).Value
          End If
        Next k
	  
        j=i+1
	    arr(j)=Array(aCommands(i), sLabel, sName, IIf(bPopup, 1, 0), nProperty, "", "")      		
	    aCmd(j-1)=aCommands(i)
	  End If  
    Next i
    
    ReDim Preserve arr(j)
    ReDim Preserve aCmd(j-1)    

    ' Module's ShortKey
    arr2=ModUICfg.ShortCutManager.getPreferredKeyEventsForCommandList(aCmd)
    For i=0 To Ubound(arr2)
      If Not IsEmpty(arr2(i)) Then
        arr(i+1)(5)=GetKeyDesc(arr2(i))
      End If  
    Next i
    
    ' Global ShortKey
    arr2=oGlobalShortCut.getPreferredKeyEventsForCommandList(aCmd)
    For i=0 To Ubound(arr2)
      If Not IsEmpty(arr2(i)) Then
        arr(i+1)(6)=GetKeyDesc(arr2(i))
      End If  
    Next i
    
    oSheet=oSheets(n)
    oRange=oSheet.getCellRangeByPosition(0, 0, Ubound(arr(0)), j)
    oRange.setDataArray arr
   
    ' Title 
    oRange.getCellRangeByPosition(0, 0, oRange.Columns.Count-1, 0).CellStyle="Accent 3"
    
    ' Don't check spelling
    locale=oRange.CharLocale
    locale.Country=""
    locale.Language="zxx"
    oRange.CharLocale=locale
       
    oColumns=oSheet.Columns
    
    ' AutoFilter
    fName="DB_" & n
    oDoc.DatabaseRanges.addNewByName(fName, oRange.RangeAddress)
    oDoc.DatabaseRanges.getByName(fName).autoFilter=True

    ' Column width
	oColumns.getByIndex(0).Width=8000
    For j = 1 To 6
      oColumns.getByIndex(j).OptimalWidth=True
    Next j

  Next n
  
  Msgbox "Number of sheets: " & (UBound(aModules)+1)
End Sub

' ----------------------------------------------------
' Returns a text description of a keyboard shortcut.
Function GetKeyDesc(ByVal keyEvent) As String
  Dim arr, n As Long, v, s As String, m As Long
  If IsEmpty(arrKeys) Then
    arr=Enum_arr("com.sun.star.awt.Key")
    ReDim arrKeys(4096)
    n=len("com.sun.star.awt.Key.") + 1
    For Each v In arr
      arrKeys(v(0))=Mid(v(1), n) 
    Next v  
  End If
 
  With keyEvent
    s=arrKeys(.KeyCode)
    m=.Modifiers
    If m And 1 Then s="Shift+" & s    
    If m And 4 Then s="Alt+" & s    
    If m And 2 Then s="Ctrl+" & s
  End With  
 
  GetKeyDesc=s
End Function

' ----------------------------------------------------
' Returns Enum as an array of arrays (value, name).
' On error, an empty array is returned.
Function Enum_arr(Byval sEnum As String)
  Dim oTD As Object, i as Long, arr, sNames, lValues  
  
  Enum_arr=Array()  
  On Error GoTo ErrLabel
  
  oTD=GetDefaultContext.getValueByName("/singletons/com.sun.star.reflection.theTypeDescriptionManager").getByHierarchicalName(sEnum) 
  
  If HasUnoInterfaces(oTD, "com.sun.star.reflection.XEnumTypeDescription") Then
    sNames = oTD.getEnumNames()
    lValues = otd.getEnumValues()
    ReDim arr(UBound(sNames))
    For i = LBound(sNames) To UBound(sNames)
      Arr(i)=Array(lValues(i), sNames(i))    
    Next i

  ElseIf HasUnoInterfaces(oTD, "com.sun.star.reflection.XConstantsTypeDescription") Then
    lValues = oTD.getConstants()
    ReDim arr(UBound(lvalues))
    For i = LBound(lValues) To UBound(lValues)
      Arr(i)=Array(lValues(i).getConstantValue, lValues(i).getName)
    Next i
  End If  
  
  If IsArray(arr) Then Enum_arr=arr
ErrLabel:  
End Function

UnoCommands.ods (11.9 KB)

1 Like

This looks very promising. I can see the label names are included in the output. To bad Windows does not directly support sqlite, this would be a good use of an in memory database to look up values while processing menus.

Hmm… I suspect was looking for the com.sun.star.frame.UICommandDescription service.

The old HSQL driver shipped with LibreOffice supports in memory tables.
The new Firebird driver too.

Took a minute but I created a Lookup Class in OooDev.
See Getting Info UNO on Commands
This lookup includes all the information that was given in the spreadsheets.

Thank you @sokol92