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 #include <standard/vclxaccessiblelistitem.hxx>
21 #include <toolkit/helper/convert.hxx>
22 #include <helper/IComboListBoxHelper.hxx>
23 #include <com/sun/star/awt/Rectangle.hpp>
24 
25 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
26 #include <com/sun/star/accessibility/AccessibleRole.hpp>
27 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
28 #include <com/sun/star/datatransfer/clipboard/XClipboard.hpp>
29 #include <com/sun/star/datatransfer/clipboard/XFlushableClipboard.hpp>
30 #include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
31 #include <cppuhelper/supportsservice.hxx>
32 #include <vcl/svapp.hxx>
33 #include <vcl/toolkit/lstbox.hxx>
34 #include <vcl/unohelp2.hxx>
35 #include <vcl/settings.hxx>
36 #include <unotools/accessiblestatesethelper.hxx>
37 #include <unotools/accessiblerelationsethelper.hxx>
38 #include <comphelper/accessibleeventnotifier.hxx>
39 #include <i18nlangtag/languagetag.hxx>
40 
41 namespace
42 {
43     /// @throws css::lang::IndexOutOfBoundsException
checkIndex_Impl(sal_Int32 _nIndex,const OUString & _sText)44     void checkIndex_Impl( sal_Int32 _nIndex, const OUString& _sText )
45     {
46         if ( _nIndex < 0 || _nIndex > _sText.getLength() )
47             throw css::lang::IndexOutOfBoundsException();
48     }
49 }
50 
51 // class VCLXAccessibleListItem ------------------------------------------
52 
53 using namespace ::com::sun::star::accessibility;
54 using namespace ::com::sun::star::uno;
55 using namespace ::com::sun::star::beans;
56 using namespace ::com::sun::star::lang;
57 using namespace ::com::sun::star;
58 
59 
60 // Ctor() and Dtor()
61 
VCLXAccessibleListItem(sal_Int32 _nIndexInParent,const rtl::Reference<VCLXAccessibleList> & _xParent)62 VCLXAccessibleListItem::VCLXAccessibleListItem(sal_Int32 _nIndexInParent, const rtl::Reference< VCLXAccessibleList >& _xParent)
63     : VCLXAccessibleListItem_BASE(m_aMutex)
64     , m_nIndexInParent(_nIndexInParent)
65     , m_bSelected(false)
66     , m_bVisible(false)
67     , m_nClientId(0)
68     , m_xParent(_xParent)
69 {
70     assert(m_xParent.is());
71     ::accessibility::IComboListBoxHelper* pListBoxHelper = m_xParent->getListBoxHelper();
72     if (pListBoxHelper)
73         m_sEntryText = pListBoxHelper->GetEntry(static_cast<sal_uInt16>(_nIndexInParent));
74 }
75 
SetSelected(bool _bSelected)76 void VCLXAccessibleListItem::SetSelected( bool _bSelected )
77 {
78     if ( m_bSelected != _bSelected )
79     {
80         Any aOldValue;
81         Any aNewValue;
82         if ( m_bSelected )
83             aOldValue <<= AccessibleStateType::SELECTED;
84         else
85             aNewValue <<= AccessibleStateType::SELECTED;
86         m_bSelected = _bSelected;
87         NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );
88     }
89 }
90 
SetVisible(bool _bVisible)91 void VCLXAccessibleListItem::SetVisible( bool _bVisible )
92 {
93     if ( m_bVisible != _bVisible )
94     {
95         Any aOldValue, aNewValue;
96         m_bVisible = _bVisible;
97         (_bVisible ? aNewValue : aOldValue ) <<= AccessibleStateType::VISIBLE;
98         NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );
99         (_bVisible ? aNewValue : aOldValue ) <<= AccessibleStateType::SHOWING;
100         NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );
101     }
102 }
103 
NotifyAccessibleEvent(sal_Int16 _nEventId,const css::uno::Any & _aOldValue,const css::uno::Any & _aNewValue)104 void VCLXAccessibleListItem::NotifyAccessibleEvent( sal_Int16 _nEventId,
105                                                     const css::uno::Any& _aOldValue,
106                                                     const css::uno::Any& _aNewValue )
107 {
108     AccessibleEventObject aEvt;
109     aEvt.Source = *this;
110     aEvt.EventId = _nEventId;
111     aEvt.OldValue = _aOldValue;
112     aEvt.NewValue = _aNewValue;
113 
114     if (m_nClientId)
115         comphelper::AccessibleEventNotifier::addEvent( m_nClientId, aEvt );
116 }
117 
118 // OCommonAccessibleText
119 
implGetText()120 OUString VCLXAccessibleListItem::implGetText()
121 {
122     return m_sEntryText;
123 }
124 
implGetLocale()125 Locale VCLXAccessibleListItem::implGetLocale()
126 {
127     return Application::GetSettings().GetLanguageTag().getLocale();
128 }
129 
implGetSelection(sal_Int32 & nStartIndex,sal_Int32 & nEndIndex)130 void VCLXAccessibleListItem::implGetSelection( sal_Int32& nStartIndex, sal_Int32& nEndIndex )
131 {
132     nStartIndex = 0;
133     nEndIndex = 0;
134 }
135 
136 // XTypeProvider
137 
getImplementationId()138 Sequence< sal_Int8 > VCLXAccessibleListItem::getImplementationId()
139 {
140     return css::uno::Sequence<sal_Int8>();
141 }
142 
143 // XComponent
144 
disposing()145 void SAL_CALL VCLXAccessibleListItem::disposing()
146 {
147     comphelper::AccessibleEventNotifier::TClientId nId( 0 );
148     Reference< XInterface > xEventSource;
149     {
150         ::osl::MutexGuard aGuard( m_aMutex );
151 
152         VCLXAccessibleListItem_BASE::disposing();
153         m_sEntryText.clear();
154         m_xParent           = nullptr;
155 
156         nId = m_nClientId;
157         m_nClientId =  0;
158         if ( nId )
159             xEventSource = *this;
160     }
161 
162     // Send a disposing to all listeners.
163     if ( nId )
164             comphelper::AccessibleEventNotifier::revokeClientNotifyDisposing( nId, *this );
165 }
166 
167 // XServiceInfo
168 
getImplementationName()169 OUString VCLXAccessibleListItem::getImplementationName()
170 {
171     return "com.sun.star.comp.toolkit.AccessibleListItem";
172 }
173 
supportsService(const OUString & rServiceName)174 sal_Bool VCLXAccessibleListItem::supportsService( const OUString& rServiceName )
175 {
176     return cppu::supportsService(this, rServiceName);
177 }
178 
getSupportedServiceNames()179 Sequence< OUString > VCLXAccessibleListItem::getSupportedServiceNames()
180 {
181     return {"com.sun.star.accessibility.AccessibleContext",
182             "com.sun.star.accessibility.AccessibleComponent",
183             "com.sun.star.accessibility.AccessibleListItem"};
184 }
185 
186 // XAccessible
187 
getAccessibleContext()188 Reference< XAccessibleContext > SAL_CALL VCLXAccessibleListItem::getAccessibleContext(  )
189 {
190     return this;
191 }
192 
193 // XAccessibleContext
194 
getAccessibleChildCount()195 sal_Int32 SAL_CALL VCLXAccessibleListItem::getAccessibleChildCount(  )
196 {
197     return 0;
198 }
199 
getAccessibleChild(sal_Int32)200 Reference< XAccessible > SAL_CALL VCLXAccessibleListItem::getAccessibleChild( sal_Int32 )
201 {
202     return Reference< XAccessible >();
203 }
204 
getAccessibleParent()205 Reference< XAccessible > SAL_CALL VCLXAccessibleListItem::getAccessibleParent(  )
206 {
207     ::osl::MutexGuard aGuard( m_aMutex );
208 
209     return m_xParent;
210 }
211 
getAccessibleIndexInParent()212 sal_Int32 SAL_CALL VCLXAccessibleListItem::getAccessibleIndexInParent(  )
213 {
214     ::osl::MutexGuard aGuard( m_aMutex );
215     return m_nIndexInParent;
216 }
217 
getAccessibleRole()218 sal_Int16 SAL_CALL VCLXAccessibleListItem::getAccessibleRole(  )
219 {
220     return AccessibleRole::LIST_ITEM;
221     //  return AccessibleRole::LABEL;
222 }
223 
getAccessibleDescription()224 OUString SAL_CALL VCLXAccessibleListItem::getAccessibleDescription(  )
225 {
226     // no description for every item
227     return OUString();
228 }
229 
getAccessibleName()230 OUString SAL_CALL VCLXAccessibleListItem::getAccessibleName(  )
231 {
232     ::osl::MutexGuard aGuard( m_aMutex );
233 
234     // entry text == accessible name
235     return m_sEntryText;
236 }
237 
getAccessibleRelationSet()238 Reference< XAccessibleRelationSet > SAL_CALL VCLXAccessibleListItem::getAccessibleRelationSet(  )
239 {
240     return new utl::AccessibleRelationSetHelper;
241 }
242 
getAccessibleStateSet()243 Reference< XAccessibleStateSet > SAL_CALL VCLXAccessibleListItem::getAccessibleStateSet(  )
244 {
245     ::osl::MutexGuard aGuard( m_aMutex );
246 
247     rtl::Reference<utl::AccessibleStateSetHelper> pStateSetHelper = new utl::AccessibleStateSetHelper;
248 
249     if ( !rBHelper.bDisposed && !rBHelper.bInDispose )
250     {
251         pStateSetHelper->AddState( AccessibleStateType::TRANSIENT );
252 
253         ::accessibility::IComboListBoxHelper* pListBoxHelper = m_xParent.is() ? m_xParent->getListBoxHelper() : nullptr;
254         if (pListBoxHelper && pListBoxHelper->IsEnabled())
255         {
256             pStateSetHelper->AddState( AccessibleStateType::SELECTABLE );
257             pStateSetHelper->AddState( AccessibleStateType::ENABLED );
258             pStateSetHelper->AddState( AccessibleStateType::SENSITIVE );
259         }
260 
261         if ( m_bSelected )
262             pStateSetHelper->AddState( AccessibleStateType::SELECTED );
263         if ( m_bVisible )
264         {
265             pStateSetHelper->AddState( AccessibleStateType::VISIBLE );
266             pStateSetHelper->AddState( AccessibleStateType::SHOWING );
267         }
268     }
269     else
270         pStateSetHelper->AddState( AccessibleStateType::DEFUNC );
271 
272     return pStateSetHelper;
273 }
274 
getLocale()275 Locale SAL_CALL VCLXAccessibleListItem::getLocale(  )
276 {
277     SolarMutexGuard aSolarGuard;
278     ::osl::MutexGuard aGuard( m_aMutex );
279 
280     return implGetLocale();
281 }
282 
283 // XAccessibleComponent
284 
containsPoint(const awt::Point & _aPoint)285 sal_Bool SAL_CALL VCLXAccessibleListItem::containsPoint( const awt::Point& _aPoint )
286 {
287     SolarMutexGuard aSolarGuard;
288     ::osl::MutexGuard aGuard( m_aMutex );
289 
290     bool bInside = false;
291     ::accessibility::IComboListBoxHelper* pListBoxHelper = m_xParent.is() ? m_xParent->getListBoxHelper() : nullptr;
292     if (pListBoxHelper)
293     {
294         tools::Rectangle aRect(pListBoxHelper->GetBoundingRectangle(static_cast<sal_uInt16>(m_nIndexInParent)));
295         aRect.Move(-aRect.Left(), -aRect.Top());
296         bInside = aRect.IsInside( VCLPoint( _aPoint ) );
297     }
298     return bInside;
299 }
300 
getAccessibleAtPoint(const awt::Point &)301 Reference< XAccessible > SAL_CALL VCLXAccessibleListItem::getAccessibleAtPoint( const awt::Point& )
302 {
303     return Reference< XAccessible >();
304 }
305 
getBounds()306 awt::Rectangle SAL_CALL VCLXAccessibleListItem::getBounds(  )
307 {
308     SolarMutexGuard aSolarGuard;
309     ::osl::MutexGuard aGuard( m_aMutex );
310 
311     awt::Rectangle aRect;
312     ::accessibility::IComboListBoxHelper* pListBoxHelper = m_xParent.is() ? m_xParent->getListBoxHelper() : nullptr;
313     if (pListBoxHelper)
314         aRect = AWTRectangle(pListBoxHelper->GetBoundingRectangle(static_cast<sal_uInt16>(m_nIndexInParent)));
315 
316     return aRect;
317 }
318 
getLocation()319 awt::Point SAL_CALL VCLXAccessibleListItem::getLocation(  )
320 {
321     SolarMutexGuard aSolarGuard;
322     ::osl::MutexGuard aGuard( m_aMutex );
323 
324     Point aPoint(0,0);
325     ::accessibility::IComboListBoxHelper* pListBoxHelper = m_xParent.is() ? m_xParent->getListBoxHelper() : nullptr;
326     if (pListBoxHelper)
327     {
328         tools::Rectangle aRect = pListBoxHelper->GetBoundingRectangle( static_cast<sal_uInt16>(m_nIndexInParent) );
329         aPoint = aRect.TopLeft();
330     }
331     return AWTPoint( aPoint );
332 }
333 
getLocationOnScreen()334 awt::Point SAL_CALL VCLXAccessibleListItem::getLocationOnScreen(  )
335 {
336     SolarMutexGuard aSolarGuard;
337     ::osl::MutexGuard aGuard( m_aMutex );
338 
339     Point aPoint(0,0);
340     ::accessibility::IComboListBoxHelper* pListBoxHelper = m_xParent.is() ? m_xParent->getListBoxHelper() : nullptr;
341     if (pListBoxHelper)
342     {
343         tools::Rectangle aRect = pListBoxHelper->GetBoundingRectangle(static_cast<sal_uInt16>(m_nIndexInParent));
344         aPoint = aRect.TopLeft();
345         aPoint += pListBoxHelper->GetWindowExtentsRelative().TopLeft();
346     }
347     return AWTPoint( aPoint );
348 }
349 
getSize()350 awt::Size SAL_CALL VCLXAccessibleListItem::getSize(  )
351 {
352     SolarMutexGuard aSolarGuard;
353     ::osl::MutexGuard aGuard( m_aMutex );
354 
355     Size aSize;
356     ::accessibility::IComboListBoxHelper* pListBoxHelper = m_xParent.is() ? m_xParent->getListBoxHelper() : nullptr;
357     if (pListBoxHelper)
358         aSize = pListBoxHelper->GetBoundingRectangle( static_cast<sal_uInt16>(m_nIndexInParent) ).GetSize();
359 
360     return AWTSize( aSize );
361 }
362 
grabFocus()363 void SAL_CALL VCLXAccessibleListItem::grabFocus(  )
364 {
365     // no focus for each item
366 }
367 
368 // XAccessibleText
369 
getCaretPosition()370 sal_Int32 SAL_CALL VCLXAccessibleListItem::getCaretPosition()
371 {
372     return -1;
373 }
374 
setCaretPosition(sal_Int32 nIndex)375 sal_Bool SAL_CALL VCLXAccessibleListItem::setCaretPosition( sal_Int32 nIndex )
376 {
377     SolarMutexGuard aSolarGuard;
378     ::osl::MutexGuard aGuard( m_aMutex );
379 
380     if ( !implIsValidRange( nIndex, nIndex, m_sEntryText.getLength() ) )
381         throw IndexOutOfBoundsException();
382 
383     return false;
384 }
385 
getCharacter(sal_Int32 nIndex)386 sal_Unicode SAL_CALL VCLXAccessibleListItem::getCharacter( sal_Int32 nIndex )
387 {
388     SolarMutexGuard aSolarGuard;
389     ::osl::MutexGuard aGuard( m_aMutex );
390 
391     return OCommonAccessibleText::implGetCharacter( m_sEntryText, nIndex );
392 }
393 
getCharacterAttributes(sal_Int32 nIndex,const Sequence<OUString> &)394 Sequence< PropertyValue > SAL_CALL VCLXAccessibleListItem::getCharacterAttributes( sal_Int32 nIndex, const Sequence< OUString >& )
395 {
396     SolarMutexGuard aSolarGuard;
397     ::osl::MutexGuard aGuard( m_aMutex );
398 
399     if ( !implIsValidIndex( nIndex, m_sEntryText.getLength() ) )
400         throw IndexOutOfBoundsException();
401 
402     return Sequence< PropertyValue >();
403 }
404 
getCharacterBounds(sal_Int32 nIndex)405 awt::Rectangle SAL_CALL VCLXAccessibleListItem::getCharacterBounds( sal_Int32 nIndex )
406 {
407     SolarMutexGuard aSolarGuard;
408     ::osl::MutexGuard aGuard( m_aMutex );
409 
410     if ( !implIsValidIndex( nIndex, m_sEntryText.getLength() ) )
411         throw IndexOutOfBoundsException();
412 
413     awt::Rectangle aBounds( 0, 0, 0, 0 );
414     ::accessibility::IComboListBoxHelper* pListBoxHelper = m_xParent.is() ? m_xParent->getListBoxHelper() : nullptr;
415     if (pListBoxHelper)
416     {
417         tools::Rectangle aCharRect = pListBoxHelper->GetEntryCharacterBounds( m_nIndexInParent, nIndex );
418         tools::Rectangle aItemRect = pListBoxHelper->GetBoundingRectangle( static_cast<sal_uInt16>(m_nIndexInParent) );
419         aCharRect.Move( -aItemRect.Left(), -aItemRect.Top() );
420         aBounds = AWTRectangle( aCharRect );
421     }
422 
423     return aBounds;
424 }
425 
getCharacterCount()426 sal_Int32 SAL_CALL VCLXAccessibleListItem::getCharacterCount()
427 {
428     SolarMutexGuard aSolarGuard;
429     ::osl::MutexGuard aGuard( m_aMutex );
430 
431     return m_sEntryText.getLength();
432 }
433 
getIndexAtPoint(const awt::Point & aPoint)434 sal_Int32 SAL_CALL VCLXAccessibleListItem::getIndexAtPoint( const awt::Point& aPoint )
435 {
436     SolarMutexGuard aSolarGuard;
437     ::osl::MutexGuard aGuard( m_aMutex );
438 
439     sal_Int32 nIndex = -1;
440     ::accessibility::IComboListBoxHelper* pListBoxHelper = m_xParent.is() ? m_xParent->getListBoxHelper() : nullptr;
441     if (pListBoxHelper)
442     {
443         sal_Int32 nPos = LISTBOX_ENTRY_NOTFOUND;
444         tools::Rectangle aItemRect = pListBoxHelper->GetBoundingRectangle( static_cast<sal_uInt16>(m_nIndexInParent) );
445         Point aPnt( VCLPoint( aPoint ) );
446         aPnt += aItemRect.TopLeft();
447         sal_Int32 nI = pListBoxHelper->GetIndexForPoint( aPnt, nPos );
448         if ( nI != -1 && m_nIndexInParent == nPos )
449             nIndex = nI;
450     }
451     return nIndex;
452 }
453 
getSelectedText()454 OUString SAL_CALL VCLXAccessibleListItem::getSelectedText()
455 {
456     SolarMutexGuard aSolarGuard;
457     ::osl::MutexGuard aGuard( m_aMutex );
458 
459     return OUString();
460 }
461 
getSelectionStart()462 sal_Int32 SAL_CALL VCLXAccessibleListItem::getSelectionStart()
463 {
464     SolarMutexGuard aSolarGuard;
465     ::osl::MutexGuard aGuard( m_aMutex );
466 
467     return 0;
468 }
469 
getSelectionEnd()470 sal_Int32 SAL_CALL VCLXAccessibleListItem::getSelectionEnd()
471 {
472     SolarMutexGuard aSolarGuard;
473     ::osl::MutexGuard aGuard( m_aMutex );
474 
475     return 0;
476 }
477 
setSelection(sal_Int32 nStartIndex,sal_Int32 nEndIndex)478 sal_Bool SAL_CALL VCLXAccessibleListItem::setSelection( sal_Int32 nStartIndex, sal_Int32 nEndIndex )
479 {
480     SolarMutexGuard aSolarGuard;
481     ::osl::MutexGuard aGuard( m_aMutex );
482 
483     if ( !implIsValidRange( nStartIndex, nEndIndex, m_sEntryText.getLength() ) )
484         throw IndexOutOfBoundsException();
485 
486     return false;
487 }
488 
getText()489 OUString SAL_CALL VCLXAccessibleListItem::getText()
490 {
491     SolarMutexGuard aSolarGuard;
492     ::osl::MutexGuard aGuard( m_aMutex );
493 
494     return m_sEntryText;
495 }
496 
getTextRange(sal_Int32 nStartIndex,sal_Int32 nEndIndex)497 OUString SAL_CALL VCLXAccessibleListItem::getTextRange( sal_Int32 nStartIndex, sal_Int32 nEndIndex )
498 {
499     SolarMutexGuard aSolarGuard;
500     ::osl::MutexGuard aGuard( m_aMutex );
501 
502     return OCommonAccessibleText::implGetTextRange( m_sEntryText, nStartIndex, nEndIndex );
503 }
504 
getTextAtIndex(sal_Int32 nIndex,sal_Int16 aTextType)505 css::accessibility::TextSegment SAL_CALL VCLXAccessibleListItem::getTextAtIndex( sal_Int32 nIndex, sal_Int16 aTextType )
506 {
507     SolarMutexGuard aSolarGuard;
508     ::osl::MutexGuard aGuard( m_aMutex );
509 
510     return OCommonAccessibleText::getTextAtIndex( nIndex, aTextType );
511 }
512 
getTextBeforeIndex(sal_Int32 nIndex,sal_Int16 aTextType)513 css::accessibility::TextSegment SAL_CALL VCLXAccessibleListItem::getTextBeforeIndex( sal_Int32 nIndex, sal_Int16 aTextType )
514 {
515     SolarMutexGuard aSolarGuard;
516     ::osl::MutexGuard aGuard( m_aMutex );
517 
518     return OCommonAccessibleText::getTextBeforeIndex( nIndex, aTextType );
519 }
520 
getTextBehindIndex(sal_Int32 nIndex,sal_Int16 aTextType)521 css::accessibility::TextSegment SAL_CALL VCLXAccessibleListItem::getTextBehindIndex( sal_Int32 nIndex, sal_Int16 aTextType )
522 {
523     SolarMutexGuard aSolarGuard;
524     ::osl::MutexGuard aGuard( m_aMutex );
525 
526     return OCommonAccessibleText::getTextBehindIndex( nIndex, aTextType );
527 }
528 
copyText(sal_Int32 nStartIndex,sal_Int32 nEndIndex)529 sal_Bool SAL_CALL VCLXAccessibleListItem::copyText( sal_Int32 nStartIndex, sal_Int32 nEndIndex )
530 {
531     SolarMutexGuard aSolarGuard;
532     ::osl::MutexGuard aGuard( m_aMutex );
533 
534     checkIndex_Impl( nStartIndex, m_sEntryText );
535     checkIndex_Impl( nEndIndex, m_sEntryText );
536 
537     bool bRet = false;
538     ::accessibility::IComboListBoxHelper* pListBoxHelper = m_xParent.is() ? m_xParent->getListBoxHelper() : nullptr;
539     if (pListBoxHelper)
540     {
541         Reference< datatransfer::clipboard::XClipboard > xClipboard = pListBoxHelper->GetClipboard();
542         if ( xClipboard.is() )
543         {
544             OUString sText( getTextRange( nStartIndex, nEndIndex ) );
545             rtl::Reference<vcl::unohelper::TextDataObject> pDataObj = new vcl::unohelper::TextDataObject( sText );
546 
547             SolarMutexReleaser aReleaser;
548             xClipboard->setContents( pDataObj, nullptr );
549             Reference< datatransfer::clipboard::XFlushableClipboard > xFlushableClipboard( xClipboard, uno::UNO_QUERY );
550             if( xFlushableClipboard.is() )
551                 xFlushableClipboard->flushClipboard();
552 
553             bRet = true;
554         }
555     }
556 
557     return bRet;
558 }
559 
scrollSubstringTo(sal_Int32,sal_Int32,AccessibleScrollType)560 sal_Bool VCLXAccessibleListItem::scrollSubstringTo( sal_Int32, sal_Int32, AccessibleScrollType )
561 {
562     return false;
563 }
564 
565 // XAccessibleEventBroadcaster
566 
addAccessibleEventListener(const Reference<XAccessibleEventListener> & xListener)567 void SAL_CALL VCLXAccessibleListItem::addAccessibleEventListener( const Reference< XAccessibleEventListener >& xListener )
568 {
569     if (xListener.is())
570     {
571         if (!m_nClientId)
572             m_nClientId = comphelper::AccessibleEventNotifier::registerClient( );
573         comphelper::AccessibleEventNotifier::addEventListener( m_nClientId, xListener );
574     }
575 }
576 
removeAccessibleEventListener(const Reference<XAccessibleEventListener> & xListener)577 void SAL_CALL VCLXAccessibleListItem::removeAccessibleEventListener( const Reference< XAccessibleEventListener >& xListener )
578 {
579     if ( !(xListener.is() && m_nClientId) )
580         return;
581 
582     sal_Int32 nListenerCount = comphelper::AccessibleEventNotifier::removeEventListener( m_nClientId, xListener );
583     if ( nListenerCount )
584         return;
585 
586     // no listeners anymore
587     // -> revoke ourself. This may lead to the notifier thread dying (if we were the last client),
588     // and at least to us not firing any events anymore, in case somebody calls
589     // NotifyAccessibleEvent, again
590     if ( m_nClientId )
591     {
592         comphelper::AccessibleEventNotifier::TClientId nId( m_nClientId );
593         m_nClientId = 0;
594         comphelper::AccessibleEventNotifier::revokeClient( nId );
595     }
596 }
597 
598 
599 // AF (Oct. 29 2002): Return black as constant foreground color.  This is an
600 // initial implementation and has to be substituted by code that determines
601 // the color that is actually used.
getForeground()602 sal_Int32 SAL_CALL VCLXAccessibleListItem::getForeground()
603 {
604     return sal_Int32(COL_BLACK);
605 }
606 
607 // AF (Oct. 29 2002): Return white as constant background color.  This is an
608 // initial implementation and has to be substituted by code that determines
609 // the color that is actually used.
getBackground()610 sal_Int32 SAL_CALL VCLXAccessibleListItem::getBackground()
611 {
612     return sal_Int32(COL_WHITE);
613 }
614 
615 
616 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
617