[dev] Dynamic menus: with Java (Problem)
Hi. I have a problem when trying to add custom menus to the OO 2.0 with Java. I've translated the Basic-based example from http://www.oooforum.org/forum/viewtopic.phtml?t=18491&highlight= into Java. It works only to some extent. The place with the problem is marked with the "PROBLEM" keyword in the code. Short: a custom submenu is not shown, something like the separator is shown insteed. The submenu is show under certain condition, this is mentioned in the code. Thank you in advance, Andrej. Code: package de.muenchen.allg.itd51.wollmux.oooui; import com.sun.star.beans.PropertyValue; import com.sun.star.beans.XPropertySet; import com.sun.star.container.XIndexAccess; import com.sun.star.container.XIndexContainer; import com.sun.star.frame.XComponentLoader; import com.sun.star.frame.XController; import com.sun.star.frame.XDesktop; import com.sun.star.frame.XFrame; import com.sun.star.frame.XLayoutManager; import com.sun.star.frame.XModel; import com.sun.star.lang.IllegalArgumentException; import com.sun.star.lang.IndexOutOfBoundsException; import com.sun.star.lang.WrappedTargetException; import com.sun.star.lang.XComponent; import com.sun.star.lang.XMultiComponentFactory; import com.sun.star.ui.XModuleUIConfigurationManagerSupplier; import com.sun.star.ui.XUIConfigurationManager; import com.sun.star.ui.XUIElement; import com.sun.star.ui.XUIElementSettings; import com.sun.star.uno.UnoRuntime; import com.sun.star.uno.XComponentContext; import de.muenchen.allg.afid.UnoService; /* * TestMisc2.java * * Created on 11. April 2002, 08:47 */ /** * * @author Martin Gallwey, Dietrich Schulten */ public class TestMisc2 { // adjust these constant to your local printer! private XComponentContext mxRemoteContext = null; private XMultiComponentFactory mxRemoteServiceManager = null; private XDesktop xDesktop; private XModel xModel; private XController xController; private XFrame xFrame; private XLayoutManager xLayoutManager; private XUIConfigurationManager uiConfigManager; private XModuleUIConfigurationManagerSupplier xCmSupplier; // 0. misc String sMenuBar = "private:resource/menubar/menubar"; String sMyPopupMenuCmdId = "TestMenu"; private XIndexAccess settings; /** Creates a new instance of TestMisc2 */ public TestMisc2() { } /** * @param args *the command line arguments */ public static void main(String[] args) { TestMisc2 textDocuments1 = new TestMisc2(); try { textDocuments1.runDemo(); } catch (java.lang.Exception e) { System.out.println(e.getMessage()); e.printStackTrace(); } finally { System.exit(0); } } protected void runDemo() throws java.lang.Exception { // storePrintExample(); // depends on printername // templateExample(); menuExampe(); // makes changes to the current document, // use with care // editingExample(); } protected void menuExampe() throws Exception { // 1. standart steps, init variables like XDesktop etc. mxRemoteServiceManager = this.getRemoteServiceManager(); xDesktop = (XDesktop) UnoRuntime.queryInterface(XDesktop.class, mxRemoteServiceManager.createInstanceWithContext( "com.sun.star.frame.Desktop", mxRemoteContext)); xModel = (XModel) UnoRuntime.queryInterface(XModel.class, xDesktop.getCurrentComponent()); xController = xModel.getCurrentController(); xFrame = xController.getFrame(); XPropertySet xps = (XPropertySet) UnoRuntime.queryInterface( XPropertySet.class, xFrame); xLayoutManager = (XLayoutManager) UnoRuntime.queryInterface( XLayoutManager.class, xps.getPropertyValue("LayoutManager")); xCmSupplier = (XModuleUIConfigurationManagerSupplier) UnoRuntime. queryInterface(XModuleUIConfigurationManagerSupplier.class, mxRemoteServiceManager.createInstanceWithContext("com.sun.star.ui.ModuleUIConfigurationManagerSupplier",mxRemoteContext)); uiConfigManager = xCmSupplier.getUIConfigurationManager("com.sun.star.text.TextDocument"); settings = uiConfigManager.getSettings(sMenuBar, true); // 2. init menu elements XUIElement oMenuBar = xLayoutManager.getElement(sMenuBar); XPropertySet props = (XPropertySet) UnoRuntime.queryInterface( XPropertySet.class, oMenuBar); props.setPropertyValue("Persistent", new Boolean(true)); XUIElementSettings xoMenuBarSettings = (XUIElementSettings) UnoRuntime .queryInterface(XUIElementSettings.class, oMenuBar); XIndexContainer oMenuBarSettings = (XIndexContainer) UnoRuntime .queryInterface(XIndexContainer.class, xoMenuBarSettings .getSettings(true)); // 3. make "Test-Menu" top-
Re: [dev] Dynamic menus: with Java (Problem)
Andrej Golovko wrote: Hi. I have a problem when trying to add custom menus to the OO 2.0 with Java. I've translated the Basic-based example from http://www.oooforum.org/forum/viewtopic.phtml?t=18491&highlight= into Java. It works only to some extent. The place with the problem is marked with the "PROBLEM" keyword in the code. Short: a custom submenu is not shown, something like the separator is shown insteed. The submenu is show under certain condition, this is mentioned in the code. Hi Andrej, I looked over your example and I am not sure what you want to do. Can you please explain what do you want to achieve? Create a new top-level menu or do you want to add a popup menu into an existing top-level menu, like "File"? One comment to your example. Please NEVER create a settings container using a ui configuration manager and insert it into another container. A container which is created by a ui configuration manager is always a root container! Every container itself is a factory to create its own sub containers. The referenced example in oooforum is wrong in that point! Regards, Carsten - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: [dev] Dynamic menus: with Java (Problem)
Hi Carsten, thank you for answering the question of Andrej who is a colleague of mine. I am continuing the work with Andrej's code. > I looked over your example and I am not sure what you want to do. Can > you please explain what do you want to achieve? Create a new top-level > menu or do you want to add a popup menu into an existing top-level menu, > like "File"? For our own UNO-Component we would like to create a *new* top-level menu that is able to contain either simple-Elements (Type.BUTTON) AND nested Sub-Menus. > > One comment to your example. Please NEVER create a settings container > using a ui configuration manager and insert it into another container. A > container which is created by a ui configuration manager is always a > root container! Every container itself is a factory to create its own > sub containers. The referenced example in oooforum is wrong in that point! I think this hint points us to the root of our problems, as we currently always use the ModuleUIConfigurationManager to create new settings-instances even for sub containers. I am trying to change this, but I can't find the corresponding entry point. So which is the access point for us to create new sub containers? If my interpretation your statement above is correct, you say that each settings-instance provides a corresponding factory for sub containers. So I xray'ed an existing settings object, which I got using the following basic-lines, but the object doesn't export an Interface that seems to me the right one: sMenuBar = "private:resource/menubar/menubar" oModel = ThisComponent oLayoutManager = oModel.getCurrentController().getFrame().LayoutManager() oMenuBar = oLayoutManager.getElement( sMenuBar ) settings = oMenuBar.getSettings(true) settings supports the following Interfaces: com.sun.star.beans.XFastPropertySet com.sun.star.beans.XMultiPropertySet com.sun.star.beans.XPropertySet com.sun.star.container.XElementAccess com.sun.star.container.XIndexAccess com.sun.star.container.XIndexContainer com.sun.star.container.XIndexReplace com.sun.star.lang.XSingleComponentFactory com.sun.star.lang.XTypeProvider com.sun.star.lang.XUnoTunnel com.sun.star.uno.XInterface Is it the XSingleComponentFactory I have to use to create the sub containers? Just to write a quick test-example in basic: How can I create a instance using basic? settings.createInstance() didn't work and I don't know how to get the required XComponentContext in Basic to call the settings.createInstanceWithContext()-Method. best regards, Christoph - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: [dev] Dynamic menus: with Java (Problem)
Christoph Lutz wrote: Hi Carsten, Is it the XSingleComponentFactory I have to use to create the sub containers? Just to write a quick test-example in basic: How can I create a instance using basic? settings.createInstance() didn't work and I don't know how to get the required XComponentContext in Basic to call the settings.createInstanceWithContext()-Method. Hi Christoph, Please look at the following example in Basic. It uses the function CreatePopupMenu to create a new popup menu. The line of interest uses the factory (the container) to create a sub container with createInstanceWithContext(). Factory.createInstanceWithContext( GetDefaultContext() ) Example: Sub Main REM *** Creates a top-level popup menu on the Writer menu bar persistently. REM *** It checks if its popup menu has already been added to the menu bar REM *** and does nothing. REM *** The popup menu contains one menu item which call the Basic macro test. REM *** Initialize strings sMenuBar = "private:resource/menubar/menubar" sMyPopupMenuCmdId = "vnd.openoffice.org:MyMenu" REM *** Retrieve the module configuration manager from central module configuration manager supplier oModuleCfgMgrSupplier = createUnoService("com.sun.star.ui.ModuleUIConfigurationManagerSupplier") REM *** Retrieve the module configuration manager with module identifier REM *** See com.sun.star.frame.ModuleManager for more information oModuleCfgMgr = oModuleCfgMgrSupplier.getUIConfigurationManager( "com.sun.star.text.TextDocument" ) oMenuBarSettings = oModuleCfgMgr.getSettings( sMenuBar, true ) REM *** Look for our top-level popup menu. Can be identified by the CommandURL property. bHasAlreadyPopupMenu = false nCount = oMenuBarSettings.getCount() for i = 0 to nCount-1 oPopupMenu() = oMenuBarSettings.getByIndex( i ) nPopupMenuCount = ubound(oPopupMenu()) for j = 0 to nPopupMenuCount if oPopupMenu(j).Name = "CommandURL" then if oPopupMenu(j).Value = sMyPopupMenuCmdId then bHasAlreadyPopupMenu = true end if endif next j next i MsgBox bHasAlreadyPopupMenu if not bHasAlreadyPopupMenu then sString = "My Macro's" oPopupMenu = CreatePopupMenu( sMyPopupMenuCmdId, sString, oMenuBarSettings ) oPopupMenuContainer = oPopupMenu(3).Value oMenuItem = CreateMenuItem( "macro:///Standard.Module1.Test()", "Standard.Module1.Test" ) oPopupMenuContainer.insertByIndex( 0, oMenuItem ) oMenuBarSettings.insertByIndex( nCount, oPopupMenu ) oModuleCfgMgr.replaceSettings( sMenuBar, oMenuBarSettings ) end if End Sub Function CreatePopupMenu( CommandId, Label, Factory ) as Variant Dim aPopupMenu(3) as new com.sun.star.beans.PropertyValue aPopupMenu(0).Name = "CommandURL" aPopupMenu(0).Value = CommandId aPopupMenu(1).Name = "Label" aPopupMenu(1).Value = Label aPopupMenu(2).Name = "Type" aPopupMenu(2).Value = 0 aPopupMenu(3).Name = "ItemDescriptorContainer" aPopupMenu(3).Value = Factory.createInstanceWithContext( GetDefaultContext() ) CreatePopupMenu = aPopupMenu() 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 Regards, Carsten - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: [dev] Dynamic menus: with Java (Problem)
Hi Carsten, sorry for the late answer, I was very busy during the last weeks... 2005/11/17, Carsten Driesner <[EMAIL PROTECTED]>: > > Please look at the following example in Basic. It uses the function > CreatePopupMenu to create a new popup menu. The line of interest uses > the factory (the container) to create a sub container with > createInstanceWithContext(). thank you for the example code. It works very well. I would like to mention a behaviour I just noticed: the new created popupmenu will not be restored after an restart of OOo, so there is no persistence like described in your code comment... But I asume it was your intention not to call the oModuleCfgMgr.store() method after the line " oModuleCfgMgr.replaceSettings( sMenuBar, oMenuBarSettings )"? For my tests, I added the respective line to your example-code. But now to my question: I translated your example to java (I tried to do an exaxt one-to-one-translation of your basic-example) and the java-code bahaves slightly differt from the basic code: In basic, the popupmenu and all elements are visible directly after calling the code. Using my java-code, the popupmenu is created, but the element(s) in the popupmenu are not visible. The strange thing is, that after the call of oModuleCfgMgr.store() and a restart of OOo, the popupmenu and all its previously unvisible item(s) get visible. Do you have got an idea, why the items are not visible directly after creation, while the same code in basic creates visible items? I think this might be a bug... If you would like to follow, here's my translated java-code: import com.sun.star.beans.PropertyValue; import com.sun.star.comp.helper.Bootstrap; import com.sun.star.container.XIndexAccess; import com.sun.star.container.XIndexContainer; import com.sun.star.lang.XSingleComponentFactory; import com.sun.star.ui.ItemType; import com.sun.star.ui.XModuleUIConfigurationManagerSupplier; import com.sun.star.ui.XUIConfigurationManager; import com.sun.star.ui.XUIConfigurationPersistence; import com.sun.star.uno.Exception; import com.sun.star.uno.UnoRuntime; import com.sun.star.uno.XComponentContext; public class MenubarTest { public static void main(String[] args) throws java.lang.Exception { addItemToMenubar(Bootstrap.bootstrap()); System.exit(0); } /** * Creates a top-level popup menu on the Writer menu bar persistently. It * checks if its popup menu has already been added to the menu bar and does * nothing. The popup menu contains one menu item which call the Basic macro * test. * * @throws Exception */ public static void addItemToMenubar(XComponentContext ctx) throws java.lang.Exception { // Initialize strings String sMenuBar = "private:resource/menubar/menubar"; String sMyPopupMenuCmdId = "vnd.openoffice.org:MyMenu"; // Retrieve the module configuration manager from central module // configuration manager supplier Object oModuleCfgMgrSupplier = ctx .getServiceManager().createInstanceWithContext( "com.sun.star.ui.ModuleUIConfigurationManagerSupplier", ctx); XModuleUIConfigurationManagerSupplier xModuleUICfgMgrSupplier = (XModuleUIConfigurationManagerSupplier) UnoRuntime .queryInterface( XModuleUIConfigurationManagerSupplier.class, oModuleCfgMgrSupplier); // Retrieve the module configuration manager with module // identifier // See com.sun.star.frame.ModuleManager for more information XUIConfigurationManager xModuleUICfgMgr = xModuleUICfgMgrSupplier .getUIConfigurationManager("com.sun.star.text.TextDocument"); XIndexAccess oMenuBarSettings = xModuleUICfgMgr.getSettings( sMenuBar, true); XIndexContainer settingsContainer = (XIndexContainer) UnoRuntime .queryInterface(XIndexContainer.class, oMenuBarSettings); XSingleComponentFactory factory = (XSingleComponentFactory) UnoRuntime .queryInterface(XSingleComponentFactory.class, oMenuBarSettings); // Look for our top-level popup menu. Can be identified by the // CommandURL property. boolean bHasAlreadyPopupMenu = false; int nCount = oMenuBarSettings.getCount(); for (int i = 0; i < nCount; ++i) { PropertyValue[] oPopupMenu = (PropertyValue[]) oMenuBarSettings .getByIndex(i); for (int j = 0; j < oPopupMenu.length; ++j) { if (oPopupMenu[j].Name.equals("CommandURL")) { if (oPopupMenu[j].Value.equals(sMyPopupMenuCmdId)) { bHasAlreadyPopupMenu = true; } } } } System.out.println(bHasAlreadyPopupMenu); if (!bHasAlreadyPopupMenu) { String sString = "My Macro's"; PropertyValue[] oPopupMenu = CreatePopupMenu( sMyP
Re: [dev] Dynamic menus: with Java (Problem)
Christoph Lutz wrote: Hi Christoph, thank you for the example code. It works very well. I would like to mention a behaviour I just noticed: the new created popupmenu will not be restored after an restart of OOo, so there is no persistence like described in your code comment... But I asume it was your intention not to call the oModuleCfgMgr.store() method after the line " oModuleCfgMgr.replaceSettings( sMenuBar, oMenuBarSettings )"? For my tests, I added the respective line to your example-code. Your are right I forgot to add the oModuleCfgMgr.store() call. But now to my question: I translated your example to java (I tried to do an exaxt one-to-one-translation of your basic-example) and the java-code bahaves slightly differt from the basic code: In basic, the popupmenu and all elements are visible directly after calling the code. Using my java-code, the popupmenu is created, but the element(s) in the popupmenu are not visible. The strange thing is, that after the call of oModuleCfgMgr.store() and a restart of OOo, the popupmenu and all its previously unvisible item(s) get visible. Do you have got an idea, why the items are not visible directly after creation, while the same code in basic creates visible items? I think this might be a bug... I looked over your example and I cannot see an obviously problem. Please give some days to check wants wrong here. I will let you know when I have more information. It's possible that this might be a bug, although OOo only uses this API internally for customization. Regards, Carsten - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]