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