| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| import com.sun.star.uno.Type; |
| import com.sun.star.uno.UnoRuntime; |
| import com.sun.star.table.XCell; |
| import com.sun.star.util.XModifyListener; |
| import com.sun.star.beans.XPropertySet; |
| import com.sun.star.text.XTextRange; |
| import com.sun.star.form.binding.IncompatibleTypesException; |
| |
| /** a value binding to be connected to a form control |
| |
| This binding synchronizes the text contained in a table cell (which you must |
| pass upon construction) to the text in an XBindableValue. |
| |
| Well, in real it does not synchronize both directions. The ValueBinding |
| service has not much room for own activity: It allows notification of changes |
| in the own value, and it allows external instances to set the current value. |
| |
| Note that we implement this binding as a separate thread, which is (more or |
| less permanently) polling for a new text at the cell. This is unfortunate, but |
| sadly the Writer table cells do not support actively notifying changes in their |
| content to other interested parties. |
| */ |
| public class TableCellTextBinding |
| extends java.lang.Thread |
| implements com.sun.star.form.binding.XValueBinding, |
| com.sun.star.util.XModifyBroadcaster |
| { |
| private XTextRange m_cellText; |
| private Object m_writeSignal; |
| private String m_newCellText; |
| private String m_lastKnownCellText; |
| private boolean m_haveNewCellText; |
| private java.util.List m_listeners; |
| |
| /** Creates a new instance of TableCellTextBinding */ |
| public TableCellTextBinding( XCell cell ) |
| { |
| m_cellText = (XTextRange)UnoRuntime.queryInterface( XTextRange.class, cell ); |
| |
| m_newCellText = new String(); |
| m_listeners = new java.util.LinkedList(); |
| |
| start(); |
| } |
| |
| /** retrieves the list of data types which this binding can exchange |
| */ |
| public com.sun.star.uno.Type[] getSupportedValueTypes() |
| { |
| try |
| { |
| // well, only strings here ... |
| return new Type[] { |
| getStringType() |
| }; |
| } |
| catch( java.lang.Exception e ) |
| { |
| } |
| return new Type[] { }; |
| } |
| |
| /** retrieves the current value |
| */ |
| public Object getValue(com.sun.star.uno.Type type) throws com.sun.star.form.binding.IncompatibleTypesException |
| { |
| if ( !type.equals( getStringType() ) ) |
| throw new com.sun.star.form.binding.IncompatibleTypesException(); |
| |
| return m_cellText.getString(); |
| } |
| |
| /** sets a new value |
| */ |
| public void setValue(Object obj) throws com.sun.star.form.binding.IncompatibleTypesException |
| { |
| String text; |
| try |
| { |
| text = (String)obj; |
| } |
| catch( java.lang.ClassCastException e ) |
| { |
| throw new com.sun.star.form.binding.IncompatibleTypesException(); |
| } |
| // remember the new text |
| synchronized( m_newCellText ) |
| { |
| m_newCellText = text; |
| m_haveNewCellText = true; |
| } |
| // and wake up the thread which is waiting for it |
| synchronized( m_writeSignal ) |
| { |
| m_writeSignal.notify(); |
| } |
| } |
| |
| /** determines whether a given value type is supported |
| */ |
| public boolean supportsType(com.sun.star.uno.Type type) |
| { |
| return type.equals( getStringType() ); |
| } |
| |
| /** retrieves the UNO type for the string class |
| */ |
| private static final Type getStringType() |
| { |
| return new com.sun.star.uno.Type( String.class ); |
| } |
| |
| /** runs the thread |
| */ |
| public void run() |
| { |
| try |
| { |
| m_writeSignal = new Object(); |
| while ( true ) |
| { |
| // go sleep a while |
| synchronized( m_writeSignal ) |
| { |
| m_writeSignal.wait( 200 ); |
| } |
| |
| // if there's new text in the control, propagate it to the cell |
| synchronized ( m_newCellText ) |
| { |
| if ( m_haveNewCellText ) |
| { |
| m_cellText.setString( m_newCellText ); |
| m_lastKnownCellText = m_newCellText; |
| } |
| m_haveNewCellText = false; |
| } |
| |
| // if there's new text in the cell, propagate it to the control |
| String currentCellText = m_cellText.getString(); |
| if ( !currentCellText.equals( m_lastKnownCellText ) ) |
| { |
| m_lastKnownCellText = currentCellText; |
| // notify the modification |
| synchronized( m_listeners ) |
| { |
| com.sun.star.lang.EventObject eventSource = new com.sun.star.lang.EventObject( this ); |
| |
| java.util.Iterator loop = m_listeners.iterator(); |
| while ( loop.hasNext() ) |
| { |
| ((XModifyListener)loop.next()).modified( eventSource ); |
| } |
| } |
| } |
| } |
| } |
| catch( java.lang.Exception e ) |
| { |
| e.printStackTrace(System.err); |
| } |
| } |
| |
| public void addModifyListener(com.sun.star.util.XModifyListener xModifyListener) |
| { |
| synchronized( m_listeners ) |
| { |
| m_listeners.add( xModifyListener ); |
| } |
| } |
| |
| public void removeModifyListener(com.sun.star.util.XModifyListener xModifyListener) |
| { |
| synchronized( m_listeners ) |
| { |
| m_listeners.remove( xModifyListener ); |
| } |
| } |
| |
| public void disposing(com.sun.star.lang.EventObject eventObject) |
| { |
| // not interested in |
| } |
| } |