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