1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 <com/sun/star/awt/XVclWindowPeer.hdl>
24 #include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
26 #include <vcl/accessibletableprovider.hxx>
27 #include <vcl/unohelp.hxx>
28 #include <sal/types.h>
31 namespace accessibility
34 using namespace ::com::sun::star::uno
;
35 using namespace ::com::sun::star
;
36 using namespace ::com::sun::star::lang
;
37 using namespace ::com::sun::star::accessibility
;
39 // Ctor/Dtor/disposing
41 AccessibleBrowseBox::AccessibleBrowseBox(
42 const css::uno::Reference
< css::accessibility::XAccessible
>& _rxParent
, const css::uno::Reference
< css::accessibility::XAccessible
>& _rxCreator
,
43 ::vcl::IAccessibleTableProvider
& _rBrowseBox
)
44 : AccessibleBrowseBoxBase(_rxParent
, _rBrowseBox
, nullptr, AccessibleBrowseBoxObjType::BrowseBox
)
45 , m_aCreator(_rxCreator
)
47 m_xFocusWindow
.set(mpBrowseBox
->GetWindowInstance()->GetComponentInterface(), css::uno::UNO_QUERY
);
50 void AccessibleBrowseBox::setCreator( const css::uno::Reference
< css::accessibility::XAccessible
>& _rxCreator
)
52 #if OSL_DEBUG_LEVEL > 0
53 css::uno::Reference
< css::accessibility::XAccessible
> xCreator(m_aCreator
);
54 OSL_ENSURE( !xCreator
.is(), "extended/AccessibleBrowseBox::setCreator: creator already set!" );
56 m_aCreator
= _rxCreator
;
60 AccessibleBrowseBox::~AccessibleBrowseBox()
65 void SAL_CALL
AccessibleBrowseBox::disposing()
67 ::osl::MutexGuard
aGuard( getMutex() );
76 if ( mxRowHeaderBar
.is() )
78 mxRowHeaderBar
->dispose();
79 mxRowHeaderBar
.clear();
81 if ( mxColumnHeaderBar
.is() )
83 mxColumnHeaderBar
->dispose();
84 mxColumnHeaderBar
.clear();
87 AccessibleBrowseBoxBase::disposing();
91 // css::accessibility::XAccessibleContext
93 sal_Int64 SAL_CALL
AccessibleBrowseBox::getAccessibleChildCount()
95 SolarMethodGuard
aGuard(getMutex());
98 return vcl::BBINDEX_FIRSTCONTROL
+ mpBrowseBox
->GetAccessibleControlCount();
102 css::uno::Reference
< css::accessibility::XAccessible
> SAL_CALL
103 AccessibleBrowseBox::getAccessibleChild( sal_Int64 nChildIndex
)
105 SolarMethodGuard
aGuard(getMutex());
108 if (nChildIndex
< 0 || nChildIndex
>= getAccessibleChildCount())
109 throw lang::IndexOutOfBoundsException();
111 css::uno::Reference
< css::accessibility::XAccessible
> xRet
;
112 if( nChildIndex
>= 0 )
114 if( nChildIndex
< vcl::BBINDEX_FIRSTCONTROL
)
115 xRet
= implGetFixedChild( nChildIndex
);
118 // additional controls
119 nChildIndex
-= vcl::BBINDEX_FIRSTCONTROL
;
120 if( nChildIndex
< mpBrowseBox
->GetAccessibleControlCount() )
121 xRet
= mpBrowseBox
->CreateAccessibleControl( nChildIndex
);
126 throw lang::IndexOutOfBoundsException();
130 // css::accessibility::XAccessibleComponent
132 css::uno::Reference
< css::accessibility::XAccessible
> SAL_CALL
133 AccessibleBrowseBox::getAccessibleAtPoint( const awt::Point
& rPoint
)
135 SolarMethodGuard
aGuard(getMutex());
138 sal_Int32 nIndex
= 0;
139 if (mpBrowseBox
->ConvertPointToControlIndex(nIndex
, vcl::unohelper::ConvertToVCLPoint(rPoint
)))
140 return mpBrowseBox
->CreateAccessibleControl(nIndex
);
142 // try whether point is in one of the fixed children
143 // (table, header bars, corner control)
144 Point
aPoint(vcl::unohelper::ConvertToVCLPoint(rPoint
));
145 for (nIndex
= 0; nIndex
< vcl::BBINDEX_FIRSTCONTROL
; ++nIndex
)
147 css::uno::Reference
< css::accessibility::XAccessible
> xCurrChild(implGetFixedChild(nIndex
));
148 css::uno::Reference
< css::accessibility::XAccessibleComponent
>
149 xCurrChildComp( xCurrChild
, uno::UNO_QUERY
);
151 if (xCurrChildComp
.is()
152 && vcl::unohelper::ConvertToVCLRect(xCurrChildComp
->getBounds()).Contains(aPoint
))
159 void SAL_CALL
AccessibleBrowseBox::grabFocus()
161 SolarMethodGuard
aGuard(getMutex());
164 mpBrowseBox
->GrabFocus();
168 OUString SAL_CALL
AccessibleBrowseBox::getImplementationName()
170 return u
"com.sun.star.comp.svtools.AccessibleBrowseBox"_ustr
;
173 // internal virtual methods
174 tools::Rectangle
AccessibleBrowseBox::implGetBoundingBox()
176 vcl::Window
* pParent
= mpBrowseBox
->GetAccessibleParentWindow();
177 assert(pParent
&& "implGetBoundingBox - missing parent window");
178 return mpBrowseBox
->GetWindowExtentsRelative( *pParent
);
181 AbsoluteScreenPixelRectangle
AccessibleBrowseBox::implGetBoundingBoxOnScreen()
183 return mpBrowseBox
->GetWindowExtentsAbsolute();
186 // internal helper methods
187 css::uno::Reference
< css::accessibility::XAccessible
> AccessibleBrowseBox::implGetTable()
191 mxTable
= createAccessibleTable();
197 css::uno::Reference
< css::accessibility::XAccessible
>
198 AccessibleBrowseBox::implGetHeaderBar(AccessibleBrowseBoxObjType eObjType
)
200 if( eObjType
== AccessibleBrowseBoxObjType::RowHeaderBar
)
202 if (!mxRowHeaderBar
.is())
203 mxRowHeaderBar
= new AccessibleBrowseBoxHeaderBar(m_aCreator
, *mpBrowseBox
, eObjType
);
204 return mxRowHeaderBar
;
206 else if( eObjType
== AccessibleBrowseBoxObjType::ColumnHeaderBar
)
208 if (!mxColumnHeaderBar
.is())
209 mxColumnHeaderBar
= new AccessibleBrowseBoxHeaderBar(m_aCreator
, *mpBrowseBox
, eObjType
);
210 return mxColumnHeaderBar
;
213 return css::uno::Reference
<css::accessibility::XAccessible
>();
216 css::uno::Reference
< css::accessibility::XAccessible
>
217 AccessibleBrowseBox::implGetFixedChild( sal_Int64 nChildIndex
)
219 css::uno::Reference
< css::accessibility::XAccessible
> xRet
;
220 switch( nChildIndex
)
222 case vcl::BBINDEX_COLUMNHEADERBAR
:
223 xRet
= implGetHeaderBar( AccessibleBrowseBoxObjType::ColumnHeaderBar
);
225 case vcl::BBINDEX_ROWHEADERBAR
:
226 xRet
= implGetHeaderBar( AccessibleBrowseBoxObjType::RowHeaderBar
);
228 case vcl::BBINDEX_TABLE
:
229 xRet
= implGetTable();
235 rtl::Reference
<AccessibleBrowseBoxTable
> AccessibleBrowseBox::createAccessibleTable()
237 css::uno::Reference
< css::accessibility::XAccessible
> xCreator(m_aCreator
);
238 OSL_ENSURE( xCreator
.is(), "extended/AccessibleBrowseBox::createAccessibleTable: my creator died - how this?" );
239 return new AccessibleBrowseBoxTable( xCreator
, *mpBrowseBox
);
242 void AccessibleBrowseBox::commitTableEvent(sal_Int16 _nEventId
,const Any
& _rNewValue
,const Any
& _rOldValue
)
246 mxTable
->commitEvent(_nEventId
,_rNewValue
,_rOldValue
);
250 void AccessibleBrowseBox::commitHeaderBarEvent( sal_Int16 _nEventId
,
251 const Any
& _rNewValue
,
252 const Any
& _rOldValue
,bool _bColumnHeaderBar
)
254 rtl::Reference
< AccessibleBrowseBoxHeaderBar
>& xHeaderBar
= _bColumnHeaderBar
? mxColumnHeaderBar
: mxRowHeaderBar
;
255 if ( xHeaderBar
.is() )
256 xHeaderBar
->commitEvent(_nEventId
,_rNewValue
,_rOldValue
);
260 // = AccessibleBrowseBoxAccess
262 AccessibleBrowseBoxAccess::AccessibleBrowseBoxAccess( css::uno::Reference
< css::accessibility::XAccessible
> _xParent
, ::vcl::IAccessibleTableProvider
& _rBrowseBox
)
263 :m_xParent(std::move( _xParent
))
264 ,m_rBrowseBox( _rBrowseBox
)
269 AccessibleBrowseBoxAccess::~AccessibleBrowseBoxAccess()
274 void AccessibleBrowseBoxAccess::dispose()
276 std::unique_lock
aGuard( m_aMutex
);
280 m_xContext
->dispose();
287 css::uno::Reference
< css::accessibility::XAccessibleContext
> SAL_CALL
AccessibleBrowseBoxAccess::getAccessibleContext()
289 std::unique_lock
aGuard( m_aMutex
);
291 // if the context died meanwhile (there is no listener, so it won't tell us explicitly when this happens),
292 // then reset and re-create.
293 if ( m_xContext
.is() && !m_xContext
->isAlive() )
294 m_xContext
= nullptr;
296 if ( !m_xContext
.is() )
297 m_xContext
= new AccessibleBrowseBox( m_xParent
, this, m_rBrowseBox
);
304 } // namespace accessibility
306 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */