Bug Summary

File:home/maarten/src/libreoffice/core/vcl/source/treelist/svtabbx.cxx
Warning:line 451, column 5
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 svtabbx.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 -isystem /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/glm -isystem /usr/include/glib-2.0 -isystem /usr/lib64/glib-2.0/include -isystem /usr/include/libmount -isystem /usr/include/blkid -isystem /usr/include/cairo -isystem /usr/include/glib-2.0 -isystem /usr/lib64/glib-2.0/include -isystem /usr/include/pixman-1 -isystem /usr/include/freetype2 -isystem /usr/include/libpng16 -isystem /usr/include/libxml2 -isystem /usr/include/freetype2 -isystem /usr/include/libpng16 -isystem /usr/include/dbus-1.0 -isystem /usr/lib64/dbus-1.0/include -isystem /usr/include/freetype2 -isystem /usr/include/libpng16 -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_DLLIMPLEMENTATION -D DLLIMPLEMENTATION_UITEST -D CUI_DLL_NAME="libcuilo.so" -D DESKTOP_DETECTOR_DLL_NAME="libdesktop_detectorlo.so" -D TK_DLL_NAME="libtklo.so" -D SYSTEM_ZLIB -D GLM_FORCE_CTOR_INIT -D SK_USER_CONFIG_HEADER=</home/maarten/src/libreoffice/core/config_host/config_skia.h> -D SKIA_DLL -D ENABLE_CUPS -D HAVE_VALGRIND_HEADERS -D EXCEPTIONS_ON -D LIBO_INTERNAL_ONLY -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/epoxy/include -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/skia/include/core -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/skia/include/effects -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/skia/include/gpu -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/skia/include/config -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/skia/include/ports -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/skia/include/third_party/vulkan -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/skia/tools/gpu -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/skia -I /home/maarten/src/libreoffice/core/external/skia/inc/ -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/mdds/include -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/lcms2/include -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/icu/source -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/icu/source/i18n -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/icu/source/common -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/harfbuzz/src -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/graphite/include -I /home/maarten/src/libreoffice/core/external/boost/include -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/boost -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/pdfium -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/pdfium/public -D COMPONENT_BUILD -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/libpng -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/libjpeg-turbo -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/vcl/inc -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/udkapi/normal -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/offapi/normal -I /home/maarten/src/libreoffice/core/workdir/CustomTarget/officecfg/registry -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libxml2 -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/vcl/source/treelist/svtabbx.cxx

/home/maarten/src/libreoffice/core/vcl/source/treelist/svtabbx.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 <vcl/svtaccessiblefactory.hxx>
21#include <vcl/accessiblefactory.hxx>
22#include <vcl/toolkit/svtabbx.hxx>
23#include <vcl/headbar.hxx>
24#include <vcl/toolkit/svlbitm.hxx>
25#include <vcl/toolkit/treelistentry.hxx>
26#include <unotools/accessiblestatesethelper.hxx>
27#include <com/sun/star/accessibility/AccessibleStateType.hpp>
28#include <rtl/ustrbuf.hxx>
29#include <sal/log.hxx>
30#include <o3tl/safeint.hxx>
31#include <osl/diagnose.h>
32#include <strings.hrc>
33#include <svdata.hxx>
34#include <memory>
35
36using namespace ::com::sun::star::uno;
37using namespace ::com::sun::star::accessibility;
38
39constexpr SvLBoxTabFlags MYTABMASK =
40 SvLBoxTabFlags::ADJUST_RIGHT | SvLBoxTabFlags::ADJUST_LEFT | SvLBoxTabFlags::ADJUST_CENTER | SvLBoxTabFlags::FORCE;
41
42// SvTreeListBox callback
43
44void SvTabListBox::SetTabs()
45{
46 SvTreeListBox::SetTabs();
47 if( mvTabList.empty() )
48 return;
49
50 DBG_ASSERT(!mvTabList.empty(),"TabList ?")do { if (true && (!(!mvTabList.empty()))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/vcl/source/treelist/svtabbx.cxx"
":" "50" ": "), "%s", "TabList ?"); } } while (false)
;
51
52 // The tree listbox has now inserted its tabs into the list. Now we
53 // fluff up the list with additional tabs and adjust the rightmost tab
54 // of the tree listbox.
55
56 // Picking the rightmost tab.
57 // HACK for the explorer! If ViewParent != 0, the first tab of the tree
58 // listbox is calculated by the tree listbox itself! This behavior is
59 // necessary for ButtonsOnRoot, as the explorer does not know in this
60 // case, which additional offset it needs to add to the tabs in this mode
61 // -- the tree listbox knows that, though!
62 /*
63 if( !pViewParent )
64 {
65 SvLBoxTab* pFirstTab = (SvLBoxTab*)aTabs.GetObject( aTabs.Count()-1 );
66 pFirstTab->SetPos( pTabList[0].GetPos() );
67 pFirstTab->nFlags &= ~MYTABMASK;
68 pFirstTab->nFlags |= pTabList[0].nFlags;
69 }
70 */
71
72 // append all other tabs to the list
73 for( sal_uInt16 nCurTab = 1; nCurTab < sal_uInt16(mvTabList.size()); nCurTab++ )
74 {
75 SvLBoxTab& rTab = mvTabList[nCurTab];
76 AddTab( rTab.GetPos(), rTab.nFlags );
77 }
78}
79
80void SvTabListBox::InitEntry(SvTreeListEntry* pEntry, const OUString& rStr,
81 const Image& rColl, const Image& rExp)
82{
83 SvTreeListBox::InitEntry(pEntry, rStr, rColl, rExp);
84
85 sal_Int32 nIndex = 0;
86 // TODO: verify if nTabCount is always >0 here!
87 const sal_uInt16 nCount = mvTabList.size() - 1;
88 for( sal_uInt16 nToken = 0; nToken < nCount; nToken++ )
89 {
90 const OUString aToken = GetToken(aCurEntry, nIndex);
91 pEntry->AddItem(std::make_unique<SvLBoxString>(aToken));
92 }
93}
94
95SvTabListBox::SvTabListBox( vcl::Window* pParent, WinBits nBits )
96 : SvTreeListBox( pParent, nBits )
97{
98 SetHighlightRange(); // select full width
99}
100
101SvTabListBox::~SvTabListBox()
102{
103 disposeOnce();
104}
105
106void SvTabListBox::dispose()
107{
108 mvTabList.clear();
109 SvTreeListBox::dispose();
110}
111
112void SvTabListBox::SetTabs(sal_uInt16 nTabs, long const pTabPositions[], MapUnit eMapUnit)
113{
114 mvTabList.resize(nTabs);
115
116 MapMode aMMSource( eMapUnit );
117 MapMode aMMDest( MapUnit::MapPixel );
118
119 for( sal_uInt16 nIdx = 0; nIdx < sal_uInt16(mvTabList.size()); nIdx++, pTabPositions++ )
120 {
121 Size aSize( *pTabPositions, 0 );
122 aSize = LogicToLogic( aSize, &aMMSource, &aMMDest );
123 long nNewTab = aSize.Width();
124 mvTabList[nIdx].SetPos( nNewTab );
125 mvTabList[nIdx].nFlags &= MYTABMASK;
126 }
127 SvTreeListBox::nTreeFlags |= SvTreeFlags::RECALCTABS;
128 if( IsUpdateMode() )
129 Invalidate();
130}
131
132SvTreeListEntry* SvTabListBox::InsertEntry( const OUString& rText, SvTreeListEntry* pParent,
133 bool /*bChildrenOnDemand*/,
134 sal_uLong nPos, void* pUserData )
135{
136 return InsertEntryToColumn( rText, pParent, nPos, 0xffff, pUserData );
137}
138
139SvTreeListEntry* SvTabListBox::InsertEntry( const OUString& rText,
140 const Image& rExpandedEntryBmp,
141 const Image& rCollapsedEntryBmp,
142 SvTreeListEntry* pParent,
143 bool /*bChildrenOnDemand*/,
144 sal_uLong nPos, void* pUserData )
145{
146 return InsertEntryToColumn( rText, rExpandedEntryBmp, rCollapsedEntryBmp,
147 pParent, nPos, 0xffff, pUserData );
148}
149
150SvTreeListEntry* SvTabListBox::InsertEntryToColumn(const OUString& rStr,SvTreeListEntry* pParent,sal_uLong nPos,sal_uInt16 nCol,
151 void* pUser )
152{
153 OUString aStr;
154 if( nCol != 0xffff )
155 {
156 while( nCol )
157 {
158 aStr += "\t";
159 nCol--;
160 }
161 }
162 aStr += rStr;
163 OUString aFirstStr( aStr );
164 sal_Int32 nEnd = aFirstStr.indexOf( '\t' );
165 if( nEnd != -1 )
166 {
167 aFirstStr = aFirstStr.copy(0, nEnd);
168 aCurEntry = aStr.copy(++nEnd);
169 }
170 else
171 aCurEntry.clear();
172 return SvTreeListBox::InsertEntry( aFirstStr, pParent, false, nPos, pUser );
173}
174
175SvTreeListEntry* SvTabListBox::InsertEntryToColumn( const OUString& rStr,
176 const Image& rExpandedEntryBmp, const Image& rCollapsedEntryBmp,
177 SvTreeListEntry* pParent,sal_uLong nPos,sal_uInt16 nCol, void* pUser )
178{
179 OUString aStr;
180 if( nCol != 0xffff )
181 {
182 while( nCol )
183 {
184 aStr += "\t";
185 nCol--;
186 }
187 }
188 aStr += rStr;
189 OUString aFirstStr( aStr );
190 sal_Int32 nEnd = aFirstStr.indexOf('\t');
191 if (nEnd != -1)
192 {
193 aFirstStr = aFirstStr.copy(0, nEnd);
194 aCurEntry = aStr.copy(++nEnd);
195 }
196 else
197 aCurEntry.clear();
198
199 return SvTreeListBox::InsertEntry(
200 aFirstStr,
201 rExpandedEntryBmp, rCollapsedEntryBmp,
202 pParent, false, nPos, pUser );
203}
204
205OUString SvTabListBox::GetEntryText( SvTreeListEntry* pEntry ) const
206{
207 return GetEntryText( pEntry, 0xffff );
208}
209
210OUString SvTabListBox::GetEntryText( SvTreeListEntry* pEntry, sal_uInt16 nCol )
211{
212 DBG_ASSERT(pEntry,"GetEntryText:Invalid Entry")do { if (true && (!(pEntry))) { sal_detail_logFormat(
(SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/vcl/source/treelist/svtabbx.cxx"
":" "212" ": "), "%s", "GetEntryText:Invalid Entry"); } } while
(false)
;
213 OUStringBuffer aResult;
214 if( pEntry )
215 {
216 sal_uInt16 nCount = pEntry->ItemCount();
217 sal_uInt16 nCur = 0;
218 while( nCur < nCount )
219 {
220 const SvLBoxItem& rStr = pEntry->GetItem( nCur );
221 if (rStr.GetType() == SvLBoxItemType::String)
222 {
223 if( nCol == 0xffff )
224 {
225 if (!aResult.isEmpty())
226 aResult.append("\t");
227 aResult.append(static_cast<const SvLBoxString&>(rStr).GetText());
228 }
229 else
230 {
231 if( nCol == 0 )
232 return static_cast<const SvLBoxString&>(rStr).GetText();
233 nCol--;
234 }
235 }
236 nCur++;
237 }
238 }
239 return aResult.makeStringAndClear();
240}
241
242OUString SvTabListBox::GetEntryText( sal_uLong nPos, sal_uInt16 nCol ) const
243{
244 SvTreeListEntry* pEntry = GetEntryOnPos( nPos );
245 return GetEntryText( pEntry, nCol );
246}
247
248OUString SvTabListBox::GetCellText( sal_uLong nPos, sal_uInt16 nCol ) const
249{
250 SvTreeListEntry* pEntry = GetEntryOnPos( nPos );
251 DBG_ASSERT( pEntry, "SvTabListBox::GetCellText(): Invalid Entry" )do { if (true && (!(pEntry))) { sal_detail_logFormat(
(SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/vcl/source/treelist/svtabbx.cxx"
":" "251" ": "), "%s", "SvTabListBox::GetCellText(): Invalid Entry"
); } } while (false)
;
252 OUString aResult;
253 if (pEntry && pEntry->ItemCount() > o3tl::make_unsigned(nCol+1))
254 {
255 const SvLBoxItem& rStr = pEntry->GetItem( nCol + 1 );
256 if (rStr.GetType() == SvLBoxItemType::String)
257 aResult = static_cast<const SvLBoxString&>(rStr).GetText();
258 }
259 return aResult;
260}
261
262sal_uLong SvTabListBox::GetEntryPos( const SvTreeListEntry* pEntry ) const
263{
264 sal_uLong nPos = 0;
265 SvTreeListEntry* pTmpEntry = First();
266 while( pTmpEntry )
267 {
268 if ( pTmpEntry == pEntry )
269 return nPos;
270 pTmpEntry = Next( pTmpEntry );
271 ++nPos;
272 }
273 return 0xffffffff;
274}
275
276// static
277OUString SvTabListBox::GetToken( const OUString &sStr, sal_Int32& nIndex )
278{
279 return sStr.getToken(0, '\t', nIndex);
280}
281
282OUString SvTabListBox::GetTabEntryText( sal_uLong nPos, sal_uInt16 nCol ) const
283{
284 SvTreeListEntry* pEntry = SvTreeListBox::GetEntry( nPos );
285 DBG_ASSERT( pEntry, "GetTabEntryText(): Invalid entry " )do { if (true && (!(pEntry))) { sal_detail_logFormat(
(SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/vcl/source/treelist/svtabbx.cxx"
":" "285" ": "), "%s", "GetTabEntryText(): Invalid entry ");
} } while (false)
;
286 OUStringBuffer aResult;
287 if ( pEntry )
288 {
289 sal_uInt16 nCount = pEntry->ItemCount();
290 sal_uInt16 nCur = 0;
291 while( nCur < nCount )
292 {
293 const SvLBoxItem& rBoxItem = pEntry->GetItem( nCur );
294 if (rBoxItem.GetType() == SvLBoxItemType::String)
295 {
296 if ( nCol == 0xffff )
297 {
298 if (!aResult.isEmpty())
299 aResult.append("\t");
300 aResult.append(static_cast<const SvLBoxString&>(rBoxItem).GetText());
301 }
302 else
303 {
304 if ( nCol == 0 )
305 {
306 OUString sRet = static_cast<const SvLBoxString&>(rBoxItem).GetText();
307 if ( sRet.isEmpty() )
308 sRet = VclResId( STR_SVT_ACC_EMPTY_FIELDreinterpret_cast<char const *>("STR_SVT_ACC_EMPTY_FIELD"
"\004" u8"Empty Field")
);
309 return sRet;
310 }
311 --nCol;
312 }
313 }
314 ++nCur;
315 }
316 }
317 return aResult.makeStringAndClear();
318}
319
320SvTreeListEntry* SvTabListBox::GetEntryOnPos( sal_uLong _nEntryPos ) const
321{
322 SvTreeListEntry* pEntry = nullptr;
323 sal_uLong i, nPos = 0, nCount = GetLevelChildCount( nullptr );
324 for ( i = 0; i < nCount; ++i )
325 {
326 SvTreeListEntry* pParent = GetEntry(i);
327 if ( nPos == _nEntryPos )
328 {
329 pEntry = pParent;
330 break;
331 }
332 else
333 {
334 nPos++;
335 pEntry = GetChildOnPos( pParent, _nEntryPos, nPos );
336 if ( pEntry )
337 break;
338 }
339 }
340
341 return pEntry;
342}
343
344SvTreeListEntry* SvTabListBox::GetChildOnPos( SvTreeListEntry* _pParent, sal_uLong _nEntryPos, sal_uLong& _rPos ) const
345{
346 sal_uLong i, nCount = GetLevelChildCount( _pParent );
347 for ( i = 0; i < nCount; ++i )
348 {
349 SvTreeListEntry* pParent = GetEntry( _pParent, i );
350 if ( _rPos == _nEntryPos )
351 return pParent;
352 else
353 {
354 _rPos++;
355 SvTreeListEntry* pEntry = GetChildOnPos( pParent, _nEntryPos, _rPos );
356 if ( pEntry )
357 return pEntry;
358 }
359 }
360
361 return nullptr;
362}
363
364void SvTabListBox::SetTabJustify( sal_uInt16 nTab, SvTabJustify eJustify)
365{
366 DBG_ASSERT(nTab<mvTabList.size(),"GetTabPos:Invalid Tab")do { if (true && (!(nTab<mvTabList.size()))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/vcl/source/treelist/svtabbx.cxx"
":" "366" ": "), "%s", "GetTabPos:Invalid Tab"); } } while (
false)
;
367 if( nTab >= mvTabList.size() )
368 return;
369 SvLBoxTab& rTab = mvTabList[ nTab ];
370 SvLBoxTabFlags nFlags = rTab.nFlags;
371 nFlags &= ~MYTABMASK;
372 // see SvLBoxTab::CalcOffset for force, which only matters for centering
373 nFlags |= static_cast<SvLBoxTabFlags>(eJustify) | SvLBoxTabFlags::FORCE;
374 rTab.nFlags = nFlags;
375 SvTreeListBox::nTreeFlags |= SvTreeFlags::RECALCTABS;
376 if( IsUpdateMode() )
377 Invalidate();
378}
379
380void SvTabListBox::SetTabEditable(sal_uInt16 nTab, bool bEditable)
381{
382 DBG_ASSERT(nTab<mvTabList.size(),"GetTabPos:Invalid Tab")do { if (true && (!(nTab<mvTabList.size()))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/vcl/source/treelist/svtabbx.cxx"
":" "382" ": "), "%s", "GetTabPos:Invalid Tab"); } } while (
false)
;
383 if( nTab >= mvTabList.size() )
384 return;
385 SvLBoxTab& rTab = mvTabList[ nTab ];
386 if (bEditable)
387 rTab.nFlags |= SvLBoxTabFlags::EDITABLE;
388 else
389 rTab.nFlags &= ~SvLBoxTabFlags::EDITABLE;
390}
391
392long SvTabListBox::GetLogicTab( sal_uInt16 nTab )
393{
394 if( SvTreeListBox::nTreeFlags & SvTreeFlags::RECALCTABS )
395 SetTabs();
396
397 DBG_ASSERT(nTab<mvTabList.size(),"GetTabPos:Invalid Tab")do { if (true && (!(nTab<mvTabList.size()))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/vcl/source/treelist/svtabbx.cxx"
":" "397" ": "), "%s", "GetTabPos:Invalid Tab"); } } while (
false)
;
398 return aTabs[ nTab ]->GetPos();
399}
400
401namespace vcl
402{
403 struct SvHeaderTabListBoxImpl
404 {
405 VclPtr<HeaderBar> m_pHeaderBar;
406 AccessibleFactoryAccess m_aFactoryAccess;
407
408 SvHeaderTabListBoxImpl() : m_pHeaderBar( nullptr ) { }
409 };
410}
411
412SvHeaderTabListBox::SvHeaderTabListBox( vcl::Window* pParent, WinBits nWinStyle )
413 : SvTabListBox(pParent, nWinStyle)
414 , m_bFirstPaint(true)
415 , m_pImpl(new ::vcl::SvHeaderTabListBoxImpl)
416 , m_pAccessible(nullptr)
417{
418}
419
420SvHeaderTabListBox::~SvHeaderTabListBox()
421{
422 disposeOnce();
423}
424
425void SvHeaderTabListBox::dispose()
426{
427 m_pImpl.reset();
428 SvTabListBox::dispose();
429}
430
431void SvHeaderTabListBox::Paint( vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect )
432{
433 if (m_bFirstPaint)
434 {
435 m_bFirstPaint = false;
436 }
437 SvTabListBox::Paint(rRenderContext, rRect);
438}
439
440void SvHeaderTabListBox::InitHeaderBar( HeaderBar* pHeaderBar )
441{
442 DBG_ASSERT( !m_pImpl->m_pHeaderBar, "header bar already initialized" )do { if (true && (!(!m_pImpl->m_pHeaderBar))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/vcl/source/treelist/svtabbx.cxx"
":" "442" ": "), "%s", "header bar already initialized"); } }
while (false)
;
443 DBG_ASSERT( pHeaderBar, "invalid header bar initialization" )do { if (true && (!(pHeaderBar))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/vcl/source/treelist/svtabbx.cxx"
":" "443" ": "), "%s", "invalid header bar initialization");
} } while (false)
;
444 m_pImpl->m_pHeaderBar = pHeaderBar;
445 SetScrolledHdl( LINK( this, SvHeaderTabListBox, ScrollHdl_Impl )::tools::detail::makeLink( ::tools::detail::castTo<SvHeaderTabListBox
*>(this), &SvHeaderTabListBox::LinkStubScrollHdl_Impl
)
);
446 m_pImpl->m_pHeaderBar->SetCreateAccessibleHdl( LINK( this, SvHeaderTabListBox, CreateAccessibleHdl_Impl )::tools::detail::makeLink( ::tools::detail::castTo<SvHeaderTabListBox
*>(this), &SvHeaderTabListBox::LinkStubCreateAccessibleHdl_Impl
)
);
447}
448
449HeaderBar* SvHeaderTabListBox::GetHeaderBar()
450{
451 return m_pImpl ? m_pImpl->m_pHeaderBar : nullptr;
1
'?' condition is true
2
Calling implicit copy constructor for 'VclPtr<HeaderBar>'
3
Calling copy constructor for 'Reference<HeaderBar>'
6
Returning from copy constructor for 'Reference<HeaderBar>'
7
Returning from copy constructor for 'VclPtr<HeaderBar>'
8
Calling implicit destructor for 'VclPtr<HeaderBar>'
9
Calling '~Reference'
16
Returning from '~Reference'
17
Returning from destructor for 'VclPtr<HeaderBar>'
18
Use of memory after it is freed
452}
453
454bool SvHeaderTabListBox::IsItemChecked( SvTreeListEntry* pEntry, sal_uInt16 nCol )
455{
456 SvButtonState eState = SvButtonState::Unchecked;
457 SvLBoxButton& rItem = static_cast<SvLBoxButton&>( pEntry->GetItem( nCol + 1 ) );
458
459 if (rItem.GetType() == SvLBoxItemType::Button)
460 {
461 SvItemStateFlags nButtonFlags = rItem.GetButtonFlags();
462 eState = SvLBoxButtonData::ConvertToButtonState( nButtonFlags );
463 }
464
465 return ( eState == SvButtonState::Checked );
466}
467
468SvTreeListEntry* SvHeaderTabListBox::InsertEntryToColumn(
469 const OUString& rStr, SvTreeListEntry* pParent, sal_uLong nPos, sal_uInt16 nCol, void* pUserData )
470{
471 SvTreeListEntry* pEntry = SvTabListBox::InsertEntryToColumn( rStr, pParent, nPos, nCol, pUserData );
472 RecalculateAccessibleChildren();
473 return pEntry;
474}
475
476SvTreeListEntry* SvHeaderTabListBox::InsertEntryToColumn(
477 const OUString& rStr, const Image& rExpandedEntryBmp, const Image& rCollapsedEntryBmp,
478 SvTreeListEntry* pParent, sal_uLong nPos, sal_uInt16 nCol, void* pUserData )
479{
480 SvTreeListEntry* pEntry = SvTabListBox::InsertEntryToColumn(
481 rStr, rExpandedEntryBmp, rCollapsedEntryBmp, pParent, nPos, nCol, pUserData );
482 RecalculateAccessibleChildren();
483 return pEntry;
484}
485
486sal_uLong SvHeaderTabListBox::Insert(
487 SvTreeListEntry* pEnt, SvTreeListEntry* pPar, sal_uLong nPos )
488{
489 sal_uLong n = SvTabListBox::Insert( pEnt, pPar, nPos );
490 RecalculateAccessibleChildren();
491 return n;
492}
493
494sal_uLong SvHeaderTabListBox::Insert( SvTreeListEntry* pEntry, sal_uLong nRootPos )
495{
496 sal_uLong nPos = SvTabListBox::Insert( pEntry, nRootPos );
497 RecalculateAccessibleChildren();
498 return nPos;
499}
500
501IMPL_LINK_NOARG(SvHeaderTabListBox, ScrollHdl_Impl, SvTreeListBox*, void)void SvHeaderTabListBox::LinkStubScrollHdl_Impl(void * instance
, SvTreeListBox* data) { return static_cast<SvHeaderTabListBox
*>(instance)->ScrollHdl_Impl(data); } void SvHeaderTabListBox
::ScrollHdl_Impl(__attribute__ ((unused)) SvTreeListBox*)
502{
503 m_pImpl->m_pHeaderBar->SetOffset( -GetXOffset() );
504}
505
506IMPL_LINK_NOARG(SvHeaderTabListBox, CreateAccessibleHdl_Impl, HeaderBar*, void)void SvHeaderTabListBox::LinkStubCreateAccessibleHdl_Impl(void
* instance, HeaderBar* data) { return static_cast<SvHeaderTabListBox
*>(instance)->CreateAccessibleHdl_Impl(data); } void SvHeaderTabListBox
::CreateAccessibleHdl_Impl(__attribute__ ((unused)) HeaderBar
*)
507{
508 vcl::Window* pParent = m_pImpl->m_pHeaderBar->GetAccessibleParentWindow();
509 DBG_ASSERT( pParent, "SvHeaderTabListBox..CreateAccessibleHdl_Impl - accessible parent not found" )do { if (true && (!(pParent))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/vcl/source/treelist/svtabbx.cxx"
":" "509" ": "), "%s", "SvHeaderTabListBox..CreateAccessibleHdl_Impl - accessible parent not found"
); } } while (false)
;
510 if ( pParent )
511 {
512 css::uno::Reference< XAccessible > xAccParent = pParent->GetAccessible();
513 if ( xAccParent.is() )
514 {
515 Reference< XAccessible > xAccessible = m_pImpl->m_aFactoryAccess.getFactory().createAccessibleBrowseBoxHeaderBar(
516 xAccParent, *this, ::vcl::BBTYPE_COLUMNHEADERBAR );
517 m_pImpl->m_pHeaderBar->SetAccessible( xAccessible );
518 }
519 }
520}
521
522void SvHeaderTabListBox::RecalculateAccessibleChildren()
523{
524 if ( !m_aAccessibleChildren.empty() )
525 {
526 sal_uInt32 nCount = ( GetRowCount() + 1 ) * GetColumnCount();
527 if ( m_aAccessibleChildren.size() < nCount )
528 m_aAccessibleChildren.resize( nCount );
529 else
530 {
531 DBG_ASSERT( m_aAccessibleChildren.size() == nCount, "wrong children count" )do { if (true && (!(m_aAccessibleChildren.size() == nCount
))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"
), ("/home/maarten/src/libreoffice/core/vcl/source/treelist/svtabbx.cxx"
":" "531" ": "), "%s", "wrong children count"); } } while (false
)
;
532 }
533 }
534}
535
536bool SvHeaderTabListBox::IsCellCheckBox( long _nRow, sal_uInt16 _nColumn, TriState& _rState )
537{
538 bool bRet = false;
539 SvTreeListEntry* pEntry = GetEntry( _nRow );
540 if ( pEntry )
541 {
542 sal_uInt16 nItemCount = pEntry->ItemCount();
543 if ( nItemCount > ( _nColumn + 1 ) )
544 {
545 SvLBoxItem& rItem = pEntry->GetItem( _nColumn + 1 );
546 if (rItem.GetType() == SvLBoxItemType::Button)
547 {
548 bRet = true;
549 _rState = ( ( static_cast<SvLBoxButton&>(rItem).GetButtonFlags() & SvItemStateFlags::UNCHECKED ) == SvItemStateFlags::NONE )
550 ? TRISTATE_TRUE : TRISTATE_FALSE;
551 }
552 }
553 else
554 {
555 SAL_WARN( "svtools.contnr", "SvHeaderTabListBox::IsCellCheckBox(): column out of range" )do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN
, "svtools.contnr")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break
; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "SvHeaderTabListBox::IsCellCheckBox(): column out of range"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("svtools.contnr"
), ("/home/maarten/src/libreoffice/core/vcl/source/treelist/svtabbx.cxx"
":" "555" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "SvHeaderTabListBox::IsCellCheckBox(): column out of range"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "SvHeaderTabListBox::IsCellCheckBox(): column out of range"
; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("svtools.contnr"
), ("/home/maarten/src/libreoffice/core/vcl/source/treelist/svtabbx.cxx"
":" "555" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "SvHeaderTabListBox::IsCellCheckBox(): column out of range"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("svtools.contnr"
), ("/home/maarten/src/libreoffice/core/vcl/source/treelist/svtabbx.cxx"
":" "555" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "SvHeaderTabListBox::IsCellCheckBox(): column out of range"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "SvHeaderTabListBox::IsCellCheckBox(): column out of range"
; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("svtools.contnr"
), ("/home/maarten/src/libreoffice/core/vcl/source/treelist/svtabbx.cxx"
":" "555" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
556 }
557 }
558 return bRet;
559}
560long SvHeaderTabListBox::GetRowCount() const
561{
562 return GetEntryCount();
563}
564
565sal_uInt16 SvHeaderTabListBox::GetColumnCount() const
566{
567 return m_pImpl->m_pHeaderBar->GetItemCount();
568}
569
570sal_Int32 SvHeaderTabListBox::GetCurrRow() const
571{
572 sal_Int32 nRet = -1;
573 SvTreeListEntry* pEntry = GetCurEntry();
574 if ( pEntry )
575 {
576 sal_uLong nCount = GetEntryCount();
577 for ( sal_uLong i = 0; i < nCount; ++i )
578 {
579 if ( pEntry == GetEntry(i) )
580 {
581 nRet = i;
582 break;
583 }
584 }
585 }
586
587 return nRet;
588}
589
590sal_uInt16 SvHeaderTabListBox::GetCurrColumn() const
591{
592 return 0;
593}
594
595OUString SvHeaderTabListBox::GetRowDescription( sal_Int32 _nRow ) const
596{
597 return GetEntryText( _nRow );
598}
599
600OUString SvHeaderTabListBox::GetColumnDescription( sal_uInt16 _nColumn ) const
601{
602 return m_pImpl->m_pHeaderBar->GetItemText( m_pImpl->m_pHeaderBar->GetItemId( _nColumn ) );
603}
604
605bool SvHeaderTabListBox::HasRowHeader() const
606{
607 return false;
608}
609
610bool SvHeaderTabListBox::GoToCell( sal_Int32 /*_nRow*/, sal_uInt16 /*_nColumn*/ )
611{
612 return false;
613}
614
615void SvHeaderTabListBox::SetNoSelection()
616{
617 SvTreeListBox::SelectAll(false);
618}
619
620void SvHeaderTabListBox::SelectAll()
621{
622 SvTreeListBox::SelectAll(true);
623}
624
625void SvHeaderTabListBox::SelectRow( long _nRow, bool _bSelect, bool )
626{
627 Select( GetEntry( _nRow ), _bSelect );
628}
629
630void SvHeaderTabListBox::SelectColumn( sal_uInt16, bool )
631{
632}
633
634sal_Int32 SvHeaderTabListBox::GetSelectedRowCount() const
635{
636 return GetSelectionCount();
637}
638
639sal_Int32 SvHeaderTabListBox::GetSelectedColumnCount() const
640{
641 return 0;
642}
643
644bool SvHeaderTabListBox::IsRowSelected( long _nRow ) const
645{
646 SvTreeListEntry* pEntry = GetEntry( _nRow );
647 return ( pEntry && IsSelected( pEntry ) );
648}
649
650bool SvHeaderTabListBox::IsColumnSelected( long ) const
651{
652 return false;
653}
654
655void SvHeaderTabListBox::GetAllSelectedRows( css::uno::Sequence< sal_Int32 >& ) const
656{
657}
658
659void SvHeaderTabListBox::GetAllSelectedColumns( css::uno::Sequence< sal_Int32 >& ) const
660{
661}
662
663bool SvHeaderTabListBox::IsCellVisible( sal_Int32, sal_uInt16 ) const
664{
665 return true;
666}
667
668OUString SvHeaderTabListBox::GetAccessibleCellText( long _nRow, sal_uInt16 _nColumnPos ) const
669{
670 return GetTabEntryText(_nRow, _nColumnPos);
671}
672
673tools::Rectangle SvHeaderTabListBox::calcHeaderRect( bool _bIsColumnBar, bool _bOnScreen )
674{
675 tools::Rectangle aRect;
676 if ( _bIsColumnBar )
677 {
678 vcl::Window* pParent = nullptr;
679 if ( !_bOnScreen )
680 pParent = m_pImpl->m_pHeaderBar->GetAccessibleParentWindow();
681
682 aRect = m_pImpl->m_pHeaderBar->GetWindowExtentsRelative( pParent );
683 }
684 return aRect;
685}
686
687tools::Rectangle SvHeaderTabListBox::calcTableRect( bool _bOnScreen )
688{
689 vcl::Window* pParent = nullptr;
690 if ( !_bOnScreen )
691 pParent = GetAccessibleParentWindow();
692
693 tools::Rectangle aRect( GetWindowExtentsRelative( pParent ) );
694 return aRect;
695}
696
697tools::Rectangle SvHeaderTabListBox::GetFieldRectPixelAbs( sal_Int32 _nRow, sal_uInt16 _nColumn, bool _bIsHeader, bool _bOnScreen )
698{
699 DBG_ASSERT( !_bIsHeader || 0 == _nRow, "invalid parameters" )do { if (true && (!(!_bIsHeader || 0 == _nRow))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/vcl/source/treelist/svtabbx.cxx"
":" "699" ": "), "%s", "invalid parameters"); } } while (false
)
;
700 tools::Rectangle aRect;
701 SvTreeListEntry* pEntry = GetEntry( _nRow );
702 if ( pEntry )
703 {
704 aRect = _bIsHeader ? calcHeaderRect( true, false ) : GetBoundingRect( pEntry );
705 Point aTopLeft = aRect.TopLeft();
706 DBG_ASSERT( m_pImpl->m_pHeaderBar->GetItemCount() > _nColumn, "invalid column" )do { if (true && (!(m_pImpl->m_pHeaderBar->GetItemCount
() > _nColumn))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN
), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/vcl/source/treelist/svtabbx.cxx"
":" "706" ": "), "%s", "invalid column"); } } while (false)
;
707 tools::Rectangle aItemRect = m_pImpl->m_pHeaderBar->GetItemRect( m_pImpl->m_pHeaderBar->GetItemId( _nColumn ) );
708 aTopLeft.setX( aItemRect.Left() );
709 Size aSize = aItemRect.GetSize();
710 aRect = tools::Rectangle( aTopLeft, aSize );
711 vcl::Window* pParent = nullptr;
712 if ( !_bOnScreen )
713 pParent = GetAccessibleParentWindow();
714 aTopLeft = aRect.TopLeft();
715 aTopLeft += GetWindowExtentsRelative( pParent ).TopLeft();
716 aRect = tools::Rectangle( aTopLeft, aRect.GetSize() );
717 }
718
719 return aRect;
720}
721
722Reference< XAccessible > SvHeaderTabListBox::CreateAccessibleCell( sal_Int32 _nRow, sal_uInt16 _nColumnPos )
723{
724 OSL_ENSURE( m_pAccessible, "Invalid call: Accessible is null" )do { if (true && (!(m_pAccessible))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/vcl/source/treelist/svtabbx.cxx"
":" "724" ": "), "%s", "Invalid call: Accessible is null"); }
} while (false)
;
725
726 Reference< XAccessible > xChild;
727
728 TriState eState = TRISTATE_INDET;
729 bool bIsCheckBox = IsCellCheckBox( _nRow, _nColumnPos, eState );
730 if ( bIsCheckBox )
731 xChild = m_pImpl->m_aFactoryAccess.getFactory().createAccessibleCheckBoxCell(
732 m_pAccessible->getHeaderBar(), *this, nullptr, _nRow, _nColumnPos, eState, false );
733 else
734 xChild = m_pImpl->m_aFactoryAccess.getFactory().createAccessibleBrowseBoxTableCell(
735 m_pAccessible->getHeaderBar(), *this, nullptr, _nRow, _nColumnPos, OFFSET_NONE(sal_Int32(0)) );
736
737 return xChild;
738}
739
740Reference< XAccessible > SvHeaderTabListBox::CreateAccessibleRowHeader( sal_Int32 )
741{
742 Reference< XAccessible > xHeader;
743 return xHeader;
744}
745
746Reference< XAccessible > SvHeaderTabListBox::CreateAccessibleColumnHeader( sal_uInt16 _nColumn )
747{
748 // first call? -> initial list
749 if ( m_aAccessibleChildren.empty() )
750 {
751 const sal_uInt16 nColumnCount = GetColumnCount();
752 m_aAccessibleChildren.assign( nColumnCount, Reference< XAccessible >() );
753 }
754
755 // get header
756 Reference< XAccessible > xChild = m_aAccessibleChildren[ _nColumn ];
757 // already exists?
758 if ( !xChild.is() && m_pAccessible )
759 {
760 // no -> create new header cell
761 xChild = m_pImpl->m_aFactoryAccess.getFactory().createAccessibleBrowseBoxHeaderCell(
762 _nColumn, m_pAccessible->getHeaderBar(),
763 *this, nullptr, ::vcl::BBTYPE_COLUMNHEADERCELL
764 );
765
766 // insert into list
767 m_aAccessibleChildren[ _nColumn ] = xChild;
768 }
769 return xChild;
770}
771
772sal_Int32 SvHeaderTabListBox::GetAccessibleControlCount() const
773{
774 return -1;
775}
776
777Reference< XAccessible > SvHeaderTabListBox::CreateAccessibleControl( sal_Int32 )
778{
779 Reference< XAccessible > xControl;
780 return xControl;
781}
782
783bool SvHeaderTabListBox::ConvertPointToControlIndex( sal_Int32&, const Point& )
784{
785 return false;
786}
787
788bool SvHeaderTabListBox::ConvertPointToCellAddress( sal_Int32&, sal_uInt16&, const Point& )
789{
790 return false;
791}
792
793bool SvHeaderTabListBox::ConvertPointToRowHeader( sal_Int32&, const Point& )
794{
795 return false;
796}
797
798bool SvHeaderTabListBox::ConvertPointToColumnHeader( sal_uInt16&, const Point& )
799{
800 return false;
801}
802
803OUString SvHeaderTabListBox::GetAccessibleObjectName( ::vcl::AccessibleBrowseBoxObjType _eType, sal_Int32 _nPos ) const
804{
805 OUString aRetText;
806 switch( _eType )
807 {
808 case ::vcl::BBTYPE_BROWSEBOX:
809 case ::vcl::BBTYPE_TABLE:
810 case ::vcl::BBTYPE_COLUMNHEADERBAR:
811 // should be empty now (see #i63983)
812 aRetText.clear();
813 break;
814
815 case ::vcl::BBTYPE_TABLECELL:
816 {
817 // here we need a valid pos, we can not handle -1
818 if ( _nPos >= 0 )
819 {
820 sal_uInt16 nColumnCount = GetColumnCount();
821 if (nColumnCount > 0)
822 {
823 sal_Int32 nRow = _nPos / nColumnCount;
824 sal_uInt16 nColumn = static_cast< sal_uInt16 >( _nPos % nColumnCount );
825 aRetText = GetCellText( nRow, nColumn );
826 }
827 }
828 break;
829 }
830 case ::vcl::BBTYPE_CHECKBOXCELL:
831 {
832 break; // checkbox cells have no name
833 }
834 case ::vcl::BBTYPE_COLUMNHEADERCELL:
835 {
836 aRetText = m_pImpl->m_pHeaderBar->GetItemText( m_pImpl->m_pHeaderBar->GetItemId( static_cast<sal_uInt16>(_nPos) ) );
837 break;
838 }
839
840 case ::vcl::BBTYPE_ROWHEADERBAR:
841 case ::vcl::BBTYPE_ROWHEADERCELL:
842 aRetText = "error";
843 break;
844
845 default:
846 OSL_FAIL("BrowseBox::GetAccessibleName: invalid enum!")do { if (true && (((sal_Bool)1))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/vcl/source/treelist/svtabbx.cxx"
":" "846" ": "), "%s", "BrowseBox::GetAccessibleName: invalid enum!"
); } } while (false)
;
847 }
848 return aRetText;
849}
850
851OUString SvHeaderTabListBox::GetAccessibleObjectDescription( ::vcl::AccessibleBrowseBoxObjType _eType, sal_Int32 _nPos ) const
852{
853 OUString aRetText;
854
855 if( _eType == ::vcl::BBTYPE_TABLECELL && _nPos != -1 )
856 {
857 sal_uInt16 nColumnCount = GetColumnCount();
858 if (nColumnCount > 0)
859 {
860 sal_Int32 nRow = _nPos / nColumnCount;
861 sal_uInt16 nColumn = static_cast< sal_uInt16 >( _nPos % nColumnCount );
862
863 OUString aText( VclResId(STR_SVT_ACC_DESC_TABLISTBOXreinterpret_cast<char const *>("STR_SVT_ACC_DESC_TABLISTBOX"
"\004" u8"Row: %1, Column: %2")
) );
864 aText = aText.replaceFirst( "%1", OUString::number( nRow ) );
865 OUString sColHeader = m_pImpl->m_pHeaderBar->GetItemText( m_pImpl->m_pHeaderBar->GetItemId( nColumn ) );
866 if ( sColHeader.isEmpty() )
867 sColHeader = OUString::number( nColumn );
868 aText = aText.replaceFirst( "%2", sColHeader );
869 aRetText = aText;
870 }
871 }
872
873 return aRetText;
874}
875
876void SvHeaderTabListBox::FillAccessibleStateSet( ::utl::AccessibleStateSetHelper& _rStateSet, ::vcl::AccessibleBrowseBoxObjType _eType ) const
877{
878 switch( _eType )
879 {
880 case ::vcl::BBTYPE_BROWSEBOX:
881 case ::vcl::BBTYPE_TABLE:
882 {
883 _rStateSet.AddState( AccessibleStateType::FOCUSABLE );
884 if ( HasFocus() )
885 _rStateSet.AddState( AccessibleStateType::FOCUSED );
886 if ( IsActive() )
887 _rStateSet.AddState( AccessibleStateType::ACTIVE );
888 if ( IsEnabled() )
889 {
890 _rStateSet.AddState( AccessibleStateType::ENABLED );
891 _rStateSet.AddState( AccessibleStateType::SENSITIVE );
892 }
893 if ( IsReallyVisible() )
894 _rStateSet.AddState( AccessibleStateType::VISIBLE );
895 if ( _eType == ::vcl::BBTYPE_TABLE )
896 {
897
898 _rStateSet.AddState( AccessibleStateType::MANAGES_DESCENDANTS );
899 _rStateSet.AddState( AccessibleStateType::MULTI_SELECTABLE );
900 }
901 break;
902 }
903
904 case ::vcl::BBTYPE_COLUMNHEADERBAR:
905 {
906 sal_Int32 nCurRow = GetCurrRow();
907 sal_uInt16 nCurColumn = GetCurrColumn();
908 if ( IsCellVisible( nCurRow, nCurColumn ) )
909 _rStateSet.AddState( AccessibleStateType::VISIBLE );
910 if ( IsEnabled() )
911 _rStateSet.AddState( AccessibleStateType::ENABLED );
912 _rStateSet.AddState( AccessibleStateType::TRANSIENT );
913 break;
914 }
915
916 case ::vcl::BBTYPE_ROWHEADERCELL:
917 case ::vcl::BBTYPE_COLUMNHEADERCELL:
918 {
919 _rStateSet.AddState( AccessibleStateType::VISIBLE );
920 _rStateSet.AddState( AccessibleStateType::FOCUSABLE );
921 _rStateSet.AddState( AccessibleStateType::TRANSIENT );
922 if ( IsEnabled() )
923 _rStateSet.AddState( AccessibleStateType::ENABLED );
924 break;
925 }
926 default:
927 break;
928 }
929}
930
931void SvHeaderTabListBox::FillAccessibleStateSetForCell( ::utl::AccessibleStateSetHelper& _rStateSet, sal_Int32 _nRow, sal_uInt16 _nColumn ) const
932{
933 _rStateSet.AddState( AccessibleStateType::SELECTABLE );
934 _rStateSet.AddState( AccessibleStateType::TRANSIENT );
935
936 if ( IsCellVisible( _nRow, _nColumn ) )
937 {
938 _rStateSet.AddState( AccessibleStateType::VISIBLE );
939 _rStateSet.AddState( AccessibleStateType::ENABLED );
940 }
941
942 if ( IsRowSelected( _nRow ) )
943 {
944 _rStateSet.AddState( AccessibleStateType::ACTIVE );
945 _rStateSet.AddState( AccessibleStateType::SELECTED );
946 }
947 if ( IsEnabled() )
948 _rStateSet.AddState( AccessibleStateType::ENABLED );
949}
950
951void SvHeaderTabListBox::GrabTableFocus()
952{
953 GrabFocus();
954}
955
956bool SvHeaderTabListBox::GetGlyphBoundRects( const Point& rOrigin, const OUString& rStr, int nIndex, int nLen, MetricVector& rVector )
957{
958 return Control::GetGlyphBoundRects( rOrigin, rStr, nIndex, nLen, rVector );
959}
960
961tools::Rectangle SvHeaderTabListBox::GetWindowExtentsRelative(const vcl::Window *pRelativeWindow) const
962{
963 return Control::GetWindowExtentsRelative( pRelativeWindow );
964}
965
966void SvHeaderTabListBox::GrabFocus()
967{
968 Control::GrabFocus();
969}
970
971Reference< XAccessible > SvHeaderTabListBox::GetAccessible()
972{
973 return Control::GetAccessible();
974}
975
976vcl::Window* SvHeaderTabListBox::GetAccessibleParentWindow() const
977{
978 return Control::GetAccessibleParentWindow();
979}
980
981vcl::Window* SvHeaderTabListBox::GetWindowInstance()
982{
983 return this;
984}
985
986Reference< XAccessible > SvHeaderTabListBox::CreateAccessible()
987{
988 vcl::Window* pParent = GetAccessibleParentWindow();
989 DBG_ASSERT( pParent, "SvHeaderTabListBox::::CreateAccessible - accessible parent not found" )do { if (true && (!(pParent))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/vcl/source/treelist/svtabbx.cxx"
":" "989" ": "), "%s", "SvHeaderTabListBox::::CreateAccessible - accessible parent not found"
); } } while (false)
;
990
991 Reference< XAccessible > xAccessible;
992 if ( m_pAccessible ) xAccessible = m_pAccessible->getMyself();
993
994 if( pParent && !m_pAccessible )
995 {
996 Reference< XAccessible > xAccParent = pParent->GetAccessible();
997 if ( xAccParent.is() )
998 {
999 m_pAccessible = m_pImpl->m_aFactoryAccess.getFactory().createAccessibleTabListBox( xAccParent, *this );
1000 if ( m_pAccessible )
1001 xAccessible = m_pAccessible->getMyself();
1002 }
1003 }
1004 return xAccessible;
1005}
1006
1007tools::Rectangle SvHeaderTabListBox::GetFieldCharacterBounds(sal_Int32,sal_Int32,sal_Int32)
1008{
1009 return tools::Rectangle();
1010}
1011
1012sal_Int32 SvHeaderTabListBox::GetFieldIndexAtPoint(sal_Int32 _nRow,sal_Int32 _nColumnPos,const Point& _rPoint)
1013{
1014 OUString sText = GetAccessibleCellText( _nRow, static_cast< sal_uInt16 >( _nColumnPos ) );
1015 MetricVector aRects;
1016 if ( GetGlyphBoundRects(Point(0,0), sText, 0, sText.getLength(), aRects) )
1017 {
1018 sal_Int32 nPos = 0;
1019 for (auto const& rectangle : aRects)
1020 {
1021 if( rectangle.IsInside(_rPoint) )
1022 return nPos;
1023 ++nPos;
1024 }
1025 }
1026
1027 return -1;
1028}
1029
1030/* 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)
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)
4
Assuming field 'm_pBody' is non-null
5
Taking true branch
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
9.1
Field 'm_pBody' is non-null
9.1
Field 'm_pBody' is non-null
)
10
Taking true branch
113 m_pBody->release();
11
Calling 'VclReferenceBase::release'
15
Returning; memory was released
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