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>
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
, std::exception
)
67 if ( rType
== cppu::UnoType
<XAccessibleTableSelection
>::get())
69 return uno::Any(uno::Reference
<XAccessibleTableSelection
>(this));
73 uno::Any
aAny (ScAccessibleTableBaseImpl::queryInterface(rType
));
74 return aAny
.hasValue() ? aAny
: ScAccessibleContextBase::queryInterface(rType
);
78 void SAL_CALL
ScAccessibleTableBase::acquire()
81 ScAccessibleContextBase::acquire();
84 void SAL_CALL
ScAccessibleTableBase::release()
87 ScAccessibleContextBase::release();
90 //===== XAccessibleTable ================================================
92 sal_Int32 SAL_CALL
ScAccessibleTableBase::getAccessibleRowCount( )
93 throw (uno::RuntimeException
, std::exception
)
95 SolarMutexGuard aGuard
;
97 return maRange
.aEnd
.Row() - maRange
.aStart
.Row() + 1;
100 sal_Int32 SAL_CALL
ScAccessibleTableBase::getAccessibleColumnCount( )
101 throw (uno::RuntimeException
, std::exception
)
103 SolarMutexGuard aGuard
;
105 return maRange
.aEnd
.Col() - maRange
.aStart
.Col() + 1;
108 OUString SAL_CALL
ScAccessibleTableBase::getAccessibleRowDescription( sal_Int32 nRow
)
109 throw (uno::RuntimeException
, lang::IndexOutOfBoundsException
, std::exception
)
111 OSL_FAIL("Here should be a implementation to fill the description");
113 if ((nRow
> (maRange
.aEnd
.Row() - maRange
.aStart
.Row())) || (nRow
< 0))
114 throw lang::IndexOutOfBoundsException();
116 //setAccessibleRowDescription(nRow, xAccessible); // to remember the created Description
120 OUString SAL_CALL
ScAccessibleTableBase::getAccessibleColumnDescription( sal_Int32 nColumn
)
121 throw (uno::RuntimeException
, lang::IndexOutOfBoundsException
, std::exception
)
123 OSL_FAIL("Here should be a implementation to fill the description");
125 if ((nColumn
> (maRange
.aEnd
.Col() - maRange
.aStart
.Col())) || (nColumn
< 0))
126 throw lang::IndexOutOfBoundsException();
128 //setAccessibleColumnDescription(nColumn, xAccessible); // to remember the created Description
132 sal_Int32 SAL_CALL
ScAccessibleTableBase::getAccessibleRowExtentAt( sal_Int32 nRow
, sal_Int32 nColumn
)
133 throw (uno::RuntimeException
, lang::IndexOutOfBoundsException
, std::exception
)
135 SolarMutexGuard aGuard
;
138 if ((nColumn
> (maRange
.aEnd
.Col() - maRange
.aStart
.Col())) || (nColumn
< 0) ||
139 (nRow
> (maRange
.aEnd
.Row() - maRange
.aStart
.Row())) || (nRow
< 0))
140 throw lang::IndexOutOfBoundsException();
142 sal_Int32
nCount(1); // the same cell
143 nRow
+= maRange
.aStart
.Row();
144 nColumn
+= maRange
.aStart
.Col();
148 ScTable
* pTab
= mpDoc
->FetchTable(maRange
.aStart
.Tab());
151 SCROW nStartRow
= static_cast<SCROW
>(nRow
);
152 SCROW nEndRow
= nStartRow
;
153 SCCOL nStartCol
= static_cast<SCCOL
>(nColumn
);
154 SCCOL nEndCol
= nStartCol
;
155 if (pTab
->ExtendMerge( nStartCol
, nStartRow
, nEndCol
, nEndRow
, false))
157 if (nEndRow
> nStartRow
)
158 nCount
= nEndRow
- nStartRow
+ 1;
166 sal_Int32 SAL_CALL
ScAccessibleTableBase::getAccessibleColumnExtentAt( sal_Int32 nRow
, sal_Int32 nColumn
)
167 throw (uno::RuntimeException
, lang::IndexOutOfBoundsException
, std::exception
)
169 SolarMutexGuard aGuard
;
172 if ((nColumn
> (maRange
.aEnd
.Col() - maRange
.aStart
.Col())) || (nColumn
< 0) ||
173 (nRow
> (maRange
.aEnd
.Row() - maRange
.aStart
.Row())) || (nRow
< 0))
174 throw lang::IndexOutOfBoundsException();
176 sal_Int32
nCount(1); // the same cell
177 nRow
+= maRange
.aStart
.Row();
178 nColumn
+= maRange
.aStart
.Col();
182 ScTable
* pTab
= mpDoc
->FetchTable(maRange
.aStart
.Tab());
185 SCROW nStartRow
= static_cast<SCROW
>(nRow
);
186 SCROW nEndRow
= nStartRow
;
187 SCCOL nStartCol
= static_cast<SCCOL
>(nColumn
);
188 SCCOL nEndCol
= nStartCol
;
189 if (pTab
->ExtendMerge( nStartCol
, nStartRow
, nEndCol
, nEndRow
, false))
191 if (nEndCol
> nStartCol
)
192 nCount
= nEndCol
- nStartCol
+ 1;
200 uno::Reference
< XAccessibleTable
> SAL_CALL
ScAccessibleTableBase::getAccessibleRowHeaders( )
201 throw (uno::RuntimeException
, std::exception
)
203 uno::Reference
< XAccessibleTable
> xAccessibleTable
;
204 OSL_FAIL("Here should be a implementation to fill the row headers");
207 return xAccessibleTable
;
210 uno::Reference
< XAccessibleTable
> SAL_CALL
ScAccessibleTableBase::getAccessibleColumnHeaders( )
211 throw (uno::RuntimeException
, std::exception
)
213 uno::Reference
< XAccessibleTable
> xAccessibleTable
;
214 OSL_FAIL("Here should be a implementation to fill the column headers");
217 return xAccessibleTable
;
220 uno::Sequence
< sal_Int32
> SAL_CALL
ScAccessibleTableBase::getSelectedAccessibleRows( )
221 throw (uno::RuntimeException
, std::exception
)
223 OSL_FAIL("not implemented yet");
224 uno::Sequence
< sal_Int32
> aSequence
;
228 uno::Sequence
< sal_Int32
> SAL_CALL
ScAccessibleTableBase::getSelectedAccessibleColumns( )
229 throw (uno::RuntimeException
, std::exception
)
231 OSL_FAIL("not implemented yet");
232 uno::Sequence
< sal_Int32
> aSequence
;
236 sal_Bool SAL_CALL
ScAccessibleTableBase::isAccessibleRowSelected( sal_Int32
/* nRow */ )
237 throw (uno::RuntimeException
, lang::IndexOutOfBoundsException
, std::exception
)
239 OSL_FAIL("not implemented yet");
243 sal_Bool SAL_CALL
ScAccessibleTableBase::isAccessibleColumnSelected( sal_Int32
/* nColumn */ )
244 throw (uno::RuntimeException
, lang::IndexOutOfBoundsException
, std::exception
)
246 OSL_FAIL("not implemented yet");
250 uno::Reference
< XAccessible
> SAL_CALL
ScAccessibleTableBase::getAccessibleCellAt( sal_Int32
/* nRow */, sal_Int32
/* nColumn */ )
251 throw (uno::RuntimeException
, lang::IndexOutOfBoundsException
, std::exception
)
253 OSL_FAIL("not implemented yet");
254 uno::Reference
< XAccessible
> xAccessible
;
258 uno::Reference
< XAccessible
> SAL_CALL
ScAccessibleTableBase::getAccessibleCaption( )
259 throw (uno::RuntimeException
, std::exception
)
261 OSL_FAIL("not implemented yet");
262 uno::Reference
< XAccessible
> xAccessible
;
266 uno::Reference
< XAccessible
> SAL_CALL
ScAccessibleTableBase::getAccessibleSummary( )
267 throw (uno::RuntimeException
, std::exception
)
269 OSL_FAIL("not implemented yet");
270 uno::Reference
< XAccessible
> xAccessible
;
274 sal_Bool SAL_CALL
ScAccessibleTableBase::isAccessibleSelected( sal_Int32
/* nRow */, sal_Int32
/* nColumn */ )
275 throw (uno::RuntimeException
, lang::IndexOutOfBoundsException
, std::exception
)
277 OSL_FAIL("not implemented yet");
281 // ===== XAccessibleExtendedTable ========================================
283 sal_Int32 SAL_CALL
ScAccessibleTableBase::getAccessibleIndex( sal_Int32 nRow
, sal_Int32 nColumn
)
284 throw (uno::RuntimeException
, lang::IndexOutOfBoundsException
, std::exception
)
286 SolarMutexGuard aGuard
;
289 if (nRow
> (maRange
.aEnd
.Row() - maRange
.aStart
.Row()) ||
291 nColumn
> (maRange
.aEnd
.Col() - maRange
.aStart
.Col()) ||
293 throw lang::IndexOutOfBoundsException();
295 nRow
-= maRange
.aStart
.Row();
296 nColumn
-= maRange
.aStart
.Col();
297 return (nRow
* (maRange
.aEnd
.Col() + 1)) + nColumn
;
300 sal_Int32 SAL_CALL
ScAccessibleTableBase::getAccessibleRow( sal_Int32 nChildIndex
)
301 throw (uno::RuntimeException
, lang::IndexOutOfBoundsException
, std::exception
)
303 SolarMutexGuard aGuard
;
306 if (nChildIndex
>= getAccessibleChildCount() || nChildIndex
< 0)
307 throw lang::IndexOutOfBoundsException();
309 return nChildIndex
/ (maRange
.aEnd
.Col() - maRange
.aStart
.Col() + 1);
312 sal_Int32 SAL_CALL
ScAccessibleTableBase::getAccessibleColumn( sal_Int32 nChildIndex
)
313 throw (uno::RuntimeException
, lang::IndexOutOfBoundsException
, std::exception
)
315 SolarMutexGuard aGuard
;
318 if (nChildIndex
>= getAccessibleChildCount() || nChildIndex
< 0)
319 throw lang::IndexOutOfBoundsException();
321 return nChildIndex
% static_cast<sal_Int32
>(maRange
.aEnd
.Col() - maRange
.aStart
.Col() + 1);
324 // ===== XAccessibleContext ==============================================
326 sal_Int32 SAL_CALL
ScAccessibleTableBase::getAccessibleChildCount()
327 throw (uno::RuntimeException
, std::exception
)
329 SolarMutexGuard aGuard
;
332 // FIXME: representing rows & columns this way is a plain and simple madness.
333 // this needs a radical re-think.
334 sal_Int64 nMax
= ((sal_Int64
)(maRange
.aEnd
.Row() - maRange
.aStart
.Row() + 1) *
335 (sal_Int64
)(maRange
.aEnd
.Col() - maRange
.aStart
.Col() + 1));
336 if (nMax
> SAL_MAX_INT32
)
337 nMax
= SAL_MAX_INT32
;
340 return static_cast<sal_Int32
>(nMax
);
343 uno::Reference
< XAccessible
> SAL_CALL
344 ScAccessibleTableBase::getAccessibleChild(sal_Int32 nIndex
)
345 throw (uno::RuntimeException
,
346 lang::IndexOutOfBoundsException
,
349 SolarMutexGuard aGuard
;
352 if (nIndex
>= getAccessibleChildCount() || nIndex
< 0)
353 throw lang::IndexOutOfBoundsException();
355 // FIXME: representing rows & columns this way is a plain and simple madness.
356 // this needs a radical re-think.
359 sal_Int32
nColumn(0);
360 sal_Int32
nTemp(maRange
.aEnd
.Col() - maRange
.aStart
.Col() + 1);
361 nRow
= nIndex
/ nTemp
;
362 nColumn
= nIndex
% nTemp
;
363 return getAccessibleCellAt(nRow
, nColumn
);
367 ScAccessibleTableBase::createAccessibleDescription()
368 throw (uno::RuntimeException
)
370 OUString
sDesc(ScResId(STR_ACC_TABLE_DESCR
));
374 OUString SAL_CALL
ScAccessibleTableBase::createAccessibleName()
375 throw (uno::RuntimeException
, std::exception
)
377 OUString
sName(SC_RESSTR(STR_ACC_TABLE_NAME
));
379 if (mpDoc
&& mpDoc
->GetName( maRange
.aStart
.Tab(), sCoreName
))
380 sName
= sName
.replaceFirst("%1", sCoreName
);
384 uno::Reference
<XAccessibleRelationSet
> SAL_CALL
385 ScAccessibleTableBase::getAccessibleRelationSet()
386 throw (uno::RuntimeException
, std::exception
)
388 OSL_FAIL("should be implemented in the abrevated class");
389 return uno::Reference
<XAccessibleRelationSet
>();
392 uno::Reference
<XAccessibleStateSet
> SAL_CALL
393 ScAccessibleTableBase::getAccessibleStateSet()
394 throw (uno::RuntimeException
, std::exception
)
396 OSL_FAIL("should be implemented in the abrevated class");
397 uno::Reference
< XAccessibleStateSet
> xAccessibleStateSet
;
398 return xAccessibleStateSet
;
401 ///===== XAccessibleSelection ===========================================
403 void SAL_CALL
ScAccessibleTableBase::selectAccessibleChild( sal_Int32
/* nChildIndex */ )
404 throw (lang::IndexOutOfBoundsException
, uno::RuntimeException
, std::exception
)
409 ScAccessibleTableBase::isAccessibleChildSelected( sal_Int32 nChildIndex
)
410 throw (lang::IndexOutOfBoundsException
, uno::RuntimeException
, std::exception
)
412 // I don't need to guard, because the called functions have a guard
413 if (nChildIndex
< 0 || nChildIndex
>= getAccessibleChildCount())
414 throw lang::IndexOutOfBoundsException();
415 return isAccessibleSelected(getAccessibleRow(nChildIndex
), getAccessibleColumn(nChildIndex
));
419 ScAccessibleTableBase::clearAccessibleSelection( )
420 throw (uno::RuntimeException
, std::exception
)
424 void SAL_CALL
ScAccessibleTableBase::selectAllAccessibleChildren()
425 throw (uno::RuntimeException
, std::exception
)
430 ScAccessibleTableBase::getSelectedAccessibleChildCount( )
431 throw (uno::RuntimeException
, std::exception
)
433 sal_Int32
nResult(0);
437 uno::Reference
<XAccessible
> SAL_CALL
438 ScAccessibleTableBase::getSelectedAccessibleChild( sal_Int32
/* nSelectedChildIndex */ )
439 throw (lang::IndexOutOfBoundsException
, uno::RuntimeException
, std::exception
)
441 uno::Reference
< XAccessible
> xAccessible
;
445 void SAL_CALL
ScAccessibleTableBase::deselectAccessibleChild( sal_Int32
/* nSelectedChildIndex */ )
446 throw (lang::IndexOutOfBoundsException
, uno::RuntimeException
, std::exception
)
450 //===== XServiceInfo ====================================================
452 OUString SAL_CALL
ScAccessibleTableBase::getImplementationName()
453 throw (uno::RuntimeException
, std::exception
)
455 return OUString("ScAccessibleTableBase");
458 //===== XTypeProvider ===================================================
460 uno::Sequence
< uno::Type
> SAL_CALL
ScAccessibleTableBase::getTypes()
461 throw (uno::RuntimeException
, std::exception
)
463 return comphelper::concatSequences(ScAccessibleTableBaseImpl::getTypes(), ScAccessibleContextBase::getTypes());
466 uno::Sequence
<sal_Int8
> SAL_CALL
467 ScAccessibleTableBase::getImplementationId()
468 throw (uno::RuntimeException
, std::exception
)
470 return css::uno::Sequence
<sal_Int8
>();
473 void ScAccessibleTableBase::CommitTableModelChange(sal_Int32 nStartRow
, sal_Int32 nStartCol
, sal_Int32 nEndRow
, sal_Int32 nEndCol
, sal_uInt16 nId
)
475 AccessibleTableModelChange aModelChange
;
476 aModelChange
.FirstRow
= nStartRow
;
477 aModelChange
.FirstColumn
= nStartCol
;
478 aModelChange
.LastRow
= nEndRow
;
479 aModelChange
.LastColumn
= nEndCol
;
480 aModelChange
.Type
= nId
;
482 AccessibleEventObject aEvent
;
483 aEvent
.EventId
= AccessibleEventId::TABLE_MODEL_CHANGED
;
484 aEvent
.Source
= uno::Reference
< XAccessibleContext
>(this);
485 aEvent
.NewValue
<<= aModelChange
;
487 CommitChange(aEvent
);
490 sal_Bool SAL_CALL
ScAccessibleTableBase::selectRow( sal_Int32
)
491 throw (lang::IndexOutOfBoundsException
, uno::RuntimeException
,
497 sal_Bool SAL_CALL
ScAccessibleTableBase::selectColumn( sal_Int32
)
498 throw (lang::IndexOutOfBoundsException
, uno::RuntimeException
,
504 sal_Bool SAL_CALL
ScAccessibleTableBase::unselectRow( sal_Int32
)
505 throw (lang::IndexOutOfBoundsException
, uno::RuntimeException
,
511 sal_Bool SAL_CALL
ScAccessibleTableBase::unselectColumn( sal_Int32
)
512 throw (lang::IndexOutOfBoundsException
, uno::RuntimeException
,
518 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */