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