Coverage Report

Created: 2026-02-14 09:37

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