1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  *   Licensed to the Apache Software Foundation (ASF) under one or more
12  *   contributor license agreements. See the NOTICE file distributed
13  *   with this work for additional information regarding copyright
14  *   ownership. The ASF licenses this file to you under the Apache
15  *   License, Version 2.0 (the "License"); you may not use this file
16  *   except in compliance with the License. You may obtain a copy of
17  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 
21 #include <accessibledialogwindow.hxx>
22 #include <accessibledialogcontrolshape.hxx>
23 #include <baside3.hxx>
24 #include <dlged.hxx>
25 #include <dlgedmod.hxx>
26 #include <dlgedpage.hxx>
27 #include <dlgedview.hxx>
28 #include <dlgedobj.hxx>
29 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
30 #include <com/sun/star/accessibility/AccessibleRole.hpp>
31 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
32 #include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
33 #include <cppuhelper/supportsservice.hxx>
34 #include <tools/debug.hxx>
35 #include <unotools/accessiblestatesethelper.hxx>
36 #include <unotools/accessiblerelationsethelper.hxx>
37 #include <toolkit/awt/vclxfont.hxx>
38 #include <toolkit/helper/convert.hxx>
39 #include <vcl/svapp.hxx>
40 #include <vcl/settings.hxx>
41 #include <i18nlangtag/languagetag.hxx>
42 
43 namespace basctl
44 {
45 
46 using namespace ::com::sun::star;
47 using namespace ::com::sun::star::uno;
48 using namespace ::com::sun::star::lang;
49 using namespace ::com::sun::star::accessibility;
50 using namespace ::comphelper;
51 
ChildDescriptor(DlgEdObj * _pDlgEdObj)52 AccessibleDialogWindow::ChildDescriptor::ChildDescriptor( DlgEdObj* _pDlgEdObj )
53     :pDlgEdObj( _pDlgEdObj )
54 {
55 }
56 
operator ==(const ChildDescriptor & rDesc)57 bool AccessibleDialogWindow::ChildDescriptor::operator==( const ChildDescriptor& rDesc )
58 {
59     bool bRet = false;
60     if ( pDlgEdObj == rDesc.pDlgEdObj )
61         bRet = true;
62 
63     return bRet;
64 }
65 
66 
operator <(const ChildDescriptor & rDesc) const67 bool AccessibleDialogWindow::ChildDescriptor::operator<( const ChildDescriptor& rDesc ) const
68 {
69     bool bRet = false;
70     if ( pDlgEdObj && rDesc.pDlgEdObj && pDlgEdObj->GetOrdNum() < rDesc.pDlgEdObj->GetOrdNum() )
71         bRet = true;
72 
73     return bRet;
74 }
75 
76 
77 // class AccessibleDialogWindow
78 
79 
AccessibleDialogWindow(basctl::DialogWindow * pDialogWindow)80 AccessibleDialogWindow::AccessibleDialogWindow (basctl::DialogWindow* pDialogWindow)
81     : m_pDialogWindow(pDialogWindow)
82     , m_pDlgEdModel(nullptr)
83 {
84     if ( m_pDialogWindow )
85     {
86         SdrPage& rPage = m_pDialogWindow->GetPage();
87         const size_t nCount = rPage.GetObjCount();
88 
89         for ( size_t i = 0; i < nCount; ++i )
90         {
91             if (DlgEdObj* pDlgEdObj = dynamic_cast<DlgEdObj*>(rPage.GetObj(i)))
92             {
93                 ChildDescriptor aDesc( pDlgEdObj );
94                 if ( IsChildVisible( aDesc ) )
95                     m_aAccessibleChildren.push_back( aDesc );
96             }
97         }
98 
99         m_pDialogWindow->AddEventListener( LINK( this, AccessibleDialogWindow, WindowEventListener ) );
100 
101         StartListening(m_pDialogWindow->GetEditor());
102 
103         m_pDlgEdModel = &m_pDialogWindow->GetModel();
104         StartListening(*m_pDlgEdModel);
105     }
106 }
107 
108 
~AccessibleDialogWindow()109 AccessibleDialogWindow::~AccessibleDialogWindow()
110 {
111     if ( m_pDialogWindow )
112         m_pDialogWindow->RemoveEventListener( LINK( this, AccessibleDialogWindow, WindowEventListener ) );
113 
114     if ( m_pDlgEdModel )
115         EndListening( *m_pDlgEdModel );
116 }
117 
118 
UpdateFocused()119 void AccessibleDialogWindow::UpdateFocused()
120 {
121     for (const ChildDescriptor & i : m_aAccessibleChildren)
122     {
123         Reference< XAccessible > xChild( i.rxAccessible );
124         if ( xChild.is() )
125         {
126             AccessibleDialogControlShape* pShape = static_cast< AccessibleDialogControlShape* >( xChild.get() );
127             if ( pShape )
128                 pShape->SetFocused( pShape->IsFocused() );
129         }
130     }
131 }
132 
133 
UpdateSelected()134 void AccessibleDialogWindow::UpdateSelected()
135 {
136     NotifyAccessibleEvent( AccessibleEventId::SELECTION_CHANGED, Any(), Any() );
137 
138     for (const ChildDescriptor & i : m_aAccessibleChildren)
139     {
140         Reference< XAccessible > xChild( i.rxAccessible );
141         if ( xChild.is() )
142         {
143             AccessibleDialogControlShape* pShape = static_cast< AccessibleDialogControlShape* >( xChild.get() );
144             if ( pShape )
145                 pShape->SetSelected( pShape->IsSelected() );
146         }
147     }
148 }
149 
150 
UpdateBounds()151 void AccessibleDialogWindow::UpdateBounds()
152 {
153     for (const ChildDescriptor & i : m_aAccessibleChildren)
154     {
155         Reference< XAccessible > xChild( i.rxAccessible );
156         if ( xChild.is() )
157         {
158             AccessibleDialogControlShape* pShape = static_cast< AccessibleDialogControlShape* >( xChild.get() );
159             if ( pShape )
160                 pShape->SetBounds( pShape->GetBounds() );
161         }
162     }
163 }
164 
165 
IsChildVisible(const ChildDescriptor & rDesc)166 bool AccessibleDialogWindow::IsChildVisible( const ChildDescriptor& rDesc )
167 {
168     bool bVisible = false;
169 
170     if ( m_pDialogWindow )
171     {
172         // first check, if the shape is in a visible layer
173         SdrLayerAdmin& rLayerAdmin = m_pDialogWindow->GetModel().GetLayerAdmin();
174         DlgEdObj* pDlgEdObj = rDesc.pDlgEdObj;
175         if ( pDlgEdObj )
176         {
177             SdrLayerID nLayerId = pDlgEdObj->GetLayer();
178             const SdrLayer* pSdrLayer = rLayerAdmin.GetLayerPerID( nLayerId );
179             if ( pSdrLayer )
180             {
181                 const OUString& aLayerName = pSdrLayer->GetName();
182                 SdrView& rView = m_pDialogWindow->GetView();
183                 if (rView.IsLayerVisible(aLayerName))
184                 {
185                     // get the bounding box of the shape in logic units
186                     tools::Rectangle aRect = pDlgEdObj->GetSnapRect();
187 
188                     // transform coordinates relative to the parent
189                     MapMode aMap = m_pDialogWindow->GetMapMode();
190                     Point aOrg = aMap.GetOrigin();
191                     aRect.Move( aOrg.X(), aOrg.Y() );
192 
193                     // convert logic units to pixel
194                     aRect = m_pDialogWindow->LogicToPixel( aRect, MapMode(MapUnit::Map100thMM) );
195 
196                     // check, if the shape's bounding box intersects with the bounding box of its parent
197                     tools::Rectangle aParentRect( Point( 0, 0 ), m_pDialogWindow->GetSizePixel() );
198                     if ( aParentRect.IsOver( aRect ) )
199                         bVisible = true;
200                 }
201             }
202         }
203     }
204 
205     return bVisible;
206 }
207 
208 
InsertChild(const ChildDescriptor & rDesc)209 void AccessibleDialogWindow::InsertChild( const ChildDescriptor& rDesc )
210 {
211     // check, if object is already in child list
212     AccessibleChildren::iterator aIter = std::find( m_aAccessibleChildren.begin(), m_aAccessibleChildren.end(), rDesc );
213 
214     // if not found, insert in child list
215     if ( aIter == m_aAccessibleChildren.end() )
216     {
217         // insert entry in child list
218         m_aAccessibleChildren.push_back( rDesc );
219 
220         // get the accessible of the inserted child
221         Reference< XAccessible > xChild( getAccessibleChild( m_aAccessibleChildren.size() - 1 ) );
222 
223         // sort child list
224         SortChildren();
225 
226         // send accessible child event
227         if ( xChild.is() )
228         {
229             Any aOldValue, aNewValue;
230             aNewValue <<= xChild;
231             NotifyAccessibleEvent( AccessibleEventId::CHILD, aOldValue, aNewValue );
232         }
233     }
234 }
235 
236 
RemoveChild(const ChildDescriptor & rDesc)237 void AccessibleDialogWindow::RemoveChild( const ChildDescriptor& rDesc )
238 {
239     // find object in child list
240     AccessibleChildren::iterator aIter = std::find( m_aAccessibleChildren.begin(), m_aAccessibleChildren.end(), rDesc );
241 
242     // if found, remove from child list
243     if ( aIter != m_aAccessibleChildren.end() )
244     {
245         // get the accessible of the removed child
246         Reference< XAccessible > xChild( aIter->rxAccessible );
247 
248         // remove entry from child list
249         m_aAccessibleChildren.erase( aIter );
250 
251         // send accessible child event
252         if ( xChild.is() )
253         {
254             Any aOldValue, aNewValue;
255             aOldValue <<= xChild;
256             NotifyAccessibleEvent( AccessibleEventId::CHILD, aOldValue, aNewValue );
257 
258             Reference< XComponent > xComponent( xChild, UNO_QUERY );
259             if ( xComponent.is() )
260                 xComponent->dispose();
261         }
262     }
263 }
264 
265 
UpdateChild(const ChildDescriptor & rDesc)266 void AccessibleDialogWindow::UpdateChild( const ChildDescriptor& rDesc )
267 {
268     if ( IsChildVisible( rDesc ) )
269     {
270         // if the object is not in the child list, insert child
271         InsertChild( rDesc );
272     }
273     else
274     {
275         // if the object is in the child list, remove child
276         RemoveChild( rDesc );
277     }
278 }
279 
280 
UpdateChildren()281 void AccessibleDialogWindow::UpdateChildren()
282 {
283     if ( m_pDialogWindow )
284     {
285         SdrPage& rPage = m_pDialogWindow->GetPage();
286         for ( size_t i = 0, nCount = rPage.GetObjCount(); i < nCount; ++i )
287             if (DlgEdObj* pDlgEdObj = dynamic_cast<DlgEdObj*>(rPage.GetObj(i)))
288                 UpdateChild( ChildDescriptor( pDlgEdObj ) );
289     }
290 }
291 
292 
SortChildren()293 void AccessibleDialogWindow::SortChildren()
294 {
295     // sort child list
296     std::sort( m_aAccessibleChildren.begin(), m_aAccessibleChildren.end() );
297 }
298 
299 
IMPL_LINK(AccessibleDialogWindow,WindowEventListener,VclWindowEvent &,rEvent,void)300 IMPL_LINK( AccessibleDialogWindow, WindowEventListener, VclWindowEvent&, rEvent, void )
301 {
302     DBG_ASSERT(rEvent.GetWindow(), "AccessibleDialogWindow::WindowEventListener: no window!");
303     if (!rEvent.GetWindow()->IsAccessibilityEventsSuppressed() || rEvent.GetId() == VclEventId::ObjectDying)
304         ProcessWindowEvent(rEvent);
305 }
306 
307 
ProcessWindowEvent(const VclWindowEvent & rVclWindowEvent)308 void AccessibleDialogWindow::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent )
309 {
310     Any aOldValue, aNewValue;
311 
312     switch ( rVclWindowEvent.GetId() )
313     {
314         case VclEventId::WindowEnabled:
315         {
316             aNewValue <<= AccessibleStateType::ENABLED;
317             NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );
318         }
319         break;
320         case VclEventId::WindowDisabled:
321         {
322             aOldValue <<= AccessibleStateType::ENABLED;
323             NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );
324         }
325         break;
326         case VclEventId::WindowActivate:
327         {
328             aNewValue <<= AccessibleStateType::ACTIVE;
329             NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );
330         }
331         break;
332         case VclEventId::WindowDeactivate:
333         {
334             aOldValue <<= AccessibleStateType::ACTIVE;
335             NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );
336         }
337         break;
338         case VclEventId::WindowGetFocus:
339         {
340             aNewValue <<= AccessibleStateType::FOCUSED;
341             NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );
342         }
343         break;
344         case VclEventId::WindowLoseFocus:
345         {
346             aOldValue <<= AccessibleStateType::FOCUSED;
347             NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );
348         }
349         break;
350         case VclEventId::WindowShow:
351         {
352             aNewValue <<= AccessibleStateType::SHOWING;
353             NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );
354         }
355         break;
356         case VclEventId::WindowHide:
357         {
358             aOldValue <<= AccessibleStateType::SHOWING;
359             NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );
360         }
361         break;
362         case VclEventId::WindowResize:
363         {
364             NotifyAccessibleEvent( AccessibleEventId::BOUNDRECT_CHANGED, aOldValue, aNewValue );
365             UpdateChildren();
366             UpdateBounds();
367         }
368         break;
369         case VclEventId::ObjectDying:
370         {
371             if ( m_pDialogWindow )
372             {
373                 m_pDialogWindow->RemoveEventListener( LINK( this, AccessibleDialogWindow, WindowEventListener ) );
374                 m_pDialogWindow = nullptr;
375 
376                 if ( m_pDlgEdModel )
377                     EndListening( *m_pDlgEdModel );
378                 m_pDlgEdModel = nullptr;
379 
380                 // dispose all children
381                 for (const ChildDescriptor & i : m_aAccessibleChildren)
382                 {
383                     Reference< XComponent > xComponent( i.rxAccessible, UNO_QUERY );
384                     if ( xComponent.is() )
385                         xComponent->dispose();
386                 }
387                 m_aAccessibleChildren.clear();
388             }
389         }
390         break;
391         default:
392         {
393         }
394         break;
395     }
396 }
397 
398 
FillAccessibleStateSet(utl::AccessibleStateSetHelper & rStateSet)399 void AccessibleDialogWindow::FillAccessibleStateSet( utl::AccessibleStateSetHelper& rStateSet )
400 {
401     if ( m_pDialogWindow )
402     {
403         if ( m_pDialogWindow->IsEnabled() )
404             rStateSet.AddState( AccessibleStateType::ENABLED );
405 
406         rStateSet.AddState( AccessibleStateType::FOCUSABLE );
407 
408         if ( m_pDialogWindow->HasFocus() )
409             rStateSet.AddState( AccessibleStateType::FOCUSED );
410 
411         rStateSet.AddState( AccessibleStateType::VISIBLE );
412 
413         if ( m_pDialogWindow->IsVisible() )
414             rStateSet.AddState( AccessibleStateType::SHOWING );
415 
416         rStateSet.AddState( AccessibleStateType::OPAQUE );
417 
418         rStateSet.AddState( AccessibleStateType::RESIZABLE );
419     }
420 }
421 
422 
423 // OCommonAccessibleComponent
424 
425 
implGetBounds()426 awt::Rectangle AccessibleDialogWindow::implGetBounds()
427 {
428     awt::Rectangle aBounds;
429     if ( m_pDialogWindow )
430         aBounds = AWTRectangle( tools::Rectangle( m_pDialogWindow->GetPosPixel(), m_pDialogWindow->GetSizePixel() ) );
431 
432     return aBounds;
433 }
434 
435 
436 // SfxListener
437 
438 
Notify(SfxBroadcaster &,const SfxHint & rHint)439 void AccessibleDialogWindow::Notify( SfxBroadcaster&, const SfxHint& rHint )
440 {
441     if (SdrHint const* pSdrHint = dynamic_cast<SdrHint const*>(&rHint))
442     {
443         switch ( pSdrHint->GetKind() )
444         {
445             case SdrHintKind::ObjectInserted:
446             {
447                 if (DlgEdObj const* pDlgEdObj = dynamic_cast<DlgEdObj const*>(pSdrHint->GetObject()))
448                 {
449                     ChildDescriptor aDesc(const_cast<DlgEdObj*>(pDlgEdObj));
450                     if ( IsChildVisible( aDesc ) )
451                         InsertChild( aDesc );
452                 }
453             }
454             break;
455             case SdrHintKind::ObjectRemoved:
456             {
457                 if (DlgEdObj const* pDlgEdObj = dynamic_cast<DlgEdObj const*>(pSdrHint->GetObject()))
458                     RemoveChild( ChildDescriptor(const_cast<DlgEdObj*>(pDlgEdObj)) );
459             }
460             break;
461             default: ;
462         }
463     }
464     else if (DlgEdHint const* pDlgEdHint = dynamic_cast<DlgEdHint const*>(&rHint))
465     {
466         switch (pDlgEdHint->GetKind())
467         {
468             case DlgEdHint::WINDOWSCROLLED:
469             {
470                 UpdateChildren();
471                 UpdateBounds();
472             }
473             break;
474             case DlgEdHint::LAYERCHANGED:
475             {
476                 if (DlgEdObj* pDlgEdObj = pDlgEdHint->GetObject())
477                     UpdateChild( ChildDescriptor( pDlgEdObj ) );
478             }
479             break;
480             case DlgEdHint::OBJORDERCHANGED:
481             {
482                 SortChildren();
483             }
484             break;
485             case DlgEdHint::SELECTIONCHANGED:
486             {
487                 UpdateFocused();
488                 UpdateSelected();
489             }
490             break;
491             default: ;
492         }
493     }
494 }
495 
496 
497 // XInterface
498 
499 
IMPLEMENT_FORWARD_XINTERFACE2(AccessibleDialogWindow,OAccessibleExtendedComponentHelper,AccessibleDialogWindow_BASE)500 IMPLEMENT_FORWARD_XINTERFACE2( AccessibleDialogWindow, OAccessibleExtendedComponentHelper, AccessibleDialogWindow_BASE )
501 
502 
503 // XTypeProvider
504 
505 
506 IMPLEMENT_FORWARD_XTYPEPROVIDER2( AccessibleDialogWindow, OAccessibleExtendedComponentHelper, AccessibleDialogWindow_BASE )
507 
508 
509 // XComponent
510 
511 
512 void AccessibleDialogWindow::disposing()
513 {
514     OAccessibleExtendedComponentHelper::disposing();
515 
516     if ( m_pDialogWindow )
517     {
518         m_pDialogWindow->RemoveEventListener( LINK( this, AccessibleDialogWindow, WindowEventListener ) );
519         m_pDialogWindow = nullptr;
520 
521         if ( m_pDlgEdModel )
522             EndListening( *m_pDlgEdModel );
523         m_pDlgEdModel = nullptr;
524 
525         // dispose all children
526         for (const ChildDescriptor & i : m_aAccessibleChildren)
527         {
528             Reference< XComponent > xComponent( i.rxAccessible, UNO_QUERY );
529             if ( xComponent.is() )
530                 xComponent->dispose();
531         }
532         m_aAccessibleChildren.clear();
533     }
534 }
535 
536 // XServiceInfo
getImplementationName()537 OUString AccessibleDialogWindow::getImplementationName()
538 {
539     return "com.sun.star.comp.basctl.AccessibleWindow";
540 }
541 
supportsService(const OUString & rServiceName)542 sal_Bool AccessibleDialogWindow::supportsService( const OUString& rServiceName )
543 {
544     return cppu::supportsService(this, rServiceName);
545 }
546 
getSupportedServiceNames()547 Sequence< OUString > AccessibleDialogWindow::getSupportedServiceNames()
548 {
549     return { "com.sun.star.awt.AccessibleWindow" };
550 }
551 
552 // XAccessible
getAccessibleContext()553 Reference< XAccessibleContext > AccessibleDialogWindow::getAccessibleContext(  )
554 {
555     return this;
556 }
557 
558 // XAccessibleContext
getAccessibleChildCount()559 sal_Int32 AccessibleDialogWindow::getAccessibleChildCount()
560 {
561     OExternalLockGuard aGuard( this );
562 
563     return m_aAccessibleChildren.size();
564 }
565 
566 
getAccessibleChild(sal_Int32 i)567 Reference< XAccessible > AccessibleDialogWindow::getAccessibleChild( sal_Int32 i )
568 {
569     OExternalLockGuard aGuard( this );
570 
571     if ( i < 0 || i >= getAccessibleChildCount() )
572         throw IndexOutOfBoundsException();
573 
574     Reference< XAccessible > xChild = m_aAccessibleChildren[i].rxAccessible;
575     if ( !xChild.is() )
576     {
577         if ( m_pDialogWindow )
578         {
579             DlgEdObj* pDlgEdObj = m_aAccessibleChildren[i].pDlgEdObj;
580             if ( pDlgEdObj )
581             {
582                 xChild = new AccessibleDialogControlShape( m_pDialogWindow, pDlgEdObj );
583 
584                 // insert into child list
585                 m_aAccessibleChildren[i].rxAccessible = xChild;
586             }
587         }
588     }
589 
590     return xChild;
591 }
592 
593 
getAccessibleParent()594 Reference< XAccessible > AccessibleDialogWindow::getAccessibleParent(  )
595 {
596     OExternalLockGuard aGuard( this );
597 
598     Reference< XAccessible > xParent;
599     if ( m_pDialogWindow )
600     {
601         vcl::Window* pParent = m_pDialogWindow->GetAccessibleParentWindow();
602         if ( pParent )
603             xParent = pParent->GetAccessible();
604     }
605 
606     return xParent;
607 }
608 
609 
getAccessibleIndexInParent()610 sal_Int32 AccessibleDialogWindow::getAccessibleIndexInParent(  )
611 {
612     OExternalLockGuard aGuard( this );
613 
614     sal_Int32 nIndexInParent = -1;
615     if ( m_pDialogWindow )
616     {
617         vcl::Window* pParent = m_pDialogWindow->GetAccessibleParentWindow();
618         if ( pParent )
619         {
620             for ( sal_uInt16 i = 0, nCount = pParent->GetAccessibleChildWindowCount(); i < nCount; ++i )
621             {
622                 vcl::Window* pChild = pParent->GetAccessibleChildWindow( i );
623                 if ( pChild == static_cast< vcl::Window* >( m_pDialogWindow ) )
624                 {
625                     nIndexInParent = i;
626                     break;
627                 }
628             }
629         }
630     }
631 
632     return nIndexInParent;
633 }
634 
635 
getAccessibleRole()636 sal_Int16 AccessibleDialogWindow::getAccessibleRole(  )
637 {
638     OExternalLockGuard aGuard( this );
639 
640     return AccessibleRole::PANEL;
641 }
642 
643 
getAccessibleDescription()644 OUString AccessibleDialogWindow::getAccessibleDescription(  )
645 {
646     OExternalLockGuard aGuard( this );
647 
648     OUString sDescription;
649     if ( m_pDialogWindow )
650         sDescription = m_pDialogWindow->GetAccessibleDescription();
651 
652     return sDescription;
653 }
654 
655 
getAccessibleName()656 OUString AccessibleDialogWindow::getAccessibleName(  )
657 {
658     OExternalLockGuard aGuard( this );
659 
660     OUString sName;
661     if ( m_pDialogWindow )
662         sName = m_pDialogWindow->GetAccessibleName();
663 
664     return sName;
665 }
666 
667 
getAccessibleRelationSet()668 Reference< XAccessibleRelationSet > AccessibleDialogWindow::getAccessibleRelationSet(  )
669 {
670     OExternalLockGuard aGuard( this );
671 
672     utl::AccessibleRelationSetHelper* pRelationSetHelper = new utl::AccessibleRelationSetHelper;
673     Reference< XAccessibleRelationSet > xSet = pRelationSetHelper;
674     return xSet;
675 }
676 
677 
getAccessibleStateSet()678 Reference< XAccessibleStateSet > AccessibleDialogWindow::getAccessibleStateSet(  )
679 {
680     OExternalLockGuard aGuard( this );
681 
682     utl::AccessibleStateSetHelper* pStateSetHelper = new utl::AccessibleStateSetHelper;
683     Reference< XAccessibleStateSet > xSet = pStateSetHelper;
684 
685     if ( !rBHelper.bDisposed && !rBHelper.bInDispose )
686     {
687         FillAccessibleStateSet( *pStateSetHelper );
688     }
689     else
690     {
691         pStateSetHelper->AddState( AccessibleStateType::DEFUNC );
692     }
693 
694     return xSet;
695 }
696 
697 
getLocale()698 Locale AccessibleDialogWindow::getLocale(  )
699 {
700     OExternalLockGuard aGuard( this );
701 
702     return Application::GetSettings().GetLanguageTag().getLocale();
703 }
704 
705 
706 // XAccessibleComponent
707 
708 
getAccessibleAtPoint(const awt::Point & rPoint)709 Reference< XAccessible > AccessibleDialogWindow::getAccessibleAtPoint( const awt::Point& rPoint )
710 {
711     OExternalLockGuard aGuard( this );
712 
713     Reference< XAccessible > xChild;
714     for ( size_t i = 0; i < m_aAccessibleChildren.size(); ++i )
715     {
716         Reference< XAccessible > xAcc = getAccessibleChild( i );
717         if ( xAcc.is() )
718         {
719             Reference< XAccessibleComponent > xComp( xAcc->getAccessibleContext(), UNO_QUERY );
720             if ( xComp.is() )
721             {
722                 tools::Rectangle aRect = VCLRectangle( xComp->getBounds() );
723                 Point aPos = VCLPoint( rPoint );
724                 if ( aRect.IsInside( aPos ) )
725                 {
726                     xChild = xAcc;
727                     break;
728                 }
729             }
730         }
731     }
732 
733     return xChild;
734 }
735 
736 
grabFocus()737 void AccessibleDialogWindow::grabFocus(  )
738 {
739     OExternalLockGuard aGuard( this );
740 
741     if ( m_pDialogWindow )
742         m_pDialogWindow->GrabFocus();
743 }
744 
745 
getForeground()746 sal_Int32 AccessibleDialogWindow::getForeground(  )
747 {
748     OExternalLockGuard aGuard( this );
749 
750     Color nColor;
751     if ( m_pDialogWindow )
752     {
753         if ( m_pDialogWindow->IsControlForeground() )
754             nColor = m_pDialogWindow->GetControlForeground();
755         else
756         {
757             vcl::Font aFont;
758             if ( m_pDialogWindow->IsControlFont() )
759                 aFont = m_pDialogWindow->GetControlFont();
760             else
761                 aFont = m_pDialogWindow->GetFont();
762             nColor = aFont.GetColor();
763         }
764     }
765 
766     return sal_Int32(nColor);
767 }
768 
769 
getBackground()770 sal_Int32 AccessibleDialogWindow::getBackground(  )
771 {
772     OExternalLockGuard aGuard( this );
773 
774     Color nColor;
775     if ( m_pDialogWindow )
776     {
777         if ( m_pDialogWindow->IsControlBackground() )
778             nColor = m_pDialogWindow->GetControlBackground();
779         else
780             nColor = m_pDialogWindow->GetBackground().GetColor();
781     }
782 
783     return sal_Int32(nColor);
784 }
785 
786 
787 // XAccessibleExtendedComponent
788 
789 
getFont()790 Reference< awt::XFont > AccessibleDialogWindow::getFont(  )
791 {
792     OExternalLockGuard aGuard( this );
793 
794     Reference< awt::XFont > xFont;
795     if ( m_pDialogWindow )
796     {
797         Reference< awt::XDevice > xDev( m_pDialogWindow->GetComponentInterface(), UNO_QUERY );
798         if ( xDev.is() )
799         {
800             vcl::Font aFont;
801             if ( m_pDialogWindow->IsControlFont() )
802                 aFont = m_pDialogWindow->GetControlFont();
803             else
804                 aFont = m_pDialogWindow->GetFont();
805             VCLXFont* pVCLXFont = new VCLXFont;
806             pVCLXFont->Init( *xDev, aFont );
807             xFont = pVCLXFont;
808         }
809     }
810 
811     return xFont;
812 }
813 
814 
getTitledBorderText()815 OUString AccessibleDialogWindow::getTitledBorderText(  )
816 {
817     OExternalLockGuard aGuard( this );
818 
819     return OUString();
820 }
821 
822 
getToolTipText()823 OUString AccessibleDialogWindow::getToolTipText(  )
824 {
825     OExternalLockGuard aGuard( this );
826 
827     OUString sText;
828     if ( m_pDialogWindow )
829         sText = m_pDialogWindow->GetQuickHelpText();
830 
831     return sText;
832 }
833 
834 
835 // XAccessibleSelection
836 
837 
selectAccessibleChild(sal_Int32 nChildIndex)838 void AccessibleDialogWindow::selectAccessibleChild( sal_Int32 nChildIndex )
839 {
840     OExternalLockGuard aGuard( this );
841 
842     if ( nChildIndex < 0 || nChildIndex >= getAccessibleChildCount() )
843         throw IndexOutOfBoundsException();
844 
845     if ( m_pDialogWindow )
846     {
847         if (DlgEdObj* pDlgEdObj = m_aAccessibleChildren[nChildIndex].pDlgEdObj)
848         {
849             SdrView& rView = m_pDialogWindow->GetView();
850             if (SdrPageView* pPgView = rView.GetSdrPageView())
851                 rView.MarkObj(pDlgEdObj, pPgView);
852         }
853     }
854 }
855 
856 
isAccessibleChildSelected(sal_Int32 nChildIndex)857 sal_Bool AccessibleDialogWindow::isAccessibleChildSelected( sal_Int32 nChildIndex )
858 {
859     OExternalLockGuard aGuard( this );
860 
861     if ( nChildIndex < 0 || nChildIndex >= getAccessibleChildCount() )
862         throw IndexOutOfBoundsException();
863 
864     if (m_pDialogWindow)
865         if (DlgEdObj* pDlgEdObj = m_aAccessibleChildren[nChildIndex].pDlgEdObj)
866             return m_pDialogWindow->GetView().IsObjMarked(pDlgEdObj);
867     return false;
868 }
869 
870 
clearAccessibleSelection()871 void AccessibleDialogWindow::clearAccessibleSelection()
872 {
873     OExternalLockGuard aGuard( this );
874 
875     if ( m_pDialogWindow )
876         m_pDialogWindow->GetView().UnmarkAll();
877 }
878 
879 
selectAllAccessibleChildren()880 void AccessibleDialogWindow::selectAllAccessibleChildren(  )
881 {
882     OExternalLockGuard aGuard( this );
883 
884     if ( m_pDialogWindow )
885         m_pDialogWindow->GetView().MarkAll();
886 }
887 
888 
getSelectedAccessibleChildCount()889 sal_Int32 AccessibleDialogWindow::getSelectedAccessibleChildCount(  )
890 {
891     OExternalLockGuard aGuard( this );
892 
893     sal_Int32 nRet = 0;
894 
895     for ( sal_Int32 i = 0, nCount = getAccessibleChildCount(); i < nCount; ++i )
896     {
897         if ( isAccessibleChildSelected( i ) )
898             ++nRet;
899     }
900 
901     return nRet;
902 }
903 
904 
getSelectedAccessibleChild(sal_Int32 nSelectedChildIndex)905 Reference< XAccessible > AccessibleDialogWindow::getSelectedAccessibleChild( sal_Int32 nSelectedChildIndex )
906 {
907     OExternalLockGuard aGuard( this );
908 
909     if ( nSelectedChildIndex < 0 || nSelectedChildIndex >= getSelectedAccessibleChildCount() )
910         throw IndexOutOfBoundsException();
911 
912     Reference< XAccessible > xChild;
913 
914     for ( sal_Int32 i = 0, j = 0, nCount = getAccessibleChildCount(); i < nCount; ++i )
915     {
916         if ( isAccessibleChildSelected( i ) && ( j++ == nSelectedChildIndex ) )
917         {
918             xChild = getAccessibleChild( i );
919             break;
920         }
921     }
922 
923     return xChild;
924 }
925 
926 
deselectAccessibleChild(sal_Int32 nChildIndex)927 void AccessibleDialogWindow::deselectAccessibleChild( sal_Int32 nChildIndex )
928 {
929     OExternalLockGuard aGuard( this );
930 
931     if ( nChildIndex < 0 || nChildIndex >= getAccessibleChildCount() )
932         throw IndexOutOfBoundsException();
933 
934     if ( m_pDialogWindow )
935     {
936         if (DlgEdObj* pDlgEdObj = m_aAccessibleChildren[nChildIndex].pDlgEdObj)
937         {
938             SdrView& rView = m_pDialogWindow->GetView();
939             SdrPageView* pPgView = rView.GetSdrPageView();
940             if (pPgView)
941                 rView.MarkObj( pDlgEdObj, pPgView, true );
942         }
943     }
944 }
945 
946 
947 } // namespace basctl
948 
949 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
950