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