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 vclxaccessibletoolbox.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/vclxaccessibletoolbox.cxx

/home/maarten/src/libreoffice/core/accessibility/source/standard/vclxaccessibletoolbox.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#include <string.h>
20
21#include <standard/vclxaccessibletoolbox.hxx>
22#include <standard/vclxaccessibletoolboxitem.hxx>
23#include <toolkit/helper/convert.hxx>
24
25#include <unotools/accessiblestatesethelper.hxx>
26#include <com/sun/star/accessibility/AccessibleEventId.hpp>
27#include <com/sun/star/accessibility/AccessibleStateType.hpp>
28#include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
29#include <com/sun/star/lang/XUnoTunnel.hpp>
30#include <o3tl/safeint.hxx>
31#include <vcl/toolbox.hxx>
32#include <vcl/vclevent.hxx>
33#include <comphelper/accessiblewrapper.hxx>
34#include <comphelper/processfactory.hxx>
35#include <comphelper/servicehelper.hxx>
36#include <comphelper/types.hxx>
37#include <cppuhelper/typeprovider.hxx>
38
39using namespace ::comphelper;
40using namespace ::com::sun::star;
41using namespace ::com::sun::star::uno;
42using namespace ::com::sun::star::lang;
43using namespace ::com::sun::star::accessibility;
44
45namespace
46{
47
48 // = OToolBoxWindowItemContext
49
50 /** XAccessibleContext implementation for a toolbox item which is represented by a VCL Window
51 */
52 class OToolBoxWindowItemContext final : public OAccessibleContextWrapper
53 {
54 sal_Int32 m_nIndexInParent;
55 public:
56 OToolBoxWindowItemContext(sal_Int32 _nIndexInParent,
57 const css::uno::Reference< css::uno::XComponentContext >& _rxContext,
58 const css::uno::Reference< css::accessibility::XAccessibleContext >& _rxInnerAccessibleContext,
59 const css::uno::Reference< css::accessibility::XAccessible >& _rxOwningAccessible,
60 const css::uno::Reference< css::accessibility::XAccessible >& _rxParentAccessible
61 ) : OAccessibleContextWrapper(
62 _rxContext,
63 _rxInnerAccessibleContext,
64 _rxOwningAccessible,
65 _rxParentAccessible )
66 ,m_nIndexInParent(_nIndexInParent)
67 {
68 }
69 virtual sal_Int32 SAL_CALL getAccessibleIndexInParent( ) override;
70 };
71
72
73 sal_Int32 SAL_CALL OToolBoxWindowItemContext::getAccessibleIndexInParent( )
74 {
75 ::osl::MutexGuard aGuard( m_aMutex );
76 return m_nIndexInParent;
77 }
78
79
80 // = OToolBoxWindowItem
81
82 typedef ::cppu::ImplHelper1 < XUnoTunnel
83 > OToolBoxWindowItem_Base;
84
85 /** XAccessible implementation for a toolbox item which is represented by a VCL Window
86 */
87 class OToolBoxWindowItem
88 :public OAccessibleWrapper
89 ,public OToolBoxWindowItem_Base
90 {
91 private:
92 sal_Int32 m_nIndexInParent;
93
94 public:
95 sal_Int32 getIndexInParent() const { return m_nIndexInParent; }
96 void setIndexInParent( sal_Int32 _nNewIndex ) { m_nIndexInParent = _nNewIndex; }
97
98 static Sequence< sal_Int8 > getUnoTunnelId();
99
100 public:
101 OToolBoxWindowItem(sal_Int32 _nIndexInParent,
102 const css::uno::Reference< css::uno::XComponentContext >& _rxContext,
103 const css::uno::Reference< css::accessibility::XAccessible >& _rxInnerAccessible,
104 const css::uno::Reference< css::accessibility::XAccessible >& _rxParentAccessible
105 ) : OAccessibleWrapper(
106 _rxContext,
107 _rxInnerAccessible,
108 _rxParentAccessible)
109 ,m_nIndexInParent(_nIndexInParent)
110 {
111 }
112
113 protected:
114 // XInterface
115 DECLARE_XINTERFACE( )virtual css::uno::Any queryInterface( const css::uno::Type&
aType ) override; virtual void acquire() throw() override; virtual
void release() throw() override;
116 DECLARE_XTYPEPROVIDER( )virtual css::uno::Sequence< css::uno::Type > getTypes( )
override; virtual css::uno::Sequence< sal_Int8 > getImplementationId
( ) override;
117
118 // OAccessibleWrapper
119 virtual OAccessibleContextWrapper* createAccessibleContext(
120 const css::uno::Reference< css::accessibility::XAccessibleContext >& _rxInnerContext
121 ) override;
122
123 // XUnoTunnel
124 virtual sal_Int64 SAL_CALL getSomething( const Sequence< sal_Int8 >& aIdentifier ) override;
125 };
126
127 IMPLEMENT_FORWARD_XINTERFACE2( OToolBoxWindowItem, OAccessibleWrapper, OToolBoxWindowItem_Base )void OToolBoxWindowItem::acquire() throw() { OAccessibleWrapper
::acquire(); } void OToolBoxWindowItem::release() throw() { OAccessibleWrapper
::release(); } css::uno::Any OToolBoxWindowItem::queryInterface
( const css::uno::Type& _rType ) { css::uno::Any aReturn =
OAccessibleWrapper::queryInterface( _rType ); if ( !aReturn.
hasValue() ) aReturn = OToolBoxWindowItem_Base::queryInterface
( _rType ); return aReturn; }
128 IMPLEMENT_FORWARD_XTYPEPROVIDER2( OToolBoxWindowItem, OAccessibleWrapper, OToolBoxWindowItem_Base )css::uno::Sequence< css::uno::Type > OToolBoxWindowItem
::getTypes( ) { return ::comphelper::concatSequences( OAccessibleWrapper
::getTypes(), OToolBoxWindowItem_Base::getTypes() ); } css::uno
::Sequence< sal_Int8 > OToolBoxWindowItem::getImplementationId
( ) { return css::uno::Sequence<sal_Int8>(); }
129
130 OAccessibleContextWrapper* OToolBoxWindowItem::createAccessibleContext(
131 const Reference< XAccessibleContext >& _rxInnerContext )
132 {
133 return new OToolBoxWindowItemContext( m_nIndexInParent, getComponentContext(), _rxInnerContext, this, getParent() );
134 }
135
136 Sequence< sal_Int8 > OToolBoxWindowItem::getUnoTunnelId()
137 {
138 static ::cppu::OImplementationId implId;
139
140 return implId.getImplementationId();
141 }
142
143 sal_Int64 SAL_CALL OToolBoxWindowItem::getSomething( const Sequence< sal_Int8 >& _rId )
144 {
145 if (isUnoTunnelId<OToolBoxWindowItem>(_rId))
146 return reinterpret_cast< sal_Int64>( this );
147
148 return 0;
149 }
150}
151
152// VCLXAccessibleToolBox
153
154VCLXAccessibleToolBox::VCLXAccessibleToolBox( VCLXWindow* pVCLXWindow ) :
155
156 VCLXAccessibleComponent( pVCLXWindow )
157
158{
159}
160
161VCLXAccessibleToolBox::~VCLXAccessibleToolBox()
162{
163}
164
165VCLXAccessibleToolBoxItem* VCLXAccessibleToolBox::GetItem_Impl( ToolBox::ImplToolItems::size_type _nPos )
166{
167 VCLXAccessibleToolBoxItem* pItem = nullptr;
168 VclPtr< ToolBox > pToolBox = GetAs< ToolBox >();
169 if ( pToolBox )
170 {
171 ToolBoxItemsMap::iterator aIter = m_aAccessibleChildren.find( _nPos );
172 //TODO: ToolBox::ImplToolItems::size_type -> sal_Int32!
173 // returns only toolbox buttons, not windows
174 if ( aIter != m_aAccessibleChildren.end() && aIter->second.is())
175 pItem = static_cast< VCLXAccessibleToolBoxItem* >( aIter->second.get() );
176 }
177
178 return pItem;
179}
180
181void VCLXAccessibleToolBox::UpdateFocus_Impl()
182{
183 VclPtr< ToolBox > pToolBox = GetAs< ToolBox >();
184 if( !pToolBox )
185 return;
186
187 // submit events only if toolbox has the focus to avoid sending events due to mouse move
188 bool bHasFocus = false;
189 if ( pToolBox->HasFocus() )
190 bHasFocus = true;
191 else
192 {
193 // check for subtoolbar, i.e. check if our parent is a toolbar
194 ToolBox* pToolBoxParent = dynamic_cast< ToolBox* >( pToolBox->GetParent() );
195 // subtoolbars never get the focus as key input is just forwarded, so check if the parent toolbar has it
196 if ( pToolBoxParent && pToolBoxParent->HasFocus() )
197 bHasFocus = true;
198 }
199
200 if ( !bHasFocus )
201 return;
202
203 sal_uInt16 nHighlightItemId = pToolBox->GetHighlightItemId();
204 sal_uInt16 nFocusCount = 0;
205 for ( const auto& [rPos, rxChild] : m_aAccessibleChildren )
206 {
207 sal_uInt16 nItemId = pToolBox->GetItemId( rPos );
208
209 if ( rxChild.is() )
210 {
211 VCLXAccessibleToolBoxItem* pItem =
212 static_cast< VCLXAccessibleToolBoxItem* >( rxChild.get() );
213 if ( pItem->HasFocus() && nItemId != nHighlightItemId )
214 {
215 // reset the old focused item
216 pItem->SetFocus( false );
217 nFocusCount++;
218 }
219 if ( nItemId == nHighlightItemId )
220 {
221 // set the new focused item
222 pItem->SetFocus( true );
223 nFocusCount++;
224 }
225 }
226 // both items changed?
227 if ( nFocusCount > 1 )
228 break;
229 }
230}
231
232void VCLXAccessibleToolBox::ReleaseFocus_Impl( ToolBox::ImplToolItems::size_type _nPos )
233{
234 VclPtr< ToolBox > pToolBox = GetAs< ToolBox >();
235 if ( pToolBox ) // #107124#, do not check for focus because this message is also handled in losefocus
236 {
237 ToolBoxItemsMap::iterator aIter = m_aAccessibleChildren.find( _nPos );
238 //TODO: ToolBox::ImplToolItems::size_type -> sal_Int32!
239 if ( aIter != m_aAccessibleChildren.end() && aIter->second.is() )
240 {
241 VCLXAccessibleToolBoxItem* pItem =
242 static_cast< VCLXAccessibleToolBoxItem* >( aIter->second.get() );
243 if ( pItem->HasFocus() )
244 pItem->SetFocus( false );
245 }
246 }
247}
248
249void VCLXAccessibleToolBox::UpdateChecked_Impl( ToolBox::ImplToolItems::size_type _nPos )
250{
251 VclPtr< ToolBox > pToolBox = GetAs< ToolBox >();
252 if ( !pToolBox )
253 return;
254
255 sal_uInt16 nFocusId = pToolBox->GetItemId( _nPos );
256 VCLXAccessibleToolBoxItem* pFocusItem = nullptr;
257
258 for ( const auto& [rPos, rxChild] : m_aAccessibleChildren )
259 {
260 sal_uInt16 nItemId = pToolBox->GetItemId( rPos );
261
262 VCLXAccessibleToolBoxItem* pItem =
263 static_cast< VCLXAccessibleToolBoxItem* >( rxChild.get() );
264 pItem->SetChecked( pToolBox->IsItemChecked( nItemId ) );
265 if ( nItemId == nFocusId )
266 pFocusItem = pItem;
267 }
268 //Solution:If the position is not a child item,the focus should not be called
269 if ( pFocusItem && _nPos != ToolBox::ITEM_NOTFOUND )
270 pFocusItem->SetFocus( true );
271}
272
273void VCLXAccessibleToolBox::UpdateIndeterminate_Impl( ToolBox::ImplToolItems::size_type _nPos )
274{
275 VclPtr< ToolBox > pToolBox = GetAs< ToolBox >();
276 if ( !pToolBox )
277 return;
278
279 sal_uInt16 nItemId = pToolBox->GetItemId( _nPos );
280
281 ToolBoxItemsMap::iterator aIter = m_aAccessibleChildren.find( _nPos );
282 //TODO: ToolBox::ImplToolItems::size_type -> sal_Int32!
283 if ( aIter != m_aAccessibleChildren.end() && aIter->second.is() )
284 {
285 VCLXAccessibleToolBoxItem* pItem =
286 static_cast< VCLXAccessibleToolBoxItem* >( aIter->second.get() );
287 if ( pItem )
288 pItem->SetIndeterminate( pToolBox->GetItemState( nItemId ) == TRISTATE_INDET );
289 }
290}
291
292void VCLXAccessibleToolBox::implReleaseToolboxItem( ToolBoxItemsMap::iterator const & _rMapPos,
293 bool _bNotifyRemoval )
294{
295 Reference< XAccessible > xItemAcc( _rMapPos->second );
296 if ( !xItemAcc.is() )
297 return;
298
299 if ( _bNotifyRemoval )
300 {
301 NotifyAccessibleEvent( AccessibleEventId::CHILD, Any( xItemAcc ), Any() );
302 }
303
304 auto pWindowItem = comphelper::getUnoTunnelImplementation<OToolBoxWindowItem>(xItemAcc);
305 if ( !pWindowItem )
306 {
307 static_cast< VCLXAccessibleToolBoxItem* >( xItemAcc.get() )->ReleaseToolBox();
308 ::comphelper::disposeComponent( xItemAcc );
309 }
310 else
311 {
312 Reference< XAccessibleContext > xContext( pWindowItem->getContextNoCreate() );
313 ::comphelper::disposeComponent( xContext );
314 }
315}
316
317void VCLXAccessibleToolBox::UpdateItem_Impl( ToolBox::ImplToolItems::size_type _nPos)
318{
319 if ( _nPos < m_aAccessibleChildren.size() )
320 {
321 UpdateAllItems_Impl();
322 return;
323 }
324
325 VclPtr< ToolBox > pToolBox = GetAs< ToolBox >();
326 if ( !pToolBox )
327 return;
328
329 // adjust the "index-in-parent"s
330 ToolBoxItemsMap::iterator aIndexAdjust = m_aAccessibleChildren.upper_bound( _nPos );
331 //TODO: ToolBox::ImplToolItems::size_type -> sal_Int32!
332 while ( m_aAccessibleChildren.end() != aIndexAdjust )
333 {
334 Reference< XAccessible > xItemAcc( aIndexAdjust->second );
335
336 auto pWindowItem = comphelper::getUnoTunnelImplementation<OToolBoxWindowItem>(xItemAcc);
337 if ( !pWindowItem )
338 {
339 VCLXAccessibleToolBoxItem* pItem = static_cast< VCLXAccessibleToolBoxItem* >( xItemAcc.get() );
340 if ( pItem )
341 {
342 sal_Int32 nIndex = pItem->getIndexInParent( );
343 nIndex++;
344 pItem->setIndexInParent( nIndex );
345 }
346 }
347 else
348 {
349 sal_Int32 nIndex = pWindowItem->getIndexInParent( );
350 nIndex++;
351 pWindowItem->setIndexInParent( nIndex );
352 }
353
354 ++aIndexAdjust;
355 }
356
357 // TODO: we should make this dependent on the existence of event listeners
358 // with the current implementation, we always create accessible object
359 Any aNewChild( getAccessibleChild( static_cast<sal_Int32>(_nPos) ) );
360 //TODO: ToolBox::ImplToolItems::size_type -> sal_Int32!
361 NotifyAccessibleEvent( AccessibleEventId::CHILD, Any(), aNewChild );
362}
363
364void VCLXAccessibleToolBox::UpdateAllItems_Impl()
365{
366 VclPtr< ToolBox > pToolBox = GetAs< ToolBox >();
367 if ( !pToolBox )
368 return;
369
370 // deregister the old items
371 for ( ToolBoxItemsMap::iterator aIter = m_aAccessibleChildren.begin();
372 aIter != m_aAccessibleChildren.end(); ++aIter )
373 {
374 implReleaseToolboxItem( aIter, true );
375 }
376 m_aAccessibleChildren.clear();
377
378 // register the new items
379 ToolBox::ImplToolItems::size_type i, nCount = pToolBox->GetItemCount();
380 for ( i = 0; i < nCount; ++i )
381 {
382 Any aNewValue;
383 aNewValue <<= getAccessibleChild( static_cast<sal_Int32>(i) );
384 //TODO: ToolBox::ImplToolItems::size_type -> sal_Int32!
385 NotifyAccessibleEvent( AccessibleEventId::CHILD, Any(), aNewValue );
386 }
387}
388
389void VCLXAccessibleToolBox::UpdateCustomPopupItemp_Impl( vcl::Window* pWindow, bool bOpen )
390{
391 VclPtr< ToolBox > pToolBox = GetAs< ToolBox >();
392 if( !(pWindow && pToolBox) )
393 return;
394
395 const sal_uInt16 nDownItem = pToolBox->GetDownItemId();
396 if ( !nDownItem )
397 // No item is currently in down state.
398 // Moreover, calling GetItemPos with 0 will find a separator if there is any.
399 return;
400
401 Reference< XAccessible > xChild( pWindow->GetAccessible() );
402 if( xChild.is() )
403 {
404 Reference< XAccessible > xChildItem( getAccessibleChild( static_cast< sal_Int32 >( pToolBox->GetItemPos( nDownItem ) ) ) );
405 //TODO: ToolBox::ImplToolItems::size_type -> sal_Int32!
406 VCLXAccessibleToolBoxItem* pItem = static_cast< VCLXAccessibleToolBoxItem* >( xChildItem.get() );
407
408 pItem->SetChild( xChild );
409 pItem->NotifyChildEvent( xChild, bOpen );
410 }
411}
412
413void VCLXAccessibleToolBox::UpdateItemName_Impl( ToolBox::ImplToolItems::size_type _nPos )
414{
415 VCLXAccessibleToolBoxItem* pItem = GetItem_Impl( _nPos );
416 if ( pItem )
417 pItem->NameChanged();
418}
419
420void VCLXAccessibleToolBox::UpdateItemEnabled_Impl( ToolBox::ImplToolItems::size_type _nPos )
421{
422 VCLXAccessibleToolBoxItem* pItem = GetItem_Impl( _nPos );
423 if ( pItem )
424 pItem->ToggleEnableState();
425}
426
427void VCLXAccessibleToolBox::HandleSubToolBarEvent( const VclWindowEvent& rVclWindowEvent )
428{
429 vcl::Window* pChildWindow = static_cast<vcl::Window *>(rVclWindowEvent.GetData());
430 VclPtr< ToolBox > pToolBox = GetAs< ToolBox >();
431 if ( !(pChildWindow
432 && pToolBox
433 && pToolBox == pChildWindow->GetParent()
434 && pChildWindow->GetType() == WindowType::TOOLBOX) )
435 return;
436
437 const sal_uInt16 nCurItemId( pToolBox->GetCurItemId() );
438 if ( !nCurItemId )
439 // No item is currently active (might happen when opening the overflow popup).
440 // Moreover, calling GetItemPos with 0 will find a separator if there is any.
441 return;
442
443 ToolBox::ImplToolItems::size_type nIndex = pToolBox->GetItemPos( nCurItemId );
444 Reference< XAccessible > xItem = getAccessibleChild( nIndex );
445 //TODO: ToolBox::ImplToolItems::size_type -> sal_Int32!
446 if ( xItem.is() )
447 {
448 Reference< XAccessible > xChild = pChildWindow->GetAccessible();
449 VCLXAccessibleToolBoxItem* pItem =
450 static_cast< VCLXAccessibleToolBoxItem* >( xItem.get() );
451 pItem->SetChild( xChild );
452 pItem->NotifyChildEvent( xChild, true/*_bShow*/ );
453 }
454}
455
456void VCLXAccessibleToolBox::ReleaseSubToolBox( ToolBox* _pSubToolBox )
457{
458 VclPtr< ToolBox > pToolBox = GetAs< ToolBox >();
459 if ( !pToolBox )
460 return;
461
462 ToolBox::ImplToolItems::size_type nIndex = pToolBox->GetItemPos( pToolBox->GetCurItemId() );
463 if ( nIndex == ToolBox::ITEM_NOTFOUND )
464 return; // not found
465
466 Reference< XAccessible > xItem = getAccessibleChild( nIndex );
467 //TODO: ToolBox::ImplToolItems::size_type -> sal_Int32!
468 if ( !xItem.is() )
469 return;
470
471 Reference< XAccessible > xChild = _pSubToolBox->GetAccessible();
472 VCLXAccessibleToolBoxItem* pItem =
473 static_cast< VCLXAccessibleToolBoxItem* >( xItem.get() );
474 if ( pItem->GetChild() == xChild )
475 {
476 pItem->SetChild( Reference< XAccessible >() );
477 pItem->NotifyChildEvent( xChild, false );
478 }
479}
480
481void VCLXAccessibleToolBox::FillAccessibleStateSet( utl::AccessibleStateSetHelper& rStateSet )
482{
483 VCLXAccessibleComponent::FillAccessibleStateSet( rStateSet );
484
485 VclPtr< ToolBox > pToolBox = GetAs< ToolBox >();
486 if ( pToolBox )
487 {
488 rStateSet.AddState( AccessibleStateType::FOCUSABLE );
489 if ( pToolBox->IsHorizontal() )
490 rStateSet.AddState( AccessibleStateType::HORIZONTAL );
491 else
492 rStateSet.AddState( AccessibleStateType::VERTICAL );
493 }
494}
495
496void VCLXAccessibleToolBox::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent )
497{
498 // to prevent an early release of the toolbox (VclEventId::ObjectDying)
499 Reference< XAccessibleContext > xHoldAlive = this;
500
501 switch ( rVclWindowEvent.GetId() )
502 {
503 case VclEventId::ToolboxClick:
504 case VclEventId::ToolboxSelect:
505 {
506 VclPtr< ToolBox > pToolBox = GetAs< ToolBox >();
507 if ( rVclWindowEvent.GetData() )
508 {
509 UpdateChecked_Impl( static_cast<ToolBox::ImplToolItems::size_type>(reinterpret_cast<sal_IntPtr>(rVclWindowEvent.GetData())) );
510 UpdateIndeterminate_Impl( static_cast<ToolBox::ImplToolItems::size_type>(reinterpret_cast<sal_IntPtr>(rVclWindowEvent.GetData())) );
511 }
512 else if( pToolBox->GetItemPos(pToolBox->GetCurItemId()) != ToolBox::ITEM_NOTFOUND )
513 {
514 UpdateChecked_Impl( pToolBox->GetItemPos(pToolBox->GetCurItemId()) );
515 UpdateIndeterminate_Impl( pToolBox->GetItemPos(pToolBox->GetCurItemId()) );
516 }
517 break;
518 }
519 case VclEventId::ToolboxDoubleClick:
520 case VclEventId::ToolboxActivate:
521 case VclEventId::ToolboxDeactivate:
522 //case VclEventId::ToolboxSelect:
523 break;
524
525 case VclEventId::ToolboxItemUpdated:
526 {
527 if ( rVclWindowEvent.GetData() )
528 {
529 UpdateChecked_Impl( ToolBox::ITEM_NOTFOUND );
530 UpdateIndeterminate_Impl( static_cast<ToolBox::ImplToolItems::size_type>(reinterpret_cast<sal_IntPtr>(rVclWindowEvent.GetData())) );
531 }
532 break;
533 }
534
535 case VclEventId::ToolboxHighlight:
536 UpdateFocus_Impl();
537 break;
538
539 case VclEventId::ToolboxHighlightOff:
540 ReleaseFocus_Impl( static_cast<ToolBox::ImplToolItems::size_type>(reinterpret_cast<sal_IntPtr>(rVclWindowEvent.GetData())) );
541 break;
542
543 case VclEventId::ToolboxItemAdded :
544 UpdateItem_Impl( static_cast<ToolBox::ImplToolItems::size_type>(reinterpret_cast<sal_IntPtr>(rVclWindowEvent.GetData())) );
545 break;
546
547 case VclEventId::ToolboxItemRemoved :
548 case VclEventId::ToolboxAllItemsChanged :
549 {
550 UpdateAllItems_Impl();
551 break;
552 }
553
554 case VclEventId::ToolboxItemWindowChanged:
555 {
556 auto nPos = static_cast<ToolBox::ImplToolItems::size_type>(reinterpret_cast<sal_IntPtr>(rVclWindowEvent.GetData()));
557 ToolBoxItemsMap::iterator aAccessiblePos( m_aAccessibleChildren.find( nPos ) );
558 //TODO: ToolBox::ImplToolItems::size_type -> sal_Int32!
559 if ( m_aAccessibleChildren.end() != aAccessiblePos )
560 {
561 implReleaseToolboxItem( aAccessiblePos, false );
562 m_aAccessibleChildren.erase (aAccessiblePos);
563 }
564
565 Any aNewValue;
566 aNewValue <<= getAccessibleChild(nPos);
567 //TODO: ToolBox::ImplToolItems::size_type -> sal_Int32!
568 NotifyAccessibleEvent( AccessibleEventId::CHILD, Any(), aNewValue );
569 break;
570 }
571 case VclEventId::ToolboxItemTextChanged :
572 UpdateItemName_Impl( static_cast<ToolBox::ImplToolItems::size_type>(reinterpret_cast<sal_IntPtr>(rVclWindowEvent.GetData())) );
573 break;
574
575 case VclEventId::ToolboxItemEnabled :
576 case VclEventId::ToolboxItemDisabled :
577 {
578 UpdateItemEnabled_Impl( static_cast<ToolBox::ImplToolItems::size_type>(reinterpret_cast<sal_IntPtr>(rVclWindowEvent.GetData())) );
579 break;
580 }
581
582 case VclEventId::DropdownOpen:
583 case VclEventId::DropdownClose:
584 {
585 UpdateCustomPopupItemp_Impl( static_cast< vcl::Window* >( rVclWindowEvent.GetData() ), rVclWindowEvent.GetId() == VclEventId::DropdownOpen );
586 break;
587 }
588
589 case VclEventId::ObjectDying :
590 {
591 // if this toolbox is a subtoolbox, we have to release it from its parent
592 VclPtr< vcl::Window > pWin = GetAs< vcl::Window >();
593 if ( pWin && pWin->GetParent() &&
594 pWin->GetParent()->GetType() == WindowType::TOOLBOX )
595 {
596 VCLXAccessibleToolBox* pParent = static_cast< VCLXAccessibleToolBox* >(
597 pWin->GetParent()->GetAccessible()->getAccessibleContext().get() );
598 if ( pParent )
599 pParent->ReleaseSubToolBox(static_cast<ToolBox *>(pWin.get()));
600 }
601
602 // dispose all items
603 for ( ToolBoxItemsMap::iterator aIter = m_aAccessibleChildren.begin();
604 aIter != m_aAccessibleChildren.end(); ++aIter )
605 {
606 implReleaseToolboxItem( aIter, false );
607 }
608 m_aAccessibleChildren.clear();
609
610 [[fallthrough]]; // call base class
611 }
612
613 default:
614 VCLXAccessibleComponent::ProcessWindowEvent( rVclWindowEvent );
615 }
616}
617
618void VCLXAccessibleToolBox::ProcessWindowChildEvent( const VclWindowEvent& rVclWindowEvent )
619{
620 switch ( rVclWindowEvent.GetId() )
621 {
622 case VclEventId::WindowShow: // send create on show for direct accessible children
623 {
624 Reference< XAccessible > xReturn = GetItemWindowAccessible(rVclWindowEvent);
625 if ( xReturn.is() )
626 NotifyAccessibleEvent( AccessibleEventId::CHILD, Any(), Any(xReturn) );
627 else
628 HandleSubToolBarEvent( rVclWindowEvent );
629 }
630 break;
631
632 default:
633 VCLXAccessibleComponent::ProcessWindowChildEvent( rVclWindowEvent );
634
635 }
636}
637
638// XInterface
639IMPLEMENT_FORWARD_XINTERFACE2( VCLXAccessibleToolBox, VCLXAccessibleComponent, VCLXAccessibleToolBox_BASE )void VCLXAccessibleToolBox::acquire() throw() { VCLXAccessibleComponent
::acquire(); } void VCLXAccessibleToolBox::release() throw() {
VCLXAccessibleComponent::release(); } css::uno::Any VCLXAccessibleToolBox
::queryInterface( const css::uno::Type& _rType ) { css::uno
::Any aReturn = VCLXAccessibleComponent::queryInterface( _rType
); if ( !aReturn.hasValue() ) aReturn = VCLXAccessibleToolBox_BASE
::queryInterface( _rType ); return aReturn; }
640
641// XTypeProvider
642IMPLEMENT_FORWARD_XTYPEPROVIDER2( VCLXAccessibleToolBox, VCLXAccessibleComponent, VCLXAccessibleToolBox_BASE )css::uno::Sequence< css::uno::Type > VCLXAccessibleToolBox
::getTypes( ) { return ::comphelper::concatSequences( VCLXAccessibleComponent
::getTypes(), VCLXAccessibleToolBox_BASE::getTypes() ); } css
::uno::Sequence< sal_Int8 > VCLXAccessibleToolBox::getImplementationId
( ) { return css::uno::Sequence<sal_Int8>(); }
643
644// XComponent
645void SAL_CALL VCLXAccessibleToolBox::disposing()
646{
647 VCLXAccessibleComponent::disposing();
648
649 // release the items
650 for ( ToolBoxItemsMap::iterator aIter = m_aAccessibleChildren.begin();
651 aIter != m_aAccessibleChildren.end(); ++aIter )
652 {
653 implReleaseToolboxItem( aIter, false );
654 }
655 m_aAccessibleChildren.clear();
656}
657
658// XServiceInfo
659OUString VCLXAccessibleToolBox::getImplementationName()
660{
661 return "com.sun.star.comp.toolkit.AccessibleToolBox";
662}
663
664Sequence< OUString > VCLXAccessibleToolBox::getSupportedServiceNames()
665{
666 return comphelper::concatSequences(VCLXAccessibleComponent::getSupportedServiceNames(),
667 Sequence<OUString>{"com.sun.star.accessibility.AccessibleToolBox"});
668}
669
670// XAccessibleContext
671sal_Int32 SAL_CALL VCLXAccessibleToolBox::getAccessibleChildCount( )
672{
673 comphelper::OExternalLockGuard aGuard( this );
674 return implGetAccessibleChildCount();
675}
676
677 sal_Int32 VCLXAccessibleToolBox::implGetAccessibleChildCount( )
678 {
679 sal_Int32 nCount = 0;
680 VclPtr< ToolBox > pToolBox = GetAs< ToolBox >();
681 if ( pToolBox )
682 nCount = pToolBox->GetItemCount();
683 //TODO: ToolBox::ImplToolItems::size_type -> sal_Int32!
684
685 return nCount;
686}
687
688Reference< XAccessible > SAL_CALL VCLXAccessibleToolBox::getAccessibleChild( sal_Int32 i )
689{
690 comphelper::OExternalLockGuard aGuard( this );
691
692 VclPtr< ToolBox > pToolBox = GetAs< ToolBox >();
693 if ( (!pToolBox) || i < 0 || o3tl::make_unsigned(i) >= pToolBox->GetItemCount() )
694 throw IndexOutOfBoundsException();
695
696 Reference< XAccessible > xChild;
697 // search for the child
698 ToolBoxItemsMap::iterator aIter = m_aAccessibleChildren.find(i);
699 if ( m_aAccessibleChildren.end() == aIter )
700 {
701 sal_uInt16 nItemId = pToolBox->GetItemId( i );
702 sal_uInt16 nHighlightItemId = pToolBox->GetHighlightItemId();
703 vcl::Window* pItemWindow = pToolBox->GetItemWindow( nItemId );
704 // not found -> create a new child
705 VCLXAccessibleToolBoxItem* pChild = new VCLXAccessibleToolBoxItem( pToolBox, i );
706 Reference< XAccessible> xParent = pChild;
707 if ( pItemWindow )
708 {
709 xChild = new OToolBoxWindowItem(0,::comphelper::getProcessComponentContext(),pItemWindow->GetAccessible(),xParent);
710 pItemWindow->SetAccessible(xChild);
711 pChild->SetChild( xChild );
712 }
713 xChild = pChild;
714 if ( nHighlightItemId > 0 && nItemId == nHighlightItemId )
715 pChild->SetFocus( true );
716 if ( pToolBox->IsItemChecked( nItemId ) )
717 pChild->SetChecked( true );
718 if ( pToolBox->GetItemState( nItemId ) == TRISTATE_INDET )
719 pChild->SetIndeterminate( true );
720 m_aAccessibleChildren.emplace( i, xChild );
721 }
722 else
723 {
724 // found it
725 xChild = aIter->second;
726 }
727 return xChild;
728}
729
730Reference< XAccessible > SAL_CALL VCLXAccessibleToolBox::getAccessibleAtPoint( const awt::Point& _rPoint )
731{
732 comphelper::OExternalLockGuard aGuard( this );
733
734 Reference< XAccessible > xAccessible;
735 VclPtr< ToolBox > pToolBox = GetAs< ToolBox >();
736 if ( pToolBox )
737 {
738 ToolBox::ImplToolItems::size_type nItemPos = pToolBox->GetItemPos( VCLPoint( _rPoint ) );
739 if ( nItemPos != ToolBox::ITEM_NOTFOUND )
740 xAccessible = getAccessibleChild( nItemPos );
741 //TODO: ToolBox::ImplToolItems::size_type -> sal_Int32!
742 }
743
744 return xAccessible;
745}
746
747Reference< XAccessible > VCLXAccessibleToolBox::GetItemWindowAccessible( const VclWindowEvent& rVclWindowEvent )
748{
749 Reference< XAccessible > xReturn;
750 vcl::Window* pChildWindow = static_cast<vcl::Window *>(rVclWindowEvent.GetData());
751 VclPtr< ToolBox > pToolBox = GetAs< ToolBox >();
2
Calling 'VCLXAccessibleComponent::GetAs'
19
Returning; memory was released
752 if ( pChildWindow && pToolBox )
20
Assuming 'pChildWindow' is null
753 {
754 ToolBox::ImplToolItems::size_type nCount = pToolBox->GetItemCount();
755 for (ToolBox::ImplToolItems::size_type i = 0 ; i < nCount && !xReturn.is() ; ++i)
756 {
757 sal_uInt16 nItemId = pToolBox->GetItemId( i );
758 vcl::Window* pItemWindow = pToolBox->GetItemWindow( nItemId );
759 if ( pItemWindow == pChildWindow )
760 xReturn = getAccessibleChild(i);
761 //TODO: ToolBox::ImplToolItems::size_type -> sal_Int32!
762 }
763 }
764 return xReturn;
21
Calling implicit destructor for 'VclPtr<ToolBox>'
22
Calling '~Reference'
765}
766
767Reference< XAccessible > VCLXAccessibleToolBox::GetChildAccessible( const VclWindowEvent& rVclWindowEvent )
768{
769 Reference< XAccessible > xReturn = GetItemWindowAccessible(rVclWindowEvent);
1
Calling 'VCLXAccessibleToolBox::GetItemWindowAccessible'
770
771 if ( !xReturn.is() )
772 xReturn = VCLXAccessibleComponent::GetChildAccessible(rVclWindowEvent);
773 return xReturn;
774}
775
776// XAccessibleSelection
777void VCLXAccessibleToolBox::selectAccessibleChild( sal_Int32 nChildIndex )
778{
779 OExternalLockGuard aGuard( this );
780
781 VclPtr< ToolBox > pToolBox = GetAs< ToolBox >();
782 if ( (!pToolBox) || nChildIndex < 0 || o3tl::make_unsigned(nChildIndex) >= pToolBox->GetItemCount() )
783 throw IndexOutOfBoundsException();
784
785 pToolBox->ChangeHighlight( nChildIndex );
786}
787
788sal_Bool VCLXAccessibleToolBox::isAccessibleChildSelected( sal_Int32 nChildIndex )
789{
790 OExternalLockGuard aGuard( this );
791 VclPtr< ToolBox > pToolBox = GetAs< ToolBox >();
792 if ( (!pToolBox) || nChildIndex < 0 || o3tl::make_unsigned(nChildIndex) >= pToolBox->GetItemCount() )
793 throw IndexOutOfBoundsException();
794
795 if ( pToolBox->GetHighlightItemId() == pToolBox->GetItemId( nChildIndex ) )
796 return true;
797 else
798 return false;
799}
800
801void VCLXAccessibleToolBox::clearAccessibleSelection( )
802{
803 OExternalLockGuard aGuard( this );
804 VclPtr< ToolBox > pToolBox = GetAs< ToolBox >();
805 pToolBox -> LoseFocus();
806}
807
808void VCLXAccessibleToolBox::selectAllAccessibleChildren( )
809{
810 OExternalLockGuard aGuard( this );
811 // intentionally empty. makes no sense for a toolbox
812}
813
814sal_Int32 VCLXAccessibleToolBox::getSelectedAccessibleChildCount( )
815{
816 OExternalLockGuard aGuard( this );
817
818 sal_Int32 nRet = 0;
819 VclPtr< ToolBox > pToolBox = GetAs< ToolBox >();
820 if (pToolBox)
821 {
822 sal_uInt16 nHighlightItemId = pToolBox->GetHighlightItemId();
823 for ( size_t i = 0, nCount = pToolBox->GetItemCount(); i < nCount; i++ )
824 {
825 if ( nHighlightItemId == pToolBox->GetItemId( i ) )
826 {
827 nRet = 1;
828 break; // a toolbox can only have (n)one selected child
829 }
830 }
831 }
832
833 return nRet;
834}
835
836Reference< XAccessible > VCLXAccessibleToolBox::getSelectedAccessibleChild( sal_Int32 nSelectedChildIndex )
837{
838 OExternalLockGuard aGuard( this );
839 if ( nSelectedChildIndex != 0 )
840 throw IndexOutOfBoundsException();
841
842 Reference< XAccessible > xChild;
843 VclPtr< ToolBox > pToolBox = GetAs< ToolBox >();
844 if (pToolBox)
845 {
846 sal_uInt16 nHighlightItemId = pToolBox->GetHighlightItemId();
847 for ( sal_Int32 i = 0, nCount = pToolBox->GetItemCount(); i < nCount; i++ )
848 {
849 if ( nHighlightItemId == pToolBox->GetItemId( i ) )
850 {
851 xChild = getAccessibleChild( i );
852 break;
853 }
854 }
855 }
856
857 if (!xChild)
858 throw IndexOutOfBoundsException();
859
860 return xChild;
861}
862
863void VCLXAccessibleToolBox::deselectAccessibleChild( sal_Int32 nChildIndex )
864{
865 OExternalLockGuard aGuard( this );
866 if ( nChildIndex < 0 || nChildIndex >= implGetAccessibleChildCount() )
867 throw IndexOutOfBoundsException();
868 clearAccessibleSelection(); // a toolbox can only have (n)one selected child
869}
870
871/* 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() ) ); }
3
Calling constructor for 'VclPtr<ToolBox>'
8
Returning from constructor for 'VclPtr<ToolBox>'
9
Calling implicit destructor for 'VclPtr<vcl::Window>'
10
Calling '~Reference'
17
Returning from '~Reference'
18
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)
4
Calling constructor for 'Reference<ToolBox>'
7
Returning from constructor for 'Reference<ToolBox>'
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)
5
Assuming field 'm_pBody' is non-null
6
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
10.1
Field 'm_pBody' is non-null
22.1
Field 'm_pBody' is non-null
10.1
Field 'm_pBody' is non-null
22.1
Field 'm_pBody' is non-null
10.1
Field 'm_pBody' is non-null
22.1
Field 'm_pBody' is non-null
10.1
Field 'm_pBody' is non-null
22.1
Field 'm_pBody' is non-null
10.1
Field 'm_pBody' is non-null
22.1
Field 'm_pBody' is non-null
)
11
Taking true branch
23
Taking true branch
113 m_pBody->release();
12
Calling 'VclReferenceBase::release'
16
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)
13
Assuming the condition is true
14
Taking true branch
40 delete this;
15
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