Bug Summary

File:home/maarten/src/libreoffice/core/include/rtl/ref.hxx
Warning:line 113, column 13
Use of memory after it is freed

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name vclxaccessiblelist.cxx -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -mframe-pointer=all -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib64/clang/11.0.0 -D BOOST_ERROR_CODE_HEADER_ONLY -D BOOST_SYSTEM_NO_DEPRECATED -D CPPU_ENV=gcc3 -D LINUX -D OSL_DEBUG_LEVEL=1 -D SAL_LOG_INFO -D SAL_LOG_WARN -D UNIX -D UNX -D X86_64 -D _PTHREADS -D _REENTRANT -D VCL_INTERNALS -D EXCEPTIONS_ON -D LIBO_INTERNAL_ONLY -I /home/maarten/src/libreoffice/core/external/boost/include -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/boost -I /home/maarten/src/libreoffice/core/include -I /usr/lib/jvm/java-11-openjdk-11.0.9.10-0.0.ea.fc33.x86_64/include -I /usr/lib/jvm/java-11-openjdk-11.0.9.10-0.0.ea.fc33.x86_64/include/linux -I /home/maarten/src/libreoffice/core/config_host -I /home/maarten/src/libreoffice/core/accessibility/inc -I /home/maarten/src/libreoffice/core/accessibility/source/inc -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/udkapi/normal -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/offapi/normal -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10 -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/x86_64-redhat-linux -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/backward -internal-isystem /usr/local/include -internal-isystem /usr/lib64/clang/11.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O0 -Wno-missing-braces -std=c++17 -fdeprecated-macro -fdebug-compilation-dir /home/maarten/src/libreoffice/core -ferror-limit 19 -fvisibility hidden -fvisibility-inlines-hidden -stack-protector 2 -fgnuc-version=4.2.1 -fcxx-exceptions -fexceptions -debug-info-kind=constructor -analyzer-output=html -faddrsig -o /home/maarten/tmp/wis/scan-build-libreoffice/output/report/2020-10-07-141433-9725-1 -x c++ /home/maarten/src/libreoffice/core/accessibility/source/standard/vclxaccessiblelist.cxx

/home/maarten/src/libreoffice/core/accessibility/source/standard/vclxaccessiblelist.cxx

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/vclxaccessiblelist.hxx>
21#include <standard/vclxaccessiblelistitem.hxx>
22#include <helper/listboxhelper.hxx>
23
24#include <unotools/accessiblerelationsethelper.hxx>
25#include <unotools/accessiblestatesethelper.hxx>
26#include <com/sun/star/accessibility/AccessibleStateType.hpp>
27#include <com/sun/star/accessibility/AccessibleEventId.hpp>
28#include <com/sun/star/accessibility/AccessibleRelationType.hpp>
29#include <com/sun/star/accessibility/AccessibleRole.hpp>
30#include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
31#include <o3tl/safeint.hxx>
32#include <vcl/svapp.hxx>
33#include <vcl/toolkit/combobox.hxx>
34#include <vcl/toolkit/lstbox.hxx>
35#include <toolkit/helper/convert.hxx>
36
37using namespace ::com::sun::star;
38using namespace ::com::sun::star::uno;
39using namespace ::com::sun::star::lang;
40using namespace ::com::sun::star::beans;
41using namespace ::com::sun::star::accessibility;
42using namespace ::accessibility;
43
44namespace
45{
46 /// @throws css::lang::IndexOutOfBoundsException
47 void checkSelection_Impl( sal_Int32 _nIndex, const IComboListBoxHelper& _rListBox, bool bSelected )
48 {
49 sal_Int32 nCount = bSelected ? _rListBox.GetSelectedEntryCount()
50 : _rListBox.GetEntryCount();
51 if ( _nIndex < 0 || _nIndex >= nCount )
52 throw css::lang::IndexOutOfBoundsException();
53 }
54}
55
56VCLXAccessibleList::VCLXAccessibleList (VCLXWindow* pVCLWindow, BoxType aBoxType,
57 const Reference< XAccessible >& _xParent)
58 : VCLXAccessibleComponent (pVCLWindow),
59 m_aBoxType (aBoxType),
60 m_nVisibleLineCount (0),
61 m_nIndexInParent (DEFAULT_INDEX_IN_PARENT),
62 m_nLastTopEntry ( 0 ),
63 m_nLastSelectedPos ( LISTBOX_ENTRY_NOTFOUND(((sal_Int32) 0x7FFFFFFF)) ),
64 m_bDisableProcessEvent ( false ),
65 m_bVisible ( true ),
66 m_nCurSelectedPos ( LISTBOX_ENTRY_NOTFOUND(((sal_Int32) 0x7FFFFFFF)) ),
67 m_xParent ( _xParent )
68{
69 // Because combo boxes and list boxes don't have a common interface for
70 // methods with identical signature we have to write down twice the
71 // same code.
72 switch (m_aBoxType)
73 {
74 case COMBOBOX:
75 {
76 VclPtr< ComboBox > pBox = GetAs< ComboBox >();
77 if ( pBox )
78 m_pListBoxHelper.reset( new VCLListBoxHelper<ComboBox> (*pBox) );
79 break;
80 }
81
82 case LISTBOX:
83 {
84 VclPtr< ListBox > pBox = GetAs< ListBox >();
85 if ( pBox )
86 m_pListBoxHelper.reset( new VCLListBoxHelper<ListBox> (*pBox) );
87 break;
88 }
89 }
90 UpdateVisibleLineCount();
91 if(m_pListBoxHelper)
92 {
93 m_nCurSelectedPos=m_pListBoxHelper->GetSelectedEntryPos(0);
94 }
95 sal_uInt16 nCount = static_cast<sal_uInt16>(getAccessibleChildCount());
96 m_aAccessibleChildren.reserve(nCount);
97}
98
99
100void VCLXAccessibleList::SetIndexInParent (sal_Int32 nIndex)
101{
102 m_nIndexInParent = nIndex;
103}
104
105
106void SAL_CALL VCLXAccessibleList::disposing()
107{
108 VCLXAccessibleComponent::disposing();
109
110 // Dispose all items in the list.
111 m_aAccessibleChildren.clear();
112
113 m_pListBoxHelper.reset();
114}
115
116
117void VCLXAccessibleList::FillAccessibleStateSet (utl::AccessibleStateSetHelper& rStateSet)
118{
119 SolarMutexGuard aSolarGuard;
120
121 VCLXAccessibleComponent::FillAccessibleStateSet( rStateSet );
122 // check if our list should be visible
123 if ( m_pListBoxHelper
124 && (m_pListBoxHelper->GetStyle() & WB_DROPDOWN ) == WB_DROPDOWN
125 && !m_pListBoxHelper->IsInDropDown() )
126 {
127 rStateSet.RemoveState (AccessibleStateType::VISIBLE);
128 rStateSet.RemoveState (AccessibleStateType::SHOWING);
129 m_bVisible = false;
130 }
131
132 // Both the combo box and list box are handled identical in the
133 // following but for some reason they don't have a common interface for
134 // the methods used.
135 if ( m_pListBoxHelper )
136 {
137 if ( m_pListBoxHelper->IsMultiSelectionEnabled() )
138 rStateSet.AddState( AccessibleStateType::MULTI_SELECTABLE);
139 rStateSet.AddState (AccessibleStateType::FOCUSABLE);
140 // All children are transient.
141 rStateSet.AddState (AccessibleStateType::MANAGES_DESCENDANTS);
142 }
143}
144
145void VCLXAccessibleList::notifyVisibleStates(bool _bSetNew )
146{
147 m_bVisible = _bSetNew;
148 Any aOldValue, aNewValue;
149 (_bSetNew ? aNewValue : aOldValue ) <<= AccessibleStateType::VISIBLE;
150 NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );
151 (_bSetNew ? aNewValue : aOldValue ) <<= AccessibleStateType::SHOWING;
152 NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );
153
154 ListItems::iterator aIter = m_aAccessibleChildren.begin();
155 UpdateVisibleLineCount();
156 // adjust the index inside the VCLXAccessibleListItem
157 for ( ; aIter != m_aAccessibleChildren.end(); )
158 {
159 Reference< XAccessible > xHold = *aIter;
160 if (!xHold.is())
161 {
162 aIter = m_aAccessibleChildren.erase(aIter);
163 }
164 else
165 {
166 VCLXAccessibleListItem* pItem = static_cast<VCLXAccessibleListItem*>(xHold.get());
167 const sal_Int32 nTopEntry = m_pListBoxHelper ? m_pListBoxHelper->GetTopEntry() : 0;
168 const sal_Int32 nPos = static_cast<sal_Int32>(aIter - m_aAccessibleChildren.begin());
169 bool bVisible = ( nPos>=nTopEntry && nPos<( nTopEntry + m_nVisibleLineCount ) );
170 pItem->SetVisible( m_bVisible && bVisible );
171 ++aIter;
172 }
173
174 }
175}
176
177void VCLXAccessibleList::UpdateSelection_Acc (const OUString& /*sTextOfSelectedItem*/, bool b_IsDropDownList)
178{
179 if ( m_aBoxType != COMBOBOX )
180 return;
181
182 /* FIXME: is there something missing here? nIndex is unused. Looks like
183 * copy-paste from VCLXAccessibleList::UpdateSelection() */
184 // VclPtr< ComboBox > pBox = GetAs< ComboBox >();
185 // if ( pBox )
186 // {
187 // // Find the index of the selected item inside the VCL control...
188 // sal_Int32 nIndex = pBox->GetEntryPos(sTextOfSelectedItem);
189 // // ...and then find the associated accessibility object.
190 // if ( nIndex == LISTBOX_ENTRY_NOTFOUND )
191 // nIndex = 0;
192 UpdateSelection_Impl_Acc(b_IsDropDownList);
193 // }
194}
195
196
197void VCLXAccessibleList::UpdateSelection_Impl_Acc(bool bHasDropDownList)
198{
199 uno::Any aOldValue, aNewValue;
200
201 {
202 SolarMutexGuard aSolarGuard;
203 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
204 Reference< XAccessible > xNewAcc;
205 if ( m_pListBoxHelper )
206 {
207 sal_Int32 i=0;
208 m_nCurSelectedPos = LISTBOX_ENTRY_NOTFOUND(((sal_Int32) 0x7FFFFFFF));
209 for ( const auto& rChild : m_aAccessibleChildren )
210 {
211 Reference< XAccessible > xHold = rChild;
212 if ( xHold.is() )
213 {
214 VCLXAccessibleListItem* pItem = static_cast< VCLXAccessibleListItem* >( xHold.get() );
215 // Retrieve the item's index from the list entry.
216 bool bNowSelected = m_pListBoxHelper->IsEntryPosSelected (i);
217 if (bNowSelected)
218 m_nCurSelectedPos = i;
219
220 if ( bNowSelected && !pItem->IsSelected() )
221 {
222 xNewAcc = rChild;
223 aNewValue <<= xNewAcc;
224 }
225 else if ( pItem->IsSelected() )
226 m_nLastSelectedPos = i;
227
228 pItem->SetSelected( bNowSelected );
229 }
230 else
231 { // it could happen that a child was not created before
232 checkEntrySelected(i,aNewValue,xNewAcc);
233 }
234 ++i;
235 }
236 const sal_Int32 nCount = m_pListBoxHelper->GetEntryCount();
237 if ( i < nCount ) // here we have to check the if any other listbox entry is selected
238 {
239 for (; i < nCount && !checkEntrySelected(i,aNewValue,xNewAcc) ;++i )
240 ;
241 }
242 if ( xNewAcc.is() && GetWindow()->HasFocus() )
243 {
244 if ( m_nLastSelectedPos != LISTBOX_ENTRY_NOTFOUND(((sal_Int32) 0x7FFFFFFF)) )
245 aOldValue <<= getAccessibleChild( m_nLastSelectedPos );
246 aNewValue <<= xNewAcc;
247 }
248 }
249 }
250
251 if (m_aBoxType == COMBOBOX)
252 {
253 //VCLXAccessibleDropDownComboBox
254 //when in list is dropped down, xText = NULL
255 if (bHasDropDownList && m_pListBoxHelper && m_pListBoxHelper->IsInDropDown())
256 {
257 if ( aNewValue.hasValue() || aOldValue.hasValue() )
258 {
259 NotifyAccessibleEvent(
260 AccessibleEventId::ACTIVE_DESCENDANT_CHANGED,
261 aOldValue,
262 aNewValue );
263
264 NotifyListItem(aNewValue);
265 }
266 }
267 else
268 {
269 //VCLXAccessibleComboBox
270 NotifyAccessibleEvent( AccessibleEventId::SELECTION_CHANGED, uno::Any(), uno::Any() );
271 }
272 }
273 else if (m_aBoxType == LISTBOX)
274 {
275 if ( aNewValue.hasValue() || aOldValue.hasValue() )
276 {
277 NotifyAccessibleEvent(
278 AccessibleEventId::ACTIVE_DESCENDANT_CHANGED,
279 aOldValue,
280 aNewValue );
281
282 NotifyListItem(aNewValue);
283 }
284 }
285}
286
287void VCLXAccessibleList::NotifyListItem(css::uno::Any const & val)
288{
289 Reference< XAccessible > xCurItem;
290 val >>= xCurItem;
291 if (xCurItem.is())
292 {
293 VCLXAccessibleListItem* pCurItem = static_cast< VCLXAccessibleListItem* >(xCurItem.get());
294 if (pCurItem)
295 {
296 pCurItem->NotifyAccessibleEvent(AccessibleEventId::SELECTION_CHANGED,Any(),Any());
297 }
298 }
299}
300
301void VCLXAccessibleList::ProcessWindowEvent (const VclWindowEvent& rVclWindowEvent, bool b_IsDropDownList)
302{
303 switch ( rVclWindowEvent.GetId() )
304 {
305 case VclEventId::DropdownSelect:
306 case VclEventId::ListboxSelect:
307 if ( !m_bDisableProcessEvent )
308 UpdateSelection_Impl_Acc(b_IsDropDownList);
309 break;
310 case VclEventId::WindowGetFocus:
311 break;
312 case VclEventId::ControlGetFocus:
313 {
314 VCLXAccessibleComponent::ProcessWindowEvent (rVclWindowEvent);
315 if (m_aBoxType == COMBOBOX && b_IsDropDownList)
316 {
317 //VCLXAccessibleDropDownComboBox
318 }
319 else if (m_aBoxType == LISTBOX && b_IsDropDownList)
320 {
321 }
322 else if ( m_aBoxType == LISTBOX && !b_IsDropDownList)
323 {
324 if ( m_pListBoxHelper )
325 {
326 uno::Any aOldValue,
327 aNewValue;
328 sal_Int32 nPos = m_nCurSelectedPos; //m_pListBoxHelper->GetSelectedEntryPos();
329
330 if ( nPos == LISTBOX_ENTRY_NOTFOUND(((sal_Int32) 0x7FFFFFFF)) )
331 nPos = m_pListBoxHelper->GetTopEntry();
332 if ( nPos != LISTBOX_ENTRY_NOTFOUND(((sal_Int32) 0x7FFFFFFF)) )
333 aNewValue <<= CreateChild(nPos);
334 NotifyAccessibleEvent( AccessibleEventId::ACTIVE_DESCENDANT_CHANGED,
335 aOldValue,
336 aNewValue );
337 }
338 }
339 }
340 break;
341 default:
342 break;
343 }
344
345}
346
347void VCLXAccessibleList::ProcessWindowEvent (const VclWindowEvent& rVclWindowEvent)
348{
349 // Create a reference to this object to prevent an early release of the
350 // listbox (VclEventId::ObjectDying).
351 Reference< XAccessible > xHoldAlive = this;
352
353 switch ( rVclWindowEvent.GetId() )
354 {
355 case VclEventId::DropdownOpen:
356 notifyVisibleStates(true);
357 break;
358 case VclEventId::DropdownClose:
359 notifyVisibleStates(false);
360 break;
361 case VclEventId::ListboxScrolled:
362 UpdateEntryRange_Impl();
363 break;
364
365 // The selection events VclEventId::ComboboxSelect and
366 // VclEventId::ComboboxDeselect are not handled here because here we
367 // have no access to the edit field. Its text is necessary to
368 // identify the currently selected item.
369
370 case VclEventId::ObjectDying:
371 {
372 dispose();
373
374 VCLXAccessibleComponent::ProcessWindowEvent (rVclWindowEvent);
375 break;
376 }
377
378 case VclEventId::ListboxItemRemoved:
379 case VclEventId::ComboboxItemRemoved:
380 case VclEventId::ListboxItemAdded:
381 case VclEventId::ComboboxItemAdded:
382 HandleChangedItemList();
383 break;
384 case VclEventId::ControlGetFocus:
385 {
386 VCLXAccessibleComponent::ProcessWindowEvent (rVclWindowEvent);
387 // Added by IBM Symphony Acc team to handle the list item focus when List control get focus
388 bool b_IsDropDownList = true;
389 if (m_pListBoxHelper)
390 b_IsDropDownList = ((m_pListBoxHelper->GetStyle() & WB_DROPDOWN ) == WB_DROPDOWN);
391 if ( m_aBoxType == LISTBOX && !b_IsDropDownList )
392 {
393 if ( m_pListBoxHelper )
394 {
395 uno::Any aOldValue,
396 aNewValue;
397 sal_Int32 nPos = m_nCurSelectedPos;
398
399 if ( nPos == LISTBOX_ENTRY_NOTFOUND(((sal_Int32) 0x7FFFFFFF)) )
400 nPos = m_pListBoxHelper->GetTopEntry();
401 if ( nPos != LISTBOX_ENTRY_NOTFOUND(((sal_Int32) 0x7FFFFFFF)) )
402 aNewValue <<= CreateChild(nPos);
403 NotifyAccessibleEvent( AccessibleEventId::ACTIVE_DESCENDANT_CHANGED,
404 aOldValue,
405 aNewValue );
406 }
407 }
408 }
409 break;
410
411 default:
412 VCLXAccessibleComponent::ProcessWindowEvent (rVclWindowEvent);
413 }
414}
415
416 void VCLXAccessibleList::FillAccessibleRelationSet( utl::AccessibleRelationSetHelper& rRelationSet )
417{
418 VclPtr< ListBox > pBox = GetAs< ListBox >();
1
Calling 'VCLXAccessibleComponent::GetAs'
18
Returning; memory was released
419 if( m_aBoxType == LISTBOX )
19
Assuming field 'm_aBoxType' is not equal to LISTBOX
20
Taking false branch
420 {
421 if (m_pListBoxHelper && (m_pListBoxHelper->GetStyle() & WB_DROPDOWN ) != WB_DROPDOWN)
422 {
423 uno::Sequence< uno::Reference< uno::XInterface > > aSequence { pBox->GetAccessible() };
424 rRelationSet.AddRelation( com::sun::star::accessibility::AccessibleRelation( com::sun::star::accessibility::AccessibleRelationType::MEMBER_OF, aSequence ) );
425 }
426 }
427 else
428 {
429 VCLXAccessibleComponent::FillAccessibleRelationSet(rRelationSet);
430 }
431}
21
Calling implicit destructor for 'VclPtr<ListBox>'
22
Calling '~Reference'
432
433
434/** To find out which item is currently selected and to update the SELECTED
435 state of the associated accessibility objects accordingly we exploit the
436 fact that the
437*/
438void VCLXAccessibleList::UpdateSelection (const OUString& sTextOfSelectedItem)
439{
440 if ( m_aBoxType != COMBOBOX )
441 return;
442
443 VclPtr< ComboBox > pBox = GetAs< ComboBox >();
444 if ( pBox )
445 {
446 // Find the index of the selected item inside the VCL control...
447 sal_Int32 nIndex = pBox->GetEntryPos(sTextOfSelectedItem);
448 // ...and then find the associated accessibility object.
449 if ( nIndex == LISTBOX_ENTRY_NOTFOUND(((sal_Int32) 0x7FFFFFFF)) )
450 nIndex = 0;
451 UpdateSelection_Impl(nIndex);
452 }
453}
454
455
456Reference<XAccessible> VCLXAccessibleList::CreateChild (sal_Int32 nPos)
457{
458 Reference<XAccessible> xChild;
459
460 if ( o3tl::make_unsigned(nPos) >= m_aAccessibleChildren.size() )
461 {
462 m_aAccessibleChildren.resize(nPos + 1);
463
464 // insert into the container
465 xChild = new VCLXAccessibleListItem(nPos, this);
466 m_aAccessibleChildren[nPos] = xChild;
467 }
468 else
469 {
470 xChild = m_aAccessibleChildren[nPos];
471 // check if position is empty and can be used else we have to adjust all entries behind this
472 if (!xChild.is())
473 {
474 xChild = new VCLXAccessibleListItem(nPos, this);
475 m_aAccessibleChildren[nPos] = xChild;
476 }
477 }
478
479 if ( xChild.is() )
480 {
481 // Just add the SELECTED state.
482 bool bNowSelected = false;
483 if ( m_pListBoxHelper )
484 bNowSelected = m_pListBoxHelper->IsEntryPosSelected(nPos);
485 if (bNowSelected)
486 m_nCurSelectedPos = nPos;
487 VCLXAccessibleListItem* pItem = static_cast< VCLXAccessibleListItem* >(xChild.get());
488 pItem->SetSelected( bNowSelected );
489
490 // Set the child's VISIBLE state.
491 UpdateVisibleLineCount();
492 const sal_Int32 nTopEntry = m_pListBoxHelper ? m_pListBoxHelper->GetTopEntry() : 0;
493 bool bVisible = ( nPos>=nTopEntry && nPos<( nTopEntry + m_nVisibleLineCount ) );
494 pItem->SetVisible( m_bVisible && bVisible );
495 }
496
497 return xChild;
498}
499
500
501void VCLXAccessibleList::HandleChangedItemList()
502{
503 m_aAccessibleChildren.clear();
504 NotifyAccessibleEvent (
505 AccessibleEventId::INVALIDATE_ALL_CHILDREN,
506 Any(), Any());
507}
508
509
510IMPLEMENT_FORWARD_XINTERFACE2(VCLXAccessibleList, VCLXAccessibleComponent, VCLXAccessibleList_BASE)void VCLXAccessibleList::acquire() throw() { VCLXAccessibleComponent
::acquire(); } void VCLXAccessibleList::release() throw() { VCLXAccessibleComponent
::release(); } css::uno::Any VCLXAccessibleList::queryInterface
( const css::uno::Type& _rType ) { css::uno::Any aReturn =
VCLXAccessibleComponent::queryInterface( _rType ); if ( !aReturn
.hasValue() ) aReturn = VCLXAccessibleList_BASE::queryInterface
( _rType ); return aReturn; }
511IMPLEMENT_FORWARD_XTYPEPROVIDER2(VCLXAccessibleList, VCLXAccessibleComponent, VCLXAccessibleList_BASE)css::uno::Sequence< css::uno::Type > VCLXAccessibleList
::getTypes( ) { return ::comphelper::concatSequences( VCLXAccessibleComponent
::getTypes(), VCLXAccessibleList_BASE::getTypes() ); } css::uno
::Sequence< sal_Int8 > VCLXAccessibleList::getImplementationId
( ) { return css::uno::Sequence<sal_Int8>(); }
512
513// XAccessible
514
515Reference<XAccessibleContext> SAL_CALL
516 VCLXAccessibleList::getAccessibleContext()
517{
518 return this;
519}
520
521
522// XAccessibleContext
523
524sal_Int32 SAL_CALL VCLXAccessibleList::getAccessibleChildCount()
525{
526 SolarMutexGuard aSolarGuard;
527 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
528 return implGetAccessibleChildCount();
529}
530
531sal_Int32 VCLXAccessibleList::implGetAccessibleChildCount()
532{
533 sal_Int32 nCount = 0;
534 if ( m_pListBoxHelper )
535 nCount = m_pListBoxHelper->GetEntryCount();
536
537 return nCount;
538}
539
540Reference<XAccessible> SAL_CALL VCLXAccessibleList::getAccessibleChild (sal_Int32 i)
541{
542 SolarMutexGuard aSolarGuard;
543 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
544
545 if ( i < 0 || i >= getAccessibleChildCount() )
546 throw IndexOutOfBoundsException();
547
548 Reference< XAccessible > xChild;
549 // search for the child
550 if ( i >= static_cast<sal_Int32>(m_aAccessibleChildren.size()) )
551 xChild = CreateChild (i);
552 else
553 {
554 xChild = m_aAccessibleChildren[i];
555 if ( !xChild.is() )
556 xChild = CreateChild (i);
557 }
558 OSL_ENSURE( xChild.is(), "VCLXAccessibleList::getAccessibleChild: returning empty child!" )do { if (true && (!(xChild.is()))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/accessibility/source/standard/vclxaccessiblelist.cxx"
":" "558" ": "), "%s", "VCLXAccessibleList::getAccessibleChild: returning empty child!"
); } } while (false)
;
559 return xChild;
560}
561
562Reference< XAccessible > SAL_CALL VCLXAccessibleList::getAccessibleParent( )
563{
564 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
565
566 return m_xParent;
567}
568
569sal_Int32 SAL_CALL VCLXAccessibleList::getAccessibleIndexInParent()
570{
571 if (m_nIndexInParent != DEFAULT_INDEX_IN_PARENT)
572 return m_nIndexInParent;
573 else
574 return VCLXAccessibleComponent::getAccessibleIndexInParent();
575}
576
577sal_Int16 SAL_CALL VCLXAccessibleList::getAccessibleRole()
578{
579 return AccessibleRole::LIST;
580}
581
582// XServiceInfo
583OUString VCLXAccessibleList::getImplementationName()
584{
585 return "com.sun.star.comp.toolkit.AccessibleList";
586}
587
588Sequence< OUString > VCLXAccessibleList::getSupportedServiceNames()
589{
590 return comphelper::concatSequences(VCLXAccessibleComponent::getSupportedServiceNames(),
591 Sequence<OUString>{"com.sun.star.accessibility.AccessibleList"});
592}
593
594void VCLXAccessibleList::UpdateVisibleLineCount()
595{
596 if ( m_pListBoxHelper )
597 {
598 if ( (m_pListBoxHelper->GetStyle() & WB_DROPDOWN ) == WB_DROPDOWN )
599 m_nVisibleLineCount = m_pListBoxHelper->GetDisplayLineCount();
600 else
601 {
602 sal_uInt16 nCols = 0,
603 nLines = 0;
604 m_pListBoxHelper->GetMaxVisColumnsAndLines (nCols, nLines);
605 m_nVisibleLineCount = nLines;
606 }
607 }
608}
609
610void VCLXAccessibleList::UpdateEntryRange_Impl()
611{
612 SolarMutexGuard aSolarGuard;
613 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
614
615 sal_Int32 nTop = m_nLastTopEntry;
616
617 if ( m_pListBoxHelper )
618 nTop = m_pListBoxHelper->GetTopEntry();
619 if ( nTop != m_nLastTopEntry )
620 {
621 UpdateVisibleLineCount();
622 sal_Int32 nBegin = std::min( m_nLastTopEntry, nTop );
623 sal_Int32 nEnd = std::max( m_nLastTopEntry + m_nVisibleLineCount, nTop + m_nVisibleLineCount );
624 for (sal_Int32 i = nBegin; (i <= nEnd); ++i)
625 {
626 bool bVisible = ( i >= nTop && i < ( nTop + m_nVisibleLineCount ) );
627 Reference< XAccessible > xHold;
628 if ( o3tl::make_unsigned(i) < m_aAccessibleChildren.size() )
629 xHold = m_aAccessibleChildren[i];
630 else if ( bVisible )
631 xHold = CreateChild(i);
632
633 if ( xHold.is() )
634 static_cast< VCLXAccessibleListItem* >( xHold.get() )->SetVisible( m_bVisible && bVisible );
635 }
636 }
637
638 m_nLastTopEntry = nTop;
639}
640
641bool VCLXAccessibleList::checkEntrySelected(sal_Int32 _nPos,Any& _rNewValue,Reference< XAccessible >& _rxNewAcc)
642{
643 OSL_ENSURE(m_pListBoxHelper,"Helper is not valid!")do { if (true && (!(m_pListBoxHelper))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/accessibility/source/standard/vclxaccessiblelist.cxx"
":" "643" ": "), "%s", "Helper is not valid!"); } } while (false
)
;
644 bool bNowSelected = false;
645 if ( m_pListBoxHelper )
646 {
647 bNowSelected = m_pListBoxHelper->IsEntryPosSelected (_nPos);
648 if ( bNowSelected )
649 {
650 _rxNewAcc = CreateChild(_nPos);
651 _rNewValue <<= _rxNewAcc;
652 }
653 }
654 return bNowSelected;
655}
656
657
658void VCLXAccessibleList::UpdateSelection_Impl(sal_Int32)
659{
660 uno::Any aOldValue, aNewValue;
661
662 {
663 SolarMutexGuard aSolarGuard;
664 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
665 Reference< XAccessible > xNewAcc;
666
667 if ( m_pListBoxHelper )
668 {
669 sal_Int32 i=0;
670 m_nCurSelectedPos = LISTBOX_ENTRY_NOTFOUND(((sal_Int32) 0x7FFFFFFF));
671 for ( const auto& rChild : m_aAccessibleChildren )
672 {
673 Reference< XAccessible > xHold = rChild;
674 if ( xHold.is() )
675 {
676 VCLXAccessibleListItem* pItem = static_cast< VCLXAccessibleListItem* >( xHold.get() );
677 // Retrieve the item's index from the list entry.
678 bool bNowSelected = m_pListBoxHelper->IsEntryPosSelected (i);
679 if (bNowSelected)
680 m_nCurSelectedPos = i;
681
682 if ( bNowSelected && !pItem->IsSelected() )
683 {
684 xNewAcc = rChild;
685 aNewValue <<= xNewAcc;
686 }
687 else if ( pItem->IsSelected() )
688 m_nLastSelectedPos = i;
689
690 pItem->SetSelected( bNowSelected );
691 }
692 else
693 { // it could happen that a child was not created before
694 checkEntrySelected(i,aNewValue,xNewAcc);
695 }
696 ++i;
697 }
698 const sal_Int32 nCount = m_pListBoxHelper->GetEntryCount();
699 if ( i < nCount ) // here we have to check the if any other listbox entry is selected
700 {
701 for (; i < nCount && !checkEntrySelected(i,aNewValue,xNewAcc) ;++i )
702 ;
703 }
704 if ( xNewAcc.is() && GetWindow()->HasFocus() )
705 {
706 if ( m_nLastSelectedPos != LISTBOX_ENTRY_NOTFOUND(((sal_Int32) 0x7FFFFFFF)) )
707 aOldValue <<= getAccessibleChild( m_nLastSelectedPos );
708 aNewValue <<= xNewAcc;
709 }
710 if (m_pListBoxHelper->IsInDropDown())
711 {
712 if ( aNewValue.hasValue() || aOldValue.hasValue() )
713 NotifyAccessibleEvent(
714 AccessibleEventId::ACTIVE_DESCENDANT_CHANGED,
715 aOldValue,
716 aNewValue );
717 //the SELECTION_CHANGED is not necessary
718 //NotifyAccessibleEvent( AccessibleEventId::SELECTION_CHANGED, Any(), Any() );
719 }
720 }
721 }
722}
723
724
725// XAccessibleSelection
726
727void SAL_CALL VCLXAccessibleList::selectAccessibleChild( sal_Int32 nChildIndex )
728{
729 bool bNotify = false;
730
731 {
732 SolarMutexGuard aSolarGuard;
733 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
734
735 if ( m_pListBoxHelper )
736 {
737 checkSelection_Impl(nChildIndex,*m_pListBoxHelper,false);
738
739 m_pListBoxHelper->SelectEntryPos( static_cast<sal_uInt16>(nChildIndex) );
740 // call the select handler, don't handle events in this time
741 m_bDisableProcessEvent = true;
742 m_pListBoxHelper->Select();
743 m_bDisableProcessEvent = false;
744 bNotify = true;
745 }
746 }
747
748 if ( bNotify )
749 UpdateSelection_Impl();
750}
751
752sal_Bool SAL_CALL VCLXAccessibleList::isAccessibleChildSelected( sal_Int32 nChildIndex )
753{
754 SolarMutexGuard aSolarGuard;
755 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
756
757 bool bRet = false;
758 if ( m_pListBoxHelper )
759 {
760 checkSelection_Impl(nChildIndex,*m_pListBoxHelper,false);
761
762 bRet = m_pListBoxHelper->IsEntryPosSelected( static_cast<sal_uInt16>(nChildIndex) );
763 }
764 return bRet;
765}
766
767void SAL_CALL VCLXAccessibleList::clearAccessibleSelection( )
768{
769 bool bNotify = false;
770
771 {
772 SolarMutexGuard aSolarGuard;
773 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
774
775 if ( m_pListBoxHelper )
776 {
777 m_pListBoxHelper->SetNoSelection();
778 bNotify = true;
779 }
780 }
781
782 if ( bNotify )
783 UpdateSelection_Impl();
784}
785
786void SAL_CALL VCLXAccessibleList::selectAllAccessibleChildren( )
787{
788 bool bNotify = false;
789
790 {
791 SolarMutexGuard aSolarGuard;
792 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
793
794 if ( m_pListBoxHelper )
795 {
796 const sal_Int32 nCount = m_pListBoxHelper->GetEntryCount();
797 for ( sal_Int32 i = 0; i < nCount; ++i )
798 m_pListBoxHelper->SelectEntryPos( i );
799 // call the select handler, don't handle events in this time
800 m_bDisableProcessEvent = true;
801 m_pListBoxHelper->Select();
802 m_bDisableProcessEvent = false;
803 bNotify = true;
804 }
805 }
806
807 if ( bNotify )
808 UpdateSelection_Impl();
809}
810
811sal_Int32 SAL_CALL VCLXAccessibleList::getSelectedAccessibleChildCount( )
812{
813 SolarMutexGuard aSolarGuard;
814 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
815
816 sal_Int32 nCount = 0;
817 if ( m_pListBoxHelper )
818 nCount = m_pListBoxHelper->GetSelectedEntryCount();
819 return nCount;
820}
821
822Reference< XAccessible > SAL_CALL VCLXAccessibleList::getSelectedAccessibleChild( sal_Int32 nSelectedChildIndex )
823{
824 SolarMutexGuard aSolarGuard;
825 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
826
827 if ( m_pListBoxHelper )
828 {
829 checkSelection_Impl(nSelectedChildIndex,*m_pListBoxHelper,true);
830 return getAccessibleChild( m_pListBoxHelper->GetSelectedEntryPos( static_cast<sal_uInt16>(nSelectedChildIndex) ) );
831 }
832
833 return nullptr;
834}
835
836void SAL_CALL VCLXAccessibleList::deselectAccessibleChild( sal_Int32 nSelectedChildIndex )
837{
838 bool bNotify = false;
839
840 {
841 SolarMutexGuard aSolarGuard;
842 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
843
844 if ( m_pListBoxHelper )
845 {
846 checkSelection_Impl(nSelectedChildIndex,*m_pListBoxHelper,false);
847
848 m_pListBoxHelper->SelectEntryPos( static_cast<sal_uInt16>(nSelectedChildIndex), false );
849 // call the select handler, don't handle events in this time
850 m_bDisableProcessEvent = true;
851 m_pListBoxHelper->Select();
852 m_bDisableProcessEvent = false;
853 bNotify = true;
854 }
855 }
856
857 if ( bNotify )
858 UpdateSelection_Impl();
859}
860
861awt::Rectangle VCLXAccessibleList::implGetBounds()
862{
863 awt::Rectangle aBounds ( 0, 0, 0, 0 );
864 if ( m_pListBoxHelper
865 && (m_pListBoxHelper->GetStyle() & WB_DROPDOWN ) == WB_DROPDOWN )
866 {
867 if ( m_pListBoxHelper->IsInDropDown() )
868 aBounds = AWTRectangle(m_pListBoxHelper->GetDropDownPosSizePixel());
869 }
870 else
871 {
872 // a list has the same bounds as his parent but starts at (0,0)
873 aBounds = VCLXAccessibleComponent::implGetBounds();
874 aBounds.X = 0;
875 aBounds.Y = 0;
876 if ( m_aBoxType == COMBOBOX )
877 {
878 VclPtr< ComboBox > pBox = GetAs< ComboBox >();
879 if ( pBox )
880 {
881 Size aSize = pBox->GetSubEdit()->GetSizePixel();
882 aBounds.Y += aSize.Height();
883 aBounds.Height -= aSize.Height();
884 }
885 }
886 }
887 return aBounds;
888}
889
890
891awt::Point VCLXAccessibleList::getLocationOnScreen( )
892{
893 SolarMutexGuard aSolarGuard;
894 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
895
896 awt::Point aPos;
897 if ( m_pListBoxHelper
898 && (m_pListBoxHelper->GetStyle() & WB_DROPDOWN ) == WB_DROPDOWN )
899 {
900 if ( m_pListBoxHelper->IsInDropDown() )
901 aPos = AWTPoint(m_pListBoxHelper->GetDropDownPosSizePixel().TopLeft());
902 }
903 else
904 {
905 aPos = VCLXAccessibleComponent::getLocationOnScreen();
906 if ( m_aBoxType == COMBOBOX )
907 {
908 VclPtr< ComboBox > pBox = GetAs< ComboBox >();
909 if ( pBox )
910 {
911 aPos.Y += pBox->GetSubEdit()->GetSizePixel().Height();
912 }
913 }
914 }
915 return aPos;
916}
917
918
919bool VCLXAccessibleList::IsInDropDown() const
920{
921 return m_pListBoxHelper->IsInDropDown();
922}
923
924
925void VCLXAccessibleList::HandleDropOpen()
926{
927 if ( !m_bDisableProcessEvent )
928 UpdateSelection_Impl();
929 if (m_nCurSelectedPos != LISTBOX_ENTRY_NOTFOUND(((sal_Int32) 0x7FFFFFFF)) &&
930 m_nLastSelectedPos != LISTBOX_ENTRY_NOTFOUND(((sal_Int32) 0x7FFFFFFF)))
931 {
932 Reference< XAccessible > xChild = getAccessibleChild(m_nCurSelectedPos);
933 if(xChild.is())
934 {
935 uno::Any aNewValue;
936 aNewValue <<= xChild;
937 NotifyAccessibleEvent(AccessibleEventId::ACTIVE_DESCENDANT_CHANGED, uno::Any(), aNewValue );
938 }
939 }
940}
941
942/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

/home/maarten/src/libreoffice/core/include/toolkit/awt/vclxaccessiblecomponent.hxx

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#ifndef INCLUDED_TOOLKIT_AWT_VCLXACCESSIBLECOMPONENT_HXX
21#define INCLUDED_TOOLKIT_AWT_VCLXACCESSIBLECOMPONENT_HXX
22
23#include <toolkit/dllapi.h>
24#include <com/sun/star/lang/XServiceInfo.hpp>
25#include <cppuhelper/implbase1.hxx>
26#include <comphelper/accimplaccess.hxx>
27#include <comphelper/accessiblecomponenthelper.hxx>
28
29
30#include <tools/link.hxx>
31#include <vcl/vclptr.hxx>
32
33namespace com::sun::star::accessibility { class XAccessible; }
34
35namespace vcl { class Window; }
36class VCLXWindow;
37class VclWindowEvent;
38
39namespace utl {
40class AccessibleRelationSetHelper;
41class AccessibleStateSetHelper;
42}
43
44
45
46typedef ::cppu::ImplHelper1<
47 css::lang::XServiceInfo > VCLXAccessibleComponent_BASE;
48
49class TOOLKIT_DLLPUBLIC__attribute__ ((visibility("default"))) VCLXAccessibleComponent
50 :public comphelper::OAccessibleExtendedComponentHelper
51 ,public ::comphelper::OAccessibleImplementationAccess
52 ,public VCLXAccessibleComponent_BASE
53{
54private:
55 rtl::Reference<VCLXWindow> m_xVCLXWindow;
56 VclPtr<vcl::Window> m_xEventSource;
57
58 DECL_LINK( WindowEventListener, VclWindowEvent&, void )static void LinkStubWindowEventListener(void *, VclWindowEvent
&); void WindowEventListener(VclWindowEvent&)
;
59 DECL_LINK( WindowChildEventListener, VclWindowEvent&, void )static void LinkStubWindowChildEventListener(void *, VclWindowEvent
&); void WindowChildEventListener(VclWindowEvent&)
;
60 void DisconnectEvents();
61
62protected:
63 virtual void ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent );
64 virtual void ProcessWindowChildEvent( const VclWindowEvent& rVclWindowEvent );
65 virtual void FillAccessibleRelationSet( utl::AccessibleRelationSetHelper& rRelationSet );
66 virtual void FillAccessibleStateSet( utl::AccessibleStateSetHelper& rStateSet );
67
68 virtual css::uno::Reference< css::accessibility::XAccessible > GetChildAccessible( const VclWindowEvent& rVclWindowEvent );
69
70public:
71 VCLXAccessibleComponent( VCLXWindow* pVCLXWindow );
72 virtual ~VCLXAccessibleComponent() override;
73
74 VCLXWindow* GetVCLXWindow() const;
75 VclPtr<vcl::Window> GetWindow() const;
76 template< class derived_type > VclPtr< derived_type > GetAs() const {
77 return VclPtr< derived_type >( static_cast< derived_type * >( GetWindow().get() ) ); }
2
Calling constructor for 'VclPtr<ListBox>'
7
Returning from constructor for 'VclPtr<ListBox>'
8
Calling implicit destructor for 'VclPtr<vcl::Window>'
9
Calling '~Reference'
16
Returning from '~Reference'
17
Returning from destructor for 'VclPtr<vcl::Window>'
78 template< class derived_type > VclPtr< derived_type > GetAsDynamic() const {
79 return VclPtr< derived_type >( dynamic_cast< derived_type * >( GetWindow().get() ) ); }
80
81 virtual void SAL_CALL disposing() override;
82
83 // css::uno::XInterface
84 DECLARE_XINTERFACE()virtual css::uno::Any queryInterface( const css::uno::Type&
aType ) override; virtual void acquire() throw() override; virtual
void release() throw() override;
85 // css::lang::XTypeProvider
86 DECLARE_XTYPEPROVIDER()virtual css::uno::Sequence< css::uno::Type > getTypes( )
override; virtual css::uno::Sequence< sal_Int8 > getImplementationId
( ) override;
87
88 // XServiceInfo
89 virtual OUString SAL_CALL getImplementationName() override;
90 virtual sal_Bool SAL_CALL supportsService( const OUString& rServiceName ) override;
91 virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override;
92
93 // css::accessibility::XAccessibleContext
94 sal_Int32 SAL_CALL getAccessibleChildCount( ) override;
95 css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getAccessibleChild( sal_Int32 i ) override;
96 css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getAccessibleParent( ) override;
97 sal_Int32 SAL_CALL getAccessibleIndexInParent( ) override;
98 sal_Int16 SAL_CALL getAccessibleRole( ) override;
99 OUString SAL_CALL getAccessibleDescription( ) override;
100 OUString SAL_CALL getAccessibleName( ) override;
101 OUString SAL_CALL getAccessibleId( ) override;
102 css::uno::Reference< css::accessibility::XAccessibleRelationSet > SAL_CALL getAccessibleRelationSet( ) override;
103 css::uno::Reference< css::accessibility::XAccessibleStateSet > SAL_CALL getAccessibleStateSet( ) override;
104 css::lang::Locale SAL_CALL getLocale( ) override;
105
106 // css::accessibility::XAccessibleComponent
107 css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getAccessibleAtPoint( const css::awt::Point& aPoint ) override;
108 css::awt::Point SAL_CALL getLocationOnScreen( ) override;
109 void SAL_CALL grabFocus( ) override;
110 virtual sal_Int32 SAL_CALL getForeground( ) override;
111 virtual sal_Int32 SAL_CALL getBackground( ) override;
112
113 // css::accessibility::XAccessibleExtendedComponent
114 virtual css::uno::Reference< css::awt::XFont > SAL_CALL getFont( ) override;
115 virtual OUString SAL_CALL getTitledBorderText( ) override;
116 virtual OUString SAL_CALL getToolTipText( ) override;
117
118protected:
119 // base class overridables
120 css::awt::Rectangle implGetBounds( ) override;
121
122private:
123 /** we may be reparented (if external components use OAccessibleImplementationAccess base class),
124 so this method here returns the parent in the VCL world, in opposite to the parent
125 an external component gave us
126 @precond
127 the caller must ensure thread safety, i.e. our mutex must be locked
128 */
129 css::uno::Reference< css::accessibility::XAccessible >
130 getVclParent() const;
131};
132
133/* ----------------------------------------------------------
134 Accessibility only for the Window hierarchy!
135 Maybe derived classes must overwrite these Accessibility interfaces:
136
137 // XAccessibleContext:
138 sal_Int16 getAccessibleRole() => VCL Window::GetAccessibleRole()
139 OUString getAccessibleDescription() => VCL Window::GetAccessibleDescription
140 OUString getAccessibleName() => VCL Window::GetAccessibleText() => Most windows return Window::GetText()
141 OUString getAccessibleId() => VCL Window::get_id()
142 Reference< XAccessibleRelationSet > getAccessibleRelationSet()
143 Reference< XAccessibleStateSet > getAccessibleStateSet() => override FillAccessibleStateSet( ... )
144
145---------------------------------------------------------- */
146
147
148#endif // INCLUDED_TOOLKIT_AWT_VCLXACCESSIBLECOMPONENT_HXX
149
150/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

/home/maarten/src/libreoffice/core/include/vcl/vclptr.hxx

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#ifndef INCLUDED_VCL_PTR_HXX
21#define INCLUDED_VCL_PTR_HXX
22
23#include <sal/config.h>
24
25#include <rtl/ref.hxx>
26
27#include <utility>
28#include <type_traits>
29
30#ifdef DBG_UTIL
31#ifndef _WIN32
32#include <vcl/vclmain.hxx>
33#endif
34#endif
35
36class VclReferenceBase;
37
38namespace vcl::detail {
39
40template<typename>
41constexpr bool isIncompleteOrDerivedFromVclReferenceBase(...) { return true; }
42
43template<typename T> constexpr bool isIncompleteOrDerivedFromVclReferenceBase(
44 int (*)[sizeof(T)])
45{ return std::is_base_of<VclReferenceBase, T>::value; }
46
47} // namespace vcl::detail
48
49/**
50 * A thin wrapper around rtl::Reference to implement the acquire and dispose semantics we want for references to vcl::Window subclasses.
51 *
52 * For more details on the design please see vcl/README.lifecycle
53 *
54 * @param reference_type must be a subclass of vcl::Window
55 */
56template <class reference_type>
57class VclPtr
58{
59 static_assert(
60 vcl::detail::isIncompleteOrDerivedFromVclReferenceBase<reference_type>(
61 nullptr),
62 "template argument type must be derived from VclReferenceBase");
63
64 ::rtl::Reference<reference_type> m_rInnerRef;
65
66public:
67 /** Constructor...
68 */
69 VclPtr()
70 : m_rInnerRef()
71 {}
72
73 /** Constructor...
74 */
75 VclPtr (reference_type * pBody)
76 : m_rInnerRef(pBody)
3
Calling constructor for 'Reference<ListBox>'
6
Returning from constructor for 'Reference<ListBox>'
77 {}
78
79 /** Constructor... that doesn't take a ref.
80 */
81 VclPtr (reference_type * pBody, __sal_NoAcquire)
82 : m_rInnerRef(pBody, SAL_NO_ACQUIRE)
83 {}
84
85 /** Up-casting conversion constructor: Copies interface reference.
86
87 Does not work for up-casts to ambiguous bases. For the special case of
88 up-casting to Reference< XInterface >, see the corresponding conversion
89 operator.
90
91 @param rRef another reference
92 */
93 template< class derived_type >
94 VclPtr(
95 const VclPtr< derived_type > & rRef,
96 typename std::enable_if<
97 std::is_base_of<reference_type, derived_type>::value, int>::type
98 = 0 )
99 : m_rInnerRef( static_cast<reference_type*>(rRef) )
100 {
101 }
102
103#if defined(DBG_UTIL) && !defined(_WIN32)
104 virtual ~VclPtr()
105 {
106 assert(m_rInnerRef.get() == nullptr || vclmain::isAlive())(static_cast <bool> (m_rInnerRef.get() == nullptr || vclmain
::isAlive()) ? void (0) : __assert_fail ("m_rInnerRef.get() == nullptr || vclmain::isAlive()"
, "/home/maarten/src/libreoffice/core/include/vcl/vclptr.hxx"
, 106, __extension__ __PRETTY_FUNCTION__))
;
107 // We can be one of the intermediate counts, but if we are the last
108 // VclPtr keeping this object alive, then something forgot to call dispose().
109 assert((!m_rInnerRef.get() || m_rInnerRef->isDisposed() || m_rInnerRef->getRefCount() > 1)(static_cast <bool> ((!m_rInnerRef.get() || m_rInnerRef
->isDisposed() || m_rInnerRef->getRefCount() > 1) &&
"someone forgot to call dispose()") ? void (0) : __assert_fail
("(!m_rInnerRef.get() || m_rInnerRef->isDisposed() || m_rInnerRef->getRefCount() > 1) && \"someone forgot to call dispose()\""
, "/home/maarten/src/libreoffice/core/include/vcl/vclptr.hxx"
, 110, __extension__ __PRETTY_FUNCTION__))
110 && "someone forgot to call dispose()")(static_cast <bool> ((!m_rInnerRef.get() || m_rInnerRef
->isDisposed() || m_rInnerRef->getRefCount() > 1) &&
"someone forgot to call dispose()") ? void (0) : __assert_fail
("(!m_rInnerRef.get() || m_rInnerRef->isDisposed() || m_rInnerRef->getRefCount() > 1) && \"someone forgot to call dispose()\""
, "/home/maarten/src/libreoffice/core/include/vcl/vclptr.hxx"
, 110, __extension__ __PRETTY_FUNCTION__))
;
111 }
112 VclPtr(VclPtr const &) = default;
113 VclPtr(VclPtr &&) = default;
114 VclPtr & operator =(VclPtr const &) = default;
115 VclPtr & operator =(VclPtr &&) = default;
116#endif
117
118 /**
119 * A construction helper for VclPtr. Since VclPtr types are created
120 * with a reference-count of one - to help fit into the existing
121 * code-flow; this helps us to construct them easily.
122 *
123 * For more details on the design please see vcl/README.lifecycle
124 *
125 * @tparam reference_type must be a subclass of vcl::Window
126 */
127 template<typename... Arg> [[nodiscard]] static VclPtr< reference_type > Create(Arg &&... arg)
128 {
129 return VclPtr< reference_type >( new reference_type(std::forward<Arg>(arg)...), SAL_NO_ACQUIRE );
130 }
131
132 /** Probably most common used: handle->someBodyOp().
133 */
134 reference_type * operator->() const
135 {
136 return m_rInnerRef.get();
137 }
138
139 /** Get the body. Can be used instead of operator->().
140 I.e. handle->someBodyOp() and handle.get()->someBodyOp()
141 are the same.
142 */
143 reference_type * get() const
144 {
145 return m_rInnerRef.get();
146 }
147
148 void set(reference_type *pBody)
149 {
150 m_rInnerRef.set(pBody);
151 }
152
153 void reset(reference_type *pBody)
154 {
155 m_rInnerRef.set(pBody);
156 }
157
158 /** Up-casting copy assignment operator.
159
160 Does not work for up-casts to ambiguous bases.
161
162 @param rRef another reference
163 */
164 template<typename derived_type>
165 typename std::enable_if<
166 std::is_base_of<reference_type, derived_type>::value,
167 VclPtr &>::type
168 operator =(VclPtr<derived_type> const & rRef)
169 {
170 m_rInnerRef.set(rRef.get());
171 return *this;
172 }
173
174 VclPtr & operator =(reference_type * pBody)
175 {
176 m_rInnerRef.set(pBody);
177 return *this;
178 }
179
180 operator reference_type * () const
181 {
182 return m_rInnerRef.get();
183 }
184
185 explicit operator bool () const
186 {
187 return m_rInnerRef.get() != nullptr;
188 }
189
190 void clear()
191 {
192 m_rInnerRef.clear();
193 }
194
195 void reset()
196 {
197 m_rInnerRef.clear();
198 }
199
200 void disposeAndClear()
201 {
202 // hold it alive for the lifetime of this method
203 ::rtl::Reference<reference_type> aTmp(m_rInnerRef);
204 m_rInnerRef.clear(); // we should use some 'swap' method ideally ;-)
205 if (aTmp.get()) {
206 aTmp->disposeOnce();
207 }
208 }
209
210 /** Needed to place VclPtr's into STL collection.
211 */
212 bool operator< (const VclPtr<reference_type> & handle) const
213 {
214 return (m_rInnerRef < handle.m_rInnerRef);
215 }
216}; // class VclPtr
217
218template<typename T1, typename T2>
219inline bool operator ==(VclPtr<T1> const & p1, VclPtr<T2> const & p2) {
220 return p1.get() == p2.get();
221}
222
223template<typename T> inline bool operator ==(VclPtr<T> const & p1, T const * p2)
224{
225 return p1.get() == p2;
226}
227
228template<typename T> inline bool operator ==(VclPtr<T> const & p1, T * p2) {
229 return p1.get() == p2;
230}
231
232template<typename T> inline bool operator ==(T const * p1, VclPtr<T> const & p2)
233{
234 return p1 == p2.get();
235}
236
237template<typename T> inline bool operator ==(T * p1, VclPtr<T> const & p2) {
238 return p1 == p2.get();
239}
240
241template<typename T1, typename T2>
242inline bool operator !=(VclPtr<T1> const & p1, VclPtr<T2> const & p2) {
243 return !(p1 == p2);
244}
245
246template<typename T> inline bool operator !=(VclPtr<T> const & p1, T const * p2)
247{
248 return !(p1 == p2);
249}
250
251template<typename T> inline bool operator !=(VclPtr<T> const & p1, T * p2) {
252 return !(p1 == p2);
253}
254
255template<typename T> inline bool operator !=(T const * p1, VclPtr<T> const & p2)
256{
257 return !(p1 == p2);
258}
259
260template<typename T> inline bool operator !=(T * p1, VclPtr<T> const & p2) {
261 return !(p1 == p2);
262}
263
264/**
265 * A construction helper for a temporary VclPtr. Since VclPtr types
266 * are created with a reference-count of one - to help fit into
267 * the existing code-flow; this helps us to construct them easily.
268 * see also VclPtr::Create and ScopedVclPtr
269 *
270 * For more details on the design please see vcl/README.lifecycle
271 *
272 * @param reference_type must be a subclass of vcl::Window
273 */
274template <class reference_type>
275class SAL_WARN_UNUSED__attribute__((warn_unused)) VclPtrInstance final : public VclPtr<reference_type>
276{
277public:
278 template<typename... Arg> VclPtrInstance(Arg &&... arg)
279 : VclPtr<reference_type>( new reference_type(std::forward<Arg>(arg)...), SAL_NO_ACQUIRE )
280 {
281 }
282
283 /**
284 * Override and disallow this, to prevent people accidentally calling it and actually
285 * getting VclPtr::Create and getting a naked VclPtr<> instance
286 */
287 template<typename... Arg> static VclPtrInstance< reference_type > Create(Arg &&... ) = delete;
288};
289
290template <class reference_type>
291class ScopedVclPtr : public VclPtr<reference_type>
292{
293public:
294 /** Constructor...
295 */
296 ScopedVclPtr()
297 : VclPtr<reference_type>()
298 {}
299
300 /** Constructor
301 */
302 ScopedVclPtr (reference_type * pBody)
303 : VclPtr<reference_type>(pBody)
304 {}
305
306 /** Copy constructor...
307 */
308 ScopedVclPtr (const VclPtr<reference_type> & handle)
309 : VclPtr<reference_type>(handle)
310 {}
311
312 /**
313 Assignment that releases the last reference.
314 */
315 void disposeAndReset(reference_type *pBody)
316 {
317 if (pBody != this->get()) {
318 VclPtr<reference_type>::disposeAndClear();
319 VclPtr<reference_type>::set(pBody);
320 }
321 }
322
323 /**
324 Assignment that releases the last reference.
325 */
326 ScopedVclPtr<reference_type>& operator = (reference_type * pBody)
327 {
328 disposeAndReset(pBody);
329 return *this;
330 }
331
332 /** Up-casting conversion constructor: Copies interface reference.
333
334 Does not work for up-casts to ambiguous bases. For the special case of
335 up-casting to Reference< XInterface >, see the corresponding conversion
336 operator.
337
338 @param rRef another reference
339 */
340 template< class derived_type >
341 ScopedVclPtr(
342 const VclPtr< derived_type > & rRef,
343 typename std::enable_if<
344 std::is_base_of<reference_type, derived_type>::value, int>::type
345 = 0 )
346 : VclPtr<reference_type>( rRef )
347 {
348 }
349
350 /** Up-casting assignment operator.
351
352 Does not work for up-casts to ambiguous bases.
353
354 @param rRef another VclPtr
355 */
356 template<typename derived_type>
357 typename std::enable_if<
358 std::is_base_of<reference_type, derived_type>::value,
359 ScopedVclPtr &>::type
360 operator =(VclPtr<derived_type> const & rRef)
361 {
362 disposeAndReset(rRef.get());
363 return *this;
364 }
365
366 /**
367 * Override and disallow this, to prevent people accidentally calling it and actually
368 * getting VclPtr::Create and getting a naked VclPtr<> instance
369 */
370 template<typename... Arg> static ScopedVclPtr< reference_type > Create(Arg &&... ) = delete;
371
372 ~ScopedVclPtr()
373 {
374 VclPtr<reference_type>::disposeAndClear();
375 assert(VclPtr<reference_type>::get() == nullptr)(static_cast <bool> (VclPtr<reference_type>::get(
) == nullptr) ? void (0) : __assert_fail ("VclPtr<reference_type>::get() == nullptr"
, "/home/maarten/src/libreoffice/core/include/vcl/vclptr.hxx"
, 375, __extension__ __PRETTY_FUNCTION__))
; // make sure there are no lingering references
376 }
377
378private:
379 // Most likely we don't want this default copy-constructor.
380 ScopedVclPtr (const ScopedVclPtr<reference_type> &) = delete;
381 // And certainly we don't want a default assignment operator.
382 ScopedVclPtr<reference_type>& operator = (const ScopedVclPtr<reference_type> &) = delete;
383 // And disallow reset as that doesn't call disposeAndClear on the original reference
384 void reset() = delete;
385 void reset(reference_type *pBody) = delete;
386
387protected:
388 ScopedVclPtr (reference_type * pBody, __sal_NoAcquire)
389 : VclPtr<reference_type>(pBody, SAL_NO_ACQUIRE)
390 {}
391};
392
393/**
394 * A construction helper for ScopedVclPtr. Since VclPtr types are created
395 * with a reference-count of one - to help fit into the existing
396 * code-flow; this helps us to construct them easily.
397 *
398 * For more details on the design please see vcl/README.lifecycle
399 *
400 * @param reference_type must be a subclass of vcl::Window
401 */
402#if defined _MSC_VER
403#pragma warning(push)
404#pragma warning(disable: 4521) // " multiple copy constructors specified"
405#endif
406template <class reference_type>
407class SAL_WARN_UNUSED__attribute__((warn_unused)) ScopedVclPtrInstance final : public ScopedVclPtr<reference_type>
408{
409public:
410 template<typename... Arg> ScopedVclPtrInstance(Arg &&... arg)
411 : ScopedVclPtr<reference_type>( new reference_type(std::forward<Arg>(arg)...), SAL_NO_ACQUIRE )
412 {
413 }
414
415 /**
416 * Override and disallow this, to prevent people accidentally calling it and actually
417 * getting VclPtr::Create and getting a naked VclPtr<> instance
418 */
419 template<typename... Arg> static ScopedVclPtrInstance< reference_type > Create(Arg &&...) = delete;
420
421private:
422 // Prevent the above perfect forwarding ctor from hijacking (accidental)
423 // attempts at ScopedVclPtrInstance copy construction (where the hijacking
424 // would typically lead to somewhat obscure error messages); both non-const
425 // and const variants are needed here, as the ScopedVclPtr base class has a
426 // const--variant copy ctor, so the implicitly declared copy ctor for
427 // ScopedVclPtrInstance would also be the const variant, so non-const copy
428 // construction attempts would be hijacked by the perfect forwarding ctor;
429 // but if we only declared a non-const variant here, the const variant would
430 // no longer be implicitly declared (as there would already be an explicitly
431 // declared copy ctor), so const copy construction attempts would then be
432 // hijacked by the perfect forwarding ctor:
433 ScopedVclPtrInstance(ScopedVclPtrInstance &) = delete;
434 ScopedVclPtrInstance(ScopedVclPtrInstance const &) = delete;
435};
436#if defined _MSC_VER
437#pragma warning(pop)
438#endif
439
440#endif // INCLUDED_VCL_PTR_HXX
441
442/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

/home/maarten/src/libreoffice/core/include/rtl/ref.hxx

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#ifndef INCLUDED_RTL_REF_HXX
21#define INCLUDED_RTL_REF_HXX
22
23#include "sal/config.h"
24
25#include <cassert>
26#include <cstddef>
27#include <functional>
28#ifdef LIBO_INTERNAL_ONLY1
29#include <type_traits>
30#endif
31
32#include "sal/types.h"
33
34namespace rtl
35{
36
37/** Template reference class for reference type.
38*/
39template <class reference_type>
40class Reference
41{
42 /** The <b>reference_type</b> body pointer.
43 */
44 reference_type * m_pBody;
45
46
47public:
48 /** Constructor...
49 */
50 Reference()
51 : m_pBody (NULL__null)
52 {}
53
54
55 /** Constructor...
56 */
57 Reference (reference_type * pBody, __sal_NoAcquire)
58 : m_pBody (pBody)
59 {
60 }
61
62 /** Constructor...
63 */
64 Reference (reference_type * pBody)
65 : m_pBody (pBody)
66 {
67 if (m_pBody)
4
Assuming field 'm_pBody' is non-null
5
Taking true branch
68 m_pBody->acquire();
69 }
70
71 /** Copy constructor...
72 */
73 Reference (const Reference<reference_type> & handle)
74 : m_pBody (handle.m_pBody)
75 {
76 if (m_pBody)
77 m_pBody->acquire();
78 }
79
80#ifdef LIBO_INTERNAL_ONLY1
81 /** Move constructor...
82 */
83 Reference (Reference<reference_type> && handle) noexcept
84 : m_pBody (handle.m_pBody)
85 {
86 handle.m_pBody = nullptr;
87 }
88#endif
89
90#if defined LIBO_INTERNAL_ONLY1
91 /** Up-casting conversion constructor: Copies interface reference.
92
93 Does not work for up-casts to ambiguous bases.
94
95 @param rRef another reference
96 */
97 template< class derived_type >
98 inline Reference(
99 const Reference< derived_type > & rRef,
100 std::enable_if_t<std::is_base_of_v<reference_type, derived_type>, int> = 0 )
101 : m_pBody (rRef.get())
102 {
103 if (m_pBody)
104 m_pBody->acquire();
105 }
106#endif
107
108 /** Destructor...
109 */
110 ~Reference() COVERITY_NOEXCEPT_FALSE
111 {
112 if (m_pBody
9.1
Field 'm_pBody' is non-null
22.1
Field 'm_pBody' is non-null
9.1
Field 'm_pBody' is non-null
22.1
Field 'm_pBody' is non-null
9.1
Field 'm_pBody' is non-null
22.1
Field 'm_pBody' is non-null
9.1
Field 'm_pBody' is non-null
22.1
Field 'm_pBody' is non-null
9.1
Field 'm_pBody' is non-null
22.1
Field 'm_pBody' is non-null
)
10
Taking true branch
23
Taking true branch
113 m_pBody->release();
11
Calling 'VclReferenceBase::release'
15
Returning; memory was released
24
Use of memory after it is freed
114 }
115
116 /** Set...
117 Similar to assignment.
118 */
119 Reference<reference_type> &
120 SAL_CALL set (reference_type * pBody)
121 {
122 if (pBody)
123 pBody->acquire();
124 reference_type * const pOld = m_pBody;
125 m_pBody = pBody;
126 if (pOld)
127 pOld->release();
128 return *this;
129 }
130
131 /** Assignment.
132 Unbinds this instance from its body (if bound) and
133 bind it to the body represented by the handle.
134 */
135 Reference<reference_type> &
136 SAL_CALL operator= (const Reference<reference_type> & handle)
137 {
138 return set( handle.m_pBody );
139 }
140
141#ifdef LIBO_INTERNAL_ONLY1
142 /** Assignment.
143 * Unbinds this instance from its body (if bound),
144 * bind it to the body represented by the handle, and
145 * set the body represented by the handle to nullptr.
146 */
147 Reference<reference_type> &
148 operator= (Reference<reference_type> && handle)
149 {
150 // self-movement guts ourself
151 if (m_pBody)
152 m_pBody->release();
153 m_pBody = handle.m_pBody;
154 handle.m_pBody = nullptr;
155 return *this;
156 }
157#endif
158
159 /** Assignment...
160 */
161 Reference<reference_type> &
162 SAL_CALL operator= (reference_type * pBody)
163 {
164 return set( pBody );
165 }
166
167 /** Unbind the body from this handle.
168 Note that for a handle representing a large body,
169 "handle.clear().set(new body());" _might_
170 perform a little bit better than "handle.set(new body());",
171 since in the second case two large objects exist in memory
172 (the old body and the new body).
173 */
174 Reference<reference_type> & SAL_CALL clear()
175 {
176 if (m_pBody)
177 {
178 reference_type * const pOld = m_pBody;
179 m_pBody = NULL__null;
180 pOld->release();
181 }
182 return *this;
183 }
184
185
186 /** Get the body. Can be used instead of operator->().
187 I.e. handle->someBodyOp() and handle.get()->someBodyOp()
188 are the same.
189 */
190 reference_type * SAL_CALL get() const
191 {
192 return m_pBody;
193 }
194
195
196 /** Probably most common used: handle->someBodyOp().
197 */
198 reference_type * SAL_CALL operator->() const
199 {
200 assert(m_pBody != NULL)(static_cast <bool> (m_pBody != __null) ? void (0) : __assert_fail
("m_pBody != NULL", "/home/maarten/src/libreoffice/core/include/rtl/ref.hxx"
, 200, __extension__ __PRETTY_FUNCTION__))
;
201 return m_pBody;
202 }
203
204
205 /** Allows (*handle).someBodyOp().
206 */
207 reference_type & SAL_CALL operator*() const
208 {
209 assert(m_pBody != NULL)(static_cast <bool> (m_pBody != __null) ? void (0) : __assert_fail
("m_pBody != NULL", "/home/maarten/src/libreoffice/core/include/rtl/ref.hxx"
, 209, __extension__ __PRETTY_FUNCTION__))
;
210 return *m_pBody;
211 }
212
213
214 /** Returns True if the handle does point to a valid body.
215 */
216 bool SAL_CALL is() const
217 {
218 return (m_pBody != NULL__null);
219 }
220
221#if defined LIBO_INTERNAL_ONLY1
222 /** Returns True if the handle does point to a valid body.
223 */
224 explicit operator bool() const
225 {
226 return is();
227 }
228#endif
229
230 /** Returns True if this points to pBody.
231 */
232 bool SAL_CALL operator== (const reference_type * pBody) const
233 {
234 return (m_pBody == pBody);
235 }
236
237
238 /** Returns True if handle points to the same body.
239 */
240 bool
241 SAL_CALL operator== (const Reference<reference_type> & handle) const
242 {
243 return (m_pBody == handle.m_pBody);
244 }
245
246
247 /** Needed to place References into STL collection.
248 */
249 bool
250 SAL_CALL operator!= (const Reference<reference_type> & handle) const
251 {
252 return (m_pBody != handle.m_pBody);
253 }
254
255
256 /** Needed to place References into STL collection.
257 */
258 bool
259 SAL_CALL operator< (const Reference<reference_type> & handle) const
260 {
261 return (m_pBody < handle.m_pBody);
262 }
263
264
265 /** Needed to place References into STL collection.
266 */
267 bool
268 SAL_CALL operator> (const Reference<reference_type> & handle) const
269 {
270 return (m_pBody > handle.m_pBody);
271 }
272};
273
274} // namespace rtl
275
276#if defined LIBO_INTERNAL_ONLY1
277namespace std
278{
279
280/// @cond INTERNAL
281/**
282 Make rtl::Reference hashable by default for use in STL containers.
283
284 @since LibreOffice 6.3
285*/
286template<typename T>
287struct hash<::rtl::Reference<T>>
288{
289 std::size_t operator()(::rtl::Reference<T> const & s) const
290 { return std::size_t(s.get()); }
291};
292/// @endcond
293
294}
295
296#endif
297
298#endif /* ! INCLUDED_RTL_REF_HXX */
299
300/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

/home/maarten/src/libreoffice/core/include/vcl/vclreferencebase.hxx

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#ifndef INCLUDED_VCL_Reference_HXX
20#define INCLUDED_VCL_Reference_HXX
21
22#include <vcl/dllapi.h>
23#include <osl/interlck.h>
24
25class VCL_DLLPUBLIC__attribute__ ((visibility("default"))) VclReferenceBase
26{
27 mutable oslInterlockedCount mnRefCnt;
28
29 template<typename T> friend class VclPtr;
30
31public:
32 void acquire() const
33 {
34 osl_atomic_increment(&mnRefCnt)__sync_add_and_fetch((&mnRefCnt), 1);
35 }
36
37 void release() const
38 {
39 if (osl_atomic_decrement(&mnRefCnt)__sync_sub_and_fetch((&mnRefCnt), 1) == 0)
12
Assuming the condition is true
13
Taking true branch
40 delete this;
14
Memory is released
41 }
42#ifdef DBG_UTIL
43#ifndef _WIN32
44 sal_Int32 getRefCount() const { return mnRefCnt; }
45#endif
46#endif
47
48
49private:
50 VclReferenceBase(const VclReferenceBase&) = delete;
51 VclReferenceBase& operator=(const VclReferenceBase&) = delete;
52
53 bool mbDisposed : 1;
54
55protected:
56 VclReferenceBase();
57protected:
58 virtual ~VclReferenceBase();
59
60protected:
61 virtual void dispose();
62
63public:
64 void disposeOnce();
65 bool isDisposed() const { return mbDisposed; }
66
67};
68#endif