Coverage Report

Created: 2026-05-16 09:25

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/svx/source/table/accessibletableshape.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
21
#include <com/sun/star/table/XMergeableCell.hpp>
22
#include <com/sun/star/accessibility/AccessibleEventId.hpp>
23
#include <com/sun/star/accessibility/AccessibleStateType.hpp>
24
#include <com/sun/star/accessibility/AccessibleRole.hpp>
25
#include <com/sun/star/drawing/XShape.hpp>
26
#include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
27
28
#include <comphelper/diagnose_ex.hxx>
29
#include <vcl/svapp.hxx>
30
31
#include <AccessibleTableShape.hxx>
32
#include <svx/sdr/table/tablecontroller.hxx>
33
#include "accessiblecell.hxx"
34
#include <cell.hxx>
35
36
#include <algorithm>
37
#include <unordered_map>
38
39
#include <cppuhelper/implbase.hxx>
40
#include <svx/svdotable.hxx>
41
#include <com/sun/star/view/XSelectionSupplier.hpp>
42
43
44
using namespace ::accessibility;
45
using namespace sdr::table;
46
using namespace ::com::sun::star::accessibility;
47
using namespace ::com::sun::star::uno;
48
using namespace ::com::sun::star::beans;
49
using namespace ::com::sun::star::util;
50
using namespace ::com::sun::star::lang;
51
using namespace ::com::sun::star::table;
52
53
namespace accessibility
54
{
55
56
typedef std::unordered_map< rtl::Reference< Cell >, rtl::Reference< AccessibleCell > > AccessibleCellMap;
57
58
class AccessibleTableShapeImpl : public cppu::WeakImplHelper< XModifyListener >
59
{
60
public:
61
    explicit AccessibleTableShapeImpl( AccessibleShapeTreeInfo& rShapeTreeInfo );
62
63
    void init( const rtl::Reference< AccessibleTableShape>& xAccessible, const rtl::Reference< TableModel >& xTable );
64
    void dispose();
65
66
    /// @throws IndexOutOfBoundsException
67
    /// @throws RuntimeException
68
    Reference< XAccessible > getAccessibleChild(sal_Int64 i);
69
    /// @throws IndexOutOfBoundsException
70
    void getColumnAndRow( sal_Int64 nChildIndex, sal_Int32& rnColumn, sal_Int32& rnRow );
71
72
    // XModifyListener
73
    virtual void SAL_CALL modified( const EventObject& aEvent ) override;
74
75
    // XEventListener
76
    virtual void SAL_CALL disposing( const EventObject& Source ) override;
77
78
    AccessibleShapeTreeInfo& mrShapeTreeInfo;
79
    rtl::Reference< TableModel > mxTable;
80
    AccessibleCellMap maChildMap;
81
    rtl::Reference< AccessibleTableShape> mxAccessible;
82
    sal_Int32 mRowCount, mColCount;
83
    //get the cached AccessibleCell from XCell
84
    rtl::Reference< AccessibleCell > getAccessibleCell (const rtl::Reference< Cell >& xCell);
85
    /// @throws IndexOutOfBoundsException
86
    /// @throws RuntimeException
87
    rtl::Reference< AccessibleCell > getAccessibleCell (sal_Int32 nRow, sal_Int32 nColumn);
88
};
89
90
91
AccessibleTableShapeImpl::AccessibleTableShapeImpl( AccessibleShapeTreeInfo& rShapeTreeInfo )
92
0
: mrShapeTreeInfo( rShapeTreeInfo )
93
0
, mRowCount(0)
94
0
, mColCount(0)
95
0
{
96
0
}
97
98
99
void AccessibleTableShapeImpl::init( const rtl::Reference<AccessibleTableShape>& xAccessible, const rtl::Reference< TableModel >& xTable )
100
0
{
101
0
    mxAccessible = xAccessible;
102
0
    mxTable = xTable;
103
104
0
    if( mxTable.is() )
105
0
    {
106
0
        Reference< XModifyListener > xListener( this );
107
0
        mxTable->addModifyListener( xListener );
108
0
        mRowCount = mxTable->getRowCount();
109
0
        mColCount = mxTable->getColumnCount();
110
0
    }
111
0
}
112
113
114
void AccessibleTableShapeImpl::dispose()
115
0
{
116
0
    if( mxTable.is() )
117
0
    {
118
        //remove all the cell's acc object in table's dispose.
119
0
        for( auto& rEntry : maChildMap )
120
0
        {
121
0
            rEntry.second->dispose();
122
0
        }
123
0
        maChildMap.clear();
124
0
        Reference< XModifyListener > xListener( this );
125
0
        mxTable->removeModifyListener( xListener );
126
0
        mxTable.clear();
127
0
    }
128
0
    mxAccessible.clear();
129
0
}
130
131
132
//get the cached AccessibleCell from XCell
133
rtl::Reference< AccessibleCell > AccessibleTableShapeImpl::getAccessibleCell (const rtl::Reference< Cell >& xCell)
134
0
{
135
0
    AccessibleCellMap::iterator iter( maChildMap.find( xCell ) );
136
137
0
    if( iter != maChildMap.end() )
138
0
    {
139
0
        rtl::Reference< AccessibleCell > xChild( (*iter).second );
140
0
        return xChild;
141
0
    }
142
0
    return rtl::Reference< AccessibleCell >();
143
0
}
144
145
rtl::Reference< AccessibleCell > AccessibleTableShapeImpl::getAccessibleCell (sal_Int32 nRow, sal_Int32 nColumn)
146
0
{
147
0
    rtl::Reference< Cell > xCell( mxTable->getCell( nColumn, nRow ) );
148
0
    rtl::Reference< AccessibleCell > xChild = getAccessibleCell( xCell );
149
150
0
    if( !xChild.is() && mxTable.is() )
151
0
    {
152
0
        sal_Int32 nChildIndex = mxTable->getColumnCount() * nRow + nColumn;
153
154
0
        rtl::Reference< AccessibleCell > xAccessibleCell( new AccessibleCell( mxAccessible, xCell, nChildIndex, mrShapeTreeInfo ) );
155
156
0
        xAccessibleCell->Init();
157
0
        maChildMap[xCell] = xAccessibleCell;
158
159
0
        xChild = std::move(xAccessibleCell);
160
0
    }
161
0
    return xChild;
162
0
}
163
164
165
Reference< XAccessible > AccessibleTableShapeImpl::getAccessibleChild(sal_Int64 nChildIndex)
166
0
{
167
0
    sal_Int32 nColumn = 0, nRow = 0;
168
0
    getColumnAndRow( nChildIndex, nColumn, nRow );
169
170
0
    rtl::Reference< Cell > xCell( mxTable->getCell( nColumn, nRow ) );
171
0
    AccessibleCellMap::iterator iter( maChildMap.find( xCell ) );
172
173
0
    if( iter != maChildMap.end() )
174
0
    {
175
0
        return (*iter).second;
176
0
    }
177
0
    else
178
0
    {
179
0
        rtl::Reference< AccessibleCell > xAccessibleCell( new AccessibleCell( mxAccessible, xCell, nChildIndex, mrShapeTreeInfo ) );
180
181
0
        xAccessibleCell->Init();
182
0
        maChildMap[xCell] = xAccessibleCell;
183
184
0
        return xAccessibleCell;
185
0
    }
186
0
}
187
188
189
void AccessibleTableShapeImpl::getColumnAndRow( sal_Int64 nChildIndex, sal_Int32& rnColumn, sal_Int32& rnRow )
190
0
{
191
0
    if( mxTable.is() )
192
0
    {
193
0
        const sal_Int32 nColumnCount = mxTable->getColumnCount();
194
0
        if (nColumnCount == 0)
195
0
            throw IndexOutOfBoundsException();
196
197
0
        rnColumn = nChildIndex % nColumnCount;
198
0
        rnRow = nChildIndex / nColumnCount;
199
200
0
        if( rnRow < mxTable->getRowCount() )
201
0
            return;
202
0
    }
203
204
0
    throw IndexOutOfBoundsException();
205
0
}
206
207
// XModifyListener
208
void SAL_CALL AccessibleTableShapeImpl::modified( const EventObject& /*aEvent*/ )
209
0
{
210
0
    if( !mxTable.is() )
211
0
        return;
212
213
0
    try
214
0
    {
215
        // structural changes may have happened to the table, validate all accessible cell instances
216
0
        AccessibleCellMap aTempChildMap;
217
0
        aTempChildMap.swap( maChildMap );
218
219
        // first move all still existing cells to maChildMap again and update their index
220
221
0
        const sal_Int32 nRowCount = mxTable->getRowCount();
222
0
        const sal_Int32 nColCount = mxTable->getColumnCount();
223
224
0
        bool bRowOrColumnChanged = false;
225
0
        if (mRowCount != nRowCount || mColCount != nColCount )
226
0
        {
227
0
            bRowOrColumnChanged = true;
228
0
            mRowCount = nRowCount;
229
0
            mColCount = nColCount;
230
0
        }
231
0
        sal_Int32 nChildIndex = 0;
232
233
0
        for( sal_Int32 nRow = 0; nRow < nRowCount; ++nRow )
234
0
        {
235
0
            for( sal_Int32 nCol = 0; nCol < nColCount; ++nCol )
236
0
            {
237
0
                rtl::Reference< Cell > xCell( mxTable->getCell( nCol, nRow ) );
238
0
                AccessibleCellMap::iterator iter( aTempChildMap.find( xCell ) );
239
240
0
                if( iter != aTempChildMap.end() )
241
0
                {
242
0
                    rtl::Reference< AccessibleCell > xAccessibleCell( (*iter).second );
243
0
                    xAccessibleCell->setIndexInParent( nChildIndex );
244
0
                    xAccessibleCell->UpdateChildren();
245
                    // If row or column count is changed, there is split or merge, so all cell's acc name should be updated
246
0
                    if (bRowOrColumnChanged)
247
0
                    {
248
0
                        xAccessibleCell->SetAccessibleName(xAccessibleCell->getAccessibleName(), AccessibleContextBase::ManuallySet);
249
0
                    }
250
                    // For merged cell, add invisible & disabled state.
251
0
                    rtl::Reference< Cell > xMergedCell( mxTable->getCell( nCol, nRow ) );
252
0
                    if (xMergedCell.is() && xMergedCell->isMerged())
253
0
                    {
254
0
                        xAccessibleCell->ResetState(AccessibleStateType::VISIBLE);
255
0
                        xAccessibleCell->ResetState(AccessibleStateType::ENABLED);
256
                        // IA2 CWS. MT: OFFSCREEN == !SHOWING, should stay consistent
257
                        // xAccessibleCell->SetState(AccessibleStateType::OFFSCREEN);
258
0
                        xAccessibleCell->ResetState(AccessibleStateType::SHOWING);
259
0
                    }
260
0
                    else
261
0
                    {
262
0
                        xAccessibleCell->SetState(AccessibleStateType::VISIBLE);
263
0
                        xAccessibleCell->SetState(AccessibleStateType::ENABLED);
264
                        // IA2 CWS. MT: OFFSCREEN == !SHOWING, should stay consistent
265
                        // xAccessibleCell->ResetState(AccessibleStateType::OFFSCREEN);
266
0
                        xAccessibleCell->SetState(AccessibleStateType::SHOWING);
267
0
                    }
268
269
                    // move still existing cell from temporary child map to our child map
270
0
                    maChildMap[xCell] = std::move(xAccessibleCell);
271
0
                    aTempChildMap.erase( iter );
272
0
                }
273
0
                else
274
0
                {
275
0
                    rtl::Reference< AccessibleCell > xAccessibleCell( new AccessibleCell( mxAccessible, xCell, nChildIndex, mrShapeTreeInfo ) );
276
277
0
                    xAccessibleCell->Init();
278
0
                    maChildMap[xCell] = std::move(xAccessibleCell);
279
0
                }
280
281
0
                ++nChildIndex;
282
0
            }
283
0
        }
284
285
        // all accessible cell instances still left in aTempChildMap must be disposed
286
        // as they are no longer part of the table
287
288
0
        for( auto& rEntry : aTempChildMap )
289
0
        {
290
0
            rEntry.second->dispose();
291
0
        }
292
        //notify bridge to update the acc cache.
293
0
        if (mxAccessible)
294
0
            mxAccessible->CommitChange(AccessibleEventId::INVALIDATE_ALL_CHILDREN, Any(), Any(), -1);
295
0
    }
296
0
    catch( const Exception& )
297
0
    {
298
0
        TOOLS_WARN_EXCEPTION("svx.table", "");
299
0
    }
300
0
}
301
302
// XEventListener
303
void SAL_CALL AccessibleTableShapeImpl::disposing( const EventObject& /*Source*/ )
304
0
{
305
0
}
306
307
AccessibleTableShape::AccessibleTableShape(const AccessibleShapeInfo& rShapeInfo,
308
                                           const AccessibleShapeTreeInfo& rShapeTreeInfo)
309
0
    : ImplInheritanceHelper(rShapeInfo, rShapeTreeInfo)
310
0
    , mnPreviousSelectionCount(0)
311
0
    , mxImpl(new AccessibleTableShapeImpl(maShapeTreeInfo))
312
0
{
313
0
}
314
315
316
AccessibleTableShape::~AccessibleTableShape()
317
0
{
318
0
}
319
320
321
void AccessibleTableShape::Init()
322
0
{
323
0
    try
324
0
    {
325
0
        Reference< XPropertySet > xSet( mxShape, UNO_QUERY_THROW );
326
0
        Reference< XTable > xTable( xSet->getPropertyValue(u"Model"_ustr), UNO_QUERY_THROW );
327
328
0
        TableModel* pModel = dynamic_cast<TableModel*>(xTable.get());
329
0
        assert(pModel);
330
0
        mxImpl->init( this, pModel );
331
0
    }
332
0
    catch( Exception& )
333
0
    {
334
0
        TOOLS_WARN_EXCEPTION("svx.table", "");
335
0
    }
336
337
0
    AccessibleShape::Init();
338
0
}
339
340
341
SvxTableController* AccessibleTableShape::getTableController()
342
0
{
343
0
    SdrView* pView = maShapeTreeInfo.GetSdrView ();
344
0
    if( pView )
345
0
        return dynamic_cast< SvxTableController* >( pView->getSelectionController().get() );
346
0
    else
347
0
        return nullptr;
348
0
}
349
350
// XAccessible
351
352
353
OUString SAL_CALL AccessibleTableShape::getImplementationName()
354
0
{
355
0
    return u"com.sun.star.comp.accessibility.AccessibleTableShape"_ustr;
356
0
}
357
358
359
OUString AccessibleTableShape::CreateAccessibleBaseName()
360
0
{
361
0
    return u"TableShape"_ustr;
362
0
}
363
364
365
sal_Int64 SAL_CALL AccessibleTableShape::getAccessibleChildCount( )
366
0
{
367
0
    SolarMutexGuard aSolarGuard;
368
0
    return mxImpl->mxTable.is() ? static_cast<sal_Int64>(mxImpl->mxTable->getRowCount()) * static_cast<sal_Int64>(mxImpl->mxTable->getColumnCount()) : 0;
369
0
}
370
371
372
Reference< XAccessible > SAL_CALL AccessibleTableShape::getAccessibleChild( sal_Int64 i )
373
0
{
374
0
    SolarMutexGuard aSolarGuard;
375
0
    ensureAlive();
376
377
0
    return mxImpl->getAccessibleChild( i );
378
0
}
379
380
381
sal_Int16 SAL_CALL AccessibleTableShape::getAccessibleRole()
382
0
{
383
0
    return AccessibleRole::TABLE;
384
0
}
385
386
387
void SAL_CALL AccessibleTableShape::disposing()
388
0
{
389
0
    mxImpl->dispose();
390
391
    // let the base do its stuff
392
0
    AccessibleShape::disposing();
393
0
}
394
395
396
// XAccessibleTable
397
398
399
sal_Int32 SAL_CALL AccessibleTableShape::getAccessibleRowCount()
400
0
{
401
0
    SolarMutexGuard aSolarGuard;
402
0
    return mxImpl->mxTable.is() ? mxImpl->mxTable->getRowCount() : 0;
403
0
}
404
405
406
sal_Int32 SAL_CALL AccessibleTableShape::getAccessibleColumnCount(  )
407
0
{
408
0
    SolarMutexGuard aSolarGuard;
409
0
    return mxImpl->mxTable.is() ? mxImpl->mxTable->getColumnCount() : 0;
410
0
}
411
412
413
OUString SAL_CALL AccessibleTableShape::getAccessibleRowDescription( sal_Int32 nRow )
414
0
{
415
0
    checkCellPosition( 0, nRow );
416
0
    return OUString();
417
0
}
418
419
420
OUString SAL_CALL AccessibleTableShape::getAccessibleColumnDescription( sal_Int32 nColumn )
421
0
{
422
0
    SolarMutexGuard aSolarGuard;
423
0
    checkCellPosition( nColumn, 0 );
424
0
    return OUString();
425
0
}
426
427
428
sal_Int32 SAL_CALL AccessibleTableShape::getAccessibleRowExtentAt( sal_Int32 nRow, sal_Int32 nColumn )
429
0
{
430
0
    SolarMutexGuard aSolarGuard;
431
0
    checkCellPosition( nColumn, nRow );
432
0
    if( mxImpl->mxTable.is() )
433
0
    {
434
0
        rtl::Reference< Cell > xCell( mxImpl->mxTable->getCell( nColumn, nRow ) );
435
0
        if( xCell.is() )
436
0
            return xCell->getRowSpan();
437
0
    }
438
0
    return 1;
439
0
}
440
441
442
sal_Int32 SAL_CALL AccessibleTableShape::getAccessibleColumnExtentAt( sal_Int32 nRow, sal_Int32 nColumn )
443
0
{
444
0
    SolarMutexGuard aSolarGuard;
445
0
    checkCellPosition( nColumn, nRow );
446
0
    if( mxImpl->mxTable.is() )
447
0
    {
448
0
        rtl::Reference< Cell > xCell( mxImpl->mxTable->getCell( nColumn, nRow ) );
449
0
        if( xCell.is() )
450
0
            return xCell->getColumnSpan();
451
0
    }
452
0
    return 1;
453
0
}
454
455
456
Reference< XAccessibleTable > SAL_CALL AccessibleTableShape::getAccessibleRowHeaders(  )
457
0
{
458
0
    SvxTableController* pController = getTableController();
459
0
    if( !pController )
460
0
        return nullptr;
461
0
    if( !pController->isRowHeader() )
462
0
        return nullptr;
463
0
    return new AccessibleTableHeaderShape( this, true );
464
0
}
465
466
467
Reference< XAccessibleTable > SAL_CALL AccessibleTableShape::getAccessibleColumnHeaders(  )
468
0
{
469
0
    SvxTableController* pController = getTableController();
470
0
    if( !pController )
471
0
        return nullptr;
472
0
    if( !pController->isColumnHeader() )
473
0
        return nullptr;
474
0
    return new AccessibleTableHeaderShape( this, false );
475
0
}
476
477
478
Sequence< sal_Int32 > SAL_CALL AccessibleTableShape::getSelectedAccessibleRows(  )
479
0
{
480
0
    sal_Int32 nRow = getAccessibleRowCount();
481
0
    ::std::vector<bool> aSelected( nRow, true );
482
0
    sal_Int32 nCount = nRow;
483
0
    for( sal_Int32 i = 0; i < nRow; i++ )
484
0
    {
485
0
        try
486
0
        {
487
0
            aSelected[i] = isAccessibleRowSelected( i );
488
0
        }
489
0
        catch( ... )
490
0
        {
491
0
            return Sequence< sal_Int32 >();
492
0
        }
493
494
0
        if( !aSelected[i] )
495
0
            nCount--;
496
0
    }
497
0
    Sequence < sal_Int32 > aRet( nCount );
498
0
    sal_Int32 *pRet = aRet.getArray();
499
0
    sal_Int32 nPos = 0;
500
0
    size_t nSize = aSelected.size();
501
0
    for( size_t i=0; i < nSize && nPos < nCount; i++ )
502
0
    {
503
0
        if( aSelected[i] )
504
0
        {
505
0
            *pRet++ = i;
506
0
            nPos++;
507
0
        }
508
0
    }
509
510
0
    return aRet;
511
0
}
512
513
514
Sequence< sal_Int32 > SAL_CALL AccessibleTableShape::getSelectedAccessibleColumns(  )
515
0
{
516
0
    sal_Int32 nColumn = getAccessibleColumnCount();
517
0
    ::std::vector<bool> aSelected( nColumn, true );
518
0
    sal_Int32 nCount = nColumn;
519
0
    for( sal_Int32 i = 0; i < nColumn; i++ )
520
0
    {
521
0
        try
522
0
        {
523
0
            aSelected[i] = isAccessibleColumnSelected( i );
524
0
        }
525
0
        catch( ... )
526
0
        {
527
0
            return Sequence< sal_Int32 >();
528
0
        }
529
530
0
        if( !aSelected[i] )
531
0
            nCount--;
532
0
    }
533
0
    Sequence < sal_Int32 > aRet( nCount );
534
0
    sal_Int32 *pRet = aRet.getArray();
535
0
    sal_Int32 nPos = 0;
536
0
    size_t nSize = aSelected.size();
537
0
    for( size_t i=0; i < nSize && nPos < nCount; i++ )
538
0
    {
539
0
        if( aSelected[i] )
540
0
        {
541
0
            *pRet++ = i;
542
0
            nPos++;
543
0
        }
544
0
    }
545
546
0
    return aRet;
547
0
}
548
549
550
sal_Bool SAL_CALL AccessibleTableShape::isAccessibleRowSelected( sal_Int32 nRow )
551
0
{
552
0
    SolarMutexGuard aSolarGuard;
553
0
    checkCellPosition( 0, nRow );
554
0
    SvxTableController* pController = getTableController();
555
0
    if( pController )
556
0
    {
557
0
        return pController->isRowSelected( nRow );
558
0
    }
559
0
    return false;
560
0
}
561
562
563
sal_Bool SAL_CALL AccessibleTableShape::isAccessibleColumnSelected( sal_Int32 nColumn )
564
0
{
565
0
    SolarMutexGuard aSolarGuard;
566
0
    checkCellPosition( nColumn, 0 );
567
0
    SvxTableController* pController = getTableController();
568
0
    if( pController )
569
0
    {
570
0
        return pController->isColumnSelected( nColumn );
571
0
    }
572
0
    return false;
573
0
}
574
575
576
Reference< XAccessible > SAL_CALL AccessibleTableShape::getAccessibleCellAt( sal_Int32 nRow, sal_Int32 nColumn )
577
0
{
578
0
    SolarMutexGuard aSolarGuard;
579
0
    checkCellPosition( nColumn, nRow );
580
581
0
    sal_Int32 nChildIndex = 0;
582
0
    if( mxImpl->mxTable.is() )
583
0
        nChildIndex = mxImpl->mxTable->getColumnCount() * nRow + nColumn;
584
585
0
    return getAccessibleChild( nChildIndex );
586
0
}
587
588
589
Reference< XAccessible > SAL_CALL AccessibleTableShape::getAccessibleCaption(  )
590
0
{
591
0
    Reference< XAccessible > xRet;
592
0
    return xRet;
593
0
}
594
595
596
Reference< XAccessible > SAL_CALL AccessibleTableShape::getAccessibleSummary(  )
597
0
{
598
0
    Reference< XAccessible > xRet;
599
0
    return xRet;
600
0
}
601
602
603
sal_Bool SAL_CALL AccessibleTableShape::isAccessibleSelected( sal_Int32 nRow, sal_Int32 nColumn )
604
0
{
605
0
    SolarMutexGuard aSolarGuard;
606
0
    checkCellPosition( nColumn, nRow );
607
608
0
    SvxTableController* pController = getTableController();
609
0
    if( pController && pController->hasSelectedCells() )
610
0
    {
611
0
        CellPos aFirstPos, aLastPos;
612
0
        pController->getSelectedCells( aFirstPos, aLastPos );
613
0
        if( (aFirstPos.mnRow <= nRow) && (aFirstPos.mnCol <= nColumn) && (nRow <= aLastPos.mnRow) && (nColumn <= aLastPos.mnCol) )
614
0
            return true;
615
0
    }
616
617
0
    return false;
618
0
}
619
620
621
sal_Int64 SAL_CALL AccessibleTableShape::getAccessibleIndex( sal_Int32 nRow, sal_Int32 nColumn )
622
0
{
623
0
    SolarMutexGuard aSolarGuard;
624
0
    checkCellPosition( nColumn, nRow );
625
0
    return  mxImpl->mxTable.is() ? (static_cast<sal_Int64>(nRow) * static_cast<sal_Int64>(mxImpl->mxTable->getColumnCount()) + nColumn) : 0;
626
0
}
627
628
629
sal_Int32 SAL_CALL AccessibleTableShape::getAccessibleRow( sal_Int64 nChildIndex )
630
0
{
631
0
    SolarMutexGuard aSolarGuard;
632
0
    sal_Int32 nColumn = 0, nRow = 0;
633
0
    mxImpl->getColumnAndRow( nChildIndex, nColumn, nRow );
634
0
    return nRow;
635
0
}
636
637
638
sal_Int32 SAL_CALL AccessibleTableShape::getAccessibleColumn( sal_Int64 nChildIndex )
639
0
{
640
0
    SolarMutexGuard aSolarGuard;
641
0
    sal_Int32 nColumn = 0, nRow = 0;
642
0
    mxImpl->getColumnAndRow( nChildIndex, nColumn, nRow );
643
0
    return nColumn;
644
0
}
645
646
647
// XAccessibleSelection
648
649
650
void SAL_CALL AccessibleTableShape::selectAccessibleChild( sal_Int64 nChildIndex )
651
0
{
652
0
    SolarMutexGuard aSolarGuard;
653
0
    CellPos aPos;
654
0
    mxImpl->getColumnAndRow( nChildIndex, aPos.mnCol, aPos.mnRow );
655
656
    // todo, select table shape?!?
657
0
    SvxTableController* pController = getTableController();
658
0
    if( !pController )
659
0
        return;
660
661
0
    CellPos aFirstPos( aPos ), aLastPos( aPos );
662
0
    if( pController->hasSelectedCells() )
663
0
    {
664
0
        pController->getSelectedCells( aFirstPos, aLastPos );
665
666
0
        aFirstPos.mnRow = std::min( aFirstPos.mnRow, aPos.mnRow );
667
0
        aFirstPos.mnCol = std::min( aFirstPos.mnCol, aPos.mnCol );
668
0
        aLastPos.mnRow = std::max( aLastPos.mnRow, aPos.mnRow );
669
0
        aLastPos.mnCol = std::max( aLastPos.mnCol, aPos.mnCol );
670
0
    }
671
0
    pController->setSelectedCells( aFirstPos, aLastPos );
672
0
}
673
674
675
sal_Bool SAL_CALL AccessibleTableShape::isAccessibleChildSelected( sal_Int64 nChildIndex )
676
0
{
677
0
    SolarMutexGuard aSolarGuard;
678
679
0
    if (nChildIndex < 0 || nChildIndex >= getAccessibleChildCount())
680
0
        throw IndexOutOfBoundsException();
681
682
0
    CellPos aPos;
683
0
    mxImpl->getColumnAndRow( nChildIndex, aPos.mnCol, aPos.mnRow );
684
685
0
    return isAccessibleSelected(aPos.mnRow, aPos.mnCol);
686
0
}
687
688
689
void SAL_CALL AccessibleTableShape::clearAccessibleSelection()
690
0
{
691
0
    SolarMutexGuard aSolarGuard;
692
693
0
    SvxTableController* pController = getTableController();
694
0
    if( pController )
695
0
        pController->clearSelection();
696
0
}
697
698
699
void SAL_CALL AccessibleTableShape::selectAllAccessibleChildren()
700
0
{
701
0
    SolarMutexGuard aSolarGuard;
702
703
   // todo: force selection of shape?
704
0
    SvxTableController* pController = getTableController();
705
0
    if( pController )
706
0
        pController->selectAll();
707
0
}
708
709
710
sal_Int64 SAL_CALL AccessibleTableShape::getSelectedAccessibleChildCount()
711
0
{
712
0
    SolarMutexGuard aSolarGuard;
713
714
0
    SvxTableController* pController = getTableController();
715
0
    if( pController && pController->hasSelectedCells() )
716
0
    {
717
0
        CellPos aFirstPos, aLastPos;
718
0
        pController->getSelectedCells( aFirstPos, aLastPos );
719
720
0
        const sal_Int32 nSelectedColumns = std::max( sal_Int32(0), aLastPos.mnCol - aFirstPos.mnCol ) + 1;
721
0
        const sal_Int32 nSelectedRows = std::max( sal_Int32(0), aLastPos.mnRow - aFirstPos.mnRow ) + 1;
722
0
        return static_cast<sal_Int64>(nSelectedRows) * static_cast<sal_Int64>(nSelectedColumns);
723
0
    }
724
725
0
    return 0;
726
0
}
727
728
729
Reference< XAccessible > SAL_CALL AccessibleTableShape::getSelectedAccessibleChild( sal_Int64 nSelectedChildIndex )
730
0
{
731
0
    SolarMutexGuard aSolarGuard;
732
733
0
    if( nSelectedChildIndex < 0 )
734
0
        throw IndexOutOfBoundsException();
735
736
0
    sal_Int64 nChildIndex = GetIndexOfSelectedChild( nSelectedChildIndex );
737
738
0
    if( nChildIndex < 0 )
739
0
        throw IndexOutOfBoundsException();
740
741
0
    if ( nChildIndex >= getAccessibleChildCount() )
742
0
    {
743
0
        throw IndexOutOfBoundsException();
744
0
    }
745
746
0
    return getAccessibleChild( nChildIndex );
747
0
}
748
749
750
void SAL_CALL AccessibleTableShape::deselectAccessibleChild( sal_Int64 nChildIndex )
751
0
{
752
0
    SolarMutexGuard aSolarGuard;
753
0
    CellPos aPos;
754
0
    mxImpl->getColumnAndRow( nChildIndex, aPos.mnCol, aPos.mnRow );
755
756
    // todo, select table shape?!?
757
0
    SvxTableController* pController = getTableController();
758
0
    if( !(pController && pController->hasSelectedCells()) )
759
0
        return;
760
761
0
    CellPos aFirstPos, aLastPos;
762
0
    pController->getSelectedCells( aFirstPos, aLastPos );
763
764
    // create a selection where aPos is not part of anymore
765
0
    aFirstPos.mnRow = std::min( aFirstPos.mnRow, aPos.mnRow+1 );
766
0
    aFirstPos.mnCol = std::min( aFirstPos.mnCol, aPos.mnCol+1 );
767
0
    aLastPos.mnRow = std::max( aLastPos.mnRow, aPos.mnRow-1 );
768
0
    aLastPos.mnCol = std::max( aLastPos.mnCol, aPos.mnCol-1 );
769
770
    // new selection may be invalid (child to deselect is not at a border of the selection but in between)
771
0
    if( (aFirstPos.mnRow > aLastPos.mnRow) || (aFirstPos.mnCol > aLastPos.mnCol) )
772
0
        pController->clearSelection(); // if selection is invalid, clear all
773
0
    else
774
0
        pController->setSelectedCells( aFirstPos, aLastPos );
775
0
}
776
777
// XAccessibleTableSelection
778
sal_Bool SAL_CALL AccessibleTableShape::selectRow( sal_Int32 row )
779
0
{
780
0
    SolarMutexGuard aSolarGuard;
781
0
    SvxTableController* pController = getTableController();
782
0
    if( !pController )
783
0
        return false;
784
0
    return pController->selectRow( row );
785
0
}
786
787
sal_Bool SAL_CALL AccessibleTableShape::selectColumn( sal_Int32 column )
788
0
{
789
0
    SolarMutexGuard aSolarGuard;
790
0
    SvxTableController* pController = getTableController();
791
0
    if( !pController )
792
0
        return false;
793
0
    return pController->selectColumn( column );
794
0
}
795
796
sal_Bool SAL_CALL AccessibleTableShape::unselectRow( sal_Int32 row )
797
0
{
798
0
    SolarMutexGuard aSolarGuard;
799
0
    SvxTableController* pController = getTableController();
800
0
    if( !pController )
801
0
        return false;
802
0
    return pController->deselectRow( row );
803
0
}
804
805
sal_Bool SAL_CALL AccessibleTableShape::unselectColumn( sal_Int32 column )
806
0
{
807
0
    SolarMutexGuard aSolarGuard;
808
0
    SvxTableController* pController = getTableController();
809
0
    if( !pController )
810
0
        return false;
811
0
    return pController->deselectColumn( column );
812
0
}
813
814
sal_Int64 AccessibleTableShape::GetIndexOfSelectedChild(
815
                sal_Int64 nSelectedChildIndex ) const
816
0
{
817
0
    sal_Int64 nChildren = const_cast<AccessibleTableShape*>(this)->getAccessibleChildCount();
818
819
0
    if( nSelectedChildIndex >= nChildren )
820
0
        return -1;
821
822
0
    sal_Int64 n = 0;
823
0
    while( n < nChildren )
824
0
    {
825
0
        if( const_cast<AccessibleTableShape*>(this)->isAccessibleChildSelected( n ) )
826
0
        {
827
0
            if( 0 == nSelectedChildIndex )
828
0
                break;
829
0
            else
830
0
                --nSelectedChildIndex;
831
0
        }
832
0
        ++n;
833
0
    }
834
835
0
    return n < nChildren ? n : -1;
836
0
}
837
void AccessibleTableShape::getColumnAndRow( sal_Int64 nChildIndex, sal_Int32& rnColumn, sal_Int32& rnRow )
838
0
{
839
0
    mxImpl->getColumnAndRow(nChildIndex, rnColumn, rnRow);
840
0
}
841
842
// XSelectionChangeListener
843
void SAL_CALL
844
    AccessibleTableShape::disposing (const EventObject& aEvent)
845
0
{
846
0
    AccessibleShape::disposing(aEvent);
847
0
}
848
void  SAL_CALL AccessibleTableShape::selectionChanged (const EventObject& rEvent)
849
0
{
850
    //sdr::table::CellRef xCellRef = static_cast< sdr::table::CellRef > (rEvent.Source);
851
0
    rtl::Reference< Cell > xCell = dynamic_cast<Cell*>(rEvent.Source.get());
852
0
    if (!xCell.is())
853
0
        return;
854
855
0
    rtl::Reference< AccessibleCell > xAccCell = mxImpl->getAccessibleCell( xCell );
856
0
    if (!xAccCell.is())
857
0
        return;
858
859
0
    sal_Int64 nIndex = xAccCell->getAccessibleIndexInParent(),
860
0
        nCount = getSelectedAccessibleChildCount();
861
0
    bool bSelected = isAccessibleChildSelected(nIndex);
862
0
    if (mnPreviousSelectionCount == 0 && nCount > 0 && bSelected)
863
0
    {
864
0
        xAccCell->SetState(AccessibleStateType::SELECTED);
865
0
        xAccCell->CommitChange(AccessibleEventId::SELECTION_CHANGED, Any(), Any(), -1);
866
0
    }
867
0
    else if (bSelected)
868
0
    {
869
0
        xAccCell->SetState(AccessibleStateType::SELECTED);
870
0
        xAccCell->CommitChange(AccessibleEventId::SELECTION_CHANGED_ADD, Any(), Any(), -1);
871
0
    }
872
0
    else
873
0
    {
874
0
        xAccCell->ResetState(AccessibleStateType::SELECTED);
875
0
        xAccCell->CommitChange(AccessibleEventId::SELECTION_CHANGED_REMOVE, Any(), Any(), -1);
876
0
    }
877
0
    mnPreviousSelectionCount = nCount;
878
0
}
879
// Get the currently active cell which is text editing
880
AccessibleCell* AccessibleTableShape::GetActiveAccessibleCell()
881
0
{
882
0
    rtl::Reference< AccessibleCell > xAccCell;
883
0
    AccessibleCell* pAccCell = nullptr;
884
0
    SvxTableController* pController = getTableController();
885
0
    if (pController)
886
0
    {
887
0
        sdr::table::SdrTableObj* pTableObj = pController->GetTableObj();
888
0
        if ( pTableObj )
889
0
        {
890
0
            const sdr::table::CellRef& xCellRef (pTableObj->getActiveCell());
891
0
            if ( xCellRef.is() )
892
0
            {
893
0
                try
894
0
                {
895
0
                    CellPos rPos;
896
0
                    pTableObj->getActiveCellPos( rPos );
897
0
                    xAccCell = mxImpl->getAccessibleCell( rPos.mnRow, rPos.mnCol );
898
0
                    if ( xAccCell.is() )
899
0
                        pAccCell = xAccCell.get();
900
0
                }
901
0
                catch ( IndexOutOfBoundsException& ) {}
902
0
            }
903
0
        }
904
0
    }
905
0
    return pAccCell;
906
0
}
907
908
//If current active cell is in editing, the focus state should be set to internal text
909
bool AccessibleTableShape::SetState (sal_Int64 aState)
910
0
{
911
0
    if( aState == AccessibleStateType::FOCUSED )
912
0
    {
913
0
        AccessibleCell* pActiveAccessibleCell = GetActiveAccessibleCell();
914
0
        if( pActiveAccessibleCell != nullptr )
915
0
            return pActiveAccessibleCell->SetState(aState);
916
0
    }
917
918
0
    return AccessibleShape::SetState (aState);
919
0
}
920
921
//If current active cell is in editing, the focus state should be reset to internal text
922
bool AccessibleTableShape::ResetState (sal_Int64 aState)
923
0
{
924
0
    if( aState == AccessibleStateType::FOCUSED )
925
0
    {
926
0
        AccessibleCell* pActiveAccessibleCell = GetActiveAccessibleCell();
927
0
        if( pActiveAccessibleCell != nullptr )
928
0
            return pActiveAccessibleCell->ResetState(aState);
929
0
    }
930
931
0
    return AccessibleShape::ResetState (aState);
932
0
}
933
934
bool AccessibleTableShape::SetStateDirectly (sal_Int64 aState)
935
0
{
936
0
    return AccessibleContextBase::SetState (aState);
937
0
}
938
939
bool AccessibleTableShape::ResetStateDirectly (sal_Int64 aState)
940
0
{
941
0
    return AccessibleContextBase::ResetState (aState);
942
0
}
943
944
void AccessibleTableShape::checkCellPosition( sal_Int32 nCol, sal_Int32 nRow )
945
0
{
946
0
    if( (nCol >= 0) && (nRow >= 0) && mxImpl->mxTable.is() && (nCol < mxImpl->mxTable->getColumnCount()) && (nRow < mxImpl->mxTable->getRowCount()) )
947
0
        return;
948
949
0
    throw IndexOutOfBoundsException();
950
0
}
951
952
AccessibleTableHeaderShape::AccessibleTableHeaderShape( AccessibleTableShape* pTable, bool bRow )
953
0
{
954
0
    mpTable = pTable;
955
0
    mbRow = bRow;
956
0
}
957
958
AccessibleTableHeaderShape::~AccessibleTableHeaderShape()
959
0
{
960
0
    mpTable = nullptr;
961
0
}
962
963
// XAccessible
964
Reference< XAccessibleContext > SAL_CALL AccessibleTableHeaderShape::getAccessibleContext()
965
0
{
966
0
    return this;
967
0
}
968
969
// XAccessibleContext
970
sal_Int64 SAL_CALL AccessibleTableHeaderShape::getAccessibleChildCount( )
971
0
{
972
0
    return static_cast<sal_Int64>(getAccessibleRowCount()) * static_cast<sal_Int64>(getAccessibleColumnCount());
973
0
}
974
975
Reference< XAccessible > SAL_CALL AccessibleTableHeaderShape::getAccessibleChild( sal_Int64 i )
976
0
{
977
0
    return mpTable->getAccessibleChild( i );
978
0
}
979
980
Reference< XAccessible > SAL_CALL AccessibleTableHeaderShape::getAccessibleParent()
981
0
{
982
0
    Reference< XAccessible > XParent;
983
0
    return XParent;
984
0
}
985
986
sal_Int64 SAL_CALL AccessibleTableHeaderShape::getAccessibleIndexInParent()
987
0
{
988
0
    return -1;
989
0
}
990
991
sal_Int16 SAL_CALL AccessibleTableHeaderShape::getAccessibleRole()
992
0
{
993
0
    return mpTable->getAccessibleRole();
994
0
}
995
996
OUString SAL_CALL AccessibleTableHeaderShape::getAccessibleDescription()
997
0
{
998
0
    return mpTable->getAccessibleDescription();
999
0
}
1000
1001
OUString SAL_CALL AccessibleTableHeaderShape::getAccessibleName()
1002
0
{
1003
0
    return mpTable->getAccessibleName();
1004
0
}
1005
1006
sal_Int64 SAL_CALL AccessibleTableHeaderShape::getAccessibleStateSet()
1007
0
{
1008
0
    return mpTable->getAccessibleStateSet();
1009
0
}
1010
1011
Reference< XAccessibleRelationSet > SAL_CALL AccessibleTableHeaderShape::getAccessibleRelationSet()
1012
0
{
1013
0
    return mpTable->getAccessibleRelationSet();
1014
0
}
1015
1016
Locale SAL_CALL AccessibleTableHeaderShape::getLocale()
1017
0
{
1018
0
    return mpTable->getLocale();
1019
0
}
1020
1021
//XAccessibleComponent
1022
sal_Bool SAL_CALL AccessibleTableHeaderShape::containsPoint ( const css::awt::Point& aPoint )
1023
0
{
1024
0
    return mpTable->containsPoint( aPoint );
1025
0
}
1026
1027
Reference< XAccessible > SAL_CALL AccessibleTableHeaderShape::getAccessibleAtPoint ( const css::awt::Point& aPoint)
1028
0
{
1029
0
    return mpTable->getAccessibleAtPoint( aPoint );
1030
0
}
1031
1032
css::awt::Rectangle SAL_CALL AccessibleTableHeaderShape::getBounds()
1033
0
{
1034
0
    return mpTable->getBounds();
1035
0
}
1036
1037
css::awt::Point SAL_CALL AccessibleTableHeaderShape::getLocation()
1038
0
{
1039
0
    return mpTable->getLocation();
1040
0
}
1041
1042
css::awt::Point SAL_CALL AccessibleTableHeaderShape::getLocationOnScreen()
1043
0
{
1044
0
    return mpTable->getLocationOnScreen();
1045
0
}
1046
1047
css::awt::Size SAL_CALL AccessibleTableHeaderShape::getSize()
1048
0
{
1049
0
    return mpTable->getSize();
1050
0
}
1051
1052
sal_Int32 SAL_CALL AccessibleTableHeaderShape::getForeground()
1053
0
{
1054
0
    return mpTable->getForeground();
1055
0
}
1056
1057
sal_Int32 SAL_CALL AccessibleTableHeaderShape::getBackground()
1058
0
{
1059
0
    return mpTable->getBackground();
1060
0
}
1061
1062
void SAL_CALL AccessibleTableHeaderShape::grabFocus()
1063
0
{
1064
0
    mpTable->grabFocus();
1065
0
}
1066
// XAccessibleTable
1067
sal_Int32 SAL_CALL AccessibleTableHeaderShape::getAccessibleRowCount()
1068
0
{
1069
0
    return mbRow ? 1 : mpTable->getAccessibleRowCount();
1070
0
}
1071
1072
sal_Int32 SAL_CALL AccessibleTableHeaderShape::getAccessibleColumnCount()
1073
0
{
1074
0
    return !mbRow ? 1 : mpTable->getAccessibleColumnCount();
1075
0
}
1076
1077
OUString SAL_CALL AccessibleTableHeaderShape::getAccessibleRowDescription( sal_Int32 nRow )
1078
0
{
1079
0
    return mpTable->getAccessibleRowDescription( nRow );
1080
0
}
1081
1082
OUString SAL_CALL AccessibleTableHeaderShape::getAccessibleColumnDescription( sal_Int32 nColumn )
1083
0
{
1084
0
    return mpTable->getAccessibleColumnDescription( nColumn );
1085
0
}
1086
1087
sal_Int32 SAL_CALL AccessibleTableHeaderShape::getAccessibleRowExtentAt( sal_Int32 nRow, sal_Int32 nColumn )
1088
0
{
1089
0
    return mpTable->getAccessibleRowExtentAt( nRow, nColumn );
1090
0
}
1091
1092
sal_Int32 SAL_CALL AccessibleTableHeaderShape::getAccessibleColumnExtentAt( sal_Int32 nRow, sal_Int32 nColumn )
1093
0
{
1094
0
    return mpTable->getAccessibleColumnExtentAt( nRow, nColumn );
1095
0
}
1096
1097
Reference< XAccessibleTable > SAL_CALL AccessibleTableHeaderShape::getAccessibleRowHeaders(  )
1098
0
{
1099
0
    Reference< XAccessibleTable > xRet;
1100
0
    return xRet;
1101
0
}
1102
1103
Reference< XAccessibleTable > SAL_CALL AccessibleTableHeaderShape::getAccessibleColumnHeaders(  )
1104
0
{
1105
0
    Reference< XAccessibleTable > xRet;
1106
0
    return xRet;
1107
0
}
1108
1109
Sequence< sal_Int32 > SAL_CALL AccessibleTableHeaderShape::getSelectedAccessibleRows(  )
1110
0
{
1111
0
    sal_Int32 nRow = getAccessibleRowCount();
1112
0
    ::std::vector<bool> aSelected( nRow, true );
1113
0
    sal_Int32 nCount = nRow;
1114
0
    for( sal_Int32 i = 0; i < nRow; i++ )
1115
0
    {
1116
0
        try
1117
0
        {
1118
0
            aSelected[i] = isAccessibleRowSelected( i );
1119
0
        }
1120
0
        catch( ... )
1121
0
        {
1122
0
            return Sequence< sal_Int32 >();
1123
0
        }
1124
1125
0
        if( !aSelected[i] )
1126
0
            nCount--;
1127
0
    }
1128
0
    Sequence < sal_Int32 > aRet( nCount );
1129
0
    sal_Int32 *pRet = aRet.getArray();
1130
0
    sal_Int32 nPos = 0;
1131
0
    size_t nSize = aSelected.size();
1132
0
    for( size_t i=0; i < nSize && nPos < nCount; i++ )
1133
0
    {
1134
0
        if( aSelected[i] )
1135
0
        {
1136
0
            *pRet++ = i;
1137
0
            nPos++;
1138
0
        }
1139
0
    }
1140
1141
0
    return aRet;
1142
0
}
1143
1144
Sequence< sal_Int32 > SAL_CALL AccessibleTableHeaderShape::getSelectedAccessibleColumns(  )
1145
0
{
1146
0
    sal_Int32 nColumn = getAccessibleColumnCount();
1147
0
    ::std::vector<bool> aSelected( nColumn, true );
1148
0
    sal_Int32 nCount = nColumn;
1149
0
    for( sal_Int32 i = 0; i < nColumn; i++ )
1150
0
    {
1151
0
        try
1152
0
        {
1153
0
            aSelected[i] = isAccessibleColumnSelected( i );
1154
0
        }
1155
0
        catch( ... )
1156
0
        {
1157
0
            return Sequence< sal_Int32 >();
1158
0
        }
1159
1160
0
        if( !aSelected[i] )
1161
0
            nCount--;
1162
0
    }
1163
0
    Sequence < sal_Int32 > aRet( nCount );
1164
0
    sal_Int32 *pRet = aRet.getArray();
1165
0
    sal_Int32 nPos = 0;
1166
0
    size_t nSize = aSelected.size();
1167
0
    for( size_t i=0; i < nSize && nPos < nCount; i++ )
1168
0
    {
1169
0
        if( aSelected[i] )
1170
0
        {
1171
0
            *pRet++ = i;
1172
0
            nPos++;
1173
0
        }
1174
0
    }
1175
1176
0
    return aRet;
1177
0
}
1178
1179
sal_Bool SAL_CALL AccessibleTableHeaderShape::isAccessibleRowSelected( sal_Int32 nRow )
1180
0
{
1181
0
    return mpTable->isAccessibleRowSelected( nRow );
1182
0
}
1183
1184
sal_Bool SAL_CALL AccessibleTableHeaderShape::isAccessibleColumnSelected( sal_Int32 nColumn )
1185
0
{
1186
0
    return mpTable->isAccessibleColumnSelected( nColumn );
1187
0
}
1188
1189
Reference< XAccessible > SAL_CALL AccessibleTableHeaderShape::getAccessibleCellAt( sal_Int32 nRow, sal_Int32 nColumn )
1190
0
{
1191
0
    return mpTable->getAccessibleCellAt( nRow, nColumn );
1192
0
}
1193
1194
Reference< XAccessible > SAL_CALL AccessibleTableHeaderShape::getAccessibleCaption(  )
1195
0
{
1196
0
    return mpTable->getAccessibleCaption();
1197
0
}
1198
1199
Reference< XAccessible > SAL_CALL AccessibleTableHeaderShape::getAccessibleSummary(  )
1200
0
{
1201
0
    return mpTable->getAccessibleSummary();
1202
0
}
1203
1204
sal_Bool SAL_CALL AccessibleTableHeaderShape::isAccessibleSelected( sal_Int32 nRow, sal_Int32 nColumn )
1205
0
{
1206
0
    return mpTable->isAccessibleSelected( nRow, nColumn );
1207
0
}
1208
1209
sal_Int64 SAL_CALL AccessibleTableHeaderShape::getAccessibleIndex( sal_Int32 nRow, sal_Int32 nColumn )
1210
0
{
1211
0
    return mpTable->getAccessibleIndex( nRow, nColumn );
1212
0
}
1213
1214
sal_Int32 SAL_CALL AccessibleTableHeaderShape::getAccessibleRow( sal_Int64 nChildIndex )
1215
0
{
1216
0
    return mpTable->getAccessibleRow( nChildIndex );
1217
0
}
1218
1219
sal_Int32 SAL_CALL AccessibleTableHeaderShape::getAccessibleColumn( sal_Int64 nChildIndex )
1220
0
{
1221
0
    return mpTable->getAccessibleColumn( nChildIndex );
1222
0
}
1223
1224
// XAccessibleTableSelection
1225
sal_Bool SAL_CALL AccessibleTableHeaderShape::selectRow( sal_Int32 row )
1226
0
{
1227
0
    if( mbRow )
1228
0
        return mpTable->selectRow( row );
1229
0
    else
1230
0
    {
1231
0
        mpTable->clearAccessibleSelection();
1232
0
        sal_Int64 nIndex = mpTable->getAccessibleIndex( row, 0 );
1233
0
        mpTable->selectAccessibleChild( nIndex );
1234
0
        return true;
1235
0
    }
1236
0
}
1237
1238
sal_Bool SAL_CALL AccessibleTableHeaderShape::selectColumn( sal_Int32 column )
1239
0
{
1240
0
    if( !mbRow )
1241
0
        return mpTable->selectColumn( column );
1242
0
    else
1243
0
    {
1244
0
        mpTable->clearAccessibleSelection();
1245
0
        sal_Int64 nIndex = mpTable->getAccessibleIndex( 0, column );
1246
0
        mpTable->selectAccessibleChild( nIndex );
1247
0
        return true;
1248
0
    }
1249
0
}
1250
1251
sal_Bool SAL_CALL AccessibleTableHeaderShape::unselectRow( sal_Int32 row )
1252
0
{
1253
0
    if( mbRow )
1254
0
        return mpTable->unselectRow( row );
1255
0
    else
1256
0
    {
1257
0
        sal_Int64 nIndex = mpTable->getAccessibleIndex( row, 0 );
1258
0
        mpTable->deselectAccessibleChild( nIndex );
1259
0
        return true;
1260
0
    }
1261
0
}
1262
1263
sal_Bool SAL_CALL AccessibleTableHeaderShape::unselectColumn( sal_Int32 column )
1264
0
{
1265
0
    if( !mbRow )
1266
0
        return mpTable->unselectColumn( column );
1267
0
    else
1268
0
    {
1269
0
        sal_Int64 nIndex = mpTable->getAccessibleIndex( 0, column );
1270
0
        mpTable->deselectAccessibleChild( nIndex );
1271
0
        return true;
1272
0
    }
1273
0
}
1274
}
1275
1276
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */