lok: vcl: fix multiple floatwin removal case more robustly.
[LibreOffice.git] / accessibility / source / extended / AccessibleBrowseBox.cxx
blobf6ffe537e981db792d5fb5ea2dc67968a0340df0
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <extended/AccessibleBrowseBox.hxx>
21 #include <extended/AccessibleBrowseBoxTable.hxx>
22 #include <extended/AccessibleBrowseBoxHeaderBar.hxx>
23 #include <vcl/accessibletableprovider.hxx>
24 #include <toolkit/helper/vclunohelper.hxx>
25 #include <sal/types.h>
28 namespace accessibility
31 using namespace ::com::sun::star::uno;
32 using namespace ::com::sun::star;
33 using namespace ::com::sun::star::lang;
34 using namespace ::com::sun::star::accessibility;
35 using namespace ::svt;
37 // Ctor/Dtor/disposing
39 AccessibleBrowseBox::AccessibleBrowseBox(
40 const css::uno::Reference< css::accessibility::XAccessible >& _rxParent, const css::uno::Reference< css::accessibility::XAccessible >& _rxCreator,
41 ::vcl::IAccessibleTableProvider& _rBrowseBox )
42 : AccessibleBrowseBoxBase( _rxParent, _rBrowseBox,nullptr, vcl::BBTYPE_BROWSEBOX ),
43 m_aCreator(_rxCreator)
45 m_xFocusWindow = VCLUnoHelper::GetInterface(mpBrowseBox->GetWindowInstance());
48 void AccessibleBrowseBox::setCreator( const css::uno::Reference< css::accessibility::XAccessible >& _rxCreator )
50 #if OSL_DEBUG_LEVEL > 0
51 css::uno::Reference< css::accessibility::XAccessible > xCreator(m_aCreator);
52 OSL_ENSURE( !xCreator.is(), "extended/AccessibleBrowseBox::setCreator: creator already set!" );
53 #endif
54 m_aCreator = _rxCreator;
58 AccessibleBrowseBox::~AccessibleBrowseBox()
63 void SAL_CALL AccessibleBrowseBox::disposing()
65 ::osl::MutexGuard aGuard( getMutex() );
67 m_aCreator.clear();
69 if ( mxTable.is() )
71 mxTable->dispose();
72 mxTable.clear();
74 if ( mxRowHeaderBar.is() )
76 mxRowHeaderBar->dispose();
77 mxRowHeaderBar.clear();
79 if ( mxColumnHeaderBar.is() )
81 mxColumnHeaderBar->dispose();
82 mxColumnHeaderBar.clear();
85 AccessibleBrowseBoxBase::disposing();
89 // css::accessibility::XAccessibleContext
91 sal_Int32 SAL_CALL AccessibleBrowseBox::getAccessibleChildCount()
93 SolarMethodGuard aGuard(getMutex());
94 ensureIsAlive();
96 return vcl::BBINDEX_FIRSTCONTROL + mpBrowseBox->GetAccessibleControlCount();
100 css::uno::Reference< css::accessibility::XAccessible > SAL_CALL
101 AccessibleBrowseBox::getAccessibleChild( sal_Int32 nChildIndex )
103 SolarMethodGuard aGuard(getMutex());
104 ensureIsAlive();
106 css::uno::Reference< css::accessibility::XAccessible > xRet;
107 if( nChildIndex >= 0 )
109 if( nChildIndex < vcl::BBINDEX_FIRSTCONTROL )
110 xRet = implGetFixedChild( nChildIndex );
111 else
113 // additional controls
114 nChildIndex -= vcl::BBINDEX_FIRSTCONTROL;
115 if( nChildIndex < mpBrowseBox->GetAccessibleControlCount() )
116 xRet = mpBrowseBox->CreateAccessibleControl( nChildIndex );
120 if( !xRet.is() )
121 throw lang::IndexOutOfBoundsException();
122 return xRet;
125 // css::accessibility::XAccessibleComponent
127 css::uno::Reference< css::accessibility::XAccessible > SAL_CALL
128 AccessibleBrowseBox::getAccessibleAtPoint( const awt::Point& rPoint )
130 SolarMethodGuard aGuard(getMutex());
131 ensureIsAlive();
133 css::uno::Reference< css::accessibility::XAccessible > xChild;
134 sal_Int32 nIndex = 0;
135 if( mpBrowseBox->ConvertPointToControlIndex( nIndex, VCLPoint( rPoint ) ) )
136 xChild = mpBrowseBox->CreateAccessibleControl( nIndex );
137 else
139 // try whether point is in one of the fixed children
140 // (table, header bars, corner control)
141 Point aPoint( VCLPoint( rPoint ) );
142 for( nIndex = 0; (nIndex < vcl::BBINDEX_FIRSTCONTROL) && !xChild.is(); ++nIndex )
144 css::uno::Reference< css::accessibility::XAccessible > xCurrChild( implGetFixedChild( nIndex ) );
145 css::uno::Reference< css::accessibility::XAccessibleComponent >
146 xCurrChildComp( xCurrChild, uno::UNO_QUERY );
148 if( xCurrChildComp.is() &&
149 VCLRectangle( xCurrChildComp->getBounds() ).IsInside( aPoint ) )
150 xChild = xCurrChild;
153 return xChild;
157 void SAL_CALL AccessibleBrowseBox::grabFocus()
159 SolarMethodGuard aGuard(getMutex());
160 ensureIsAlive();
162 mpBrowseBox->GrabFocus();
165 // XServiceInfo
167 OUString SAL_CALL AccessibleBrowseBox::getImplementationName()
169 return OUString( "com.sun.star.comp.svtools.AccessibleBrowseBox" );
173 // internal virtual methods
175 tools::Rectangle AccessibleBrowseBox::implGetBoundingBox()
177 vcl::Window* pParent = mpBrowseBox->GetAccessibleParentWindow();
178 OSL_ENSURE( pParent, "implGetBoundingBox - missing parent window" );
179 return mpBrowseBox->GetWindowExtentsRelative( pParent );
183 tools::Rectangle AccessibleBrowseBox::implGetBoundingBoxOnScreen()
185 return mpBrowseBox->GetWindowExtentsRelative( nullptr );
188 // internal helper methods
189 css::uno::Reference< css::accessibility::XAccessible > AccessibleBrowseBox::implGetTable()
191 if( !mxTable.is() )
193 mxTable = createAccessibleTable();
196 return mxTable.get();
199 css::uno::Reference< css::accessibility::XAccessible >
200 AccessibleBrowseBox::implGetHeaderBar(vcl::AccessibleBrowseBoxObjType eObjType)
202 css::uno::Reference< css::accessibility::XAccessible > xRet;
203 rtl::Reference< AccessibleBrowseBoxHeaderBar >* pxMember = nullptr;
205 if( eObjType == vcl::BBTYPE_ROWHEADERBAR )
206 pxMember = &mxRowHeaderBar;
207 else if( eObjType == vcl::BBTYPE_COLUMNHEADERBAR )
208 pxMember = &mxColumnHeaderBar;
210 if( pxMember )
212 if( !pxMember->is() )
214 AccessibleBrowseBoxHeaderBar* pHeaderBar = new AccessibleBrowseBoxHeaderBar(
215 m_aCreator, *mpBrowseBox, eObjType );
216 *pxMember = pHeaderBar;
218 xRet = pxMember->get();
220 return xRet;
223 css::uno::Reference< css::accessibility::XAccessible >
224 AccessibleBrowseBox::implGetFixedChild( sal_Int32 nChildIndex )
226 css::uno::Reference< css::accessibility::XAccessible > xRet;
227 switch( nChildIndex )
229 case vcl::BBINDEX_COLUMNHEADERBAR:
230 xRet = implGetHeaderBar( vcl::BBTYPE_COLUMNHEADERBAR );
231 break;
232 case vcl::BBINDEX_ROWHEADERBAR:
233 xRet = implGetHeaderBar( vcl::BBTYPE_ROWHEADERBAR );
234 break;
235 case vcl::BBINDEX_TABLE:
236 xRet = implGetTable();
237 break;
239 return xRet;
242 AccessibleBrowseBoxTable* AccessibleBrowseBox::createAccessibleTable()
244 css::uno::Reference< css::accessibility::XAccessible > xCreator(m_aCreator);
245 OSL_ENSURE( xCreator.is(), "extended/AccessibleBrowseBox::createAccessibleTable: my creator died - how this?" );
246 return new AccessibleBrowseBoxTable( xCreator, *mpBrowseBox );
249 void AccessibleBrowseBox::commitTableEvent(sal_Int16 _nEventId,const Any& _rNewValue,const Any& _rOldValue)
251 if ( mxTable.is() )
253 mxTable->commitEvent(_nEventId,_rNewValue,_rOldValue);
257 void AccessibleBrowseBox::commitHeaderBarEvent( sal_Int16 _nEventId,
258 const Any& _rNewValue,
259 const Any& _rOldValue,bool _bColumnHeaderBar)
261 rtl::Reference< AccessibleBrowseBoxHeaderBar >& xHeaderBar = _bColumnHeaderBar ? mxColumnHeaderBar : mxRowHeaderBar;
262 if ( xHeaderBar.is() )
263 xHeaderBar->commitEvent(_nEventId,_rNewValue,_rOldValue);
267 // = AccessibleBrowseBoxAccess
269 AccessibleBrowseBoxAccess::AccessibleBrowseBoxAccess( const css::uno::Reference< css::accessibility::XAccessible >& _rxParent, ::vcl::IAccessibleTableProvider& _rBrowseBox )
270 :m_xParent( _rxParent )
271 ,m_rBrowseBox( _rBrowseBox )
276 AccessibleBrowseBoxAccess::~AccessibleBrowseBoxAccess()
281 void AccessibleBrowseBoxAccess::dispose()
283 ::osl::MutexGuard aGuard( m_aMutex );
285 if (m_xContext.is())
287 m_xContext->dispose();
288 m_xContext.clear();
293 css::uno::Reference< css::accessibility::XAccessibleContext > SAL_CALL AccessibleBrowseBoxAccess::getAccessibleContext()
295 ::osl::MutexGuard aGuard( m_aMutex );
297 // if the context died meanwhile (there is no listener, so it won't tell us explicitly when this happens),
298 // then reset and re-create.
299 if ( m_xContext.is() && !m_xContext->isAlive() )
300 m_xContext = nullptr;
302 if ( !m_xContext.is() )
303 m_xContext = new AccessibleBrowseBox( m_xParent, this, m_rBrowseBox );
305 return m_xContext.get();
310 } // namespace accessibility
312 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */