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();
}
}
}
parcel-descriptor.xml
Description: XML document
--------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
