[Solved] Java Netbeans add-on Writer - get current document

Discussions about using 3rd party extension with OpenOffice.org
Post Reply
johnrdorazio
Posts: 35
Joined: Sun Aug 17, 2014 2:04 pm
Location: Italy

[Solved] Java Netbeans add-on Writer - get current document

Post by johnrdorazio »

I downloaded the SDK and I installed the plugin for Netbeans 8.0.
I created a project of type "Add-on for Apache OpenOffice", with some menu items contextualized in Office Writer.
Now I would like to know how to get a reference to the Current Document from the class of the add-on.
It would be useful to have an example of code for this, it's pretty much impossible to find examples at least for the new API anyways.

In the "dispatch" method that is automatically created in my project class, I can intercept the clicks on the menu items, but then I'm not sure how to get a reference to the current active document.

I'm finding some examples that use XScriptContext, but I have the impression that the new SDK / API doesn't use XSCriptContext but rather XComponentContext...

From the examples that I have seen, I believe I'm supposed to use UnoRuntime.queryInterface(), but I don't know how to do this with XComponentContext.

Well here's the code that is automatically created by the Add-on project wizard, where you see the comment "//Now how do I get a reference to the active document?" I would like to start interacting with the current document (inserting paragraphs, inserting text, etc.):

Code: Select all

package com.example;

import com.sun.star.lang.XSingleComponentFactory;
import com.sun.star.lib.uno.helper.Factory;
import com.sun.star.lib.uno.helper.WeakBase;
import com.sun.star.registry.XRegistryKey;
import com.sun.star.uno.UnoRuntime;
import com.sun.star.uno.XComponentContext;

public final class BibleGetIO extends WeakBase
        implements com.sun.star.frame.XDispatchProvider,
        com.sun.star.frame.XDispatch,
        com.sun.star.lang.XServiceInfo,
        com.sun.star.lang.XInitialization {

    private final XComponentContext m_xContext;
    private com.sun.star.frame.XFrame m_xFrame;
    private static final String m_implementationName = BibleGetIO.class.getName();
    private static final String[] m_serviceNames = {"com.sun.star.frame.ProtocolHandler"};

    public BibleGetIO(XComponentContext context) {
        m_xContext = context;
    };

    public static XSingleComponentFactory __getComponentFactory(String sImplementationName) {
        XSingleComponentFactory xFactory = null;

        if (sImplementationName.equals(m_implementationName)) {
            xFactory = Factory.createComponentFactory(BibleGetIO.class, m_serviceNames);
        }
        return xFactory;
    }

    public static boolean __writeRegistryServiceInfo(XRegistryKey xRegistryKey) {
        return Factory.writeRegistryServiceInfo(m_implementationName,
                m_serviceNames,
                xRegistryKey);
    }

    // com.sun.star.frame.XDispatchProvider:
    public com.sun.star.frame.XDispatch queryDispatch(com.sun.star.util.URL aURL,
            String sTargetFrameName,
            int iSearchFlags) {
        if (aURL.Protocol.compareTo("de.bibleget.biblegetio:") == 0) {
            if (aURL.Path.compareTo("CitazioneDaInput") == 0) {
                return this;
            }
        }
        return null;
    }

    // com.sun.star.frame.XDispatchProvider:
    public com.sun.star.frame.XDispatch[] queryDispatches(
            com.sun.star.frame.DispatchDescriptor[] seqDescriptors) {
        int nCount = seqDescriptors.length;
        com.sun.star.frame.XDispatch[] seqDispatcher
                = new com.sun.star.frame.XDispatch[seqDescriptors.length];

        for (int i = 0; i < nCount; ++i) {
            seqDispatcher[i] = queryDispatch(seqDescriptors[i].FeatureURL,
                    seqDescriptors[i].FrameName,
                    seqDescriptors[i].SearchFlags);
        }
        return seqDispatcher;
    }

   public void dispatch(com.sun.star.util.URL aURL,
            com.sun.star.beans.PropertyValue[] aArguments) {
        if (aURL.Protocol.compareTo("com.example.biblegetio:") == 0) {
            if (aURL.Path.compareTo("QuotationFromInput") == 0) {
                // add your own code here
                System.out.println("You clicked on menu item QuotationFromInput");

                //Now how do I get a reference to the active document?

                return;
            }
         }
    }

    public void addStatusListener(com.sun.star.frame.XStatusListener xControl,
            com.sun.star.util.URL aURL) {
        // add your own code here
    }

    public void removeStatusListener(com.sun.star.frame.XStatusListener xControl,
            com.sun.star.util.URL aURL) {
        // add your own code here
    }

    // com.sun.star.lang.XServiceInfo:
    public String getImplementationName() {
        return m_implementationName;
    }

    public boolean supportsService(String sService) {
        int len = m_serviceNames.length;

        for (int i = 0; i < len; i++) {
            if (sService.equals(m_serviceNames[i])) {
                return true;
            }
        }
        return false;
    }

    public String[] getSupportedServiceNames() {
        return m_serviceNames;
    }

    // com.sun.star.lang.XInitialization:
    public void initialize(Object[] object)
            throws com.sun.star.uno.Exception {
        if (object.length > 0) {
            m_xFrame = (com.sun.star.frame.XFrame) UnoRuntime.queryInterface(
                    com.sun.star.frame.XFrame.class, object[0]);
        }
    }

}
Last edited by johnrdorazio on Sun Sep 21, 2014 11:31 am, edited 1 time in total.
OpenOffice 4.1.6, NetBeans 8.1, Windows 10 x64 Home
hanya
Volunteer
Posts: 885
Joined: Fri Nov 23, 2007 9:27 am
Location: Japan

Re: java netbeans add-in for Writer: get current document

Post by hanya »

In "initialize" method, m_xFrame variable is set and it is the frame object that the document bound to and your dispatch provider is also bound to the frame. So you can use it to get access to the document something like the following:

Code: Select all

com.sun.star.frame.XController xController = m_xFrame.getController();
if (xController != null) {
  com.sun.star.frame.XModel xModel = xController.getModel();
}
Please, edit this thread's initial post and add "[Solved]" to the subject line if your problem has been solved.
Apache OpenOffice 4-dev on Xubuntu 14.04
johnrdorazio
Posts: 35
Joined: Sun Aug 17, 2014 2:04 pm
Location: Italy

Re: java netbeans add-in for Writer: get current document

Post by johnrdorazio »

So to get the current active document in Writer, it should be something like this? (Supposing I have declared m_xTextDocument already.)

Code: Select all

    // com.sun.star.lang.XInitialization:
    public void initialize(Object[] object)
            throws com.sun.star.uno.Exception {
        if (object.length > 0) {
            m_xFrame = (com.sun.star.frame.XFrame) UnoRuntime.queryInterface(
                    com.sun.star.frame.XFrame.class, object[0]);
            com.sun.star.frame.XController xController = m_xFrame.getController();
            if (xController != null) {
                //m_xModel = (com.sun.star.frame.XModel) xController.getModel();
                m_xTextDocument = (com.sun.star.text.XTextDocument) UnoRuntime.queryInterface(XTextDocument.class,xController);
            }
        }
    }
I can see that I'm this close to getting a reference to the active document, but I'm still missing one piece somewhere I think... Because if I try :

Code: Select all

m_xTextDocument.getText();
I get a runtime error of non-uno object or something along those lines.
OpenOffice 4.1.6, NetBeans 8.1, Windows 10 x64 Home
hanya
Volunteer
Posts: 885
Joined: Fri Nov 23, 2007 9:27 am
Location: Japan

Re: java netbeans add-in for Writer: get current document

Post by hanya »

XTextDocument interface is implemented by the same instance of the document model.

Code: Select all

m_xTextDocument = (com.sun.star.text.XTextDocument) UnoRuntime.queryInterface(XTextDocument.class,xController.getModel());
Try MRI introspection tool to get sequence of query interfaces in Java: viewtopic.php?f=74&t=49294
Please, edit this thread's initial post and add "[Solved]" to the subject line if your problem has been solved.
Apache OpenOffice 4-dev on Xubuntu 14.04
johnrdorazio
Posts: 35
Joined: Sun Aug 17, 2014 2:04 pm
Location: Italy

Re: java netbeans add-in for Writer: get current document

Post by johnrdorazio »

Yes thank you I had just tried that and was now successful:

Code: Select all

            if (xController != null) {
                m_xModel = (com.sun.star.frame.XModel) xController.getModel();
                m_xTextDocument = (com.sun.star.text.XTextDocument) UnoRuntime.queryInterface(XTextDocument.class,m_xModel);
            }
Now when I call m_xTextDocument.getText() I no longer get an error, and if I System.out.println(m_xTextDocument.getText().getString()) I successfully see the string contents of the document.

I'll take a look at the MRI tool, thank you for the link.
OpenOffice 4.1.6, NetBeans 8.1, Windows 10 x64 Home
hanya
Volunteer
Posts: 885
Joined: Fri Nov 23, 2007 9:27 am
Location: Japan

Re: [Solved] Java Netbeans add-on Writer - get current docum

Post by hanya »

As a note, avoid to query some interfaces from queried interface. Use the original value as query base. In this case, "m_xModel" variable keeps the original value taken from the controller and use it as query base for required interfaces that you want to access. If you not, you may get null value as an invalid reference.
Please, edit this thread's initial post and add "[Solved]" to the subject line if your problem has been solved.
Apache OpenOffice 4-dev on Xubuntu 14.04
Post Reply