Hi Matthias, >>>>> I created a little programm that removes a menu item from a menu and >>>>> adds another instead. In case the user tries to access the menu while >>>>> the menu update is performed my OO crashes and says:
[...] > Usually this shouldn't happen. I'm afraid that without a test case or at > least the relevant source code of your java program we can't do much. I > assume that one of your API calls leaves the menu in an inconsistent > state (that is resolved with one or more subsequent calls) or one of the > API calls you are using is not synchronized correctly. In the first case > we must check the involved API calls and see what can be done, in the > latter case we definitely must fix our code. I created a little sample application. You will find it at the end of the mail. May be a little oversized, but that is how it works here. One hint: in the main method the String args[] expects on Postition args[0] the filename. Please enter the file menu as soon as the application openes. [...] > Not really. Can you create and send a crash report (with your e-mail > address in the report so that I can find it in our database)? How can I do this? I use a Debian Sid OpenOffice (2.0.2) and no crashreport screen is shown. How can I activate it? Greetings, Tobias -----%<----- package de.twc.oocom; import java.io.File; import java.net.MalformedURLException; import java.util.Vector; import com.sun.star.beans.PropertyValue; import com.sun.star.beans.XPropertySet; import com.sun.star.comp.helper.Bootstrap; import com.sun.star.comp.helper.BootstrapException; import com.sun.star.container.XIndexAccess; import com.sun.star.container.XIndexContainer; import com.sun.star.frame.XComponentLoader; import com.sun.star.frame.XDesktop; import com.sun.star.frame.XFrame; import com.sun.star.frame.XLayoutManager; import com.sun.star.lang.EventObject; 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.XUIElement; import com.sun.star.ui.XUIElementSettings; import com.sun.star.uno.UnoRuntime; import com.sun.star.uno.XComponentContext; import com.sun.star.uri.ExternalUriReferenceTranslator; import com.sun.star.util.CloseVetoException; import com.sun.star.util.XCloseListener; import com.sun.star.util.XCloseable; public class MenuCrashTest { // You will need these Objects often... private Object desktop = null; private XComponentContext xRemoteContext = null; private XMultiComponentFactory xRemoteServiceManager = null; private XDesktop xDesktop = null; private XFrame xFrame = null; private XLayoutManager xLayoutManager = null; // The opened document itself private XComponent openDocument = null; private String openFilename = null; private MenuCrashTest(String newFilename) { openFilename = newFilename; } public static void main(String[] args){ MenuCrashTest myCrashTest = new MenuCrashTest(args[0]); myCrashTest.bootstrapOpenOffice(); myCrashTest.openDocument(); // add a menu item after the menu item ".uno:Save" myCrashTest.changeMenus(".uno:Save", ".JudasSaveTo:", "Sicherheitskopie"); // remove menu item ".uno:SaveAs" myCrashTest.changeMenus(".uno:SaveAs", null, null); // remove toolbar item ".uno:SaveAs" myCrashTest.changeToolbars(".uno:SaveAs", "remove"); myCrashTest.addCloseListener(); } /** * This method bootstraps a OpenOffice and returns it's Desktop. * * @return */ private void bootstrapOpenOffice() { try { // Connect or start a OpenOffice instance xRemoteContext = Bootstrap.bootstrap(); } catch (BootstrapException e) { System.out.println("Unable to start OpenOffice. Starter says:"); System.out.println(e.getLocalizedMessage()); } // get OO desktop xRemoteServiceManager = xRemoteContext.getServiceManager(); try { desktop = xRemoteServiceManager.createInstanceWithContext( "com.sun.star.frame.Desktop", xRemoteContext ); } catch (com.sun.star.uno.Exception e) { System.out.println("OpenOffice started, but can't get Desktop:"); System.out.println(e.getLocalizedMessage()); } // Get the XDesktop so you can close Openoffice correctly xDesktop = (XDesktop) UnoRuntime.queryInterface(XDesktop.class, desktop); System.out.println("OpenOffice successfully started."); } /** * This method connects to a running OpenOffice or, if none found starts it. * Afterwards a specified document is loaded. * * @param documentProperties * @param source_File * @return */ public XComponent openDocument() { // Query the XComponentLoader interface from the desktop XComponentLoader xComponentLoader = (XComponentLoader) UnoRuntime.queryInterface(XComponentLoader.class, this.desktop); PropertyValue[] myProperties = new PropertyValue[1]; myProperties[0] = new PropertyValue(); // open document read only myProperties[0].Name = "ReadOnly"; myProperties[0].Value = new Boolean(false); // Load a given document try { this.openDocument = xComponentLoader.loadComponentFromURL( createUNOFileURL(this.openFilename), // File folder and name "_blank", // New windos 0, // Is ignored myProperties); // Special properties } catch(com.sun.star.uno.Exception e) { System.out.println("OpenOffice runs, but error opening document:"); System.out.println(e.getLocalizedMessage()); } if (openDocument == null) { System.err.println("I cannot open the document. Is the filename " + "correct?"); System.exit(-1); } System.out.println("Document successfully opened."); return this.openDocument; } /** * Creating a correct File URL that OpenOffice can handle. This is * necessary to be platform independent. * * @param filelocation * @return */ protected String createUNOFileURL(String filelocation) { java.io.File newfile = new java.io.File(filelocation); java.net.URL before = null; try { before = newfile.toURL(); } catch (MalformedURLException e) { System.out.println(e); } // Create a URL, which can be used by UNO String myUNOFileURL = ExternalUriReferenceTranslator .create(xRemoteContext).translateToInternal(before.toExternalForm()); if (myUNOFileURL.length() == 0 && filelocation.length() > 0) { System.out.println("File URL conversion faild. Filelocation " + "contains illegal characters: " + filelocation); } return myUNOFileURL; } /** * This method either removes the item specified in the CommandURL from * OpenOffice menubar or adds the menu item specified in the * addItemCommandURL after myCommandURL to the menu. Changes are transient. * * @param myCommandURL * @param addItemCommandURL * @param addItemLabel */ public void changeMenus(String myCommandURL, String addItemCommandURL, String addItemLabel) { // Init menu elements // 1. Getting the menubar com.sun.star.ui.XUIElement myMenubar = this.getLayoutManager().getElement("private:resource/menubar/menubar"); // 2. Getting the menubar settings XUIElementSettings myMenuBarSettings = (XUIElementSettings) UnoRuntime.queryInterface(XUIElementSettings.class, myMenubar); // 3. Casting the settings into a container to be able to get the // properties XIndexContainer myMenuBarContainer = (XIndexContainer) UnoRuntime.queryInterface(XIndexContainer.class, myMenuBarSettings.getSettings(true)); try { // Creating a Vector containing all menus with a "Save" item Vector foundSaveMenuItems = this.searchXIndexContainerForItem( myCommandURL, myMenuBarContainer, new Vector()); if(addItemCommandURL != null) { this.addItemToMenu(addItemCommandURL, addItemLabel, foundSaveMenuItems); } else { // Remove the menu items this.removeXIndexContainerItems(foundSaveMenuItems); } // Make changes only transient (temporary). com.sun.star.beans.XPropertySet xPropSet = (XPropertySet) UnoRuntime.queryInterface(XPropertySet.class, myMenubar); xPropSet.setPropertyValue("Persistent", new Boolean(false)); // Apply settings to the root container (includes all subcontainers) myMenuBarSettings.setSettings(myMenuBarContainer); } catch (Exception e) { System.out.println("Cannot modify menubar. Reason: " + e); } } /** * This method return a Layout Manager of an opened OpenOffice. * * @return */ protected XLayoutManager getLayoutManager() { this.xFrame = this.xDesktop.getCurrentFrame(); XPropertySet xps = (XPropertySet) UnoRuntime.queryInterface(XPropertySet.class, this.xFrame); try { this.xLayoutManager = (XLayoutManager) UnoRuntime.queryInterface(XLayoutManager.class, xps.getPropertyValue("LayoutManager")); } catch (com.sun.star.uno.Exception e) { System.out.println("Cannot get Layout Manager:"); System.out.println(e.getLocalizedMessage()); } return this.xLayoutManager; } /** * Method that searches menus and its submenus for the "CommandURL" * property. The returned Vector consists of Vectors. Each contained Vector * has two values. The first gives the XIndexContainer where the searched * menu item was found, the second is an Integer that tells the position * where the menu item was found. * * @param myCommandURL * @param myMenuContainer * @param foundMenuItems * @return * @throws IllegalArgumentException * @throws IndexOutOfBoundsException * @throws WrappedTargetException */ private Vector searchXIndexContainerForItem(String myCommandURL, XIndexContainer myMenuContainer, Vector foundMenuItems) throws IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException { if(myMenuContainer != null) { for(int g = 0; g < myMenuContainer.getCount(); g++) { // Getting the properties of the given container PropertyValue[] gMenuItem = (PropertyValue[]) com.sun.star.uno.AnyConverter.toObject( PropertyValue[].class, myMenuContainer.getByIndex(g)); for(int h = 0; h < gMenuItem.length; h++) { if(gMenuItem[h].Name.equals("CommandURL")) { if(gMenuItem[h].Value.equals(myCommandURL)) { Vector thisMenuItem = new Vector(); thisMenuItem.addElement(myMenuContainer); thisMenuItem.addElement(new Integer(g)); foundMenuItems.addElement(thisMenuItem); break; } } else if(gMenuItem[h].Name.equals("ItemDescriptorContainer")) { XIndexAccess subMenuAccess = (XIndexAccess) com.sun.star.uno.AnyConverter.toObject( XIndexAccess.class, gMenuItem[h].Value); XIndexContainer subMenuContainer = (XIndexContainer) UnoRuntime.queryInterface( XIndexContainer.class, subMenuAccess); if(subMenuAccess != null) { searchXIndexContainerForItem(myCommandURL, subMenuContainer, foundMenuItems); } } } } } return foundMenuItems; } /** * This method adds the specified myCommandURL with the itemLabel to the * menu / toolbar after the specified menu item in foundMenuItems. * * @param myCommandURL * @param itemLabel * @param foundMenuItems */ private void addItemToMenu(String myCommandURL, String itemLabel, Vector foundMenuItems) { try { // Starting with the last Element, because removing changes item index for (int i = foundMenuItems.size() -1; i >= 0; i--) { Vector thisVectorItem = (Vector)foundMenuItems.elementAt(i); XIndexContainer thisMenuContainer = (XIndexContainer) thisVectorItem.elementAt(0); Integer menuPosition = (Integer)thisVectorItem.elementAt(1); // add the menu item thisMenuContainer.insertByIndex(menuPosition.intValue() + 1, createMenuItem(myCommandURL, itemLabel)); } } catch(IndexOutOfBoundsException e) { System.out.println("Can't add this item. Reason: " + e); } catch(WrappedTargetException e) { System.out.println("Can't add this item. Reason: " + e); } catch(IllegalArgumentException e) { System.out.println("Can't add this item. Reason: " + e); } } /** * Method that removes the given menu items. The given Vector contains a * XIndexContainer at first position (the menu containing the Item to remove) * and an Integer at second position (the item number of the item to remove. * The changes are transient (temporary). * * @param itemsToRemove * @throws IndexOutOfBoundsException * @throws WrappedTargetException */ private void removeXIndexContainerItems(Vector itemsToRemove) throws IndexOutOfBoundsException, WrappedTargetException { // Starting with the last Element, because removing changes item index for (int i = itemsToRemove.size() -1; i >= 0; i--) { Vector thisVectorItem = (Vector)itemsToRemove.elementAt(i); XIndexContainer thisMenuContainer = (XIndexContainer) thisVectorItem.elementAt(0); Integer menuPosition = (Integer)thisVectorItem.elementAt(1); // remove the item, but settings must be set to make it visible thisMenuContainer.removeByIndex(menuPosition.intValue()); } } /** * Creating the properties for a new menu item. * * @param sMyCommand * @param label * @return */ private PropertyValue[] createMenuItem(String sMyCommand, String label) { PropertyValue[] menuItemProperties = new PropertyValue[3]; menuItemProperties[0] = new PropertyValue(); menuItemProperties[0].Name = "CommandURL"; menuItemProperties[0].Value = sMyCommand; menuItemProperties[1] = new PropertyValue(); menuItemProperties[1].Name = "Label"; menuItemProperties[1].Value = label; menuItemProperties[2] = new PropertyValue(); menuItemProperties[2].Name = "Type"; menuItemProperties[2].Value = new Short((short)0); return menuItemProperties; } /** * This method removes the in the CommandURL specified items from OpenOffice * toolbars. Changes are transient. * * @param xLayoutManager * @param CommandURL * @param action * @throws Exception */ public void changeToolbars(String myCommandURL, String action) { final String[] toolbars = { "private:resource/toolbar/alignmentbar", "private:resource/toolbar/arrowshapes", "private:resource/toolbar/basicshapes", "private:resource/toolbar/calloutshapes", "private:resource/toolbar/colorbar", "private:resource/toolbar/drawbar", "private:resource/toolbar/drawobjectbar", "private:resource/toolbar/extrusionobjectbar", "private:resource/toolbar/fontworkobjectbar", "private:resource/toolbar/fontworkshapetypes", "private:resource/toolbar/formatobjectbar", "private:resource/toolbar/formcontrols", "private:resource/toolbar/formdesign", "private:resource/toolbar/formsfilterbar", "private:resource/toolbar/formsnavigationbar", "private:resource/toolbar/formsobjectbar", "private:resource/toolbar/formtextobjectbar", "private:resource/toolbar/fullscreenbar", "private:resource/toolbar/graphicobjectbar", "private:resource/toolbar/insertbar", "private:resource/toolbar/insertcellsbar", "private:resource/toolbar/insertobjectbar", "private:resource/toolbar/mediaobjectbar", "private:resource/toolbar/moreformcontrols", "private:resource/toolbar/previewbar", "private:resource/toolbar/standardbar", "private:resource/toolbar/starshapes", "private:resource/toolbar/symbolshapes", "private:resource/toolbar/textobjectbar", "private:resource/toolbar/toolbar", "private:resource/toolbar/viewerbar"}; for (int i = 0; i < toolbars.length; i++) { if (this.getLayoutManager().getElement(toolbars[i]) != null) { // Getting the toolbar XUIElement myToolbar = this.getLayoutManager().getElement(toolbars[i]); // Getting the toolbar settings XUIElementSettings myToolBarSettings = (XUIElementSettings) UnoRuntime.queryInterface(XUIElementSettings.class, myToolbar); // Casting the settings into a container to be able to get the // properties XIndexContainer myToolBarSettingsContainer = (XIndexContainer) UnoRuntime.queryInterface( XIndexContainer.class, myToolBarSettings.getSettings(true)); try { // Creating a Vector containing all toolbars containing // the CommanURL Vector foundSaveToolbarItems = this.searchXIndexContainerForItem( myCommandURL, myToolBarSettingsContainer, new Vector()); if(action.equals("remove")) { // Remove the toolbar items this.removeXIndexContainerItems(foundSaveToolbarItems); } else { System.out.println("Unknown action: '" + action + "'"); } // Make changes only transient (temporary). com.sun.star.beans.XPropertySet xPropSet = (XPropertySet) UnoRuntime.queryInterface(XPropertySet.class, myToolbar); xPropSet.setPropertyValue("Persistent", new Boolean(false)); // Apply changes myToolBarSettings.setSettings(myToolBarSettingsContainer); } catch (Exception e) { System.out.println("Cannot modify toolbars. Reason: " + e); } } } } /** * This method adds a CloseListener to the opened document. */ public void addCloseListener() { // initial close listener XCloseable close = (XCloseable)UnoRuntime.queryInterface( com.sun.star.util.XCloseable.class, this.openDocument); final File openFile = new File(this.openFilename); final long last_modified_old = openFile.lastModified(); close.addCloseListener(new XCloseListener() { public void queryClosing(EventObject arg0, boolean arg1) throws CloseVetoException { // TODO Auto-generated method stub long last_modified = openFile.lastModified(); if (last_modified != last_modified_old) { System.exit(0); } else { // XModifiable modi = openDocument.interfaces.getXModifiable(); // System.out.println(modi.isModified()); System.exit(1); } } public void notifyClosing(EventObject arg0) { // TODO Auto-generated method stub } public void disposing(EventObject arg0) { // TODO Auto-generated method stub } }); // wait for closing document while (true) { try { Thread.sleep(1000); } catch (InterruptedException e) { System.out.println(e); } } } } --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]