I've been using OpenOffice and LibreOffice to batch process documents using the Java UNO interface. Upon updating to LibreOffice 3.4.3, LibreOffice is ignoring the Java UNO calls to populate the input fields with data. Running the same code with LibreOffice 3.3 works flawlessly. Below is sample code, which I've stepped through in debug mode, and everything is running correctly. The fields are found, but calling xPropertySet.setPropertyValue("Content", newValue) leaves the document unchanged. Updating table cells with 3.4.3, however, is working as expected. Has something changed with the API that is not documented? CODE: String file = "/path/to/SomeFile.ott"; /* Initialize some variables */ // xRemoteServiceManager initialized previously Object desktop = xRemoteServiceManager.createInstanceWithContext("com.sun.star.frame.Desktop", xRemoteContext); XComponentLoader xComponentLoader = (XComponentLoader) UnoRuntime.queryInterface(XComponentLoader.class, desktop); // createPropertyValueArray and createPropertyValue are simply utility methods. PropertyValue[] xComponentLoadProps = createPropertyValueArray( createPropertyValue("AsTemplate", new Any(Type.BOOLEAN, Boolean.TRUE)), createPropertyValue("Hidden", new Any(Type.BOOLEAN, Boolean.TRUE))); XComponent xTemplateComponent = (XComponent) xComponentLoader.loadComponentFromURL("file:///" + file, "_blank", 0, properties); XTextDocument comp = (XTextDocument) UnoRuntime.queryInterface(XTextDocument.class, xTemplateComponent); XBookmarksSupplier bookmarksSupplier = (XBookmarksSupplier) UnoRuntime.queryInterface(XBookmarksSupplier.class, comp); XNameAccess namedBookmarks = bookmarksSupplier.getBookmarks(); XTextTablesSupplier xTablesSupplier = (XTextTablesSupplier) UnoRuntime.queryInterface(XTextTablesSupplier.class, comp); XNameAccess namedTables = xTablesSupplier.getTextTables(); XDrawPageSupplier xSuppPage = (XDrawPageSupplier) UnoRuntime.queryInterface(XDrawPageSupplier.class, comp); XDrawPage xDrawPage = xSuppPage.getDrawPage(); /* Create a HashMap to reference all the text fields */ XTextFieldsSupplier supplier = (XTextFieldsSupplier) UnoRuntime.queryInterface(XTextFieldsSupplier.class, comp); XEnumerationAccess enumAccess = supplier.getTextFields(); XEnumeration xEnum = enumAccess.createEnumeration(); Map textFields = new HashMap(); while (xEnum.hasMoreElements()) { Object o = xEnum.nextElement(); XTextField text = (XTextField) UnoRuntime.queryInterface(XTextField.class, o); XPropertySet xPropertySet = (XPropertySet) UnoRuntime.queryInterface(XPropertySet.class, text); XServiceInfo xServiceInfo = (XServiceInfo) UnoRuntime.queryInterface(XServiceInfo.class, text); if (xServiceInfo.supportsService("com.sun.star.text.TextField.Input")) { textFields.put(((String) xPropertySet.getPropertyValue("Hint")), text); } } /* Set some input fields */ setInputField("FirstName", "John"); setInputField("LastName", "Doe"); setInputField("Phone", "123-456-7890"); /* defined methods */ public void setInputField(String name, String value) { String newValue = (value == null) ? "" : value.replaceAll("\\u0000", ""); newValue = (newValue.contains("\r\n")) ? newValue.replace("\r", "") : newValue.replace("\r", "\n"); Object o = textFields.get(name); XTextField text = (XTextField) UnoRuntime.queryInterface(XTextField.class, o); XPropertySet xPropertySet = (XPropertySet) UnoRuntime.queryInterface(XPropertySet.class, text); xPropertySet.setPropertyValue("Content", newValue); }
I just tested with version 3.4.4, and the same problem exists. This is a show stopper.
I add some experts into CC. Does it trigger any bell?
cannot reproduce a regression here, what am i missing? the following runs successfully against LO 3.3.4, LO 3.4.3, LO master, OOo 3.3, OOo 3.2.1, OOo 3.0.1: @Test public void test_fdo42073() throws Exception { XMultiServiceFactory xDocFactory = (XMultiServiceFactory) UnoRuntime.queryInterface(XMultiServiceFactory.class, m_xDoc); Object xField = xDocFactory.createInstance("com.sun.star.text.TextField.Input"); XText xBodyText = m_xDoc.getText(); XTextCursor xCursor = xBodyText.createTextCursor(); XTextContent xContent = (XTextContent) UnoRuntime.queryInterface(XTextContent.class, xField); xBodyText.insertTextContent(xCursor, xContent, true); XPropertySet xPropSet = (XPropertySet) UnoRuntime.queryInterface(XPropertySet.class, xField); String content = "this is not surprising"; xPropSet.setPropertyValue("Content", content); Object readContent = xPropSet.getPropertyValue("Content"); assertEquals(content, readContent); }
I tried your code (and mine), and it does work (sort of). When running the code (with the document visible), the input fields do not show the newly set text. ie, they are collapsed. In order to view the text, I have to enable "Field Names" from the View menu, then disable them again. Only after doing that does the text show. More so, if I export the document to a file (through code) prior to the enable/disable workaround, the data in the fields does not get saved. Only after performing the enable/disable function does the export include the field data. Obviously is wrong/bad, because I can't sit here for automated system. The latest test is running LO 3.4.4 on Ubuntu Linux 11.10, but the same thing occurs on my Windows installation. @Test public void test_fdo42073() throws Exception { initializeOpenOffice(); PropertyValue[] loadProps = createPropertyValueArray( createPropertyValue("AsTemplate", new Any(Type.BOOLEAN, Boolean.TRUE)), createPropertyValue("Hidden", new Any(Type.BOOLEAN, Boolean.FALSE))); XComponent component = componentImport("/home/jmanko/VirtualBox VMs/PCID_042_LO_3.4.3/shared/templates/0198.OTT", loadProps); XTextDocument document = (XTextDocument) UnoRuntime.queryInterface(XTextDocument.class, component); XMultiServiceFactory xDocFactory = (XMultiServiceFactory) UnoRuntime.queryInterface(XMultiServiceFactory.class, document); Object xField = xDocFactory.createInstance("com.sun.star.text.TextField.Input"); XText xBodyText = document.getText(); XTextCursor xCursor = xBodyText.createTextCursor(); XTextContent xContent = (XTextContent) UnoRuntime.queryInterface(XTextContent.class, xField); xBodyText.insertTextContent(xCursor, xContent, true); XPropertySet xPropSet = (XPropertySet) UnoRuntime.queryInterface(XPropertySet.class, xField); String content = "this is not surprising"; xPropSet.setPropertyValue("Content", content); XTextFieldsSupplier supplier = (XTextFieldsSupplier) UnoRuntime.queryInterface(XTextFieldsSupplier.class, document); XEnumerationAccess enumAccess = supplier.getTextFields(); XEnumeration xEnum = enumAccess.createEnumeration(); Map textFields = new HashMap(); while (xEnum.hasMoreElements()) { Object o = xEnum.nextElement(); XTextField text = (XTextField) UnoRuntime.queryInterface(XTextField.class, o); XPropertySet xPropertySet = (XPropertySet) UnoRuntime.queryInterface(XPropertySet.class, text); XServiceInfo xServiceInfo = (XServiceInfo) UnoRuntime.queryInterface(XServiceInfo.class, text); if (xServiceInfo.supportsService("com.sun.star.text.TextField.Input")) { textFields.put(((String) xPropertySet.getPropertyValue("Hint")), text); } } Object o = textFields.get("POLICY_NO"); XTextField text = text = (XTextField) UnoRuntime.queryInterface(XTextField.class, o); XPropertySet xPropertySet = (XPropertySet) UnoRuntime.queryInterface(XPropertySet.class, text); xPropertySet.setPropertyValue("Content", "123456789"); PropertyValue[] saveProps = createPropertyValueArray( createPropertyValue("FilterName", new Any(Type.STRING, DocumentType.WRITER_OPENDOCUMENT_TEXT)), createPropertyValue("CompressionMode", new Any(Type.STRING, "1")), createPropertyValue("Pages", new Any(Type.STRING, "All")), createPropertyValue("Overwrite", new Any(Type.BOOLEAN, Boolean.TRUE))); /** BREAKPOINT PRIOR TO SAVING TO VIEW THE DOCUMENT. **/ componentExport(component, saveProps, "/home/jmanko/VirtualBox VMs/PCID_042_LO_3.4.3/shared/templates/0198_AFTER.ODT"); closeComponent(component); }
How did my last test code work?
I just tried this with versions 3.4.5 and 3.5.0 RC1, and neither worked correctly. So, this is an ongoing bug that was introduced with 3.4.3 and is unresolved. Let me know if you have any suggestions on how to provide more details for this bug.
ok, the problem here is that following a setPropertyValue, the getPresentation method will return stale values. this is a regression in OOo 3.4, from CWS sw34bf01 (8485708f3001fca132c3353c464fe7187ef62bed), related to fix for issue 112425, issue 85766. what confused me is that setPropertyValue also does not cause the text in the document view to be refreshed, which is a pre-existing condition (see comment #3). bug 39694 is a different regression from the same change.
Great find, Michael! If there any way this can be targeted for 3.5.1?
Michael Stahl committed a patch related to this issue. It has been pushed to "master": http://cgit.freedesktop.org/libreoffice/core/commit/?id=e3dfae0741aae8581cd3fc713ba1b4459bb22d88 fdo#42073: sw: expand all text fields when setting properties:
fixed on master probably too late for 3.5.1 now, with rc2 scheduled for Monday
Now in -3-5 branch => will be in 3.5.2 => set target accordingly http://cgit.freedesktop.org/libreoffice/core/commit/?h=libreoffice-3-5&id=be999f1bc692a122e36add37f23312edad8f81d2
added unit test for this: http://cgit.freedesktop.org/libreoffice/core/commit/?id=870e5a8e8251967b513b4255231ee9665b085431 because of the bugzilla outage it wasn't picked up automatically, so: fixed in libreoffice-3-4 as well: http://cgit.freedesktop.org/libreoffice/writer/commit/?h=libreoffice-3-4&id=ea137eef21554dfc7b8420b1f40e7a26eaaa5210