Coverage Report

Created: 2026-04-09 11:41

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/vcl/source/accessibility/accessiblelistboxentry.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 <accessibility/accessiblelistboxentry.hxx>
21
#include <accessibility/accessiblelistbox.hxx>
22
#include <vcl/toolkit/treelistbox.hxx>
23
#include <vcl/toolkit/viewdataentry.hxx>
24
#include <com/sun/star/awt/Rectangle.hpp>
25
#include <com/sun/star/accessibility/AccessibleEventId.hpp>
26
#include <com/sun/star/accessibility/AccessibleRelationType.hpp>
27
#include <com/sun/star/accessibility/AccessibleRole.hpp>
28
#include <com/sun/star/accessibility/AccessibleStateType.hpp>
29
#include <com/sun/star/datatransfer/clipboard/XClipboard.hpp>
30
#include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
31
#include <i18nlangtag/languagetag.hxx>
32
#include <vcl/svapp.hxx>
33
#include <vcl/settings.hxx>
34
#include <vcl/unohelp.hxx>
35
#include <vcl/unohelp2.hxx>
36
#include <unotools/accessiblerelationsethelper.hxx>
37
#include <cppuhelper/supportsservice.hxx>
38
#include <svdata.hxx>
39
#include <strings.hrc>
40
41
using namespace ::com::sun::star::accessibility;
42
using namespace ::com::sun::star::uno;
43
using namespace ::com::sun::star::lang;
44
using namespace ::com::sun::star;
45
using namespace ::comphelper;
46
47
AccessibleListBoxEntry::AccessibleListBoxEntry( SvTreeListBox& _rListBox,
48
                                                SvTreeListEntry& rEntry,
49
                                                AccessibleListBox & rListBox)
50
0
    : AccessibleListBoxEntry_BASE()
51
52
0
    , m_pTreeListBox( &_rListBox )
53
0
    , m_pSvLBoxEntry(&rEntry)
54
0
    , m_wListBox(&rListBox)
55
0
{
56
0
    m_pTreeListBox->AddEventListener( LINK( this, AccessibleListBoxEntry, WindowEventListener ) );
57
0
    _rListBox.FillEntryPath( m_pSvLBoxEntry, m_aEntryPath );
58
0
}
59
60
IMPL_LINK( AccessibleListBoxEntry, WindowEventListener, VclWindowEvent&, rEvent, void )
61
0
{
62
0
    OSL_ENSURE( rEvent.GetWindow() , "AccessibleListBoxEntry::WindowEventListener: no event window!" );
63
0
    OSL_ENSURE( rEvent.GetWindow() == m_pTreeListBox, "AccessibleListBoxEntry::WindowEventListener: where did this come from?" );
64
65
0
    if ( m_pTreeListBox == nullptr )
66
0
        return;
67
68
0
    switch ( rEvent.GetId() )
69
0
    {
70
0
        case VclEventId::CheckboxToggle:
71
0
        {
72
            // assert this object is represented as a checkbox on a11y layer (LABEL role is used for
73
            // SvButtonState::Tristate, s. AccessibleListBoxEntry::getAccessibleRole)
74
0
            assert(getAccessibleRole() == AccessibleRole::CHECK_BOX
75
0
                   || getAccessibleRole() == AccessibleRole::LABEL);
76
0
            Any aOldValue;
77
0
            Any aNewValue;
78
0
            if (getAccessibleStateSet() & AccessibleStateType::CHECKED)
79
0
                aNewValue <<= AccessibleStateType::CHECKED;
80
0
            else
81
0
                aOldValue <<= AccessibleStateType::CHECKED;
82
83
0
            NotifyAccessibleEvent(AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue);
84
0
            break;
85
0
        }
86
0
        case  VclEventId::ObjectDying :
87
0
        {
88
0
            dispose();
89
0
            break;
90
0
        }
91
0
        default: break;
92
0
    }
93
0
}
94
95
tools::Rectangle AccessibleListBoxEntry::GetBoundingBox_Impl() const
96
0
{
97
0
    tools::Rectangle aRect;
98
0
    SvTreeListEntry* pEntry = m_pTreeListBox->GetEntryFromPath( m_aEntryPath );
99
0
    if ( pEntry )
100
0
    {
101
0
        aRect = m_pTreeListBox->GetBoundingRect( pEntry );
102
0
        SvTreeListEntry* pParent = m_pTreeListBox->GetParent( pEntry );
103
0
        if ( pParent )
104
0
        {
105
            // position relative to parent entry
106
0
            Point aTopLeft = aRect.TopLeft();
107
0
            aTopLeft -= m_pTreeListBox->GetBoundingRect( pParent ).TopLeft();
108
0
            aRect = tools::Rectangle( aTopLeft, aRect.GetSize() );
109
0
        }
110
0
    }
111
112
0
    return aRect;
113
0
}
114
115
bool AccessibleListBoxEntry::IsShowing_Impl() const
116
0
{
117
0
    rtl::Reference<comphelper::OAccessible> pParent = implGetParentAccessible();
118
119
0
    bool bShowing = false;
120
0
    if (pParent.is())
121
0
    {
122
0
        bShowing = GetBoundingBox_Impl().Overlaps(
123
0
            vcl::unohelper::ConvertToVCLRect(pParent->getBounds()));
124
0
    }
125
126
0
    return bShowing;
127
0
}
128
129
void AccessibleListBoxEntry::CheckActionIndex(sal_Int32 nIndex)
130
0
{
131
0
    if (nIndex < 0 || nIndex >= getAccessibleActionCount())
132
0
        throw css::lang::IndexOutOfBoundsException();
133
0
}
134
135
OUString AccessibleListBoxEntry::implGetText()
136
0
{
137
0
    SvTreeListEntry* pEntry = m_pTreeListBox->GetEntryFromPath( m_aEntryPath );
138
0
    if (pEntry)
139
0
        return SvTreeListBox::SearchEntryTextWithHeadTitle(pEntry);
140
0
    return OUString();
141
0
}
142
143
Locale AccessibleListBoxEntry::implGetLocale()
144
0
{
145
0
    return Application::GetSettings().GetUILanguageTag().getLocale();
146
0
}
147
void AccessibleListBoxEntry::implGetSelection( sal_Int32& nStartIndex, sal_Int32& nEndIndex )
148
0
{
149
0
    nStartIndex = 0;
150
0
    nEndIndex = 0;
151
0
}
152
153
css::awt::Rectangle AccessibleListBoxEntry::implGetBounds()
154
0
{
155
0
    return vcl::unohelper::ConvertToAWTRect(GetBoundingBox_Impl());
156
0
}
157
158
159
// XComponent
160
161
void SAL_CALL AccessibleListBoxEntry::disposing()
162
0
{
163
0
    SolarMutexGuard aSolarGuard;
164
0
    ::osl::MutexGuard aGuard( m_aMutex );
165
166
0
    Reference< XAccessible > xKeepAlive( this );
167
168
0
    OAccessible::disposing();
169
170
    // clean up
171
0
    m_wListBox.clear();
172
173
0
    if ( m_pTreeListBox )
174
0
        m_pTreeListBox->RemoveEventListener( LINK( this, AccessibleListBoxEntry, WindowEventListener ) );
175
0
    m_pTreeListBox = nullptr;
176
0
}
177
178
uno::Any SAL_CALL AccessibleListBoxEntry::queryInterface(const uno::Type& rType)
179
0
{
180
0
    if (rType == cppu::UnoType<XAccessibleText>::get())
181
0
    {
182
        // don't support XAccessibleText interface if there's no text item
183
        // (e.g. for IconView items), as screen readers may give text a higher
184
        // priority than accessible name and just say something like "blank" otherwise
185
0
        SvTreeListEntry* pEntry = m_pTreeListBox->GetEntryFromPath(m_aEntryPath);
186
0
        if (pEntry && !pEntry->GetFirstItem(SvLBoxItemType::String))
187
0
            return uno::Any();
188
0
    }
189
190
0
    return AccessibleListBoxEntry_BASE::queryInterface(rType);
191
0
}
192
193
// XServiceInfo
194
195
OUString SAL_CALL AccessibleListBoxEntry::getImplementationName()
196
0
{
197
0
    return u"com.sun.star.comp.svtools.AccessibleTreeListBoxEntry"_ustr;
198
0
}
199
200
Sequence< OUString > SAL_CALL AccessibleListBoxEntry::getSupportedServiceNames()
201
0
{
202
0
    return {u"com.sun.star.accessibility.AccessibleContext"_ustr};
203
0
}
204
205
sal_Bool SAL_CALL AccessibleListBoxEntry::supportsService( const OUString& _rServiceName )
206
0
{
207
0
    return cppu::supportsService(this, _rServiceName);
208
0
}
209
210
// XAccessibleContext
211
212
sal_Int64 SAL_CALL AccessibleListBoxEntry::getAccessibleChildCount(  )
213
0
{
214
0
    SolarMutexGuard aSolarGuard;
215
0
    ::osl::MutexGuard aGuard( m_aMutex );
216
217
0
    ensureAlive();
218
0
    SvTreeListEntry* pEntry = m_pTreeListBox->GetEntryFromPath( m_aEntryPath );
219
0
    sal_Int32 nCount = 0;
220
0
    if ( pEntry )
221
0
        nCount = m_pTreeListBox->GetLevelChildCount( pEntry );
222
223
0
    return nCount;
224
0
}
225
226
Reference< XAccessible > SAL_CALL AccessibleListBoxEntry::getAccessibleChild( sal_Int64 i )
227
0
{
228
0
    SolarMutexGuard aSolarGuard;
229
0
    ::osl::MutexGuard aGuard( m_aMutex );
230
0
    ensureAlive();
231
232
0
    SvTreeListEntry* pEntry = GetRealChild(i);
233
0
    if ( !pEntry )
234
0
        throw IndexOutOfBoundsException();
235
236
0
    rtl::Reference<AccessibleListBox> xListBox(m_wListBox);
237
0
    assert(xListBox.is());
238
239
0
    return xListBox->implGetAccessible(*pEntry);
240
0
}
241
242
rtl::Reference<comphelper::OAccessible> AccessibleListBoxEntry::implGetParentAccessible() const
243
0
{
244
0
    rtl::Reference<comphelper::OAccessible> pParent;
245
0
    assert( m_aEntryPath.size() ); // invalid path
246
0
    if ( m_aEntryPath.size() == 1 )
247
0
    {   // we're a top level entry
248
        // -> our parent is the tree listbox itself
249
0
        if ( m_pTreeListBox )
250
0
            pParent = m_pTreeListBox->GetAccessible();
251
0
    }
252
0
    else
253
0
    {   // we have an entry as parent -> get its accessible
254
255
        // shorten our access path by one
256
0
        std::deque< sal_Int32 > aParentPath( m_aEntryPath );
257
0
        aParentPath.pop_back();
258
259
        // get the entry for this shortened access path
260
0
        SvTreeListEntry* pParentEntry = m_pTreeListBox->GetEntryFromPath( aParentPath );
261
0
        assert(pParentEntry && "AccessibleListBoxEntry::implGetParentAccessible: could not obtain a parent entry!");
262
0
        if ( pParentEntry )
263
0
        {
264
0
            rtl::Reference<AccessibleListBox> xListBox(m_wListBox);
265
0
            assert(xListBox.is());
266
0
            return xListBox->implGetAccessible(*pParentEntry);
267
            // the AccessibleListBoxEntry class will create its parent
268
            // when needed
269
0
        }
270
0
    }
271
272
0
    return pParent;
273
0
}
274
275
276
Reference< XAccessible > SAL_CALL AccessibleListBoxEntry::getAccessibleParent(  )
277
0
{
278
0
    SolarMutexGuard aSolarGuard;
279
0
    ::osl::MutexGuard aGuard( m_aMutex );
280
0
    ensureAlive();
281
282
0
    return implGetParentAccessible( );
283
0
}
284
285
sal_Int64 SAL_CALL AccessibleListBoxEntry::getAccessibleIndexInParent(  )
286
0
{
287
0
    ::osl::MutexGuard aGuard( m_aMutex );
288
289
0
    OSL_ENSURE( !m_aEntryPath.empty(), "empty path" );
290
0
    return m_aEntryPath.empty() ? -1 : m_aEntryPath.back();
291
0
}
292
293
sal_Int32 AccessibleListBoxEntry::GetRoleType() const
294
0
{
295
0
    sal_Int32 nCase = 0;
296
0
    SvTreeListEntry* pEntry = m_pTreeListBox->GetEntry(0);
297
0
    if ( pEntry )
298
0
    {
299
0
        if( pEntry->HasChildrenOnDemand() || m_pTreeListBox->GetChildCount(pEntry) > 0  )
300
0
        {
301
0
            nCase = 1;
302
0
            return nCase;
303
0
        }
304
0
    }
305
306
0
    bool bHasButtons = (m_pTreeListBox->GetStyle() & WB_HASBUTTONS)!=0;
307
0
    if( !(m_pTreeListBox->GetTreeFlags() & SvTreeFlags::CHKBTN) )
308
0
    {
309
0
        if( bHasButtons )
310
0
            nCase = 1;
311
0
    }
312
0
    else
313
0
    {
314
0
        if( bHasButtons )
315
0
            nCase = 2;
316
0
        else
317
0
            nCase = 3;
318
0
    }
319
0
    return nCase;
320
0
}
321
322
sal_Int16 SAL_CALL AccessibleListBoxEntry::getAccessibleRole(  )
323
0
{
324
0
    SolarMutexGuard aSolarGuard;
325
0
    ::osl::MutexGuard aGuard( m_aMutex );
326
327
0
    SvTreeListBox* pBox = m_pTreeListBox;
328
0
    if(!pBox)
329
0
        return AccessibleRole::UNKNOWN;
330
331
0
    SvTreeFlags treeFlag = pBox->GetTreeFlags();
332
0
    if(treeFlag & SvTreeFlags::CHKBTN )
333
0
    {
334
0
        SvTreeListEntry* pEntry = pBox->GetEntryFromPath( m_aEntryPath );
335
0
        SvButtonState eState = pBox->GetCheckButtonState( pEntry );
336
0
        switch( eState )
337
0
        {
338
0
        case SvButtonState::Checked:
339
0
        case SvButtonState::Unchecked:
340
0
            return AccessibleRole::CHECK_BOX;
341
0
        case SvButtonState::Tristate:
342
0
        default:
343
0
            return AccessibleRole::LABEL;
344
0
        }
345
0
    }
346
0
    if (GetRoleType() == 0)
347
0
        return AccessibleRole::LIST_ITEM;
348
0
    else
349
        //o is: return AccessibleRole::LABEL;
350
0
        return AccessibleRole::TREE_ITEM;
351
0
}
352
353
OUString SAL_CALL AccessibleListBoxEntry::getAccessibleDescription(  )
354
0
{
355
0
    SolarMutexGuard aSolarGuard;
356
0
    ::osl::MutexGuard aGuard( m_aMutex );
357
358
0
    return OUString();
359
0
}
360
361
OUString SAL_CALL AccessibleListBoxEntry::getAccessibleName(  )
362
0
{
363
0
    ::osl::MutexGuard aGuard( m_aMutex );
364
365
0
    ensureAlive();
366
367
0
    if (SvTreeListEntry* pEntry = m_pTreeListBox->GetEntryFromPath(m_aEntryPath))
368
0
    {
369
0
        OUString sName = pEntry->GetAccessibleName();
370
0
        if (!sName.isEmpty())
371
0
            return sName;
372
0
    }
373
374
0
    return implGetText();
375
0
}
376
377
Reference< XAccessibleRelationSet > SAL_CALL AccessibleListBoxEntry::getAccessibleRelationSet(  )
378
0
{
379
0
    rtl::Reference<comphelper::OAccessible> pParent;
380
0
    if ( m_aEntryPath.size() > 1 ) // not a root entry
381
0
        pParent = implGetParentAccessible();
382
0
    if (!pParent.is())
383
0
        return nullptr;
384
385
0
    rtl::Reference<utl::AccessibleRelationSetHelper> pRelationSetHelper = new utl::AccessibleRelationSetHelper;
386
0
    Sequence<Reference<XAccessible>> aSequence{ pParent };
387
0
    pRelationSetHelper->AddRelation(
388
0
        AccessibleRelation( AccessibleRelationType_NODE_CHILD_OF, aSequence ) );
389
0
    return pRelationSetHelper;
390
0
}
391
392
sal_Int64 SAL_CALL AccessibleListBoxEntry::getAccessibleStateSet(  )
393
0
{
394
0
    ::osl::MutexGuard aGuard( m_aMutex );
395
396
0
    sal_Int64 nStateSet = 0;
397
398
0
    if (isAlive())
399
0
    {
400
0
        switch(getAccessibleRole())
401
0
        {
402
0
            case AccessibleRole::LABEL:
403
0
                nStateSet |= AccessibleStateType::TRANSIENT;
404
0
                nStateSet |= AccessibleStateType::SELECTABLE;
405
0
                nStateSet |= AccessibleStateType::ENABLED;
406
0
                if (m_pTreeListBox->IsInplaceEditingEnabled())
407
0
                    nStateSet |= AccessibleStateType::EDITABLE;
408
0
                if (IsShowing_Impl())
409
0
                    nStateSet |= AccessibleStateType::SHOWING;
410
0
                break;
411
0
            case AccessibleRole::CHECK_BOX:
412
0
                nStateSet |= AccessibleStateType::TRANSIENT;
413
0
                nStateSet |= AccessibleStateType::SELECTABLE;
414
0
                nStateSet |= AccessibleStateType::ENABLED;
415
0
                if (IsShowing_Impl())
416
0
                    nStateSet |= AccessibleStateType::SHOWING;
417
0
                break;
418
0
        }
419
420
0
        if (SvTreeListEntry* pEntry = m_pTreeListBox->GetEntryFromPath(m_aEntryPath))
421
0
        {
422
0
            if (pEntry->HasChildrenOnDemand() || pEntry->HasChildren())
423
0
            {
424
0
                nStateSet |= AccessibleStateType::EXPANDABLE;
425
0
                if (m_pTreeListBox->IsExpanded(pEntry))
426
0
                    nStateSet |= AccessibleStateType::EXPANDED;
427
0
            }
428
429
0
            if (m_pTreeListBox->GetTreeFlags() & SvTreeFlags::CHKBTN)
430
0
                nStateSet |= AccessibleStateType::CHECKABLE;
431
0
            if (m_pTreeListBox->GetCheckButtonState(pEntry) == SvButtonState::Checked)
432
0
                nStateSet |= AccessibleStateType::CHECKED;
433
0
            if (m_pTreeListBox->IsEntryVisible(pEntry))
434
0
                nStateSet |= AccessibleStateType::VISIBLE;
435
0
            if (m_pTreeListBox->IsSelected(pEntry))
436
0
                nStateSet |= AccessibleStateType::SELECTED;
437
0
            if (m_pTreeListBox->IsEnabled())
438
0
            {
439
0
                nStateSet |= AccessibleStateType::ENABLED;
440
0
                nStateSet |= AccessibleStateType::FOCUSABLE;
441
0
                nStateSet |= AccessibleStateType::SELECTABLE;
442
0
                SvViewDataEntry* pViewDataNewCur = m_pTreeListBox->GetViewDataEntry(pEntry);
443
0
                if (pViewDataNewCur && pViewDataNewCur->HasFocus())
444
0
                    nStateSet |= AccessibleStateType::FOCUSED;
445
0
            }
446
0
        }
447
0
    }
448
0
    else
449
0
        nStateSet |= AccessibleStateType::DEFUNC;
450
451
0
    return nStateSet;
452
0
}
453
454
Locale SAL_CALL AccessibleListBoxEntry::getLocale(  )
455
0
{
456
0
    SolarMutexGuard aSolarGuard;
457
0
    ::osl::MutexGuard aGuard( m_aMutex );
458
459
0
    return implGetLocale();
460
0
}
461
462
// XAccessibleComponent
463
464
Reference< XAccessible > SAL_CALL AccessibleListBoxEntry::getAccessibleAtPoint( const awt::Point& _aPoint )
465
0
{
466
0
    SolarMutexGuard aSolarGuard;
467
0
    ::osl::MutexGuard aGuard( m_aMutex );
468
469
0
    ensureAlive();
470
0
    SvTreeListEntry* pEntry
471
0
        = m_pTreeListBox->GetEntry(vcl::unohelper::ConvertToVCLPoint(_aPoint));
472
0
    if ( !pEntry )
473
0
        throw RuntimeException(u"AccessibleListBoxEntry::getAccessibleAtPoint - pEntry cannot be empty!"_ustr);
474
475
0
    rtl::Reference<AccessibleListBox> xListBox(m_wListBox);
476
0
    assert(xListBox.is());
477
0
    rtl::Reference<AccessibleListBoxEntry> pAccEntry = xListBox->implGetAccessible(*pEntry);
478
0
    tools::Rectangle aRect = pAccEntry->GetBoundingBox_Impl();
479
0
    if (aRect.Contains(vcl::unohelper::ConvertToVCLPoint(_aPoint))
480
0
        && pAccEntry->implGetParentAccessible().get() == this)
481
0
        return pAccEntry;
482
483
0
    return {};
484
0
}
485
486
void SAL_CALL AccessibleListBoxEntry::grabFocus(  )
487
0
{
488
    // do nothing, because no focus for each item
489
0
}
490
491
sal_Int32 AccessibleListBoxEntry::getForeground(    )
492
0
{
493
0
    SolarMutexGuard aSolarGuard;
494
0
    ::osl::MutexGuard aGuard( m_aMutex );
495
496
0
    sal_Int32 nColor = 0;
497
0
    Reference< XAccessible > xParent = getAccessibleParent();
498
0
    if ( xParent.is() )
499
0
    {
500
0
        Reference< XAccessibleComponent > xParentComp( xParent->getAccessibleContext(), UNO_QUERY );
501
0
        if ( xParentComp.is() )
502
0
            nColor = xParentComp->getForeground();
503
0
    }
504
505
0
    return nColor;
506
0
}
507
508
sal_Int32 AccessibleListBoxEntry::getBackground(  )
509
0
{
510
0
    SolarMutexGuard aSolarGuard;
511
0
    ::osl::MutexGuard aGuard( m_aMutex );
512
513
0
    sal_Int32 nColor = 0;
514
0
    Reference< XAccessible > xParent = getAccessibleParent();
515
0
    if ( xParent.is() )
516
0
    {
517
0
        Reference< XAccessibleComponent > xParentComp( xParent->getAccessibleContext(), UNO_QUERY );
518
0
        if ( xParentComp.is() )
519
0
            nColor = xParentComp->getBackground();
520
0
    }
521
522
0
    return nColor;
523
0
}
524
525
// XAccessibleText
526
527
528
awt::Rectangle SAL_CALL AccessibleListBoxEntry::getCharacterBounds( sal_Int32 nIndex )
529
0
{
530
0
    SolarMutexGuard aSolarGuard;
531
0
    ::osl::MutexGuard aGuard( m_aMutex );
532
533
0
    ensureAlive();
534
535
0
    if ( !implIsValidIndex( nIndex, implGetText().getLength() ) )
536
0
        throw IndexOutOfBoundsException();
537
538
0
    awt::Rectangle aBounds( 0, 0, 0, 0 );
539
0
    SvTreeListEntry* pEntry = m_pTreeListBox->GetEntryFromPath( m_aEntryPath );
540
0
    if ( pEntry )
541
0
    {
542
0
        vcl::ControlLayoutData aLayoutData;
543
0
        tools::Rectangle aItemRect = GetBoundingBox_Impl();
544
0
        m_pTreeListBox->RecordLayoutData( &aLayoutData, aItemRect );
545
0
        tools::Rectangle aCharRect = aLayoutData.GetCharacterBounds( nIndex );
546
0
        aCharRect.Move( -aItemRect.Left(), -aItemRect.Top() );
547
0
        aBounds = vcl::unohelper::ConvertToAWTRect(aCharRect);
548
0
    }
549
550
0
    return aBounds;
551
0
}
552
553
sal_Int32 SAL_CALL AccessibleListBoxEntry::getIndexAtPoint( const awt::Point& aPoint )
554
0
{
555
0
    SolarMutexGuard aSolarGuard;
556
0
    ::osl::MutexGuard aGuard( m_aMutex );
557
0
    ensureAlive();
558
0
    if(aPoint.X==0 && aPoint.Y==0) return 0;
559
560
0
    sal_Int32 nIndex = -1;
561
0
    SvTreeListEntry* pEntry = m_pTreeListBox->GetEntryFromPath( m_aEntryPath );
562
0
    if ( pEntry )
563
0
    {
564
0
        vcl::ControlLayoutData aLayoutData;
565
0
        tools::Rectangle aItemRect = GetBoundingBox_Impl();
566
0
        m_pTreeListBox->RecordLayoutData( &aLayoutData, aItemRect );
567
0
        Point aPnt(vcl::unohelper::ConvertToVCLPoint(aPoint));
568
0
        aPnt += aItemRect.TopLeft();
569
0
        nIndex = aLayoutData.GetIndexForPoint( aPnt );
570
0
    }
571
572
0
    return nIndex;
573
0
}
574
575
sal_Bool SAL_CALL AccessibleListBoxEntry::copyText( sal_Int32 nStartIndex, sal_Int32 nEndIndex )
576
0
{
577
0
    SolarMutexGuard aSolarGuard;
578
0
    ::osl::MutexGuard aGuard( m_aMutex );
579
0
    ensureAlive();
580
581
0
    OUString sText = implGetText();
582
0
    if  ( ( 0 > nStartIndex ) || ( sText.getLength() <= nStartIndex )
583
0
        || ( 0 > nEndIndex ) || ( sText.getLength() <= nEndIndex ) )
584
0
        throw IndexOutOfBoundsException();
585
586
0
    if (!m_pTreeListBox)
587
0
        return false;
588
589
0
    sal_Int32 nLen = nEndIndex - nStartIndex + 1;
590
0
    css::uno::Reference<css::datatransfer::clipboard::XClipboard> xClipBoard = m_pTreeListBox->GetClipboard();
591
0
    vcl::unohelper::TextDataObject::CopyStringTo(sText.copy(nStartIndex, nLen), xClipBoard);
592
593
0
    return true;
594
0
}
595
596
sal_Bool SAL_CALL AccessibleListBoxEntry::scrollSubstringTo( sal_Int32, sal_Int32, AccessibleScrollType )
597
0
{
598
0
    return false;
599
0
}
600
601
// XAccessibleAction
602
603
sal_Int32 SAL_CALL AccessibleListBoxEntry::getAccessibleActionCount(  )
604
0
{
605
0
    ::osl::MutexGuard aGuard( m_aMutex );
606
607
    // three actions supported
608
0
    SvTreeFlags treeFlag = m_pTreeListBox->GetTreeFlags();
609
0
    bool bHasButtons = (m_pTreeListBox->GetStyle() & WB_HASBUTTONS)!=0;
610
0
    if( (treeFlag & SvTreeFlags::CHKBTN) && !bHasButtons)
611
0
    {
612
0
        sal_Int16 role = getAccessibleRole();
613
0
        if ( role == AccessibleRole::CHECK_BOX )
614
0
            return 2;
615
0
        else if ( role == AccessibleRole::LABEL )
616
0
            return 0;
617
0
    }
618
0
    else
619
0
        return 1;
620
0
    return 0;
621
0
}
622
623
sal_Bool SAL_CALL AccessibleListBoxEntry::doAccessibleAction( sal_Int32 nIndex )
624
0
{
625
0
    SolarMutexGuard aSolarGuard;
626
0
    ::osl::MutexGuard aGuard( m_aMutex );
627
628
0
    bool bRet = false;
629
0
    CheckActionIndex(nIndex);
630
0
    ensureAlive();
631
632
0
    SvTreeFlags treeFlag = m_pTreeListBox->GetTreeFlags();
633
0
    if( nIndex == 0 && (treeFlag & SvTreeFlags::CHKBTN) )
634
0
    {
635
0
        if(getAccessibleRole() == AccessibleRole::CHECK_BOX)
636
0
        {
637
0
            SvTreeListEntry* pEntry = m_pTreeListBox->GetEntryFromPath( m_aEntryPath );
638
0
            SvButtonState state = m_pTreeListBox->GetCheckButtonState( pEntry );
639
0
            if ( state == SvButtonState::Checked )
640
0
                m_pTreeListBox->SetCheckButtonState(pEntry, SvButtonState::Unchecked);
641
0
            else if (state == SvButtonState::Unchecked)
642
0
                m_pTreeListBox->SetCheckButtonState(pEntry, SvButtonState::Checked);
643
0
        }
644
0
    }
645
0
    else if( (nIndex == 1 && (treeFlag & SvTreeFlags::CHKBTN) ) || (nIndex == 0) )
646
0
    {
647
0
        SvTreeListEntry* pEntry = m_pTreeListBox->GetEntryFromPath( m_aEntryPath );
648
0
        if ( pEntry )
649
0
        {
650
0
            if ( m_pTreeListBox->IsExpanded( pEntry ) )
651
0
                m_pTreeListBox->Collapse( pEntry );
652
0
            else
653
0
                m_pTreeListBox->Expand( pEntry );
654
0
            bRet = true;
655
0
        }
656
0
    }
657
658
0
    return bRet;
659
0
}
660
661
OUString SAL_CALL AccessibleListBoxEntry::getAccessibleActionDescription( sal_Int32 nIndex )
662
0
{
663
0
    SolarMutexGuard aSolarGuard;
664
0
    ::osl::MutexGuard aGuard( m_aMutex );
665
666
0
    CheckActionIndex(nIndex);
667
0
    ensureAlive();
668
669
0
    SvTreeListEntry* pEntry = m_pTreeListBox->GetEntryFromPath( m_aEntryPath );
670
0
    SvButtonState state = m_pTreeListBox->GetCheckButtonState( pEntry );
671
0
    SvTreeFlags treeFlag = m_pTreeListBox->GetTreeFlags();
672
0
    if(nIndex == 0 && (treeFlag & SvTreeFlags::CHKBTN))
673
0
    {
674
0
        if(getAccessibleRole() == AccessibleRole::CHECK_BOX)
675
0
        {
676
0
            if ( state == SvButtonState::Checked )
677
0
                return u"UnCheck"_ustr;
678
0
            else if (state == SvButtonState::Unchecked)
679
0
                return u"Check"_ustr;
680
0
        }
681
0
        else
682
0
        {
683
            //Sometimes, a List or Tree may have both checkbox and label at the same time
684
0
            return OUString();
685
0
        }
686
0
    }
687
0
    else if( (nIndex == 1 && (treeFlag & SvTreeFlags::CHKBTN)) || nIndex == 0 )
688
0
    {
689
0
        if( pEntry && (pEntry->HasChildren() || pEntry->HasChildrenOnDemand()) )
690
0
            return m_pTreeListBox->IsExpanded( pEntry ) ?
691
0
            VclResId(STR_SVT_ACC_ACTION_COLLAPSE) :
692
0
            VclResId(STR_SVT_ACC_ACTION_EXPAND);
693
0
        return OUString();
694
695
0
    }
696
0
    throw IndexOutOfBoundsException();
697
0
}
698
699
Reference< XAccessibleKeyBinding > AccessibleListBoxEntry::getAccessibleActionKeyBinding( sal_Int32 nIndex )
700
0
{
701
0
    Reference< XAccessibleKeyBinding > xRet;
702
0
    CheckActionIndex(nIndex);
703
    // ... which key?
704
0
    return xRet;
705
0
}
706
707
// XAccessibleSelection
708
709
void SAL_CALL AccessibleListBoxEntry::selectAccessibleChild( sal_Int64 nChildIndex )
710
0
{
711
0
    SolarMutexGuard aSolarGuard;
712
0
    ::osl::MutexGuard aGuard( m_aMutex );
713
714
0
    ensureAlive();
715
716
0
    if (nChildIndex < 0 || nChildIndex >= getAccessibleChildCount())
717
0
        throw IndexOutOfBoundsException();
718
719
0
    SvTreeListEntry* pEntry = GetRealChild(nChildIndex);
720
0
    if ( !pEntry )
721
0
        throw IndexOutOfBoundsException();
722
723
0
    m_pTreeListBox->Select( pEntry );
724
0
}
725
726
sal_Bool SAL_CALL AccessibleListBoxEntry::isAccessibleChildSelected( sal_Int64 nChildIndex )
727
0
{
728
0
    SolarMutexGuard aSolarGuard;
729
0
    ::osl::MutexGuard aGuard( m_aMutex );
730
731
0
    ensureAlive();
732
733
0
    if (nChildIndex < 0 || nChildIndex >= getAccessibleChildCount())
734
0
        throw IndexOutOfBoundsException();
735
736
0
    SvTreeListEntry* pParent = m_pTreeListBox->GetEntryFromPath( m_aEntryPath );
737
0
    SvTreeListEntry* pEntry = m_pTreeListBox->GetEntry( pParent, nChildIndex );
738
0
    if ( !pEntry )
739
0
        throw IndexOutOfBoundsException();
740
741
0
    return m_pTreeListBox->IsSelected( pEntry );
742
0
}
743
744
void SAL_CALL AccessibleListBoxEntry::clearAccessibleSelection(  )
745
0
{
746
0
    SolarMutexGuard aSolarGuard;
747
0
    ::osl::MutexGuard aGuard( m_aMutex );
748
749
0
    ensureAlive();
750
751
0
    SvTreeListEntry* pParent = m_pTreeListBox->GetEntryFromPath( m_aEntryPath );
752
0
    if ( !pParent )
753
0
        throw RuntimeException(u"AccessibleListBoxEntry::clearAccessibleSelection - pParent cannot be empty!"_ustr);
754
0
    sal_Int32 nCount = m_pTreeListBox->GetLevelChildCount( pParent );
755
0
    for ( sal_Int32 i = 0; i < nCount; ++i )
756
0
    {
757
0
        SvTreeListEntry* pEntry = m_pTreeListBox->GetEntry( pParent, i );
758
0
        if ( m_pTreeListBox->IsSelected( pEntry ) )
759
0
            m_pTreeListBox->Select( pEntry, false );
760
0
    }
761
0
}
762
763
void SAL_CALL AccessibleListBoxEntry::selectAllAccessibleChildren(  )
764
0
{
765
0
    SolarMutexGuard aSolarGuard;
766
0
    ::osl::MutexGuard aGuard( m_aMutex );
767
768
0
    ensureAlive();
769
770
0
    SvTreeListEntry* pParent = m_pTreeListBox->GetEntryFromPath( m_aEntryPath );
771
0
    if ( !pParent )
772
0
        throw RuntimeException(u"AccessibleListBoxEntry::selectAllAccessibleChildren - pParent cannot be empty!"_ustr);
773
0
    sal_Int32 nCount = m_pTreeListBox->GetLevelChildCount( pParent );
774
0
    for ( sal_Int32 i = 0; i < nCount; ++i )
775
0
    {
776
0
        SvTreeListEntry* pEntry = m_pTreeListBox->GetEntry( pParent, i );
777
0
        if ( !m_pTreeListBox->IsSelected( pEntry ) )
778
0
            m_pTreeListBox->Select( pEntry );
779
0
    }
780
0
}
781
782
sal_Int64 SAL_CALL AccessibleListBoxEntry::getSelectedAccessibleChildCount(  )
783
0
{
784
0
    SolarMutexGuard aSolarGuard;
785
0
    ::osl::MutexGuard aGuard( m_aMutex );
786
787
0
    ensureAlive();
788
789
0
    sal_Int64 nSelCount = 0;
790
791
0
    SvTreeListEntry* pParent = m_pTreeListBox->GetEntryFromPath( m_aEntryPath );
792
0
    if ( !pParent )
793
0
        throw RuntimeException(u"AccessibleListBoxEntry::getSelectedAccessibleChildCount - pParent cannot be empty!"_ustr);
794
0
    sal_Int32 nCount = m_pTreeListBox->GetLevelChildCount( pParent );
795
0
    for (sal_Int32 i = 0; i < nCount; ++i )
796
0
    {
797
0
        SvTreeListEntry* pEntry = m_pTreeListBox->GetEntry( pParent, i );
798
0
        if ( m_pTreeListBox->IsSelected( pEntry ) )
799
0
            ++nSelCount;
800
0
    }
801
802
0
    return nSelCount;
803
0
}
804
805
Reference< XAccessible > SAL_CALL AccessibleListBoxEntry::getSelectedAccessibleChild( sal_Int64 nSelectedChildIndex )
806
0
{
807
0
    SolarMutexGuard aSolarGuard;
808
0
    ::osl::MutexGuard aGuard( m_aMutex );
809
810
0
    ensureAlive();
811
812
0
    if ( nSelectedChildIndex < 0 || nSelectedChildIndex >= getSelectedAccessibleChildCount() )
813
0
        throw IndexOutOfBoundsException();
814
815
0
    Reference< XAccessible > xChild;
816
0
    sal_Int64 nSelCount = 0;
817
818
0
    SvTreeListEntry* pParent = m_pTreeListBox->GetEntryFromPath( m_aEntryPath );
819
0
    if ( !pParent )
820
0
        throw RuntimeException(u"AccessibleListBoxEntry::getSelectedAccessibleChild - pParent cannot be empty!"_ustr);
821
0
    sal_Int32 nCount = m_pTreeListBox->GetLevelChildCount( pParent );
822
0
    for (sal_Int32 i = 0; i < nCount; ++i )
823
0
    {
824
0
        SvTreeListEntry* pEntry = m_pTreeListBox->GetEntry( pParent, i );
825
0
        if ( m_pTreeListBox->IsSelected( pEntry ) )
826
0
            ++nSelCount;
827
828
0
        if ( nSelCount == ( nSelectedChildIndex + 1 ) )
829
0
        {
830
0
            rtl::Reference<AccessibleListBox> xListBox(m_wListBox);
831
0
            assert(xListBox.is());
832
0
            xChild = xListBox->implGetAccessible(*pEntry).get();
833
0
            break;
834
0
        }
835
0
    }
836
837
0
    return xChild;
838
0
}
839
840
void SAL_CALL AccessibleListBoxEntry::deselectAccessibleChild( sal_Int64 nSelectedChildIndex )
841
0
{
842
0
    SolarMutexGuard aSolarGuard;
843
0
    ::osl::MutexGuard aGuard( m_aMutex );
844
845
0
    ensureAlive();
846
847
0
    if (nSelectedChildIndex < 0 || nSelectedChildIndex >= getAccessibleChildCount())
848
0
        throw IndexOutOfBoundsException();
849
850
0
    SvTreeListEntry* pParent = m_pTreeListBox->GetEntryFromPath( m_aEntryPath );
851
0
    SvTreeListEntry* pEntry = m_pTreeListBox->GetEntry( pParent, nSelectedChildIndex );
852
0
    if ( !pEntry )
853
0
        throw IndexOutOfBoundsException();
854
855
0
    m_pTreeListBox->Select( pEntry, false );
856
0
}
857
sal_Int32 SAL_CALL AccessibleListBoxEntry::getCaretPosition(  )
858
0
{
859
0
    return -1;
860
0
}
861
sal_Bool SAL_CALL AccessibleListBoxEntry::setCaretPosition ( sal_Int32 nIndex )
862
0
{
863
0
    SolarMutexGuard aSolarGuard;
864
0
    ::osl::MutexGuard aGuard( m_aMutex );
865
0
    ensureAlive();
866
867
0
    if ( !implIsValidRange( nIndex, nIndex, implGetText().getLength() ) )
868
0
        throw IndexOutOfBoundsException();
869
870
0
    return false;
871
0
}
872
sal_Unicode SAL_CALL AccessibleListBoxEntry::getCharacter( sal_Int32 nIndex )
873
0
{
874
0
    SolarMutexGuard aSolarGuard;
875
0
    ::osl::MutexGuard aGuard( m_aMutex );
876
0
    ensureAlive();
877
0
    return OCommonAccessibleText::implGetCharacter( implGetText(), nIndex );
878
0
}
879
css::uno::Sequence< css::beans::PropertyValue > SAL_CALL AccessibleListBoxEntry::getCharacterAttributes( sal_Int32 nIndex, const css::uno::Sequence< OUString >& )
880
0
{
881
0
    SolarMutexGuard aSolarGuard;
882
0
    ::osl::MutexGuard aGuard( m_aMutex );
883
0
    ensureAlive();
884
885
0
    OUString sText( implGetText() );
886
887
0
    if ( !implIsValidIndex( nIndex, sText.getLength() ) )
888
0
        throw IndexOutOfBoundsException();
889
890
0
    return css::uno::Sequence< css::beans::PropertyValue >();
891
0
}
892
sal_Int32 SAL_CALL AccessibleListBoxEntry::getCharacterCount(  )
893
0
{
894
0
    SolarMutexGuard aSolarGuard;
895
0
    ::osl::MutexGuard aGuard( m_aMutex );
896
0
    ensureAlive();
897
0
    return implGetText().getLength();
898
0
}
899
900
OUString SAL_CALL AccessibleListBoxEntry::getSelectedText(  )
901
0
{
902
0
    SolarMutexGuard aSolarGuard;
903
0
    ::osl::MutexGuard aGuard( m_aMutex );
904
0
    ensureAlive();
905
0
    return OUString();
906
0
}
907
sal_Int32 SAL_CALL AccessibleListBoxEntry::getSelectionStart(  )
908
0
{
909
0
    SolarMutexGuard aSolarGuard;
910
0
    ::osl::MutexGuard aGuard( m_aMutex );
911
0
    ensureAlive();
912
0
    return 0;
913
0
}
914
sal_Int32 SAL_CALL AccessibleListBoxEntry::getSelectionEnd(  )
915
0
{
916
0
    SolarMutexGuard aSolarGuard;
917
0
    ::osl::MutexGuard aGuard( m_aMutex );
918
0
    ensureAlive();
919
0
    return 0;
920
0
}
921
sal_Bool SAL_CALL AccessibleListBoxEntry::setSelection( sal_Int32 nStartIndex, sal_Int32 nEndIndex )
922
0
{
923
0
    SolarMutexGuard aSolarGuard;
924
0
    ::osl::MutexGuard aGuard( m_aMutex );
925
0
    ensureAlive();
926
927
0
    if ( !implIsValidRange( nStartIndex, nEndIndex, implGetText().getLength() ) )
928
0
        throw IndexOutOfBoundsException();
929
930
0
    return false;
931
0
}
932
OUString SAL_CALL AccessibleListBoxEntry::getText(  )
933
0
{
934
0
    SolarMutexGuard aSolarGuard;
935
0
    ::osl::MutexGuard aGuard( m_aMutex );
936
0
    ensureAlive();
937
0
    return implGetText(  );
938
0
}
939
OUString SAL_CALL AccessibleListBoxEntry::getTextRange( sal_Int32 nStartIndex, sal_Int32 nEndIndex )
940
0
{
941
0
    SolarMutexGuard aSolarGuard;
942
0
    ::osl::MutexGuard aGuard( m_aMutex );
943
0
    ensureAlive();
944
0
    return OCommonAccessibleText::implGetTextRange( implGetText(), nStartIndex, nEndIndex );
945
0
}
946
css::accessibility::TextSegment SAL_CALL AccessibleListBoxEntry::getTextAtIndex( sal_Int32 nIndex, sal_Int16 aTextType )
947
0
{
948
0
    SolarMutexGuard aSolarGuard;
949
0
    ::osl::MutexGuard aGuard( m_aMutex );
950
0
    ensureAlive();
951
0
    return OCommonAccessibleText::getTextAtIndex( nIndex ,aTextType);
952
0
}
953
css::accessibility::TextSegment SAL_CALL AccessibleListBoxEntry::getTextBeforeIndex( sal_Int32 nIndex, sal_Int16 aTextType )
954
0
{
955
0
    SolarMutexGuard aSolarGuard;
956
0
    ::osl::MutexGuard aGuard( m_aMutex );
957
0
    ensureAlive();
958
0
    return OCommonAccessibleText::getTextBeforeIndex( nIndex ,aTextType);
959
0
}
960
css::accessibility::TextSegment SAL_CALL AccessibleListBoxEntry::getTextBehindIndex( sal_Int32 nIndex, sal_Int16 aTextType )
961
0
{
962
0
    SolarMutexGuard aSolarGuard;
963
0
    ::osl::MutexGuard aGuard( m_aMutex );
964
0
    ensureAlive();
965
966
0
    return OCommonAccessibleText::getTextBehindIndex( nIndex ,aTextType);
967
0
}
968
969
// XAccessibleValue
970
971
972
Any AccessibleListBoxEntry::getCurrentValue(  )
973
0
{
974
0
    ::osl::MutexGuard aGuard( m_aMutex );
975
0
    Any aValue;
976
0
    sal_Int32 level = static_cast<sal_Int32>(m_aEntryPath.size()) - 1;
977
0
    level = level < 0 ?  0: level;
978
0
    aValue <<= level;
979
0
    return aValue;
980
0
}
981
982
983
sal_Bool AccessibleListBoxEntry::setCurrentValue( const Any& aNumber )
984
0
{
985
0
    ::osl::MutexGuard aGuard( m_aMutex );
986
987
988
0
    bool bReturn = false;
989
0
    SvTreeListBox* pBox = m_pTreeListBox;
990
0
    if(getAccessibleRole() == AccessibleRole::CHECK_BOX)
991
0
    {
992
0
        SvTreeListEntry* pEntry = pBox->GetEntryFromPath( m_aEntryPath );
993
0
        if ( pEntry )
994
0
        {
995
0
            sal_Int32 nValue(0), nValueMin(0), nValueMax(0);
996
0
            aNumber >>= nValue;
997
0
            getMinimumValue() >>= nValueMin;
998
0
            getMaximumValue() >>= nValueMax;
999
1000
0
            if ( nValue < nValueMin )
1001
0
                nValue = nValueMin;
1002
0
            else if ( nValue > nValueMax )
1003
0
                nValue = nValueMax;
1004
1005
0
            pBox->SetCheckButtonState(pEntry,  static_cast<SvButtonState>(nValue) );
1006
0
            bReturn = true;
1007
0
        }
1008
0
    }
1009
1010
0
    return bReturn;
1011
0
}
1012
1013
1014
Any AccessibleListBoxEntry::getMaximumValue(  )
1015
0
{
1016
0
    ::osl::MutexGuard aGuard( m_aMutex );
1017
1018
0
    Any aValue;
1019
0
    switch(getAccessibleRole())
1020
0
    {
1021
0
        case AccessibleRole::CHECK_BOX:
1022
0
            aValue <<= sal_Int32(1);
1023
0
            break;
1024
0
        case AccessibleRole::LABEL:
1025
0
        default:
1026
0
            break;
1027
0
    }
1028
1029
0
    return aValue;
1030
0
}
1031
1032
1033
Any AccessibleListBoxEntry::getMinimumValue(  )
1034
0
{
1035
0
    ::osl::MutexGuard aGuard( m_aMutex );
1036
1037
0
    Any aValue;
1038
0
    switch(getAccessibleRole())
1039
0
    {
1040
0
        case AccessibleRole::CHECK_BOX:
1041
0
            aValue <<= sal_Int32(0);
1042
0
            break;
1043
0
        case AccessibleRole::LABEL:
1044
0
        default:
1045
0
            break;
1046
0
    }
1047
1048
0
    return aValue;
1049
0
}
1050
1051
Any AccessibleListBoxEntry::getMinimumIncrement(  )
1052
0
{
1053
0
    ::osl::MutexGuard aGuard( m_aMutex );
1054
1055
0
    Any aValue;
1056
0
    switch(getAccessibleRole())
1057
0
    {
1058
0
        case AccessibleRole::CHECK_BOX:
1059
0
            aValue <<= sal_Int32(1);
1060
0
            break;
1061
0
        case AccessibleRole::LABEL:
1062
0
        default:
1063
0
            break;
1064
0
    }
1065
1066
0
    return aValue;
1067
0
}
1068
1069
SvTreeListEntry* AccessibleListBoxEntry::GetRealChild(sal_Int32 nIndex)
1070
0
{
1071
0
    SvTreeListEntry* pEntry = nullptr;
1072
0
    SvTreeListEntry* pParent = m_pTreeListBox->GetEntryFromPath( m_aEntryPath );
1073
0
    if (pParent)
1074
0
    {
1075
0
        pEntry = m_pTreeListBox->GetEntry( pParent, nIndex );
1076
0
        if ( !pEntry && getAccessibleChildCount() > 0 )
1077
0
        {
1078
0
            m_pTreeListBox->RequestingChildren(pParent);
1079
0
            pEntry = m_pTreeListBox->GetEntry( pParent, nIndex );
1080
0
        }
1081
0
    }
1082
0
    return pEntry;
1083
0
}
1084
1085
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */