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