Julien Galand wrote:

Le 13 oct. 06, à 16:54, Carsten Driesner a écrit :

Although this is a possible way to implement your add-on it looks a bit strange and has a drawback you should consider. If the user choose to uninstall your add-on all the changes you did programmatically in the configuration won't be removed. The user would see a non-working top-level menu! Therefore I cannot recommend to use this way.


I agree; in the case of my add-on, I strongly needed to avoid manual registration of a package. As a "solution" to this drawback, I have chosen to remove the inserted menu (modifying the configuration again) when OO quits (on OnCloseApp event).
Hi Julien,

Although your solution may work in most cases, a crash would leave persistent changes. You should consider to use transient changes on the user interface. The Basic code at the end of this message uses the transient user interface feature to change the menu bar for a frame. No other frame can see the changes and even a crash won't change any file.



You can use the layout manager from the frame to destroy and create the menu bar again. The current implementation doesn't listen to changes in the Addon.xcu file. The following Basic code snippet "refreshes" the menu bar.

REM  *****  BASIC  *****
Sub Main
    REM *** Initialize strings
    sMenubar = "private:resource/menubar/menubar"

    REM *** Retrieve the desktop service
    oDesktop = createUnoService("com.sun.star.frame.Desktop")

    REM *** Retrieve the current frame and layout manager
    oCurrFrame = oDesktop.getCurrentFrame()
    oLayoutManager = oCurrFrame.LayoutManager

    REM *** Destroy and create menu bar to refresh content
    oLayoutManager.destroyElement( sMenubar )
    oLayoutManager.createElement( sMenubar )
End Sub

Regards,
Carsten


I have tried your suggestion. It doesn't seem to work, though all calls seem to be successful.

I checked my code and it works without any problem. OpenOffice.org internally uses the same mechanism, if you customize the menubar with Tools-Customize. Please check if you use the correct frame to destroy/create the menubar.


I have only one (writer) document opened.
My code is parallel to yours, in C++ :

__________________________________________________________________________________
Reference<XFrame> curFrame = m_appDesktop->getCurrentFrame();
Reference<XLayoutManager> layoutMgr(GetObjectProperty(curFrame, "LayoutManager"), UNO_QUERY);

OUString element = OUString::createFromAscii("private:resource/menubar/menubar");
layoutMgr->destroyElement(element);
layoutMgr->createElement(element);
__________________________________________________________________________________

What may happen ?
The menu bar disappears for a short moment. As the menu bar is newly created it reads the new Addons.xcu content and you should see your changes.

Regards,
Carsten

---------------------------------------------------------
Sample code to make transient changes on a frame menu bar

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

Sub Main
  REM *** Adds a item to the File Menu only transient. Means
  REM *** that this menu item only exists for and during the
  REM *** lifetime of the current frame.

  REM *** Initialize strings
  sMenuBar = "private:resource/menubar/menubar"
  sMyPopupMenuCmdId = ".uno:PickList"
  sMyCommand = "macro:///Standard.Module1.Test()"

  REM *** Retrieve the current frame of my model
  oModel = ThisComponent

  if not isNull( oModel ) then
    REM *** Retrieve frame from current controller
    oFrame = oModel.getCurrentController().getFrame()

    REM *** Retrieve the layout manager of my current frame
    oLayoutManager = oFrame.LayoutManager()

    REM *** Retrieve the menu bar from the layout manager
    oMenuBar = oLayoutManager.getElement( sMenuBar )

    REM *** Retrieve writable configuration settings from menu bar
    oMenuBarSettings = oMenuBar.getSettings( true )

    REM *** Make our changes only transient. An Add-on should
    REM *** never change configuration persistently as it can
    REM *** be deinstalled by a user without any chance to
    REM *** undo its configuration changes!
    REM *** Please look for bug #i46194 which prevents using
    REM *** oMenuBar.Persistent = false!!
    oMenuBar.Persistent = false

    REM *** Look for the "File" popup menu and add our command
    REM *** We must look if we haven't added our command already!
    fileMenuIndex = FindPopupMenu( sMyPopupMenuCmdId, oMenuBarSettings )
    if fileMenuIndex >= 0 then
      oPopupMenuItem() = oMenuBarSettings.getByIndex(fileMenuIndex)
oPopupMenu = GetProperty( "ItemDescriptorContainer", oPopupMenuItem() )
      if not isNull( oPopupMenu ) then
        if FindCommand( sMyCommand, oPopupMenu ) = -1 then
          oMenuItem = CreateMenuItem( sMyCommand, "Standard.Module1.Test" )
          nCount = oPopupMenu.getCount()
          oPopupMenu.insertByIndex( nCount, oMenuItem )
        endif
      endif
    else
      msgbox "No file menu found!"
    endif

    oMenuBar.setSettings( oMenuBarSettings )
  endif
End Sub

Function FindCommand( Command as String, oPopupMenu as Object ) as Integer
  nCount = oPopupMenu.getCount()-1
  for i = 0 to nCount
    oMenuItem() = oPopupMenu.getByIndex(i)
        nPropertyCount = ubound(oMenuItem())
        for j = 0 to nPropertyCount
          if oMenuItem(j).Name = "CommandURL" then
        if oMenuItem(j).Value = Command then
           FindCommand = j
          exit function
                endif
          endif
        next j
  next i
        
  FindCommand = -1
End Function

Function FindPopupMenu( Command as String, oMenuBarSettings as Object ) as Integer
  for i = 0 to oMenuBarSettings.getCount()-1
    oPopupMenu() = oMenuBarSettings.getByIndex(i)
        nPopupMenuCount = ubound(oPopupMenu())
        for j = 0 to nPopupMenuCount
          if oPopupMenu(j).Name = "CommandURL" then
        if oPopupMenu(j).Value = Command then
           FindPopupMenu = j
           exit function
                endif
          endif
        next j
  next i
        
  FindPopupMenu = -1
End Function

Function GetProperty( PropertyName as String, properties() as Variant ) as Variant
  for j = lbound( properties() ) to ubound( properties() )
    oPropertyValue = properties(j)
    if oPropertyValue.Name = PropertyName then
          GetProperty = oPropertyValue.Value
      exit function
        endif
  next j

  GetProperty = null
end function
        
Function CreateMenuItem( Command as String, Label as String ) as Variant
  Dim aMenuItem(2) as new com.sun.star.beans.PropertyValue

  aMenuItem(0).Name = "CommandURL"
  aMenuItem(0).Value = Command
  aMenuItem(1).Name = "Label"
  aMenuItem(1).Value = Label
  aMenuItem(2).Name = "Type"
  aMenuItem(2).Value = 0

  CreateMenuItem = aMenuItem()
End Function

Sub Test
 MsgBox "Test"
End Sub

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to