Coverage Report

Created: 2025-07-07 10:01

/src/libreoffice/vcl/source/accessibility/AccessibleBrowseBox.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 <com/sun/star/awt/XVclWindowPeer.hdl>
21
#include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
22
#include <vcl/accessibility/AccessibleBrowseBox.hxx>
23
#include <vcl/accessibility/AccessibleBrowseBoxHeaderBar.hxx>
24
#include <vcl/accessibility/AccessibleBrowseBoxTable.hxx>
25
#include <vcl/accessibletableprovider.hxx>
26
#include <vcl/unohelp.hxx>
27
#include <sal/types.h>
28
29
30
using namespace ::com::sun::star::uno;
31
using namespace ::com::sun::star;
32
using namespace ::com::sun::star::lang;
33
using namespace ::com::sun::star::accessibility;
34
35
// Ctor/Dtor/disposing
36
37
AccessibleBrowseBox::AccessibleBrowseBox(
38
    const css::uno::Reference<css::accessibility::XAccessible>& _rxParent,
39
    ::vcl::IAccessibleTableProvider& _rBrowseBox)
40
0
    : AccessibleBrowseBoxBase(_rxParent, _rBrowseBox, nullptr,
41
0
                              AccessibleBrowseBoxObjType::BrowseBox)
42
0
{
43
0
    m_xFocusWindow.set(mpBrowseBox->GetWindowInstance()->GetComponentInterface(), css::uno::UNO_QUERY);
44
0
}
45
46
AccessibleBrowseBox::~AccessibleBrowseBox()
47
0
{
48
0
}
49
50
51
void SAL_CALL AccessibleBrowseBox::disposing()
52
0
{
53
0
    ::osl::MutexGuard aGuard( getMutex() );
54
55
0
    if ( mxTable.is() )
56
0
    {
57
0
        mxTable->dispose();
58
0
        mxTable.clear();
59
0
    }
60
0
    if ( mxRowHeaderBar.is() )
61
0
    {
62
0
        mxRowHeaderBar->dispose();
63
0
        mxRowHeaderBar.clear();
64
0
    }
65
0
    if ( mxColumnHeaderBar.is() )
66
0
    {
67
0
        mxColumnHeaderBar->dispose();
68
0
        mxColumnHeaderBar.clear();
69
0
    }
70
71
0
    AccessibleBrowseBoxBase::disposing();
72
0
}
73
74
// css::accessibility::XAccessibleContext
75
76
sal_Int64 SAL_CALL AccessibleBrowseBox::getAccessibleChildCount()
77
0
{
78
0
    SolarMethodGuard aGuard(getMutex());
79
0
    ensureIsAlive();
80
81
0
    return vcl::BBINDEX_FIRSTCONTROL + mpBrowseBox->GetAccessibleControlCount();
82
0
}
83
84
85
css::uno::Reference< css::accessibility::XAccessible > SAL_CALL
86
AccessibleBrowseBox::getAccessibleChild( sal_Int64 nChildIndex )
87
0
{
88
0
    SolarMethodGuard aGuard(getMutex());
89
0
    ensureIsAlive();
90
91
0
    if (nChildIndex < 0 || nChildIndex >= getAccessibleChildCount())
92
0
        throw lang::IndexOutOfBoundsException();
93
94
0
    css::uno::Reference< css::accessibility::XAccessible > xRet;
95
0
    if (nChildIndex < vcl::BBINDEX_FIRSTCONTROL)
96
0
        xRet = implGetFixedChild(nChildIndex);
97
0
    else
98
0
    {
99
        // additional controls
100
0
        nChildIndex -= vcl::BBINDEX_FIRSTCONTROL;
101
0
        if (nChildIndex < mpBrowseBox->GetAccessibleControlCount())
102
0
            xRet = mpBrowseBox->CreateAccessibleControl(nChildIndex);
103
0
    }
104
105
0
    if( !xRet.is() )
106
0
        throw lang::IndexOutOfBoundsException();
107
0
    return xRet;
108
0
}
109
110
// css::accessibility::XAccessibleComponent
111
112
css::uno::Reference< css::accessibility::XAccessible > SAL_CALL
113
AccessibleBrowseBox::getAccessibleAtPoint( const awt::Point& rPoint )
114
0
{
115
0
    SolarMethodGuard aGuard(getMutex());
116
0
    ensureIsAlive();
117
118
0
    sal_Int32 nIndex = 0;
119
0
    if (mpBrowseBox->ConvertPointToControlIndex(nIndex, vcl::unohelper::ConvertToVCLPoint(rPoint)))
120
0
        return mpBrowseBox->CreateAccessibleControl(nIndex);
121
122
    // try whether point is in one of the fixed children
123
    // (table, header bars, corner control)
124
0
    Point aPoint(vcl::unohelper::ConvertToVCLPoint(rPoint));
125
0
    for (nIndex = 0; nIndex < vcl::BBINDEX_FIRSTCONTROL; ++nIndex)
126
0
    {
127
0
        css::uno::Reference< css::accessibility::XAccessible > xCurrChild(implGetFixedChild(nIndex));
128
0
        css::uno::Reference< css::accessibility::XAccessibleComponent >
129
0
            xCurrChildComp( xCurrChild, uno::UNO_QUERY );
130
131
0
        if (xCurrChildComp.is()
132
0
            && vcl::unohelper::ConvertToVCLRect(xCurrChildComp->getBounds()).Contains(aPoint))
133
0
            return xCurrChild;
134
0
    }
135
0
    return nullptr;
136
0
}
137
138
139
void SAL_CALL AccessibleBrowseBox::grabFocus()
140
0
{
141
0
    SolarMethodGuard aGuard(getMutex());
142
0
    ensureIsAlive();
143
144
0
    mpBrowseBox->GrabFocus();
145
0
}
146
147
// XServiceInfo
148
OUString SAL_CALL AccessibleBrowseBox::getImplementationName()
149
0
{
150
0
    return u"com.sun.star.comp.svtools.AccessibleBrowseBox"_ustr;
151
0
}
152
153
// internal virtual methods
154
tools::Rectangle AccessibleBrowseBox::implGetBoundingBox()
155
0
{
156
0
    vcl::Window* pParent = mpBrowseBox->GetAccessibleParentWindow();
157
0
    assert(pParent && "implGetBoundingBox - missing parent window");
158
0
    return mpBrowseBox->GetWindowExtentsRelative( *pParent );
159
0
}
160
161
// internal helper methods
162
css::uno::Reference< css::accessibility::XAccessible > AccessibleBrowseBox::implGetTable()
163
0
{
164
0
    if( !mxTable.is() )
165
0
    {
166
0
        mxTable = createAccessibleTable();
167
168
0
    }
169
0
    return mxTable;
170
0
}
171
172
css::uno::Reference< css::accessibility::XAccessible >
173
AccessibleBrowseBox::implGetHeaderBar(AccessibleBrowseBoxObjType eObjType)
174
0
{
175
0
    if( eObjType == AccessibleBrowseBoxObjType::RowHeaderBar )
176
0
    {
177
0
        if (!mxRowHeaderBar.is())
178
0
            mxRowHeaderBar = new AccessibleBrowseBoxHeaderBar(this, *mpBrowseBox, eObjType);
179
0
        return mxRowHeaderBar;
180
0
    }
181
0
    else if( eObjType == AccessibleBrowseBoxObjType::ColumnHeaderBar )
182
0
    {
183
0
        if (!mxColumnHeaderBar.is())
184
0
            mxColumnHeaderBar = new AccessibleBrowseBoxHeaderBar(this, *mpBrowseBox, eObjType);
185
0
        return mxColumnHeaderBar;
186
0
    }
187
188
0
    return css::uno::Reference<css::accessibility::XAccessible>();
189
0
}
190
191
css::uno::Reference< css::accessibility::XAccessible >
192
AccessibleBrowseBox::implGetFixedChild( sal_Int64 nChildIndex )
193
0
{
194
0
    css::uno::Reference< css::accessibility::XAccessible > xRet;
195
0
    switch( nChildIndex )
196
0
    {
197
0
        case vcl::BBINDEX_COLUMNHEADERBAR:
198
0
            xRet = implGetHeaderBar( AccessibleBrowseBoxObjType::ColumnHeaderBar );
199
0
        break;
200
0
        case vcl::BBINDEX_ROWHEADERBAR:
201
0
            xRet = implGetHeaderBar( AccessibleBrowseBoxObjType::RowHeaderBar );
202
0
        break;
203
0
        case vcl::BBINDEX_TABLE:
204
0
            xRet = implGetTable();
205
0
        break;
206
0
    }
207
0
    return xRet;
208
0
}
209
210
rtl::Reference<AccessibleBrowseBoxTable> AccessibleBrowseBox::createAccessibleTable()
211
0
{
212
0
    return new AccessibleBrowseBoxTable(this, *mpBrowseBox);
213
0
}
214
215
void AccessibleBrowseBox::commitTableEvent(sal_Int16 _nEventId,const Any& _rNewValue,const Any& _rOldValue)
216
0
{
217
0
    if ( mxTable.is() )
218
0
    {
219
0
        mxTable->commitEvent(_nEventId,_rNewValue,_rOldValue);
220
0
    }
221
0
}
222
223
void AccessibleBrowseBox::commitHeaderBarEvent( sal_Int16 _nEventId,
224
                                                const Any& _rNewValue,
225
                                                const Any& _rOldValue,bool _bColumnHeaderBar)
226
0
{
227
0
    rtl::Reference< AccessibleBrowseBoxHeaderBar >& xHeaderBar = _bColumnHeaderBar ? mxColumnHeaderBar : mxRowHeaderBar;
228
0
    if ( xHeaderBar.is() )
229
0
        xHeaderBar->commitEvent(_nEventId,_rNewValue,_rOldValue);
230
0
}
231
232
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */