how do i get the xscriptcontext? :)
Ariel Constenla-Haile wrote: > > Hello allirpa, > > On Friday 06 March 2009, 23:38, allirpa wrote: >> is there a way how to access math objects available in open office using >> java? > > the API to *access* differs a little in Writer from the other apps. In > Writer > you have com.sun.star.text.XTextEmbeddedObjectsSupplier to access all the > embedded objects, then check the CLSID > (078B7ABA-54FC-457F-8551-6147e776a997) > to see if it's an OOo Math object [see code attached] > >> i am trying to make an addon for open office which will enable users to >> insert equations without using OO.o Math. >> >> Here's how it should work: there will be a button in the toolbar and when >> it is clicked, a WYSIWYG editor would popup and the user would just have >> to >> click buttons to insert math objects and make their own equations. when > > isn't this what already does OOo Math when called from within another > application (vs. standalone)? > >> they're done, they should be able to insert the equation that they made >> in >> the document. >> >> is that even possible? > > inserting an OOo Math embedded object is very simple [see code attached] > >> i am using OpenOffice 2.4, > > then you're done, you'll better update to OOo 3.0, because IIRC there are > issue on OOo 2.4 that don't let the object resize [see code attached for a > work-around] > >> java, netbeans 6.5. > the code attached uses the Scripting framework [put both files attached in > your > OOo user dir.: user/Scripts/java/HelloMath/], but works with NetBeans, > following the instructions in > http://wiki.services.openoffice.org/wiki/Scripting_in_Java_with_NetBeans_IDE > [didn't have time to update this completely, just the Linux text. Feel > free to > fix it if you find Windows errors] > > > Regards > -- > Ariel Constenla-Haile > La Plata, Argentina > > > "Aus der Kriegsschule des Lebens > - Was mich nicht umbringt, > macht mich härter." > Nietzsche Götzendämmerung, Sprüche und Pfeile, 8. > > > import com.sun.star.beans.XPropertySet; > import com.sun.star.container.XIndexAccess; > import com.sun.star.container.XNameAccess; > import com.sun.star.document.XEmbeddedObjectSupplier2; > import com.sun.star.frame.XController; > import com.sun.star.frame.XModel; > import com.sun.star.lang.Locale; > import com.sun.star.lang.XComponent; > import com.sun.star.lang.XMultiServiceFactory; > import com.sun.star.lang.XServiceInfo; > import com.sun.star.script.provider.XScriptContext; > import com.sun.star.text.ControlCharacter; > import com.sun.star.text.TextContentAnchorType; > import com.sun.star.text.XDependentTextField; > import com.sun.star.uno.UnoRuntime; > import com.sun.star.text.XTextDocument; > import com.sun.star.text.XTextRange; > import com.sun.star.text.XTextContent; > import com.sun.star.text.XTextCursor; > import com.sun.star.text.XTextEmbeddedObjectsSupplier; > import com.sun.star.text.XTextFieldsSupplier; > import com.sun.star.uno.AnyConverter; > import com.sun.star.util.XNumberFormats; > import com.sun.star.util.XNumberFormatsSupplier; > import com.sun.star.util.XRefreshable; > import com.sun.star.view.XSelectionSupplier; > > public class HelloMath { > > /** > * this is FIXED > */ > public static String OOO_MATH_CLSID = > "078B7ABA-54FC-457F-8551-6147e776a997"; > /** > * this can be customized (d.i. only "OOoMathFormula" part, the field > master name) > */ > public static String OOO_MATH_SEQ_FIELDMASTER_NAME = "OOoMathFormula"; > public static String OOO_MATH_SEQ_FIELDMASTER = > "com.sun.star.text.FieldMaster.SetExpression"; > > /** > * > * @param xScriptContext > */ > public static void accessFormulae(XScriptContext xScriptContext) { > XTextDocument xTextDocument = (XTextDocument) > UnoRuntime.queryInterface( > XTextDocument.class, xScriptContext.getDocument()); > if (xTextDocument == null) { > System.out.println("This isn't a text document!"); > return; > } > > XTextEmbeddedObjectsSupplier xSupplier = > (XTextEmbeddedObjectsSupplier) UnoRuntime.queryInterface( > XTextEmbeddedObjectsSupplier.class, xTextDocument); > > XNameAccess xEmbeddedObjects = xSupplier.getEmbeddedObjects(); > XIndexAccess xIndexAccess = (XIndexAccess) > UnoRuntime.queryInterface( > XIndexAccess.class, xEmbeddedObjects); > > for (int i = 0; i < xIndexAccess.getCount(); i++) { > try { > Object object = xIndexAccess.getByIndex(i); > > XPropertySet xPropertySet = (XPropertySet) > UnoRuntime.queryInterface( > XPropertySet.class, object); > String sCLSID = > AnyConverter.toString(xPropertySet.getPropertyValue("CLSID")); > > if (sCLSID.equals(OOO_MATH_CLSID)) { > > XEmbeddedObjectSupplier2 xEmbeddedObjectSupplier = > (XEmbeddedObjectSupplier2) > UnoRuntime.queryInterface( > XEmbeddedObjectSupplier2.class, object); > XComponent xEmbeddedObjectModel = > xEmbeddedObjectSupplier.getEmbeddedObject(); > > XPropertySet xFormulaProperties = (XPropertySet) > UnoRuntime.queryInterface( > XPropertySet.class, xEmbeddedObjectModel); > > String sFormula = AnyConverter.toString( > > xFormulaProperties.getPropertyValue("Formula")); > > System.out.printf( > "Found an OOo Math formula.\nFormula: %s%n%n", > sFormula); > } > } catch (Exception e) { > e.printStackTrace(); > } > } > } > > > /** > * > * @param xScriptContext > */ > public static void insertFormula(XScriptContext xScriptContext) { > XTextDocument xTextDocument = (XTextDocument) > UnoRuntime.queryInterface( > XTextDocument.class, xScriptContext.getDocument()); > if (xTextDocument == null) { > System.out.println("This isn't a text document!"); > return; > } > > XModel xModel = (XModel) UnoRuntime.queryInterface( > XModel.class, xTextDocument); > > XController xController = xModel.getCurrentController(); > // that the Model knows about the View's selection is a non-sense > // Object aSelection = xModel.getCurrentSelection(); > > /** > * The writer controller implementation supports the interface > * com.sun.star.view.XSelectionSupplier that returns the object > * that is currently selected in the user interface. > * > * Its method getSelection() returns an any that may contain > * different kind of objects depending on the selection: > */ > XSelectionSupplier xSelectionSupplier = (XSelectionSupplier) > UnoRuntime.queryInterface(XSelectionSupplier.class, > xController); > XServiceInfo xServiceInfo = (XServiceInfo) > UnoRuntime.queryInterface( > XServiceInfo.class, xSelectionSupplier.getSelection()); > > if ( xServiceInfo.supportsService("com.sun.star.text.TextRanges") > ) { > /** > * Selection: Text > * > * In this case, not only text in the body text may be > selected, > * but also text inside a frame, or atext table's cell > * (but only the text inside the cell, not the whole cell). > * > * As the user can select multiple texts at the same time > * (selecting while pressing Ctrl key), for example > * text inside a frame, a text table, the body text, a foot > note, etc. > * getSelection() returns an XIndexAccess. > * > * Note that when there is nothing selected, and there is only > the > * insertion point, getSelection() will NOT return a null > reference, > * BUT an XIndexAccess with only one text range at index zero > * pointing to the view cursor. > */ > > XIndexAccess xIndexAccess = (XIndexAccess) > UnoRuntime.queryInterface(XIndexAccess.class, > xServiceInfo); > int nCount = xIndexAccess.getCount(); > > /** > * Testing possible getCount() return values... > * > * * no selection, just the insertion point ==> > getCount() = 1 > * * 1 selection ==> getCount() = 1 > * * 2 selections ==> getCount() = 3 > * * 3 selections ==> getCount() = 4 > * * 4 selections ==> getCount() = 5 > * > * When nothing is selected, getCount() returns ONE: a > XTextRange > * pointing to the current view cursor's insertion point. > * > * When only one text range is selected, getCount() still > returns ONE. > * > * When there are two or more text ranges selected, getCount() > * always returns the actual number of text ranges selected > PLUS one: > * the current view cursor's insertion point. > * For example, with 2 text ranges selected, getCount() > returns 3: > * the two text ranges and the insertion point. > * > * When getCount() returns 0 (zero), there is nothing selected > * and not even an insertion point (for example when you are > drawing > * a drawing shape, a control or a text frame). > * > * The PROBLEM is when getCount() return 1 : is there actually > a > * text range selected, or is it only the cursor's insertion > point? > * > * The solution to this problem is to create a text cursor for > * this text range and check the text cursor's state employing > * XTextCursor::isCollapsed(), to see if the start and end > positions > * of this cursor are the same. If yes, then nothing is > selected, > * and it's just the cursor's insertion point. > * > * Cheking the lenght of the text range's string is not a > * languege independent solution (for example, OOo Basic > strings > * can only hold up to 65535 characters, so a longer string > will > * have a length of zero). > */ > > XTextRange xTextRange = null; > XTextCursor xTextCursor = null; > > // check that this is only the insertion point... > if ( nCount == 1 ) { > try { > // create a text cursor and check if it is collapsed > xTextRange = (XTextRange) UnoRuntime.queryInterface( > XTextRange.class, xIndexAccess.getByIndex(0)); > xTextCursor = > xTextRange.getText().createTextCursorByRange(xTextRange); > > if ( xTextCursor.isCollapsed() ){ > System.out.println("\nNothing selected, " + > "it is only the insertion point;" + > "so we can safely insert a formula..."); > XMultiServiceFactory xDocFactory = > (XMultiServiceFactory) > UnoRuntime.queryInterface( > XMultiServiceFactory.class, > xTextDocument); > insertMathFormula(xDocFactory, xTextRange, > "{ { 6 over 7 times 8 } + 5 } over > 10"); > } > } catch (Exception ex) { > ex.printStackTrace(); > } > } > } > } > > /** > * > * @param xScriptContext > */ > public static void insertFormulaWithField(XScriptContext > xScriptContext) { > XTextDocument xTextDocument = (XTextDocument) > UnoRuntime.queryInterface( > XTextDocument.class, xScriptContext.getDocument()); > if (xTextDocument == null) { > System.out.println("This isn't a text document!"); > return; > } > > XModel xModel = (XModel) UnoRuntime.queryInterface( > XModel.class, xTextDocument); > XController xController = xModel.getCurrentController(); > XSelectionSupplier xSelectionSupplier = (XSelectionSupplier) > UnoRuntime.queryInterface(XSelectionSupplier.class, > xController); > XServiceInfo xServiceInfo = (XServiceInfo) > UnoRuntime.queryInterface( > XServiceInfo.class, xSelectionSupplier.getSelection()); > > if ( xServiceInfo.supportsService("com.sun.star.text.TextRanges") > ) { > XIndexAccess xIndexAccess = (XIndexAccess) > UnoRuntime.queryInterface(XIndexAccess.class, > xServiceInfo); > int nCount = xIndexAccess.getCount(); > > XTextRange xTextRange = null; > XTextCursor xTextCursor = null; > if ( nCount == 1 ) { > try { > // create a text cursor and check if it is collapsed > xTextRange = (XTextRange) UnoRuntime.queryInterface( > XTextRange.class, xIndexAccess.getByIndex(0)); > xTextCursor = > xTextRange.getText().createTextCursorByRange(xTextRange); > > if ( xTextCursor.isCollapsed() ){ > System.out.println("\nNothing selected, " + > "it is only the insertion point;" + > "so we can safely insert a formula..."); > XMultiServiceFactory xDocFactory = > (XMultiServiceFactory) > UnoRuntime.queryInterface( > XMultiServiceFactory.class, > xTextDocument); > insertMathFormulaWithSeqField(xDocFactory, > xTextRange, > "{ { 6 over 7 times 8 } + 5 } over > 10", > "Formula Nr. $ "); > refreshTextFields(xTextDocument); > } > } catch (Exception ex) { > ex.printStackTrace(); > } > } > } > } > > > /** > * > * @param xDocFactory > * @param xTextRange > * @param sFormula > * @return > */ > private static XTextContent insertMathFormula( > XMultiServiceFactory xDocFactory, XTextRange xTextRange, > String sFormula) { > XTextContent xTextContent = null; > try { > xTextContent = (XTextContent) UnoRuntime.queryInterface( > XTextContent.class, xDocFactory.createInstance( > "com.sun.star.text.TextEmbeddedObject")); > > XPropertySet xPropertySet = (XPropertySet) > UnoRuntime.queryInterface( > XPropertySet.class, xTextContent); > > xPropertySet.setPropertyValue("CLSID", OOO_MATH_CLSID); > xPropertySet.setPropertyValue("AnchorType", > TextContentAnchorType.AS_CHARACTER); > > insertTextContent(xTextRange, xTextContent); > > XEmbeddedObjectSupplier2 xEmbeddedObjectSupplier = > (XEmbeddedObjectSupplier2) UnoRuntime.queryInterface( > XEmbeddedObjectSupplier2.class, xTextContent); > XComponent xEmbeddedObjectModel = > xEmbeddedObjectSupplier.getEmbeddedObject(); > > XPropertySet xFormulaProperties = (XPropertySet) > UnoRuntime.queryInterface( > XPropertySet.class, xEmbeddedObjectModel); > > xFormulaProperties.setPropertyValue("Formula", sFormula); > > /** > * to solve the issue with the formula size: > */ > /*XGraphic xGraphic = > xEmbeddedObjectSupplier.getReplacementGraphic(); > XPropertySet xGraphicPropertySet = (XPropertySet) > UnoRuntime.queryInterface( > XPropertySet.class, xGraphic); > Object any = > xGraphicPropertySet.getPropertyValue("Size100thMM"); > Size aSize = null; > try { > if (!AnyConverter.isVoid(any)) { > aSize = (Size) AnyConverter.toObject(Size.class, any); > } > } catch (Exception e) { > e.printStackTrace(); > } > if (aSize != null && aSize.Width > 0 && aSize.Height > 0) { > xPropertySet.setPropertyValue("Width", aSize.Width); > xPropertySet.setPropertyValue("Height", aSize.Height); > }*/ > } catch (Exception ex) { > ex.printStackTrace(); > } finally { > return xTextContent; > } > } > > /** > * > * @param xDocFactory > * @param xTextRange > * @param sFormula > * @param sCaption > * @return > */ > private static XTextContent insertMathFormulaWithSeqField( > XMultiServiceFactory xDocFactory, XTextRange xTextRange, > String sFormula, String sCaption) { > XTextContent xTextContent = null; > try { > xTextContent = insertMathFormula(xDocFactory, xTextRange, > sFormula); > > XDependentTextField xSeqField = createSequentialField( > xDocFactory, getOrCreateFieldMaster(xDocFactory)); > > XTextRange xFormulaAnchor = xTextContent.getAnchor(); > XTextCursor xFormulaCursor = > xFormulaAnchor.getText().createTextCursorByRange( > xFormulaAnchor.getStart()); > insertText(xFormulaCursor, sCaption); > > int idx = sCaption.lastIndexOf('$'); > if (idx > -1) { > xFormulaCursor.goLeft( (short)(sCaption.length() - idx), > false); > xFormulaCursor.goRight( (short)1, true); > insertTextContent(xFormulaCursor, xSeqField, true); > } else > insertTextContent(xFormulaCursor, xSeqField, false); > > } catch (Exception ex) { > ex.printStackTrace(); > } finally { > return xTextContent; > } > } > > private static XDependentTextField createSequentialField( > XMultiServiceFactory xDocFactory,XPropertySet xFieldMaster){ > return createSetExpression( xDocFactory, xFieldMaster, > OOO_MATH_SEQ_FIELDMASTER_NAME + "+1", > queryOrAddNumberFormat( (XComponent) > UnoRuntime.queryInterface( > XComponent.class, xDocFactory), "#.##0,00"), > com.sun.star.style.NumberingType.ARABIC, > com.sun.star.text.SetVariableType.SEQUENCE); > } > > > private static XPropertySet > getOrCreateFieldMaster(XMultiServiceFactory xDocFactory){ > return createMasterSetExpression( > xDocFactory, OOO_MATH_SEQ_FIELDMASTER_NAME, (byte)-1, > "", com.sun.star.text.SetVariableType.SEQUENCE); > } > > > private static void refreshTextFields(XTextDocument xTextDocument) { > XTextFieldsSupplier xTextFieldsSupplier = > (XTextFieldsSupplier) UnoRuntime.queryInterface( > XTextFieldsSupplier.class, xTextDocument); > XRefreshable xRefreshable = (XRefreshable) > UnoRuntime.queryInterface( > XRefreshable.class, xTextFieldsSupplier.getTextFields()); > xRefreshable.refresh(); > } > > > //************************************************************************** > > /** > * > * @param xDocFactory > * @param sFieldName > * @param nChapNumLevel > * @param sNumSeparator > * @param nSubType > * @return > */ > private static XPropertySet createMasterSetExpression( > XMultiServiceFactory > xDocFactory, > String sFieldName, > byte nChapNumLevel, > String sNumSeparator, > short nSubType) { > > XPropertySet xFieldMaster = null; > String fieldMasterName = OOO_MATH_SEQ_FIELDMASTER + "." + > sFieldName; > try { > XTextFieldsSupplier xTextFieldsSupplier = > (XTextFieldsSupplier) UnoRuntime.queryInterface( > XTextFieldsSupplier.class, xDocFactory); > > XNameAccess xFieldMasterAccess = > xTextFieldsSupplier.getTextFieldMasters(); > > if (xFieldMasterAccess.hasByName(fieldMasterName)) { > > xFieldMaster = (XPropertySet) UnoRuntime.queryInterface( > XPropertySet.class, > xFieldMasterAccess.getByName(fieldMasterName)); > } else { > xFieldMaster = (XPropertySet) UnoRuntime.queryInterface( > XPropertySet.class, > xDocFactory.createInstance(OOO_MATH_SEQ_FIELDMASTER)); > > if (xFieldMaster != null) { > > xFieldMaster.setPropertyValue("Name", sFieldName); > xFieldMaster.setPropertyValue("ChapterNumberingLevel", > new Byte(nChapNumLevel)); > xFieldMaster.setPropertyValue("NumberingSeparator", > sNumSeparator); > xFieldMaster.setPropertyValue("SubType", new > Short(nSubType)); > } > } > } catch (Exception ex) { > ex.printStackTrace(); > } finally { > return xFieldMaster; > } > } > > private static XDependentTextField createSetExpression( > > XMultiServiceFactory xDocFactory, > XPropertySet > xFieldMaster, > String > sContent, > int > nNumberFormat, > short > nNumberingType, > short > nSubType) { > XDependentTextField xDependentTextField = null; > try { > xDependentTextField = (XDependentTextField) > UnoRuntime.queryInterface( > XDependentTextField.class, xDocFactory.createInstance( > "com.sun.star.text.TextField.SetExpression")); > XPropertySet xSetExpression = (XPropertySet) > UnoRuntime.queryInterface( > XPropertySet.class, xDependentTextField); > > xSetExpression.setPropertyValue("Content", sContent); > xSetExpression.setPropertyValue("SubType", new > Short(nSubType)); > xSetExpression.setPropertyValue("NumberFormat", new > Integer(nNumberFormat)); > xSetExpression.setPropertyValue("NumberingType", new > Short(nNumberingType)); > > xDependentTextField.attachTextFieldMaster(xFieldMaster); > } catch (Exception ex) { > ex.printStackTrace(); > } finally { > return xDependentTextField; > } > } > > /** > * > * @param xComponent > * @param sFormat > * @return > */ > private static int queryOrAddNumberFormat(XComponent xComponent, > String sFormat){ > int nFormatCode = 0; > try { > XNumberFormatsSupplier xNumberFormatsSupplier = > (XNumberFormatsSupplier) UnoRuntime.queryInterface( > XNumberFormatsSupplier.class, xComponent); > > XNumberFormats xNumberFormats = > xNumberFormatsSupplier.getNumberFormats(); > Locale aLocale = new Locale(); > nFormatCode = xNumberFormats.queryKey(sFormat, aLocale, > false); > if (nFormatCode == -1) { > nFormatCode = xNumberFormats.addNew(sFormat, aLocale); > } > } catch (Exception e) { > e.printStackTrace(); > } finally { > return nFormatCode; > } > } > > private static void insertText(XTextRange xTextRange, String string) { > xTextRange.getText().insertString(xTextRange, string, false); > } > > private static void insertParaBreak(XTextRange xTextRange) { > try { > xTextRange.getText().insertControlCharacter( > xTextRange, ControlCharacter.PARAGRAPH_BREAK, false); > } catch (Exception ex) { > ex.printStackTrace(); > } > } > > private static void insertTextContent(XTextRange xTextRange, > XTextContent xContent) { > insertTextContent(xTextRange, xContent, false); > } > > private static void insertTextContent(XTextRange xTextRange, > XTextContent xContent, boolean bAbsorb) { > try { > xTextRange.getText().insertTextContent(xTextRange, xContent, > bAbsorb); > } catch (Exception ex) { > ex.printStackTrace(); > } > } > } > > > --------------------------------------------------------------------- > To unsubscribe, e-mail: [email protected] > For additional commands, e-mail: [email protected] > ----- "What cannot kill you will make you stronger." -- View this message in context: http://www.nabble.com/open-office-math-objects-tp22383486p22614646.html Sent from the openoffice - api dev mailing list archive at Nabble.com. --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
