1*b1cdbd2cSJim Jagielski /************************************************************** 2*b1cdbd2cSJim Jagielski * 3*b1cdbd2cSJim Jagielski * Licensed to the Apache Software Foundation (ASF) under one 4*b1cdbd2cSJim Jagielski * or more contributor license agreements. See the NOTICE file 5*b1cdbd2cSJim Jagielski * distributed with this work for additional information 6*b1cdbd2cSJim Jagielski * regarding copyright ownership. The ASF licenses this file 7*b1cdbd2cSJim Jagielski * to you under the Apache License, Version 2.0 (the 8*b1cdbd2cSJim Jagielski * "License"); you may not use this file except in compliance 9*b1cdbd2cSJim Jagielski * with the License. You may obtain a copy of the License at 10*b1cdbd2cSJim Jagielski * 11*b1cdbd2cSJim Jagielski * http://www.apache.org/licenses/LICENSE-2.0 12*b1cdbd2cSJim Jagielski * 13*b1cdbd2cSJim Jagielski * Unless required by applicable law or agreed to in writing, 14*b1cdbd2cSJim Jagielski * software distributed under the License is distributed on an 15*b1cdbd2cSJim Jagielski * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*b1cdbd2cSJim Jagielski * KIND, either express or implied. See the License for the 17*b1cdbd2cSJim Jagielski * specific language governing permissions and limitations 18*b1cdbd2cSJim Jagielski * under the License. 19*b1cdbd2cSJim Jagielski * 20*b1cdbd2cSJim Jagielski *************************************************************/ 21*b1cdbd2cSJim Jagielski 22*b1cdbd2cSJim Jagielski 23*b1cdbd2cSJim Jagielski import com.sun.star.uno.Type; 24*b1cdbd2cSJim Jagielski import com.sun.star.uno.UnoRuntime; 25*b1cdbd2cSJim Jagielski import com.sun.star.table.XCell; 26*b1cdbd2cSJim Jagielski import com.sun.star.util.XModifyListener; 27*b1cdbd2cSJim Jagielski import com.sun.star.beans.XPropertySet; 28*b1cdbd2cSJim Jagielski import com.sun.star.text.XTextRange; 29*b1cdbd2cSJim Jagielski import com.sun.star.form.binding.IncompatibleTypesException; 30*b1cdbd2cSJim Jagielski 31*b1cdbd2cSJim Jagielski /** a value binding to be connected to a form control 32*b1cdbd2cSJim Jagielski 33*b1cdbd2cSJim Jagielski This binding synchronizes the text contained in a table cell (which you must 34*b1cdbd2cSJim Jagielski pass upon construction) to the text in an XBindableValue. 35*b1cdbd2cSJim Jagielski 36*b1cdbd2cSJim Jagielski Well, in real it does not synchronize both directions. The ValueBinding 37*b1cdbd2cSJim Jagielski service has not much room for own activity: It allows notification of changes 38*b1cdbd2cSJim Jagielski in the own value, and it allows external instances to set the current value. 39*b1cdbd2cSJim Jagielski 40*b1cdbd2cSJim Jagielski Note that we implement this binding as a separate thread, which is (more or 41*b1cdbd2cSJim Jagielski less permanently) polling for a new text at the cell. This is unfortunate, but 42*b1cdbd2cSJim Jagielski sadly the Writer table cells do not support actively notifying changes in their 43*b1cdbd2cSJim Jagielski content to other interested parties. 44*b1cdbd2cSJim Jagielski */ 45*b1cdbd2cSJim Jagielski public class TableCellTextBinding 46*b1cdbd2cSJim Jagielski extends java.lang.Thread 47*b1cdbd2cSJim Jagielski implements com.sun.star.form.binding.XValueBinding, 48*b1cdbd2cSJim Jagielski com.sun.star.util.XModifyBroadcaster 49*b1cdbd2cSJim Jagielski { 50*b1cdbd2cSJim Jagielski private XTextRange m_cellText; 51*b1cdbd2cSJim Jagielski private Object m_writeSignal; 52*b1cdbd2cSJim Jagielski private String m_newCellText; 53*b1cdbd2cSJim Jagielski private String m_lastKnownCellText; 54*b1cdbd2cSJim Jagielski private boolean m_haveNewCellText; 55*b1cdbd2cSJim Jagielski private java.util.List m_listeners; 56*b1cdbd2cSJim Jagielski 57*b1cdbd2cSJim Jagielski /** Creates a new instance of TableCellTextBinding */ TableCellTextBinding( XCell cell )58*b1cdbd2cSJim Jagielski public TableCellTextBinding( XCell cell ) 59*b1cdbd2cSJim Jagielski { 60*b1cdbd2cSJim Jagielski m_cellText = (XTextRange)UnoRuntime.queryInterface( XTextRange.class, cell ); 61*b1cdbd2cSJim Jagielski 62*b1cdbd2cSJim Jagielski m_newCellText = new String(); 63*b1cdbd2cSJim Jagielski m_listeners = new java.util.LinkedList(); 64*b1cdbd2cSJim Jagielski 65*b1cdbd2cSJim Jagielski start(); 66*b1cdbd2cSJim Jagielski } 67*b1cdbd2cSJim Jagielski 68*b1cdbd2cSJim Jagielski /** retrieves the list of data types which this binding can exchange 69*b1cdbd2cSJim Jagielski */ getSupportedValueTypes()70*b1cdbd2cSJim Jagielski public com.sun.star.uno.Type[] getSupportedValueTypes() 71*b1cdbd2cSJim Jagielski { 72*b1cdbd2cSJim Jagielski try 73*b1cdbd2cSJim Jagielski { 74*b1cdbd2cSJim Jagielski // well, only strings here ... 75*b1cdbd2cSJim Jagielski return new Type[] { 76*b1cdbd2cSJim Jagielski getStringType() 77*b1cdbd2cSJim Jagielski }; 78*b1cdbd2cSJim Jagielski } 79*b1cdbd2cSJim Jagielski catch( java.lang.Exception e ) 80*b1cdbd2cSJim Jagielski { 81*b1cdbd2cSJim Jagielski } 82*b1cdbd2cSJim Jagielski return new Type[] { }; 83*b1cdbd2cSJim Jagielski } 84*b1cdbd2cSJim Jagielski 85*b1cdbd2cSJim Jagielski /** retrieves the current value 86*b1cdbd2cSJim Jagielski */ getValue(com.sun.star.uno.Type type)87*b1cdbd2cSJim Jagielski public Object getValue(com.sun.star.uno.Type type) throws com.sun.star.form.binding.IncompatibleTypesException 88*b1cdbd2cSJim Jagielski { 89*b1cdbd2cSJim Jagielski if ( !type.equals( getStringType() ) ) 90*b1cdbd2cSJim Jagielski throw new com.sun.star.form.binding.IncompatibleTypesException(); 91*b1cdbd2cSJim Jagielski 92*b1cdbd2cSJim Jagielski return m_cellText.getString(); 93*b1cdbd2cSJim Jagielski } 94*b1cdbd2cSJim Jagielski 95*b1cdbd2cSJim Jagielski /** sets a new value 96*b1cdbd2cSJim Jagielski */ setValue(Object obj)97*b1cdbd2cSJim Jagielski public void setValue(Object obj) throws com.sun.star.form.binding.IncompatibleTypesException 98*b1cdbd2cSJim Jagielski { 99*b1cdbd2cSJim Jagielski String text; 100*b1cdbd2cSJim Jagielski try 101*b1cdbd2cSJim Jagielski { 102*b1cdbd2cSJim Jagielski text = (String)obj; 103*b1cdbd2cSJim Jagielski } 104*b1cdbd2cSJim Jagielski catch( java.lang.ClassCastException e ) 105*b1cdbd2cSJim Jagielski { 106*b1cdbd2cSJim Jagielski throw new com.sun.star.form.binding.IncompatibleTypesException(); 107*b1cdbd2cSJim Jagielski } 108*b1cdbd2cSJim Jagielski // remember the new text 109*b1cdbd2cSJim Jagielski synchronized( m_newCellText ) 110*b1cdbd2cSJim Jagielski { 111*b1cdbd2cSJim Jagielski m_newCellText = text; 112*b1cdbd2cSJim Jagielski m_haveNewCellText = true; 113*b1cdbd2cSJim Jagielski } 114*b1cdbd2cSJim Jagielski // and wake up the thread which is waiting for it 115*b1cdbd2cSJim Jagielski synchronized( m_writeSignal ) 116*b1cdbd2cSJim Jagielski { 117*b1cdbd2cSJim Jagielski m_writeSignal.notify(); 118*b1cdbd2cSJim Jagielski } 119*b1cdbd2cSJim Jagielski } 120*b1cdbd2cSJim Jagielski 121*b1cdbd2cSJim Jagielski /** determines whether a given value type is supported 122*b1cdbd2cSJim Jagielski */ supportsType(com.sun.star.uno.Type type)123*b1cdbd2cSJim Jagielski public boolean supportsType(com.sun.star.uno.Type type) 124*b1cdbd2cSJim Jagielski { 125*b1cdbd2cSJim Jagielski return type.equals( getStringType() ); 126*b1cdbd2cSJim Jagielski } 127*b1cdbd2cSJim Jagielski 128*b1cdbd2cSJim Jagielski /** retrieves the UNO type for the string class 129*b1cdbd2cSJim Jagielski */ getStringType()130*b1cdbd2cSJim Jagielski private static final Type getStringType() 131*b1cdbd2cSJim Jagielski { 132*b1cdbd2cSJim Jagielski return new com.sun.star.uno.Type( String.class ); 133*b1cdbd2cSJim Jagielski } 134*b1cdbd2cSJim Jagielski 135*b1cdbd2cSJim Jagielski /** runs the thread 136*b1cdbd2cSJim Jagielski */ run()137*b1cdbd2cSJim Jagielski public void run() 138*b1cdbd2cSJim Jagielski { 139*b1cdbd2cSJim Jagielski try 140*b1cdbd2cSJim Jagielski { 141*b1cdbd2cSJim Jagielski m_writeSignal = new Object(); 142*b1cdbd2cSJim Jagielski while ( true ) 143*b1cdbd2cSJim Jagielski { 144*b1cdbd2cSJim Jagielski // go sleep a while 145*b1cdbd2cSJim Jagielski synchronized( m_writeSignal ) 146*b1cdbd2cSJim Jagielski { 147*b1cdbd2cSJim Jagielski m_writeSignal.wait( 200 ); 148*b1cdbd2cSJim Jagielski } 149*b1cdbd2cSJim Jagielski 150*b1cdbd2cSJim Jagielski // if there's new text in the control, propagate it to the cell 151*b1cdbd2cSJim Jagielski synchronized ( m_newCellText ) 152*b1cdbd2cSJim Jagielski { 153*b1cdbd2cSJim Jagielski if ( m_haveNewCellText ) 154*b1cdbd2cSJim Jagielski { 155*b1cdbd2cSJim Jagielski m_cellText.setString( m_newCellText ); 156*b1cdbd2cSJim Jagielski m_lastKnownCellText = m_newCellText; 157*b1cdbd2cSJim Jagielski } 158*b1cdbd2cSJim Jagielski m_haveNewCellText = false; 159*b1cdbd2cSJim Jagielski } 160*b1cdbd2cSJim Jagielski 161*b1cdbd2cSJim Jagielski // if there's new text in the cell, propagate it to the control 162*b1cdbd2cSJim Jagielski String currentCellText = m_cellText.getString(); 163*b1cdbd2cSJim Jagielski if ( !currentCellText.equals( m_lastKnownCellText ) ) 164*b1cdbd2cSJim Jagielski { 165*b1cdbd2cSJim Jagielski m_lastKnownCellText = currentCellText; 166*b1cdbd2cSJim Jagielski // notify the modification 167*b1cdbd2cSJim Jagielski synchronized( m_listeners ) 168*b1cdbd2cSJim Jagielski { 169*b1cdbd2cSJim Jagielski com.sun.star.lang.EventObject eventSource = new com.sun.star.lang.EventObject( this ); 170*b1cdbd2cSJim Jagielski 171*b1cdbd2cSJim Jagielski java.util.Iterator loop = m_listeners.iterator(); 172*b1cdbd2cSJim Jagielski while ( loop.hasNext() ) 173*b1cdbd2cSJim Jagielski { 174*b1cdbd2cSJim Jagielski ((XModifyListener)loop.next()).modified( eventSource ); 175*b1cdbd2cSJim Jagielski } 176*b1cdbd2cSJim Jagielski } 177*b1cdbd2cSJim Jagielski } 178*b1cdbd2cSJim Jagielski } 179*b1cdbd2cSJim Jagielski } 180*b1cdbd2cSJim Jagielski catch( java.lang.Exception e ) 181*b1cdbd2cSJim Jagielski { 182*b1cdbd2cSJim Jagielski e.printStackTrace(System.err); 183*b1cdbd2cSJim Jagielski } 184*b1cdbd2cSJim Jagielski } 185*b1cdbd2cSJim Jagielski addModifyListener(com.sun.star.util.XModifyListener xModifyListener)186*b1cdbd2cSJim Jagielski public void addModifyListener(com.sun.star.util.XModifyListener xModifyListener) 187*b1cdbd2cSJim Jagielski { 188*b1cdbd2cSJim Jagielski synchronized( m_listeners ) 189*b1cdbd2cSJim Jagielski { 190*b1cdbd2cSJim Jagielski m_listeners.add( xModifyListener ); 191*b1cdbd2cSJim Jagielski } 192*b1cdbd2cSJim Jagielski } 193*b1cdbd2cSJim Jagielski removeModifyListener(com.sun.star.util.XModifyListener xModifyListener)194*b1cdbd2cSJim Jagielski public void removeModifyListener(com.sun.star.util.XModifyListener xModifyListener) 195*b1cdbd2cSJim Jagielski { 196*b1cdbd2cSJim Jagielski synchronized( m_listeners ) 197*b1cdbd2cSJim Jagielski { 198*b1cdbd2cSJim Jagielski m_listeners.remove( xModifyListener ); 199*b1cdbd2cSJim Jagielski } 200*b1cdbd2cSJim Jagielski } 201*b1cdbd2cSJim Jagielski disposing(com.sun.star.lang.EventObject eventObject)202*b1cdbd2cSJim Jagielski public void disposing(com.sun.star.lang.EventObject eventObject) 203*b1cdbd2cSJim Jagielski { 204*b1cdbd2cSJim Jagielski // not interested in 205*b1cdbd2cSJim Jagielski } 206*b1cdbd2cSJim Jagielski } 207