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 #include "accessibility/extended/AccessibleBrowseBox.hxx"
27 #include "accessibility/extended/AccessibleBrowseBoxTable.hxx"
28 #include "accessibility/extended/AccessibleBrowseBoxHeaderBar.hxx"
29 #include <svtools/accessibletableprovider.hxx>
30 #include <comphelper/types.hxx>
31 #include <toolkit/helper/vclunohelper.hxx>
32
33 // ============================================================================
34
35 namespace accessibility
36 {
37
38 // ============================================================================
39
40 using ::rtl::OUString;
41
42 using namespace ::com::sun::star::uno;
43 using namespace ::com::sun::star;
44 using namespace ::com::sun::star::lang;
45 using namespace ::com::sun::star::accessibility;
46 using namespace ::svt;
47
48 // ============================================================================
49 class AccessibleBrowseBoxImpl
50 {
51 public:
52 /// the XAccessible which created the AccessibleBrowseBox
53 WeakReference< XAccessible > m_aCreator;
54
55 /** The data table child. */
56 Reference<
57 ::com::sun::star::accessibility::XAccessible > mxTable;
58 AccessibleBrowseBoxTable* m_pTable;
59
60 /** The header bar for rows ("handle column"). */
61 Reference<
62 ::com::sun::star::accessibility::XAccessible > mxRowHeaderBar;
63 AccessibleBrowseBoxHeaderBar* m_pRowHeaderBar;
64
65 /** The header bar for columns (first row of the table). */
66 Reference<
67 ::com::sun::star::accessibility::XAccessible > mxColumnHeaderBar;
68 AccessibleBrowseBoxHeaderBar* m_pColumnHeaderBar;
69 };
70
71 // Ctor/Dtor/disposing --------------------------------------------------------
72
DBG_NAME(AccessibleBrowseBox)73 DBG_NAME( AccessibleBrowseBox )
74
75 AccessibleBrowseBox::AccessibleBrowseBox(
76 const Reference< XAccessible >& _rxParent, const Reference< XAccessible >& _rxCreator,
77 IAccessibleTableProvider& _rBrowseBox )
78 : AccessibleBrowseBoxBase( _rxParent, _rBrowseBox,NULL, BBTYPE_BROWSEBOX )
79 {
80 DBG_CTOR( AccessibleBrowseBox, NULL );
81 m_pImpl.reset( new AccessibleBrowseBoxImpl() );
82 m_pImpl->m_aCreator = _rxCreator;
83
84 m_xFocusWindow = VCLUnoHelper::GetInterface(mpBrowseBox->GetWindowInstance());
85 }
86 // -----------------------------------------------------------------------------
setCreator(const Reference<XAccessible> & _rxCreator)87 void AccessibleBrowseBox::setCreator( const Reference< XAccessible >& _rxCreator )
88 {
89 #if OSL_DEBUG_LEVEL > 0
90 Reference< XAccessible > xCreator = (Reference< XAccessible >)m_pImpl->m_aCreator;
91 DBG_ASSERT( !xCreator.is(), "accessibility/extended/AccessibleBrowseBox::setCreator: creator already set!" );
92 #endif
93 m_pImpl->m_aCreator = _rxCreator;
94 }
95
96 // -----------------------------------------------------------------------------
~AccessibleBrowseBox()97 AccessibleBrowseBox::~AccessibleBrowseBox()
98 {
99 DBG_DTOR( AccessibleBrowseBox, NULL );
100 }
101 // -----------------------------------------------------------------------------
102
disposing()103 void SAL_CALL AccessibleBrowseBox::disposing()
104 {
105 ::osl::MutexGuard aGuard( getOslMutex() );
106
107 m_pImpl->m_pTable = NULL;
108 m_pImpl->m_pColumnHeaderBar = NULL;
109 m_pImpl->m_pRowHeaderBar = NULL;
110 m_pImpl->m_aCreator = Reference< XAccessible >();
111
112 Reference< XAccessible > xTable = m_pImpl->mxTable;
113
114 Reference< XComponent > xComp( m_pImpl->mxTable, UNO_QUERY );
115 if ( xComp.is() )
116 {
117 xComp->dispose();
118
119 }
120 //! ::comphelper::disposeComponent(m_pImpl->mxTable);
121 ::comphelper::disposeComponent(m_pImpl->mxRowHeaderBar);
122 ::comphelper::disposeComponent(m_pImpl->mxColumnHeaderBar);
123
124 AccessibleBrowseBoxBase::disposing();
125 }
126 // -----------------------------------------------------------------------------
127
128 // XAccessibleContext ---------------------------------------------------------
129
getAccessibleChildCount()130 sal_Int32 SAL_CALL AccessibleBrowseBox::getAccessibleChildCount()
131 throw ( uno::RuntimeException )
132 {
133 BBSolarGuard aSolarGuard;
134 ::osl::MutexGuard aGuard( getOslMutex() );
135 ensureIsAlive();
136 return BBINDEX_FIRSTCONTROL + mpBrowseBox->GetAccessibleControlCount();
137 }
138 // -----------------------------------------------------------------------------
139
140 Reference< XAccessible > SAL_CALL
getAccessibleChild(sal_Int32 nChildIndex)141 AccessibleBrowseBox::getAccessibleChild( sal_Int32 nChildIndex )
142 throw ( lang::IndexOutOfBoundsException, uno::RuntimeException )
143 {
144 BBSolarGuard aSolarGuard;
145 ::osl::MutexGuard aGuard( getOslMutex() );
146 ensureIsAlive();
147
148 Reference< XAccessible > xRet;
149 if( nChildIndex >= 0 )
150 {
151 if( nChildIndex < BBINDEX_FIRSTCONTROL )
152 xRet = implGetFixedChild( nChildIndex );
153 else
154 {
155 // additional controls
156 nChildIndex -= BBINDEX_FIRSTCONTROL;
157 if( nChildIndex < mpBrowseBox->GetAccessibleControlCount() )
158 xRet = mpBrowseBox->CreateAccessibleControl( nChildIndex );
159 }
160 }
161
162 if( !xRet.is() )
163 throw lang::IndexOutOfBoundsException();
164 return xRet;
165 }
166 // -----------------------------------------------------------------------------
167
168 //sal_Int16 SAL_CALL AccessibleBrowseBox::getAccessibleRole()
169 // throw ( uno::RuntimeException )
170 //{
171 // ensureIsAlive();
172 // return AccessibleRole::PANEL;
173 //}
174 // -----------------------------------------------------------------------------
175
176 // XAccessibleComponent -------------------------------------------------------
177
178 Reference< XAccessible > SAL_CALL
getAccessibleAtPoint(const awt::Point & rPoint)179 AccessibleBrowseBox::getAccessibleAtPoint( const awt::Point& rPoint )
180 throw ( uno::RuntimeException )
181 {
182 BBSolarGuard aSolarGuard;
183 ::osl::MutexGuard aGuard( getOslMutex() );
184 ensureIsAlive();
185
186 Reference< XAccessible > xChild;
187 sal_Int32 nIndex = 0;
188 if( mpBrowseBox->ConvertPointToControlIndex( nIndex, VCLPoint( rPoint ) ) )
189 xChild = mpBrowseBox->CreateAccessibleControl( nIndex );
190 else
191 {
192 // try whether point is in one of the fixed children
193 // (table, header bars, corner control)
194 Point aPoint( VCLPoint( rPoint ) );
195 for( nIndex = 0; (nIndex < BBINDEX_FIRSTCONTROL) && !xChild.is(); ++nIndex )
196 {
197 Reference< XAccessible > xCurrChild( implGetFixedChild( nIndex ) );
198 Reference< XAccessibleComponent >
199 xCurrChildComp( xCurrChild, uno::UNO_QUERY );
200
201 if( xCurrChildComp.is() &&
202 VCLRectangle( xCurrChildComp->getBounds() ).IsInside( aPoint ) )
203 xChild = xCurrChild;
204 }
205 }
206 return xChild;
207 }
208 // -----------------------------------------------------------------------------
209
grabFocus()210 void SAL_CALL AccessibleBrowseBox::grabFocus()
211 throw ( uno::RuntimeException )
212 {
213 BBSolarGuard aSolarGuard;
214 ::osl::MutexGuard aGuard( getOslMutex() );
215 ensureIsAlive();
216 mpBrowseBox->GrabFocus();
217 }
218 // -----------------------------------------------------------------------------
219
getAccessibleKeyBinding()220 Any SAL_CALL AccessibleBrowseBox::getAccessibleKeyBinding()
221 throw ( uno::RuntimeException )
222 {
223 ensureIsAlive();
224 return Any();
225 }
226 // -----------------------------------------------------------------------------
227
228 // XServiceInfo ---------------------------------------------------------------
229
getImplementationName()230 OUString SAL_CALL AccessibleBrowseBox::getImplementationName()
231 throw ( uno::RuntimeException )
232 {
233 return OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.svtools.AccessibleBrowseBox" ) );
234 }
235 // -----------------------------------------------------------------------------
236
237 // internal virtual methods ---------------------------------------------------
238
implGetBoundingBox()239 Rectangle AccessibleBrowseBox::implGetBoundingBox()
240 {
241 Window* pParent = mpBrowseBox->GetAccessibleParentWindow();
242 DBG_ASSERT( pParent, "implGetBoundingBox - missing parent window" );
243 return mpBrowseBox->GetWindowExtentsRelative( pParent );
244 }
245 // -----------------------------------------------------------------------------
246
implGetBoundingBoxOnScreen()247 Rectangle AccessibleBrowseBox::implGetBoundingBoxOnScreen()
248 {
249 return mpBrowseBox->GetWindowExtentsRelative( NULL );
250 }
251 // -----------------------------------------------------------------------------
252
253 // internal helper methods ----------------------------------------------------
254
implGetTable()255 Reference< XAccessible > AccessibleBrowseBox::implGetTable()
256 {
257 if( !m_pImpl->mxTable.is() )
258 {
259 m_pImpl->m_pTable = createAccessibleTable();
260 m_pImpl->mxTable = m_pImpl->m_pTable;
261
262 }
263 return m_pImpl->mxTable;
264 }
265 // -----------------------------------------------------------------------------
266
267 Reference< XAccessible >
implGetHeaderBar(AccessibleBrowseBoxObjType eObjType)268 AccessibleBrowseBox::implGetHeaderBar( AccessibleBrowseBoxObjType eObjType )
269 {
270 Reference< XAccessible > xRet;
271 Reference< XAccessible >* pxMember = NULL;
272
273 if( eObjType == BBTYPE_ROWHEADERBAR )
274 pxMember = &m_pImpl->mxRowHeaderBar;
275 else if( eObjType == BBTYPE_COLUMNHEADERBAR )
276 pxMember = &m_pImpl->mxColumnHeaderBar;
277
278 if( pxMember )
279 {
280 if( !pxMember->is() )
281 {
282 AccessibleBrowseBoxHeaderBar* pHeaderBar = new AccessibleBrowseBoxHeaderBar(
283 (Reference< XAccessible >)m_pImpl->m_aCreator, *mpBrowseBox, eObjType );
284
285 if ( BBTYPE_COLUMNHEADERBAR == eObjType)
286 m_pImpl->m_pColumnHeaderBar = pHeaderBar;
287 else
288 m_pImpl->m_pRowHeaderBar = pHeaderBar;
289
290 *pxMember = pHeaderBar;
291 }
292 xRet = *pxMember;
293 }
294 return xRet;
295 }
296 // -----------------------------------------------------------------------------
297
298 Reference< XAccessible >
implGetFixedChild(sal_Int32 nChildIndex)299 AccessibleBrowseBox::implGetFixedChild( sal_Int32 nChildIndex )
300 {
301 Reference< XAccessible > xRet;
302 switch( nChildIndex )
303 {
304 case BBINDEX_COLUMNHEADERBAR:
305 xRet = implGetHeaderBar( BBTYPE_COLUMNHEADERBAR );
306 break;
307 case BBINDEX_ROWHEADERBAR:
308 xRet = implGetHeaderBar( BBTYPE_ROWHEADERBAR );
309 break;
310 case BBINDEX_TABLE:
311 xRet = implGetTable();
312 break;
313 }
314 return xRet;
315 }
316 // -----------------------------------------------------------------------------
createAccessibleTable()317 AccessibleBrowseBoxTable* AccessibleBrowseBox::createAccessibleTable()
318 {
319 Reference< XAccessible > xCreator = (Reference< XAccessible >)m_pImpl->m_aCreator;
320 DBG_ASSERT( xCreator.is(), "accessibility/extended/AccessibleBrowseBox::createAccessibleTable: my creator died - how this?" );
321 return new AccessibleBrowseBoxTable( xCreator, *mpBrowseBox );
322 }
323 // -----------------------------------------------------------------------------
commitTableEvent(sal_Int16 _nEventId,const Any & _rNewValue,const Any & _rOldValue)324 void AccessibleBrowseBox::commitTableEvent(sal_Int16 _nEventId,const Any& _rNewValue,const Any& _rOldValue)
325 {
326 if ( m_pImpl->mxTable.is() )
327 {
328 m_pImpl->m_pTable->commitEvent(_nEventId,_rNewValue,_rOldValue);
329 }
330 }
331 // -----------------------------------------------------------------------------
commitHeaderBarEvent(sal_Int16 _nEventId,const Any & _rNewValue,const Any & _rOldValue,sal_Bool _bColumnHeaderBar)332 void AccessibleBrowseBox::commitHeaderBarEvent( sal_Int16 _nEventId,
333 const Any& _rNewValue,
334 const Any& _rOldValue,sal_Bool _bColumnHeaderBar)
335 {
336 Reference< XAccessible > xHeaderBar = _bColumnHeaderBar ? m_pImpl->mxColumnHeaderBar : m_pImpl->mxRowHeaderBar;
337 AccessibleBrowseBoxHeaderBar* pHeaderBar = _bColumnHeaderBar ? m_pImpl->m_pColumnHeaderBar : m_pImpl->m_pRowHeaderBar;
338 if ( xHeaderBar.is() )
339 pHeaderBar->commitEvent(_nEventId,_rNewValue,_rOldValue);
340 }
341
342 // ============================================================================
343 // = AccessibleBrowseBoxAccess
344 // ============================================================================
DBG_NAME(AccessibleBrowseBoxAccess)345 DBG_NAME( AccessibleBrowseBoxAccess )
346 // -----------------------------------------------------------------------------
347 AccessibleBrowseBoxAccess::AccessibleBrowseBoxAccess( const Reference< XAccessible >& _rxParent, IAccessibleTableProvider& _rBrowseBox )
348 :m_xParent( _rxParent )
349 ,m_rBrowseBox( _rBrowseBox )
350 ,m_pContext( NULL )
351 {
352 DBG_CTOR( AccessibleBrowseBoxAccess, NULL );
353 }
354
355 // -----------------------------------------------------------------------------
~AccessibleBrowseBoxAccess()356 AccessibleBrowseBoxAccess::~AccessibleBrowseBoxAccess()
357 {
358 DBG_DTOR( AccessibleBrowseBoxAccess, NULL );
359 }
360
361 // -----------------------------------------------------------------------------
dispose()362 void AccessibleBrowseBoxAccess::dispose()
363 {
364 ::osl::MutexGuard aGuard( m_aMutex );
365
366 m_pContext = NULL;
367 ::comphelper::disposeComponent( m_xContext );
368 }
369
370 // -----------------------------------------------------------------------------
getAccessibleContext()371 Reference< XAccessibleContext > SAL_CALL AccessibleBrowseBoxAccess::getAccessibleContext() throw ( RuntimeException )
372 {
373 ::osl::MutexGuard aGuard( m_aMutex );
374
375 DBG_ASSERT( ( m_pContext && m_xContext.is() ) || ( !m_pContext && !m_xContext.is() ),
376 "accessibility/extended/AccessibleBrowseBoxAccess::getAccessibleContext: inconsistency!" );
377
378 // if the context died meanwhile (we're no listener, so it won't tell us explicitily when this happens),
379 // then reset an re-create.
380 if ( m_pContext && !m_pContext->isAlive() )
381 m_xContext = m_pContext = NULL;
382
383 if ( !m_xContext.is() )
384 m_xContext = m_pContext = new AccessibleBrowseBox( m_xParent, this, m_rBrowseBox );
385
386 return m_xContext;
387 }
388
389 // -----------------------------------------------------------------------------
isContextAlive() const390 bool AccessibleBrowseBoxAccess::isContextAlive() const
391 {
392 return ( NULL != m_pContext ) && m_pContext->isAlive();
393 }
394
395 // ============================================================================
396
397 } // namespace accessibility
398