xref: /AOO41X/main/basctl/source/accessibility/accessibledialogwindow.cxx (revision 31598a226906602f93ad246cbee896e3caca5f8f)
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