[Solved] OO/LibreOffice UNO-Java: Setting Styles

Java, C++, C#, Delphi... - Using the UNO bridges
Post Reply
Quaternion
Posts: 2
Joined: Mon Feb 10, 2014 8:08 pm

[Solved] OO/LibreOffice UNO-Java: Setting Styles

Post by Quaternion »

I have an issue where I'm simply trying to add new text and then apply a LibreOffice style to it. I want to add text and have it follow a particular style ("Heading 1", "Heading 2", etc).

Adding text to the document does work, changing the style does work however the last style set is applied to the entire document and not just the last String. I need some way to limit the selection to the String. I think I need an XTextRange and the Style belongs to that and not the cursor... but don't know how to create new XTextRanges containing only my latest String... clearly not certain, and advice would be most welcome.

NOTE 1: Although the following code is in Java I am more than willing at accept a solution using any programming language, the UNO APIs are similar enough that I could convert a solution from another language. I have the feeling there are more VB macro writers for OOo/LO than Java developers, then again maybe a C++ or Python developer has a solution. I should think to write out a document changing styles would be a pretty basic requirement!

NOTE 2: This message has been posted on StackOverflow with users with accounts there I should mention this question is there with a 200 pt bounty. After answering here post your answer there so I can avoid having the points soon expire. (Here: http://stackoverflow.com/q/21898500/514065)

Code: Select all

com.sun.star.text.XText xText = this.xDoc.getText();
//create a cursor object
com.sun.star.text.XTextCursor xTCursor = xText.createTextCursor();
this.writeResume(xText, xTCursor);
method to write resume... you will see where I attempt to change the style with the changeStyle method

Code: Select all

private void writeResume(com.sun.star.text.XText xText, com.sun.star.text.XTextCursor xTCursor) {
    TestData resume = new TestData();
    List<Company> companies = resume.getCompanies();
    this.changeStyle(xTCursor, "Heading 1");
    xText.insertString(xTCursor, "Professional Experience\n", false);
    xTCursor.collapseToEnd();
    this.changeStyle(xTCursor, "Heading 2");
    Company company = companies.get(0);
    String date = dformat.format(company.getStartDate().getTime()) + " - " + dformat.format(company.getEndDate().getTime());
    xText.insertString(xTCursor, company.getName() + "," + company.getLocation() + "\t" + date + "\n", false);
    xTCursor.collapseToEnd();
    this.changeStyle(xTCursor, "Heading 3");
    xText.insertString(xTCursor, "Test Point 1\n", false);
    xText.insertString(xTCursor, "Test Point 2\n", false);
    xText.insertString(xTCursor, "Test Point 3\n", false);
}
The changeStyle method

Code: Select all

public void changeStyle(com.sun.star.text.XTextCursor xTCursor, String styleName) {
    XPropertySet xCursorProps = UnoRuntime.queryInterface(XPropertySet.class, xTCursor);
    try {
        xCursorProps.setPropertyValue("ParaStyleName", styleName);
    } catch (UnknownPropertyException | PropertyVetoException | IllegalArgumentException | WrappedTargetException ex) {
        Logger.getLogger(ResumeWriter.class.getName()).log(Level.SEVERE, null, ex);
    }
}
Last edited by Quaternion on Mon Mar 03, 2014 7:01 am, edited 2 times in total.
LibreOffice 4.1.4.2 on Ubuntu 13.10
B Marcelly
Volunteer
Posts: 1160
Joined: Mon Oct 08, 2007 1:26 am
Location: France, Paris area

Re: OOo/LibreOffice UNO-Java: Setting Styles

Post by B Marcelly »

Hi,
Quaternion wrote:I have an issue where I'm simply trying to add new text and then apply a LibreOffice style to it. I want to add text and have it follow a particular style ("Heading 1", "Heading 2", etc).

Adding text to the document does work, changing the style does work however the last style set is applied to the entire document and not just the last String. I need some way to limit the selection to the String.
Before doing any programming, you need to understand how styles work in OpenOffice.
There are different types of style :
in Writer : Paragraph style, Character styles, Page Styles, Frame styles, List styles.
in Calc : Cell styles, Page styles.

You are concerned with Paragraph styles in Writer. As you should expect, a paragraph style applies to the whole paragraph. If your text range is one paragraph or less you can only apply one paragraph style.

You create a paragraph with insertion of a control character PARAGRAPH_BREAK. This character is different from the character LINE_BREAK. A control character is usually inserted by method :

Code: Select all

 void insertControlCharacter( [in] com::sun::star::text::XTextRange xRange,
                                    [in] short nControlCharacter, 
                                    [in] boolean bAbsorb)
More information in the Wiki, page Editing Text.
Bernard

OpenOffice.org 1.1.5 / Apache OpenOffice 4.1.1 / LibreOffice 5.0.5
MS-Windows 7 Home SP1
Quaternion
Posts: 2
Joined: Mon Feb 10, 2014 8:08 pm

Re: OOo/LibreOffice UNO-Java: Setting Styles

Post by Quaternion »

I did use that function to insert control codes earlier but your post made me revisit the idea, thank you. Java's "\n" is interpreted as a new line, while Java's "\r" is interpreted as new paragraph... which makes the code a lot lighter than the function to insert control characters.

The working version just required a couple small changes here:

Code: Select all

private void writeResume(com.sun.star.text.XText xText, com.sun.star.text.XTextCursor xTCursor) {
    TestData resume = new TestData();
    List<Company> companies = resume.getCompanies();
    //throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    this.changeStyle(xTCursor, "Heading 1");//if this line is NOT here then will default to a custom style
    xText.insertString(xTCursor, "Professional Experience\n\r", false);
    xTCursor.collapseToEnd();
    //xText.insertControlCharacter(xText, com.sun.star.text.ControlCharacter.PARAGRAPH_BREAK, false);
    this.changeStyle(xTCursor, "Heading 2");//if this line is NOT here then will default to a custom style
    Company company = companies.get(0);
    String date = dformat.format(company.getStartDate().getTime()) + " - " + dformat.format(company.getEndDate().getTime());
    xText.insertString(xTCursor, company.getName() + "," + company.getLocation() + "\t" + date + "\r", false);
    xText.insertString(xTCursor,"Title\r", false);

    this.changeStyle(xTCursor, "Heading 3");//if this line is NOT here then will default to a custom style
    xText.insertString(xTCursor, "Test Point 1\r", false);
    this.changeStyle(xTCursor, "Heading 3");
    xText.insertString(xTCursor, "Test Point 2\r", false);
    this.changeStyle(xTCursor, "Heading 3");
    xText.insertString(xTCursor, "Test Point 3\r", false);
}
Clearly this can be done better but at least I now have traction!
LibreOffice 4.1.4.2 on Ubuntu 13.10
Post Reply