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