Access to com.sun.star.text.textfield.Annotation in {Libre,Open}Office Writer using Java

674 views Asked by At

I am using Java to iterate over all Paragraphs and TextPortions within a XText object.

When I check the TextPortionType:

XPropertySet props= UnoRuntime.queryInferface(XPropertySet.class, portion);
String portionType= (String)props.getPropertyValue("TextPortionType");
if(portionType.equals("Annotation"))
{
  // get com.sun.star.text.textfield.Annotation
}

and encounter an Annotation or AnnotationEnd, I would like to access the corresponding Annotation (and later create some myself).

I know of the service com.sun.star.text.textfield.Annotation, however Annotation indicates via XServiceInfo that it does not support it. How do I obtain a reference to the Annotation from the Annotation I encounter in a TextPortion?

How do I create Annotations myself?

I am using OpenOffice 4.1.1.

1

There are 1 answers

0
Jens Jensen On

The LibreOffice API docs show that service com.sun.star.text.textfield.Annotation provides a single interface: XTextField. Although "Annotation" is not documented as a possible value for TextPortionType, the value of property "TextField" is the Annotation service.

In order to access Annotation properties, do:

XPropertySet portionProps= UnoRuntime.queryInferface(XPropertySet.class, portion);
String portionType= (String)portionProps.getPropertyValue("TextPortionType");
if(portionType.equals("Annotation"))
{
  // get com.sun.star.text.textfield.Annotation
  Object textField= portionProps.getPropertyValue("TextField");
  XPropertySet annotProps= UnoRuntime.queryInterface(XPropertySet.class, textField);
  String author= (String)annotProps.getPropertyValue("Author");
  // ... 
}

Ohter attributes of service Annotation are:

  • Author
  • Content
  • Name
  • Initialis
  • DateTimeValue
  • Date
  • TextRange
  • IsFieldUsed
  • IsFieldDisplayed
  • TextWrap
  • AnchorTypes
  • AnchorType

The PropertyValue "TextField" is not set for TextPortionType "AnnotationEnd". There is also no service AnnotationEnd.

Annotations can be created as follows:

public static void createAnnotation( XComponentContext xContext, XTextRange xTextRange )
{
  // per-document stuff
  XMultiComponentFactory xServiceManager= xContext.getServiceManager();
  Object desktop= xServiceManager.createInstanceWithContext("com.sun.star.frame.Desktop", xContext);
  XComponent xComponent= xDesktop.getCurrentComponent();
  XTextDocument xTextDocument= UnoRunime.queryInterface(XTextDocument.class, xComponent);
  XText xText= xTextDocument.getText();
  XMultiServiceFactory xWriterFactory= UnoRuntime.queryInterface(XMultiServiceFactory.class, xComponent);

  // per-annotation stuff
  Object annotation= xWriterFactory.createInstance("com.sun.star.text.textfield.nnotation");
  XPropertySet annotProps=   UnoRuntime.queryInterface(XPropertySet.class, annotation);
  annotProps.setValue("Content", "It's a me!")
  annotProps.setValue("Author", "Mario");
  XTextField annotTextField= UnoRuntime.queryInterface(XTextfield.class, annotation);
  xText.insertTextContent( xTextRange, annotTextField, true ); // "true" spans the range
}

Annotations can be removed too. Be careful when trying to remove Annotations with Change Tracking enabled: getPropertyValue("TextPortionType") may raise a RuntimeException on ApacheOO 4.1.1. Also for some reason I have not debugged yet, the removal does nothing on my LibreOffice 4.2.7.2

public static void removeAnnotations( XText xText ) throws Exception
{
  // follow https://wiki.openoffice.org/wiki/Documentation/DevGuide/Text/Iterating_over_Text
  final XEnumerationAccess xParaAccess= UnoRuntime.queryInterface(XEnumerationAccess.class, xText);
  final XEnumeration xParaEnum= xParaAccess.createEnumeration();

  for( int par_i=0; xParaEnum.hasMoreElements(); par_i++ )
  {
    final Object para= xParaEnum.nextElement();
    final XServiceInfo xParaInfo= UnoRuntime.queryInterface(XServiceInfo.class, para);

    final XEnumerationAccess xParamPortionsAccess= UnoRuntime.queryInterface(XEnumerationAccess.class, para);
    final XEnumeration xParamPortionsEnum= xParamPortionsAccess.createEnumeration();

    for( int port_i=0; xParamPortionsEnum.hasMoreElements(); port_i++ )
    {
      final Object portion= xParamPortionsEnum.nextElement();
      final XPropertySet portProps= UnoRuntime.queryInterface(XPropertySet.class, portion);

      // will cause RuntimeException when called with Change Tracking enabled
      final String xTextPortionType= (String)portProps.getPropertyValue("TextPortionType");
      if( xTextPortionType.equals("Annotation") )
      {
        final Object annotation= portProps.getPropertyValue("TextField");
        final XPropertySet annotProps= UnoRuntime.queryInterface(XPropertySet.class, annotation);
        final String annotAuthor= (String)annotProps.getPropertyValue("Author");

        if( annotAuthor.equals("Mario")
        {
          final XTextField xTextField= UnoRuntime.queryInterface(XTextField.class, annotation);
          xText.removeTextContent( xTextField );
        }
      }
      // AnnotationEnd has no associated TextField, can't call removeTextContent on anything
    }
  }
}