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