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