Coverage Report

Created: 2026-11-06 11:29

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/vcl/source/treelist/SvHeaderTabListBox.cxx
Line
Count
Source
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 <SvHeaderTabListBox.hxx>
21
#include <SvLBoxButton.hxx>
22
#include <accessibility/accessibletablistbox.hxx>
23
#include <strings.hrc>
24
#include <svdata.hxx>
25
26
#include <o3tl/safeint.hxx>
27
#include <o3tl/string_view.hxx>
28
#include <osl/diagnose.h>
29
#include <rtl/ustrbuf.hxx>
30
#include <sal/log.hxx>
31
#include <tools/json_writer.hxx>
32
#include <vcl/accessibility/AccessibleBrowseBoxCheckBoxCell.hxx>
33
#include <vcl/accessibility/AccessibleBrowseBoxHeaderBar.hxx>
34
#include <vcl/accessibility/AccessibleBrowseBoxHeaderCell.hxx>
35
#include <vcl/accessibility/AccessibleBrowseBoxTableCell.hxx>
36
#include <vcl/headbar.hxx>
37
#include <vcl/toolkit/svlbitm.hxx>
38
#include <vcl/toolkit/treelistbox.hxx>
39
#include <vcl/toolkit/treelistentry.hxx>
40
41
#include <com/sun/star/accessibility/AccessibleStateType.hpp>
42
#include <com/sun/star/accessibility/XAccessible.hpp>
43
44
using namespace ::com::sun::star::uno;
45
using namespace ::com::sun::star::accessibility;
46
47
SvHeaderTabListBox::SvHeaderTabListBox(vcl::Window* pParent, WinBits nWinStyle,
48
                                       HeaderBar* pHeaderBar)
49
0
    : SvTabListBox(pParent, nWinStyle)
50
0
{
51
0
    assert(pHeaderBar);
52
0
    m_xHeaderBar = pHeaderBar;
53
0
    SetScrolledHdl(LINK(this, SvHeaderTabListBox, ScrollHdl_Impl));
54
0
    m_xHeaderBar->SetCreateAccessibleHdl(LINK(this, SvHeaderTabListBox, CreateAccessibleHdl_Impl));
55
0
}
Unexecuted instantiation: SvHeaderTabListBox::SvHeaderTabListBox(vcl::Window*, long, HeaderBar*)
Unexecuted instantiation: SvHeaderTabListBox::SvHeaderTabListBox(vcl::Window*, long, HeaderBar*)
56
57
0
SvHeaderTabListBox::~SvHeaderTabListBox() { disposeOnce(); }
58
59
void SvHeaderTabListBox::dispose()
60
0
{
61
0
    for (rtl::Reference<AccessibleBrowseBoxHeaderCell>& rxChild : m_aAccessibleChildren)
62
0
        rxChild->dispose();
63
0
    m_aAccessibleChildren.clear();
64
0
    m_xAccessible.clear();
65
66
0
    m_xHeaderBar.reset();
67
0
    SvTabListBox::dispose();
68
0
}
69
70
0
HeaderBar* SvHeaderTabListBox::GetHeaderBar() { return m_xHeaderBar; }
71
72
bool SvHeaderTabListBox::IsItemChecked(SvTreeListEntry* pEntry, sal_uInt16 nCol)
73
0
{
74
0
    SvButtonState eState = SvButtonState::Unchecked;
75
0
    SvLBoxButton& rItem = static_cast<SvLBoxButton&>(pEntry->GetItem(nCol + 1));
76
77
0
    if (rItem.GetType() == SvLBoxItemType::Button)
78
0
    {
79
0
        SvItemStateFlags nButtonFlags = rItem.GetButtonFlags();
80
0
        eState = SvLBoxButtonData::ConvertToButtonState(nButtonFlags);
81
0
    }
82
83
0
    return (eState == SvButtonState::Checked);
84
0
}
85
86
IMPL_LINK_NOARG(SvHeaderTabListBox, ScrollHdl_Impl, SvTreeListBox*, void)
87
0
{
88
0
    m_xHeaderBar->SetOffset(-GetXOffset());
89
0
}
90
91
IMPL_LINK_NOARG(SvHeaderTabListBox, CreateAccessibleHdl_Impl, HeaderBar*, void)
92
0
{
93
0
    rtl::Reference<comphelper::OAccessible> pAccParent = m_xHeaderBar->GetAccessibleParent();
94
0
    if (pAccParent.is())
95
0
    {
96
0
        rtl::Reference<comphelper::OAccessible> pAccessible = new AccessibleBrowseBoxHeaderBar(
97
0
            pAccParent, *this, AccessibleBrowseBoxObjType::ColumnHeaderBar);
98
0
        m_xHeaderBar->SetAccessible(pAccessible);
99
0
    }
100
0
}
101
102
bool SvHeaderTabListBox::IsCellCheckBox(sal_Int32 _nRow, sal_uInt16 _nColumn,
103
                                        TriState& _rState) const
104
0
{
105
0
    bool bRet = false;
106
0
    SvTreeListEntry* pEntry = GetEntryOnPos(_nRow);
107
0
    if (pEntry)
108
0
    {
109
0
        sal_uInt16 nItemCount = pEntry->ItemCount();
110
0
        if (nItemCount > (_nColumn + 1))
111
0
        {
112
0
            SvLBoxItem& rItem = pEntry->GetItem(_nColumn + 1);
113
0
            if (rItem.GetType() == SvLBoxItemType::Button)
114
0
            {
115
0
                bRet = true;
116
0
                _rState = ((static_cast<SvLBoxButton&>(rItem).GetButtonFlags()
117
0
                            & SvItemStateFlags::UNCHECKED)
118
0
                           == SvItemStateFlags::NONE)
119
0
                              ? TRISTATE_TRUE
120
0
                              : TRISTATE_FALSE;
121
0
            }
122
0
        }
123
0
        else
124
0
        {
125
0
            SAL_WARN("svtools.contnr", "SvHeaderTabListBox::IsCellCheckBox(): column out of range");
126
0
        }
127
0
    }
128
0
    return bRet;
129
0
}
130
0
sal_Int32 SvHeaderTabListBox::GetRowCount() const { return GetEntryCount(); }
131
132
0
sal_uInt16 SvHeaderTabListBox::GetColumnCount() const { return m_xHeaderBar->GetItemCount(); }
133
134
sal_Int32 SvHeaderTabListBox::GetCurrRow() const
135
0
{
136
0
    sal_Int32 nRet = -1;
137
0
    SvTreeListEntry* pEntry = GetCurEntry();
138
0
    if (pEntry)
139
0
    {
140
0
        sal_uInt32 nCount = GetEntryCount();
141
0
        for (sal_uInt32 i = 0; i < nCount; ++i)
142
0
        {
143
0
            if (pEntry == GetEntryOnPos(i))
144
0
            {
145
0
                nRet = i;
146
0
                break;
147
0
            }
148
0
        }
149
0
    }
150
151
0
    return nRet;
152
0
}
153
154
0
sal_uInt16 SvHeaderTabListBox::GetCurrColumn() const { return 0; }
155
156
OUString SvHeaderTabListBox::GetRowDescription(sal_Int32 _nRow) const
157
0
{
158
0
    SvTreeListEntry* pEntry = GetEntryOnPos(_nRow);
159
0
    return GetEntryText(pEntry);
160
0
}
161
162
OUString SvHeaderTabListBox::GetColumnDescription(sal_uInt16 _nColumn) const
163
0
{
164
0
    return m_xHeaderBar->GetItemText(m_xHeaderBar->GetItemId(_nColumn));
165
0
}
166
167
0
bool SvHeaderTabListBox::HasRowHeader() const { return false; }
168
169
0
bool SvHeaderTabListBox::GoToCell(sal_Int32 /*_nRow*/, sal_uInt16 /*_nColumn*/) { return false; }
170
171
0
void SvHeaderTabListBox::SetNoSelection() { SvTreeListBox::SelectAll(false); }
172
173
0
void SvHeaderTabListBox::SelectAll() { SvTreeListBox::SelectAll(true); }
174
175
void SvHeaderTabListBox::SelectRow(sal_Int32 _nRow, bool _bSelect, bool)
176
0
{
177
0
    Select(GetEntryOnPos(_nRow), _bSelect);
178
0
}
179
180
0
void SvHeaderTabListBox::SelectColumn(sal_uInt16, bool) {}
181
182
0
sal_Int32 SvHeaderTabListBox::GetSelectedRowCount() const { return GetSelectionCount(); }
183
184
0
sal_Int32 SvHeaderTabListBox::GetSelectedColumnCount() const { return 0; }
185
186
bool SvHeaderTabListBox::IsRowSelected(sal_Int32 _nRow) const
187
0
{
188
0
    SvTreeListEntry* pEntry = GetEntryOnPos(_nRow);
189
0
    return (pEntry && IsSelected(pEntry));
190
0
}
191
192
0
bool SvHeaderTabListBox::IsColumnSelected(sal_Int32) const { return false; }
193
194
void SvHeaderTabListBox::GetAllSelectedRows(css::uno::Sequence<sal_Int32>& rRowIndices) const
195
0
{
196
0
    const sal_Int32 nCount = GetSelectedRowCount();
197
0
    rRowIndices.realloc(nCount);
198
0
    auto pRows = rRowIndices.getArray();
199
0
    SvTreeListEntry* pEntry = FirstSelected();
200
0
    sal_Int32 nIndex = 0;
201
0
    while (nIndex < nCount && pEntry)
202
0
    {
203
0
        pRows[nIndex] = GetEntryPos(pEntry);
204
0
        pEntry = NextSelected(pEntry);
205
0
        ++nIndex;
206
0
    }
207
0
    assert(nIndex == nCount
208
0
           && "Mismatch between GetSelectedRowCount() and count of selected rows when iterating.");
209
0
}
210
211
0
void SvHeaderTabListBox::GetAllSelectedColumns(css::uno::Sequence<sal_Int32>&) const {}
212
213
0
bool SvHeaderTabListBox::IsCellVisible(sal_Int32, sal_uInt16) const { return true; }
214
215
OUString SvHeaderTabListBox::GetAccessibleCellText(sal_Int32 _nRow, sal_uInt16 _nColumnPos) const
216
0
{
217
0
    return GetTabEntryText(_nRow, _nColumnPos);
218
0
}
219
220
tools::Rectangle SvHeaderTabListBox::calcHeaderRect(bool _bIsColumnBar)
221
0
{
222
0
    tools::Rectangle aRect;
223
0
    if (_bIsColumnBar)
224
0
    {
225
0
        vcl::Window* pParent = m_xHeaderBar->GetAccessibleParentWindow();
226
0
        assert(pParent);
227
0
        aRect = m_xHeaderBar->GetWindowExtentsRelative(*pParent);
228
0
    }
229
0
    return aRect;
230
0
}
231
232
tools::Rectangle SvHeaderTabListBox::calcTableRect()
233
0
{
234
0
    tools::Rectangle aScreenRect(GetWindowExtentsAbsolute());
235
0
    return tools::Rectangle(Point(0, 0), aScreenRect.GetSize());
236
0
}
237
238
tools::Rectangle SvHeaderTabListBox::calcFieldRectPixel(sal_Int32 _nRow, sal_uInt16 _nColumn,
239
                                                        bool _bIsHeader)
240
0
{
241
0
    DBG_ASSERT(!_bIsHeader || 0 == _nRow, "invalid parameters");
242
0
    tools::Rectangle aRect;
243
0
    SvTreeListEntry* pEntry = GetEntryOnPos(_nRow);
244
0
    if (pEntry)
245
0
    {
246
0
        aRect = _bIsHeader ? calcHeaderRect(true) : GetBoundingRect(*pEntry);
247
0
        Point aTopLeft = aRect.TopLeft();
248
0
        DBG_ASSERT(m_xHeaderBar->GetItemCount() > _nColumn, "invalid column");
249
0
        tools::Rectangle aItemRect = m_xHeaderBar->GetItemRect(m_xHeaderBar->GetItemId(_nColumn));
250
0
        aTopLeft.setX(aItemRect.Left());
251
0
        Size aSize = aItemRect.GetSize();
252
0
        aRect = tools::Rectangle(aTopLeft, aSize);
253
0
    }
254
255
0
    return aRect;
256
0
}
257
258
rtl::Reference<comphelper::OAccessible>
259
SvHeaderTabListBox::CreateAccessibleCell(sal_Int32 _nRow, sal_uInt16 _nColumnPos)
260
0
{
261
0
    assert(m_xAccessible.is() && "Invalid call: Accessible is null");
262
263
0
    TriState eState = TRISTATE_INDET;
264
0
    bool bIsCheckBox = IsCellCheckBox(_nRow, _nColumnPos, eState);
265
0
    if (bIsCheckBox)
266
0
        return new AccessibleCheckBoxCell(m_xAccessible->getTable(), *this, _nRow, _nColumnPos,
267
0
                                          eState, false);
268
269
0
    return new AccessibleBrowseBoxTableCell(m_xAccessible->getTable(), *this, _nRow, _nColumnPos);
270
0
}
271
272
rtl::Reference<comphelper::OAccessible> SvHeaderTabListBox::CreateAccessibleRowHeader(sal_Int32)
273
0
{
274
0
    return {};
275
0
}
276
277
rtl::Reference<comphelper::OAccessible>
278
SvHeaderTabListBox::CreateAccessibleColumnHeader(sal_uInt16 _nColumn)
279
0
{
280
    // first call? -> initial list
281
0
    if (m_aAccessibleChildren.empty())
282
0
    {
283
0
        const sal_uInt16 nColumnCount = GetColumnCount();
284
0
        m_aAccessibleChildren.resize(nColumnCount);
285
0
    }
286
287
0
    assert(m_aAccessibleChildren.size() == GetColumnCount());
288
289
    // get header
290
0
    rtl::Reference<AccessibleBrowseBoxHeaderCell> xChild = m_aAccessibleChildren[_nColumn];
291
    // already exists?
292
0
    if (!xChild.is() && m_xAccessible.is())
293
0
    {
294
        // no -> create new header cell
295
0
        xChild = new AccessibleBrowseBoxHeaderCell(_nColumn, m_xAccessible->getHeaderBar(), *this,
296
0
                                                   AccessibleBrowseBoxObjType::ColumnHeaderCell);
297
298
        // insert into list
299
0
        m_aAccessibleChildren[_nColumn] = xChild;
300
0
    }
301
0
    return xChild;
302
0
}
303
304
0
sal_Int32 SvHeaderTabListBox::GetAccessibleControlCount() const { return -1; }
305
306
rtl::Reference<comphelper::OAccessible> SvHeaderTabListBox::CreateAccessibleControl(sal_Int32)
307
0
{
308
0
    return {};
309
0
}
310
311
0
bool SvHeaderTabListBox::ConvertPointToControlIndex(sal_Int32&, const Point&) { return false; }
312
313
bool SvHeaderTabListBox::ConvertPointToCellAddress(sal_Int32&, sal_uInt16&, const Point&)
314
0
{
315
0
    return false;
316
0
}
317
318
0
bool SvHeaderTabListBox::ConvertPointToRowHeader(sal_Int32&, const Point&) { return false; }
319
320
0
bool SvHeaderTabListBox::ConvertPointToColumnHeader(sal_uInt16&, const Point&) { return false; }
321
322
OUString SvHeaderTabListBox::GetAccessibleObjectName(AccessibleBrowseBoxObjType _eType,
323
                                                     sal_Int32 _nPos) const
324
0
{
325
0
    OUString aRetText;
326
0
    switch (_eType)
327
0
    {
328
0
        case AccessibleBrowseBoxObjType::BrowseBox:
329
0
        case AccessibleBrowseBoxObjType::Table:
330
0
        case AccessibleBrowseBoxObjType::ColumnHeaderBar:
331
            // should be empty now (see #i63983)
332
0
            aRetText.clear();
333
0
            break;
334
335
0
        case AccessibleBrowseBoxObjType::TableCell:
336
0
        {
337
            // here we need a valid pos, we can not handle -1
338
0
            if (_nPos >= 0)
339
0
            {
340
0
                sal_uInt16 nColumnCount = GetColumnCount();
341
0
                if (nColumnCount > 0)
342
0
                {
343
0
                    sal_Int32 nRow = _nPos / nColumnCount;
344
0
                    sal_uInt16 nColumn = static_cast<sal_uInt16>(_nPos % nColumnCount);
345
0
                    aRetText = GetCellText(nRow, nColumn);
346
0
                }
347
0
            }
348
0
            break;
349
0
        }
350
0
        case AccessibleBrowseBoxObjType::CheckBoxCell:
351
0
        {
352
0
            break; // checkbox cells have no name
353
0
        }
354
0
        case AccessibleBrowseBoxObjType::ColumnHeaderCell:
355
0
        {
356
0
            aRetText = m_xHeaderBar->GetItemText(
357
0
                m_xHeaderBar->GetItemId(static_cast<sal_uInt16>(_nPos)));
358
0
            break;
359
0
        }
360
361
0
        case AccessibleBrowseBoxObjType::RowHeaderBar:
362
0
        case AccessibleBrowseBoxObjType::RowHeaderCell:
363
0
            aRetText = "error";
364
0
            break;
365
366
0
        default:
367
0
            OSL_FAIL("BrowseBox::GetAccessibleName: invalid enum!");
368
0
    }
369
0
    return aRetText;
370
0
}
371
372
OUString SvHeaderTabListBox::GetAccessibleObjectDescription(AccessibleBrowseBoxObjType _eType,
373
                                                            sal_Int32 _nPos) const
374
0
{
375
0
    OUString aRetText;
376
377
0
    if (_eType == AccessibleBrowseBoxObjType::TableCell && _nPos != -1)
378
0
    {
379
0
        sal_uInt16 nColumnCount = GetColumnCount();
380
0
        if (nColumnCount > 0)
381
0
        {
382
0
            sal_Int32 nRow = _nPos / nColumnCount;
383
0
            sal_uInt16 nColumn = static_cast<sal_uInt16>(_nPos % nColumnCount);
384
385
0
            OUString aText(VclResId(STR_SVT_ACC_DESC_TABLISTBOX));
386
0
            aText = aText.replaceFirst("%1", OUString::number(nRow));
387
0
            OUString sColHeader = m_xHeaderBar->GetItemText(m_xHeaderBar->GetItemId(nColumn));
388
0
            if (sColHeader.isEmpty())
389
0
                sColHeader = OUString::number(nColumn);
390
0
            aText = aText.replaceFirst("%2", sColHeader);
391
0
            aRetText = aText;
392
0
        }
393
0
    }
394
395
0
    return aRetText;
396
0
}
397
398
void SvHeaderTabListBox::FillAccessibleStateSet(sal_Int64& _rStateSet,
399
                                                AccessibleBrowseBoxObjType _eType) const
400
0
{
401
0
    switch (_eType)
402
0
    {
403
0
        case AccessibleBrowseBoxObjType::BrowseBox:
404
0
        case AccessibleBrowseBoxObjType::Table:
405
0
        {
406
0
            _rStateSet |= AccessibleStateType::FOCUSABLE;
407
0
            if (HasFocus())
408
0
                _rStateSet |= AccessibleStateType::FOCUSED;
409
0
            if (IsActive())
410
0
                _rStateSet |= AccessibleStateType::ACTIVE;
411
0
            if (IsEnabled())
412
0
            {
413
0
                _rStateSet |= AccessibleStateType::ENABLED;
414
0
                _rStateSet |= AccessibleStateType::SENSITIVE;
415
0
            }
416
0
            if (IsReallyVisible())
417
0
                _rStateSet |= AccessibleStateType::VISIBLE;
418
0
            if (_eType == AccessibleBrowseBoxObjType::Table)
419
0
            {
420
0
                _rStateSet |= AccessibleStateType::MANAGES_DESCENDANTS;
421
0
                _rStateSet |= AccessibleStateType::MULTI_SELECTABLE;
422
0
            }
423
0
            break;
424
0
        }
425
426
0
        case AccessibleBrowseBoxObjType::ColumnHeaderBar:
427
0
        {
428
0
            sal_Int32 nCurRow = GetCurrRow();
429
0
            sal_uInt16 nCurColumn = GetCurrColumn();
430
0
            if (IsCellVisible(nCurRow, nCurColumn))
431
0
                _rStateSet |= AccessibleStateType::VISIBLE;
432
0
            if (IsEnabled())
433
0
                _rStateSet |= AccessibleStateType::ENABLED;
434
0
            _rStateSet |= AccessibleStateType::TRANSIENT;
435
0
            break;
436
0
        }
437
438
0
        case AccessibleBrowseBoxObjType::RowHeaderCell:
439
0
        case AccessibleBrowseBoxObjType::ColumnHeaderCell:
440
0
        {
441
0
            _rStateSet |= AccessibleStateType::VISIBLE;
442
0
            _rStateSet |= AccessibleStateType::FOCUSABLE;
443
0
            _rStateSet |= AccessibleStateType::TRANSIENT;
444
0
            if (IsEnabled())
445
0
                _rStateSet |= AccessibleStateType::ENABLED;
446
0
            break;
447
0
        }
448
0
        default:
449
0
            break;
450
0
    }
451
0
}
452
453
void SvHeaderTabListBox::FillAccessibleStateSetForCell(sal_Int64& _rStateSet, sal_Int32 _nRow,
454
                                                       sal_uInt16 _nColumn) const
455
0
{
456
0
    _rStateSet |= AccessibleStateType::FOCUSABLE;
457
0
    _rStateSet |= AccessibleStateType::SELECTABLE;
458
0
    _rStateSet |= AccessibleStateType::TRANSIENT;
459
460
0
    if (IsCellVisible(_nRow, _nColumn))
461
0
    {
462
0
        _rStateSet |= AccessibleStateType::VISIBLE;
463
0
        _rStateSet |= AccessibleStateType::ENABLED;
464
0
    }
465
466
0
    if (IsRowSelected(_nRow))
467
0
    {
468
0
        _rStateSet |= AccessibleStateType::ACTIVE;
469
0
        if (HasChildPathFocus())
470
0
            _rStateSet |= AccessibleStateType::FOCUSED;
471
0
        _rStateSet |= AccessibleStateType::SELECTED;
472
0
    }
473
0
    if (IsEnabled())
474
0
        _rStateSet |= AccessibleStateType::ENABLED;
475
0
}
476
477
0
void SvHeaderTabListBox::GrabTableFocus() { GrabFocus(); }
478
479
tools::Rectangle
480
SvHeaderTabListBox::GetWindowExtentsRelative(const vcl::Window& rRelativeWindow) const
481
0
{
482
0
    return Control::GetWindowExtentsRelative(rRelativeWindow);
483
0
}
484
485
0
void SvHeaderTabListBox::GrabFocus() { Control::GrabFocus(); }
486
487
rtl::Reference<comphelper::OAccessible> SvHeaderTabListBox::GetAccessible()
488
0
{
489
0
    return Control::GetAccessible();
490
0
}
491
492
vcl::Window* SvHeaderTabListBox::GetAccessibleParentWindow() const
493
0
{
494
0
    return Control::GetAccessibleParentWindow();
495
0
}
496
497
0
vcl::Window* SvHeaderTabListBox::GetWindowInstance() { return this; }
498
499
rtl::Reference<comphelper::OAccessible> SvHeaderTabListBox::CreateAccessible()
500
0
{
501
0
    if (m_xAccessible.is())
502
0
        return m_xAccessible;
503
504
0
    rtl::Reference<comphelper::OAccessible> pAccParent = GetAccessibleParent();
505
0
    if (pAccParent.is())
506
0
    {
507
0
        m_xAccessible = new AccessibleTabListBox(pAccParent, *this);
508
0
        return m_xAccessible;
509
0
    }
510
0
    return nullptr;
511
0
}
512
513
tools::Rectangle SvHeaderTabListBox::GetFieldCharacterBounds(sal_Int32, sal_Int32, sal_Int32)
514
0
{
515
0
    return tools::Rectangle();
516
0
}
517
518
sal_Int32 SvHeaderTabListBox::GetFieldIndexAtPoint(sal_Int32 _nRow, sal_Int32 _nColumnPos,
519
                                                   const Point& _rPoint)
520
0
{
521
0
    OUString sText = GetAccessibleCellText(_nRow, static_cast<sal_uInt16>(_nColumnPos));
522
0
    std::vector<tools::Rectangle> aRects;
523
0
    if (GetOutDev()->GetGlyphBoundRects(Point(0, 0), sText, 0, sText.getLength(), aRects))
524
0
    {
525
0
        sal_Int32 nPos = 0;
526
0
        for (auto const& rectangle : aRects)
527
0
        {
528
0
            if (rectangle.Contains(_rPoint))
529
0
                return nPos;
530
0
            ++nPos;
531
0
        }
532
0
    }
533
534
0
    return -1;
535
0
}
536
537
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */