package noncommit.clipboard; import java.util.HashSet; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue; import com.sun.star.comp.helper.Bootstrap; import com.sun.star.comp.helper.BootstrapException; import com.sun.star.container.XIndexAccess; import com.sun.star.frame.XComponentLoader; import com.sun.star.frame.XController; import com.sun.star.frame.XDesktop; import com.sun.star.frame.XFrame; import com.sun.star.frame.XFrames; import com.sun.star.frame.XFramesSupplier; import com.sun.star.lang.EventObject; import com.sun.star.lang.XMultiComponentFactory; import com.sun.star.lang.XServiceInfo; import com.sun.star.text.XTextRange; import com.sun.star.uno.Exception; import com.sun.star.uno.UnoRuntime; import com.sun.star.uno.XComponentContext; import com.sun.star.view.XSelectionChangeListener; import com.sun.star.view.XSelectionSupplier; /** * Selection listener test */ public class OpenOfficeLink implements XSelectionChangeListener { /** * Static OpenOfficeLink instance */ static OpenOfficeLink openOfficeLink; /** * OpenOffice selection suppliers */ private HashSet selectionSupplierSet = null; /** * Communication queue to allow selection processing to happen outside the OpenOffice callback thread */ private BlockingQueue selectionQueue = null; /** * Thread that watches for new OpenOffice frames and attaches selection change listeners to them. * We'd like to do this with callbacks rather than polling but can't currently get that to work */ private class FramesWatcher extends Thread { /** * OpenOffice frames supplier. Allows iteration over currently existing frames (windows) */ XFramesSupplier framesSupplier; /* (non-Javadoc) * @see java.lang.Thread#run() */ public void run() { while (true) { XFrames xFrames = this.framesSupplier.getFrames(); XIndexAccess xAcc = (XIndexAccess) UnoRuntime.queryInterface (XIndexAccess.class, xFrames); for (int i = 0; i < xAcc.getCount(); i++) { XFrame frame; try { frame = (XFrame) UnoRuntime.queryInterface (XFrame.class, xAcc.getByIndex (i)); XSelectionSupplier xSelSupp = (XSelectionSupplier) UnoRuntime.queryInterface (XSelectionSupplier.class, frame.getController()); if (!OpenOfficeLink.this.selectionSupplierSet.contains (xSelSupp)) { OpenOfficeLink.this.selectionSupplierSet.add (xSelSupp); xSelSupp.addSelectionChangeListener (OpenOfficeLink.this); } } catch (Exception e) { e.printStackTrace(); } } try { Thread.sleep (1000); } catch (InterruptedException e) { // do nothing } } } /** * @param framesSupplier The OpenOffice frames supplier */ public FramesWatcher (XFramesSupplier framesSupplier) { this.framesSupplier = framesSupplier; } } /** * Watches for OpenOffice selection changes */ private class SelectionWatcher extends Thread { /* (non-Javadoc) * @see java.lang.Thread#run() */ public void run() { while (true) { try { Object selection = OpenOfficeLink.this.selectionQueue.take(); String selectedString = getSelectionString (selection); System.out.println ("Selected: " + selectedString); } catch (InterruptedException e) { // nothing } } } } /** * Default constructor */ public OpenOfficeLink() { this.selectionSupplierSet = new HashSet(); this.selectionQueue = new ArrayBlockingQueue(10); try { // bootstrap UNO and retrieve OOo desktop XComponentContext xContext = Bootstrap.bootstrap(); XMultiComponentFactory xMCF = xContext.getServiceManager(); XDesktop xDesktop = (XDesktop) UnoRuntime.queryInterface( XDesktop.class, xMCF.createInstanceWithContext ("com.sun.star.frame.Desktop", xContext) ); XComponentLoader componentLoader = (XComponentLoader) UnoRuntime.queryInterface (XComponentLoader.class, xDesktop); XFramesSupplier framesSupplier = (XFramesSupplier) UnoRuntime.queryInterface (XFramesSupplier.class, componentLoader); // Open a new text document window componentLoader.loadComponentFromURL ("private:factory/swriter", "_blank", 0, new com.sun.star.beans.PropertyValue[0]); // Watch for new Frames and attach selection listeners new FramesWatcher(framesSupplier).start(); // Watch for selections new SelectionWatcher().start(); } catch (Exception e) { e.printStackTrace(); System.exit(1); } catch (BootstrapException e) { e.printStackTrace(); System.exit(1); } } /** * Gets the text of an OpenOffice selection * * @param selection The OpenOffice selection object * @return The selection text as a String */ public static String getSelectionString (Object selection) { String selectionString = ""; try { XServiceInfo xServInfo = (XServiceInfo) UnoRuntime.queryInterface (XServiceInfo.class, selection); if (xServInfo.supportsService ("com.sun.star.text.TextRanges")) { XIndexAccess xIndexAccess = (XIndexAccess) UnoRuntime.queryInterface (XIndexAccess.class, selection); int count = xIndexAccess.getCount(); XTextRange xTextRange = null; for (int j = 0; j < count; j++) { xTextRange = (XTextRange) UnoRuntime.queryInterface (XTextRange.class, xIndexAccess.getByIndex (j)); selectionString += xTextRange.getString(); } } } catch (Exception e) { e.printStackTrace(); } return selectionString; } /* XSelectionChangeListener interface */ /* (non-Javadoc) * @see com.sun.star.view.XSelectionChangeListener#selectionChanged(com.sun.star.lang.EventObject) */ public void selectionChanged (EventObject event) { XController controller = (XController) UnoRuntime.queryInterface (XController.class, event.Source); if (controller != null) { XSelectionSupplier selectionSupplier = (XSelectionSupplier) UnoRuntime.queryInterface (XSelectionSupplier.class, controller); if (selectionSupplier != null) { this.selectionQueue.clear(); try { this.selectionQueue.put (selectionSupplier.getSelection()); } catch (InterruptedException e) { e.printStackTrace(); } } } } /* (non-Javadoc) * @see com.sun.star.lang.XEventListener#disposing(com.sun.star.lang.EventObject) */ public void disposing (EventObject event) { XSelectionSupplier selectionSupplier = (XSelectionSupplier) UnoRuntime.queryInterface (XSelectionSupplier.class, event); if (selectionSupplier != null) { this.selectionSupplierSet.remove (selectionSupplier); selectionSupplier.removeSelectionChangeListener (this); } } /** * Main method * * @param args Ignored */ public static void main (String args[]) { openOfficeLink = new OpenOfficeLink(); } }