Coverage Report

Created: 2026-07-10 11:04

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/vcl/source/accessibility/AccessibleBrowseBoxBase.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 <utility>
21
#include <vcl/accessibletableprovider.hxx>
22
#include <cppuhelper/supportsservice.hxx>
23
24
#include <com/sun/star/accessibility/AccessibleEventId.hpp>
25
#include <com/sun/star/accessibility/AccessibleRole.hpp>
26
#include <com/sun/star/accessibility/AccessibleStateType.hpp>
27
#include <com/sun/star/accessibility/IllegalAccessibleComponentStateException.hpp>
28
#include <com/sun/star/awt/XWindow.hpp>
29
#include <unotools/accessiblerelationsethelper.hxx>
30
#include <vcl/accessibility/AccessibleBrowseBoxBase.hxx>
31
#include <vcl/accessibility/AccessibleBrowseBoxObjType.hxx>
32
#include <vcl/unohelp.hxx>
33
#include <vcl/window.hxx>
34
#include <vcl/svapp.hxx>
35
36
37
using ::com::sun::star::uno::Reference;
38
using ::com::sun::star::uno::Sequence;
39
using ::com::sun::star::uno::Any;
40
41
using namespace ::com::sun::star;
42
using namespace ::com::sun::star::accessibility;
43
using namespace ::comphelper;
44
45
using namespace com::sun::star::accessibility::AccessibleStateType;
46
47
48
// Ctor/Dtor/disposing
49
50
AccessibleBrowseBoxBase::AccessibleBrowseBoxBase(
51
    const css::uno::Reference<css::accessibility::XAccessible>& xParent,
52
    ::vcl::IAccessibleTableProvider& rBrowseBox,
53
    const css::uno::Reference<css::awt::XWindow>& xFocusWindow, AccessibleBrowseBoxObjType eObjType)
54
0
    : AccessibleBrowseBoxBase(xParent, rBrowseBox, xFocusWindow, eObjType,
55
0
                              rBrowseBox.GetAccessibleObjectName(eObjType),
56
0
                              rBrowseBox.GetAccessibleObjectDescription(eObjType))
57
0
{
58
0
}
59
60
AccessibleBrowseBoxBase::AccessibleBrowseBoxBase(
61
        css::uno::Reference< css::accessibility::XAccessible >  rxParent,
62
        ::vcl::IAccessibleTableProvider&                      rBrowseBox,
63
        css::uno::Reference< css::awt::XWindow >  _xFocusWindow,
64
        AccessibleBrowseBoxObjType      eObjType,
65
        OUString           rName,
66
        OUString           rDescription ) :
67
0
    ImplInheritanceHelper(),
68
0
    mxParent(std::move( rxParent )),
69
0
    mpBrowseBox( &rBrowseBox ),
70
0
    m_xFocusWindow(std::move(_xFocusWindow)),
71
0
    maName(std::move( rName )),
72
0
    maDescription(std::move( rDescription )),
73
0
    meObjType( eObjType )
74
0
{
75
0
    if ( m_xFocusWindow.is() )
76
0
        m_xFocusWindow->addFocusListener( this );
77
0
}
78
79
void SAL_CALL AccessibleBrowseBoxBase::disposing()
80
0
{
81
0
    ::osl::MutexGuard aGuard( getMutex() );
82
0
    if ( m_xFocusWindow.is() )
83
0
    {
84
0
        SolarMutexGuard aSolarGuard;
85
0
        m_xFocusWindow->removeFocusListener( this );
86
0
    }
87
88
0
    OAccessible::disposing();
89
90
0
    mxParent = nullptr;
91
0
    mpBrowseBox = nullptr;
92
0
}
93
94
css::awt::Rectangle AccessibleBrowseBoxBase::implGetBounds()
95
0
{
96
0
    return vcl::unohelper::ConvertToAWTRect(implGetBoundingBox());
97
0
}
98
99
// css::accessibility::XAccessibleContext
100
101
Reference< css::accessibility::XAccessible > SAL_CALL AccessibleBrowseBoxBase::getAccessibleParent()
102
0
{
103
0
    ::osl::MutexGuard aGuard( getMutex() );
104
0
    ensureIsAlive();
105
0
    return mxParent;
106
0
}
107
108
OUString SAL_CALL AccessibleBrowseBoxBase::getAccessibleDescription()
109
0
{
110
0
    ::osl::MutexGuard aGuard( getMutex() );
111
0
    ensureIsAlive();
112
0
    return maDescription;
113
0
}
114
115
OUString SAL_CALL AccessibleBrowseBoxBase::getAccessibleName()
116
0
{
117
0
    ::osl::MutexGuard aGuard( getMutex() );
118
0
    ensureIsAlive();
119
0
    return maName;
120
0
}
121
122
Reference< css::accessibility::XAccessibleRelationSet > SAL_CALL
123
AccessibleBrowseBoxBase::getAccessibleRelationSet()
124
0
{
125
0
    ::osl::MutexGuard aGuard( getMutex() );
126
0
    ensureIsAlive();
127
    // BrowseBox does not have relations.
128
0
    return new utl::AccessibleRelationSetHelper;
129
0
}
130
131
sal_Int64 SAL_CALL
132
AccessibleBrowseBoxBase::getAccessibleStateSet()
133
0
{
134
0
    SolarMethodGuard aGuard( getMutex() );
135
    // don't check whether alive -> StateSet may contain DEFUNC
136
0
    return implCreateStateSet();
137
0
}
138
139
lang::Locale SAL_CALL AccessibleBrowseBoxBase::getLocale()
140
0
{
141
0
    ::osl::MutexGuard aGuard( getMutex() );
142
0
    ensureIsAlive();
143
0
    if( mxParent.is() )
144
0
    {
145
0
        css::uno::Reference< css::accessibility::XAccessibleContext >
146
0
            xParentContext( mxParent->getAccessibleContext() );
147
0
        if( xParentContext.is() )
148
0
            return xParentContext->getLocale();
149
0
    }
150
0
    throw IllegalAccessibleComponentStateException();
151
0
}
152
153
// css::accessibility::XAccessibleComponent
154
155
void SAL_CALL AccessibleBrowseBoxBase::focusGained( const css::awt::FocusEvent& )
156
0
{
157
0
    css::uno::Any aFocused;
158
0
    css::uno::Any aEmpty;
159
0
    aFocused <<= FOCUSED;
160
161
0
    commitEvent(AccessibleEventId::STATE_CHANGED,aFocused,aEmpty);
162
0
}
163
164
165
void SAL_CALL AccessibleBrowseBoxBase::focusLost( const css::awt::FocusEvent& )
166
0
{
167
0
    css::uno::Any aFocused;
168
0
    css::uno::Any aEmpty;
169
0
    aFocused <<= FOCUSED;
170
171
0
    commitEvent(AccessibleEventId::STATE_CHANGED,aEmpty,aFocused);
172
0
}
173
174
// XServiceInfo
175
176
sal_Bool SAL_CALL AccessibleBrowseBoxBase::supportsService(
177
        const OUString& rServiceName )
178
0
{
179
0
    return cppu::supportsService(this, rServiceName);
180
0
}
181
182
Sequence< OUString > SAL_CALL AccessibleBrowseBoxBase::getSupportedServiceNames()
183
0
{
184
0
    return { u"com.sun.star.accessibility.AccessibleContext"_ustr };
185
0
}
186
187
// other public methods
188
189
void AccessibleBrowseBoxBase::setAccessibleName( const OUString& rName )
190
0
{
191
0
    ::osl::ClearableMutexGuard aGuard( getMutex() );
192
0
    Any aOld;
193
0
    aOld <<= maName;
194
0
    maName = rName;
195
196
0
    aGuard.clear();
197
198
0
    commitEvent(
199
0
        AccessibleEventId::NAME_CHANGED,
200
0
        uno::Any( maName ),
201
0
        aOld );
202
0
}
203
204
void AccessibleBrowseBoxBase::setAccessibleDescription( const OUString& rDescription )
205
0
{
206
0
    ::osl::ClearableMutexGuard aGuard( getMutex() );
207
0
    Any aOld;
208
0
    aOld <<= maDescription;
209
0
    maDescription = rDescription;
210
211
0
    aGuard.clear();
212
213
0
    commitEvent(
214
0
        AccessibleEventId::DESCRIPTION_CHANGED,
215
0
        uno::Any( maDescription ),
216
0
        aOld );
217
0
}
218
219
// internal virtual methods
220
221
bool AccessibleBrowseBoxBase::implIsShowing()
222
0
{
223
0
    bool bShowing = false;
224
0
    if( mxParent.is() )
225
0
    {
226
0
        css::uno::Reference< css::accessibility::XAccessibleComponent >
227
0
            xParentComp( mxParent->getAccessibleContext(), uno::UNO_QUERY );
228
0
        if( xParentComp.is() )
229
0
            bShowing = implGetBoundingBox().Overlaps(
230
0
                vcl::unohelper::ConvertToVCLRect(xParentComp->getBounds()));
231
0
    }
232
0
    return bShowing;
233
0
}
234
235
sal_Int64 AccessibleBrowseBoxBase::implCreateStateSet()
236
0
{
237
0
    sal_Int64 nStateSet = 0;
238
239
0
    if( isAlive() )
240
0
    {
241
        // SHOWING done with mxParent
242
0
        if( implIsShowing() )
243
0
            nStateSet |= AccessibleStateType::SHOWING;
244
        // BrowseBox fills StateSet with states depending on object type
245
0
        mpBrowseBox->FillAccessibleStateSet( nStateSet, getType() );
246
0
    }
247
0
    else
248
0
        nStateSet |= AccessibleStateType::DEFUNC;
249
250
0
    return nStateSet;
251
0
}
252
253
// internal helper methods
254
255
bool AccessibleBrowseBoxBase::isAlive() const
256
0
{
257
0
    return OAccessible::isAlive() && mpBrowseBox;
258
0
}
259
260
void AccessibleBrowseBoxBase::ensureIsAlive() const
261
0
{
262
0
    if( !isAlive() )
263
0
        throw lang::DisposedException();
264
0
}
265
266
void AccessibleBrowseBoxBase::commitEvent(
267
        sal_Int16 _nEventId, const Any& _rNewValue, const Any& _rOldValue )
268
0
{
269
0
    NotifyAccessibleEvent(_nEventId, _rOldValue, _rNewValue);
270
0
}
271
272
sal_Int16 SAL_CALL AccessibleBrowseBoxBase::getAccessibleRole()
273
0
{
274
0
    osl::MutexGuard aGuard( getMutex() );
275
0
    ensureIsAlive();
276
0
    sal_Int16 nRole = AccessibleRole::UNKNOWN;
277
0
    switch ( meObjType )
278
0
    {
279
0
        case AccessibleBrowseBoxObjType::RowHeaderCell:
280
0
            nRole = AccessibleRole::ROW_HEADER;
281
0
            break;
282
0
        case AccessibleBrowseBoxObjType::ColumnHeaderCell:
283
0
            nRole = AccessibleRole::COLUMN_HEADER;
284
0
            break;
285
0
        case AccessibleBrowseBoxObjType::ColumnHeaderBar:
286
0
        case AccessibleBrowseBoxObjType::RowHeaderBar:
287
0
        case AccessibleBrowseBoxObjType::Table:
288
0
            nRole = AccessibleRole::TABLE;
289
0
            break;
290
0
        case AccessibleBrowseBoxObjType::TableCell:
291
0
            nRole = AccessibleRole::TABLE_CELL;
292
0
            break;
293
0
        case AccessibleBrowseBoxObjType::BrowseBox:
294
0
            nRole = AccessibleRole::PANEL;
295
0
            break;
296
0
        case AccessibleBrowseBoxObjType::CheckBoxCell:
297
0
            nRole = AccessibleRole::CHECK_BOX;
298
0
            break;
299
0
    }
300
0
    return nRole;
301
0
}
302
303
Reference<XAccessible > SAL_CALL AccessibleBrowseBoxBase::getAccessibleAtPoint( const css::awt::Point& )
304
0
{
305
0
    return nullptr;
306
0
}
307
308
void SAL_CALL AccessibleBrowseBoxBase::disposing( const css::lang::EventObject& )
309
0
{
310
0
    m_xFocusWindow = nullptr;
311
0
}
312
313
sal_Int32 SAL_CALL AccessibleBrowseBoxBase::getForeground(  )
314
0
{
315
0
    SolarMethodGuard aGuard(getMutex());
316
0
    ensureIsAlive();
317
318
0
    Color nColor;
319
0
    vcl::Window* pInst = mpBrowseBox->GetWindowInstance();
320
0
    if ( pInst )
321
0
    {
322
0
        if ( pInst->IsControlForeground() )
323
0
            nColor = pInst->GetControlForeground();
324
0
        else
325
0
        {
326
0
            vcl::Font aFont;
327
0
            if ( pInst->IsControlFont() )
328
0
                aFont = pInst->GetControlFont();
329
0
            else
330
0
                aFont = pInst->GetFont();
331
0
            nColor = aFont.GetColor();
332
0
        }
333
0
    }
334
335
0
    return sal_Int32(nColor);
336
0
}
337
338
sal_Int32 SAL_CALL AccessibleBrowseBoxBase::getBackground(  )
339
0
{
340
0
    SolarMethodGuard aGuard(getMutex());
341
0
    ensureIsAlive();
342
343
0
    Color nColor;
344
0
    vcl::Window* pInst = mpBrowseBox->GetWindowInstance();
345
0
    if ( pInst )
346
0
    {
347
0
        if ( pInst->IsControlBackground() )
348
0
            nColor = pInst->GetControlBackground();
349
0
        else
350
0
            nColor = pInst->GetBackground().GetColor();
351
0
    }
352
353
0
    return sal_Int32(nColor);
354
0
}
355
356
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */