Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 : #include <svtools/accessibleruler.hxx>
20 : #include <com/sun/star/accessibility/AccessibleRole.hpp>
21 : #include <com/sun/star/accessibility/AccessibleEventId.hpp>
22 : #include <unotools/accessiblestatesethelper.hxx>
23 : #include <com/sun/star/accessibility/AccessibleStateType.hpp>
24 : #include <com/sun/star/beans/PropertyChangeEvent.hpp>
25 : #include <com/sun/star/awt/XWindow.hpp>
26 : #include <comphelper/accessibleeventnotifier.hxx>
27 : #include <cppuhelper/supportsservice.hxx>
28 : #include <cppuhelper/typeprovider.hxx>
29 : #include <toolkit/helper/vclunohelper.hxx>
30 : #include <toolkit/helper/convert.hxx>
31 : #include <vcl/svapp.hxx>
32 : #include <osl/mutex.hxx>
33 : #include <rtl/uuid.h>
34 : #include <tools/gen.hxx>
35 :
36 : #include <svtools/ruler.hxx>
37 :
38 : using namespace ::cppu;
39 : using namespace ::osl;
40 : using namespace ::com::sun::star;
41 : using namespace ::com::sun::star::uno;
42 : using namespace ::com::sun::star::accessibility;
43 :
44 :
45 :
46 : //===== internal ============================================================
47 :
48 5 : SvtRulerAccessible::SvtRulerAccessible(
49 : const uno::Reference< XAccessible >& rxParent, Ruler& rRepr, const OUString& rName ) :
50 :
51 : SvtRulerAccessible_Base( m_aMutex ),
52 : msName( rName ),
53 : mxParent( rxParent ),
54 : mpRepr( &rRepr ),
55 5 : mnClientId( 0 )
56 : {
57 5 : }
58 :
59 15 : SvtRulerAccessible::~SvtRulerAccessible()
60 : {
61 :
62 5 : if( IsAlive() )
63 : {
64 0 : osl_atomic_increment( &m_refCount );
65 0 : dispose(); // set mpRepr = NULL & release all children
66 : }
67 10 : }
68 :
69 : //===== XAccessible =========================================================
70 :
71 5 : uno::Reference< XAccessibleContext > SAL_CALL SvtRulerAccessible::getAccessibleContext() throw( RuntimeException, std::exception )
72 : {
73 5 : return this;
74 : }
75 :
76 : //===== XAccessibleComponent ================================================
77 :
78 0 : sal_Bool SAL_CALL SvtRulerAccessible::containsPoint( const awt::Point& rPoint ) throw( RuntimeException, std::exception )
79 : {
80 : // no guard -> done in getBounds()
81 : // return GetBoundingBox().IsInside( VCLPoint( rPoint ) );
82 0 : return Rectangle( Point( 0, 0 ), GetBoundingBox().GetSize() ).IsInside( VCLPoint( rPoint ) );
83 : }
84 :
85 0 : uno::Reference< XAccessible > SAL_CALL SvtRulerAccessible::getAccessibleAtPoint( const awt::Point& ) throw( RuntimeException, std::exception )
86 : {
87 0 : ::osl::MutexGuard aGuard( m_aMutex );
88 :
89 0 : ThrowExceptionIfNotAlive();
90 :
91 0 : uno::Reference< XAccessible > xRet;
92 :
93 :
94 0 : return xRet;
95 : }
96 :
97 0 : awt::Rectangle SAL_CALL SvtRulerAccessible::getBounds() throw( RuntimeException, std::exception )
98 : {
99 : // no guard -> done in GetBoundingBox()
100 0 : return AWTRectangle( GetBoundingBox() );
101 : }
102 :
103 0 : awt::Point SAL_CALL SvtRulerAccessible::getLocation() throw( RuntimeException, std::exception )
104 : {
105 : // no guard -> done in GetBoundingBox()
106 0 : return AWTPoint( GetBoundingBox().TopLeft() );
107 : }
108 :
109 0 : awt::Point SAL_CALL SvtRulerAccessible::getLocationOnScreen() throw( RuntimeException, std::exception )
110 : {
111 : // no guard -> done in GetBoundingBoxOnScreen()
112 0 : return AWTPoint( GetBoundingBoxOnScreen().TopLeft() );
113 : }
114 :
115 0 : awt::Size SAL_CALL SvtRulerAccessible::getSize() throw( RuntimeException, std::exception )
116 : {
117 : // no guard -> done in GetBoundingBox()
118 0 : return AWTSize( GetBoundingBox().GetSize() );
119 : }
120 :
121 5 : bool SAL_CALL SvtRulerAccessible::isVisible() throw( RuntimeException )
122 : {
123 5 : ::osl::MutexGuard aGuard( m_aMutex );
124 :
125 5 : ThrowExceptionIfNotAlive();
126 :
127 5 : return mpRepr->IsVisible();
128 : }
129 :
130 : //===== XAccessibleContext ==================================================
131 10 : sal_Int32 SAL_CALL SvtRulerAccessible::getAccessibleChildCount() throw( RuntimeException, std::exception )
132 : {
133 10 : ::osl::MutexGuard aGuard( m_aMutex );
134 :
135 10 : ThrowExceptionIfNotAlive();
136 :
137 10 : return 0;
138 : }
139 :
140 0 : uno::Reference< XAccessible > SAL_CALL SvtRulerAccessible::getAccessibleChild( sal_Int32 )
141 : throw( RuntimeException, lang::IndexOutOfBoundsException, std::exception )
142 : {
143 0 : uno::Reference< XAccessible > xChild ;
144 :
145 0 : return xChild;
146 : }
147 :
148 0 : uno::Reference< XAccessible > SAL_CALL SvtRulerAccessible::getAccessibleParent() throw( RuntimeException, std::exception )
149 : {
150 0 : return mxParent;
151 : }
152 :
153 0 : sal_Int32 SAL_CALL SvtRulerAccessible::getAccessibleIndexInParent() throw( RuntimeException, std::exception )
154 : {
155 0 : ::osl::MutexGuard aGuard( m_aMutex );
156 : // Use a simple but slow solution for now. Optimize later.
157 :
158 : // Iterate over all the parent's children and search for this object.
159 0 : if( mxParent.is() )
160 : {
161 0 : uno::Reference< XAccessibleContext > xParentContext( mxParent->getAccessibleContext() );
162 0 : if( xParentContext.is() )
163 : {
164 0 : sal_Int32 nChildCount = xParentContext->getAccessibleChildCount();
165 0 : for( sal_Int32 i = 0 ; i < nChildCount ; ++i )
166 : {
167 0 : uno::Reference< XAccessible > xChild( xParentContext->getAccessibleChild( i ) );
168 0 : if( xChild.get() == static_cast<XAccessible*>(this) )
169 0 : return i;
170 0 : }
171 0 : }
172 : }
173 :
174 : // Return -1 to indicate that this object's parent does not know about the
175 : // object.
176 0 : return -1;
177 : }
178 :
179 5 : sal_Int16 SAL_CALL SvtRulerAccessible::getAccessibleRole() throw( RuntimeException, std::exception )
180 : {
181 5 : return AccessibleRole::RULER;
182 : }
183 :
184 0 : OUString SAL_CALL SvtRulerAccessible::getAccessibleDescription() throw( RuntimeException, std::exception )
185 : {
186 0 : ::osl::MutexGuard aGuard( m_aMutex );
187 0 : return msDescription;
188 : }
189 :
190 0 : OUString SAL_CALL SvtRulerAccessible::getAccessibleName() throw( RuntimeException, std::exception )
191 : {
192 0 : ::osl::MutexGuard aGuard( m_aMutex );
193 0 : return msName;
194 : }
195 :
196 : /** Return empty uno::Reference to indicate that the relation set is not
197 : supported.
198 : */
199 0 : uno::Reference< XAccessibleRelationSet > SAL_CALL SvtRulerAccessible::getAccessibleRelationSet() throw( RuntimeException, std::exception )
200 : {
201 0 : return uno::Reference< XAccessibleRelationSet >();
202 : }
203 :
204 :
205 5 : uno::Reference< XAccessibleStateSet > SAL_CALL SvtRulerAccessible::getAccessibleStateSet() throw( RuntimeException, std::exception )
206 : {
207 5 : ::osl::MutexGuard aGuard( m_aMutex );
208 5 : utl::AccessibleStateSetHelper* pStateSetHelper = new utl::AccessibleStateSetHelper;
209 :
210 5 : if( IsAlive() )
211 : {
212 5 : pStateSetHelper->AddState( AccessibleStateType::ENABLED );
213 :
214 5 : pStateSetHelper->AddState( AccessibleStateType::SHOWING );
215 :
216 5 : if( isVisible() )
217 5 : pStateSetHelper->AddState( AccessibleStateType::VISIBLE );
218 :
219 5 : if ( mpRepr->GetStyle() & WB_HORZ )
220 5 : pStateSetHelper->AddState( AccessibleStateType::HORIZONTAL );
221 : else
222 0 : pStateSetHelper->AddState( AccessibleStateType::VERTICAL );
223 :
224 5 : if(pStateSetHelper->contains(AccessibleStateType::FOCUSABLE))
225 : {
226 0 : pStateSetHelper->RemoveState( AccessibleStateType::FOCUSABLE );
227 : }
228 :
229 : }
230 :
231 :
232 5 : return pStateSetHelper;
233 : }
234 :
235 0 : lang::Locale SAL_CALL SvtRulerAccessible::getLocale() throw( IllegalAccessibleComponentStateException, RuntimeException, std::exception )
236 : {
237 0 : ::osl::MutexGuard aGuard( m_aMutex );
238 0 : if( mxParent.is() )
239 : {
240 0 : uno::Reference< XAccessibleContext > xParentContext( mxParent->getAccessibleContext() );
241 0 : if( xParentContext.is() )
242 0 : return xParentContext->getLocale();
243 : }
244 :
245 : // No parent. Therefore throw exception to indicate this cluelessness.
246 0 : throw IllegalAccessibleComponentStateException();
247 : }
248 :
249 0 : void SAL_CALL SvtRulerAccessible::addAccessibleEventListener( const uno::Reference< XAccessibleEventListener >& xListener )
250 : throw( RuntimeException, std::exception )
251 : {
252 0 : if (xListener.is())
253 : {
254 0 : ::osl::MutexGuard aGuard( m_aMutex );
255 0 : if (!mnClientId)
256 0 : mnClientId = comphelper::AccessibleEventNotifier::registerClient( );
257 0 : comphelper::AccessibleEventNotifier::addEventListener( mnClientId, xListener );
258 : }
259 0 : }
260 :
261 0 : void SAL_CALL SvtRulerAccessible::removeAccessibleEventListener( const uno::Reference< XAccessibleEventListener >& xListener )
262 : throw( RuntimeException, std::exception )
263 : {
264 0 : if (xListener.is())
265 : {
266 0 : ::osl::MutexGuard aGuard( m_aMutex );
267 :
268 0 : sal_Int32 nListenerCount = comphelper::AccessibleEventNotifier::removeEventListener( mnClientId, xListener );
269 0 : if ( !nListenerCount )
270 : {
271 : // no listeners anymore
272 : // -> revoke ourself. This may lead to the notifier thread dying (if we were the last client),
273 : // and at least to us not firing any events anymore, in case somebody calls
274 : // NotifyAccessibleEvent, again
275 0 : comphelper::AccessibleEventNotifier::revokeClient( mnClientId );
276 0 : mnClientId = 0;
277 0 : }
278 : }
279 0 : }
280 :
281 0 : void SAL_CALL SvtRulerAccessible::grabFocus() throw( RuntimeException, std::exception )
282 : {
283 0 : SolarMutexGuard aSolarGuard;
284 0 : ::osl::MutexGuard aGuard( m_aMutex );
285 :
286 0 : ThrowExceptionIfNotAlive();
287 :
288 0 : mpRepr->GrabFocus();
289 0 : }
290 :
291 0 : sal_Int32 SvtRulerAccessible::getForeground( )
292 : throw (::com::sun::star::uno::RuntimeException, std::exception)
293 : {
294 0 : SolarMutexGuard aSolarGuard;
295 0 : ::osl::MutexGuard aGuard( m_aMutex );
296 0 : ThrowExceptionIfNotAlive();
297 :
298 0 : return mpRepr->GetControlForeground().GetColor();
299 : }
300 0 : sal_Int32 SvtRulerAccessible::getBackground( )
301 : throw (::com::sun::star::uno::RuntimeException, std::exception)
302 : {
303 0 : SolarMutexGuard aSolarGuard;
304 0 : ::osl::MutexGuard aGuard( m_aMutex );
305 0 : ThrowExceptionIfNotAlive();
306 :
307 0 : return mpRepr->GetControlBackground().GetColor();
308 : }
309 :
310 : // XServiceInfo
311 0 : OUString SAL_CALL SvtRulerAccessible::getImplementationName() throw( RuntimeException, std::exception )
312 : {
313 0 : return OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.ui.SvtRulerAccessible" ) );
314 : }
315 :
316 0 : sal_Bool SAL_CALL SvtRulerAccessible::supportsService( const OUString& sServiceName ) throw( RuntimeException, std::exception )
317 : {
318 0 : return cppu::supportsService( this, sServiceName );
319 : }
320 :
321 0 : Sequence< OUString > SAL_CALL SvtRulerAccessible::getSupportedServiceNames() throw( RuntimeException, std::exception )
322 : {
323 0 : const OUString sServiceName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.accessibility.AccessibleContext" ) );
324 0 : return Sequence< OUString >( &sServiceName, 1 );
325 : }
326 :
327 : //===== XTypeProvider =======================================================
328 0 : Sequence< sal_Int8 > SAL_CALL SvtRulerAccessible::getImplementationId() throw( RuntimeException, std::exception )
329 : {
330 0 : return css::uno::Sequence<sal_Int8>();
331 : }
332 :
333 5 : void SAL_CALL SvtRulerAccessible::disposing()
334 : {
335 5 : if( !rBHelper.bDisposed )
336 : {
337 : {
338 5 : ::osl::MutexGuard aGuard( m_aMutex );
339 5 : mpRepr = NULL; // object dies with representation
340 :
341 : }
342 :
343 : {
344 5 : ::osl::MutexGuard aGuard( m_aMutex );
345 :
346 : // Send a disposing to all listeners.
347 5 : if ( mnClientId )
348 : {
349 0 : comphelper::AccessibleEventNotifier::revokeClientNotifyDisposing( mnClientId, *this );
350 0 : mnClientId = 0;
351 : }
352 5 : mxParent = uno::Reference< XAccessible >();
353 : }
354 : }
355 5 : }
356 :
357 0 : Rectangle SvtRulerAccessible::GetBoundingBoxOnScreen() throw( RuntimeException )
358 : {
359 0 : SolarMutexGuard aSolarGuard;
360 0 : ::osl::MutexGuard aGuard( m_aMutex );
361 :
362 0 : ThrowExceptionIfNotAlive();
363 0 : return Rectangle( mpRepr->GetParent()->OutputToAbsoluteScreenPixel( mpRepr->GetPosPixel() ), mpRepr->GetSizePixel() );
364 : }
365 :
366 0 : Rectangle SvtRulerAccessible::GetBoundingBox() throw( RuntimeException )
367 : {
368 0 : SolarMutexGuard aSolarGuard;
369 0 : ::osl::MutexGuard aGuard( m_aMutex );
370 :
371 0 : ThrowExceptionIfNotAlive();
372 :
373 0 : return Rectangle( mpRepr->GetPosPixel(), mpRepr->GetSizePixel() );
374 : }
375 :
376 15 : void SvtRulerAccessible::ThrowExceptionIfNotAlive() throw( lang::DisposedException )
377 : {
378 15 : if( IsNotAlive() )
379 0 : throw lang::DisposedException();
380 813 : }
381 :
382 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|