1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_accessibility.hxx"
26 
27 #include "accessibility/extended/AccessibleGridControlTableCell.hxx"
28 #include <svtools/accessibletable.hxx>
29 #include "accessibility/extended/AccessibleGridControl.hxx"
30 #include <tools/gen.hxx>
31 #include <toolkit/helper/vclunohelper.hxx>
32 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
33 
34 namespace accessibility
35 {
36 	namespace
37 	{
38 		void checkIndex_Impl( sal_Int32 _nIndex, const ::rtl::OUString& _sText ) throw (::com::sun::star::lang::IndexOutOfBoundsException)
39 		{
40 			if ( _nIndex >= _sText.getLength() )
41 				throw ::com::sun::star::lang::IndexOutOfBoundsException();
42 		}
43 
44 		sal_Int32 getIndex_Impl( sal_Int32 _nRow, sal_uInt16 _nColumn, sal_uInt16 _nColumnCount )
45 		{
46 			return _nRow * _nColumnCount + _nColumn;
47 		}
48 	}
49 	using namespace ::com::sun::star::lang;
50 	using namespace utl;
51 	using namespace comphelper;
52 	using ::rtl::OUString;
53 	using ::accessibility::AccessibleGridControl;
54 	using namespace ::com::sun::star::uno;
55 	using ::com::sun::star::accessibility::XAccessible;
56 	using namespace ::com::sun::star::accessibility;
57 	using namespace ::svt;
58 	using namespace ::svt::table;
59 
60 
61 	// =============================================================================
62 	// = AccessibleGridControlCell
63 	// =============================================================================
64 	// -----------------------------------------------------------------------------
65 	AccessibleGridControlCell::AccessibleGridControlCell(
66 			const Reference< XAccessible >& _rxParent, IAccessibleTable& _rTable,
67             sal_Int32 _nRowPos, sal_uInt16 _nColPos, AccessibleTableControlObjType _eType )
68         :AccessibleGridControlBase( _rxParent, _rTable, _eType )
69 		,m_nRowPos( _nRowPos )
70 		,m_nColPos( _nColPos )
71 	{
72 		// set accessible name here, because for that we need the position of the cell
73 		// and so the base class isn't capable of doing this
74 		::rtl::OUString aAccName;
75 		if(_eType == TCTYPE_TABLECELL)
76 			aAccName = _rTable.GetAccessibleObjectName( TCTYPE_TABLECELL, _nRowPos, _nColPos );
77 		else if(_eType == TCTYPE_ROWHEADERCELL)
78 			aAccName = _rTable.GetAccessibleObjectName( TCTYPE_ROWHEADERCELL, _nRowPos, 0 );
79 		else if(_eType == TCTYPE_COLUMNHEADERCELL)
80 			aAccName = _rTable.GetAccessibleObjectName( TCTYPE_COLUMNHEADERCELL, 0, _nRowPos );
81 		implSetName( aAccName );
82 	}
83 
84 	// -----------------------------------------------------------------------------
85 	AccessibleGridControlCell::~AccessibleGridControlCell()
86 	{
87 	}
88 
89 	// -----------------------------------------------------------------------------
90 	void SAL_CALL AccessibleGridControlCell::grabFocus() throw ( RuntimeException )
91 	{
92 		TCSolarGuard aSolarGuard;
93 		::osl::MutexGuard aGuard( getOslMutex() );
94 		m_aTable.GoToCell( m_nColPos, m_nRowPos );
95 	}
96 	//// -----------------------------------------------------------------------------
97 	// implementation of a table cell
98 	::rtl::OUString AccessibleGridControlTableCell::implGetText()
99 	{
100 		ensureIsAlive();
101 		return m_aTable.GetAccessibleCellText( getRowPos(),  getColumnPos() );
102 	}
103 
104 	::com::sun::star::lang::Locale AccessibleGridControlTableCell::implGetLocale()
105 	{
106 		ensureIsAlive();
107 		return m_aTable.GetAccessible()->getAccessibleContext()->getLocale();
108 	}
109 
110 	void AccessibleGridControlTableCell::implGetSelection( sal_Int32& nStartIndex, sal_Int32& nEndIndex )
111 	{
112 		nStartIndex = 0;
113 		nEndIndex = 0;
114 	}
115 
116 	AccessibleGridControlTableCell::AccessibleGridControlTableCell(const Reference<XAccessible >& _rxParent,
117 								IAccessibleTable& _rTable,
118 								sal_Int32 _nRowPos,
119 								sal_uInt16 _nColPos,
120 								AccessibleTableControlObjType  eObjType)
121 		:AccessibleGridControlCell( _rxParent, _rTable, _nRowPos, _nColPos, eObjType )
122 	{
123 	}
124 
125 	// XInterface -------------------------------------------------------------
126 
127 	/** Queries for a new interface. */
128 	::com::sun::star::uno::Any SAL_CALL AccessibleGridControlTableCell::queryInterface(
129 			const ::com::sun::star::uno::Type& rType )
130 		throw ( ::com::sun::star::uno::RuntimeException )
131 	{
132 		Any aRet = AccessibleGridControlCell::queryInterface(rType);
133 		if ( !aRet.hasValue() )
134 			aRet = AccessibleTextHelper_BASE::queryInterface(rType);
135 		return aRet;
136 	}
137 
138 	/** Aquires the object (calls acquire() on base class). */
139 	void SAL_CALL AccessibleGridControlTableCell::acquire() throw ()
140 	{
141 		AccessibleGridControlCell::acquire();
142 	}
143 
144 	/** Releases the object (calls release() on base class). */
145 	void SAL_CALL AccessibleGridControlTableCell::release() throw ()
146 	{
147 		AccessibleGridControlCell::release();
148 	}
149 
150 	::com::sun::star::awt::Rectangle SAL_CALL AccessibleGridControlTableCell::getCharacterBounds( sal_Int32 nIndex ) throw (IndexOutOfBoundsException, RuntimeException)
151 	{
152 		TCSolarGuard aSolarGuard;
153 		::osl::MutexGuard aGuard( getOslMutex() );
154 
155 		ensureIsAlive();
156 		if ( !implIsValidIndex( nIndex, implGetText().getLength() ) )
157 			throw IndexOutOfBoundsException();
158 
159 		::com::sun::star::awt::Rectangle aRect;
160 
161 		if ( &m_aTable )
162 			aRect = AWTRectangle( m_aTable.GetFieldCharacterBounds( getRowPos(), getColumnPos(), nIndex ) );
163 		return aRect;
164 	}
165 
166 	sal_Int32 SAL_CALL AccessibleGridControlTableCell::getIndexAtPoint( const ::com::sun::star::awt::Point& _aPoint ) throw (RuntimeException)
167 	{
168 		TCSolarGuard aSolarGuard;
169 		::osl::MutexGuard aGuard( getOslMutex() );
170 		ensureIsAlive();
171 
172 		return m_aTable.GetFieldIndexAtPoint( getRowPos(), getColumnPos(), VCLPoint( _aPoint ) );
173 	}
174 
175 	/** @return
176 			The name of this class.
177 	*/
178 	::rtl::OUString SAL_CALL AccessibleGridControlTableCell::getImplementationName()
179 		throw ( ::com::sun::star::uno::RuntimeException )
180 	{
181 		return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.accessibility.AccessibleGridControlTableCell" ) );
182 	}
183 
184 	/** @return  The count of visible children. */
185 	sal_Int32 SAL_CALL AccessibleGridControlTableCell::getAccessibleChildCount()
186 		throw ( ::com::sun::star::uno::RuntimeException )
187 	{
188 		return 0;
189 	}
190 
191 	/** @return  The XAccessible interface of the specified child. */
192 	::com::sun::star::uno::Reference<
193 		::com::sun::star::accessibility::XAccessible > SAL_CALL
194 		AccessibleGridControlTableCell::getAccessibleChild( sal_Int32 )
195 			throw ( ::com::sun::star::lang::IndexOutOfBoundsException,
196 					::com::sun::star::uno::RuntimeException )
197 	{
198 		throw ::com::sun::star::lang::IndexOutOfBoundsException();
199 	}
200 
201 	/** Creates a new AccessibleStateSetHelper and fills it with states of the
202 		current object.
203 		@return
204 			A filled AccessibleStateSetHelper.
205 	*/
206 	::utl::AccessibleStateSetHelper* AccessibleGridControlTableCell::implCreateStateSetHelper()
207 	{
208 		TCSolarGuard aSolarGuard;
209 		::osl::MutexGuard aGuard( getOslMutex() );
210 
211 		::utl::AccessibleStateSetHelper* pStateSetHelper = new ::utl::AccessibleStateSetHelper;
212 
213 		if( isAlive() )
214 		{
215 			// SHOWING done with mxParent
216 			if( implIsShowing() )
217 				pStateSetHelper->AddState( AccessibleStateType::SHOWING );
218 
219 			m_aTable.FillAccessibleStateSetForCell( *pStateSetHelper, getRowPos(), static_cast< sal_uInt16 >( getColumnPos() ) );
220 		}
221 		else
222 			pStateSetHelper->AddState( AccessibleStateType::DEFUNC );
223 
224 		return pStateSetHelper;
225 	}
226 
227 
228 	// XAccessible ------------------------------------------------------------
229 
230 	/** @return  The XAccessibleContext interface of this object. */
231 	Reference< XAccessibleContext > SAL_CALL AccessibleGridControlTableCell::getAccessibleContext() throw ( RuntimeException )
232 	{
233 		ensureIsAlive();
234 		return this;
235 	}
236 
237 	// XAccessibleContext -----------------------------------------------------
238 
239 	sal_Int32 SAL_CALL AccessibleGridControlTableCell::getAccessibleIndexInParent()
240 			throw ( ::com::sun::star::uno::RuntimeException )
241 	{
242 		TCSolarGuard aSolarGuard;
243 		::osl::MutexGuard aGuard( getOslMutex() );
244 		ensureIsAlive();
245 
246         return ( getRowPos() * m_aTable.GetColumnCount() ) + getColumnPos();
247 	}
248 
249 	sal_Int32 SAL_CALL AccessibleGridControlTableCell::getCaretPosition(  ) throw (::com::sun::star::uno::RuntimeException)
250 	{
251 		return -1;
252 	}
253 	sal_Bool SAL_CALL AccessibleGridControlTableCell::setCaretPosition ( sal_Int32 nIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException)
254 	{
255 		TCSolarGuard aSolarGuard;
256 		::osl::MutexGuard aGuard( getOslMutex() );
257 
258 		if ( !implIsValidRange( nIndex, nIndex, implGetText().getLength() ) )
259 			throw IndexOutOfBoundsException();
260 
261 		return sal_False;
262 	}
263 	sal_Unicode SAL_CALL AccessibleGridControlTableCell::getCharacter( sal_Int32 nIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException)
264 	{
265 		TCSolarGuard aSolarGuard;
266 		::osl::MutexGuard aGuard( getOslMutex() );
267 		return OCommonAccessibleText::getCharacter( nIndex );
268 	}
269 	::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > SAL_CALL AccessibleGridControlTableCell::getCharacterAttributes( sal_Int32 nIndex, const ::com::sun::star::uno::Sequence< ::rtl::OUString >& ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException)
270 	{
271 		TCSolarGuard aSolarGuard;
272 		::osl::MutexGuard aGuard( getOslMutex() );
273 
274 		::rtl::OUString sText( implGetText() );
275 
276 		if ( !implIsValidIndex( nIndex, sText.getLength() ) )
277 			throw IndexOutOfBoundsException();
278 
279 		return ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >();
280 	}
281 	sal_Int32 SAL_CALL AccessibleGridControlTableCell::getCharacterCount(  ) throw (::com::sun::star::uno::RuntimeException)
282 	{
283 		TCSolarGuard aSolarGuard;
284 		::osl::MutexGuard aGuard( getOslMutex() );
285 		return OCommonAccessibleText::getCharacterCount(  );
286 	}
287 
288 	::rtl::OUString SAL_CALL AccessibleGridControlTableCell::getSelectedText(  ) throw (::com::sun::star::uno::RuntimeException)
289 	{
290 		TCSolarGuard aSolarGuard;
291 		::osl::MutexGuard aGuard( getOslMutex() );
292 		return OCommonAccessibleText::getSelectedText(  );
293 	}
294 	sal_Int32 SAL_CALL AccessibleGridControlTableCell::getSelectionStart(  ) throw (::com::sun::star::uno::RuntimeException)
295 	{
296 		TCSolarGuard aSolarGuard;
297 		::osl::MutexGuard aGuard( getOslMutex() );
298 		return OCommonAccessibleText::getSelectionStart(  );
299 	}
300 	sal_Int32 SAL_CALL AccessibleGridControlTableCell::getSelectionEnd(  ) throw (::com::sun::star::uno::RuntimeException)
301 	{
302 		TCSolarGuard aSolarGuard;
303 		::osl::MutexGuard aGuard( getOslMutex() );
304 		return OCommonAccessibleText::getSelectionEnd(  );
305 	}
306 	sal_Bool SAL_CALL AccessibleGridControlTableCell::setSelection( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException)
307 	{
308 		TCSolarGuard aSolarGuard;
309 		::osl::MutexGuard aGuard( getOslMutex() );
310 		if ( !implIsValidRange( nStartIndex, nEndIndex, implGetText().getLength() ) )
311 			throw IndexOutOfBoundsException();
312 
313 		return sal_False;
314 	}
315 	::rtl::OUString SAL_CALL AccessibleGridControlTableCell::getText(  ) throw (::com::sun::star::uno::RuntimeException)
316 	{
317 		TCSolarGuard aSolarGuard;
318 		::osl::MutexGuard aGuard( getOslMutex() );
319 		return OCommonAccessibleText::getText(  );
320 	}
321 	::rtl::OUString SAL_CALL AccessibleGridControlTableCell::getTextRange( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException)
322 	{
323 		TCSolarGuard aSolarGuard;
324 		::osl::MutexGuard aGuard( getOslMutex() );
325 		return OCommonAccessibleText::getTextRange( nStartIndex, nEndIndex );
326 	}
327 	::com::sun::star::accessibility::TextSegment SAL_CALL AccessibleGridControlTableCell::getTextAtIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException)
328 	{
329 		TCSolarGuard aSolarGuard;
330 		::osl::MutexGuard aGuard( getOslMutex() );
331 		return OCommonAccessibleText::getTextAtIndex( nIndex ,aTextType);
332 	}
333 	::com::sun::star::accessibility::TextSegment SAL_CALL AccessibleGridControlTableCell::getTextBeforeIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException)
334 	{
335 		TCSolarGuard aSolarGuard;
336 		::osl::MutexGuard aGuard( getOslMutex() );
337 		return OCommonAccessibleText::getTextBeforeIndex( nIndex ,aTextType);
338 	}
339 	::com::sun::star::accessibility::TextSegment SAL_CALL AccessibleGridControlTableCell::getTextBehindIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException)
340 	{
341 		TCSolarGuard aSolarGuard;
342 		::osl::MutexGuard aGuard( getOslMutex() );
343 		return OCommonAccessibleText::getTextBehindIndex( nIndex ,aTextType);
344 	}
345 	sal_Bool SAL_CALL AccessibleGridControlTableCell::copyText( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException)
346 	{
347 		TCSolarGuard aSolarGuard;
348 		::osl::MutexGuard aGuard( getOslMutex() );
349 		::rtl::OUString sText = implGetText();
350 		checkIndex_Impl( nStartIndex, sText );
351 		checkIndex_Impl( nEndIndex, sText );
352 
353 		//!!! don't know how to put a string into the clipboard
354 		return sal_False;
355 	}
356 
357 	Rectangle AccessibleGridControlTableCell::implGetBoundingBox()
358 	{
359 		Window* pParent = m_aTable.GetAccessibleParentWindow();
360 		DBG_ASSERT( pParent, "implGetBoundingBox - missing parent window" );
361 		Rectangle aGridRect = m_aTable.GetWindowExtentsRelative( pParent );
362 		sal_Int32 nIndex = getAccessibleIndexInParent();
363 		Rectangle aCellRect = m_aTable.calcCellRect(nIndex%m_aTable.GetColumnCount(), nIndex/m_aTable.GetColumnCount());
364 		long nX = aGridRect.Left() + aCellRect.Left();
365 		long nY = aGridRect.Top() + aCellRect.Top();
366 		Rectangle aCell( Point( nX, nY ), aCellRect.GetSize());
367 		return aCell;
368 	}
369 	// -----------------------------------------------------------------------------
370 	Rectangle AccessibleGridControlTableCell::implGetBoundingBoxOnScreen()
371 	{
372 		Rectangle aGridRect = m_aTable.GetWindowExtentsRelative( NULL );
373 		sal_Int32 nIndex = getAccessibleIndexInParent();
374 		Rectangle aCellRect = m_aTable.calcCellRect(nIndex%m_aTable.GetColumnCount(), nIndex/m_aTable.GetColumnCount());
375 		long nX = aGridRect.Left() + aCellRect.Left();
376 		long nY = aGridRect.Top() + aCellRect.Top();
377 		Rectangle aCell( Point( nX, nY ), aCellRect.GetSize());
378 		return aCell;
379 	}
380 }
381