xref: /trunk/main/basctl/source/accessibility/accessibledialogwindow.cxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
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