xref: /trunk/main/accessibility/source/extended/accessiblelistbox.cxx (revision 04c88002691bc4b2a5ac56d20828b7f32c699f8c)
10841af79SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
30841af79SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
40841af79SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
50841af79SAndrew Rist  * distributed with this work for additional information
60841af79SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
70841af79SAndrew Rist  * to you under the Apache License, Version 2.0 (the
80841af79SAndrew Rist  * "License"); you may not use this file except in compliance
90841af79SAndrew Rist  * with the License.  You may obtain a copy of the License at
10cdf0e10cSrcweir  *
110841af79SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir  *
130841af79SAndrew Rist  * Unless required by applicable law or agreed to in writing,
140841af79SAndrew Rist  * software distributed under the License is distributed on an
150841af79SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
160841af79SAndrew Rist  * KIND, either express or implied.  See the License for the
170841af79SAndrew Rist  * specific language governing permissions and limitations
180841af79SAndrew Rist  * under the License.
19cdf0e10cSrcweir  *
200841af79SAndrew Rist  *************************************************************/
210841af79SAndrew Rist 
220841af79SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_accessibility.hxx"
26cdf0e10cSrcweir #include <accessibility/extended/accessiblelistbox.hxx>
27cdf0e10cSrcweir #include <accessibility/extended/accessiblelistboxentry.hxx>
28cdf0e10cSrcweir #include <svtools/svtreebx.hxx>
29cdf0e10cSrcweir #include <com/sun/star/awt/Point.hpp>
30cdf0e10cSrcweir #include <com/sun/star/awt/Rectangle.hpp>
31cdf0e10cSrcweir #include <com/sun/star/awt/Size.hpp>
32cdf0e10cSrcweir #include <com/sun/star/accessibility/AccessibleEventId.hpp>
33cdf0e10cSrcweir #include <com/sun/star/accessibility/AccessibleRole.hpp>
34cdf0e10cSrcweir #include <com/sun/star/accessibility/AccessibleStateType.hpp>
35cdf0e10cSrcweir #include <tools/debug.hxx>
36cdf0e10cSrcweir #include <vcl/svapp.hxx>
37cdf0e10cSrcweir #include <toolkit/awt/vclxwindow.hxx>
38cdf0e10cSrcweir #include <toolkit/helper/convert.hxx>
39cdf0e10cSrcweir #include <unotools/accessiblestatesethelper.hxx>
40cdf0e10cSrcweir 
41cdf0e10cSrcweir //........................................................................
42cdf0e10cSrcweir namespace accessibility
43cdf0e10cSrcweir {
44cdf0e10cSrcweir //........................................................................
45cdf0e10cSrcweir 
46cdf0e10cSrcweir     // class AccessibleListBox -----------------------------------------------------
47cdf0e10cSrcweir 
48cdf0e10cSrcweir     using namespace ::com::sun::star::accessibility;
49cdf0e10cSrcweir     using namespace ::com::sun::star::uno;
50cdf0e10cSrcweir     using namespace ::com::sun::star::lang;
51cdf0e10cSrcweir     using namespace ::com::sun::star;
52cdf0e10cSrcweir 
DBG_NAME(AccessibleListBox)53cdf0e10cSrcweir     DBG_NAME(AccessibleListBox)
54cdf0e10cSrcweir 
55cdf0e10cSrcweir     // -----------------------------------------------------------------------------
56cdf0e10cSrcweir     // Ctor() and Dtor()
57cdf0e10cSrcweir     // -----------------------------------------------------------------------------
58cdf0e10cSrcweir     AccessibleListBox::AccessibleListBox( SvTreeListBox& _rListBox, const Reference< XAccessible >& _xParent ) :
59cdf0e10cSrcweir 
60cdf0e10cSrcweir         VCLXAccessibleComponent( _rListBox.GetWindowPeer() ),
61cdf0e10cSrcweir         m_xParent( _xParent )
62cdf0e10cSrcweir     {
63cdf0e10cSrcweir         DBG_CTOR( AccessibleListBox, NULL );
64cdf0e10cSrcweir     }
65cdf0e10cSrcweir     // -----------------------------------------------------------------------------
~AccessibleListBox()66cdf0e10cSrcweir     AccessibleListBox::~AccessibleListBox()
67cdf0e10cSrcweir     {
68cdf0e10cSrcweir         DBG_DTOR( AccessibleListBox, NULL );
69cdf0e10cSrcweir         if ( isAlive() )
70cdf0e10cSrcweir         {
71cdf0e10cSrcweir             // increment ref count to prevent double call of Dtor
72cdf0e10cSrcweir             osl_incrementInterlockedCount( &m_refCount );
73cdf0e10cSrcweir             dispose();
74cdf0e10cSrcweir         }
75cdf0e10cSrcweir     }
IMPLEMENT_FORWARD_XINTERFACE2(AccessibleListBox,VCLXAccessibleComponent,AccessibleListBox_BASE)76cdf0e10cSrcweir     IMPLEMENT_FORWARD_XINTERFACE2(AccessibleListBox, VCLXAccessibleComponent, AccessibleListBox_BASE)
77cdf0e10cSrcweir     IMPLEMENT_FORWARD_XTYPEPROVIDER2(AccessibleListBox, VCLXAccessibleComponent, AccessibleListBox_BASE)
78cdf0e10cSrcweir     // -----------------------------------------------------------------------------
79cdf0e10cSrcweir     SvTreeListBox* AccessibleListBox::getListBox() const
80cdf0e10cSrcweir     {
81cdf0e10cSrcweir         return  static_cast< SvTreeListBox* >( const_cast<AccessibleListBox*>(this)->GetWindow() );
82cdf0e10cSrcweir     }
83cdf0e10cSrcweir     // -----------------------------------------------------------------------------
ProcessWindowEvent(const VclWindowEvent & rVclWindowEvent)84cdf0e10cSrcweir     void AccessibleListBox::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent )
85cdf0e10cSrcweir     {
86cdf0e10cSrcweir         if ( isAlive() )
87cdf0e10cSrcweir         {
88cdf0e10cSrcweir             switch ( rVclWindowEvent.GetId() )
89cdf0e10cSrcweir             {
90cdf0e10cSrcweir                 case VCLEVENT_CHECKBOX_TOGGLE :
91cdf0e10cSrcweir                 {
92*21075d77SSteve Yin                     if ( !getListBox() || !getListBox()->HasFocus() )
93cdf0e10cSrcweir                     {
94*21075d77SSteve Yin                         return;
95cdf0e10cSrcweir                     }
96*21075d77SSteve Yin                     AccessibleListBoxEntry* pCurOpEntry = GetCurEventEntry(rVclWindowEvent);
97*21075d77SSteve Yin                     if(!pCurOpEntry)
98*21075d77SSteve Yin                     {
99*21075d77SSteve Yin                         return ;
100*21075d77SSteve Yin                     }
101*21075d77SSteve Yin                     uno::Any aValue;
102*21075d77SSteve Yin                     aValue <<= AccessibleStateType::CHECKED;
103*21075d77SSteve Yin 
104*21075d77SSteve Yin                     if ( getListBox()->GetCheckButtonState( pCurOpEntry->GetSvLBoxEntry() ) == SV_BUTTON_CHECKED )
105*21075d77SSteve Yin                     {
106*21075d77SSteve Yin                         pCurOpEntry->NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, uno::Any(), aValue );
107*21075d77SSteve Yin                     }
108*21075d77SSteve Yin                     else
109*21075d77SSteve Yin                     {
110*21075d77SSteve Yin                         pCurOpEntry->NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aValue,uno::Any() );
111cdf0e10cSrcweir                     }
112cdf0e10cSrcweir                     break;
113cdf0e10cSrcweir                 }
114cdf0e10cSrcweir 
115cdf0e10cSrcweir                 case VCLEVENT_LISTBOX_SELECT :
116cdf0e10cSrcweir                 {
117cdf0e10cSrcweir                     // First send an event that tells the listeners of a
118cdf0e10cSrcweir                     // modified selection. The active descendant event is
119cdf0e10cSrcweir                     // send after that so that the receiving AT has time to
120cdf0e10cSrcweir                     // read the text or name of the active child.
121*21075d77SSteve Yin //                  NotifyAccessibleEvent( AccessibleEventId::SELECTION_CHANGED, Any(), Any() );
122*21075d77SSteve Yin                     OSL_ASSERT(0 && "Debug: Treelist shouldn't use VCLEVENT_LISTBOX_SELECT");
123*21075d77SSteve Yin                 }
124*21075d77SSteve Yin                 case VCLEVENT_LISTBOX_TREESELECT:
125*21075d77SSteve Yin                     {
126cdf0e10cSrcweir                         if ( getListBox() && getListBox()->HasFocus() )
127cdf0e10cSrcweir                         {
128*21075d77SSteve Yin                             AccessibleListBoxEntry* pEntry =static_cast< AccessibleListBoxEntry* >(m_xFocusedChild.get());
129*21075d77SSteve Yin                             if (pEntry)
130*21075d77SSteve Yin                             {
131*21075d77SSteve Yin                                 pEntry->NotifyAccessibleEvent( AccessibleEventId::SELECTION_CHANGED, Any(), Any() );
132*21075d77SSteve Yin                             }
133*21075d77SSteve Yin                         }
134*21075d77SSteve Yin                     }
135*21075d77SSteve Yin                     break;
136*21075d77SSteve Yin                 case VCLEVENT_LISTBOX_TREEFOCUS:
137*21075d77SSteve Yin                     {
138*21075d77SSteve Yin                         SvTreeListBox* pBox = getListBox();
139*21075d77SSteve Yin                         sal_Bool bNeedFocus = sal_False;
140*21075d77SSteve Yin                         if (pBox)
141*21075d77SSteve Yin                         {
142*21075d77SSteve Yin                             Window* pParent = ((Window*)pBox)->GetParent();
143*21075d77SSteve Yin                             if (pParent && pParent->GetType() == WINDOW_FLOATINGWINDOW)
144*21075d77SSteve Yin                             {
145*21075d77SSteve Yin                                 // MT: ImplGetAppSVData shouldn't be exported from VCL.
146*21075d77SSteve Yin                                 // In which scenario is this needed?
147*21075d77SSteve Yin                                 // If needed, we need to find an other solution
148*21075d77SSteve Yin                                 /*
149*21075d77SSteve Yin                                 ImplSVData* pSVData = ImplGetAppSVData();
150*21075d77SSteve Yin                                 if (pSVData && pSVData->maWinData.mpFirstFloat == (FloatingWindow*)pParent)
151*21075d77SSteve Yin                                     bNeedFocus = sal_True;
152*21075d77SSteve Yin                                 */
153*21075d77SSteve Yin                             }
154*21075d77SSteve Yin                         }
155*21075d77SSteve Yin                         if( pBox && (pBox->HasFocus() || bNeedFocus) )
156*21075d77SSteve Yin                         {
157*21075d77SSteve Yin                             uno::Any aOldValue, aNewValue;
158*21075d77SSteve Yin                             SvLBoxEntry* pEntry = static_cast< SvLBoxEntry* >( rVclWindowEvent.GetData() );
159*21075d77SSteve Yin                             if ( pEntry )
160*21075d77SSteve Yin                             {
161*21075d77SSteve Yin                                 AccessibleListBoxEntry* pEntryFocus =static_cast< AccessibleListBoxEntry* >(m_xFocusedChild.get());
162*21075d77SSteve Yin                                 if (pEntryFocus && pEntryFocus->GetSvLBoxEntry() == pEntry)
163*21075d77SSteve Yin                                 {
164*21075d77SSteve Yin                                     aOldValue <<= uno::Any();
165*21075d77SSteve Yin                                     aNewValue <<= m_xFocusedChild;
166*21075d77SSteve Yin                                     NotifyAccessibleEvent( AccessibleEventId::ACTIVE_DESCENDANT_CHANGED, aOldValue, aNewValue );
167*21075d77SSteve Yin                                     return ;
168*21075d77SSteve Yin                                 }
169*21075d77SSteve Yin 
170*21075d77SSteve Yin                                 aOldValue <<= m_xFocusedChild;
171*21075d77SSteve Yin 
172*21075d77SSteve Yin                                 MAP_ENTRY::iterator mi = m_mapEntry.find(pEntry);
173*21075d77SSteve Yin                                 if(mi != m_mapEntry.end())
174*21075d77SSteve Yin                                 {
175*21075d77SSteve Yin                                     OSL_ASSERT(mi->second.get() != NULL);
176*21075d77SSteve Yin                                     m_xFocusedChild = mi->second;
177*21075d77SSteve Yin                                 }
178*21075d77SSteve Yin                                 else
179*21075d77SSteve Yin                                 {
180*21075d77SSteve Yin                                     AccessibleListBoxEntry *pEntNew = new AccessibleListBoxEntry( *getListBox(), pEntry, NULL );
181*21075d77SSteve Yin                                     m_xFocusedChild = pEntNew;
182*21075d77SSteve Yin                                     m_mapEntry.insert(MAP_ENTRY::value_type(pEntry,pEntNew));
183*21075d77SSteve Yin                                 }
184*21075d77SSteve Yin 
185*21075d77SSteve Yin                                 aNewValue <<= m_xFocusedChild;
186*21075d77SSteve Yin                                 NotifyAccessibleEvent( AccessibleEventId::ACTIVE_DESCENDANT_CHANGED, aOldValue, aNewValue );
187*21075d77SSteve Yin                             }
188*21075d77SSteve Yin                             else
189*21075d77SSteve Yin                             {
190*21075d77SSteve Yin                                 aOldValue <<= uno::Any();
191*21075d77SSteve Yin                                 aNewValue <<= AccessibleStateType::FOCUSED;
192*21075d77SSteve Yin                                 NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );
193*21075d77SSteve Yin                             }
194*21075d77SSteve Yin                         }
195*21075d77SSteve Yin                     }
196*21075d77SSteve Yin                     break;
197*21075d77SSteve Yin                 case VCLEVENT_LISTBOX_ITEMREMOVED:
198*21075d77SSteve Yin                     {
199cdf0e10cSrcweir                         SvLBoxEntry* pEntry = static_cast< SvLBoxEntry* >( rVclWindowEvent.GetData() );
200cdf0e10cSrcweir                         if ( pEntry )
201cdf0e10cSrcweir                         {
202*21075d77SSteve Yin                             RemoveChildEntries(pEntry);
203cdf0e10cSrcweir                         }
204*21075d77SSteve Yin                         else
205*21075d77SSteve Yin                         {
206*21075d77SSteve Yin                             // NULL means Clear()
207*21075d77SSteve Yin                             MAP_ENTRY::iterator mi = m_mapEntry.begin();
208*21075d77SSteve Yin                             for ( ; mi != m_mapEntry.end() ; ++mi)
209*21075d77SSteve Yin                             {
210*21075d77SSteve Yin                                 uno::Any aNewValue;
211*21075d77SSteve Yin                                 uno::Any aOldValue;
212*21075d77SSteve Yin                                 aOldValue <<= mi->second;
213*21075d77SSteve Yin                                 NotifyAccessibleEvent( AccessibleEventId::CHILD, aOldValue, aNewValue );
214*21075d77SSteve Yin                             }
215*21075d77SSteve Yin                             m_mapEntry.clear();
216*21075d77SSteve Yin                         }
217*21075d77SSteve Yin 
218*21075d77SSteve Yin 
219cdf0e10cSrcweir                     }
220cdf0e10cSrcweir                     break;
221cdf0e10cSrcweir 
222cdf0e10cSrcweir                 // --> OD 2009-04-01 #i92103#
223cdf0e10cSrcweir                 case VCLEVENT_ITEM_EXPANDED :
224cdf0e10cSrcweir                 case VCLEVENT_ITEM_COLLAPSED :
225cdf0e10cSrcweir                 {
226cdf0e10cSrcweir                     SvLBoxEntry* pEntry = static_cast< SvLBoxEntry* >( rVclWindowEvent.GetData() );
227cdf0e10cSrcweir                     if ( pEntry )
228cdf0e10cSrcweir                     {
229cdf0e10cSrcweir                         AccessibleListBoxEntry* pAccListBoxEntry =
230cdf0e10cSrcweir                             new AccessibleListBoxEntry( *getListBox(), pEntry, this );
231cdf0e10cSrcweir                         Reference< XAccessible > xChild = pAccListBoxEntry;
232cdf0e10cSrcweir                         const short nAccEvent =
233cdf0e10cSrcweir                             ( rVclWindowEvent.GetId() == VCLEVENT_ITEM_EXPANDED )
234cdf0e10cSrcweir                             ? AccessibleEventId::LISTBOX_ENTRY_EXPANDED
235cdf0e10cSrcweir                             : AccessibleEventId::LISTBOX_ENTRY_COLLAPSED;
236cdf0e10cSrcweir                         uno::Any aListBoxEntry;
237cdf0e10cSrcweir                         aListBoxEntry <<= xChild;
238cdf0e10cSrcweir                         NotifyAccessibleEvent( nAccEvent, Any(), aListBoxEntry );
239cdf0e10cSrcweir                         if ( getListBox() && getListBox()->HasFocus() )
240cdf0e10cSrcweir                         {
241cdf0e10cSrcweir                             NotifyAccessibleEvent( AccessibleEventId::ACTIVE_DESCENDANT_CHANGED, Any(), aListBoxEntry );
242cdf0e10cSrcweir                         }
243cdf0e10cSrcweir                     }
244*21075d77SSteve Yin                 }
245cdf0e10cSrcweir                 break;
246cdf0e10cSrcweir                 // <--
247cdf0e10cSrcweir                 default:
248cdf0e10cSrcweir                     VCLXAccessibleComponent::ProcessWindowEvent (rVclWindowEvent);
249cdf0e10cSrcweir             }
250cdf0e10cSrcweir         }
251cdf0e10cSrcweir     }
252*21075d77SSteve Yin 
GetCurEventEntry(const VclWindowEvent & rVclWindowEvent)253*21075d77SSteve Yin     AccessibleListBoxEntry* AccessibleListBox::GetCurEventEntry( const VclWindowEvent& rVclWindowEvent )
254*21075d77SSteve Yin     {
255*21075d77SSteve Yin         SvLBoxEntry* pEntry = static_cast< SvLBoxEntry* >( rVclWindowEvent.GetData() );
256*21075d77SSteve Yin         if ( !pEntry )
257*21075d77SSteve Yin             pEntry = getListBox()->GetCurEntry();
258*21075d77SSteve Yin 
259*21075d77SSteve Yin         AccessibleListBoxEntry* pEntryFocus =static_cast< AccessibleListBoxEntry* >(m_xFocusedChild.get());
260*21075d77SSteve Yin         if (pEntryFocus && pEntry && pEntry != pEntryFocus->GetSvLBoxEntry())
261*21075d77SSteve Yin         {
262*21075d77SSteve Yin             AccessibleListBoxEntry *pAccCurOptionEntry =NULL;
263*21075d77SSteve Yin             MAP_ENTRY::iterator mi = m_mapEntry.find(pEntry);
264*21075d77SSteve Yin             if (mi != m_mapEntry.end())
265*21075d77SSteve Yin             {
266*21075d77SSteve Yin                 pAccCurOptionEntry= static_cast< AccessibleListBoxEntry* >(mi->second.get());
267*21075d77SSteve Yin             }
268*21075d77SSteve Yin             else
269*21075d77SSteve Yin             {
270*21075d77SSteve Yin                 pAccCurOptionEntry =new AccessibleListBoxEntry( *getListBox(), pEntry, NULL );
271*21075d77SSteve Yin                 std::pair<MAP_ENTRY::iterator, bool> pairMi = m_mapEntry.insert(MAP_ENTRY::value_type(pAccCurOptionEntry->GetSvLBoxEntry(),pAccCurOptionEntry));
272*21075d77SSteve Yin                 mi = pairMi.first;
273*21075d77SSteve Yin             }
274*21075d77SSteve Yin 
275*21075d77SSteve Yin             uno::Any aNewValue;
276*21075d77SSteve Yin             aNewValue <<= mi->second;//xAcc
277*21075d77SSteve Yin             NotifyAccessibleEvent( AccessibleEventId::CHILD, uno::Any(), aNewValue );//Add
278*21075d77SSteve Yin 
279*21075d77SSteve Yin             return pAccCurOptionEntry;
280*21075d77SSteve Yin         }
281*21075d77SSteve Yin         else
282*21075d77SSteve Yin         {
283*21075d77SSteve Yin             return pEntryFocus;
284*21075d77SSteve Yin         }
285*21075d77SSteve Yin         return NULL;
286*21075d77SSteve Yin     }
287*21075d77SSteve Yin 
RemoveChildEntries(SvLBoxEntry * pEntry)288*21075d77SSteve Yin     void AccessibleListBox::RemoveChildEntries(SvLBoxEntry* pEntry)
289*21075d77SSteve Yin     {
290*21075d77SSteve Yin         MAP_ENTRY::iterator mi = m_mapEntry.find(pEntry);
291*21075d77SSteve Yin         if ( mi != m_mapEntry.end() )
292*21075d77SSteve Yin         {
293*21075d77SSteve Yin             uno::Any aNewValue;
294*21075d77SSteve Yin             uno::Any aOldValue;
295*21075d77SSteve Yin             aOldValue <<= mi->second;
296*21075d77SSteve Yin             NotifyAccessibleEvent( AccessibleEventId::CHILD, aOldValue, aNewValue );
297*21075d77SSteve Yin 
298*21075d77SSteve Yin             m_mapEntry.erase(mi);
299*21075d77SSteve Yin         }
300*21075d77SSteve Yin 
301*21075d77SSteve Yin         SvTreeListBox* pBox = getListBox();
302*21075d77SSteve Yin         SvLBoxEntry* pEntryChild = pBox->FirstChild(pEntry);
303*21075d77SSteve Yin         while (pEntryChild)
304*21075d77SSteve Yin         {
305*21075d77SSteve Yin             RemoveChildEntries(pEntryChild);
306*21075d77SSteve Yin             pEntryChild = pBox->NextSibling(pEntryChild);
307*21075d77SSteve Yin         }
308*21075d77SSteve Yin     }
309*21075d77SSteve Yin 
310cdf0e10cSrcweir     // -----------------------------------------------------------------------------
ProcessWindowChildEvent(const VclWindowEvent & rVclWindowEvent)311cdf0e10cSrcweir     void AccessibleListBox::ProcessWindowChildEvent( const VclWindowEvent& rVclWindowEvent )
312cdf0e10cSrcweir     {
313cdf0e10cSrcweir         switch ( rVclWindowEvent.GetId() )
314cdf0e10cSrcweir         {
315cdf0e10cSrcweir             case VCLEVENT_WINDOW_SHOW:
316cdf0e10cSrcweir             case VCLEVENT_WINDOW_HIDE:
317cdf0e10cSrcweir             {
318cdf0e10cSrcweir             }
319cdf0e10cSrcweir             break;
320cdf0e10cSrcweir             default:
321cdf0e10cSrcweir             {
322cdf0e10cSrcweir                 VCLXAccessibleComponent::ProcessWindowChildEvent( rVclWindowEvent );
323cdf0e10cSrcweir             }
324cdf0e10cSrcweir             break;
325cdf0e10cSrcweir         }
326cdf0e10cSrcweir     }
327cdf0e10cSrcweir 
328cdf0e10cSrcweir     // -----------------------------------------------------------------------------
329cdf0e10cSrcweir     // XComponent
330cdf0e10cSrcweir     // -----------------------------------------------------------------------------
disposing()331cdf0e10cSrcweir     void SAL_CALL AccessibleListBox::disposing()
332cdf0e10cSrcweir     {
333cdf0e10cSrcweir         ::osl::MutexGuard aGuard( m_aMutex );
334cdf0e10cSrcweir 
335*21075d77SSteve Yin         m_mapEntry.clear();
336cdf0e10cSrcweir         VCLXAccessibleComponent::disposing();
337cdf0e10cSrcweir         m_xParent = NULL;
338cdf0e10cSrcweir     }
339cdf0e10cSrcweir     // -----------------------------------------------------------------------------
340cdf0e10cSrcweir     // XServiceInfo
341cdf0e10cSrcweir     // -----------------------------------------------------------------------------
getImplementationName()342cdf0e10cSrcweir     ::rtl::OUString SAL_CALL AccessibleListBox::getImplementationName() throw(RuntimeException)
343cdf0e10cSrcweir     {
344cdf0e10cSrcweir         return getImplementationName_Static();
345cdf0e10cSrcweir     }
346cdf0e10cSrcweir     // -----------------------------------------------------------------------------
getSupportedServiceNames()347cdf0e10cSrcweir     Sequence< ::rtl::OUString > SAL_CALL AccessibleListBox::getSupportedServiceNames() throw(RuntimeException)
348cdf0e10cSrcweir     {
349cdf0e10cSrcweir         return getSupportedServiceNames_Static();
350cdf0e10cSrcweir     }
351cdf0e10cSrcweir     // -----------------------------------------------------------------------------
supportsService(const::rtl::OUString & _rServiceName)352cdf0e10cSrcweir     sal_Bool SAL_CALL AccessibleListBox::supportsService( const ::rtl::OUString& _rServiceName ) throw (RuntimeException)
353cdf0e10cSrcweir     {
354cdf0e10cSrcweir         Sequence< ::rtl::OUString > aSupported( getSupportedServiceNames() );
355cdf0e10cSrcweir         const ::rtl::OUString* pSupported = aSupported.getConstArray();
356cdf0e10cSrcweir         const ::rtl::OUString* pEnd = pSupported + aSupported.getLength();
357cdf0e10cSrcweir         for ( ; pSupported != pEnd && !pSupported->equals(_rServiceName); ++pSupported )
358cdf0e10cSrcweir             ;
359cdf0e10cSrcweir 
360cdf0e10cSrcweir         return pSupported != pEnd;
361cdf0e10cSrcweir     }
362cdf0e10cSrcweir     // -----------------------------------------------------------------------------
363cdf0e10cSrcweir     // XServiceInfo - static methods
364cdf0e10cSrcweir     // -----------------------------------------------------------------------------
getSupportedServiceNames_Static(void)365cdf0e10cSrcweir     Sequence< ::rtl::OUString > AccessibleListBox::getSupportedServiceNames_Static(void) throw( RuntimeException )
366cdf0e10cSrcweir     {
367cdf0e10cSrcweir         Sequence< ::rtl::OUString > aSupported(3);
368cdf0e10cSrcweir         aSupported[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.accessibility.AccessibleContext") );
369cdf0e10cSrcweir         aSupported[1] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.accessibility.AccessibleComponent") );
370cdf0e10cSrcweir         aSupported[2] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.awt.AccessibleTreeListBox") );
371cdf0e10cSrcweir         return aSupported;
372cdf0e10cSrcweir     }
373cdf0e10cSrcweir     // -----------------------------------------------------------------------------
getImplementationName_Static(void)374cdf0e10cSrcweir     ::rtl::OUString AccessibleListBox::getImplementationName_Static(void) throw( RuntimeException )
375cdf0e10cSrcweir     {
376cdf0e10cSrcweir         return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.svtools.AccessibleTreeListBox") );
377cdf0e10cSrcweir     }
378cdf0e10cSrcweir     // -----------------------------------------------------------------------------
379cdf0e10cSrcweir     // XAccessible
380cdf0e10cSrcweir     // -----------------------------------------------------------------------------
getAccessibleContext()381cdf0e10cSrcweir     Reference< XAccessibleContext > SAL_CALL AccessibleListBox::getAccessibleContext(  ) throw (RuntimeException)
382cdf0e10cSrcweir     {
383cdf0e10cSrcweir         ensureAlive();
384cdf0e10cSrcweir         return this;
385cdf0e10cSrcweir     }
386cdf0e10cSrcweir     // -----------------------------------------------------------------------------
387cdf0e10cSrcweir     // XAccessibleContext
388cdf0e10cSrcweir     // -----------------------------------------------------------------------------
getAccessibleChildCount()389cdf0e10cSrcweir     sal_Int32 SAL_CALL AccessibleListBox::getAccessibleChildCount(  ) throw (RuntimeException)
390cdf0e10cSrcweir     {
391cdf0e10cSrcweir         ::comphelper::OExternalLockGuard aGuard( this );
392cdf0e10cSrcweir 
393cdf0e10cSrcweir         ensureAlive();
394cdf0e10cSrcweir 
395cdf0e10cSrcweir         sal_Int32 nCount = 0;
396cdf0e10cSrcweir         SvTreeListBox* pSvTreeListBox = getListBox();
397cdf0e10cSrcweir         if ( pSvTreeListBox )
398cdf0e10cSrcweir             nCount = pSvTreeListBox->GetLevelChildCount( NULL );
399cdf0e10cSrcweir 
400cdf0e10cSrcweir         return nCount;
401cdf0e10cSrcweir     }
402cdf0e10cSrcweir     // -----------------------------------------------------------------------------
getAccessibleChild(sal_Int32 i)403cdf0e10cSrcweir     Reference< XAccessible > SAL_CALL AccessibleListBox::getAccessibleChild( sal_Int32 i ) throw (IndexOutOfBoundsException,RuntimeException)
404cdf0e10cSrcweir     {
405cdf0e10cSrcweir         ::comphelper::OExternalLockGuard aGuard( this );
406cdf0e10cSrcweir 
407cdf0e10cSrcweir         ensureAlive();
408cdf0e10cSrcweir         SvLBoxEntry* pEntry = getListBox()->GetEntry(i);
409cdf0e10cSrcweir         if ( !pEntry )
410cdf0e10cSrcweir             throw IndexOutOfBoundsException();
411cdf0e10cSrcweir 
412*21075d77SSteve Yin         // Solution: Set the parameter of the parent to null to let entry determine the parent by itself
413*21075d77SSteve Yin         //return new AccessibleListBoxEntry( *getListBox(), pEntry, this );
414*21075d77SSteve Yin         return new AccessibleListBoxEntry( *getListBox(), pEntry, NULL );
415cdf0e10cSrcweir     }
416cdf0e10cSrcweir     // -----------------------------------------------------------------------------
getAccessibleParent()417cdf0e10cSrcweir     Reference< XAccessible > SAL_CALL AccessibleListBox::getAccessibleParent(  ) throw (RuntimeException)
418cdf0e10cSrcweir     {
419cdf0e10cSrcweir         ::osl::MutexGuard aGuard( m_aMutex );
420cdf0e10cSrcweir 
421cdf0e10cSrcweir         ensureAlive();
422cdf0e10cSrcweir         return m_xParent;
423cdf0e10cSrcweir     }
424cdf0e10cSrcweir     // -----------------------------------------------------------------------------
getRoleType()425*21075d77SSteve Yin     sal_Int32 SAL_CALL AccessibleListBox::getRoleType()
426*21075d77SSteve Yin     {
427*21075d77SSteve Yin         sal_Int32 nCase = 0;
428*21075d77SSteve Yin         SvLBoxEntry* pEntry = getListBox()->GetEntry(0);
429*21075d77SSteve Yin         if ( pEntry )
430*21075d77SSteve Yin         {
431*21075d77SSteve Yin             if( pEntry->HasChildsOnDemand() || getListBox()->GetChildCount(pEntry) > 0  )
432*21075d77SSteve Yin             {
433*21075d77SSteve Yin                 nCase = 1;
434*21075d77SSteve Yin                 return nCase;
435*21075d77SSteve Yin             }
436*21075d77SSteve Yin         }
437*21075d77SSteve Yin 
438*21075d77SSteve Yin         sal_Bool bHasButtons = (getListBox()->GetStyle() & WB_HASBUTTONS)!=0;
439*21075d77SSteve Yin         if( !(getListBox()->GetTreeFlags() & TREEFLAG_CHKBTN) )
440*21075d77SSteve Yin         {
441*21075d77SSteve Yin             if( bHasButtons )
442*21075d77SSteve Yin                 nCase = 1;
443*21075d77SSteve Yin         }
444*21075d77SSteve Yin         else
445*21075d77SSteve Yin         {
446*21075d77SSteve Yin             if( bHasButtons )
447*21075d77SSteve Yin                 nCase = 2;
448*21075d77SSteve Yin              else
449*21075d77SSteve Yin                 nCase = 3;
450*21075d77SSteve Yin         }
451*21075d77SSteve Yin         return nCase;
452*21075d77SSteve Yin     }
getAccessibleRole()453cdf0e10cSrcweir     sal_Int16 SAL_CALL AccessibleListBox::getAccessibleRole(  ) throw (RuntimeException)
454cdf0e10cSrcweir     {
455*21075d77SSteve Yin         if(getListBox())
456*21075d77SSteve Yin         {
457*21075d77SSteve Yin             short nType = getListBox()->GetAllEntriesAccessibleRoleType();
458*21075d77SSteve Yin             if( nType == TREEBOX_ALLITEM_ACCROLE_TYPE_TREE)
459*21075d77SSteve Yin                     return AccessibleRole::TREE;
460*21075d77SSteve Yin             else if( nType == TREEBOX_ALLITEM_ACCROLE_TYPE_LIST)
461*21075d77SSteve Yin                     return AccessibleRole::LIST;
462*21075d77SSteve Yin         }
463*21075d77SSteve Yin 
464*21075d77SSteve Yin         //o is: return AccessibleRole::TREE;
465*21075d77SSteve Yin         sal_Bool bHasButtons = (getListBox()->GetStyle() & WB_HASBUTTONS)!=0;
466*21075d77SSteve Yin         if(!bHasButtons && (getListBox()->GetTreeFlags() & TREEFLAG_CHKBTN))
467*21075d77SSteve Yin             return AccessibleRole::LIST;
468*21075d77SSteve Yin         else
469*21075d77SSteve Yin             if(getRoleType() == 0)
470*21075d77SSteve Yin                 return AccessibleRole::LIST;
471*21075d77SSteve Yin             else
472cdf0e10cSrcweir             return AccessibleRole::TREE;
473cdf0e10cSrcweir     }
474cdf0e10cSrcweir     // -----------------------------------------------------------------------------
getAccessibleDescription()475cdf0e10cSrcweir     ::rtl::OUString SAL_CALL AccessibleListBox::getAccessibleDescription(  ) throw (RuntimeException)
476cdf0e10cSrcweir     {
477cdf0e10cSrcweir         ::comphelper::OExternalLockGuard aGuard( this );
478cdf0e10cSrcweir 
479cdf0e10cSrcweir         ensureAlive();
480cdf0e10cSrcweir         return getListBox()->GetAccessibleDescription();
481cdf0e10cSrcweir     }
482cdf0e10cSrcweir     // -----------------------------------------------------------------------------
getAccessibleName()483cdf0e10cSrcweir     ::rtl::OUString SAL_CALL AccessibleListBox::getAccessibleName(  ) throw (RuntimeException)
484cdf0e10cSrcweir     {
485cdf0e10cSrcweir         ::comphelper::OExternalLockGuard aGuard( this );
486cdf0e10cSrcweir 
487cdf0e10cSrcweir         ensureAlive();
488cdf0e10cSrcweir         return getListBox()->GetAccessibleName();
489cdf0e10cSrcweir     }
490cdf0e10cSrcweir     // -----------------------------------------------------------------------------
491cdf0e10cSrcweir     // XAccessibleSelection
492cdf0e10cSrcweir     // -----------------------------------------------------------------------------
selectAccessibleChild(sal_Int32 nChildIndex)493cdf0e10cSrcweir     void SAL_CALL AccessibleListBox::selectAccessibleChild( sal_Int32 nChildIndex ) throw (IndexOutOfBoundsException, RuntimeException)
494cdf0e10cSrcweir     {
495cdf0e10cSrcweir         ::comphelper::OExternalLockGuard aGuard( this );
496cdf0e10cSrcweir 
497cdf0e10cSrcweir         ensureAlive();
498cdf0e10cSrcweir 
499cdf0e10cSrcweir         SvLBoxEntry* pEntry = getListBox()->GetEntry( nChildIndex );
500cdf0e10cSrcweir         if ( !pEntry )
501cdf0e10cSrcweir             throw IndexOutOfBoundsException();
502cdf0e10cSrcweir 
503cdf0e10cSrcweir         getListBox()->Select( pEntry, sal_True );
504cdf0e10cSrcweir     }
505cdf0e10cSrcweir     // -----------------------------------------------------------------------------
isAccessibleChildSelected(sal_Int32 nChildIndex)506cdf0e10cSrcweir     sal_Bool SAL_CALL AccessibleListBox::isAccessibleChildSelected( sal_Int32 nChildIndex ) throw (IndexOutOfBoundsException, RuntimeException)
507cdf0e10cSrcweir     {
508cdf0e10cSrcweir         ::comphelper::OExternalLockGuard aGuard( this );
509cdf0e10cSrcweir 
510cdf0e10cSrcweir         ensureAlive();
511cdf0e10cSrcweir 
512cdf0e10cSrcweir         SvLBoxEntry* pEntry = getListBox()->GetEntry( nChildIndex );
513cdf0e10cSrcweir         if ( !pEntry )
514cdf0e10cSrcweir             throw IndexOutOfBoundsException();
515cdf0e10cSrcweir 
516cdf0e10cSrcweir         return getListBox()->IsSelected( pEntry );
517cdf0e10cSrcweir     }
518cdf0e10cSrcweir     // -----------------------------------------------------------------------------
clearAccessibleSelection()519cdf0e10cSrcweir     void SAL_CALL AccessibleListBox::clearAccessibleSelection(  ) throw (RuntimeException)
520cdf0e10cSrcweir     {
521cdf0e10cSrcweir         ::comphelper::OExternalLockGuard aGuard( this );
522cdf0e10cSrcweir 
523cdf0e10cSrcweir         ensureAlive();
524cdf0e10cSrcweir 
525cdf0e10cSrcweir         sal_Int32 i, nCount = 0;
526cdf0e10cSrcweir         nCount = getListBox()->GetLevelChildCount( NULL );
527cdf0e10cSrcweir         for ( i = 0; i < nCount; ++i )
528cdf0e10cSrcweir         {
529cdf0e10cSrcweir             SvLBoxEntry* pEntry = getListBox()->GetEntry( i );
530cdf0e10cSrcweir             if ( getListBox()->IsSelected( pEntry ) )
531cdf0e10cSrcweir                 getListBox()->Select( pEntry, sal_False );
532cdf0e10cSrcweir         }
533cdf0e10cSrcweir     }
534cdf0e10cSrcweir     // -----------------------------------------------------------------------------
selectAllAccessibleChildren()535cdf0e10cSrcweir     void SAL_CALL AccessibleListBox::selectAllAccessibleChildren(  ) throw (RuntimeException)
536cdf0e10cSrcweir     {
537cdf0e10cSrcweir         ::comphelper::OExternalLockGuard aGuard( this );
538cdf0e10cSrcweir 
539cdf0e10cSrcweir         ensureAlive();
540cdf0e10cSrcweir 
541cdf0e10cSrcweir         sal_Int32 i, nCount = 0;
542cdf0e10cSrcweir         nCount = getListBox()->GetLevelChildCount( NULL );
543cdf0e10cSrcweir         for ( i = 0; i < nCount; ++i )
544cdf0e10cSrcweir         {
545cdf0e10cSrcweir             SvLBoxEntry* pEntry = getListBox()->GetEntry( i );
546cdf0e10cSrcweir             if ( !getListBox()->IsSelected( pEntry ) )
547cdf0e10cSrcweir                 getListBox()->Select( pEntry, sal_True );
548cdf0e10cSrcweir         }
549cdf0e10cSrcweir     }
550cdf0e10cSrcweir     // -----------------------------------------------------------------------------
getSelectedAccessibleChildCount()551cdf0e10cSrcweir     sal_Int32 SAL_CALL AccessibleListBox::getSelectedAccessibleChildCount(  ) throw (RuntimeException)
552cdf0e10cSrcweir     {
553cdf0e10cSrcweir         ::comphelper::OExternalLockGuard aGuard( this );
554cdf0e10cSrcweir 
555cdf0e10cSrcweir         ensureAlive();
556cdf0e10cSrcweir 
557cdf0e10cSrcweir 
558*21075d77SSteve Yin //      sal_Int32 i, nSelCount = 0, nCount = 0;
559*21075d77SSteve Yin //      nCount = getListBox()->GetLevelChildCount( NULL );
560*21075d77SSteve Yin //      for ( i = 0; i < nCount; ++i )
561*21075d77SSteve Yin //      {
562*21075d77SSteve Yin //          SvLBoxEntry* pEntry = getListBox()->GetEntry( i );
563*21075d77SSteve Yin //          if ( getListBox()->IsSelected( pEntry ) )
564*21075d77SSteve Yin //              ++nSelCount;
565*21075d77SSteve Yin //      }
566*21075d77SSteve Yin //      return nSelCount;
567*21075d77SSteve Yin 
568*21075d77SSteve Yin         int nTestCount = getListBox()->GetSelectionCount();
569*21075d77SSteve Yin         return nTestCount;
570cdf0e10cSrcweir     }
571cdf0e10cSrcweir     // -----------------------------------------------------------------------------
getSelectedAccessibleChild(sal_Int32 nSelectedChildIndex)572cdf0e10cSrcweir     Reference< XAccessible > SAL_CALL AccessibleListBox::getSelectedAccessibleChild( sal_Int32 nSelectedChildIndex ) throw (IndexOutOfBoundsException, RuntimeException)
573cdf0e10cSrcweir     {
574cdf0e10cSrcweir         ::comphelper::OExternalLockGuard aGuard( this );
575cdf0e10cSrcweir 
576cdf0e10cSrcweir         ensureAlive();
577cdf0e10cSrcweir 
578cdf0e10cSrcweir         if ( nSelectedChildIndex < 0 || nSelectedChildIndex >= getSelectedAccessibleChildCount() )
579cdf0e10cSrcweir             throw IndexOutOfBoundsException();
580cdf0e10cSrcweir 
581cdf0e10cSrcweir         Reference< XAccessible > xChild;
582cdf0e10cSrcweir         sal_Int32 i, nSelCount = 0, nCount = 0;
583cdf0e10cSrcweir         nCount = getListBox()->GetLevelChildCount( NULL );
584cdf0e10cSrcweir         for ( i = 0; i < nCount; ++i )
585cdf0e10cSrcweir         {
586cdf0e10cSrcweir             SvLBoxEntry* pEntry = getListBox()->GetEntry( i );
587cdf0e10cSrcweir             if ( getListBox()->IsSelected( pEntry ) )
588cdf0e10cSrcweir                 ++nSelCount;
589cdf0e10cSrcweir 
590cdf0e10cSrcweir             if ( nSelCount == ( nSelectedChildIndex + 1 ) )
591cdf0e10cSrcweir             {
592*21075d77SSteve Yin                 // Solution: Set the parameter of the parent to null to let entry determine the parent by itself
593*21075d77SSteve Yin                 //xChild = new AccessibleListBoxEntry( *getListBox(), pEntry, this );
594*21075d77SSteve Yin                 xChild = new AccessibleListBoxEntry( *getListBox(), pEntry, NULL );
595cdf0e10cSrcweir                 break;
596cdf0e10cSrcweir             }
597cdf0e10cSrcweir         }
598cdf0e10cSrcweir 
599cdf0e10cSrcweir         return xChild;
600cdf0e10cSrcweir     }
601cdf0e10cSrcweir     // -----------------------------------------------------------------------------
deselectAccessibleChild(sal_Int32 nSelectedChildIndex)602cdf0e10cSrcweir     void SAL_CALL AccessibleListBox::deselectAccessibleChild( sal_Int32 nSelectedChildIndex ) throw (IndexOutOfBoundsException, RuntimeException)
603cdf0e10cSrcweir     {
604cdf0e10cSrcweir         ::comphelper::OExternalLockGuard aGuard( this );
605cdf0e10cSrcweir 
606cdf0e10cSrcweir         ensureAlive();
607cdf0e10cSrcweir 
608cdf0e10cSrcweir         SvLBoxEntry* pEntry = getListBox()->GetEntry( nSelectedChildIndex );
609cdf0e10cSrcweir         if ( !pEntry )
610cdf0e10cSrcweir             throw IndexOutOfBoundsException();
611cdf0e10cSrcweir 
612cdf0e10cSrcweir         getListBox()->Select( pEntry, sal_False );
613cdf0e10cSrcweir     }
614cdf0e10cSrcweir     // -----------------------------------------------------------------------------
FillAccessibleStateSet(utl::AccessibleStateSetHelper & rStateSet)615cdf0e10cSrcweir     void AccessibleListBox::FillAccessibleStateSet( utl::AccessibleStateSetHelper& rStateSet )
616cdf0e10cSrcweir     {
617cdf0e10cSrcweir         VCLXAccessibleComponent::FillAccessibleStateSet( rStateSet );
618cdf0e10cSrcweir         if ( getListBox() && isAlive() )
619cdf0e10cSrcweir         {
620cdf0e10cSrcweir             rStateSet.AddState( AccessibleStateType::FOCUSABLE );
621cdf0e10cSrcweir             rStateSet.AddState( AccessibleStateType::MANAGES_DESCENDANTS );
622cdf0e10cSrcweir             if ( getListBox()->GetSelectionMode() == MULTIPLE_SELECTION )
623cdf0e10cSrcweir                 rStateSet.AddState( AccessibleStateType::MULTI_SELECTABLE );
624cdf0e10cSrcweir         }
625cdf0e10cSrcweir     }
626cdf0e10cSrcweir 
627cdf0e10cSrcweir 
628cdf0e10cSrcweir //........................................................................
629cdf0e10cSrcweir }// namespace accessibility
630cdf0e10cSrcweir //........................................................................
631