1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include "AccessibleTableBase.hxx"
21 #include "miscuno.hxx"
22 #include "document.hxx"
23 #include "scresid.hxx"
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 <comphelper/sequence.hxx>
31 #include <comphelper/servicehelper.hxx>
32 #include <vcl/svapp.hxx>
35 using namespace ::com::sun::star
;
36 using namespace ::com::sun::star::accessibility
;
38 //===== internal ============================================================
40 ScAccessibleTableBase::ScAccessibleTableBase(
41 const uno::Reference
<XAccessible
>& rxParent
,
43 const ScRange
& rRange
)
45 ScAccessibleContextBase (rxParent
, AccessibleRole::TABLE
),
51 ScAccessibleTableBase::~ScAccessibleTableBase()
55 void SAL_CALL
ScAccessibleTableBase::disposing()
57 SolarMutexGuard aGuard
;
60 ScAccessibleContextBase::disposing();
63 //===== XInterface =====================================================
65 uno::Any SAL_CALL
ScAccessibleTableBase::queryInterface( uno::Type
const & rType
)
66 throw (uno::RuntimeException
, std::exception
)
68 if ( rType
== cppu::UnoType
<XAccessibleTableSelection
>::get())
70 return uno::Any(uno::Reference
<XAccessibleTableSelection
>(this));
74 uno::Any
aAny (ScAccessibleTableBaseImpl::queryInterface(rType
));
75 return aAny
.hasValue() ? aAny
: ScAccessibleContextBase::queryInterface(rType
);
79 void SAL_CALL
ScAccessibleTableBase::acquire()
82 ScAccessibleContextBase::acquire();
85 void SAL_CALL
ScAccessibleTableBase::release()
88 ScAccessibleContextBase::release();
91 //===== XAccessibleTable ================================================
93 sal_Int32 SAL_CALL
ScAccessibleTableBase::getAccessibleRowCount( )
94 throw (uno::RuntimeException
, std::exception
)
96 SolarMutexGuard aGuard
;
98 return maRange
.aEnd
.Row() - maRange
.aStart
.Row() + 1;
101 sal_Int32 SAL_CALL
ScAccessibleTableBase::getAccessibleColumnCount( )
102 throw (uno::RuntimeException
, std::exception
)
104 SolarMutexGuard aGuard
;
106 return maRange
.aEnd
.Col() - maRange
.aStart
.Col() + 1;
109 OUString SAL_CALL
ScAccessibleTableBase::getAccessibleRowDescription( sal_Int32 nRow
)
110 throw (uno::RuntimeException
, lang::IndexOutOfBoundsException
, std::exception
)
112 OSL_FAIL("Here should be a implementation to fill the description");
114 if ((nRow
> (maRange
.aEnd
.Row() - maRange
.aStart
.Row())) || (nRow
< 0))
115 throw lang::IndexOutOfBoundsException();
117 //setAccessibleRowDescription(nRow, xAccessible); // to remember the created Description
121 OUString SAL_CALL
ScAccessibleTableBase::getAccessibleColumnDescription( sal_Int32 nColumn
)
122 throw (uno::RuntimeException
, lang::IndexOutOfBoundsException
, std::exception
)
124 OSL_FAIL("Here should be a implementation to fill the description");
126 if ((nColumn
> (maRange
.aEnd
.Col() - maRange
.aStart
.Col())) || (nColumn
< 0))
127 throw lang::IndexOutOfBoundsException();
129 //setAccessibleColumnDescription(nColumn, xAccessible); // to remember the created Description
133 sal_Int32 SAL_CALL
ScAccessibleTableBase::getAccessibleRowExtentAt( sal_Int32 nRow
, sal_Int32 nColumn
)
134 throw (uno::RuntimeException
, lang::IndexOutOfBoundsException
, std::exception
)
136 SolarMutexGuard aGuard
;
139 if ((nColumn
> (maRange
.aEnd
.Col() - maRange
.aStart
.Col())) || (nColumn
< 0) ||
140 (nRow
> (maRange
.aEnd
.Row() - maRange
.aStart
.Row())) || (nRow
< 0))
141 throw lang::IndexOutOfBoundsException();
143 sal_Int32
nCount(1); // the same cell
144 nRow
+= maRange
.aStart
.Row();
145 nColumn
+= maRange
.aStart
.Col();
149 ScTable
* pTab
= mpDoc
->FetchTable(maRange
.aStart
.Tab());
152 SCROW nStartRow
= static_cast<SCROW
>(nRow
);
153 SCROW nEndRow
= nStartRow
;
154 SCCOL nStartCol
= static_cast<SCCOL
>(nColumn
);
155 SCCOL nEndCol
= nStartCol
;
156 if (pTab
->ExtendMerge( nStartCol
, nStartRow
, nEndCol
, nEndRow
, false))
158 if (nEndRow
> nStartRow
)
159 nCount
= nEndRow
- nStartRow
+ 1;
167 sal_Int32 SAL_CALL
ScAccessibleTableBase::getAccessibleColumnExtentAt( sal_Int32 nRow
, sal_Int32 nColumn
)
168 throw (uno::RuntimeException
, lang::IndexOutOfBoundsException
, std::exception
)
170 SolarMutexGuard aGuard
;
173 if ((nColumn
> (maRange
.aEnd
.Col() - maRange
.aStart
.Col())) || (nColumn
< 0) ||
174 (nRow
> (maRange
.aEnd
.Row() - maRange
.aStart
.Row())) || (nRow
< 0))
175 throw lang::IndexOutOfBoundsException();
177 sal_Int32
nCount(1); // the same cell
178 nRow
+= maRange
.aStart
.Row();
179 nColumn
+= maRange
.aStart
.Col();
183 ScTable
* pTab
= mpDoc
->FetchTable(maRange
.aStart
.Tab());
186 SCROW nStartRow
= static_cast<SCROW
>(nRow
);
187 SCROW nEndRow
= nStartRow
;
188 SCCOL nStartCol
= static_cast<SCCOL
>(nColumn
);
189 SCCOL nEndCol
= nStartCol
;
190 if (pTab
->ExtendMerge( nStartCol
, nStartRow
, nEndCol
, nEndRow
, false))
192 if (nEndCol
> nStartCol
)
193 nCount
= nEndCol
- nStartCol
+ 1;
201 uno::Reference
< XAccessibleTable
> SAL_CALL
ScAccessibleTableBase::getAccessibleRowHeaders( )
202 throw (uno::RuntimeException
, std::exception
)
204 uno::Reference
< XAccessibleTable
> xAccessibleTable
;
205 OSL_FAIL("Here should be a implementation to fill the row headers");
208 return xAccessibleTable
;
211 uno::Reference
< XAccessibleTable
> SAL_CALL
ScAccessibleTableBase::getAccessibleColumnHeaders( )
212 throw (uno::RuntimeException
, std::exception
)
214 uno::Reference
< XAccessibleTable
> xAccessibleTable
;
215 OSL_FAIL("Here should be a implementation to fill the column headers");
218 return xAccessibleTable
;
221 uno::Sequence
< sal_Int32
> SAL_CALL
ScAccessibleTableBase::getSelectedAccessibleRows( )
222 throw (uno::RuntimeException
, std::exception
)
224 OSL_FAIL("not implemented yet");
225 uno::Sequence
< sal_Int32
> aSequence
;
229 uno::Sequence
< sal_Int32
> SAL_CALL
ScAccessibleTableBase::getSelectedAccessibleColumns( )
230 throw (uno::RuntimeException
, std::exception
)
232 OSL_FAIL("not implemented yet");
233 uno::Sequence
< sal_Int32
> aSequence
;
237 sal_Bool SAL_CALL
ScAccessibleTableBase::isAccessibleRowSelected( sal_Int32
/* nRow */ )
238 throw (uno::RuntimeException
, lang::IndexOutOfBoundsException
, std::exception
)
240 OSL_FAIL("not implemented yet");
244 sal_Bool SAL_CALL
ScAccessibleTableBase::isAccessibleColumnSelected( sal_Int32
/* nColumn */ )
245 throw (uno::RuntimeException
, lang::IndexOutOfBoundsException
, std::exception
)
247 OSL_FAIL("not implemented yet");
251 uno::Reference
< XAccessible
> SAL_CALL
ScAccessibleTableBase::getAccessibleCellAt( sal_Int32
/* nRow */, sal_Int32
/* nColumn */ )
252 throw (uno::RuntimeException
, lang::IndexOutOfBoundsException
, std::exception
)
254 OSL_FAIL("not implemented yet");
255 uno::Reference
< XAccessible
> xAccessible
;
259 uno::Reference
< XAccessible
> SAL_CALL
ScAccessibleTableBase::getAccessibleCaption( )
260 throw (uno::RuntimeException
, std::exception
)
262 OSL_FAIL("not implemented yet");
263 uno::Reference
< XAccessible
> xAccessible
;
267 uno::Reference
< XAccessible
> SAL_CALL
ScAccessibleTableBase::getAccessibleSummary( )
268 throw (uno::RuntimeException
, std::exception
)
270 OSL_FAIL("not implemented yet");
271 uno::Reference
< XAccessible
> xAccessible
;
275 sal_Bool SAL_CALL
ScAccessibleTableBase::isAccessibleSelected( sal_Int32
/* nRow */, sal_Int32
/* nColumn */ )
276 throw (uno::RuntimeException
, lang::IndexOutOfBoundsException
, std::exception
)
278 OSL_FAIL("not implemented yet");
282 // ===== XAccessibleExtendedTable ========================================
284 sal_Int32 SAL_CALL
ScAccessibleTableBase::getAccessibleIndex( sal_Int32 nRow
, sal_Int32 nColumn
)
285 throw (uno::RuntimeException
, lang::IndexOutOfBoundsException
, std::exception
)
287 SolarMutexGuard aGuard
;
290 if (nRow
> (maRange
.aEnd
.Row() - maRange
.aStart
.Row()) ||
292 nColumn
> (maRange
.aEnd
.Col() - maRange
.aStart
.Col()) ||
294 throw lang::IndexOutOfBoundsException();
296 nRow
-= maRange
.aStart
.Row();
297 nColumn
-= maRange
.aStart
.Col();
298 return (nRow
* (maRange
.aEnd
.Col() + 1)) + nColumn
;
301 sal_Int32 SAL_CALL
ScAccessibleTableBase::getAccessibleRow( sal_Int32 nChildIndex
)
302 throw (uno::RuntimeException
, lang::IndexOutOfBoundsException
, std::exception
)
304 SolarMutexGuard aGuard
;
307 if (nChildIndex
>= getAccessibleChildCount() || nChildIndex
< 0)
308 throw lang::IndexOutOfBoundsException();
310 return nChildIndex
/ (maRange
.aEnd
.Col() - maRange
.aStart
.Col() + 1);
313 sal_Int32 SAL_CALL
ScAccessibleTableBase::getAccessibleColumn( sal_Int32 nChildIndex
)
314 throw (uno::RuntimeException
, lang::IndexOutOfBoundsException
, std::exception
)
316 SolarMutexGuard aGuard
;
319 if (nChildIndex
>= getAccessibleChildCount() || nChildIndex
< 0)
320 throw lang::IndexOutOfBoundsException();
322 return nChildIndex
% static_cast<sal_Int32
>(maRange
.aEnd
.Col() - maRange
.aStart
.Col() + 1);
325 // ===== XAccessibleContext ==============================================
327 sal_Int32 SAL_CALL
ScAccessibleTableBase::getAccessibleChildCount()
328 throw (uno::RuntimeException
, std::exception
)
330 SolarMutexGuard aGuard
;
333 // FIXME: representing rows & columns this way is a plain and simple madness.
334 // this needs a radical re-think.
335 sal_Int64 nMax
= ((sal_Int64
)(maRange
.aEnd
.Row() - maRange
.aStart
.Row() + 1) *
336 (sal_Int64
)(maRange
.aEnd
.Col() - maRange
.aStart
.Col() + 1));
337 if (nMax
> SAL_MAX_INT32
)
338 nMax
= SAL_MAX_INT32
;
341 return static_cast<sal_Int32
>(nMax
);
344 uno::Reference
< XAccessible
> SAL_CALL
345 ScAccessibleTableBase::getAccessibleChild(sal_Int32 nIndex
)
346 throw (uno::RuntimeException
,
347 lang::IndexOutOfBoundsException
,
350 SolarMutexGuard aGuard
;
353 if (nIndex
>= getAccessibleChildCount() || nIndex
< 0)
354 throw lang::IndexOutOfBoundsException();
356 // FIXME: representing rows & columns this way is a plain and simple madness.
357 // this needs a radical re-think.
360 sal_Int32
nColumn(0);
361 sal_Int32
nTemp(maRange
.aEnd
.Col() - maRange
.aStart
.Col() + 1);
362 nRow
= nIndex
/ nTemp
;
363 nColumn
= nIndex
% nTemp
;
364 return getAccessibleCellAt(nRow
, nColumn
);
368 ScAccessibleTableBase::createAccessibleDescription(void)
369 throw (uno::RuntimeException
)
371 OUString
sDesc(ScResId(STR_ACC_TABLE_DESCR
));
375 OUString SAL_CALL
ScAccessibleTableBase::createAccessibleName()
376 throw (uno::RuntimeException
, std::exception
)
378 OUString
sName(SC_RESSTR(STR_ACC_TABLE_NAME
));
380 if (mpDoc
&& mpDoc
->GetName( maRange
.aStart
.Tab(), sCoreName
))
381 sName
= sName
.replaceFirst("%1", sCoreName
);
385 uno::Reference
<XAccessibleRelationSet
> SAL_CALL
386 ScAccessibleTableBase::getAccessibleRelationSet(void)
387 throw (uno::RuntimeException
, std::exception
)
389 OSL_FAIL("should be implemented in the abrevated class");
390 return uno::Reference
<XAccessibleRelationSet
>();
393 uno::Reference
<XAccessibleStateSet
> SAL_CALL
394 ScAccessibleTableBase::getAccessibleStateSet(void)
395 throw (uno::RuntimeException
, std::exception
)
397 OSL_FAIL("should be implemented in the abrevated class");
398 uno::Reference
< XAccessibleStateSet
> xAccessibleStateSet
;
399 return xAccessibleStateSet
;
402 ///===== XAccessibleSelection ===========================================
404 void SAL_CALL
ScAccessibleTableBase::selectAccessibleChild( sal_Int32
/* nChildIndex */ )
405 throw (lang::IndexOutOfBoundsException
, uno::RuntimeException
, std::exception
)
410 ScAccessibleTableBase::isAccessibleChildSelected( sal_Int32 nChildIndex
)
411 throw (lang::IndexOutOfBoundsException
, uno::RuntimeException
, std::exception
)
413 // I don't need to guard, because the called functions have a guard
414 if (nChildIndex
< 0 || nChildIndex
>= getAccessibleChildCount())
415 throw lang::IndexOutOfBoundsException();
416 return isAccessibleSelected(getAccessibleRow(nChildIndex
), getAccessibleColumn(nChildIndex
));
420 ScAccessibleTableBase::clearAccessibleSelection( )
421 throw (uno::RuntimeException
, std::exception
)
425 void SAL_CALL
ScAccessibleTableBase::selectAllAccessibleChildren()
426 throw (uno::RuntimeException
, std::exception
)
431 ScAccessibleTableBase::getSelectedAccessibleChildCount( )
432 throw (uno::RuntimeException
, std::exception
)
434 sal_Int32
nResult(0);
438 uno::Reference
<XAccessible
> SAL_CALL
439 ScAccessibleTableBase::getSelectedAccessibleChild( sal_Int32
/* nSelectedChildIndex */ )
440 throw (lang::IndexOutOfBoundsException
, uno::RuntimeException
, std::exception
)
442 uno::Reference
< XAccessible
> xAccessible
;
446 void SAL_CALL
ScAccessibleTableBase::deselectAccessibleChild( sal_Int32
/* nSelectedChildIndex */ )
447 throw (lang::IndexOutOfBoundsException
, uno::RuntimeException
, std::exception
)
451 //===== XServiceInfo ====================================================
453 OUString SAL_CALL
ScAccessibleTableBase::getImplementationName(void)
454 throw (uno::RuntimeException
, std::exception
)
456 return OUString("ScAccessibleTableBase");
459 //===== XTypeProvider ===================================================
461 uno::Sequence
< uno::Type
> SAL_CALL
ScAccessibleTableBase::getTypes()
462 throw (uno::RuntimeException
, std::exception
)
464 return comphelper::concatSequences(ScAccessibleTableBaseImpl::getTypes(), ScAccessibleContextBase::getTypes());
467 uno::Sequence
<sal_Int8
> SAL_CALL
468 ScAccessibleTableBase::getImplementationId(void)
469 throw (uno::RuntimeException
, std::exception
)
471 return css::uno::Sequence
<sal_Int8
>();
474 void ScAccessibleTableBase::CommitTableModelChange(sal_Int32 nStartRow
, sal_Int32 nStartCol
, sal_Int32 nEndRow
, sal_Int32 nEndCol
, sal_uInt16 nId
)
476 AccessibleTableModelChange aModelChange
;
477 aModelChange
.FirstRow
= nStartRow
;
478 aModelChange
.FirstColumn
= nStartCol
;
479 aModelChange
.LastRow
= nEndRow
;
480 aModelChange
.LastColumn
= nEndCol
;
481 aModelChange
.Type
= nId
;
483 AccessibleEventObject aEvent
;
484 aEvent
.EventId
= AccessibleEventId::TABLE_MODEL_CHANGED
;
485 aEvent
.Source
= uno::Reference
< XAccessibleContext
>(this);
486 aEvent
.NewValue
<<= aModelChange
;
488 CommitChange(aEvent
);
491 sal_Bool SAL_CALL
ScAccessibleTableBase::selectRow( sal_Int32
)
492 throw (lang::IndexOutOfBoundsException
, uno::RuntimeException
,
498 sal_Bool SAL_CALL
ScAccessibleTableBase::selectColumn( sal_Int32
)
499 throw (lang::IndexOutOfBoundsException
, uno::RuntimeException
,
505 sal_Bool SAL_CALL
ScAccessibleTableBase::unselectRow( sal_Int32
)
506 throw (lang::IndexOutOfBoundsException
, uno::RuntimeException
,
512 sal_Bool SAL_CALL
ScAccessibleTableBase::unselectColumn( sal_Int32
)
513 throw (lang::IndexOutOfBoundsException
, uno::RuntimeException
,
519 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */