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 <accessibledialogwindow.hxx>
27 #include <accessibledialogcontrolshape.hxx>
28 #include <baside3.hxx>
29 #include <dlged.hxx>
30 #include <dlgedmod.hxx>
31 #include <dlgedpage.hxx>
32 #include <dlgedview.hxx>
33 #include <dlgedobj.hxx>
34 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
35 #include <com/sun/star/accessibility/AccessibleRole.hpp>
36 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
37 #include <unotools/accessiblestatesethelper.hxx>
38 #include <unotools/accessiblerelationsethelper.hxx>
39 #include <toolkit/awt/vclxfont.hxx>
40 #include <toolkit/helper/externallock.hxx>
41 #include <toolkit/helper/convert.hxx>
42 #include <vcl/svapp.hxx>
43 
44 #include <vector>
45 #include <algorithm>
46 
47 
48 using namespace ::com::sun::star;
49 using namespace ::com::sun::star::uno;
50 using namespace ::com::sun::star::lang;
51 using namespace ::com::sun::star::accessibility;
52 using namespace ::comphelper;
53 
DBG_NAME(AccessibleDialogWindow)54 DBG_NAME( AccessibleDialogWindow )
55 
56 
57 // -----------------------------------------------------------------------------
58 //	class ChildDescriptor
59 // -----------------------------------------------------------------------------
60 
61 AccessibleDialogWindow::ChildDescriptor::ChildDescriptor( DlgEdObj* _pDlgEdObj )
62 	:pDlgEdObj( _pDlgEdObj )
63 	,rxAccessible( 0 )
64 {
65 }
66 
67 // -----------------------------------------------------------------------------
68 
~ChildDescriptor()69 AccessibleDialogWindow::ChildDescriptor::~ChildDescriptor()
70 {
71 }
72 
73 // -----------------------------------------------------------------------------
74 
ChildDescriptor(const ChildDescriptor & rDesc)75 AccessibleDialogWindow::ChildDescriptor::ChildDescriptor( const ChildDescriptor& rDesc )
76 	:pDlgEdObj( rDesc.pDlgEdObj )
77 	,rxAccessible( rDesc.rxAccessible )
78 {
79 }
80 
81 // -----------------------------------------------------------------------------
82 
operator =(const ChildDescriptor & rDesc)83 AccessibleDialogWindow::ChildDescriptor& AccessibleDialogWindow::ChildDescriptor::operator=( const ChildDescriptor& rDesc )
84 {
85 	pDlgEdObj = rDesc.pDlgEdObj;
86 	rxAccessible = rDesc.rxAccessible;
87 
88 	return *this;
89 }
90 
91 // -----------------------------------------------------------------------------
92 
operator ==(const ChildDescriptor & rDesc)93 bool AccessibleDialogWindow::ChildDescriptor::operator==( const ChildDescriptor& rDesc )
94 {
95 	bool bRet = false;
96 	if ( pDlgEdObj == rDesc.pDlgEdObj )
97 		bRet = true;
98 
99 	return bRet;
100 }
101 
102 // -----------------------------------------------------------------------------
103 
operator <(const ChildDescriptor & rDesc) const104 bool AccessibleDialogWindow::ChildDescriptor::operator<( const ChildDescriptor& rDesc ) const
105 {
106 	bool bRet = false;
107 	if ( pDlgEdObj && rDesc.pDlgEdObj && pDlgEdObj->GetOrdNum() < rDesc.pDlgEdObj->GetOrdNum() )
108 		bRet = true;
109 
110 	return bRet;
111 }
112 
113 // -----------------------------------------------------------------------------
114 //	class AccessibleDialogWindow
115 // -----------------------------------------------------------------------------
116 
AccessibleDialogWindow(DialogWindow * pDialogWindow)117 AccessibleDialogWindow::AccessibleDialogWindow( DialogWindow* pDialogWindow )
118 	:AccessibleExtendedComponentHelper_BASE( new VCLExternalSolarLock() )
119 	,m_pDialogWindow( pDialogWindow )
120 {
121 	DBG_CTOR( AccessibleDialogWindow, NULL );
122 	m_pExternalLock = static_cast< VCLExternalSolarLock* >( getExternalLock() );
123 
124 	if ( m_pDialogWindow )
125 	{
126 		SdrPage* pSdrPage = m_pDialogWindow->GetPage();
127 		if ( pSdrPage )
128 		{
129 			sal_uLong nCount = pSdrPage->GetObjCount();
130 
131 			for ( sal_uLong i = 0; i < nCount; ++i )
132 			{
133 				SdrObject* pObj = pSdrPage->GetObj( i );
134 				DlgEdObj* pDlgEdObj = PTR_CAST( DlgEdObj, pObj );
135 				if ( pDlgEdObj )
136 				{
137 					ChildDescriptor aDesc( pDlgEdObj );
138 					if ( IsChildVisible( aDesc ) )
139 						m_aAccessibleChildren.push_back( aDesc );
140 				}
141 			}
142 		}
143 
144 		m_pDialogWindow->AddEventListener( LINK( this, AccessibleDialogWindow, WindowEventListener ) );
145 
146 		m_pDlgEditor = m_pDialogWindow->GetEditor();
147 		if ( m_pDlgEditor )
148 			StartListening( *m_pDlgEditor );
149 
150 		m_pDlgEdModel = m_pDialogWindow->GetModel();
151 		if ( m_pDlgEdModel )
152 			StartListening( *m_pDlgEdModel );
153 	}
154 }
155 
156 // -----------------------------------------------------------------------------
157 
~AccessibleDialogWindow()158 AccessibleDialogWindow::~AccessibleDialogWindow()
159 {
160 	DBG_DTOR( AccessibleDialogWindow, NULL );
161 	if ( m_pDialogWindow )
162 		m_pDialogWindow->RemoveEventListener( LINK( this, AccessibleDialogWindow, WindowEventListener ) );
163 
164 	if ( m_pDlgEditor )
165 		EndListening( *m_pDlgEditor );
166 
167 	if ( m_pDlgEdModel )
168 		EndListening( *m_pDlgEdModel );
169 
170 	delete m_pExternalLock;
171 	m_pExternalLock = NULL;
172 }
173 
174 // -----------------------------------------------------------------------------
175 
UpdateFocused()176 void AccessibleDialogWindow::UpdateFocused()
177 {
178 	for ( sal_uInt32 i = 0; i < m_aAccessibleChildren.size(); ++i )
179 	{
180 		Reference< XAccessible > xChild( m_aAccessibleChildren[i].rxAccessible );
181 		if ( xChild.is() )
182 		{
183 			AccessibleDialogControlShape* pShape = static_cast< AccessibleDialogControlShape* >( xChild.get() );
184 			if ( pShape )
185 				pShape->SetFocused( pShape->IsFocused() );
186 		}
187 	}
188 }
189 
190 // -----------------------------------------------------------------------------
191 
UpdateSelected()192 void AccessibleDialogWindow::UpdateSelected()
193 {
194 	NotifyAccessibleEvent( AccessibleEventId::SELECTION_CHANGED, Any(), Any() );
195 
196 	for ( sal_uInt32 i = 0; i < m_aAccessibleChildren.size(); ++i )
197 	{
198 		Reference< XAccessible > xChild( m_aAccessibleChildren[i].rxAccessible );
199 		if ( xChild.is() )
200 		{
201 			AccessibleDialogControlShape* pShape = static_cast< AccessibleDialogControlShape* >( xChild.get() );
202 			if ( pShape )
203 				pShape->SetSelected( pShape->IsSelected() );
204 		}
205 	}
206 }
207 
208 // -----------------------------------------------------------------------------
209 
UpdateBounds()210 void AccessibleDialogWindow::UpdateBounds()
211 {
212 	for ( sal_uInt32 i = 0; i < m_aAccessibleChildren.size(); ++i )
213 	{
214 		Reference< XAccessible > xChild( m_aAccessibleChildren[i].rxAccessible );
215 		if ( xChild.is() )
216 		{
217 			AccessibleDialogControlShape* pShape = static_cast< AccessibleDialogControlShape* >( xChild.get() );
218 			if ( pShape )
219 				pShape->SetBounds( pShape->GetBounds() );
220 		}
221 	}
222 }
223 
224 // -----------------------------------------------------------------------------
225 
IsChildVisible(const ChildDescriptor & rDesc)226 sal_Bool AccessibleDialogWindow::IsChildVisible( const ChildDescriptor& rDesc )
227 {
228 	sal_Bool bVisible = sal_False;
229 
230 	if ( m_pDialogWindow )
231 	{
232 		// first check, if the shape is in a visible layer
233 		SdrModel* pSdrModel = m_pDialogWindow->GetModel();
234 		if ( pSdrModel )
235 		{
236 			SdrLayerAdmin& rLayerAdmin = pSdrModel->GetLayerAdmin();
237 			DlgEdObj* pDlgEdObj = rDesc.pDlgEdObj;
238 			if ( pDlgEdObj )
239 			{
240 				SdrLayerID nLayerId = pDlgEdObj->GetLayer();
241 				const SdrLayer* pSdrLayer = rLayerAdmin.GetLayerPerID( nLayerId );
242 				if ( pSdrLayer )
243 				{
244 					String aLayerName = pSdrLayer->GetName();
245 					SdrView* pSdrView = m_pDialogWindow->GetView();
246 					if ( pSdrView && pSdrView->IsLayerVisible( aLayerName ) )
247 					{
248 						// get the bounding box of the shape in logic units
249 						Rectangle aRect = pDlgEdObj->GetSnapRect();
250 
251 						// transform coordinates relative to the parent
252 						MapMode aMap = m_pDialogWindow->GetMapMode();
253 						Point aOrg = aMap.GetOrigin();
254 						aRect.Move( aOrg.X(), aOrg.Y() );
255 
256 						// convert logic units to pixel
257 						aRect = m_pDialogWindow->LogicToPixel( aRect, MapMode(MAP_100TH_MM) );
258 
259 						// check, if the shape's bounding box intersects with the bounding box of its parent
260 						Rectangle aParentRect( Point( 0, 0 ), m_pDialogWindow->GetSizePixel() );
261 						if ( aParentRect.IsOver( aRect ) )
262 							bVisible = sal_True;
263 					}
264 				}
265 			}
266 		}
267 	}
268 
269 	return bVisible;
270 }
271 
272 // -----------------------------------------------------------------------------
273 
InsertChild(const ChildDescriptor & rDesc)274 void AccessibleDialogWindow::InsertChild( const ChildDescriptor& rDesc )
275 {
276 	// check, if object is already in child list
277 	AccessibleChildren::iterator aIter = ::std::find( m_aAccessibleChildren.begin(), m_aAccessibleChildren.end(), rDesc );
278 
279 	// if not found, insert in child list
280 	if ( aIter == m_aAccessibleChildren.end() )
281 	{
282 		// insert entry in child list
283 		m_aAccessibleChildren.push_back( rDesc );
284 
285 		// get the accessible of the inserted child
286 		Reference< XAccessible > xChild( getAccessibleChild( m_aAccessibleChildren.size() - 1 ) );
287 
288 		// sort child list
289 		SortChildren();
290 
291 		// send accessible child event
292 		if ( xChild.is() )
293 		{
294 			Any aOldValue, aNewValue;
295 			aNewValue <<= xChild;
296 			NotifyAccessibleEvent( AccessibleEventId::CHILD, aOldValue, aNewValue );
297 		}
298 	}
299 }
300 
301 // -----------------------------------------------------------------------------
302 
RemoveChild(const ChildDescriptor & rDesc)303 void AccessibleDialogWindow::RemoveChild( const ChildDescriptor& rDesc )
304 {
305 	// find object in child list
306 	AccessibleChildren::iterator aIter = ::std::find( m_aAccessibleChildren.begin(), m_aAccessibleChildren.end(), rDesc );
307 
308 	// if found, remove from child list
309 	if ( aIter != m_aAccessibleChildren.end() )
310 	{
311 		// get the accessible of the removed child
312 		Reference< XAccessible > xChild( aIter->rxAccessible );
313 
314 		// remove entry from child list
315 		m_aAccessibleChildren.erase( aIter );
316 
317 		// send accessible child event
318 		if ( xChild.is() )
319 		{
320 			Any aOldValue, aNewValue;
321 			aOldValue <<= xChild;
322 			NotifyAccessibleEvent( AccessibleEventId::CHILD, aOldValue, aNewValue );
323 
324 			Reference< XComponent > xComponent( xChild, UNO_QUERY );
325 			if ( xComponent.is() )
326 				xComponent->dispose();
327 		}
328 	}
329 }
330 
331 // -----------------------------------------------------------------------------
332 
UpdateChild(const ChildDescriptor & rDesc)333 void AccessibleDialogWindow::UpdateChild( const ChildDescriptor& rDesc )
334 {
335 	if ( IsChildVisible( rDesc ) )
336 	{
337 		// if the object is not in the child list, insert child
338 		InsertChild( rDesc );
339 	}
340 	else
341 	{
342 		// if the object is in the child list, remove child
343 		RemoveChild( rDesc );
344 	}
345 }
346 
347 // -----------------------------------------------------------------------------
348 
UpdateChildren()349 void AccessibleDialogWindow::UpdateChildren()
350 {
351 	if ( m_pDialogWindow )
352 	{
353 		SdrPage* pSdrPage = m_pDialogWindow->GetPage();
354 		if ( pSdrPage )
355 		{
356 			for ( sal_uLong i = 0, nCount = pSdrPage->GetObjCount(); i < nCount; ++i )
357 			{
358 				SdrObject* pObj = pSdrPage->GetObj( i );
359 				DlgEdObj* pDlgEdObj = PTR_CAST( DlgEdObj, pObj );
360 				if ( pDlgEdObj )
361 					UpdateChild( ChildDescriptor( pDlgEdObj ) );
362 			}
363 		}
364 	}
365 }
366 
367 // -----------------------------------------------------------------------------
368 
SortChildren()369 void AccessibleDialogWindow::SortChildren()
370 {
371 	// sort child list
372 	::std::sort( m_aAccessibleChildren.begin(), m_aAccessibleChildren.end() );
373 }
374 
375 // -----------------------------------------------------------------------------
376 
IMPL_LINK(AccessibleDialogWindow,WindowEventListener,VclSimpleEvent *,pEvent)377 IMPL_LINK( AccessibleDialogWindow, WindowEventListener, VclSimpleEvent*, pEvent )
378 {
379 	DBG_CHKTHIS( AccessibleDialogWindow, 0 );
380 	DBG_ASSERT( pEvent && pEvent->ISA( VclWindowEvent ), "AccessibleDialogWindow::WindowEventListener: unknown window event!" );
381 
382 	if ( pEvent && pEvent->ISA( VclWindowEvent ) )
383 	{
384 		DBG_ASSERT( ((VclWindowEvent*)pEvent)->GetWindow(), "AccessibleDialogWindow::WindowEventListener: no window!" );
385 		if ( !((VclWindowEvent*)pEvent)->GetWindow()->IsAccessibilityEventsSuppressed() || ( pEvent->GetId() == VCLEVENT_OBJECT_DYING ) )
386 		{
387 			ProcessWindowEvent( *(VclWindowEvent*)pEvent );
388 		}
389 	}
390 
391 	return 0;
392 }
393 
394 // -----------------------------------------------------------------------------
395 
ProcessWindowEvent(const VclWindowEvent & rVclWindowEvent)396 void AccessibleDialogWindow::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent )
397 {
398 	Any aOldValue, aNewValue;
399 
400 	switch ( rVclWindowEvent.GetId() )
401 	{
402 		case VCLEVENT_WINDOW_ENABLED:
403 		{
404 			aNewValue <<= AccessibleStateType::ENABLED;
405 			NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );
406 		}
407 		break;
408 		case VCLEVENT_WINDOW_DISABLED:
409 		{
410 			aOldValue <<= AccessibleStateType::ENABLED;
411 			NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );
412 		}
413 		break;
414 		case VCLEVENT_WINDOW_ACTIVATE:
415 		{
416 			aNewValue <<= AccessibleStateType::ACTIVE;
417 			NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );
418 		}
419 		break;
420 		case VCLEVENT_WINDOW_DEACTIVATE:
421 		{
422 			aOldValue <<= AccessibleStateType::ACTIVE;
423 			NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );
424 		}
425 		break;
426 		case VCLEVENT_WINDOW_GETFOCUS:
427 		{
428 			aNewValue <<= AccessibleStateType::FOCUSED;
429 			NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );
430 		}
431 		break;
432 		case VCLEVENT_WINDOW_LOSEFOCUS:
433 		{
434 			aOldValue <<= AccessibleStateType::FOCUSED;
435 			NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );
436 		}
437 		break;
438 		case VCLEVENT_WINDOW_SHOW:
439 		{
440 			aNewValue <<= AccessibleStateType::SHOWING;
441 			NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );
442 		}
443 		break;
444 		case VCLEVENT_WINDOW_HIDE:
445 		{
446 			aOldValue <<= AccessibleStateType::SHOWING;
447 			NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );
448 		}
449 		break;
450 		case VCLEVENT_WINDOW_RESIZE:
451 		{
452 			NotifyAccessibleEvent( AccessibleEventId::BOUNDRECT_CHANGED, aOldValue, aNewValue );
453 			UpdateChildren();
454 			UpdateBounds();
455 		}
456 		break;
457 		case VCLEVENT_OBJECT_DYING:
458 		{
459 			if ( m_pDialogWindow )
460 			{
461 				m_pDialogWindow->RemoveEventListener( LINK( this, AccessibleDialogWindow, WindowEventListener ) );
462 				m_pDialogWindow = NULL;
463 
464 				if ( m_pDlgEditor )
465 					EndListening( *m_pDlgEditor );
466 				m_pDlgEditor = NULL;
467 
468 				if ( m_pDlgEdModel )
469 					EndListening( *m_pDlgEdModel );
470 				m_pDlgEdModel = NULL;
471 
472 				// dispose all children
473 				for ( sal_uInt32 i = 0; i < m_aAccessibleChildren.size(); ++i )
474 				{
475 					Reference< XComponent > xComponent( m_aAccessibleChildren[i].rxAccessible, UNO_QUERY );
476 					if ( xComponent.is() )
477 						xComponent->dispose();
478 				}
479 				m_aAccessibleChildren.clear();
480 			}
481 		}
482 		break;
483 		default:
484 		{
485 		}
486 		break;
487 	}
488 }
489 
490 // -----------------------------------------------------------------------------
491 
FillAccessibleStateSet(utl::AccessibleStateSetHelper & rStateSet)492 void AccessibleDialogWindow::FillAccessibleStateSet( utl::AccessibleStateSetHelper& rStateSet )
493 {
494 	if ( m_pDialogWindow )
495 	{
496 		if ( m_pDialogWindow->IsEnabled() )
497 			rStateSet.AddState( AccessibleStateType::ENABLED );
498 
499 		rStateSet.AddState( AccessibleStateType::FOCUSABLE );
500 
501 		if ( m_pDialogWindow->HasFocus() )
502 			rStateSet.AddState( AccessibleStateType::FOCUSED );
503 
504 		rStateSet.AddState( AccessibleStateType::VISIBLE );
505 
506 		if ( m_pDialogWindow->IsVisible() )
507 			rStateSet.AddState( AccessibleStateType::SHOWING );
508 
509 		rStateSet.AddState( AccessibleStateType::OPAQUE );
510 
511 		rStateSet.AddState( AccessibleStateType::RESIZABLE );
512 	}
513 }
514 
515 // -----------------------------------------------------------------------------
516 // OCommonAccessibleComponent
517 // -----------------------------------------------------------------------------
518 
implGetBounds()519 awt::Rectangle AccessibleDialogWindow::implGetBounds() throw (RuntimeException)
520 {
521 	awt::Rectangle aBounds;
522 	if ( m_pDialogWindow )
523 		aBounds = AWTRectangle( Rectangle( m_pDialogWindow->GetPosPixel(), m_pDialogWindow->GetSizePixel() ) );
524 
525 	return aBounds;
526 }
527 
528 // -----------------------------------------------------------------------------
529 // SfxListener
530 // -----------------------------------------------------------------------------
531 
Notify(SfxBroadcaster &,const SfxHint & rHint)532 void AccessibleDialogWindow::Notify( SfxBroadcaster&, const SfxHint& rHint )
533 {
534 	if ( rHint.ISA( SdrHint ) )
535 	{
536 		SdrHint* pSdrHint = (SdrHint*)&rHint;
537 		switch ( pSdrHint->GetKind() )
538 		{
539 			case HINT_OBJINSERTED:
540 			{
541 				SdrObject* pObj = (SdrObject*)pSdrHint->GetObject();
542 				DlgEdObj* pDlgEdObj = PTR_CAST( DlgEdObj, pObj );
543 				if ( pDlgEdObj )
544 				{
545 					ChildDescriptor aDesc( pDlgEdObj );
546 					if ( IsChildVisible( aDesc ) )
547 						InsertChild( aDesc );
548 				}
549 			}
550 			break;
551 			case HINT_OBJREMOVED:
552 			{
553 				SdrObject* pObj = (SdrObject*)pSdrHint->GetObject();
554 				DlgEdObj* pDlgEdObj = PTR_CAST( DlgEdObj, pObj );
555 				if ( pDlgEdObj )
556 					RemoveChild( ChildDescriptor( pDlgEdObj ) );
557 			}
558 			break;
559 			default: ;
560 		}
561 	}
562 	else if ( rHint.ISA( DlgEdHint ) )
563 	{
564 		DlgEdHint* pDlgEdHint = (DlgEdHint*)&rHint;
565 		switch ( pDlgEdHint->GetKind() )
566 		{
567 			case DLGED_HINT_WINDOWSCROLLED:
568 			{
569 				UpdateChildren();
570 				UpdateBounds();
571 			}
572 			break;
573 			case DLGED_HINT_LAYERCHANGED:
574 			{
575 				DlgEdObj* pDlgEdObj = pDlgEdHint->GetObject();
576 				if ( pDlgEdObj )
577 					UpdateChild( ChildDescriptor( pDlgEdObj ) );
578 			}
579 			break;
580 			case DLGED_HINT_OBJORDERCHANGED:
581 			{
582 				SortChildren();
583 			}
584 			break;
585 			case DLGED_HINT_SELECTIONCHANGED:
586 			{
587 				UpdateFocused();
588 				UpdateSelected();
589 			}
590 			break;
591 			default: ;
592 		}
593 	}
594 }
595 
596 // -----------------------------------------------------------------------------
597 // XInterface
598 // -----------------------------------------------------------------------------
599 
IMPLEMENT_FORWARD_XINTERFACE2(AccessibleDialogWindow,AccessibleExtendedComponentHelper_BASE,AccessibleDialogWindow_BASE)600 IMPLEMENT_FORWARD_XINTERFACE2( AccessibleDialogWindow, AccessibleExtendedComponentHelper_BASE, AccessibleDialogWindow_BASE )
601 
602 // -----------------------------------------------------------------------------
603 // XTypeProvider
604 // -----------------------------------------------------------------------------
605 
606 IMPLEMENT_FORWARD_XTYPEPROVIDER2( AccessibleDialogWindow, AccessibleExtendedComponentHelper_BASE, AccessibleDialogWindow_BASE )
607 
608 // -----------------------------------------------------------------------------
609 // XComponent
610 // -----------------------------------------------------------------------------
611 
612 void AccessibleDialogWindow::disposing()
613 {
614 	AccessibleExtendedComponentHelper_BASE::disposing();
615 
616 	if ( m_pDialogWindow )
617 	{
618 		m_pDialogWindow->RemoveEventListener( LINK( this, AccessibleDialogWindow, WindowEventListener ) );
619 		m_pDialogWindow = NULL;
620 
621 		if ( m_pDlgEditor )
622 			EndListening( *m_pDlgEditor );
623 		m_pDlgEditor = NULL;
624 
625 		if ( m_pDlgEdModel )
626 			EndListening( *m_pDlgEdModel );
627 		m_pDlgEdModel = NULL;
628 
629 		// dispose all children
630 		for ( sal_uInt32 i = 0; i < m_aAccessibleChildren.size(); ++i )
631 		{
632 			Reference< XComponent > xComponent( m_aAccessibleChildren[i].rxAccessible, UNO_QUERY );
633 			if ( xComponent.is() )
634 				xComponent->dispose();
635 		}
636 		m_aAccessibleChildren.clear();
637 	}
638 }
639 
640 // -----------------------------------------------------------------------------
641 // XServiceInfo
642 // -----------------------------------------------------------------------------
643 
getImplementationName()644 ::rtl::OUString AccessibleDialogWindow::getImplementationName() throw (RuntimeException)
645 {
646 	return ::rtl::OUString::createFromAscii( "com.sun.star.comp.basctl.AccessibleWindow" );
647 }
648 
649 // -----------------------------------------------------------------------------
650 
supportsService(const::rtl::OUString & rServiceName)651 sal_Bool AccessibleDialogWindow::supportsService( const ::rtl::OUString& rServiceName ) throw (RuntimeException)
652 {
653 	Sequence< ::rtl::OUString > aNames( getSupportedServiceNames() );
654 	const ::rtl::OUString* pNames = aNames.getConstArray();
655 	const ::rtl::OUString* pEnd = pNames + aNames.getLength();
656 	for ( ; pNames != pEnd && !pNames->equals( rServiceName ); ++pNames )
657 		;
658 
659 	return pNames != pEnd;
660 }
661 
662 // -----------------------------------------------------------------------------
663 
getSupportedServiceNames()664 Sequence< ::rtl::OUString > AccessibleDialogWindow::getSupportedServiceNames() throw (RuntimeException)
665 {
666 	Sequence< ::rtl::OUString > aNames(1);
667 	aNames[0] = ::rtl::OUString::createFromAscii( "com.sun.star.awt.AccessibleWindow" );
668 	return aNames;
669 }
670 
671 // -----------------------------------------------------------------------------
672 // XAccessible
673 // -----------------------------------------------------------------------------
674 
getAccessibleContext()675 Reference< XAccessibleContext > AccessibleDialogWindow::getAccessibleContext(  ) throw (RuntimeException)
676 {
677 	OExternalLockGuard aGuard( this );
678 
679 	return this;
680 }
681 
682 // -----------------------------------------------------------------------------
683 // XAccessibleContext
684 // -----------------------------------------------------------------------------
685 
getAccessibleChildCount()686 sal_Int32 AccessibleDialogWindow::getAccessibleChildCount() throw (RuntimeException)
687 {
688 	OExternalLockGuard aGuard( this );
689 
690 	return m_aAccessibleChildren.size();
691 }
692 
693 // -----------------------------------------------------------------------------
694 
getAccessibleChild(sal_Int32 i)695 Reference< XAccessible > AccessibleDialogWindow::getAccessibleChild( sal_Int32 i ) throw (IndexOutOfBoundsException, RuntimeException)
696 {
697 	OExternalLockGuard aGuard( this );
698 
699 	if ( i < 0 || i >= getAccessibleChildCount() )
700 		throw IndexOutOfBoundsException();
701 
702 	Reference< XAccessible > xChild = m_aAccessibleChildren[i].rxAccessible;
703 	if ( !xChild.is() )
704 	{
705 		if ( m_pDialogWindow )
706 		{
707 			DlgEdObj* pDlgEdObj = m_aAccessibleChildren[i].pDlgEdObj;
708 			if ( pDlgEdObj )
709 			{
710 				xChild = new AccessibleDialogControlShape( m_pDialogWindow, pDlgEdObj );
711 
712 				// insert into child list
713 				m_aAccessibleChildren[i].rxAccessible = xChild;
714 			}
715 		}
716 	}
717 
718 	return xChild;
719 }
720 
721 // -----------------------------------------------------------------------------
722 
getAccessibleParent()723 Reference< XAccessible > AccessibleDialogWindow::getAccessibleParent(  ) throw (RuntimeException)
724 {
725 	OExternalLockGuard aGuard( this );
726 
727 	Reference< XAccessible > xParent;
728 	if ( m_pDialogWindow )
729 	{
730 		Window* pParent = m_pDialogWindow->GetAccessibleParentWindow();
731 		if ( pParent )
732 			xParent = pParent->GetAccessible();
733 	}
734 
735 	return xParent;
736 }
737 
738 // -----------------------------------------------------------------------------
739 
getAccessibleIndexInParent()740 sal_Int32 AccessibleDialogWindow::getAccessibleIndexInParent(  ) throw (RuntimeException)
741 {
742 	OExternalLockGuard aGuard( this );
743 
744 	sal_Int32 nIndexInParent = -1;
745 	if ( m_pDialogWindow )
746 	{
747 		Window* pParent = m_pDialogWindow->GetAccessibleParentWindow();
748 		if ( pParent )
749 		{
750 			for ( sal_uInt16 i = 0, nCount = pParent->GetAccessibleChildWindowCount(); i < nCount; ++i )
751 			{
752 				Window* pChild = pParent->GetAccessibleChildWindow( i );
753 				if ( pChild == static_cast< Window* >( m_pDialogWindow ) )
754 				{
755 					nIndexInParent = i;
756 					break;
757 				}
758 			}
759 		}
760 	}
761 
762 	return nIndexInParent;
763 }
764 
765 // -----------------------------------------------------------------------------
766 
getAccessibleRole()767 sal_Int16 AccessibleDialogWindow::getAccessibleRole(  ) throw (RuntimeException)
768 {
769 	OExternalLockGuard aGuard( this );
770 
771 	return AccessibleRole::PANEL;
772 }
773 
774 // -----------------------------------------------------------------------------
775 
getAccessibleDescription()776 ::rtl::OUString AccessibleDialogWindow::getAccessibleDescription(	) throw (RuntimeException)
777 {
778 	OExternalLockGuard aGuard( this );
779 
780 	::rtl::OUString sDescription;
781 	if ( m_pDialogWindow )
782 		sDescription = m_pDialogWindow->GetAccessibleDescription();
783 
784 	return sDescription;
785 }
786 
787 // -----------------------------------------------------------------------------
788 
getAccessibleName()789 ::rtl::OUString AccessibleDialogWindow::getAccessibleName(  ) throw (RuntimeException)
790 {
791 	OExternalLockGuard aGuard( this );
792 
793 	::rtl::OUString sName;
794 	if ( m_pDialogWindow )
795 		sName = m_pDialogWindow->GetAccessibleName();
796 
797 	return sName;
798 }
799 
800 // -----------------------------------------------------------------------------
801 
getAccessibleRelationSet()802 Reference< XAccessibleRelationSet > AccessibleDialogWindow::getAccessibleRelationSet(  ) throw (RuntimeException)
803 {
804 	OExternalLockGuard aGuard( this );
805 
806 	utl::AccessibleRelationSetHelper* pRelationSetHelper = new utl::AccessibleRelationSetHelper;
807 	Reference< XAccessibleRelationSet > xSet = pRelationSetHelper;
808 	return xSet;
809 }
810 
811 // -----------------------------------------------------------------------------
812 
getAccessibleStateSet()813 Reference< XAccessibleStateSet > AccessibleDialogWindow::getAccessibleStateSet(  ) throw (RuntimeException)
814 {
815 	OExternalLockGuard aGuard( this );
816 
817 	utl::AccessibleStateSetHelper* pStateSetHelper = new utl::AccessibleStateSetHelper;
818 	Reference< XAccessibleStateSet > xSet = pStateSetHelper;
819 
820 	if ( !rBHelper.bDisposed && !rBHelper.bInDispose )
821 	{
822 		FillAccessibleStateSet( *pStateSetHelper );
823 	}
824 	else
825 	{
826 		pStateSetHelper->AddState( AccessibleStateType::DEFUNC );
827 	}
828 
829 	return xSet;
830 }
831 
832 // -----------------------------------------------------------------------------
833 
getLocale()834 Locale AccessibleDialogWindow::getLocale(  ) throw (IllegalAccessibleComponentStateException, RuntimeException)
835 {
836 	OExternalLockGuard aGuard( this );
837 
838 	return Application::GetSettings().GetLocale();
839 }
840 
841 // -----------------------------------------------------------------------------
842 // XAccessibleComponent
843 // -----------------------------------------------------------------------------
844 
getAccessibleAtPoint(const awt::Point & rPoint)845 Reference< XAccessible > AccessibleDialogWindow::getAccessibleAtPoint( const awt::Point& rPoint ) throw (RuntimeException)
846 {
847 	OExternalLockGuard aGuard( this );
848 
849 	Reference< XAccessible > xChild;
850 	for ( sal_uInt32 i = 0; i < m_aAccessibleChildren.size(); ++i )
851 	{
852 		Reference< XAccessible > xAcc = getAccessibleChild( i );
853 		if ( xAcc.is() )
854 		{
855 			Reference< XAccessibleComponent > xComp( xAcc->getAccessibleContext(), UNO_QUERY );
856 			if ( xComp.is() )
857 			{
858 				Rectangle aRect = VCLRectangle( xComp->getBounds() );
859 				Point aPos = VCLPoint( rPoint );
860 				if ( aRect.IsInside( aPos ) )
861 				{
862 					xChild = xAcc;
863 					break;
864 				}
865 			}
866 		}
867 	}
868 
869 	return xChild;
870 }
871 
872 // -----------------------------------------------------------------------------
873 
grabFocus()874 void AccessibleDialogWindow::grabFocus(  ) throw (RuntimeException)
875 {
876 	OExternalLockGuard aGuard( this );
877 
878 	if ( m_pDialogWindow )
879 		m_pDialogWindow->GrabFocus();
880 }
881 
882 // -----------------------------------------------------------------------------
883 
getForeground()884 sal_Int32 AccessibleDialogWindow::getForeground(  ) throw (RuntimeException)
885 {
886 	OExternalLockGuard aGuard( this );
887 
888 	sal_Int32 nColor = 0;
889 	if ( m_pDialogWindow )
890 	{
891 		if ( m_pDialogWindow->IsControlForeground() )
892 			nColor = m_pDialogWindow->GetControlForeground().GetColor();
893 		else
894 		{
895 			Font aFont;
896 			if ( m_pDialogWindow->IsControlFont() )
897 				aFont = m_pDialogWindow->GetControlFont();
898 			else
899 				aFont = m_pDialogWindow->GetFont();
900 			nColor = aFont.GetColor().GetColor();
901 		}
902 	}
903 
904 	return nColor;
905 }
906 
907 // -----------------------------------------------------------------------------
908 
getBackground()909 sal_Int32 AccessibleDialogWindow::getBackground(  ) throw (RuntimeException)
910 {
911 	OExternalLockGuard aGuard( this );
912 
913 	sal_Int32 nColor = 0;
914 	if ( m_pDialogWindow )
915 	{
916 		if ( m_pDialogWindow->IsControlBackground() )
917 			nColor = m_pDialogWindow->GetControlBackground().GetColor();
918 		else
919 			nColor = m_pDialogWindow->GetBackground().GetColor().GetColor();
920 	}
921 
922 	return nColor;
923 }
924 
925 // -----------------------------------------------------------------------------
926 // XAccessibleExtendedComponent
927 // -----------------------------------------------------------------------------
928 
getFont()929 Reference< awt::XFont > AccessibleDialogWindow::getFont(  ) throw (RuntimeException)
930 {
931 	OExternalLockGuard aGuard( this );
932 
933 	Reference< awt::XFont > xFont;
934 	if ( m_pDialogWindow )
935 	{
936 		Reference< awt::XDevice > xDev( m_pDialogWindow->GetComponentInterface(), UNO_QUERY );
937 		if ( xDev.is() )
938 		{
939 			Font aFont;
940 			if ( m_pDialogWindow->IsControlFont() )
941 				aFont = m_pDialogWindow->GetControlFont();
942 			else
943 				aFont = m_pDialogWindow->GetFont();
944 			VCLXFont* pVCLXFont = new VCLXFont;
945 			pVCLXFont->Init( *xDev.get(), aFont );
946 			xFont = pVCLXFont;
947 		}
948 	}
949 
950 	return xFont;
951 }
952 
953 // -----------------------------------------------------------------------------
954 
getTitledBorderText()955 ::rtl::OUString AccessibleDialogWindow::getTitledBorderText(  ) throw (RuntimeException)
956 {
957 	OExternalLockGuard aGuard( this );
958 
959 	return ::rtl::OUString();
960 }
961 
962 // -----------------------------------------------------------------------------
963 
getToolTipText()964 ::rtl::OUString AccessibleDialogWindow::getToolTipText(  ) throw (RuntimeException)
965 {
966 	OExternalLockGuard aGuard( this );
967 
968 	::rtl::OUString sText;
969 	if ( m_pDialogWindow )
970 		sText = m_pDialogWindow->GetQuickHelpText();
971 
972 	return sText;
973 }
974 
975 // -----------------------------------------------------------------------------
976 // XAccessibleSelection
977 // -----------------------------------------------------------------------------
978 
selectAccessibleChild(sal_Int32 nChildIndex)979 void AccessibleDialogWindow::selectAccessibleChild( sal_Int32 nChildIndex ) throw (IndexOutOfBoundsException, RuntimeException)
980 {
981 	OExternalLockGuard aGuard( this );
982 
983 	if ( nChildIndex < 0 || nChildIndex >= getAccessibleChildCount() )
984 		throw IndexOutOfBoundsException();
985 
986 	if ( m_pDialogWindow )
987 	{
988 		DlgEdObj* pDlgEdObj = m_aAccessibleChildren[nChildIndex].pDlgEdObj;
989 		if ( pDlgEdObj )
990 		{
991 			SdrView* pSdrView = m_pDialogWindow->GetView();
992 			if ( pSdrView )
993 			{
994 				SdrPageView* pPgView = pSdrView->GetSdrPageView();
995 				if ( pPgView )
996 					pSdrView->MarkObj( pDlgEdObj, pPgView );
997 			}
998 		}
999 	}
1000 }
1001 
1002 // -----------------------------------------------------------------------------
1003 
isAccessibleChildSelected(sal_Int32 nChildIndex)1004 sal_Bool AccessibleDialogWindow::isAccessibleChildSelected( sal_Int32 nChildIndex ) throw (IndexOutOfBoundsException, RuntimeException)
1005 {
1006 	OExternalLockGuard aGuard( this );
1007 
1008 	if ( nChildIndex < 0 || nChildIndex >= getAccessibleChildCount() )
1009 		throw IndexOutOfBoundsException();
1010 
1011 	sal_Bool bSelected = sal_False;
1012 	if ( m_pDialogWindow )
1013 	{
1014 		DlgEdObj* pDlgEdObj = m_aAccessibleChildren[nChildIndex].pDlgEdObj;
1015 		if ( pDlgEdObj )
1016 		{
1017 			SdrView* pSdrView = m_pDialogWindow->GetView();
1018 			if ( pSdrView )
1019 				bSelected = pSdrView->IsObjMarked( pDlgEdObj );
1020 		}
1021 	}
1022 
1023 	return bSelected;
1024 }
1025 
1026 // -----------------------------------------------------------------------------
1027 
clearAccessibleSelection()1028 void AccessibleDialogWindow::clearAccessibleSelection(  ) throw (RuntimeException)
1029 {
1030 	OExternalLockGuard aGuard( this );
1031 
1032 	if ( m_pDialogWindow )
1033 	{
1034 		SdrView* pSdrView = m_pDialogWindow->GetView();
1035 		if ( pSdrView )
1036 			pSdrView->UnmarkAll();
1037 	}
1038 }
1039 
1040 // -----------------------------------------------------------------------------
1041 
selectAllAccessibleChildren()1042 void AccessibleDialogWindow::selectAllAccessibleChildren(  ) throw (RuntimeException)
1043 {
1044 	OExternalLockGuard aGuard( this );
1045 
1046 	if ( m_pDialogWindow )
1047 	{
1048 		SdrView* pSdrView = m_pDialogWindow->GetView();
1049 		if ( pSdrView )
1050 			pSdrView->MarkAll();
1051 	}
1052 }
1053 
1054 // -----------------------------------------------------------------------------
1055 
getSelectedAccessibleChildCount()1056 sal_Int32 AccessibleDialogWindow::getSelectedAccessibleChildCount(  ) throw (RuntimeException)
1057 {
1058 	OExternalLockGuard aGuard( this );
1059 
1060 	sal_Int32 nRet = 0;
1061 
1062 	for ( sal_Int32 i = 0, nCount = getAccessibleChildCount(); i < nCount; ++i )
1063 	{
1064 		if ( isAccessibleChildSelected( i ) )
1065 			++nRet;
1066 	}
1067 
1068 	return nRet;
1069 }
1070 
1071 // -----------------------------------------------------------------------------
1072 
getSelectedAccessibleChild(sal_Int32 nSelectedChildIndex)1073 Reference< XAccessible > AccessibleDialogWindow::getSelectedAccessibleChild( sal_Int32 nSelectedChildIndex ) throw (IndexOutOfBoundsException, RuntimeException)
1074 {
1075 	OExternalLockGuard aGuard( this );
1076 
1077 	if ( nSelectedChildIndex < 0 || nSelectedChildIndex >= getSelectedAccessibleChildCount() )
1078 		throw IndexOutOfBoundsException();
1079 
1080 	Reference< XAccessible > xChild;
1081 
1082 	for ( sal_Int32 i = 0, j = 0, nCount = getAccessibleChildCount(); i < nCount; ++i )
1083 	{
1084 		if ( isAccessibleChildSelected( i ) && ( j++ == nSelectedChildIndex ) )
1085 		{
1086 			xChild = getAccessibleChild( i );
1087 			break;
1088 		}
1089 	}
1090 
1091 	return xChild;
1092 }
1093 
1094 // -----------------------------------------------------------------------------
1095 
deselectAccessibleChild(sal_Int32 nChildIndex)1096 void AccessibleDialogWindow::deselectAccessibleChild( sal_Int32 nChildIndex ) throw (IndexOutOfBoundsException, RuntimeException)
1097 {
1098 	OExternalLockGuard aGuard( this );
1099 
1100 	if ( nChildIndex < 0 || nChildIndex >= getAccessibleChildCount() )
1101 		throw IndexOutOfBoundsException();
1102 
1103 	if ( m_pDialogWindow )
1104 	{
1105 		DlgEdObj* pDlgEdObj = m_aAccessibleChildren[nChildIndex].pDlgEdObj;
1106 		if ( pDlgEdObj )
1107 		{
1108 			SdrView* pSdrView = m_pDialogWindow->GetView();
1109 			if ( pSdrView )
1110 			{
1111 				SdrPageView* pPgView = pSdrView->GetSdrPageView();
1112 				if ( pPgView )
1113 					pSdrView->MarkObj( pDlgEdObj, pPgView, sal_True );
1114 			}
1115 		}
1116 	}
1117 }
1118 
1119 // -----------------------------------------------------------------------------
1120