fix baseline build (old cairo) - 'cairo_rectangle_int_t' does not name a type
[LibreOffice.git] / sc / source / ui / Accessibility / AccessibleContextBase.cxx
blobc4d7c53b968070fb82ce9888cd0e6d9606bda37a
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 "AccessibleContextBase.hxx"
21 #include <com/sun/star/accessibility/AccessibleRole.hpp>
22 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
23 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
24 #include <com/sun/star/beans/PropertyChangeEvent.hpp>
25 #include <tools/debug.hxx>
26 #include <tools/gen.hxx>
27 #include <unotools/accessiblestatesethelper.hxx>
28 #include <toolkit/helper/convert.hxx>
29 #include <svl/smplhint.hxx>
30 #include <comphelper/sequence.hxx>
31 #include <comphelper/servicehelper.hxx>
32 #include <cppuhelper/supportsservice.hxx>
33 #include <unotools/accessiblerelationsethelper.hxx>
34 #include <vcl/unohelp.hxx>
35 #include <comphelper/accessibleeventnotifier.hxx>
36 #include <vcl/svapp.hxx>
38 using namespace ::com::sun::star;
39 using namespace ::com::sun::star::accessibility;
41 ScAccessibleContextBase::ScAccessibleContextBase(
42 const uno::Reference<XAccessible>& rxParent,
43 const sal_Int16 aRole)
45 ScAccessibleContextBaseWeakImpl(m_aMutex),
46 mxParent(rxParent),
47 mnClientId(0),
48 maRole(aRole)
52 ScAccessibleContextBase::~ScAccessibleContextBase()
54 if (!IsDefunc() && !rBHelper.bInDispose)
56 // increment refcount to prevent double call off dtor
57 osl_atomic_increment( &m_refCount );
58 // call dispose to inform object which have a weak reference to this object
59 dispose();
63 void ScAccessibleContextBase::Init()
65 // hold reference to make sure that the destructor is not called
66 uno::Reference< XAccessibleContext > xOwnContext(this);
68 if (mxParent.is())
70 uno::Reference< XAccessibleEventBroadcaster > xBroadcaster (mxParent->getAccessibleContext(), uno::UNO_QUERY);
71 if (xBroadcaster.is())
72 xBroadcaster->addAccessibleEventListener(this);
74 msName = createAccessibleName();
75 msDescription = createAccessibleDescription();
78 void SAL_CALL ScAccessibleContextBase::disposing()
80 SolarMutexGuard aGuard;
81 // CommitDefunc(); not necessary and should not be send, because it cost a lot of time
83 // hold reference to make sure that the destructor is not called
84 uno::Reference< XAccessibleContext > xOwnContext(this);
86 if ( mnClientId )
88 sal_Int32 nTemClientId(mnClientId);
89 mnClientId = 0;
90 comphelper::AccessibleEventNotifier::revokeClientNotifyDisposing( nTemClientId, *this );
93 if (mxParent.is())
95 uno::Reference< XAccessibleEventBroadcaster > xBroadcaster (mxParent->getAccessibleContext(), uno::UNO_QUERY);
96 if (xBroadcaster.is())
97 xBroadcaster->removeAccessibleEventListener(this);
98 mxParent = NULL;
101 ScAccessibleContextBaseWeakImpl::disposing();
104 //===== XInterface =====================================================
106 uno::Any SAL_CALL ScAccessibleContextBase::queryInterface( uno::Type const & rType )
107 throw (uno::RuntimeException, std::exception)
109 uno::Any aAny (ScAccessibleContextBaseWeakImpl::queryInterface(rType));
110 return aAny.hasValue() ? aAny : ScAccessibleContextBaseImplEvent::queryInterface(rType);
113 void SAL_CALL ScAccessibleContextBase::acquire()
114 throw ()
116 ScAccessibleContextBaseWeakImpl::acquire();
119 void SAL_CALL ScAccessibleContextBase::release()
120 throw ()
122 ScAccessibleContextBaseWeakImpl::release();
125 //===== SfxListener =====================================================
127 void ScAccessibleContextBase::Notify( SfxBroadcaster&, const SfxHint& rHint )
129 const SfxSimpleHint* pSimpleHint = dynamic_cast<const SfxSimpleHint*>(&rHint);
130 if (pSimpleHint)
132 if (pSimpleHint->GetId() == SFX_HINT_DYING)
134 // it seems the Broadcaster is dying, since the view is dying
135 dispose();
140 //===== XAccessible =========================================================
142 uno::Reference< XAccessibleContext> SAL_CALL
143 ScAccessibleContextBase::getAccessibleContext()
144 throw (uno::RuntimeException, std::exception)
146 return this;
149 //===== XAccessibleComponent ================================================
151 sal_Bool SAL_CALL ScAccessibleContextBase::containsPoint(const awt::Point& rPoint )
152 throw (uno::RuntimeException, std::exception)
154 SolarMutexGuard aGuard;
155 IsObjectValid();
156 return Rectangle (Point(), GetBoundingBox().GetSize()).IsInside(VCLPoint(rPoint));
159 uno::Reference< XAccessible > SAL_CALL ScAccessibleContextBase::getAccessibleAtPoint(
160 const awt::Point& /* rPoint */ )
161 throw (uno::RuntimeException, std::exception)
163 OSL_FAIL("not implemented");
164 return uno::Reference<XAccessible>();
167 awt::Rectangle SAL_CALL ScAccessibleContextBase::getBounds( )
168 throw (uno::RuntimeException, std::exception)
170 SolarMutexGuard aGuard;
171 IsObjectValid();
172 return AWTRectangle(GetBoundingBox());
175 awt::Point SAL_CALL ScAccessibleContextBase::getLocation( )
176 throw (uno::RuntimeException, std::exception)
178 SolarMutexGuard aGuard;
179 IsObjectValid();
180 return AWTPoint(GetBoundingBox().TopLeft());
183 awt::Point SAL_CALL ScAccessibleContextBase::getLocationOnScreen( )
184 throw (uno::RuntimeException, std::exception)
186 SolarMutexGuard aGuard;
187 IsObjectValid();
188 return AWTPoint(GetBoundingBoxOnScreen().TopLeft());
191 awt::Size SAL_CALL ScAccessibleContextBase::getSize( )
192 throw (uno::RuntimeException, std::exception)
194 SolarMutexGuard aGuard;
195 IsObjectValid();
196 return AWTSize(GetBoundingBox().GetSize());
199 bool SAL_CALL ScAccessibleContextBase::isShowing( )
200 throw (uno::RuntimeException)
202 SolarMutexGuard aGuard;
203 IsObjectValid();
204 bool bShowing(false);
205 if (mxParent.is())
207 uno::Reference<XAccessibleComponent> xParentComponent (mxParent->getAccessibleContext(), uno::UNO_QUERY);
208 if (xParentComponent.is())
210 Rectangle aParentBounds(VCLRectangle(xParentComponent->getBounds()));
211 Rectangle aBounds(VCLRectangle(getBounds()));
212 bShowing = aBounds.IsOver(aParentBounds);
215 return bShowing;
218 bool SAL_CALL ScAccessibleContextBase::isVisible()
219 throw (uno::RuntimeException, std::exception)
221 return true;
224 void SAL_CALL ScAccessibleContextBase::grabFocus( )
225 throw (uno::RuntimeException, std::exception)
227 OSL_FAIL("not implemented");
230 sal_Int32 SAL_CALL ScAccessibleContextBase::getForeground( )
231 throw (uno::RuntimeException, std::exception)
233 return COL_BLACK;
236 sal_Int32 SAL_CALL ScAccessibleContextBase::getBackground( )
237 throw (uno::RuntimeException, std::exception)
239 return COL_WHITE;
242 //===== XAccessibleContext ==================================================
244 sal_Int32 SAL_CALL ScAccessibleContextBase::getAccessibleChildCount()
245 throw (uno::RuntimeException, std::exception)
247 OSL_FAIL("should be implemented in the abrevated class");
248 return 0;
251 uno::Reference<XAccessible> SAL_CALL
252 ScAccessibleContextBase::getAccessibleChild(sal_Int32 /* nIndex */)
253 throw (lang::IndexOutOfBoundsException, uno::RuntimeException,
254 std::exception)
256 OSL_FAIL("should be implemented in the abrevated class");
257 return uno::Reference<XAccessible>();
260 uno::Reference<XAccessible> SAL_CALL
261 ScAccessibleContextBase::getAccessibleParent()
262 throw (uno::RuntimeException, std::exception)
264 return mxParent;
267 sal_Int32 SAL_CALL
268 ScAccessibleContextBase::getAccessibleIndexInParent()
269 throw (uno::RuntimeException, std::exception)
271 SolarMutexGuard aGuard;
272 IsObjectValid();
273 // Use a simple but slow solution for now. Optimize later.
274 // Return -1 to indicate that this object's parent does not know about the
275 // object.
276 sal_Int32 nIndex(-1);
278 // Iterate over all the parent's children and search for this object.
279 if (mxParent.is())
281 uno::Reference<XAccessibleContext> xParentContext (
282 mxParent->getAccessibleContext());
283 if (xParentContext.is())
285 sal_Int32 nChildCount = xParentContext->getAccessibleChildCount();
286 for (sal_Int32 i=0; i<nChildCount; ++i)
288 uno::Reference<XAccessible> xChild (xParentContext->getAccessibleChild (i));
289 if (xChild.is())
291 if (xChild.get() == this)
292 nIndex = i;
298 return nIndex;
301 sal_Int16 SAL_CALL
302 ScAccessibleContextBase::getAccessibleRole()
303 throw (uno::RuntimeException, std::exception)
305 return maRole;
308 OUString SAL_CALL
309 ScAccessibleContextBase::getAccessibleDescription()
310 throw (uno::RuntimeException, std::exception)
312 SolarMutexGuard aGuard;
313 IsObjectValid();
314 if (msDescription.isEmpty())
316 OUString sDescription(createAccessibleDescription());
318 if (msDescription != sDescription)
320 AccessibleEventObject aEvent;
321 aEvent.EventId = AccessibleEventId::DESCRIPTION_CHANGED;
322 aEvent.Source = uno::Reference< XAccessibleContext >(this);
323 aEvent.OldValue <<= msDescription;
324 aEvent.NewValue <<= sDescription;
326 msDescription = sDescription;
328 CommitChange(aEvent);
331 return msDescription;
334 OUString SAL_CALL
335 ScAccessibleContextBase::getAccessibleName()
336 throw (uno::RuntimeException, std::exception)
338 SolarMutexGuard aGuard;
339 IsObjectValid();
340 if (msName.isEmpty())
342 OUString sName(createAccessibleName());
343 OSL_ENSURE(!sName.isEmpty(), "We should give always a name.");
345 if (msName != sName)
347 AccessibleEventObject aEvent;
348 aEvent.EventId = AccessibleEventId::NAME_CHANGED;
349 aEvent.Source = uno::Reference< XAccessibleContext >(this);
350 aEvent.OldValue <<= msName;
351 aEvent.NewValue <<= sName;
353 msName = sName;
355 CommitChange(aEvent);
358 return msName;
361 uno::Reference<XAccessibleRelationSet> SAL_CALL
362 ScAccessibleContextBase::getAccessibleRelationSet()
363 throw (uno::RuntimeException, std::exception)
365 return new utl::AccessibleRelationSetHelper();
368 uno::Reference<XAccessibleStateSet> SAL_CALL
369 ScAccessibleContextBase::getAccessibleStateSet()
370 throw (uno::RuntimeException, std::exception)
372 return uno::Reference<XAccessibleStateSet>();
375 lang::Locale SAL_CALL
376 ScAccessibleContextBase::getLocale()
377 throw (IllegalAccessibleComponentStateException,
378 uno::RuntimeException, std::exception)
380 SolarMutexGuard aGuard;
381 IsObjectValid();
382 if (mxParent.is())
384 uno::Reference<XAccessibleContext> xParentContext (
385 mxParent->getAccessibleContext());
386 if (xParentContext.is())
387 return xParentContext->getLocale ();
390 // No locale and no parent. Therefore throw exception to indicate this
391 // cluelessness.
392 throw IllegalAccessibleComponentStateException ();
395 //===== XAccessibleEventBroadcaster =====================================
397 void SAL_CALL
398 ScAccessibleContextBase::addAccessibleEventListener(
399 const uno::Reference<XAccessibleEventListener>& xListener)
400 throw (uno::RuntimeException, std::exception)
402 if (xListener.is())
404 SolarMutexGuard aGuard;
405 IsObjectValid();
406 if (!IsDefunc())
408 if (!mnClientId)
409 mnClientId = comphelper::AccessibleEventNotifier::registerClient( );
410 comphelper::AccessibleEventNotifier::addEventListener( mnClientId, xListener );
415 void SAL_CALL
416 ScAccessibleContextBase::removeAccessibleEventListener(
417 const uno::Reference<XAccessibleEventListener>& xListener)
418 throw (uno::RuntimeException, std::exception)
420 if (xListener.is())
422 SolarMutexGuard aGuard;
423 if (!IsDefunc() && mnClientId)
425 sal_Int32 nListenerCount = comphelper::AccessibleEventNotifier::removeEventListener( mnClientId, xListener );
426 if ( !nListenerCount )
428 // no listeners anymore
429 // -> revoke ourself. This may lead to the notifier thread dying (if we were the last client),
430 // and at least to us not firing any events anymore, in case somebody calls
431 // NotifyAccessibleEvent, again
432 comphelper::AccessibleEventNotifier::revokeClient( mnClientId );
433 mnClientId = 0;
439 //===== XAccessibleEventListener ========================================
441 void SAL_CALL ScAccessibleContextBase::disposing(
442 const lang::EventObject& rSource )
443 throw (uno::RuntimeException, std::exception)
445 SolarMutexGuard aGuard;
446 if (rSource.Source == mxParent)
447 dispose();
450 void SAL_CALL ScAccessibleContextBase::notifyEvent(
451 const AccessibleEventObject& /* aEvent */ )
452 throw (uno::RuntimeException, std::exception)
456 // XServiceInfo
457 OUString SAL_CALL ScAccessibleContextBase::getImplementationName()
458 throw (uno::RuntimeException, std::exception)
460 return OUString("ScAccessibleContextBase");
463 sal_Bool SAL_CALL ScAccessibleContextBase::supportsService(const OUString& sServiceName)
464 throw (uno::RuntimeException, std::exception)
466 return cppu::supportsService(this, sServiceName);
469 uno::Sequence< OUString> SAL_CALL
470 ScAccessibleContextBase::getSupportedServiceNames()
471 throw (uno::RuntimeException, std::exception)
473 uno::Sequence<OUString> aServiceNames(2);
474 OUString* pServiceNames = aServiceNames.getArray();
475 if (pServiceNames)
477 pServiceNames[0] = "com.sun.star.accessibility.Accessible";
478 pServiceNames[1] = "com.sun.star.accessibility.AccessibleContext";
481 return aServiceNames;
484 //===== XTypeProvider =======================================================
486 uno::Sequence< uno::Type > SAL_CALL ScAccessibleContextBase::getTypes()
487 throw (uno::RuntimeException, std::exception)
489 return comphelper::concatSequences(ScAccessibleContextBaseWeakImpl::getTypes(), ScAccessibleContextBaseImplEvent::getTypes());
492 uno::Sequence<sal_Int8> SAL_CALL
493 ScAccessibleContextBase::getImplementationId()
494 throw (uno::RuntimeException, std::exception)
496 return css::uno::Sequence<sal_Int8>();
499 //===== internal ============================================================
501 OUString SAL_CALL
502 ScAccessibleContextBase::createAccessibleDescription()
503 throw (uno::RuntimeException)
505 OSL_FAIL("should be implemented in the abrevated class");
506 return OUString();
509 OUString SAL_CALL ScAccessibleContextBase::createAccessibleName()
510 throw (uno::RuntimeException, std::exception)
512 OSL_FAIL("should be implemented in the abrevated class");
513 return OUString();
516 void ScAccessibleContextBase::CommitChange(const AccessibleEventObject& rEvent) const
518 if (mnClientId)
519 comphelper::AccessibleEventNotifier::addEvent( mnClientId, rEvent );
522 void ScAccessibleContextBase::CommitFocusGained() const
524 AccessibleEventObject aEvent;
525 aEvent.EventId = AccessibleEventId::STATE_CHANGED;
526 aEvent.Source = uno::Reference< XAccessibleContext >(const_cast<ScAccessibleContextBase*>(this));
527 aEvent.NewValue <<= AccessibleStateType::FOCUSED;
529 CommitChange(aEvent);
531 vcl::unohelper::NotifyAccessibleStateEventGlobally(aEvent);
534 void ScAccessibleContextBase::CommitFocusLost() const
536 AccessibleEventObject aEvent;
537 aEvent.EventId = AccessibleEventId::STATE_CHANGED;
538 aEvent.Source = uno::Reference< XAccessibleContext >(const_cast<ScAccessibleContextBase*>(this));
539 aEvent.OldValue <<= AccessibleStateType::FOCUSED;
541 CommitChange(aEvent);
543 vcl::unohelper::NotifyAccessibleStateEventGlobally(aEvent);
546 Rectangle ScAccessibleContextBase::GetBoundingBoxOnScreen() const
547 throw (uno::RuntimeException, std::exception)
549 OSL_FAIL("not implemented");
550 return Rectangle();
553 Rectangle ScAccessibleContextBase::GetBoundingBox() const
554 throw (uno::RuntimeException, std::exception)
556 OSL_FAIL("not implemented");
557 return Rectangle();
560 void ScAccessibleContextBase::IsObjectValid() const
561 throw (lang::DisposedException)
563 if (rBHelper.bDisposed || rBHelper.bInDispose)
564 throw lang::DisposedException();
567 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */