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]