Gtk-WARNING gtktreestore.c:1047: Invalid column number 1 added to iter
[LibreOffice.git] / accessibility / source / extended / AccessibleBrowseBoxBase.cxx
blob5557ba691564ed9c5911755ec06d4df6a86c2812
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/AccessibleBrowseBoxBase.hxx>
21 #include <utility>
22 #include <vcl/accessibletableprovider.hxx>
23 #include <cppuhelper/supportsservice.hxx>
25 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
26 #include <com/sun/star/accessibility/AccessibleRole.hpp>
27 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
28 #include <com/sun/star/accessibility/IllegalAccessibleComponentStateException.hpp>
29 #include <unotools/accessiblerelationsethelper.hxx>
30 #include <vcl/unohelp.hxx>
31 #include <vcl/window.hxx>
32 #include <vcl/svapp.hxx>
33 #include <sal/log.hxx>
36 using ::com::sun::star::uno::Reference;
37 using ::com::sun::star::uno::Sequence;
38 using ::com::sun::star::uno::Any;
40 using namespace ::com::sun::star;
41 using namespace ::com::sun::star::accessibility;
42 using namespace ::comphelper;
45 namespace accessibility {
47 using namespace com::sun::star::accessibility::AccessibleStateType;
50 // Ctor/Dtor/disposing
52 AccessibleBrowseBoxBase::AccessibleBrowseBoxBase(
53 const css::uno::Reference<css::accessibility::XAccessible>& xParent,
54 ::vcl::IAccessibleTableProvider& rBrowseBox,
55 const css::uno::Reference<css::awt::XWindow>& xFocusWindow, AccessibleBrowseBoxObjType eObjType)
56 : AccessibleBrowseBoxBase(xParent, rBrowseBox, xFocusWindow, eObjType,
57 rBrowseBox.GetAccessibleObjectName(eObjType),
58 rBrowseBox.GetAccessibleObjectDescription(eObjType))
62 AccessibleBrowseBoxBase::AccessibleBrowseBoxBase(
63 css::uno::Reference< css::accessibility::XAccessible > rxParent,
64 ::vcl::IAccessibleTableProvider& rBrowseBox,
65 css::uno::Reference< css::awt::XWindow > _xFocusWindow,
66 AccessibleBrowseBoxObjType eObjType,
67 OUString rName,
68 OUString rDescription ) :
69 AccessibleBrowseBoxImplHelper( m_aMutex ),
70 mxParent(std::move( rxParent )),
71 mpBrowseBox( &rBrowseBox ),
72 m_xFocusWindow(std::move(_xFocusWindow)),
73 maName(std::move( rName )),
74 maDescription(std::move( rDescription )),
75 meObjType( eObjType ),
76 m_aClientId(0)
78 if ( m_xFocusWindow.is() )
79 m_xFocusWindow->addFocusListener( this );
82 AccessibleBrowseBoxBase::~AccessibleBrowseBoxBase()
84 if( isAlive() )
86 // increment ref count to prevent double call of Dtor
87 osl_atomic_increment( &m_refCount );
88 dispose();
92 void SAL_CALL AccessibleBrowseBoxBase::disposing()
94 ::osl::MutexGuard aGuard( getMutex() );
95 if ( m_xFocusWindow.is() )
97 SolarMutexGuard aSolarGuard;
98 m_xFocusWindow->removeFocusListener( this );
101 if ( getClientId( ) )
103 AccessibleEventNotifier::TClientId nId( getClientId( ) );
104 setClientId( 0 );
105 AccessibleEventNotifier::revokeClientNotifyDisposing( nId, *this );
108 mxParent = nullptr;
109 mpBrowseBox = nullptr;
112 // css::accessibility::XAccessibleContext
114 Reference< css::accessibility::XAccessible > SAL_CALL AccessibleBrowseBoxBase::getAccessibleParent()
116 ::osl::MutexGuard aGuard( getMutex() );
117 ensureIsAlive();
118 return mxParent;
121 sal_Int64 SAL_CALL AccessibleBrowseBoxBase::getAccessibleIndexInParent()
123 ::osl::MutexGuard aGuard( getMutex() );
124 ensureIsAlive();
126 // -1 for child not found/no parent (according to specification)
127 sal_Int64 nRet = -1;
129 css::uno::Reference< uno::XInterface > xMeMyselfAndI( static_cast< css::accessibility::XAccessibleContext* >( this ), uno::UNO_QUERY );
131 // iterate over parent's children and search for this object
132 if( mxParent.is() )
134 css::uno::Reference< css::accessibility::XAccessibleContext >
135 xParentContext( mxParent->getAccessibleContext() );
136 if( xParentContext.is() )
138 css::uno::Reference< uno::XInterface > xChild;
140 sal_Int64 nChildCount = xParentContext->getAccessibleChildCount();
141 for( sal_Int64 nChild = 0; nChild < nChildCount; ++nChild )
143 xChild.set(xParentContext->getAccessibleChild( nChild ), css::uno::UNO_QUERY);
145 if ( xMeMyselfAndI.get() == xChild.get() )
147 nRet = nChild;
148 break;
153 return nRet;
156 OUString SAL_CALL AccessibleBrowseBoxBase::getAccessibleDescription()
158 ::osl::MutexGuard aGuard( getMutex() );
159 ensureIsAlive();
160 return maDescription;
163 OUString SAL_CALL AccessibleBrowseBoxBase::getAccessibleName()
165 ::osl::MutexGuard aGuard( getMutex() );
166 ensureIsAlive();
167 return maName;
170 Reference< css::accessibility::XAccessibleRelationSet > SAL_CALL
171 AccessibleBrowseBoxBase::getAccessibleRelationSet()
173 ::osl::MutexGuard aGuard( getMutex() );
174 ensureIsAlive();
175 // BrowseBox does not have relations.
176 return new utl::AccessibleRelationSetHelper;
179 sal_Int64 SAL_CALL
180 AccessibleBrowseBoxBase::getAccessibleStateSet()
182 SolarMethodGuard aGuard( getMutex() );
183 // don't check whether alive -> StateSet may contain DEFUNC
184 return implCreateStateSet();
187 lang::Locale SAL_CALL AccessibleBrowseBoxBase::getLocale()
189 ::osl::MutexGuard aGuard( getMutex() );
190 ensureIsAlive();
191 if( mxParent.is() )
193 css::uno::Reference< css::accessibility::XAccessibleContext >
194 xParentContext( mxParent->getAccessibleContext() );
195 if( xParentContext.is() )
196 return xParentContext->getLocale();
198 throw IllegalAccessibleComponentStateException();
201 // css::accessibility::XAccessibleComponent
203 sal_Bool SAL_CALL AccessibleBrowseBoxBase::containsPoint( const css::awt::Point& rPoint )
205 return tools::Rectangle(Point(), getBoundingBox().GetSize())
206 .Contains(vcl::unohelper::ConvertToVCLPoint(rPoint));
209 awt::Rectangle SAL_CALL AccessibleBrowseBoxBase::getBounds()
211 return vcl::unohelper::ConvertToAWTRect(getBoundingBox());
214 awt::Point SAL_CALL AccessibleBrowseBoxBase::getLocation()
216 return vcl::unohelper::ConvertToAWTPoint(getBoundingBox().TopLeft());
219 awt::Point SAL_CALL AccessibleBrowseBoxBase::getLocationOnScreen()
221 return vcl::unohelper::ConvertToAWTPoint(getBoundingBoxOnScreen().TopLeft());
224 awt::Size SAL_CALL AccessibleBrowseBoxBase::getSize()
226 return vcl::unohelper::ConvertToAWTSize(getBoundingBox().GetSize());
229 void SAL_CALL AccessibleBrowseBoxBase::focusGained( const css::awt::FocusEvent& )
231 css::uno::Any aFocused;
232 css::uno::Any aEmpty;
233 aFocused <<= FOCUSED;
235 commitEvent(AccessibleEventId::STATE_CHANGED,aFocused,aEmpty);
239 void SAL_CALL AccessibleBrowseBoxBase::focusLost( const css::awt::FocusEvent& )
241 css::uno::Any aFocused;
242 css::uno::Any aEmpty;
243 aFocused <<= FOCUSED;
245 commitEvent(AccessibleEventId::STATE_CHANGED,aEmpty,aFocused);
247 // css::accessibility::XAccessibleEventBroadcaster
249 void SAL_CALL AccessibleBrowseBoxBase::addAccessibleEventListener(
250 const css::uno::Reference< css::accessibility::XAccessibleEventListener>& _rxListener )
252 if ( _rxListener.is() )
254 ::osl::MutexGuard aGuard( getMutex() );
255 if ( !getClientId( ) )
256 setClientId( AccessibleEventNotifier::registerClient( ) );
258 AccessibleEventNotifier::addEventListener( getClientId( ), _rxListener );
262 void SAL_CALL AccessibleBrowseBoxBase::removeAccessibleEventListener(
263 const css::uno::Reference< css::accessibility::XAccessibleEventListener>& _rxListener )
265 if( !(_rxListener.is() && getClientId( )) )
266 return;
268 ::osl::MutexGuard aGuard( getMutex() );
269 sal_Int32 nListenerCount = AccessibleEventNotifier::removeEventListener( getClientId( ), _rxListener );
270 if ( !nListenerCount )
272 // no listeners anymore
273 // -> revoke ourself. This may lead to the notifier thread dying (if we were the last client),
274 // and at least to us not firing any events anymore, in case somebody calls
275 // NotifyAccessibleEvent, again
277 AccessibleEventNotifier::TClientId nId( getClientId( ) );
278 setClientId( 0 );
279 AccessibleEventNotifier::revokeClient( nId );
283 // XTypeProvider
285 Sequence< sal_Int8 > SAL_CALL AccessibleBrowseBoxBase::getImplementationId()
287 return css::uno::Sequence<sal_Int8>();
290 // XServiceInfo
292 sal_Bool SAL_CALL AccessibleBrowseBoxBase::supportsService(
293 const OUString& rServiceName )
295 return cppu::supportsService(this, rServiceName);
298 Sequence< OUString > SAL_CALL AccessibleBrowseBoxBase::getSupportedServiceNames()
300 return { u"com.sun.star.accessibility.AccessibleContext"_ustr };
303 // other public methods
305 void AccessibleBrowseBoxBase::setAccessibleName( const OUString& rName )
307 ::osl::ClearableMutexGuard aGuard( getMutex() );
308 Any aOld;
309 aOld <<= maName;
310 maName = rName;
312 aGuard.clear();
314 commitEvent(
315 AccessibleEventId::NAME_CHANGED,
316 uno::Any( maName ),
317 aOld );
320 void AccessibleBrowseBoxBase::setAccessibleDescription( const OUString& rDescription )
322 ::osl::ClearableMutexGuard aGuard( getMutex() );
323 Any aOld;
324 aOld <<= maDescription;
325 maDescription = rDescription;
327 aGuard.clear();
329 commitEvent(
330 AccessibleEventId::DESCRIPTION_CHANGED,
331 uno::Any( maDescription ),
332 aOld );
335 // internal virtual methods
337 bool AccessibleBrowseBoxBase::implIsShowing()
339 bool bShowing = false;
340 if( mxParent.is() )
342 css::uno::Reference< css::accessibility::XAccessibleComponent >
343 xParentComp( mxParent->getAccessibleContext(), uno::UNO_QUERY );
344 if( xParentComp.is() )
345 bShowing = implGetBoundingBox().Overlaps(
346 vcl::unohelper::ConvertToVCLRect(xParentComp->getBounds()));
348 return bShowing;
351 sal_Int64 AccessibleBrowseBoxBase::implCreateStateSet()
353 sal_Int64 nStateSet = 0;
355 if( isAlive() )
357 // SHOWING done with mxParent
358 if( implIsShowing() )
359 nStateSet |= AccessibleStateType::SHOWING;
360 // BrowseBox fills StateSet with states depending on object type
361 mpBrowseBox->FillAccessibleStateSet( nStateSet, getType() );
363 else
364 nStateSet |= AccessibleStateType::DEFUNC;
366 return nStateSet;
369 // internal helper methods
371 bool AccessibleBrowseBoxBase::isAlive() const
373 return !rBHelper.bDisposed && !rBHelper.bInDispose && mpBrowseBox;
376 void AccessibleBrowseBoxBase::ensureIsAlive() const
378 if( !isAlive() )
379 throw lang::DisposedException();
382 tools::Rectangle AccessibleBrowseBoxBase::getBoundingBox()
384 SolarMethodGuard aGuard(getMutex());
385 ensureIsAlive();
387 tools::Rectangle aRect = implGetBoundingBox();
388 if ( aRect.Left() == 0 && aRect.Top() == 0 && aRect.Right() == 0 && aRect.Bottom() == 0 )
390 SAL_WARN( "accessibility", "rectangle doesn't exist" );
392 return aRect;
395 AbsoluteScreenPixelRectangle AccessibleBrowseBoxBase::getBoundingBoxOnScreen()
397 SolarMethodGuard aGuard(getMutex());
398 ensureIsAlive();
400 AbsoluteScreenPixelRectangle aRect = implGetBoundingBoxOnScreen();
401 if ( aRect.Left() == 0 && aRect.Top() == 0 && aRect.Right() == 0 && aRect.Bottom() == 0 )
403 SAL_WARN( "accessibility", "rectangle doesn't exist" );
405 return aRect;
408 void AccessibleBrowseBoxBase::commitEvent(
409 sal_Int16 _nEventId, const Any& _rNewValue, const Any& _rOldValue )
411 osl::MutexGuard aGuard( getMutex() );
412 if ( !getClientId( ) )
413 // if we don't have a client id for the notifier, then we don't have listeners, then
414 // we don't need to notify anything
415 return;
417 // build an event object
418 AccessibleEventObject aEvent(*this, _nEventId, _rNewValue, _rOldValue, -1);
420 // let the notifier handle this event
422 AccessibleEventNotifier::addEvent( getClientId( ), aEvent );
425 sal_Int16 SAL_CALL AccessibleBrowseBoxBase::getAccessibleRole()
427 osl::MutexGuard aGuard( getMutex() );
428 ensureIsAlive();
429 sal_Int16 nRole = AccessibleRole::UNKNOWN;
430 switch ( meObjType )
432 case AccessibleBrowseBoxObjType::RowHeaderCell:
433 nRole = AccessibleRole::ROW_HEADER;
434 break;
435 case AccessibleBrowseBoxObjType::ColumnHeaderCell:
436 nRole = AccessibleRole::COLUMN_HEADER;
437 break;
438 case AccessibleBrowseBoxObjType::ColumnHeaderBar:
439 case AccessibleBrowseBoxObjType::RowHeaderBar:
440 case AccessibleBrowseBoxObjType::Table:
441 nRole = AccessibleRole::TABLE;
442 break;
443 case AccessibleBrowseBoxObjType::TableCell:
444 nRole = AccessibleRole::TABLE_CELL;
445 break;
446 case AccessibleBrowseBoxObjType::BrowseBox:
447 nRole = AccessibleRole::PANEL;
448 break;
449 case AccessibleBrowseBoxObjType::CheckBoxCell:
450 nRole = AccessibleRole::CHECK_BOX;
451 break;
453 return nRole;
456 Reference<XAccessible > SAL_CALL AccessibleBrowseBoxBase::getAccessibleAtPoint( const css::awt::Point& )
458 return nullptr;
461 void SAL_CALL AccessibleBrowseBoxBase::disposing( const css::lang::EventObject& )
463 m_xFocusWindow = nullptr;
466 sal_Int32 SAL_CALL AccessibleBrowseBoxBase::getForeground( )
468 SolarMethodGuard aGuard(getMutex());
469 ensureIsAlive();
471 Color nColor;
472 vcl::Window* pInst = mpBrowseBox->GetWindowInstance();
473 if ( pInst )
475 if ( pInst->IsControlForeground() )
476 nColor = pInst->GetControlForeground();
477 else
479 vcl::Font aFont;
480 if ( pInst->IsControlFont() )
481 aFont = pInst->GetControlFont();
482 else
483 aFont = pInst->GetFont();
484 nColor = aFont.GetColor();
488 return sal_Int32(nColor);
491 sal_Int32 SAL_CALL AccessibleBrowseBoxBase::getBackground( )
493 SolarMethodGuard aGuard(getMutex());
494 ensureIsAlive();
496 Color nColor;
497 vcl::Window* pInst = mpBrowseBox->GetWindowInstance();
498 if ( pInst )
500 if ( pInst->IsControlBackground() )
501 nColor = pInst->GetControlBackground();
502 else
503 nColor = pInst->GetBackground().GetColor();
506 return sal_Int32(nColor);
510 // css::accessibility::XAccessible
512 Reference< css::accessibility::XAccessibleContext > SAL_CALL BrowseBoxAccessibleElement::getAccessibleContext()
514 osl::MutexGuard aGuard( getMutex() );
515 ensureIsAlive();
516 return this;
520 BrowseBoxAccessibleElement::BrowseBoxAccessibleElement( const css::uno::Reference< css::accessibility::XAccessible >& rxParent, ::vcl::IAccessibleTableProvider& rBrowseBox,
521 AccessibleBrowseBoxObjType eObjType )
522 : BrowseBoxAccessibleElement_Base(rxParent, rBrowseBox, nullptr, eObjType)
527 BrowseBoxAccessibleElement::BrowseBoxAccessibleElement( const css::uno::Reference< css::accessibility::XAccessible >& rxParent, ::vcl::IAccessibleTableProvider& rBrowseBox,
528 AccessibleBrowseBoxObjType eObjType, const OUString& rName, const OUString& rDescription )
529 : BrowseBoxAccessibleElement_Base(rxParent, rBrowseBox, nullptr, eObjType, rName, rDescription)
534 BrowseBoxAccessibleElement::~BrowseBoxAccessibleElement( )
539 } // namespace accessibility
542 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */