/*************************************************************************
*
* $RCSfile: OfficeWriter.java,v $
*
* $Revision: 1.3 $
*
* last change: $Author: hr $ $Date: 2003/06/30 15:30:33 $
*
* The Contents of this file are made available subject to the terms of
* the BSD license.
*
* Copyright (c) 2003 by Sun Microsystems, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Sun Microsystems, Inc. nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*************************************************************************/
import java.awt.*;
import java.awt.event.*;
import javax.swing.event.*;
import java.util.Vector;
import com.sun.star.uno.XInterface;
import com.sun.star.uno.UnoRuntime;
import com.sun.star.container.XIndexAccess;
import com.sun.star.text.XText;
import com.sun.star.text.XTextDocument;
import com.sun.star.text.XTextRange;
import com.sun.star.text.XTextCursor;
import com.sun.star.frame.XFrame;
import com.sun.star.frame.XModel;
import com.sun.star.view.XSelectionSupplier;
import com.sun.star.view.XSelectionChangeListener;
/** Implementation of the Office Writer Component as a Java Bean.
*
* The OfficeWriter provides methods for getting and setting the
* contents of an embedded Office Writer document and also for adding a
* listener for changes in the current selection in the document.
*/
public class OfficeWriter extends Office
{
public static final String NEW_DOCUMENT = "private:factory/swriter";
private transient XSelectionChangeListener mXSelectionChangeListener = null;
private transient EventListenerList mSelectionChangeListenerList = null;
/** Method to get the complete text of the current OfficeWriter document.
*
* @return the complete text of the current OfficeWriter document
*/
public String getString()
{
XText xText = getXText();
String sText = "";
if (xText != null) {
XTextCursor xTextCursor = xText.createTextCursor();
xTextCursor.gotoStart(false);
xTextCursor.gotoEnd(true);
sText = xTextCursor.getString();
}
return sText;
}
/** Method to replace the complete text of the OfficeWriter document.
*
* @param s the new text
*/
public void setString(String s)
{
XText xText = getXText();
if (xText != null) {
XTextCursor xTextCursor = xText.createTextCursor();
xTextCursor.gotoStart(false);
xTextCursor.gotoEnd(true);
xTextCursor.setString(s);
}
}
/** Method to get the XTextDocument interface.
*
* @return the XTextDocument interface of the current document
*
*/
public XTextDocument getTextDocument()
{
XTextDocument xTextDocument = null;
XModel xModel = null;
if ((getFrame() != null) && (getFrame().getController() != null))
xModel = getFrame().getController().getModel();
if (xModel != null) {
xTextDocument = (XTextDocument) UnoRuntime.queryInterface(
XTextDocument.class, xModel);
}
return xTextDocument;
}
/** Method which gets the text currently selected in the Writer document
*
* @return the currently selected text as a String
*/
public String getSelection()
{
XTextRange xTextRange = null;
String s = "";
try {
xTextRange = queryCurrentPosition();
if (xTextRange != null)
s = xTextRange.getString();
}
catch (Exception e) {
e.printStackTrace();
}
return s;
}
/** Adds a ChangeListener, event is fired when the text selection changes
*
* @param l ChangeListener to be added
*/
public void addSelectionChangeListener(ChangeListener l)
{
if (mSelectionChangeListenerList == null)
mSelectionChangeListenerList = new EventListenerList();
mSelectionChangeListenerList.add(ChangeListener.class , l);
if (mXSelectionChangeListener == null)
postInitListenersEvent();
}
/** Removes a previously added ChangeListener
*
* @param l ChangeListener to be removed
*/
public void removeSelectionChangeListener(ChangeListener l)
{
if (mSelectionChangeListenerList == null)
return;
mSelectionChangeListenerList.remove(ChangeListener.class, l);
if (mSelectionChangeListenerList.getListenerCount() == 0)
{
removeXSelectionChangeListener();
mSelectionChangeListenerList = null;
}
}
/**
* Loads a document referenced by a URL.
*
* @param url The document's URL string.
* @exception java.io.IOException if the document loading process has
* failed.
*/
public synchronized void load(String url)
throws java.io.IOException
{
// remove XSelectionChangeListener for previous document
removeXSelectionChangeListener();
// now call parent load method
super.load(url);
// and queue a call to add a XSelectionChangeListener to the new document
postInitListenersEvent();
}
/** Bean is always focusTraversable
*
* @return boolean, always true as the bean is focusTraversable
*/
public boolean isFocusTraversable()
{
return true;
}
/* Get the XText interface of the current document */
private XText getXText()
{
XTextDocument xTextDocument = getTextDocument();
XText xText = null;
if (xTextDocument != null) {
xText = (XText) xTextDocument.getText();
}
return xText;
}
/** Returns the first selected TextRange in the TextDocument,
* or the cursor position if no text position is selected.
*
* @return current cursor position
* @throws Exception element could not be retrieved
*/
private XTextRange queryCurrentPosition()
throws java.lang.Exception
{
XTextRange xTextRange = null;
try {
XIndexAccess xIndexAccess = getSelectionIndex();
if(xIndexAccess != null) {
XInterface xInterfaceText = (XInterface)UnoRuntime.queryInterface(
XInterface.class, xIndexAccess.getByIndex((int)0));
xTextRange = (XTextRange)UnoRuntime.queryInterface(
XTextRange.class, xInterfaceText);
}
}
catch( java.lang.Exception e ) {
e.printStackTrace(System.err);
}
return xTextRange;
}
/** Returns a container of all selected text positions in the document,
* at least the current cursor position
*
* @return Indexed Access to container
* @throws Exception No SelectionSupplier available
*/
private XIndexAccess getSelectionIndex()
throws java.lang.Exception
{
XIndexAccess xIndexAccess = null;
XSelectionSupplier xSelectionSupplier = getSelectionSupplier();
if (xSelectionSupplier == null)
throw new Exception("queryCurrentPosition: xSelectionSupplier == null");
try {
XInterface xInterface = (XInterface) UnoRuntime.queryInterface(
XInterface.class,xSelectionSupplier.getSelection());
xIndexAccess = (XIndexAccess)UnoRuntime.queryInterface(
XIndexAccess.class,xInterface);
}
catch( java.lang.Exception e ) {
e.printStackTrace(System.err);
}
return xIndexAccess;
}
/** Fires StateChanged Event to Listeners
*
* @param event StateChanged event
*/
private void fireStateChangedEvent(EventListenerList list, ChangeEvent event)
{
Object listenerList[] = list.getListenerList();
for (int i = listenerList.length - 2; i >= 0; i -= 2) {
if (listenerList[i] == ChangeListener.class) {
((ChangeListener) listenerList[i+1]).stateChanged(event);
}
}
}
private void postInitListenersEvent()
{
EventQueue eq = java.awt.Toolkit.getDefaultToolkit().getSystemEventQueue();
eq.postEvent(new AddSelectionChangeEvent(this, AWTEvent.RESERVED_ID_MAX+1));
}
/** Creates an XSelectionChangeListener and adds it to the active document
*/
private void initListeners()
{
XSelectionSupplier xSelectionSupplier = null;
if (getFrame() == null) return;
if (mXSelectionChangeListener == null) {
try {
mXSelectionChangeListener = new CSelectionChangeListener();
getSelectionSupplier().addSelectionChangeListener(
mXSelectionChangeListener);
}
catch (Exception e) {
mXSelectionChangeListener = null;
e.printStackTrace(System.err);
}
}
}
private void removeXSelectionChangeListener()
{
if (mXSelectionChangeListener != null) {
try {
getSelectionSupplier().removeSelectionChangeListener(
mXSelectionChangeListener);
mXSelectionChangeListener.disposing(null);
mXSelectionChangeListener = null;
}
catch (java.lang.Exception e) {
e.printStackTrace(System.err);
}
}
}
/**
* Closes the connection.
*/
public synchronized void closeConnection()
{
removeXSelectionChangeListener();
super.closeConnection();
}
/** Inner Class implements java.awt.ActiveEvent
* creates API SelectionChangeListener
*/
private class AddSelectionChangeEvent extends AWTEvent implements ActiveEvent
{
/** Constructor of inner class
* @param source event source
* @param id event id
*/
public AddSelectionChangeEvent(Object source, int id)
{
super (source, id);
}
/** Creates a Listener */
public void dispatch ()
{
initListeners();
}
}
private class CSelectionChangeListener implements XSelectionChangeListener
{
/** Listener is about to be destroyed
* @param aEvent Event
*/
public void disposing(com.sun.star.lang.EventObject o)
{
}
/** SelectionChanged
* @param aEvent Event
*/
public void selectionChanged(com.sun.star.lang.EventObject o)
{
fireStateChangedEvent(mSelectionChangeListenerList, new ChangeEvent(o));
}
}
}