Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include <toolkit/controls/accessiblecontrolcontext.hxx>
30 : : #include <unotools/accessiblestatesethelper.hxx>
31 : : #include <com/sun/star/awt/XControl.hpp>
32 : : #include <com/sun/star/awt/XWindow.hpp>
33 : : #include <vcl/svapp.hxx>
34 : : #include <com/sun/star/accessibility/AccessibleStateType.hpp>
35 : : #include <com/sun/star/accessibility/AccessibleRole.hpp>
36 : : #include <toolkit/helper/vclunohelper.hxx>
37 : : #include <vcl/window.hxx>
38 : :
39 : : //........................................................................
40 : : namespace toolkit
41 : : {
42 : : //........................................................................
43 : :
44 : : using ::comphelper::OContextEntryGuard;
45 : : using namespace ::com::sun::star;
46 : : using namespace ::com::sun::star::uno;
47 : : using namespace ::com::sun::star::lang;
48 : : using namespace ::com::sun::star::beans;
49 : : using namespace ::com::sun::star::accessibility;
50 : :
51 : : //====================================================================
52 : : //= OAccessibleControlContext
53 : : //====================================================================
54 : : //--------------------------------------------------------------------
55 : 60 : OAccessibleControlContext::OAccessibleControlContext()
56 [ + - ]: 60 : :OAccessibleControlContext_Base( )
57 : : {
58 : : // nothing to do here, we have a late ctor
59 : 60 : }
60 : :
61 : : //--------------------------------------------------------------------
62 [ + - ]: 60 : OAccessibleControlContext::~OAccessibleControlContext()
63 : : {
64 [ + - ]: 60 : ensureDisposed();
65 [ - + ]: 120 : }
66 : :
67 : : //--------------------------------------------------------------------
68 [ + + ][ + - ]: 2871 : IMPLEMENT_FORWARD_XINTERFACE3( OAccessibleControlContext, OAccessibleControlContext_Base, OAccessibleImplementationAccess, OAccessibleControlContext_IBase )
[ + - ][ + - ]
69 [ # # ][ # # ]: 0 : IMPLEMENT_FORWARD_XTYPEPROVIDER3( OAccessibleControlContext, OAccessibleControlContext_Base, OAccessibleImplementationAccess, OAccessibleControlContext_IBase )
[ # # ][ # # ]
[ # # ]
70 : : // (order matters: the first is the class name, the second is the class doing the ref counting)
71 : :
72 : : //--------------------------------------------------------------------
73 : 60 : void OAccessibleControlContext::Init( const Reference< XAccessible >& _rxCreator ) SAL_THROW( ( Exception ) )
74 : : {
75 [ + - ]: 60 : OContextEntryGuard aGuard( this );
76 : :
77 : : // retrieve the model of the control
78 : : OSL_ENSURE( !m_xControlModel.is(), "OAccessibleControlContext::Init: already know a control model....!???" );
79 : :
80 [ + - ]: 60 : Reference< awt::XControl > xControl( _rxCreator, UNO_QUERY );
81 [ + - ]: 60 : if ( xControl.is() )
82 [ + - ][ + - ]: 60 : m_xControlModel = m_xControlModel.query( xControl->getModel() );
[ + - ][ + - ]
83 : : OSL_ENSURE( m_xControlModel.is(), "OAccessibleControlContext::Init: invalid creator (no control, or control without model!" );
84 [ - + ]: 60 : if ( !m_xControlModel.is() )
85 [ # # ]: 0 : throw DisposedException(); // caught by the caller (the create method)
86 : :
87 : : // start listening at the model
88 [ + - ]: 60 : startModelListening();
89 : :
90 : : // announce the XAccessible to our base class
91 [ + - ][ + - ]: 60 : OAccessibleControlContext_Base::lateInit( _rxCreator );
92 : 60 : }
93 : :
94 : : //--------------------------------------------------------------------
95 : 60 : OAccessibleControlContext* OAccessibleControlContext::create( const Reference< XAccessible >& _rxCreator ) SAL_THROW( ( ) )
96 : : {
97 : 60 : OAccessibleControlContext* pNew = NULL;
98 : : try
99 : : {
100 [ + - # # ]: 60 : pNew = new OAccessibleControlContext;
101 [ + - ]: 60 : pNew->Init( _rxCreator );
102 : : }
103 : 0 : catch( const Exception& )
104 : : {
105 : : OSL_FAIL( "OAccessibleControlContext::create: caught an exception from the late ctor!" );
106 : : }
107 : 60 : return pNew;
108 : : }
109 : :
110 : : //--------------------------------------------------------------------
111 : 60 : void OAccessibleControlContext::startModelListening( ) SAL_THROW( ( Exception ) )
112 : : {
113 [ + - ]: 60 : Reference< XComponent > xModelComp( m_xControlModel, UNO_QUERY );
114 : : OSL_ENSURE( xModelComp.is(), "OAccessibleControlContext::startModelListening: invalid model!" );
115 [ + - ]: 60 : if ( xModelComp.is() )
116 [ + - ][ + - ]: 60 : xModelComp->addEventListener( this );
[ + - ]
117 : 60 : }
118 : :
119 : : //--------------------------------------------------------------------
120 : 60 : void OAccessibleControlContext::stopModelListening( ) SAL_THROW( ( Exception ) )
121 : : {
122 [ + - ]: 60 : Reference< XComponent > xModelComp( m_xControlModel, UNO_QUERY );
123 : : OSL_ENSURE( xModelComp.is(), "OAccessibleControlContext::stopModelListening: invalid model!" );
124 [ + - ]: 60 : if ( xModelComp.is() )
125 [ + - ][ + - ]: 60 : xModelComp->removeEventListener( this );
[ + - ]
126 : 60 : }
127 : :
128 : : //--------------------------------------------------------------------
129 : 0 : sal_Int32 SAL_CALL OAccessibleControlContext::getAccessibleChildCount( ) throw (RuntimeException)
130 : : {
131 : : // we do not have children
132 : 0 : return 0;
133 : : }
134 : :
135 : : //--------------------------------------------------------------------
136 : 0 : Reference< XAccessible > SAL_CALL OAccessibleControlContext::getAccessibleChild( sal_Int32 ) throw (IndexOutOfBoundsException, RuntimeException)
137 : : {
138 : : // we do not have children
139 [ # # ]: 0 : throw IndexOutOfBoundsException();
140 : : }
141 : :
142 : : //--------------------------------------------------------------------
143 : 0 : Reference< XAccessible > SAL_CALL OAccessibleControlContext::getAccessibleParent( ) throw (RuntimeException)
144 : : {
145 [ # # ]: 0 : OContextEntryGuard aGuard( this );
146 : : OSL_ENSURE( implGetForeignControlledParent().is(), "OAccessibleControlContext::getAccessibleParent: somebody forgot to set a parent!" );
147 : : // this parent of us is foreign controlled - somebody has to set it using the OAccessibleImplementationAccess
148 : : // class, before integrating our instance into an AccessibleDocumentModel
149 [ # # ][ # # ]: 0 : return implGetForeignControlledParent();
150 : : }
151 : :
152 : : //--------------------------------------------------------------------
153 : 0 : sal_Int16 SAL_CALL OAccessibleControlContext::getAccessibleRole( ) throw (RuntimeException)
154 : : {
155 : 0 : return AccessibleRole::SHAPE;
156 : : }
157 : :
158 : : //--------------------------------------------------------------------
159 : 0 : ::rtl::OUString SAL_CALL OAccessibleControlContext::getAccessibleDescription( ) throw (RuntimeException)
160 : : {
161 [ # # ]: 0 : OContextEntryGuard aGuard( this );
162 [ # # ][ # # ]: 0 : return getModelStringProperty( "HelpText" );
163 : : }
164 : :
165 : : //--------------------------------------------------------------------
166 : 0 : ::rtl::OUString SAL_CALL OAccessibleControlContext::getAccessibleName( ) throw (RuntimeException)
167 : : {
168 [ # # ]: 0 : OContextEntryGuard aGuard( this );
169 [ # # ][ # # ]: 0 : return getModelStringProperty( "Name" );
170 : : }
171 : :
172 : : //--------------------------------------------------------------------
173 : 0 : Reference< XAccessibleRelationSet > SAL_CALL OAccessibleControlContext::getAccessibleRelationSet( ) throw (RuntimeException)
174 : : {
175 : 0 : return NULL;
176 : : }
177 : :
178 : : //--------------------------------------------------------------------
179 : 0 : Reference< XAccessibleStateSet > SAL_CALL OAccessibleControlContext::getAccessibleStateSet( ) throw (RuntimeException)
180 : : {
181 [ # # ]: 0 : ::osl::MutexGuard aGuard( GetMutex() );
182 : : // no OContextEntryGuard here, as we do not want to throw an exception in case we're not alive anymore
183 : :
184 : 0 : ::utl::AccessibleStateSetHelper* pStateSet = NULL;
185 [ # # ][ # # ]: 0 : if ( isAlive() )
186 : : {
187 : : // no own states, only the ones which are foreign controlled
188 [ # # ][ # # ]: 0 : pStateSet = new ::utl::AccessibleStateSetHelper( implGetForeignControlledStates() );
189 : : }
190 : : else
191 : : { // only the DEFUNC state if we're already disposed
192 [ # # ]: 0 : pStateSet = new ::utl::AccessibleStateSetHelper;
193 [ # # ]: 0 : pStateSet->AddState( AccessibleStateType::DEFUNC );
194 : : }
195 [ # # ][ # # ]: 0 : return pStateSet;
[ # # ]
196 : : }
197 : :
198 : : //--------------------------------------------------------------------
199 : 60 : void SAL_CALL OAccessibleControlContext::disposing( const EventObject&
200 : : #if OSL_DEBUG_LEVEL > 0
201 : : _rSource
202 : : #endif
203 : : ) throw ( RuntimeException )
204 : : {
205 : : OSL_ENSURE( Reference< XPropertySet >( _rSource.Source, UNO_QUERY ).get() == m_xControlModel.get(),
206 : : "OAccessibleControlContext::disposing: where did this come from?" );
207 : :
208 : 60 : stopModelListening( );
209 : 60 : m_xControlModel.clear();
210 : 60 : m_xModelPropsInfo.clear();
211 : :
212 : 60 : OAccessibleControlContext_Base::disposing();
213 : 60 : }
214 : :
215 : : //--------------------------------------------------------------------
216 : 0 : ::rtl::OUString OAccessibleControlContext::getModelStringProperty( const sal_Char* _pPropertyName )
217 : : {
218 : 0 : ::rtl::OUString sReturn;
219 : : try
220 : : {
221 [ # # ][ # # ]: 0 : if ( !m_xModelPropsInfo.is() && m_xControlModel.is() )
[ # # ]
222 [ # # ][ # # ]: 0 : m_xModelPropsInfo = m_xControlModel->getPropertySetInfo();
[ # # ]
223 : :
224 : 0 : ::rtl::OUString sPropertyName( ::rtl::OUString::createFromAscii( _pPropertyName ) );
225 [ # # ][ # # ]: 0 : if ( m_xModelPropsInfo.is() && m_xModelPropsInfo->hasPropertyByName( sPropertyName ) )
[ # # ][ # # ]
[ # # ]
226 [ # # ][ # # ]: 0 : m_xControlModel->getPropertyValue( sPropertyName ) >>= sReturn;
[ # # ]
227 : : }
228 [ # # ]: 0 : catch( const Exception& )
229 : : {
230 : : OSL_FAIL( "OAccessibleControlContext::getModelStringProperty: caught an exception!" );
231 : : }
232 : 0 : return sReturn;
233 : : }
234 : :
235 : : //--------------------------------------------------------------------
236 : 0 : Window* OAccessibleControlContext::implGetWindow( Reference< awt::XWindow >* _pxUNOWindow ) const
237 : : {
238 [ # # ][ # # ]: 0 : Reference< awt::XControl > xControl( getAccessibleCreator(), UNO_QUERY );
239 : 0 : Reference< awt::XWindow > xWindow;
240 [ # # ]: 0 : if ( xControl.is() )
241 [ # # ][ # # ]: 0 : xWindow = xWindow.query( xControl->getPeer() );
[ # # ][ # # ]
242 : :
243 [ # # ][ # # ]: 0 : Window* pWindow = xWindow.is() ? VCLUnoHelper::GetWindow( xWindow ) : NULL;
244 : :
245 [ # # ]: 0 : if ( _pxUNOWindow )
246 [ # # ]: 0 : *_pxUNOWindow = xWindow;
247 : 0 : return pWindow;
248 : : }
249 : :
250 : : //--------------------------------------------------------------------
251 : 0 : awt::Rectangle SAL_CALL OAccessibleControlContext::implGetBounds( ) throw (RuntimeException)
252 : : {
253 [ # # ]: 0 : SolarMutexGuard aSolarGuard;
254 : : // want to do some VCL stuff here ...
255 [ # # ]: 0 : OContextEntryGuard aGuard( this );
256 : :
257 : : OSL_FAIL( "OAccessibleControlContext::implGetBounds: performance issue: forced to calc the size myself!" );
258 : : // In design mode (and this is what this class is for), the surrounding shape (if any) should handle this call
259 : : // The problem is that in design mode, our size may not be correct (in the drawing layer, controls are
260 : : // positioned/sized for painting only), and that calculation of our position is expensive
261 : :
262 : : // what we know (or can obtain from somewhere):
263 : : // * the PosSize of our peer, relative to it's parent window
264 : : // * the parent window which the PosSize is relative to
265 : : // * our foreign controlled accessible parent
266 : : // from this info, we can determine the the position of our peer relative to the foreign parent
267 : :
268 : : // our control
269 : 0 : Reference< awt::XWindow > xWindow;
270 [ # # ]: 0 : Window* pVCLWindow = implGetWindow( &xWindow );
271 : :
272 : 0 : awt::Rectangle aBounds( 0, 0, 0, 0 );
273 [ # # ]: 0 : if ( xWindow.is() )
274 : : {
275 : : // ugly, but .... though the XWindow has a getPosSize, it is impossible to determine the
276 : : // parent which this position/size is relative to. This means we must tunnel UNO and ask the
277 : : // implementation
278 [ # # ][ # # ]: 0 : Window* pVCLParent = pVCLWindow ? pVCLWindow->GetParent() : NULL;
279 : :
280 : : // the relative location of the window
281 : 0 : ::Point aWindowRelativePos( 0, 0);
282 [ # # ]: 0 : if ( pVCLWindow )
283 [ # # ]: 0 : aWindowRelativePos = pVCLWindow->GetPosPixel();
284 : :
285 : : // the screnn position of the "window parent" of the control
286 : 0 : ::Point aVCLParentScreenPos( 0, 0 );
287 [ # # ]: 0 : if ( pVCLParent )
288 [ # # ]: 0 : aVCLParentScreenPos = pVCLParent->GetPosPixel();
289 : :
290 : : // the screen position of the "accessible parent" of the control
291 [ # # ]: 0 : Reference< XAccessible > xParentAcc( implGetForeignControlledParent() );
292 : 0 : Reference< XAccessibleComponent > xParentAccComponent;
293 [ # # ]: 0 : if ( xParentAcc.is() )
294 [ # # ][ # # ]: 0 : xParentAccComponent = xParentAccComponent.query( xParentAcc->getAccessibleContext() );
[ # # ][ # # ]
295 : 0 : awt::Point aAccParentScreenPos( 0, 0 );
296 [ # # ]: 0 : if ( xParentAccComponent.is() )
297 [ # # ][ # # ]: 0 : aAccParentScreenPos = xParentAccComponent->getLocationOnScreen();
298 : :
299 : : // now the size of the control
300 [ # # ][ # # ]: 0 : aBounds = xWindow->getPosSize();
301 : :
302 : : // correct the pos
303 : 0 : aBounds.X = aWindowRelativePos.X() + aVCLParentScreenPos.X() - aAccParentScreenPos.X;
304 : 0 : aBounds.Y = aWindowRelativePos.Y() + aVCLParentScreenPos.Y() - aAccParentScreenPos.Y;
305 : : }
306 : :
307 [ # # ][ # # ]: 0 : return aBounds;
308 : : }
309 : :
310 : : //--------------------------------------------------------------------
311 : 0 : Reference< XAccessible > SAL_CALL OAccessibleControlContext::getAccessibleAtPoint( const awt::Point& /* _rPoint */ ) throw (RuntimeException)
312 : : {
313 : : // no children at all
314 : 0 : return NULL;
315 : : }
316 : :
317 : : //--------------------------------------------------------------------
318 : 0 : void SAL_CALL OAccessibleControlContext::grabFocus( ) throw (RuntimeException)
319 : : {
320 : : OSL_FAIL( "OAccessibleControlContext::grabFocus: !isFocusTraversable, but grabFocus!" );
321 : 0 : }
322 : :
323 : : //--------------------------------------------------------------------
324 : 0 : Any SAL_CALL OAccessibleControlContext::getAccessibleKeyBinding( ) throw (RuntimeException)
325 : : {
326 : : // we do not have any key bindings to activate a UNO control in design mode
327 : 0 : return Any();
328 : : }
329 : :
330 : : //--------------------------------------------------------------------
331 : 0 : sal_Int32 SAL_CALL OAccessibleControlContext::getForeground( ) throw (::com::sun::star::uno::RuntimeException)
332 : : {
333 [ # # ]: 0 : SolarMutexGuard aSolarGuard;
334 : : // want to do some VCL stuff here ...
335 [ # # ]: 0 : OContextEntryGuard aGuard( this );
336 : :
337 [ # # ]: 0 : Window* pWindow = implGetWindow( );
338 : 0 : sal_Int32 nColor = 0;
339 [ # # ]: 0 : if ( pWindow )
340 : : {
341 [ # # ][ # # ]: 0 : if ( pWindow->IsControlForeground() )
342 [ # # ]: 0 : nColor = pWindow->GetControlForeground().GetColor();
343 : : else
344 : : {
345 [ # # ]: 0 : Font aFont;
346 [ # # ][ # # ]: 0 : if ( pWindow->IsControlFont() )
347 [ # # ][ # # ]: 0 : aFont = pWindow->GetControlFont();
[ # # ]
348 : : else
349 [ # # ]: 0 : aFont = pWindow->GetFont();
350 [ # # ][ # # ]: 0 : nColor = aFont.GetColor().GetColor();
351 : : }
352 : : }
353 [ # # ][ # # ]: 0 : return nColor;
354 : : }
355 : :
356 : : //--------------------------------------------------------------------
357 : 0 : sal_Int32 SAL_CALL OAccessibleControlContext::getBackground( ) throw (::com::sun::star::uno::RuntimeException)
358 : : {
359 [ # # ]: 0 : SolarMutexGuard aSolarGuard;
360 : : // want to do some VCL stuff here ...
361 [ # # ]: 0 : OContextEntryGuard aGuard( this );
362 : :
363 [ # # ]: 0 : Window* pWindow = implGetWindow( );
364 : 0 : sal_Int32 nColor = 0;
365 [ # # ]: 0 : if ( pWindow )
366 : : {
367 [ # # ][ # # ]: 0 : if ( pWindow->IsControlBackground() )
368 [ # # ]: 0 : nColor = pWindow->GetControlBackground().GetColor();
369 : : else
370 [ # # ]: 0 : nColor = pWindow->GetBackground().GetColor().GetColor();
371 : : }
372 : :
373 [ # # ][ # # ]: 0 : return nColor;
374 : : }
375 : :
376 : : //........................................................................
377 : : } //namespace toolkit
378 : : //........................................................................
379 : :
380 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|