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