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"
26 #include <com/sun/star/accessibility/AccessibleRole.hpp>
27 #include <com/sun/star/accessibility/AccessibleTableModelChange.hpp>
28 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
29 #include <comphelper/sequence.hxx>
30 #include <comphelper/servicehelper.hxx>
31 #include <vcl/svapp.hxx>
34 using namespace ::com::sun::star
;
35 using namespace ::com::sun::star::accessibility
;
37 //===== internal ============================================================
39 ScAccessibleTableBase::ScAccessibleTableBase(
40 const uno::Reference
<XAccessible
>& rxParent
,
42 const ScRange
& rRange
)
44 ScAccessibleContextBase (rxParent
, AccessibleRole::TABLE
),
50 ScAccessibleTableBase::~ScAccessibleTableBase()
54 void SAL_CALL
ScAccessibleTableBase::disposing()
56 SolarMutexGuard aGuard
;
59 ScAccessibleContextBase::disposing();
62 //===== XInterface =====================================================
64 uno::Any SAL_CALL
ScAccessibleTableBase::queryInterface( uno::Type
const & rType
)
65 throw (uno::RuntimeException
)
67 uno::Any
aAny (ScAccessibleTableBaseImpl::queryInterface(rType
));
68 return aAny
.hasValue() ? aAny
: ScAccessibleContextBase::queryInterface(rType
);
71 void SAL_CALL
ScAccessibleTableBase::acquire()
74 ScAccessibleContextBase::acquire();
77 void SAL_CALL
ScAccessibleTableBase::release()
80 ScAccessibleContextBase::release();
83 //===== XAccessibleTable ================================================
85 sal_Int32 SAL_CALL
ScAccessibleTableBase::getAccessibleRowCount( )
86 throw (uno::RuntimeException
)
88 SolarMutexGuard aGuard
;
90 return maRange
.aEnd
.Row() - maRange
.aStart
.Row() + 1;
93 sal_Int32 SAL_CALL
ScAccessibleTableBase::getAccessibleColumnCount( )
94 throw (uno::RuntimeException
)
96 SolarMutexGuard aGuard
;
98 return maRange
.aEnd
.Col() - maRange
.aStart
.Col() + 1;
101 OUString SAL_CALL
ScAccessibleTableBase::getAccessibleRowDescription( sal_Int32 nRow
)
102 throw (uno::RuntimeException
, lang::IndexOutOfBoundsException
)
104 OSL_FAIL("Here should be a implementation to fill the description");
106 if ((nRow
> (maRange
.aEnd
.Row() - maRange
.aStart
.Row())) || (nRow
< 0))
107 throw lang::IndexOutOfBoundsException();
109 //setAccessibleRowDescription(nRow, xAccessible); // to remember the created Description
113 OUString SAL_CALL
ScAccessibleTableBase::getAccessibleColumnDescription( sal_Int32 nColumn
)
114 throw (uno::RuntimeException
, lang::IndexOutOfBoundsException
)
116 OSL_FAIL("Here should be a implementation to fill the description");
118 if ((nColumn
> (maRange
.aEnd
.Col() - maRange
.aStart
.Col())) || (nColumn
< 0))
119 throw lang::IndexOutOfBoundsException();
121 //setAccessibleColumnDescription(nColumn, xAccessible); // to remember the created Description
125 sal_Int32 SAL_CALL
ScAccessibleTableBase::getAccessibleRowExtentAt( sal_Int32 nRow
, sal_Int32 nColumn
)
126 throw (uno::RuntimeException
, lang::IndexOutOfBoundsException
)
128 SolarMutexGuard aGuard
;
131 if ((nColumn
> (maRange
.aEnd
.Col() - maRange
.aStart
.Col())) || (nColumn
< 0) ||
132 (nRow
> (maRange
.aEnd
.Row() - maRange
.aStart
.Row())) || (nRow
< 0))
133 throw lang::IndexOutOfBoundsException();
135 sal_Int32
nCount(1); // the same cell
136 nRow
+= maRange
.aStart
.Row();
137 nColumn
+= maRange
.aStart
.Col();
143 if (mpDoc
->ExtendMerge(static_cast<SCCOL
>(nColumn
), static_cast<SCROW
>(nRow
),
144 nEndCol
, nEndRow
, maRange
.aStart
.Tab()))
147 nCount
= nEndRow
- nRow
+ 1;
154 sal_Int32 SAL_CALL
ScAccessibleTableBase::getAccessibleColumnExtentAt( sal_Int32 nRow
, sal_Int32 nColumn
)
155 throw (uno::RuntimeException
, lang::IndexOutOfBoundsException
)
157 SolarMutexGuard aGuard
;
160 if ((nColumn
> (maRange
.aEnd
.Col() - maRange
.aStart
.Col())) || (nColumn
< 0) ||
161 (nRow
> (maRange
.aEnd
.Row() - maRange
.aStart
.Row())) || (nRow
< 0))
162 throw lang::IndexOutOfBoundsException();
164 sal_Int32
nCount(1); // the same cell
165 nRow
+= maRange
.aStart
.Row();
166 nColumn
+= maRange
.aStart
.Col();
172 if (mpDoc
->ExtendMerge(static_cast<SCCOL
>(nColumn
), static_cast<SCROW
>(nRow
),
173 nEndCol
, nEndRow
, maRange
.aStart
.Tab()))
175 if (nEndCol
> nColumn
)
176 nCount
= nEndCol
- nColumn
+ 1;
183 uno::Reference
< XAccessibleTable
> SAL_CALL
ScAccessibleTableBase::getAccessibleRowHeaders( )
184 throw (uno::RuntimeException
)
186 uno::Reference
< XAccessibleTable
> xAccessibleTable
;
187 OSL_FAIL("Here should be a implementation to fill the row headers");
190 return xAccessibleTable
;
193 uno::Reference
< XAccessibleTable
> SAL_CALL
ScAccessibleTableBase::getAccessibleColumnHeaders( )
194 throw (uno::RuntimeException
)
196 uno::Reference
< XAccessibleTable
> xAccessibleTable
;
197 OSL_FAIL("Here should be a implementation to fill the column headers");
200 return xAccessibleTable
;
203 uno::Sequence
< sal_Int32
> SAL_CALL
ScAccessibleTableBase::getSelectedAccessibleRows( )
204 throw (uno::RuntimeException
)
206 OSL_FAIL("not implemented yet");
207 uno::Sequence
< sal_Int32
> aSequence
;
211 uno::Sequence
< sal_Int32
> SAL_CALL
ScAccessibleTableBase::getSelectedAccessibleColumns( )
212 throw (uno::RuntimeException
)
214 OSL_FAIL("not implemented yet");
215 uno::Sequence
< sal_Int32
> aSequence
;
219 sal_Bool SAL_CALL
ScAccessibleTableBase::isAccessibleRowSelected( sal_Int32
/* nRow */ )
220 throw (uno::RuntimeException
, lang::IndexOutOfBoundsException
)
222 OSL_FAIL("not implemented yet");
226 sal_Bool SAL_CALL
ScAccessibleTableBase::isAccessibleColumnSelected( sal_Int32
/* nColumn */ )
227 throw (uno::RuntimeException
, lang::IndexOutOfBoundsException
)
229 OSL_FAIL("not implemented yet");
233 uno::Reference
< XAccessible
> SAL_CALL
ScAccessibleTableBase::getAccessibleCellAt( sal_Int32
/* nRow */, sal_Int32
/* nColumn */ )
234 throw (uno::RuntimeException
, lang::IndexOutOfBoundsException
)
236 OSL_FAIL("not implemented yet");
237 uno::Reference
< XAccessible
> xAccessible
;
241 uno::Reference
< XAccessible
> SAL_CALL
ScAccessibleTableBase::getAccessibleCaption( )
242 throw (uno::RuntimeException
)
244 OSL_FAIL("not implemented yet");
245 uno::Reference
< XAccessible
> xAccessible
;
249 uno::Reference
< XAccessible
> SAL_CALL
ScAccessibleTableBase::getAccessibleSummary( )
250 throw (uno::RuntimeException
)
252 OSL_FAIL("not implemented yet");
253 uno::Reference
< XAccessible
> xAccessible
;
257 sal_Bool SAL_CALL
ScAccessibleTableBase::isAccessibleSelected( sal_Int32
/* nRow */, sal_Int32
/* nColumn */ )
258 throw (uno::RuntimeException
, lang::IndexOutOfBoundsException
)
260 OSL_FAIL("not implemented yet");
264 // ===== XAccessibleExtendedTable ========================================
266 sal_Int32 SAL_CALL
ScAccessibleTableBase::getAccessibleIndex( sal_Int32 nRow
, sal_Int32 nColumn
)
267 throw (uno::RuntimeException
, lang::IndexOutOfBoundsException
)
269 SolarMutexGuard aGuard
;
272 if (nRow
> (maRange
.aEnd
.Row() - maRange
.aStart
.Row()) ||
274 nColumn
> (maRange
.aEnd
.Col() - maRange
.aStart
.Col()) ||
276 throw lang::IndexOutOfBoundsException();
278 nRow
-= maRange
.aStart
.Row();
279 nColumn
-= maRange
.aStart
.Col();
280 return (nRow
* (maRange
.aEnd
.Col() + 1)) + nColumn
;
283 sal_Int32 SAL_CALL
ScAccessibleTableBase::getAccessibleRow( sal_Int32 nChildIndex
)
284 throw (uno::RuntimeException
, lang::IndexOutOfBoundsException
)
286 SolarMutexGuard aGuard
;
289 if (nChildIndex
>= getAccessibleChildCount() || nChildIndex
< 0)
290 throw lang::IndexOutOfBoundsException();
292 return nChildIndex
/ (maRange
.aEnd
.Col() - maRange
.aStart
.Col() + 1);
295 sal_Int32 SAL_CALL
ScAccessibleTableBase::getAccessibleColumn( sal_Int32 nChildIndex
)
296 throw (uno::RuntimeException
, lang::IndexOutOfBoundsException
)
298 SolarMutexGuard aGuard
;
301 if (nChildIndex
>= getAccessibleChildCount() || nChildIndex
< 0)
302 throw lang::IndexOutOfBoundsException();
304 return nChildIndex
% static_cast<sal_Int32
>(maRange
.aEnd
.Col() - maRange
.aStart
.Col() + 1);
307 // ===== XAccessibleContext ==============================================
310 ScAccessibleTableBase::getAccessibleChildCount(void)
311 throw (uno::RuntimeException
)
313 SolarMutexGuard aGuard
;
316 // FIXME: representing rows & columns this way is a plain and simple madness.
317 // this needs a radical re-think.
318 sal_Int64 nMax
= ((sal_Int64
)(maRange
.aEnd
.Row() - maRange
.aStart
.Row() + 1) *
319 (sal_Int64
)(maRange
.aEnd
.Col() - maRange
.aStart
.Col() + 1));
320 if (nMax
> SAL_MAX_INT32
)
321 nMax
= SAL_MAX_INT32
;
324 return static_cast<sal_Int32
>(nMax
);
327 uno::Reference
< XAccessible
> SAL_CALL
328 ScAccessibleTableBase::getAccessibleChild(sal_Int32 nIndex
)
329 throw (uno::RuntimeException
,
330 lang::IndexOutOfBoundsException
)
332 SolarMutexGuard aGuard
;
335 if (nIndex
>= getAccessibleChildCount() || nIndex
< 0)
336 throw lang::IndexOutOfBoundsException();
338 // FIXME: representing rows & columns this way is a plain and simple madness.
339 // this needs a radical re-think.
342 sal_Int32
nColumn(0);
343 sal_Int32
nTemp(maRange
.aEnd
.Col() - maRange
.aStart
.Col() + 1);
344 nRow
= nIndex
/ nTemp
;
345 nColumn
= nIndex
% nTemp
;
346 return getAccessibleCellAt(nRow
, nColumn
);
350 ScAccessibleTableBase::createAccessibleDescription(void)
351 throw (uno::RuntimeException
)
353 String
sDesc(ScResId(STR_ACC_TABLE_DESCR
));
354 return OUString(sDesc
);
358 ScAccessibleTableBase::createAccessibleName(void)
359 throw (uno::RuntimeException
)
361 String
sName(ScResId(STR_ACC_TABLE_NAME
));
363 if (mpDoc
&& mpDoc
->GetName( maRange
.aStart
.Tab(), sCoreName
))
364 sName
.SearchAndReplaceAscii("%1", sCoreName
);
365 return OUString(sName
);
368 uno::Reference
<XAccessibleRelationSet
> SAL_CALL
369 ScAccessibleTableBase::getAccessibleRelationSet(void)
370 throw (uno::RuntimeException
)
372 OSL_FAIL("should be implemented in the abrevated class");
373 return uno::Reference
<XAccessibleRelationSet
>();
376 uno::Reference
<XAccessibleStateSet
> SAL_CALL
377 ScAccessibleTableBase::getAccessibleStateSet(void)
378 throw (uno::RuntimeException
)
380 OSL_FAIL("should be implemented in the abrevated class");
381 uno::Reference
< XAccessibleStateSet
> xAccessibleStateSet
;
382 return xAccessibleStateSet
;
385 ///===== XAccessibleSelection ===========================================
388 ScAccessibleTableBase::selectAccessibleChild( sal_Int32
/* nChildIndex */ )
389 throw (lang::IndexOutOfBoundsException
, uno::RuntimeException
)
394 ScAccessibleTableBase::isAccessibleChildSelected( sal_Int32 nChildIndex
)
395 throw (lang::IndexOutOfBoundsException
, uno::RuntimeException
)
397 // I don't need to guard, because the called functions have a guard
398 if (nChildIndex
< 0 || nChildIndex
>= getAccessibleChildCount())
399 throw lang::IndexOutOfBoundsException();
400 return isAccessibleSelected(getAccessibleRow(nChildIndex
), getAccessibleColumn(nChildIndex
));
404 ScAccessibleTableBase::clearAccessibleSelection( )
405 throw (uno::RuntimeException
)
410 ScAccessibleTableBase::selectAllAccessibleChildren( )
411 throw (uno::RuntimeException
)
416 ScAccessibleTableBase::getSelectedAccessibleChildCount( )
417 throw (uno::RuntimeException
)
419 sal_Int32
nResult(0);
423 uno::Reference
<XAccessible
> SAL_CALL
424 ScAccessibleTableBase::getSelectedAccessibleChild( sal_Int32
/* nSelectedChildIndex */ )
425 throw (lang::IndexOutOfBoundsException
, uno::RuntimeException
)
427 uno::Reference
< XAccessible
> xAccessible
;
432 ScAccessibleTableBase::deselectAccessibleChild( sal_Int32
/* nSelectedChildIndex */ )
433 throw (lang::IndexOutOfBoundsException
, uno::RuntimeException
)
437 //===== XServiceInfo ====================================================
439 OUString SAL_CALL
ScAccessibleTableBase::getImplementationName(void)
440 throw (uno::RuntimeException
)
442 return OUString("ScAccessibleTableBase");
445 //===== XTypeProvider ===================================================
447 uno::Sequence
< uno::Type
> SAL_CALL
ScAccessibleTableBase::getTypes()
448 throw (uno::RuntimeException
)
450 return comphelper::concatSequences(ScAccessibleTableBaseImpl::getTypes(), ScAccessibleContextBase::getTypes());
455 class theScAccessibleTableBaseImplementationId
: public rtl::Static
< UnoTunnelIdInit
, theScAccessibleTableBaseImplementationId
> {};
458 uno::Sequence
<sal_Int8
> SAL_CALL
459 ScAccessibleTableBase::getImplementationId(void)
460 throw (uno::RuntimeException
)
462 return theScAccessibleTableBaseImplementationId::get().getSeq();
465 void ScAccessibleTableBase::CommitTableModelChange(sal_Int32 nStartRow
, sal_Int32 nStartCol
, sal_Int32 nEndRow
, sal_Int32 nEndCol
, sal_uInt16 nId
)
467 AccessibleTableModelChange aModelChange
;
468 aModelChange
.FirstRow
= nStartRow
;
469 aModelChange
.FirstColumn
= nStartCol
;
470 aModelChange
.LastRow
= nEndRow
;
471 aModelChange
.LastColumn
= nEndCol
;
472 aModelChange
.Type
= nId
;
474 AccessibleEventObject aEvent
;
475 aEvent
.EventId
= AccessibleEventId::TABLE_MODEL_CHANGED
;
476 aEvent
.Source
= uno::Reference
< XAccessibleContext
>(this);
477 aEvent
.NewValue
<<= aModelChange
;
479 CommitChange(aEvent
);
482 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */