Coverage Report

Created: 2026-10-14 09:33

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/sc/source/ui/Accessibility/AccessibleTableBase.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 <AccessibleTableBase.hxx>
21
#include <document.hxx>
22
#include <scresid.hxx>
23
#include <strings.hrc>
24
#include <strings.hxx>
25
#include <table.hxx>
26
27
#include <com/sun/star/accessibility/AccessibleRole.hpp>
28
#include <com/sun/star/accessibility/AccessibleTableModelChange.hpp>
29
#include <com/sun/star/accessibility/AccessibleEventId.hpp>
30
#include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
31
#include <comphelper/sequence.hxx>
32
#include <vcl/svapp.hxx>
33
34
using namespace ::com::sun::star;
35
using namespace ::com::sun::star::accessibility;
36
37
ScAccessibleTableBase::ScAccessibleTableBase(
38
    const rtl::Reference<comphelper::OAccessible>& rpParent, ScDocument* pDoc,
39
    const ScRange& rRange)
40
0
    : ImplInheritanceHelper(rpParent, AccessibleRole::TABLE)
41
0
    , maRange(rRange)
42
0
    , mpDoc(pDoc)
43
0
{
44
0
}
45
46
ScAccessibleTableBase::~ScAccessibleTableBase()
47
0
{
48
0
}
49
50
void SAL_CALL ScAccessibleTableBase::disposing()
51
0
{
52
0
    SolarMutexGuard aGuard;
53
0
    mpDoc = nullptr;
54
55
0
    ScAccessibleContextBase::disposing();
56
0
}
57
58
    //=====  XAccessibleTable  ================================================
59
60
sal_Int32 SAL_CALL ScAccessibleTableBase::getAccessibleRowCount(  )
61
0
{
62
0
    SolarMutexGuard aGuard;
63
0
    ensureAlive();
64
0
    return maRange.aEnd.Row() - maRange.aStart.Row() + 1;
65
0
}
66
67
sal_Int32 SAL_CALL ScAccessibleTableBase::getAccessibleColumnCount(  )
68
0
{
69
0
    SolarMutexGuard aGuard;
70
0
    ensureAlive();
71
0
    return maRange.aEnd.Col() - maRange.aStart.Col() + 1;
72
0
}
73
74
OUString SAL_CALL ScAccessibleTableBase::getAccessibleRowDescription( sal_Int32 nRow )
75
0
{
76
0
    OSL_FAIL("Here should be an implementation to fill the description");
77
78
0
    if ((nRow > (maRange.aEnd.Row() - maRange.aStart.Row())) || (nRow < 0))
79
0
        throw lang::IndexOutOfBoundsException();
80
81
    //setAccessibleRowDescription(nRow, xAccessible); // to remember the created Description
82
0
    return OUString();
83
0
}
84
85
OUString SAL_CALL ScAccessibleTableBase::getAccessibleColumnDescription( sal_Int32 nColumn )
86
0
{
87
0
    OSL_FAIL("Here should be an implementation to fill the description");
88
89
0
    if ((nColumn > (maRange.aEnd.Col() - maRange.aStart.Col())) || (nColumn < 0))
90
0
        throw lang::IndexOutOfBoundsException();
91
92
    //setAccessibleColumnDescription(nColumn, xAccessible); // to remember the created Description
93
0
    return OUString();
94
0
}
95
96
sal_Int32 SAL_CALL ScAccessibleTableBase::getAccessibleRowExtentAt( sal_Int32 nRow, sal_Int32 nColumn )
97
0
{
98
0
    SolarMutexGuard aGuard;
99
0
    ensureAlive();
100
101
0
    if ((nColumn > (maRange.aEnd.Col() - maRange.aStart.Col())) || (nColumn < 0) ||
102
0
        (nRow > (maRange.aEnd.Row() - maRange.aStart.Row())) || (nRow < 0))
103
0
        throw lang::IndexOutOfBoundsException();
104
105
0
    sal_Int32 nCount(1); // the same cell
106
0
    nRow += maRange.aStart.Row();
107
0
    nColumn += maRange.aStart.Col();
108
109
0
    if (mpDoc)
110
0
    {
111
0
        ScTable* pTab = mpDoc->FetchTable(maRange.aStart.Tab());
112
0
        if (pTab)
113
0
        {
114
0
            SCROW nStartRow = static_cast<SCROW>(nRow);
115
0
            SCROW nEndRow   = nStartRow;
116
0
            SCCOL nStartCol = static_cast<SCCOL>(nColumn);
117
0
            SCCOL nEndCol   = nStartCol;
118
0
            if (pTab->ExtendMerge( nStartCol, nStartRow, nEndCol, nEndRow, false))
119
0
            {
120
0
                if (nEndRow > nStartRow)
121
0
                    nCount = nEndRow - nStartRow + 1;
122
0
            }
123
0
        }
124
0
    }
125
126
0
    return nCount;
127
0
}
128
129
sal_Int32 SAL_CALL ScAccessibleTableBase::getAccessibleColumnExtentAt( sal_Int32 nRow, sal_Int32 nColumn )
130
0
{
131
0
    SolarMutexGuard aGuard;
132
0
    ensureAlive();
133
134
0
    if ((nColumn > (maRange.aEnd.Col() - maRange.aStart.Col())) || (nColumn < 0) ||
135
0
        (nRow > (maRange.aEnd.Row() - maRange.aStart.Row())) || (nRow < 0))
136
0
        throw lang::IndexOutOfBoundsException();
137
138
0
    sal_Int32 nCount(1); // the same cell
139
0
    nRow += maRange.aStart.Row();
140
0
    nColumn += maRange.aStart.Col();
141
142
0
    if (mpDoc)
143
0
    {
144
0
        ScTable* pTab = mpDoc->FetchTable(maRange.aStart.Tab());
145
0
        if (pTab)
146
0
        {
147
0
            SCROW nStartRow = static_cast<SCROW>(nRow);
148
0
            SCROW nEndRow   = nStartRow;
149
0
            SCCOL nStartCol = static_cast<SCCOL>(nColumn);
150
0
            SCCOL nEndCol   = nStartCol;
151
0
            if (pTab->ExtendMerge( nStartCol, nStartRow, nEndCol, nEndRow, false))
152
0
            {
153
0
                if (nEndCol > nStartCol)
154
0
                    nCount = nEndCol - nStartCol + 1;
155
0
            }
156
0
        }
157
0
    }
158
159
0
    return nCount;
160
0
}
161
162
uno::Reference< XAccessibleTable > SAL_CALL ScAccessibleTableBase::getAccessibleRowHeaders(  )
163
0
{
164
0
    uno::Reference< XAccessibleTable > xAccessibleTable;
165
0
    OSL_FAIL("Here should be an implementation to fill the row headers");
166
167
    //CommitChange
168
0
    return xAccessibleTable;
169
0
}
170
171
uno::Reference< XAccessibleTable > SAL_CALL ScAccessibleTableBase::getAccessibleColumnHeaders(  )
172
0
{
173
0
    uno::Reference< XAccessibleTable > xAccessibleTable;
174
0
    OSL_FAIL("Here should be an implementation to fill the column headers");
175
176
    //CommitChange
177
0
    return xAccessibleTable;
178
0
}
179
180
uno::Sequence< sal_Int32 > SAL_CALL ScAccessibleTableBase::getSelectedAccessibleRows(  )
181
0
{
182
0
    OSL_FAIL("not implemented yet");
183
0
    uno::Sequence< sal_Int32 > aSequence;
184
0
    return aSequence;
185
0
}
186
187
uno::Sequence< sal_Int32 > SAL_CALL ScAccessibleTableBase::getSelectedAccessibleColumns(  )
188
0
{
189
0
    OSL_FAIL("not implemented yet");
190
0
    uno::Sequence< sal_Int32 > aSequence;
191
0
    return aSequence;
192
0
}
193
194
sal_Bool SAL_CALL ScAccessibleTableBase::isAccessibleRowSelected( sal_Int32 /* nRow */ )
195
0
{
196
0
    OSL_FAIL("not implemented yet");
197
0
    return false;
198
0
}
199
200
sal_Bool SAL_CALL ScAccessibleTableBase::isAccessibleColumnSelected( sal_Int32 /* nColumn */ )
201
0
{
202
0
    OSL_FAIL("not implemented yet");
203
0
    return false;
204
0
}
205
206
uno::Reference< XAccessible > SAL_CALL ScAccessibleTableBase::getAccessibleCellAt( sal_Int32 /* nRow */, sal_Int32 /* nColumn */ )
207
0
{
208
0
    OSL_FAIL("not implemented yet");
209
0
    return {};
210
0
}
211
212
uno::Reference< XAccessible > SAL_CALL ScAccessibleTableBase::getAccessibleCaption(  )
213
0
{
214
0
    OSL_FAIL("not implemented yet");
215
0
    return {};
216
0
}
217
218
uno::Reference< XAccessible > SAL_CALL ScAccessibleTableBase::getAccessibleSummary(  )
219
0
{
220
0
    OSL_FAIL("not implemented yet");
221
0
    return {};
222
0
}
223
224
sal_Bool SAL_CALL ScAccessibleTableBase::isAccessibleSelected( sal_Int32 /* nRow */, sal_Int32 /* nColumn */ )
225
0
{
226
0
    OSL_FAIL("not implemented yet");
227
0
    return false;
228
0
}
229
230
// =====  XAccessibleExtendedTable  ========================================
231
232
sal_Int64 SAL_CALL ScAccessibleTableBase::getAccessibleIndex( sal_Int32 nRow, sal_Int32 nColumn )
233
0
{
234
0
    SolarMutexGuard aGuard;
235
0
    ensureAlive();
236
237
0
    if (nRow > (maRange.aEnd.Row() - maRange.aStart.Row()) ||
238
0
        nRow < 0 ||
239
0
        nColumn > (maRange.aEnd.Col() - maRange.aStart.Col()) ||
240
0
        nColumn < 0)
241
0
        throw lang::IndexOutOfBoundsException();
242
243
0
    nRow -= maRange.aStart.Row();
244
0
    nColumn -= maRange.aStart.Col();
245
0
    return (static_cast<sal_Int64>(nRow) * static_cast<sal_Int64>(maRange.aEnd.Col() + 1)) + nColumn;
246
0
}
247
248
sal_Int32 SAL_CALL ScAccessibleTableBase::getAccessibleRow( sal_Int64 nChildIndex )
249
0
{
250
0
    SolarMutexGuard aGuard;
251
0
    ensureAlive();
252
253
0
    if (nChildIndex >= getAccessibleChildCount() || nChildIndex < 0)
254
0
        throw lang::IndexOutOfBoundsException();
255
256
0
    return nChildIndex / (maRange.aEnd.Col() - maRange.aStart.Col() + 1);
257
0
}
258
259
sal_Int32 SAL_CALL ScAccessibleTableBase::getAccessibleColumn( sal_Int64 nChildIndex )
260
0
{
261
0
    SolarMutexGuard aGuard;
262
0
    ensureAlive();
263
264
0
    if (nChildIndex >= getAccessibleChildCount() || nChildIndex < 0)
265
0
        throw lang::IndexOutOfBoundsException();
266
267
0
    return nChildIndex % static_cast<sal_Int32>(maRange.aEnd.Col() - maRange.aStart.Col() + 1);
268
0
}
269
270
// =====  XAccessibleContext  ==============================================
271
272
sal_Int64 SAL_CALL ScAccessibleTableBase::getAccessibleChildCount()
273
0
{
274
0
    SolarMutexGuard aGuard;
275
0
    ensureAlive();
276
277
    // FIXME: representing rows & columns this way is a plain and simple madness.
278
    // this needs a radical re-think.
279
0
    sal_Int64 nMax = static_cast<sal_Int64>(maRange.aEnd.Row() - maRange.aStart.Row() + 1) *
280
0
                     static_cast<sal_Int64>(maRange.aEnd.Col() - maRange.aStart.Col() + 1);
281
0
    if (nMax < 0)
282
0
        return 0;
283
0
    return nMax;
284
0
}
285
286
uno::Reference< XAccessible > SAL_CALL
287
    ScAccessibleTableBase::getAccessibleChild(sal_Int64 nIndex)
288
0
{
289
0
    SolarMutexGuard aGuard;
290
0
    ensureAlive();
291
292
0
    if (nIndex >= getAccessibleChildCount() || nIndex < 0)
293
0
        throw lang::IndexOutOfBoundsException();
294
295
    // FIXME: representing rows & columns this way is a plain and simple madness.
296
    // this needs a radical re-think.
297
298
0
    sal_Int32 nRow(0);
299
0
    sal_Int32 nColumn(0);
300
0
    sal_Int32 nTemp(maRange.aEnd.Col() - maRange.aStart.Col() + 1);
301
0
    nRow = nIndex / nTemp;
302
0
    nColumn = nIndex % nTemp;
303
0
    return getAccessibleCellAt(nRow, nColumn);
304
0
}
305
306
OUString
307
    ScAccessibleTableBase::createAccessibleDescription()
308
0
{
309
0
    return STR_ACC_TABLE_DESCR;
310
0
}
311
312
OUString ScAccessibleTableBase::createAccessibleName()
313
0
{
314
0
    OUString sName(ScResId(STR_ACC_TABLE_NAME));
315
0
    OUString sCoreName;
316
0
    if (mpDoc && mpDoc->GetName( maRange.aStart.Tab(), sCoreName ))
317
0
        sName = sName.replaceFirst("%1", sCoreName);
318
0
    return sName;
319
0
}
320
321
uno::Reference<XAccessibleRelationSet> SAL_CALL
322
    ScAccessibleTableBase::getAccessibleRelationSet()
323
0
{
324
0
    OSL_FAIL("should be implemented in the abbreviated class");
325
0
    return uno::Reference<XAccessibleRelationSet>();
326
0
}
327
328
sal_Int64 SAL_CALL ScAccessibleTableBase::getAccessibleStateSet()
329
0
{
330
0
    OSL_FAIL("should be implemented in the abbreviated class");
331
0
    return 0;
332
0
}
333
334
    ///=====  XAccessibleSelection  ===========================================
335
336
void SAL_CALL ScAccessibleTableBase::selectAccessibleChild( sal_Int64 /* nChildIndex */ )
337
0
{
338
0
}
339
340
sal_Bool SAL_CALL
341
        ScAccessibleTableBase::isAccessibleChildSelected( sal_Int64 nChildIndex )
342
0
{
343
    // I don't need to guard, because the called functions have a guard
344
0
    if (nChildIndex < 0 || nChildIndex >= getAccessibleChildCount())
345
0
        throw lang::IndexOutOfBoundsException();
346
0
    return isAccessibleSelected(getAccessibleRow(nChildIndex), getAccessibleColumn(nChildIndex));
347
0
}
348
349
void SAL_CALL
350
        ScAccessibleTableBase::clearAccessibleSelection(  )
351
0
{
352
0
}
353
354
void SAL_CALL ScAccessibleTableBase::selectAllAccessibleChildren()
355
0
{
356
0
}
357
358
sal_Int64 SAL_CALL
359
        ScAccessibleTableBase::getSelectedAccessibleChildCount(  )
360
0
{
361
0
    return 0;
362
0
}
363
364
uno::Reference<XAccessible > SAL_CALL
365
        ScAccessibleTableBase::getSelectedAccessibleChild( sal_Int64 /* nSelectedChildIndex */ )
366
0
{
367
0
    uno::Reference < XAccessible > xAccessible;
368
0
    return xAccessible;
369
0
}
370
371
void SAL_CALL ScAccessibleTableBase::deselectAccessibleChild( sal_Int64 /* nSelectedChildIndex */ )
372
0
{
373
0
}
374
375
void ScAccessibleTableBase::CommitTableModelChange(sal_Int32 nStartRow, sal_Int32 nStartCol, sal_Int32 nEndRow, sal_Int32 nEndCol, sal_uInt16 nId)
376
0
{
377
0
    AccessibleTableModelChange aModelChange;
378
0
    aModelChange.FirstRow = nStartRow;
379
0
    aModelChange.FirstColumn = nStartCol;
380
0
    aModelChange.LastRow = nEndRow;
381
0
    aModelChange.LastColumn = nEndCol;
382
0
    aModelChange.Type = nId;
383
384
0
    CommitChange(AccessibleEventId::TABLE_MODEL_CHANGED, uno::Any(), uno::Any(aModelChange));
385
0
}
386
387
sal_Bool SAL_CALL ScAccessibleTableBase::selectRow( sal_Int32 )
388
0
{
389
0
    return true;
390
0
}
391
392
sal_Bool SAL_CALL ScAccessibleTableBase::selectColumn( sal_Int32 )
393
0
{
394
0
    return true;
395
0
}
396
397
sal_Bool SAL_CALL ScAccessibleTableBase::unselectRow( sal_Int32 )
398
0
{
399
0
        return true;
400
0
}
401
402
sal_Bool SAL_CALL ScAccessibleTableBase::unselectColumn( sal_Int32 )
403
0
{
404
0
    return true;
405
0
}
406
407
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */