Coverage Report

Created: 2025-07-07 10:01

/src/libreoffice/svtools/source/control/valueacc.cxx
Line
Count
Source (jump to first uncovered line)
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/svapp.hxx>
21
#include <vcl/settings.hxx>
22
#include <vcl/unohelp.hxx>
23
#include <sal/log.hxx>
24
#include <tools/debug.hxx>
25
#include <comphelper/diagnose_ex.hxx>
26
#include <svtools/valueset.hxx>
27
#include "valueimp.hxx"
28
#include <comphelper/servicehelper.hxx>
29
#include <com/sun/star/accessibility/AccessibleEventId.hpp>
30
#include <com/sun/star/accessibility/AccessibleRole.hpp>
31
#include <com/sun/star/accessibility/AccessibleStateType.hpp>
32
#include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
33
#include <com/sun/star/uno/RuntimeException.hpp>
34
35
using namespace ::com::sun::star;
36
37
38
ValueSetItem::ValueSetItem( ValueSet& rParent )
39
0
    : mrParent(rParent)
40
0
    , mpData(nullptr)
41
0
    , mxAcc()
42
0
    , mnId(0)
43
0
    , meType(VALUESETITEM_NONE)
44
0
    , mbVisible(true)
45
0
{
46
0
}
47
48
49
ValueSetItem::~ValueSetItem()
50
0
{
51
0
    if( mxAcc.is() )
52
0
    {
53
0
        mxAcc->ValueSetItemDestroyed();
54
0
    }
55
0
}
56
57
const rtl::Reference<ValueItemAcc>& ValueSetItem::GetAccessible(bool bCreate)
58
0
{
59
0
    if (!mxAcc.is() && bCreate)
60
0
        mxAcc = new ValueItemAcc(this);
61
62
0
    return mxAcc;
63
0
}
64
65
ValueItemAcc::ValueItemAcc(ValueSetItem* pValueSetItem)
66
0
    : mpValueSetItem(pValueSetItem)
67
0
{
68
0
}
69
70
ValueItemAcc::~ValueItemAcc()
71
0
{
72
0
}
73
74
void ValueItemAcc::ValueSetItemDestroyed()
75
0
{
76
0
    const SolarMutexGuard aSolarGuard;
77
0
    mpValueSetItem = nullptr;
78
0
}
79
80
sal_Int64 SAL_CALL ValueItemAcc::getAccessibleChildCount()
81
0
{
82
0
    return 0;
83
0
}
84
85
86
uno::Reference< accessibility::XAccessible > SAL_CALL ValueItemAcc::getAccessibleChild( sal_Int64 )
87
0
{
88
0
    throw lang::IndexOutOfBoundsException();
89
0
}
90
91
92
uno::Reference< accessibility::XAccessible > SAL_CALL ValueItemAcc::getAccessibleParent()
93
0
{
94
0
    const SolarMutexGuard aSolarGuard;
95
96
0
    if (!mpValueSetItem)
97
0
        return nullptr;
98
0
    return mpValueSetItem->mrParent.mxAccessible;
99
0
}
100
101
102
sal_Int64 SAL_CALL ValueItemAcc::getAccessibleIndexInParent()
103
0
{
104
0
    const SolarMutexGuard aSolarGuard;
105
    // The index defaults to -1 to indicate the child does not belong to its
106
    // parent.
107
0
    sal_Int64 nIndexInParent = -1;
108
109
0
    if (mpValueSetItem)
110
0
    {
111
0
        bool bDone = false;
112
113
0
        sal_uInt16 nCount = mpValueSetItem->mrParent.ImplGetVisibleItemCount();
114
0
        ValueSetItem* pItem;
115
0
        for (sal_uInt16 i=0; i<nCount && !bDone; i++)
116
0
        {
117
            // Guard the retrieval of the i-th child with a try/catch block
118
            // just in case the number of children changes in the meantime.
119
0
            try
120
0
            {
121
0
                pItem = mpValueSetItem->mrParent.ImplGetItem(i);
122
0
            }
123
0
            catch (const lang::IndexOutOfBoundsException&)
124
0
            {
125
0
                pItem = nullptr;
126
0
            }
127
128
0
            if (pItem && pItem == mpValueSetItem)
129
0
            {
130
0
                nIndexInParent = i;
131
0
                bDone = true;
132
0
            }
133
0
        }
134
0
    }
135
136
    //if this valueset contain a none field(common value is default), then we should increase the real index and set the noitem index value equal 0.
137
0
    if (mpValueSetItem && ((mpValueSetItem->mrParent.GetStyle() & WB_NONEFIELD) != 0))
138
0
    {
139
0
        ValueSetItem* pFirstItem = mpValueSetItem->mrParent.ImplGetItem(VALUESET_ITEM_NONEITEM);
140
0
        if( pFirstItem && pFirstItem == mpValueSetItem)
141
0
            nIndexInParent = 0;
142
0
        else
143
0
            nIndexInParent++;
144
0
    }
145
0
    return nIndexInParent;
146
0
}
147
148
149
sal_Int16 SAL_CALL ValueItemAcc::getAccessibleRole()
150
0
{
151
0
    return accessibility::AccessibleRole::LIST_ITEM;
152
0
}
153
154
155
OUString SAL_CALL ValueItemAcc::getAccessibleDescription()
156
0
{
157
0
    return OUString();
158
0
}
159
160
161
OUString SAL_CALL ValueItemAcc::getAccessibleName()
162
0
{
163
0
    const SolarMutexGuard aSolarGuard;
164
165
0
    if (mpValueSetItem)
166
0
    {
167
0
        if (mpValueSetItem->maText.isEmpty())
168
0
            return "Item " + OUString::number(static_cast<sal_Int32>(mpValueSetItem->mnId));
169
0
        else
170
0
            return mpValueSetItem->maText;
171
0
    }
172
173
0
    return OUString();
174
0
}
175
176
177
uno::Reference< accessibility::XAccessibleRelationSet > SAL_CALL ValueItemAcc::getAccessibleRelationSet()
178
0
{
179
0
    return uno::Reference< accessibility::XAccessibleRelationSet >();
180
0
}
181
182
183
sal_Int64 SAL_CALL ValueItemAcc::getAccessibleStateSet()
184
0
{
185
0
    const SolarMutexGuard aSolarGuard;
186
0
    sal_Int64 nStateSet = 0;
187
188
0
    if (mpValueSetItem)
189
0
    {
190
0
        nStateSet |= accessibility::AccessibleStateType::ENABLED;
191
0
        nStateSet |= accessibility::AccessibleStateType::SENSITIVE;
192
0
        nStateSet |= accessibility::AccessibleStateType::SHOWING;
193
0
        nStateSet |= accessibility::AccessibleStateType::VISIBLE;
194
0
        nStateSet |= accessibility::AccessibleStateType::TRANSIENT;
195
0
        nStateSet |= accessibility::AccessibleStateType::SELECTABLE;
196
0
        nStateSet |= accessibility::AccessibleStateType::FOCUSABLE;
197
198
0
        if (mpValueSetItem->mrParent.GetSelectedItemId() == mpValueSetItem->mnId)
199
0
        {
200
201
0
            nStateSet |= accessibility::AccessibleStateType::SELECTED;
202
0
            if (mpValueSetItem->mrParent.HasChildFocus())
203
0
                nStateSet |= accessibility::AccessibleStateType::FOCUSED;
204
0
        }
205
0
    }
206
207
0
    return nStateSet;
208
0
}
209
210
211
lang::Locale SAL_CALL ValueItemAcc::getLocale()
212
0
{
213
0
    const SolarMutexGuard aSolarGuard;
214
0
    uno::Reference< accessibility::XAccessible >    xParent( getAccessibleParent() );
215
0
    lang::Locale                                    aRet( u""_ustr, u""_ustr, u""_ustr );
216
217
0
    if( xParent.is() )
218
0
    {
219
0
        uno::Reference< accessibility::XAccessibleContext > xParentContext( xParent->getAccessibleContext() );
220
221
0
        if( xParentContext.is() )
222
0
            aRet = xParentContext->getLocale();
223
0
    }
224
225
0
    return aRet;
226
0
}
227
228
uno::Reference< accessibility::XAccessible > SAL_CALL ValueItemAcc::getAccessibleAtPoint( const awt::Point& )
229
0
{
230
0
    uno::Reference< accessibility::XAccessible > xRet;
231
0
    return xRet;
232
0
}
233
234
awt::Rectangle ValueItemAcc::implGetBounds()
235
0
{
236
0
    awt::Rectangle      aRet;
237
238
0
    if (mpValueSetItem)
239
0
    {
240
0
        tools::Rectangle aRect(mpValueSetItem->mrParent.GetItemRect(mpValueSetItem->mnId));
241
0
        tools::Rectangle aParentRect(Point(), mpValueSetItem->mrParent.GetOutputSizePixel());
242
243
0
        aRect.Intersection( aParentRect );
244
245
0
        aRet.X = aRect.Left();
246
0
        aRet.Y = aRect.Top();
247
0
        aRet.Width = aRect.GetWidth();
248
0
        aRet.Height = aRect.GetHeight();
249
0
    }
250
251
0
    return aRet;
252
0
}
253
254
void SAL_CALL ValueItemAcc::grabFocus()
255
0
{
256
    // nothing to do
257
0
}
258
259
sal_Int32 SAL_CALL ValueItemAcc::getForeground(  )
260
0
{
261
0
    Color nColor = Application::GetSettings().GetStyleSettings().GetWindowTextColor();
262
0
    return static_cast<sal_Int32>(nColor);
263
0
}
264
265
sal_Int32 SAL_CALL ValueItemAcc::getBackground(  )
266
0
{
267
0
    Color nColor;
268
0
    if (mpValueSetItem && mpValueSetItem->meType == VALUESETITEM_COLOR)
269
0
        nColor = mpValueSetItem->maColor;
270
0
    else
271
0
        nColor = Application::GetSettings().GetStyleSettings().GetWindowColor();
272
0
    return static_cast<sal_Int32>(nColor);
273
0
}
274
275
void ValueItemAcc::FireAccessibleEvent( short nEventId, const uno::Any& rOldValue, const uno::Any& rNewValue )
276
0
{
277
0
    NotifyAccessibleEvent(nEventId, rOldValue, rNewValue);
278
0
}
279
280
ValueSetAcc::ValueSetAcc(ValueSet* pValueSet) :
281
0
    mpValueSet(pValueSet),
282
0
    mbIsFocused(false)
283
0
{
284
0
}
285
286
287
ValueSetAcc::~ValueSetAcc()
288
0
{
289
0
}
290
291
292
void ValueSetAcc::FireAccessibleEvent( short nEventId, const uno::Any& rOldValue, const uno::Any& rNewValue )
293
0
{
294
0
    NotifyAccessibleEvent(nEventId, rOldValue, rNewValue);
295
0
}
296
297
bool ValueSetAcc::HasAccessibleListeners() const
298
0
{
299
0
    return comphelper::OAccessible::hasAccessibleListeners();
300
0
}
301
302
void ValueSetAcc::GetFocus()
303
0
{
304
0
    mbIsFocused = true;
305
306
    // Broadcast the state change.
307
0
    css::uno::Any aOldState, aNewState;
308
0
    aNewState <<= css::accessibility::AccessibleStateType::FOCUSED;
309
0
    FireAccessibleEvent(
310
0
        css::accessibility::AccessibleEventId::STATE_CHANGED,
311
0
        aOldState, aNewState);
312
0
}
313
314
315
void ValueSetAcc::LoseFocus()
316
0
{
317
0
    mbIsFocused = false;
318
319
    // Broadcast the state change.
320
0
    css::uno::Any aOldState, aNewState;
321
0
    aOldState <<= css::accessibility::AccessibleStateType::FOCUSED;
322
0
    FireAccessibleEvent(
323
0
        css::accessibility::AccessibleEventId::STATE_CHANGED,
324
0
        aOldState, aNewState);
325
0
}
326
327
sal_Int64 SAL_CALL ValueSetAcc::getAccessibleChildCount()
328
0
{
329
0
    const SolarMutexGuard aSolarGuard;
330
0
    ThrowIfDisposed();
331
332
0
    sal_Int64 nCount = mpValueSet->ImplGetVisibleItemCount();
333
0
    if (HasNoneField())
334
0
        nCount += 1;
335
0
    return nCount;
336
0
}
337
338
339
uno::Reference< accessibility::XAccessible > SAL_CALL ValueSetAcc::getAccessibleChild( sal_Int64 i )
340
0
{
341
0
    ThrowIfDisposed();
342
0
    const SolarMutexGuard aSolarGuard;
343
344
0
    if (i < 0 || i >= getAccessibleChildCount())
345
0
        throw lang::IndexOutOfBoundsException();
346
347
0
    ValueSetItem* pItem = getItem (sal::static_int_cast< sal_uInt16 >(i));
348
349
0
    if( !pItem )
350
0
        throw lang::IndexOutOfBoundsException();
351
352
0
    rtl::Reference< ValueItemAcc > xRet = pItem->GetAccessible();
353
0
    return xRet;
354
0
}
355
356
uno::Reference< accessibility::XAccessible > SAL_CALL ValueSetAcc::getAccessibleParent()
357
0
{
358
0
    ThrowIfDisposed();
359
0
    const SolarMutexGuard aSolarGuard;
360
0
    return mpValueSet->GetDrawingArea()->get_accessible_parent();
361
0
}
362
363
sal_Int64 SAL_CALL ValueSetAcc::getAccessibleIndexInParent()
364
0
{
365
0
    ThrowIfDisposed();
366
0
    const SolarMutexGuard aSolarGuard;
367
368
    // -1 for child not found/no parent (according to specification)
369
0
    sal_Int64 nRet = -1;
370
371
0
    uno::Reference<accessibility::XAccessible> xParent(getAccessibleParent());
372
0
    if (!xParent)
373
0
        return nRet;
374
375
0
    try
376
0
    {
377
0
        uno::Reference<accessibility::XAccessibleContext> xParentContext(xParent->getAccessibleContext());
378
379
        //  iterate over parent's children and search for this object
380
0
        if ( xParentContext.is() )
381
0
        {
382
0
            sal_Int64 nChildCount = xParentContext->getAccessibleChildCount();
383
0
            for ( sal_Int64 nChild = 0; ( nChild < nChildCount ) && ( -1 == nRet ); ++nChild )
384
0
            {
385
0
                uno::Reference<XAccessible> xChild(xParentContext->getAccessibleChild(nChild));
386
0
                if ( xChild.get() == this )
387
0
                    nRet = nChild;
388
0
            }
389
0
        }
390
0
    }
391
0
    catch (const uno::Exception&)
392
0
    {
393
0
        TOOLS_WARN_EXCEPTION( "svtools", "ValueSetAcc::getAccessibleIndexInParent" );
394
0
    }
395
396
0
    return nRet;
397
0
}
398
399
sal_Int16 SAL_CALL ValueSetAcc::getAccessibleRole()
400
0
{
401
0
    ThrowIfDisposed();
402
0
    return accessibility::AccessibleRole::LIST;
403
0
}
404
405
406
OUString SAL_CALL ValueSetAcc::getAccessibleDescription()
407
0
{
408
0
    ThrowIfDisposed();
409
0
    const SolarMutexGuard aSolarGuard;
410
0
    OUString              aRet;
411
412
0
    if (mpValueSet)
413
0
    {
414
0
        aRet = mpValueSet->GetAccessibleDescription();
415
0
    }
416
417
0
    return aRet;
418
0
}
419
420
421
OUString SAL_CALL ValueSetAcc::getAccessibleName()
422
0
{
423
0
    ThrowIfDisposed();
424
0
    const SolarMutexGuard aSolarGuard;
425
0
    OUString              aRet;
426
427
0
    if (mpValueSet)
428
0
    {
429
0
        aRet = mpValueSet->GetAccessibleName();
430
0
    }
431
432
0
    return aRet;
433
0
}
434
435
uno::Reference< accessibility::XAccessibleRelationSet > SAL_CALL ValueSetAcc::getAccessibleRelationSet()
436
0
{
437
0
    ThrowIfDisposed();
438
0
    SolarMutexGuard g;
439
0
    return mpValueSet->GetDrawingArea()->get_accessible_relation_set();
440
0
}
441
442
sal_Int64 SAL_CALL ValueSetAcc::getAccessibleStateSet()
443
0
{
444
0
    ThrowIfDisposed();
445
0
    sal_Int64 nStateSet = 0;
446
447
    // Set some states.
448
0
    nStateSet |= accessibility::AccessibleStateType::ENABLED;
449
0
    nStateSet |= accessibility::AccessibleStateType::SENSITIVE;
450
0
    nStateSet |= accessibility::AccessibleStateType::SHOWING;
451
0
    nStateSet |= accessibility::AccessibleStateType::VISIBLE;
452
0
    nStateSet |= accessibility::AccessibleStateType::MANAGES_DESCENDANTS;
453
0
    nStateSet |= accessibility::AccessibleStateType::FOCUSABLE;
454
0
    if (mbIsFocused)
455
0
        nStateSet |= accessibility::AccessibleStateType::FOCUSED;
456
457
0
    return nStateSet;
458
0
}
459
460
461
lang::Locale SAL_CALL ValueSetAcc::getLocale()
462
0
{
463
0
    ThrowIfDisposed();
464
0
    const SolarMutexGuard aSolarGuard;
465
0
    uno::Reference< accessibility::XAccessible >    xParent( getAccessibleParent() );
466
0
    lang::Locale                                    aRet( u""_ustr, u""_ustr, u""_ustr );
467
468
0
    if( xParent.is() )
469
0
    {
470
0
        uno::Reference< accessibility::XAccessibleContext > xParentContext( xParent->getAccessibleContext() );
471
472
0
        if( xParentContext.is() )
473
0
            aRet = xParentContext->getLocale ();
474
0
    }
475
476
0
    return aRet;
477
0
}
478
479
uno::Reference< accessibility::XAccessible > SAL_CALL ValueSetAcc::getAccessibleAtPoint( const awt::Point& aPoint )
480
0
{
481
0
    ThrowIfDisposed();
482
0
    const SolarMutexGuard aSolarGuard;
483
484
0
    const sal_uInt16 nItemId = mpValueSet->GetItemId(Point(aPoint.X, aPoint.Y));
485
0
    if ( !nItemId )
486
0
        return nullptr;
487
488
0
    const size_t nItemPos = mpValueSet->GetItemPos(nItemId);
489
0
    if( VALUESET_ITEM_NONEITEM == nItemPos )
490
0
        return nullptr;
491
492
0
    ValueSetItem* const pItem = mpValueSet->mItemList[nItemPos].get();
493
0
    return pItem->GetAccessible();
494
0
}
495
496
awt::Rectangle ValueSetAcc::implGetBounds()
497
0
{
498
0
    weld::DrawingArea* pDrawingArea = mpValueSet->GetDrawingArea();
499
0
    if (!pDrawingArea)
500
0
        return css::awt::Rectangle();
501
502
0
    const AbsoluteScreenPixelPoint aOutPos = pDrawingArea->get_accessible_location_on_screen();
503
0
    const Size aOutSize(mpValueSet->GetOutputSizePixel());
504
0
    tools::Rectangle aBounds(aOutPos, aOutSize);
505
506
    // subtract absolute parent pos to get relative pos in parent
507
0
    uno::Reference<accessibility::XAccessible> xParent(getAccessibleParent());
508
0
    if (xParent)
509
0
    {
510
0
        uno::Reference<accessibility::XAccessibleContext> xParentContext(xParent->getAccessibleContext());
511
0
        uno::Reference<accessibility::XAccessibleComponent> xParentComponent(xParent->getAccessibleContext(), css::uno::UNO_QUERY);
512
0
        if (xParentComponent.is())
513
0
        {
514
0
            awt::Point aParentPos = xParentComponent->getLocationOnScreen();
515
0
            aBounds.Move(-aParentPos.X, - aParentPos.Y);
516
0
        }
517
0
    }
518
519
0
    return vcl::unohelper::ConvertToAWTRect(aBounds);
520
0
}
521
522
void SAL_CALL ValueSetAcc::grabFocus()
523
0
{
524
0
    ThrowIfDisposed();
525
0
    const SolarMutexGuard aSolarGuard;
526
0
    mpValueSet->GrabFocus();
527
0
}
528
529
sal_Int32 SAL_CALL ValueSetAcc::getForeground(  )
530
0
{
531
0
    ThrowIfDisposed();
532
0
    Color nColor = Application::GetSettings().GetStyleSettings().GetWindowTextColor();
533
0
    return static_cast<sal_Int32>(nColor);
534
0
}
535
536
sal_Int32 SAL_CALL ValueSetAcc::getBackground(  )
537
0
{
538
0
    ThrowIfDisposed();
539
0
    Color nColor = Application::GetSettings().GetStyleSettings().GetWindowColor();
540
0
    return static_cast<sal_Int32>(nColor);
541
0
}
542
543
void SAL_CALL ValueSetAcc::selectAccessibleChild( sal_Int64 nChildIndex )
544
0
{
545
0
    ThrowIfDisposed();
546
0
    const SolarMutexGuard aSolarGuard;
547
548
0
    if (nChildIndex < 0 || nChildIndex >= getAccessibleChildCount())
549
0
        throw lang::IndexOutOfBoundsException();
550
551
0
    ValueSetItem* pItem = getItem (sal::static_int_cast< sal_uInt16 >(nChildIndex));
552
553
0
    if(pItem == nullptr)
554
0
        throw lang::IndexOutOfBoundsException();
555
556
0
    mpValueSet->SelectItem(pItem->mnId);
557
0
}
558
559
560
sal_Bool SAL_CALL ValueSetAcc::isAccessibleChildSelected( sal_Int64 nChildIndex )
561
0
{
562
0
    ThrowIfDisposed();
563
0
    const SolarMutexGuard aSolarGuard;
564
565
0
    if (nChildIndex < 0 || nChildIndex >= getAccessibleChildCount())
566
0
        throw lang::IndexOutOfBoundsException();
567
568
0
    ValueSetItem* pItem = getItem (sal::static_int_cast< sal_uInt16 >(nChildIndex));
569
570
0
    if (pItem == nullptr)
571
0
        throw lang::IndexOutOfBoundsException();
572
573
0
    bool bRet = mpValueSet->IsItemSelected(pItem->mnId);
574
0
    return bRet;
575
0
}
576
577
578
void SAL_CALL ValueSetAcc::clearAccessibleSelection()
579
0
{
580
0
    ThrowIfDisposed();
581
0
    const SolarMutexGuard aSolarGuard;
582
0
    mpValueSet->SetNoSelection();
583
0
}
584
585
586
void SAL_CALL ValueSetAcc::selectAllAccessibleChildren()
587
0
{
588
0
    ThrowIfDisposed();
589
    // unsupported due to single selection only
590
0
}
591
592
593
sal_Int64 SAL_CALL ValueSetAcc::getSelectedAccessibleChildCount()
594
0
{
595
0
    ThrowIfDisposed();
596
0
    const SolarMutexGuard aSolarGuard;
597
0
    sal_Int64 nRet = 0;
598
599
0
    for( sal_uInt16 i = 0, nCount = getItemCount(); i < nCount; i++ )
600
0
    {
601
0
        ValueSetItem* pItem = getItem (i);
602
603
0
        if (pItem && mpValueSet->IsItemSelected(pItem->mnId))
604
0
            ++nRet;
605
0
    }
606
607
0
    return nRet;
608
0
}
609
610
611
uno::Reference< accessibility::XAccessible > SAL_CALL ValueSetAcc::getSelectedAccessibleChild( sal_Int64 nSelectedChildIndex )
612
0
{
613
0
    ThrowIfDisposed();
614
0
    const SolarMutexGuard aSolarGuard;
615
0
    rtl::Reference< ValueItemAcc >    xRet;
616
617
0
    for( sal_uInt16 i = 0, nCount = getItemCount(), nSel = 0; ( i < nCount ) && !xRet.is(); i++ )
618
0
    {
619
0
        ValueSetItem* pItem = getItem(i);
620
621
0
        if (pItem && mpValueSet->IsItemSelected(pItem->mnId) && (nSelectedChildIndex == static_cast< sal_Int64 >(nSel++)))
622
0
            xRet = pItem->GetAccessible();
623
0
    }
624
625
0
    return xRet;
626
0
}
627
628
629
void SAL_CALL ValueSetAcc::deselectAccessibleChild( sal_Int64 nChildIndex )
630
0
{
631
0
    ThrowIfDisposed();
632
0
    const SolarMutexGuard aSolarGuard;
633
634
0
    if (nChildIndex < 0 || nChildIndex >= getAccessibleChildCount())
635
0
        throw lang::IndexOutOfBoundsException();
636
637
    // Because of the single selection we can reset the whole selection when
638
    // the specified child is currently selected.
639
0
    if (isAccessibleChildSelected(nChildIndex))
640
0
        mpValueSet->SetNoSelection();
641
0
}
642
643
void ValueSetAcc::Invalidate()
644
0
{
645
0
    mpValueSet = nullptr;
646
0
}
647
648
sal_uInt16 ValueSetAcc::getItemCount() const
649
0
{
650
0
    sal_uInt16 nCount = mpValueSet->ImplGetVisibleItemCount();
651
    // When the None-Item is visible then increase the number of items by
652
    // one.
653
0
    if (HasNoneField())
654
0
        nCount += 1;
655
0
    return nCount;
656
0
}
657
658
ValueSetItem* ValueSetAcc::getItem (sal_uInt16 nIndex) const
659
0
{
660
0
    ValueSetItem* pItem = nullptr;
661
662
0
    if (HasNoneField())
663
0
    {
664
0
        if (nIndex == 0)
665
            // When present the first item is the then always visible none field.
666
0
            pItem = mpValueSet->ImplGetItem(VALUESET_ITEM_NONEITEM);
667
0
        else
668
            // Shift down the index to compensate for the none field.
669
0
            nIndex -= 1;
670
0
    }
671
0
    if (pItem == nullptr)
672
0
        pItem = mpValueSet->ImplGetItem(nIndex);
673
674
0
    return pItem;
675
0
}
676
677
678
void ValueSetAcc::ThrowIfDisposed()
679
0
{
680
0
    ensureAlive();
681
682
0
    if (!mpValueSet)
683
0
    {
684
0
        assert(false && "ValueSetAcc not disposed but mpValueSet  == NULL");
685
0
        throw css::uno::RuntimeException(u"ValueSetAcc not disposed but mpValueSet == NULL"_ustr);
686
0
    }
687
0
}
688
689
bool ValueSetAcc::HasNoneField() const
690
0
{
691
0
    assert(mpValueSet && "ValueSetAcc::HasNoneField called with mpValueSet==NULL");
692
0
    return ((mpValueSet->GetStyle() & WB_NONEFIELD) != 0);
693
0
}
694
695
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */