xref: /trunk/main/basctl/source/accessibility/accessibledialogcontrolshape.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_basctl.hxx"
30 #include <accessibledialogcontrolshape.hxx>
31 #include <baside3.hxx>
32 #include <dlgeddef.hxx>
33 #include <dlgedview.hxx>
34 #include <dlgedobj.hxx>
35 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
36 #include <com/sun/star/accessibility/AccessibleRole.hpp>
37 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
38 #include <unotools/accessiblestatesethelper.hxx>
39 #include <unotools/accessiblerelationsethelper.hxx>
40 #include <toolkit/awt/vclxfont.hxx>
41 #include <toolkit/helper/externallock.hxx>
42 #include <toolkit/helper/convert.hxx>
43 #include <toolkit/helper/vclunohelper.hxx>
44 #include <vcl/svapp.hxx>
45 
46 using namespace ::com::sun::star;
47 using namespace ::com::sun::star::uno;
48 using namespace ::com::sun::star::lang;
49 using namespace ::com::sun::star::beans;
50 using namespace ::com::sun::star::accessibility;
51 using namespace ::comphelper;
52 
53 
54 // -----------------------------------------------------------------------------
55 // class AccessibleDialogControlShape
56 // -----------------------------------------------------------------------------
57 
58 AccessibleDialogControlShape::AccessibleDialogControlShape( DialogWindow* pDialogWindow, DlgEdObj* pDlgEdObj )
59     :AccessibleExtendedComponentHelper_BASE( new VCLExternalSolarLock() )
60     ,m_pDialogWindow( pDialogWindow )
61     ,m_pDlgEdObj( pDlgEdObj )
62 {
63     m_pExternalLock = static_cast< VCLExternalSolarLock* >( getExternalLock() );
64 
65     if ( m_pDlgEdObj )
66         m_xControlModel = Reference< XPropertySet >( m_pDlgEdObj->GetUnoControlModel(), UNO_QUERY );
67 
68     if ( m_xControlModel.is() )
69         m_xControlModel->addPropertyChangeListener( ::rtl::OUString(), static_cast< beans::XPropertyChangeListener* >( this ) );
70 
71     m_bFocused = IsFocused();
72     m_bSelected = IsSelected();
73     m_aBounds = GetBounds();
74 }
75 
76 // -----------------------------------------------------------------------------
77 
78 AccessibleDialogControlShape::~AccessibleDialogControlShape()
79 {
80     if ( m_xControlModel.is() )
81         m_xControlModel->removePropertyChangeListener( ::rtl::OUString(), static_cast< beans::XPropertyChangeListener* >( this ) );
82 
83     delete m_pExternalLock;
84     m_pExternalLock = NULL;
85 }
86 
87 // -----------------------------------------------------------------------------
88 
89 sal_Bool AccessibleDialogControlShape::IsFocused()
90 {
91     sal_Bool bFocused = sal_False;
92     if ( m_pDialogWindow )
93     {
94         SdrView* pSdrView = m_pDialogWindow->GetView();
95         if ( pSdrView && pSdrView->IsObjMarked( m_pDlgEdObj ) && pSdrView->GetMarkedObjectList().GetMarkCount() == 1 )
96             bFocused = sal_True;
97     }
98 
99     return bFocused;
100 }
101 
102 // -----------------------------------------------------------------------------
103 
104 sal_Bool AccessibleDialogControlShape::IsSelected()
105 {
106     sal_Bool bSelected = sal_False;
107     if ( m_pDialogWindow )
108     {
109         SdrView* pSdrView = m_pDialogWindow->GetView();
110         if ( pSdrView )
111             bSelected = pSdrView->IsObjMarked( m_pDlgEdObj );
112     }
113 
114     return bSelected;
115 }
116 
117 // -----------------------------------------------------------------------------
118 
119 void AccessibleDialogControlShape::SetFocused( sal_Bool bFocused )
120 {
121     if ( m_bFocused != bFocused )
122     {
123         Any aOldValue, aNewValue;
124         if ( m_bFocused )
125             aOldValue <<= AccessibleStateType::FOCUSED;
126         else
127             aNewValue <<= AccessibleStateType::FOCUSED;
128         m_bFocused = bFocused;
129         NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );
130     }
131 }
132 
133 // -----------------------------------------------------------------------------
134 
135 void AccessibleDialogControlShape::SetSelected( sal_Bool bSelected )
136 {
137     if ( m_bSelected != bSelected )
138     {
139         Any aOldValue, aNewValue;
140         if ( m_bSelected )
141             aOldValue <<= AccessibleStateType::SELECTED;
142         else
143             aNewValue <<= AccessibleStateType::SELECTED;
144         m_bSelected = bSelected;
145         NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );
146     }
147 }
148 
149 // -----------------------------------------------------------------------------
150 
151 awt::Rectangle AccessibleDialogControlShape::GetBounds()
152 {
153     awt::Rectangle aBounds( 0, 0, 0, 0 );
154     if ( m_pDlgEdObj )
155     {
156         // get the bounding box of the shape in logic units
157         Rectangle aRect = m_pDlgEdObj->GetSnapRect();
158 
159         if ( m_pDialogWindow )
160         {
161             // transform coordinates relative to the parent
162             MapMode aMap = m_pDialogWindow->GetMapMode();
163             Point aOrg = aMap.GetOrigin();
164             aRect.Move( aOrg.X(), aOrg.Y() );
165 
166             // convert logic units to pixel
167             aRect = m_pDialogWindow->LogicToPixel( aRect, MapMode(MAP_100TH_MM) );
168 
169             // clip the shape's bounding box with the bounding box of its parent
170             Rectangle aParentRect( Point( 0, 0 ), m_pDialogWindow->GetSizePixel() );
171             aRect = aRect.GetIntersection( aParentRect );
172             aBounds = AWTRectangle( aRect );
173         }
174     }
175 
176     return aBounds;
177 }
178 
179 // -----------------------------------------------------------------------------
180 
181 void AccessibleDialogControlShape::SetBounds( const awt::Rectangle& aBounds )
182 {
183     if ( m_aBounds.X != aBounds.X || m_aBounds.Y != aBounds.Y || m_aBounds.Width != aBounds.Width || m_aBounds.Height != aBounds.Height )
184     {
185         m_aBounds = aBounds;
186         NotifyAccessibleEvent( AccessibleEventId::BOUNDRECT_CHANGED, Any(), Any() );
187     }
188 }
189 
190 // -----------------------------------------------------------------------------
191 
192 Window* AccessibleDialogControlShape::GetWindow() const
193 {
194     Window* pWindow = NULL;
195     if ( m_pDlgEdObj )
196     {
197         Reference< awt::XControl > xControl( m_pDlgEdObj->GetControl(), UNO_QUERY );
198         if ( xControl.is() )
199             pWindow = VCLUnoHelper::GetWindow( xControl->getPeer() );
200     }
201 
202     return pWindow;
203 }
204 
205 // -----------------------------------------------------------------------------
206 
207 ::rtl::OUString AccessibleDialogControlShape::GetModelStringProperty( const sal_Char* pPropertyName )
208 {
209     ::rtl::OUString sReturn;
210 
211     try
212     {
213         if ( m_xControlModel.is() )
214         {
215             ::rtl::OUString sPropertyName( ::rtl::OUString::createFromAscii( pPropertyName ) );
216             Reference< XPropertySetInfo > xInfo = m_xControlModel->getPropertySetInfo();
217             if ( xInfo.is() && xInfo->hasPropertyByName( sPropertyName ) )
218                 m_xControlModel->getPropertyValue( sPropertyName ) >>= sReturn;
219         }
220     }
221     catch ( const Exception& )
222     {
223         OSL_ENSURE( sal_False, "AccessibleDialogControlShape::GetModelStringProperty: caught an exception!" );
224     }
225 
226     return sReturn;
227 }
228 
229 // -----------------------------------------------------------------------------
230 
231 void AccessibleDialogControlShape::FillAccessibleStateSet( utl::AccessibleStateSetHelper& rStateSet )
232 {
233     rStateSet.AddState( AccessibleStateType::ENABLED );
234 
235     rStateSet.AddState( AccessibleStateType::VISIBLE );
236 
237     rStateSet.AddState( AccessibleStateType::SHOWING );
238 
239     rStateSet.AddState( AccessibleStateType::FOCUSABLE );
240 
241     if ( IsFocused() )
242         rStateSet.AddState( AccessibleStateType::FOCUSED );
243 
244     rStateSet.AddState( AccessibleStateType::SELECTABLE );
245 
246     if ( IsSelected() )
247         rStateSet.AddState( AccessibleStateType::SELECTED );
248 
249     rStateSet.AddState( AccessibleStateType::RESIZABLE );
250 }
251 
252 // -----------------------------------------------------------------------------
253 // OCommonAccessibleComponent
254 // -----------------------------------------------------------------------------
255 
256 awt::Rectangle AccessibleDialogControlShape::implGetBounds() throw (RuntimeException)
257 {
258     return GetBounds();
259 }
260 
261 // -----------------------------------------------------------------------------
262 // XInterface
263 // -----------------------------------------------------------------------------
264 
265 IMPLEMENT_FORWARD_XINTERFACE2( AccessibleDialogControlShape, AccessibleExtendedComponentHelper_BASE, AccessibleDialogControlShape_BASE )
266 
267 // -----------------------------------------------------------------------------
268 // XTypeProvider
269 // -----------------------------------------------------------------------------
270 
271 IMPLEMENT_FORWARD_XTYPEPROVIDER2( AccessibleDialogControlShape, AccessibleExtendedComponentHelper_BASE, AccessibleDialogControlShape_BASE )
272 
273 // -----------------------------------------------------------------------------
274 // XComponent
275 // -----------------------------------------------------------------------------
276 
277 void AccessibleDialogControlShape::disposing()
278 {
279     AccessibleExtendedComponentHelper_BASE::disposing();
280 
281     m_pDialogWindow = NULL;
282     m_pDlgEdObj = NULL;
283 
284     if ( m_xControlModel.is() )
285         m_xControlModel->removePropertyChangeListener( ::rtl::OUString(), static_cast< beans::XPropertyChangeListener* >( this ) );
286     m_xControlModel.clear();
287 }
288 
289 // -----------------------------------------------------------------------------
290 // XEventListener
291 // -----------------------------------------------------------------------------
292 
293 void AccessibleDialogControlShape::disposing( const lang::EventObject& ) throw (RuntimeException)
294 {
295     if ( m_xControlModel.is() )
296         m_xControlModel->removePropertyChangeListener( ::rtl::OUString(), static_cast< beans::XPropertyChangeListener* >( this ) );
297     m_xControlModel.clear();
298 }
299 
300 // -----------------------------------------------------------------------------
301 // XPropertyChangeListener
302 // -----------------------------------------------------------------------------
303 
304 void AccessibleDialogControlShape::propertyChange( const beans::PropertyChangeEvent& rEvent ) throw (RuntimeException)
305 {
306     if ( rEvent.PropertyName == DLGED_PROP_NAME )
307     {
308         NotifyAccessibleEvent( AccessibleEventId::NAME_CHANGED, rEvent.OldValue, rEvent.NewValue );
309     }
310     else if ( rEvent.PropertyName == DLGED_PROP_POSITIONX ||
311               rEvent.PropertyName == DLGED_PROP_POSITIONY ||
312               rEvent.PropertyName == DLGED_PROP_WIDTH ||
313               rEvent.PropertyName == DLGED_PROP_HEIGHT )
314     {
315         SetBounds( GetBounds() );
316     }
317     else if ( rEvent.PropertyName == DLGED_PROP_BACKGROUNDCOLOR ||
318               rEvent.PropertyName == DLGED_PROP_TEXTCOLOR ||
319               rEvent.PropertyName == DLGED_PROP_TEXTLINECOLOR )
320     {
321         NotifyAccessibleEvent( AccessibleEventId::VISIBLE_DATA_CHANGED, Any(), Any() );
322     }
323 }
324 
325 // -----------------------------------------------------------------------------
326 // XServiceInfo
327 // -----------------------------------------------------------------------------
328 
329 ::rtl::OUString AccessibleDialogControlShape::getImplementationName() throw (RuntimeException)
330 {
331     return ::rtl::OUString::createFromAscii( "com.sun.star.comp.basctl.AccessibleShape" );
332 }
333 
334 // -----------------------------------------------------------------------------
335 
336 sal_Bool AccessibleDialogControlShape::supportsService( const ::rtl::OUString& rServiceName ) throw (RuntimeException)
337 {
338     Sequence< ::rtl::OUString > aNames( getSupportedServiceNames() );
339     const ::rtl::OUString* pNames = aNames.getConstArray();
340     const ::rtl::OUString* pEnd = pNames + aNames.getLength();
341     for ( ; pNames != pEnd && !pNames->equals( rServiceName ); ++pNames )
342         ;
343 
344     return pNames != pEnd;
345 }
346 
347 // -----------------------------------------------------------------------------
348 
349 Sequence< ::rtl::OUString > AccessibleDialogControlShape::getSupportedServiceNames() throw (RuntimeException)
350 {
351     Sequence< ::rtl::OUString > aNames(1);
352     aNames[0] = ::rtl::OUString::createFromAscii( "com.sun.star.drawing.AccessibleShape" );
353     return aNames;
354 }
355 
356 // -----------------------------------------------------------------------------
357 // XAccessible
358 // -----------------------------------------------------------------------------
359 
360 Reference< XAccessibleContext > AccessibleDialogControlShape::getAccessibleContext(  ) throw (RuntimeException)
361 {
362     OExternalLockGuard aGuard( this );
363 
364     return this;
365 }
366 
367 // -----------------------------------------------------------------------------
368 // XAccessibleContext
369 // -----------------------------------------------------------------------------
370 
371 sal_Int32 AccessibleDialogControlShape::getAccessibleChildCount() throw (RuntimeException)
372 {
373     OExternalLockGuard aGuard( this );
374 
375     return 0;
376 }
377 
378 // -----------------------------------------------------------------------------
379 
380 Reference< XAccessible > AccessibleDialogControlShape::getAccessibleChild( sal_Int32 i ) throw (IndexOutOfBoundsException, RuntimeException)
381 {
382     OExternalLockGuard aGuard( this );
383 
384     if ( i < 0 || i >= getAccessibleChildCount() )
385         throw IndexOutOfBoundsException();
386 
387     return Reference< XAccessible >();
388 }
389 
390 // -----------------------------------------------------------------------------
391 
392 Reference< XAccessible > AccessibleDialogControlShape::getAccessibleParent(  ) throw (RuntimeException)
393 {
394     OExternalLockGuard aGuard( this );
395 
396     Reference< XAccessible > xParent;
397     if ( m_pDialogWindow )
398         xParent = m_pDialogWindow->GetAccessible();
399 
400     return xParent;
401 }
402 
403 // -----------------------------------------------------------------------------
404 
405 sal_Int32 AccessibleDialogControlShape::getAccessibleIndexInParent(  ) throw (RuntimeException)
406 {
407     OExternalLockGuard aGuard( this );
408 
409     sal_Int32 nIndexInParent = -1;
410     Reference< XAccessible > xParent( getAccessibleParent() );
411     if ( xParent.is() )
412     {
413         Reference< XAccessibleContext > xParentContext( xParent->getAccessibleContext() );
414         if ( xParentContext.is() )
415         {
416             for ( sal_Int32 i = 0, nCount = xParentContext->getAccessibleChildCount(); i < nCount; ++i )
417             {
418                 Reference< XAccessible > xChild( xParentContext->getAccessibleChild( i ) );
419                 if ( xChild.is() )
420                 {
421                     Reference< XAccessibleContext > xChildContext = xChild->getAccessibleContext();
422                     if ( xChildContext == (XAccessibleContext*)this )
423                     {
424                         nIndexInParent = i;
425                         break;
426                     }
427                 }
428             }
429         }
430     }
431 
432     return nIndexInParent;
433 }
434 
435 // -----------------------------------------------------------------------------
436 
437 sal_Int16 AccessibleDialogControlShape::getAccessibleRole(  ) throw (RuntimeException)
438 {
439     OExternalLockGuard aGuard( this );
440 
441     return AccessibleRole::SHAPE;
442 }
443 
444 // -----------------------------------------------------------------------------
445 
446 ::rtl::OUString AccessibleDialogControlShape::getAccessibleDescription( ) throw (RuntimeException)
447 {
448     OExternalLockGuard aGuard( this );
449 
450     return GetModelStringProperty( "HelpText" );
451 }
452 
453 // -----------------------------------------------------------------------------
454 
455 ::rtl::OUString AccessibleDialogControlShape::getAccessibleName(  ) throw (RuntimeException)
456 {
457     OExternalLockGuard aGuard( this );
458 
459     return GetModelStringProperty( "Name" );
460 }
461 
462 // -----------------------------------------------------------------------------
463 
464 Reference< XAccessibleRelationSet > AccessibleDialogControlShape::getAccessibleRelationSet(  ) throw (RuntimeException)
465 {
466     OExternalLockGuard aGuard( this );
467 
468     utl::AccessibleRelationSetHelper* pRelationSetHelper = new utl::AccessibleRelationSetHelper;
469     Reference< XAccessibleRelationSet > xSet = pRelationSetHelper;
470     return xSet;
471 }
472 
473 // -----------------------------------------------------------------------------
474 
475 Reference< XAccessibleStateSet > AccessibleDialogControlShape::getAccessibleStateSet(  ) throw (RuntimeException)
476 {
477     OExternalLockGuard aGuard( this );
478 
479     utl::AccessibleStateSetHelper* pStateSetHelper = new utl::AccessibleStateSetHelper;
480     Reference< XAccessibleStateSet > xSet = pStateSetHelper;
481 
482     if ( !rBHelper.bDisposed && !rBHelper.bInDispose )
483     {
484         FillAccessibleStateSet( *pStateSetHelper );
485     }
486     else
487     {
488         pStateSetHelper->AddState( AccessibleStateType::DEFUNC );
489     }
490 
491     return xSet;
492 }
493 
494 // -----------------------------------------------------------------------------
495 
496 Locale AccessibleDialogControlShape::getLocale(  ) throw (IllegalAccessibleComponentStateException, RuntimeException)
497 {
498     OExternalLockGuard aGuard( this );
499 
500     return Application::GetSettings().GetLocale();
501 }
502 
503 // -----------------------------------------------------------------------------
504 // XAccessibleComponent
505 // -----------------------------------------------------------------------------
506 
507 Reference< XAccessible > AccessibleDialogControlShape::getAccessibleAtPoint( const awt::Point& ) throw (RuntimeException)
508 {
509     OExternalLockGuard aGuard( this );
510 
511     return Reference< XAccessible >();
512 }
513 
514 // -----------------------------------------------------------------------------
515 
516 void AccessibleDialogControlShape::grabFocus(  ) throw (RuntimeException)
517 {
518     // no focus for shapes
519 }
520 
521 // -----------------------------------------------------------------------------
522 
523 sal_Int32 AccessibleDialogControlShape::getForeground(  ) throw (RuntimeException)
524 {
525     OExternalLockGuard aGuard( this );
526 
527     sal_Int32 nColor = 0;
528     Window* pWindow = GetWindow();
529     if ( pWindow )
530     {
531         if ( pWindow->IsControlForeground() )
532             nColor = pWindow->GetControlForeground().GetColor();
533         else
534         {
535             Font aFont;
536             if ( pWindow->IsControlFont() )
537                 aFont = pWindow->GetControlFont();
538             else
539                 aFont = pWindow->GetFont();
540             nColor = aFont.GetColor().GetColor();
541         }
542     }
543 
544     return nColor;
545 }
546 
547 // -----------------------------------------------------------------------------
548 
549 sal_Int32 AccessibleDialogControlShape::getBackground(  ) throw (RuntimeException)
550 {
551     OExternalLockGuard aGuard( this );
552 
553     sal_Int32 nColor = 0;
554     Window* pWindow = GetWindow();
555     if ( pWindow )
556     {
557         if ( pWindow->IsControlBackground() )
558             nColor = pWindow->GetControlBackground().GetColor();
559         else
560             nColor = pWindow->GetBackground().GetColor().GetColor();
561     }
562 
563     return nColor;
564 }
565 
566 // -----------------------------------------------------------------------------
567 // XAccessibleExtendedComponent
568 // -----------------------------------------------------------------------------
569 
570 Reference< awt::XFont > AccessibleDialogControlShape::getFont(  ) throw (RuntimeException)
571 {
572     OExternalLockGuard aGuard( this );
573 
574     Reference< awt::XFont > xFont;
575     Window* pWindow = GetWindow();
576     if ( pWindow )
577     {
578         Reference< awt::XDevice > xDev( pWindow->GetComponentInterface(), UNO_QUERY );
579         if ( xDev.is() )
580         {
581             Font aFont;
582             if ( pWindow->IsControlFont() )
583                 aFont = pWindow->GetControlFont();
584             else
585                 aFont = pWindow->GetFont();
586             VCLXFont* pVCLXFont = new VCLXFont;
587             pVCLXFont->Init( *xDev.get(), aFont );
588             xFont = pVCLXFont;
589         }
590     }
591 
592     return xFont;
593 }
594 
595 // -----------------------------------------------------------------------------
596 
597 ::rtl::OUString AccessibleDialogControlShape::getTitledBorderText(  ) throw (RuntimeException)
598 {
599     OExternalLockGuard aGuard( this );
600 
601     return ::rtl::OUString();
602 }
603 
604 // -----------------------------------------------------------------------------
605 
606 ::rtl::OUString AccessibleDialogControlShape::getToolTipText(  ) throw (RuntimeException)
607 {
608     OExternalLockGuard aGuard( this );
609 
610     ::rtl::OUString sText;
611     Window* pWindow = GetWindow();
612     if ( pWindow )
613         sText = pWindow->GetQuickHelpText();
614 
615     return sText;
616 }
617 
618 // -----------------------------------------------------------------------------
619 
620