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 
412 } // namespace accessibility
413 
414 // ============================================================================
415 
416