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 
28 #include "accessibility/extended/AccessibleBrowseBoxHeaderBar.hxx"
29 #include <svtools/accessibletableprovider.hxx>
30 
31 // ============================================================================
32 
33 using ::rtl::OUString;
34 
35 using ::com::sun::star::uno::Reference;
36 using ::com::sun::star::uno::Sequence;
37 using ::com::sun::star::uno::Any;
38 
39 using namespace ::com::sun::star;
40 using namespace ::com::sun::star::accessibility;
41 using namespace ::svt;
42 
43 // ============================================================================
44 
45 namespace accessibility {
46 
47 // ============================================================================
48 
49 // Ctor/Dtor/disposing --------------------------------------------------------
50 
DBG_NAME(AccessibleBrowseBoxHeaderBar)51 DBG_NAME( AccessibleBrowseBoxHeaderBar )
52 
53 AccessibleBrowseBoxHeaderBar::AccessibleBrowseBoxHeaderBar(
54 		const Reference< XAccessible >& rxParent,
55 		IAccessibleTableProvider& rBrowseBox,
56 		AccessibleBrowseBoxObjType eObjType ) :
57 	AccessibleBrowseBoxTableBase( rxParent, rBrowseBox,eObjType )
58 {
59 	DBG_CTOR( AccessibleBrowseBoxHeaderBar, NULL );
60 
61 	DBG_ASSERT( isRowBar() || isColumnBar(),
62 		"accessibility/extended/AccessibleBrowseBoxHeaderBar - invalid object type" );
63 }
64 
~AccessibleBrowseBoxHeaderBar()65 AccessibleBrowseBoxHeaderBar::~AccessibleBrowseBoxHeaderBar()
66 {
67 	DBG_DTOR( AccessibleBrowseBoxHeaderBar, NULL );
68 }
69 
70 // XAccessibleContext ---------------------------------------------------------
71 
72 Reference< XAccessible > SAL_CALL
getAccessibleChild(sal_Int32 nChildIndex)73 AccessibleBrowseBoxHeaderBar::getAccessibleChild( sal_Int32 nChildIndex )
74 	throw ( lang::IndexOutOfBoundsException, uno::RuntimeException )
75 {
76 	BBSolarGuard aSolarGuard;
77 	::osl::MutexGuard aGuard( getOslMutex() );
78 	ensureIsAlive();
79 	ensureIsValidHeaderIndex( nChildIndex );
80 	return implGetChild( nChildIndex, implToVCLColumnPos( nChildIndex ) );
81 }
82 
getAccessibleIndexInParent()83 sal_Int32 SAL_CALL AccessibleBrowseBoxHeaderBar::getAccessibleIndexInParent()
84 	throw ( uno::RuntimeException )
85 {
86 	return isRowBar() ? BBINDEX_ROWHEADERBAR : BBINDEX_COLUMNHEADERBAR;
87 }
88 
89 // XAccessibleComponent -------------------------------------------------------
90 
91 Reference< XAccessible > SAL_CALL
getAccessibleAtPoint(const awt::Point & rPoint)92 AccessibleBrowseBoxHeaderBar::getAccessibleAtPoint( const awt::Point& rPoint )
93 	throw ( uno::RuntimeException )
94 {
95 	BBSolarGuard aSolarGuard;
96 	::osl::MutexGuard aGuard( getOslMutex() );
97 	ensureIsAlive();
98 
99 	sal_Int32 nRow = 0;
100 	sal_uInt16 nColumnPos = 0;
101 	sal_Bool bConverted = isRowBar() ?
102 		mpBrowseBox->ConvertPointToRowHeader( nRow, VCLPoint( rPoint ) ) :
103 		mpBrowseBox->ConvertPointToColumnHeader( nColumnPos, VCLPoint( rPoint ) );
104 
105 	return bConverted ? implGetChild( nRow, nColumnPos ) : Reference< XAccessible >();
106 }
107 
grabFocus()108 void SAL_CALL AccessibleBrowseBoxHeaderBar::grabFocus()
109 	throw ( uno::RuntimeException )
110 {
111 	ensureIsAlive();
112 	// focus on header not supported
113 }
114 
getAccessibleKeyBinding()115 Any SAL_CALL AccessibleBrowseBoxHeaderBar::getAccessibleKeyBinding()
116 	throw ( uno::RuntimeException )
117 {
118 	ensureIsAlive();
119 	return Any(); // no special key bindings for header
120 }
121 
122 // XAccessibleTable -----------------------------------------------------------
123 
getAccessibleRowDescription(sal_Int32 nRow)124 OUString SAL_CALL AccessibleBrowseBoxHeaderBar::getAccessibleRowDescription( sal_Int32 nRow )
125 	throw ( lang::IndexOutOfBoundsException, uno::RuntimeException )
126 {
127 	BBSolarGuard aSolarGuard;
128 	::osl::MutexGuard aGuard( getOslMutex() );
129 	ensureIsAlive();
130 	ensureIsValidRow( nRow );
131 	return OUString(); // no headers in headers
132 }
133 
getAccessibleColumnDescription(sal_Int32 nColumn)134 OUString SAL_CALL AccessibleBrowseBoxHeaderBar::getAccessibleColumnDescription( sal_Int32 nColumn )
135 	throw ( lang::IndexOutOfBoundsException, uno::RuntimeException )
136 {
137 	BBSolarGuard aSolarGuard;
138 	::osl::MutexGuard aGuard( getOslMutex() );
139 	ensureIsAlive();
140 	ensureIsValidColumn( nColumn );
141 	return OUString(); // no headers in headers
142 }
143 
getAccessibleRowHeaders()144 Reference< XAccessibleTable > SAL_CALL AccessibleBrowseBoxHeaderBar::getAccessibleRowHeaders()
145 	throw ( uno::RuntimeException )
146 {
147 	ensureIsAlive();
148 	return NULL; // no headers in headers
149 }
150 
getAccessibleColumnHeaders()151 Reference< XAccessibleTable > SAL_CALL AccessibleBrowseBoxHeaderBar::getAccessibleColumnHeaders()
152 	throw ( uno::RuntimeException )
153 {
154 	ensureIsAlive();
155 	return NULL; // no headers in headers
156 }
157 
getSelectedAccessibleRows()158 Sequence< sal_Int32 > SAL_CALL AccessibleBrowseBoxHeaderBar::getSelectedAccessibleRows()
159 	throw ( uno::RuntimeException )
160 {
161 	BBSolarGuard aSolarGuard;
162 	::osl::MutexGuard aGuard( getOslMutex() );
163 	ensureIsAlive();
164 
165 	Sequence< sal_Int32 > aSelSeq;
166 	// row of column header bar not selectable
167 	if( isRowBar() )
168 		implGetSelectedRows( aSelSeq );
169 	return aSelSeq;
170 }
171 
getSelectedAccessibleColumns()172 Sequence< sal_Int32 > SAL_CALL AccessibleBrowseBoxHeaderBar::getSelectedAccessibleColumns()
173 	throw ( uno::RuntimeException )
174 {
175 	BBSolarGuard aSolarGuard;
176 	::osl::MutexGuard aGuard( getOslMutex() );
177 	ensureIsAlive();
178 
179 	Sequence< sal_Int32 > aSelSeq;
180 	// column of row header bar ("handle column") not selectable
181 	if( isColumnBar() )
182 		implGetSelectedColumns( aSelSeq );
183 	return aSelSeq;
184 }
185 
isAccessibleRowSelected(sal_Int32 nRow)186 sal_Bool SAL_CALL AccessibleBrowseBoxHeaderBar::isAccessibleRowSelected( sal_Int32 nRow )
187 	throw ( lang::IndexOutOfBoundsException, uno::RuntimeException )
188 {
189 	BBSolarGuard aSolarGuard;
190 	::osl::MutexGuard aGuard( getOslMutex() );
191 	ensureIsAlive();
192 	ensureIsValidRow( nRow );
193 	return isRowBar() ? implIsRowSelected( nRow ) : sal_False;
194 }
195 
isAccessibleColumnSelected(sal_Int32 nColumn)196 sal_Bool SAL_CALL AccessibleBrowseBoxHeaderBar::isAccessibleColumnSelected( sal_Int32 nColumn )
197 	throw ( lang::IndexOutOfBoundsException, uno::RuntimeException )
198 {
199 	BBSolarGuard aSolarGuard;
200 	::osl::MutexGuard aGuard( getOslMutex() );
201 	ensureIsAlive();
202 	ensureIsValidColumn( nColumn );
203 	return isColumnBar() ? implIsColumnSelected( nColumn ) : sal_False;
204 }
205 
getAccessibleCellAt(sal_Int32 nRow,sal_Int32 nColumn)206 Reference< XAccessible > SAL_CALL AccessibleBrowseBoxHeaderBar::getAccessibleCellAt(
207 		sal_Int32 nRow, sal_Int32 nColumn )
208 	throw ( lang::IndexOutOfBoundsException, uno::RuntimeException )
209 {
210 	BBSolarGuard aSolarGuard;
211 	::osl::MutexGuard aGuard( getOslMutex() );
212 	ensureIsAlive();
213 	ensureIsValidAddress( nRow, nColumn );
214 	return implGetChild( nRow, implToVCLColumnPos( nColumn ) );
215 }
216 
isAccessibleSelected(sal_Int32 nRow,sal_Int32 nColumn)217 sal_Bool SAL_CALL AccessibleBrowseBoxHeaderBar::isAccessibleSelected(
218 		sal_Int32 nRow, sal_Int32 nColumn )
219 	throw ( lang::IndexOutOfBoundsException, uno::RuntimeException )
220 {
221 	BBSolarGuard aSolarGuard;
222 	::osl::MutexGuard aGuard( getOslMutex() );
223 	ensureIsAlive();
224 	ensureIsValidAddress( nRow, nColumn );
225 	return isRowBar() ? implIsRowSelected( nRow ) : implIsColumnSelected( nColumn );
226 }
227 
228 // XAccessibleSelection -------------------------------------------------------
229 
selectAccessibleChild(sal_Int32 nChildIndex)230 void SAL_CALL AccessibleBrowseBoxHeaderBar::selectAccessibleChild( sal_Int32 nChildIndex )
231 	throw ( lang::IndexOutOfBoundsException, uno::RuntimeException )
232 {
233 	BBSolarGuard aSolarGuard;
234 	::osl::MutexGuard aGuard( getOslMutex() );
235 	ensureIsAlive();
236 	ensureIsValidHeaderIndex( nChildIndex );
237 	if( isRowBar() )
238 		implSelectRow( nChildIndex, sal_True );
239 	else
240 		implSelectColumn( implToVCLColumnPos( nChildIndex ), sal_True );
241 }
242 
isAccessibleChildSelected(sal_Int32 nChildIndex)243 sal_Bool SAL_CALL AccessibleBrowseBoxHeaderBar::isAccessibleChildSelected( sal_Int32 nChildIndex )
244 	throw ( lang::IndexOutOfBoundsException, uno::RuntimeException )
245 {
246 	// using interface methods - no mutex
247 	return isRowBar() ?
248 		isAccessibleRowSelected( nChildIndex ) :
249 		isAccessibleColumnSelected( nChildIndex );
250 }
251 
clearAccessibleSelection()252 void SAL_CALL AccessibleBrowseBoxHeaderBar::clearAccessibleSelection()
253 	throw ( uno::RuntimeException )
254 {
255 	BBSolarGuard aSolarGuard;
256 	::osl::MutexGuard aGuard( getOslMutex() );
257 	ensureIsAlive();
258 	mpBrowseBox->SetNoSelection();
259 }
260 
selectAllAccessibleChildren()261 void SAL_CALL AccessibleBrowseBoxHeaderBar::selectAllAccessibleChildren()
262 	throw ( uno::RuntimeException )
263 {
264 	BBSolarGuard aSolarGuard;
265 	::osl::MutexGuard aGuard( getOslMutex() );
266 	ensureIsAlive();
267 	// no multiselection of columns possible
268 	if( isRowBar() )
269 		mpBrowseBox->SelectAll();
270 	else
271 		implSelectColumn( implToVCLColumnPos( 0 ), sal_True );
272 }
273 
getSelectedAccessibleChildCount()274 sal_Int32 SAL_CALL AccessibleBrowseBoxHeaderBar::getSelectedAccessibleChildCount()
275 	throw ( uno::RuntimeException )
276 {
277 	BBSolarGuard aSolarGuard;
278 	::osl::MutexGuard aGuard( getOslMutex() );
279 	ensureIsAlive();
280 	return isRowBar() ? implGetSelectedRowCount() : implGetSelectedColumnCount();
281 }
282 
283 Reference< XAccessible > SAL_CALL
getSelectedAccessibleChild(sal_Int32 nSelectedChildIndex)284 AccessibleBrowseBoxHeaderBar::getSelectedAccessibleChild( sal_Int32 nSelectedChildIndex )
285 	throw ( lang::IndexOutOfBoundsException, uno::RuntimeException )
286 {
287 	BBSolarGuard aSolarGuard;
288 	::osl::MutexGuard aGuard( getOslMutex() );
289 	ensureIsAlive();
290 
291 	// method may throw lang::IndexOutOfBoundsException
292 	sal_Int32 nIndex = implGetChildIndexFromSelectedIndex( nSelectedChildIndex );
293 	return implGetChild( nIndex, implToVCLColumnPos( nIndex ) );
294 }
295 
deselectAccessibleChild(sal_Int32 nSelectedChildIndex)296 void SAL_CALL AccessibleBrowseBoxHeaderBar::deselectAccessibleChild(
297 		sal_Int32 nSelectedChildIndex )
298 	throw ( lang::IndexOutOfBoundsException, uno::RuntimeException )
299 {
300 	BBSolarGuard aSolarGuard;
301 	::osl::MutexGuard aGuard( getOslMutex() );
302 	ensureIsAlive();
303 
304 	// method may throw lang::IndexOutOfBoundsException
305 	if ( isAccessibleChildSelected(nSelectedChildIndex) )
306 	{
307 		if( isRowBar() )
308 			implSelectRow( nSelectedChildIndex, sal_False );
309 		else
310 			implSelectColumn( implToVCLColumnPos( nSelectedChildIndex ), sal_False );
311 	}
312 }
313 
314 // XInterface -----------------------------------------------------------------
315 
queryInterface(const uno::Type & rType)316 Any SAL_CALL AccessibleBrowseBoxHeaderBar::queryInterface( const uno::Type& rType )
317 	throw ( uno::RuntimeException )
318 {
319 	Any aAny( AccessibleBrowseBoxTableBase::queryInterface( rType ) );
320 	return aAny.hasValue() ?
321 		aAny : AccessibleBrowseBoxHeaderBarImplHelper::queryInterface( rType );
322 }
323 
acquire()324 void SAL_CALL AccessibleBrowseBoxHeaderBar::acquire() throw ()
325 {
326 	AccessibleBrowseBoxTableBase::acquire();
327 }
328 
release()329 void SAL_CALL AccessibleBrowseBoxHeaderBar::release() throw ()
330 {
331 	AccessibleBrowseBoxTableBase::release();
332 }
333 
334 // XServiceInfo ---------------------------------------------------------------
335 
getImplementationName()336 OUString SAL_CALL AccessibleBrowseBoxHeaderBar::getImplementationName()
337 	throw ( uno::RuntimeException )
338 {
339 	return OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.svtools.AccessibleBrowseBoxHeaderBar" ) );
340 }
341 
getImplementationId()342 Sequence< sal_Int8 > SAL_CALL AccessibleBrowseBoxHeaderBar::getImplementationId()
343 	throw ( uno::RuntimeException )
344 {
345 	::osl::MutexGuard aGuard( getOslGlobalMutex() );
346 	static Sequence< sal_Int8 > aId;
347 	implCreateUuid( aId );
348 	return aId;
349 }
350 
351 // internal virtual methods ---------------------------------------------------
352 
implGetBoundingBox()353 Rectangle AccessibleBrowseBoxHeaderBar::implGetBoundingBox()
354 {
355 	return mpBrowseBox->calcHeaderRect(isColumnBar(),sal_False);
356 }
357 
implGetBoundingBoxOnScreen()358 Rectangle AccessibleBrowseBoxHeaderBar::implGetBoundingBoxOnScreen()
359 {
360 	return mpBrowseBox->calcHeaderRect(isColumnBar(),sal_True);
361 }
362 
implGetRowCount() const363 sal_Int32 AccessibleBrowseBoxHeaderBar::implGetRowCount() const
364 {
365 	// column header bar: only 1 row
366 	return isRowBar() ? AccessibleBrowseBoxTableBase::implGetRowCount() : 1;
367 }
368 
implGetColumnCount() const369 sal_Int32 AccessibleBrowseBoxHeaderBar::implGetColumnCount() const
370 {
371 	// row header bar ("handle column"): only 1 column
372 	return isColumnBar() ? AccessibleBrowseBoxTableBase::implGetColumnCount() : 1;
373 }
374 
375 // internal helper methods ----------------------------------------------------
376 
implGetChild(sal_Int32 nRow,sal_uInt16 nColumnPos)377 Reference< XAccessible > AccessibleBrowseBoxHeaderBar::implGetChild(
378 		sal_Int32 nRow, sal_uInt16 nColumnPos )
379 {
380 	return isRowBar() ?
381 		mpBrowseBox->CreateAccessibleRowHeader( nRow ) :
382 		mpBrowseBox->CreateAccessibleColumnHeader( nColumnPos );
383 }
384 
implGetChildIndexFromSelectedIndex(sal_Int32 nSelectedChildIndex)385 sal_Int32 AccessibleBrowseBoxHeaderBar::implGetChildIndexFromSelectedIndex(
386 		sal_Int32 nSelectedChildIndex )
387 	throw ( lang::IndexOutOfBoundsException )
388 {
389 	Sequence< sal_Int32 > aSelSeq;
390 	if( isRowBar() )
391 		implGetSelectedRows( aSelSeq );
392 	else
393 		implGetSelectedColumns( aSelSeq );
394 
395 	if( (nSelectedChildIndex < 0) || (nSelectedChildIndex >= aSelSeq.getLength()) )
396 		throw lang::IndexOutOfBoundsException();
397 
398 	return aSelSeq[ nSelectedChildIndex ];
399 }
400 
ensureIsValidHeaderIndex(sal_Int32 nIndex)401 void AccessibleBrowseBoxHeaderBar::ensureIsValidHeaderIndex( sal_Int32 nIndex )
402 	throw ( lang::IndexOutOfBoundsException )
403 {
404 	if( isRowBar() )
405 		ensureIsValidRow( nIndex );
406 	else
407 		ensureIsValidColumn( nIndex );
408 }
409 
410 // ============================================================================
411 } // namespace accessibility
412 // ============================================================================
413