File: | home/maarten/src/libreoffice/core/vcl/source/treelist/svtabbx.cxx |
Warning: | line 451, column 5 Use of memory after it is freed |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
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 | ||||
36 | using namespace ::com::sun::star::uno; | |||
37 | using namespace ::com::sun::star::accessibility; | |||
38 | ||||
39 | constexpr SvLBoxTabFlags MYTABMASK = | |||
40 | SvLBoxTabFlags::ADJUST_RIGHT | SvLBoxTabFlags::ADJUST_LEFT | SvLBoxTabFlags::ADJUST_CENTER | SvLBoxTabFlags::FORCE; | |||
41 | ||||
42 | // SvTreeListBox callback | |||
43 | ||||
44 | void 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 | ||||
80 | void 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 | ||||
95 | SvTabListBox::SvTabListBox( vcl::Window* pParent, WinBits nBits ) | |||
96 | : SvTreeListBox( pParent, nBits ) | |||
97 | { | |||
98 | SetHighlightRange(); // select full width | |||
99 | } | |||
100 | ||||
101 | SvTabListBox::~SvTabListBox() | |||
102 | { | |||
103 | disposeOnce(); | |||
104 | } | |||
105 | ||||
106 | void SvTabListBox::dispose() | |||
107 | { | |||
108 | mvTabList.clear(); | |||
109 | SvTreeListBox::dispose(); | |||
110 | } | |||
111 | ||||
112 | void 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 | ||||
132 | SvTreeListEntry* 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 | ||||
139 | SvTreeListEntry* 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 | ||||
150 | SvTreeListEntry* 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 | ||||
175 | SvTreeListEntry* 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 | ||||
205 | OUString SvTabListBox::GetEntryText( SvTreeListEntry* pEntry ) const | |||
206 | { | |||
207 | return GetEntryText( pEntry, 0xffff ); | |||
208 | } | |||
209 | ||||
210 | OUString 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 | ||||
242 | OUString SvTabListBox::GetEntryText( sal_uLong nPos, sal_uInt16 nCol ) const | |||
243 | { | |||
244 | SvTreeListEntry* pEntry = GetEntryOnPos( nPos ); | |||
245 | return GetEntryText( pEntry, nCol ); | |||
246 | } | |||
247 | ||||
248 | OUString 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 | ||||
262 | sal_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 | |||
277 | OUString SvTabListBox::GetToken( const OUString &sStr, sal_Int32& nIndex ) | |||
278 | { | |||
279 | return sStr.getToken(0, '\t', nIndex); | |||
280 | } | |||
281 | ||||
282 | OUString 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 | ||||
320 | SvTreeListEntry* 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 | ||||
344 | SvTreeListEntry* 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 | ||||
364 | void 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 | ||||
380 | void 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 | ||||
392 | long 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 | ||||
401 | namespace vcl | |||
402 | { | |||
403 | struct SvHeaderTabListBoxImpl | |||
404 | { | |||
405 | VclPtr<HeaderBar> m_pHeaderBar; | |||
406 | AccessibleFactoryAccess m_aFactoryAccess; | |||
407 | ||||
408 | SvHeaderTabListBoxImpl() : m_pHeaderBar( nullptr ) { } | |||
409 | }; | |||
410 | } | |||
411 | ||||
412 | SvHeaderTabListBox::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 | ||||
420 | SvHeaderTabListBox::~SvHeaderTabListBox() | |||
421 | { | |||
422 | disposeOnce(); | |||
423 | } | |||
424 | ||||
425 | void SvHeaderTabListBox::dispose() | |||
426 | { | |||
427 | m_pImpl.reset(); | |||
428 | SvTabListBox::dispose(); | |||
429 | } | |||
430 | ||||
431 | void 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 | ||||
440 | void 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 | ||||
449 | HeaderBar* SvHeaderTabListBox::GetHeaderBar() | |||
450 | { | |||
451 | return m_pImpl ? m_pImpl->m_pHeaderBar : nullptr; | |||
| ||||
| ||||
452 | } | |||
453 | ||||
454 | bool 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 | ||||
468 | SvTreeListEntry* 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 | ||||
476 | SvTreeListEntry* 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 | ||||
486 | sal_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 | ||||
494 | sal_uLong SvHeaderTabListBox::Insert( SvTreeListEntry* pEntry, sal_uLong nRootPos ) | |||
495 | { | |||
496 | sal_uLong nPos = SvTabListBox::Insert( pEntry, nRootPos ); | |||
497 | RecalculateAccessibleChildren(); | |||
498 | return nPos; | |||
499 | } | |||
500 | ||||
501 | IMPL_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 | ||||
506 | IMPL_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 | ||||
522 | void 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 | ||||
536 | bool 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 | } | |||
560 | long SvHeaderTabListBox::GetRowCount() const | |||
561 | { | |||
562 | return GetEntryCount(); | |||
563 | } | |||
564 | ||||
565 | sal_uInt16 SvHeaderTabListBox::GetColumnCount() const | |||
566 | { | |||
567 | return m_pImpl->m_pHeaderBar->GetItemCount(); | |||
568 | } | |||
569 | ||||
570 | sal_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 | ||||
590 | sal_uInt16 SvHeaderTabListBox::GetCurrColumn() const | |||
591 | { | |||
592 | return 0; | |||
593 | } | |||
594 | ||||
595 | OUString SvHeaderTabListBox::GetRowDescription( sal_Int32 _nRow ) const | |||
596 | { | |||
597 | return GetEntryText( _nRow ); | |||
598 | } | |||
599 | ||||
600 | OUString SvHeaderTabListBox::GetColumnDescription( sal_uInt16 _nColumn ) const | |||
601 | { | |||
602 | return m_pImpl->m_pHeaderBar->GetItemText( m_pImpl->m_pHeaderBar->GetItemId( _nColumn ) ); | |||
603 | } | |||
604 | ||||
605 | bool SvHeaderTabListBox::HasRowHeader() const | |||
606 | { | |||
607 | return false; | |||
608 | } | |||
609 | ||||
610 | bool SvHeaderTabListBox::GoToCell( sal_Int32 /*_nRow*/, sal_uInt16 /*_nColumn*/ ) | |||
611 | { | |||
612 | return false; | |||
613 | } | |||
614 | ||||
615 | void SvHeaderTabListBox::SetNoSelection() | |||
616 | { | |||
617 | SvTreeListBox::SelectAll(false); | |||
618 | } | |||
619 | ||||
620 | void SvHeaderTabListBox::SelectAll() | |||
621 | { | |||
622 | SvTreeListBox::SelectAll(true); | |||
623 | } | |||
624 | ||||
625 | void SvHeaderTabListBox::SelectRow( long _nRow, bool _bSelect, bool ) | |||
626 | { | |||
627 | Select( GetEntry( _nRow ), _bSelect ); | |||
628 | } | |||
629 | ||||
630 | void SvHeaderTabListBox::SelectColumn( sal_uInt16, bool ) | |||
631 | { | |||
632 | } | |||
633 | ||||
634 | sal_Int32 SvHeaderTabListBox::GetSelectedRowCount() const | |||
635 | { | |||
636 | return GetSelectionCount(); | |||
637 | } | |||
638 | ||||
639 | sal_Int32 SvHeaderTabListBox::GetSelectedColumnCount() const | |||
640 | { | |||
641 | return 0; | |||
642 | } | |||
643 | ||||
644 | bool SvHeaderTabListBox::IsRowSelected( long _nRow ) const | |||
645 | { | |||
646 | SvTreeListEntry* pEntry = GetEntry( _nRow ); | |||
647 | return ( pEntry && IsSelected( pEntry ) ); | |||
648 | } | |||
649 | ||||
650 | bool SvHeaderTabListBox::IsColumnSelected( long ) const | |||
651 | { | |||
652 | return false; | |||
653 | } | |||
654 | ||||
655 | void SvHeaderTabListBox::GetAllSelectedRows( css::uno::Sequence< sal_Int32 >& ) const | |||
656 | { | |||
657 | } | |||
658 | ||||
659 | void SvHeaderTabListBox::GetAllSelectedColumns( css::uno::Sequence< sal_Int32 >& ) const | |||
660 | { | |||
661 | } | |||
662 | ||||
663 | bool SvHeaderTabListBox::IsCellVisible( sal_Int32, sal_uInt16 ) const | |||
664 | { | |||
665 | return true; | |||
666 | } | |||
667 | ||||
668 | OUString SvHeaderTabListBox::GetAccessibleCellText( long _nRow, sal_uInt16 _nColumnPos ) const | |||
669 | { | |||
670 | return GetTabEntryText(_nRow, _nColumnPos); | |||
671 | } | |||
672 | ||||
673 | tools::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 | ||||
687 | tools::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 | ||||
697 | tools::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 | ||||
722 | Reference< 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 | ||||
740 | Reference< XAccessible > SvHeaderTabListBox::CreateAccessibleRowHeader( sal_Int32 ) | |||
741 | { | |||
742 | Reference< XAccessible > xHeader; | |||
743 | return xHeader; | |||
744 | } | |||
745 | ||||
746 | Reference< 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 | ||||
772 | sal_Int32 SvHeaderTabListBox::GetAccessibleControlCount() const | |||
773 | { | |||
774 | return -1; | |||
775 | } | |||
776 | ||||
777 | Reference< XAccessible > SvHeaderTabListBox::CreateAccessibleControl( sal_Int32 ) | |||
778 | { | |||
779 | Reference< XAccessible > xControl; | |||
780 | return xControl; | |||
781 | } | |||
782 | ||||
783 | bool SvHeaderTabListBox::ConvertPointToControlIndex( sal_Int32&, const Point& ) | |||
784 | { | |||
785 | return false; | |||
786 | } | |||
787 | ||||
788 | bool SvHeaderTabListBox::ConvertPointToCellAddress( sal_Int32&, sal_uInt16&, const Point& ) | |||
789 | { | |||
790 | return false; | |||
791 | } | |||
792 | ||||
793 | bool SvHeaderTabListBox::ConvertPointToRowHeader( sal_Int32&, const Point& ) | |||
794 | { | |||
795 | return false; | |||
796 | } | |||
797 | ||||
798 | bool SvHeaderTabListBox::ConvertPointToColumnHeader( sal_uInt16&, const Point& ) | |||
799 | { | |||
800 | return false; | |||
801 | } | |||
802 | ||||
803 | OUString 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 | ||||
851 | OUString 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 | ||||
876 | void 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 | ||||
931 | void 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 | ||||
951 | void SvHeaderTabListBox::GrabTableFocus() | |||
952 | { | |||
953 | GrabFocus(); | |||
954 | } | |||
955 | ||||
956 | bool 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 | ||||
961 | tools::Rectangle SvHeaderTabListBox::GetWindowExtentsRelative(const vcl::Window *pRelativeWindow) const | |||
962 | { | |||
963 | return Control::GetWindowExtentsRelative( pRelativeWindow ); | |||
964 | } | |||
965 | ||||
966 | void SvHeaderTabListBox::GrabFocus() | |||
967 | { | |||
968 | Control::GrabFocus(); | |||
969 | } | |||
970 | ||||
971 | Reference< XAccessible > SvHeaderTabListBox::GetAccessible() | |||
972 | { | |||
973 | return Control::GetAccessible(); | |||
974 | } | |||
975 | ||||
976 | vcl::Window* SvHeaderTabListBox::GetAccessibleParentWindow() const | |||
977 | { | |||
978 | return Control::GetAccessibleParentWindow(); | |||
979 | } | |||
980 | ||||
981 | vcl::Window* SvHeaderTabListBox::GetWindowInstance() | |||
982 | { | |||
983 | return this; | |||
984 | } | |||
985 | ||||
986 | Reference< 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 | ||||
1007 | tools::Rectangle SvHeaderTabListBox::GetFieldCharacterBounds(sal_Int32,sal_Int32,sal_Int32) | |||
1008 | { | |||
1009 | return tools::Rectangle(); | |||
1010 | } | |||
1011 | ||||
1012 | sal_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: */ |
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 | |||||||
34 | namespace rtl | ||||||
35 | { | ||||||
36 | |||||||
37 | /** Template reference class for reference type. | ||||||
38 | */ | ||||||
39 | template <class reference_type> | ||||||
40 | class Reference | ||||||
41 | { | ||||||
42 | /** The <b>reference_type</b> body pointer. | ||||||
43 | */ | ||||||
44 | reference_type * m_pBody; | ||||||
45 | |||||||
46 | |||||||
47 | public: | ||||||
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) | ||||||
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
| ||||||
113 | m_pBody->release(); | ||||||
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 | ||||||
277 | namespace 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 | */ | ||||||
286 | template<typename T> | ||||||
287 | struct 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: */ |
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 | |
25 | class VCL_DLLPUBLIC__attribute__ ((visibility("default"))) VclReferenceBase |
26 | { |
27 | mutable oslInterlockedCount mnRefCnt; |
28 | |
29 | template<typename T> friend class VclPtr; |
30 | |
31 | public: |
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) |
40 | delete this; |
41 | } |
42 | #ifdef DBG_UTIL |
43 | #ifndef _WIN32 |
44 | sal_Int32 getRefCount() const { return mnRefCnt; } |
45 | #endif |
46 | #endif |
47 | |
48 | |
49 | private: |
50 | VclReferenceBase(const VclReferenceBase&) = delete; |
51 | VclReferenceBase& operator=(const VclReferenceBase&) = delete; |
52 | |
53 | bool mbDisposed : 1; |
54 | |
55 | protected: |
56 | VclReferenceBase(); |
57 | protected: |
58 | virtual ~VclReferenceBase(); |
59 | |
60 | protected: |
61 | virtual void dispose(); |
62 | |
63 | public: |
64 | void disposeOnce(); |
65 | bool isDisposed() const { return mbDisposed; } |
66 | |
67 | }; |
68 | #endif |