/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This file incorporates work covered by the following license notice: * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed * with this work for additional information regarding copyright * ownership. The ASF licenses this file to you under the Apache * License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
struct ScAccessibleShapeData
{
ScAccessibleShapeData(css::uno::Reference< css::drawing::XShape > xShape_);
~ScAccessibleShapeData(); mutable rtl::Reference< ::accessibility::AccessibleShape > pAccShape;
std::optional<ScAddress> xRelationCell; // if it is NULL this shape is anchored on the table
css::uno::Reference< css::drawing::XShape > xShape; bool bSelected; bool bSelectable; // cache these to make the sorting cheaper
std::optional<sal_Int16> mxLayerID;
std::optional<sal_Int32> mxZOrder;
};
// gets the index of the shape starting on 0 (without the index of the table) // returns the selected shape bool IsSelected(sal_Int32 nIndex,
css::uno::Reference<css::drawing::XShape>& rShape) const;
mutable SortedShapes maZOrderedShapes; // a null pointer represents the sheet in the correct order mutable ShapesMap maShapesMap; mutablebool mbShapesNeedSorting; // set if maZOrderedShapes needs sorting
maZOrderedShapes.push_back(nullptr); // add an element which represents the table
GetCount(); // fill list with filtered shapes (no internal shapes)
if (mnShapesSelected)
{ //set flag on every selected shape if (!xSelectionSupplier.is()) throw uno::RuntimeException("Could not get selected shapes. Null reference to xSelectionSupplier in ScChildrenShapes::ScChildrenShapes.");
uno::Reference<drawing::XShapes> xShapes(mpViewShell->getSelectedXShapes()); if (xShapes.is())
FindSelectedShapesChanges(xShapes);
} if (!pViewShell) return;
SdrObject* pObj = const_cast<SdrObject*>(pSdrHint->GetObject()); if (!(pObj && /*(pObj->GetLayer() != SC_LAYER_INTERN) && */(pObj->getSdrPageFromSdrObject() == GetDrawPage()) &&
(pObj->getSdrPageFromSdrObject() == pObj->getParentSdrObjListFromSdrObject())) ) //only do something if the object lies direct on the page return;
switch (pSdrHint->GetKind())
{ case SdrHintKind::ObjectChange : // object changed
{
uno::Reference<drawing::XShape> xShape (pObj->getUnoShape(), uno::UNO_QUERY); if (xShape.is())
{
mbShapesNeedSorting = true; // sort, because the z index or layer could be changed auto it = maShapesMap.find(xShape); if (it != maShapesMap.end())
SetAnchor(xShape, it->second);
}
} break; case SdrHintKind::ObjectInserted : // new drawing object inserted
{
uno::Reference<drawing::XShape> xShape (pObj->getUnoShape(), uno::UNO_QUERY); if (xShape.is())
AddShape(xShape, true);
} break; case SdrHintKind::ObjectRemoved : // Removed drawing object from list
{
uno::Reference<drawing::XShape> xShape (pObj->getUnoShape(), uno::UNO_QUERY); if (xShape.is())
RemoveShape(xShape);
} break; default :
{ // other events are not interesting
} break;
}
}
bool bResult(false); if (pReplacement.is())
{
OSL_ENSURE(pCurrentChild->GetXShape().get() == pReplacement->GetXShape().get(), "XShape changes and should be inserted sorted"); auto it = maShapesMap.find(pCurrentChild->GetXShape()); if (it != maShapesMap.end() && it->second->pAccShape.is())
{
OSL_ENSURE(it->second->pAccShape == pCurrentChild, "wrong child found"); // child is gone - event
mpAccessibleDocument->CommitChange(AccessibleEventId::CHILD,
uno::Any(uno::Reference<XAccessible>(pCurrentChild)),
uno::Any());
pCurrentChild->dispose();
}
// Init after above possible pCurrentChild->dispose so we don't trigger the assert // ScDrawModelBroadcaster::addShapeEventListener of duplicate listeners
pReplacement->Init();
if (it != maShapesMap.end())
{
it->second->pAccShape = pReplacement; // child is new - event
mpAccessibleDocument->CommitChange(AccessibleEventId::CHILD, uno::Any(),
uno::Any(uno::Reference<XAccessible>(pReplacement)));
bResult = true;
}
} return bResult;
}
::accessibility::AccessibleShape*
ScChildrenShapes::GetAccessibleCaption (const css::uno::Reference < css::drawing::XShape>& xShape)
{
GetCount(); // populate auto it = maShapesMap.find(xShape); if (it == maShapesMap.end()) return nullptr;
ScAccessibleShapeData* pShape = it->second; return pShape->pAccShape.get();
}
sal_Int32 ScChildrenShapes::GetCount() const
{
SdrPage* pDrawPage = GetDrawPage(); if (pDrawPage && (maZOrderedShapes.size() == 1)) // the table is always in
{
size_t nSdrObjCount = pDrawPage->GetObjCount();
maZOrderedShapes.reserve(nSdrObjCount + 1); // the table is always in for (const rtl::Reference<SdrObject>& pObj : *pDrawPage)
{
uno::Reference< drawing::XShape > xShape (pObj->getUnoShape(), uno::UNO_QUERY);
AddShape(xShape, false); //inserts in the correct order
}
} return maZOrderedShapes.size();
}
rtl::Reference<::accessibility::AccessibleShape>
ScChildrenShapes::Get(const ScAccessibleShapeData* pData) const
{ if (!pData) return nullptr;
if (!pData->pAccShape.is())
{
::accessibility::ShapeTypeHandler& rShapeHandler = ::accessibility::ShapeTypeHandler::Instance();
::accessibility::AccessibleShapeInfo aShapeInfo(pData->xShape, mpAccessibleDocument, const_cast<ScChildrenShapes*>(this));
pData->pAccShape = rShapeHandler.CreateAccessibleObject(
aShapeInfo, maShapeTreeInfo); if (pData->pAccShape.is())
{
pData->pAccShape->Init(); if (pData->bSelected)
pData->pAccShape->SetState(AccessibleStateType::SELECTED); if (!pData->bSelectable)
pData->pAccShape->ResetState(AccessibleStateType::SELECTABLE);
pData->pAccShape->SetRelationSet(GetRelationSet(pData));
}
} return pData->pAccShape;
}
rtl::Reference<::accessibility::AccessibleShape> ScChildrenShapes::Get(sal_Int32 nIndex) const
{ if (maZOrderedShapes.size() <= 1)
GetCount(); // fill list with filtered shapes (no internal shapes)
if (mbShapesNeedSorting)
{
std::sort(maZOrderedShapes.begin(), maZOrderedShapes.end(), ScShapeDataLess());
mbShapesNeedSorting = false;
}
if (o3tl::make_unsigned(nIndex) >= maZOrderedShapes.size()) return nullptr;
sal_Int32 i(maZOrderedShapes.size() - 1); bool bFound(false); while (!bFound && i >= 0)
{
ScAccessibleShapeData* pShape = maZOrderedShapes[i]; if (pShape)
{ if (!pShape->pAccShape.is())
Get(pShape);
if (pShape->pAccShape.is())
{
Point aPoint(vcl::unohelper::ConvertToVCLPoint(rPoint));
aPoint
-= vcl::unohelper::ConvertToVCLRect(pShape->pAccShape->getBounds()).TopLeft(); if (pShape->pAccShape->containsPoint(vcl::unohelper::ConvertToAWTPoint(aPoint)))
{
xAccessible = pShape->pAccShape.get();
bFound = true;
}
} else
{
OSL_FAIL("I should have an accessible shape now!");
}
} else
bFound = true; // this is the sheet and it lies before the rest of the shapes which are background shapes
--i;
}
} return xAccessible;
}
bool ScChildrenShapes::IsSelected(sal_Int32 nIndex,
uno::Reference<drawing::XShape>& rShape) const
{ bool bResult (false); if (maZOrderedShapes.size() <= 1)
GetCount(); // fill list with filtered shapes (no internal shapes)
if (!xSelectionSupplier.is()) throw uno::RuntimeException("Could not get selected shapes. Null reference to xSelectionSupplier in ScChildrenShapes::IsSelected.");
if (mbShapesNeedSorting)
{
std::sort(maZOrderedShapes.begin(), maZOrderedShapes.end(), ScShapeDataLess());
mbShapesNeedSorting = false;
}
#if OSL_DEBUG_LEVEL > 0 // test whether it is truly selected by a slower method
uno::Reference< drawing::XShape > xReturnShape; bool bDebugResult(false);
uno::Reference<drawing::XShapes> xShapes(mpViewShell->getSelectedXShapes());
if (xShapes.is())
{
sal_Int32 nCount(xShapes->getCount()); if (nCount)
{
uno::Reference< drawing::XShape > xShape;
uno::Reference< drawing::XShape > xIndexShape = maZOrderedShapes[nIndex]->xShape;
sal_Int32 i(0); while (!bDebugResult && (i < nCount))
{
xShapes->getByIndex(i) >>= xShape; if (xShape.is() && (xIndexShape.get() == xShape.get()))
{
bDebugResult = true;
xReturnShape = xShape;
} else
++i;
}
}
}
OSL_ENSURE((bResult == bDebugResult) && ((bResult && (rShape.get() == xReturnShape.get())) || !bResult), "found the wrong shape or result"); #endif
return bResult;
}
bool ScChildrenShapes::SelectionChanged()
{ bool bResult(false); if (!xSelectionSupplier.is()) throw uno::RuntimeException("Could not get selected shapes. Null reference to xSelectionSupplier in ScChildrenShapes::SelectionChanged.");
void ScChildrenShapes::Select(sal_Int32 nIndex)
{ if (maZOrderedShapes.size() <= 1)
GetCount(); // fill list with filtered shapes (no internal shapes)
if (!xSelectionSupplier.is()) throw uno::RuntimeException("Could not get selected shapes. Null reference to xSelectionSupplier in ScChildrenShapes::Select.");
if (mbShapesNeedSorting)
{
std::sort(maZOrderedShapes.begin(), maZOrderedShapes.end(), ScShapeDataLess());
mbShapesNeedSorting = false;
}
if (!maZOrderedShapes[nIndex]) return;
uno::Reference<drawing::XShape> xShape; if (IsSelected(nIndex, xShape) || !maZOrderedShapes[nIndex]->bSelectable) return;
void ScChildrenShapes::DeselectAll()
{ if (!xSelectionSupplier.is()) throw uno::RuntimeException("Could not get selected shapes. Null reference to xSelectionSupplier in ScChildrenShapes::DeselectAll.");
if (bSomethingSelected) for (ScAccessibleShapeData* pAccShapeData : maZOrderedShapes) if (pAccShapeData)
{
pAccShapeData->bSelected = false; if (pAccShapeData->pAccShape.is())
pAccShapeData->pAccShape->ResetState(AccessibleStateType::SELECTED);
}
};
void ScChildrenShapes::SelectAll()
{ if (!xSelectionSupplier.is()) throw uno::RuntimeException("Could not get selected shapes. Null reference to xSelectionSupplier in ScChildrenShapes::SelectAll.");
if (maZOrderedShapes.size() <= 1)
GetCount(); // fill list with filtered shapes (no internal shapes)
try
{ for (ScAccessibleShapeData* pAccShapeData : maZOrderedShapes)
{ if (pAccShapeData && pAccShapeData->bSelectable)
{
pAccShapeData->bSelected = true; if (pAccShapeData->pAccShape.is())
pAccShapeData->pAccShape->SetState(AccessibleStateType::SELECTED); if (xShapes.is())
xShapes->add(pAccShapeData->xShape);
}
}
xSelectionSupplier->select(uno::Any(xShapes));
} catch (lang::IllegalArgumentException&)
{
SelectionChanged(); // find all selected shapes and set the flags
}
}
void ScChildrenShapes::FillShapes(std::vector < uno::Reference < drawing::XShape > >& rShapes) const
{
uno::Reference<drawing::XShapes> xShapes(mpViewShell->getSelectedXShapes()); if (xShapes.is())
{
sal_uInt32 nCount(xShapes->getCount()); for (sal_uInt32 i = 0; i < nCount; ++i)
{
uno::Reference<drawing::XShape> xShape;
xShapes->getByIndex(i) >>= xShape; if (xShape.is())
rShapes.push_back(xShape);
}
}
}
sal_Int32 ScChildrenShapes::GetSelectedCount() const
{ if (!xSelectionSupplier.is()) throw uno::RuntimeException("Could not get selected shapes. Null reference to xSelectionSupplier in ScChildrenShapes::GetSelectedCount.");
if (nSelectedChildIndex < 0 || o3tl::make_unsigned(nSelectedChildIndex) >= aShapes.size()) return xAccessible;
SortedShapes::iterator aItr; if (FindShape(aShapes[nSelectedChildIndex], aItr))
xAccessible = Get(*aItr);
} else
{ if (mbShapesNeedSorting)
{
std::sort(maZOrderedShapes.begin(), maZOrderedShapes.end(), ScShapeDataLess());
mbShapesNeedSorting = false;
} for(constauto& rpShape : maZOrderedShapes)
{ if (!rpShape || rpShape->bSelected)
{ if (nSelectedChildIndex == 0)
{ if (rpShape)
xAccessible = rpShape->pAccShape.get(); break;
} else
--nSelectedChildIndex;
}
}
}
return xAccessible;
}
void ScChildrenShapes::Deselect(sal_Int32 nChildIndex)
{
uno::Reference<drawing::XShape> xShape; if (!IsSelected(nChildIndex, xShape)) // returns false if it is the sheet return;
if (!xShape.is()) return;
uno::Reference<drawing::XShapes> xShapes(mpViewShell->getSelectedXShapes()); if (xShapes.is())
xShapes->remove(xShape);
if (!xSelectionSupplier.is()) throw uno::RuntimeException("Could not get selected shapes. Null reference to xSelectionSupplier in ScChildrenShapes::AddShape.");
uno::Reference<drawing::XShapes> xShapes(mpViewShell->getSelectedXShapes());
uno::Reference<container::XEnumerationAccess> xEnumAcc(xShapes, uno::UNO_QUERY); if (xEnumAcc.is())
{
uno::Reference<container::XEnumeration> xEnum = xEnumAcc->createEnumeration(); if (xEnum.is())
{
uno::Reference<drawing::XShape> xSelectedShape; bool bFound(false); while (!bFound && xEnum->hasMoreElements())
{
xEnum->nextElement() >>= xSelectedShape; if (xShape.is() && (xShape.get() == xSelectedShape.get()))
{
pShape->bSelected = true;
bFound = true;
}
}
}
} if (mpAccessibleDocument && bCommitChange)
{ // new child - event
mpAccessibleDocument->CommitChange(AccessibleEventId::CHILD, uno::Any(),
uno::Any(uno::Reference<XAccessible>(Get(pShape))));
}
}
void ScChildrenShapes::RemoveShape(const uno::Reference<drawing::XShape>& xShape) const
{ if (mbShapesNeedSorting)
{
std::sort(maZOrderedShapes.begin(), maZOrderedShapes.end(), ScShapeDataLess());
mbShapesNeedSorting = false;
}
SortedShapes::iterator aItr; if (FindShape(xShape, aItr))
{ if (mpAccessibleDocument)
{
rtl::Reference<::accessibility::AccessibleShape> xOldAccessible(Get(*aItr));
IMPL_LINK( ScAccessibleDocument, WindowChildEventListener, VclWindowEvent&, rEvent, void )
{
OSL_ENSURE( rEvent.GetWindow(), "Window???" ); switch ( rEvent.GetId() )
{ case VclEventId::WindowShow: // send create on show for direct accessible children
{
vcl::Window* pChildWin = static_cast < vcl::Window * >( rEvent.GetData() ); if( pChildWin && AccessibleRole::EMBEDDED_OBJECT == pChildWin->GetAccessibleRole() )
{
AddChild( pChildWin->GetAccessible(), true );
}
} break; case VclEventId::WindowHide: // send destroy on hide for direct accessible children
{
vcl::Window* pChildWin = static_cast < vcl::Window * >( rEvent.GetData() ); if( pChildWin && AccessibleRole::EMBEDDED_OBJECT == pChildWin->GetAccessibleRole() )
{
RemoveChild( pChildWin->GetAccessible(), true );
}
} break; default: break;
}
}
void ScAccessibleDocument::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
{ if (rHint.GetId() == SfxHintId::ScAccGridWinFocusLost )
{ auto pFocusLostHint = static_cast<const ScAccGridWinFocusLostHint*>(&rHint); if (pFocusLostHint->GetOldGridWin() == meSplitPos)
{ if (mxTempAcc.is() && mpTempAccEdit)
mpTempAccEdit->LostFocus(); elseif (mpAccessibleSpreadsheet.is())
mpAccessibleSpreadsheet->LostFocus(); else
CommitFocusLost();
}
} elseif (rHint.GetId() == SfxHintId::ScAccGridWinFocusGot)
{ auto pFocusGotHint = static_cast<const ScAccGridWinFocusGotHint*>(&rHint); if (pFocusGotHint->GetNewGridWin() == meSplitPos)
{
rtl::Reference<::accessibility::AccessibleShape> xAccShape; if (mpChildrenShapes)
{ bool bTabMarked(IsTableSelected());
xAccShape = mpChildrenShapes->GetSelected(0, bTabMarked);
} if (xAccShape.is())
{
uno::Any aNewValue;
aNewValue<<=AccessibleStateType::FOCUSED;
xAccShape->CommitChange(AccessibleEventId::STATE_CHANGED, aNewValue, uno::Any(),
-1);
} else
{ if (mxTempAcc.is() && mpTempAccEdit)
mpTempAccEdit->GotFocus(); elseif (mpAccessibleSpreadsheet.is())
mpAccessibleSpreadsheet->GotFocus(); else
CommitFocusGained();
}
}
} elseif (rHint.GetId() == SfxHintId::ScAccTableChanged)
{ // only notify if child exist, otherwise it is not necessary if (mpAccessibleSpreadsheet.is())
{
FreeAccessibleSpreadsheet();
// Shapes / form controls after reload not accessible, rebuild the // mpChildrenShapes variable.
mpChildrenShapes.reset( new ScChildrenShapes( this, mpViewShell, meSplitPos ) );
// all children changed
CommitChange(AccessibleEventId::INVALIDATE_ALL_CHILDREN, uno::Any(), uno::Any());
if (mpAccessibleSpreadsheet.is())
mpAccessibleSpreadsheet->GotFocus();
}
} elseif (rHint.GetId() == SfxHintId::ScAccMakeDrawLayer)
{ if (mpChildrenShapes)
mpChildrenShapes->SetDrawBroadcaster();
} elseif (rHint.GetId() == SfxHintId::ScAccEnterEditMode) // this event comes only on creating edit field of a cell
{ if (mpViewShell->GetViewData().GetEditActivePart() == meSplitPos)
{
ScViewData& rViewData = mpViewShell->GetViewData();
EditEngine const& rEditEng = rViewData.GetEditView(meSplitPos)->getEditEngine(); if (rEditEng.IsUpdateLayout())
{
mpTempAccEdit = new ScAccessibleEditObject(this, rViewData.GetEditView(meSplitPos),
mpViewShell->GetWindowByPos(meSplitPos), GetCurrentCellName(),
ScResId(STR_ACC_EDITLINE_DESCR), ScAccessibleEditObject::CellInEditMode);
uno::Reference<XAccessibleComponent> xAccessibleComponent(getAccessibleParent()->getAccessibleContext(), uno::UNO_QUERY); if (xAccessibleComponent.is())
{
xAccessibleComponent->grabFocus(); // grab only focus if it does not have the focus and it is not hidden if (mpViewShell &&
(mpViewShell->GetViewData().GetActivePart() != meSplitPos) &&
mpViewShell->GetWindowByPos(meSplitPos)->IsVisible())
{
mpViewShell->ActivatePart(meSplitPos);
}
}
}
/// Return the number of currently visible children.
sal_Int64 SAL_CALL
ScAccessibleDocument::getAccessibleChildCount()
{
SolarMutexGuard aGuard;
ensureAlive();
sal_Int64 nCount(1); if (mpChildrenShapes)
nCount = mpChildrenShapes->GetCount(); // returns the count of the shapes inclusive the table
if (mxTempAcc.is())
++nCount;
return nCount;
}
/// Return the specified child or NULL if index is invalid.
uno::Reference<XAccessible> SAL_CALL
ScAccessibleDocument::getAccessibleChild(sal_Int64 nIndex)
{
SolarMutexGuard aGuard;
ensureAlive();
uno::Reference<XAccessible> xAccessible; if (nIndex >= 0)
{
sal_Int64 nCount(1); if (mpChildrenShapes)
{
xAccessible = mpChildrenShapes->Get(nIndex); // returns NULL if it is the table or out of range
nCount = mpChildrenShapes->GetCount(); //there is always a table
} if (!xAccessible.is())
{ if (nIndex < nCount)
xAccessible = GetAccessibleSpreadsheet(); elseif (nIndex == nCount && mxTempAcc.is())
xAccessible = mxTempAcc;
}
}
if (!xAccessible.is()) throw lang::IndexOutOfBoundsException();
return xAccessible;
}
/// Return the set of current states.
sal_Int64 SAL_CALL
ScAccessibleDocument::getAccessibleStateSet()
{
SolarMutexGuard aGuard;
sal_Int64 nParentStates = 0; if (getAccessibleParent().is())
{
uno::Reference<XAccessibleContext> xParentContext = getAccessibleParent()->getAccessibleContext();
nParentStates = xParentContext->getAccessibleStateSet();
}
sal_Int64 nStateSet = 0; if (IsDefunc(nParentStates))
nStateSet |= AccessibleStateType::DEFUNC; else
{
nStateSet |= AccessibleStateType::EDITABLE;
nStateSet |= AccessibleStateType::ENABLED;
nStateSet |= AccessibleStateType::OPAQUE; if (isShowing())
nStateSet |= AccessibleStateType::SHOWING; if (isVisible())
nStateSet |= AccessibleStateType::VISIBLE;
} return nStateSet;
}
sal_Int32 nCount(mpChildrenShapes->GetCount()); // all shapes and the table if (mxTempAcc.is())
++nCount; if (nChildIndex < 0 || nChildIndex >= nCount) throw lang::IndexOutOfBoundsException();
uno::Reference < XAccessible > xAccessible = mpChildrenShapes->Get(nChildIndex); if (xAccessible.is())
{ bool bWasTableSelected(IsTableSelected());
mpChildrenShapes->Select(nChildIndex); // throws no lang::IndexOutOfBoundsException if Index is too high if (bWasTableSelected)
mpViewShell->SelectAll();
} else
{
mpViewShell->SelectAll();
}
}
if (mpChildrenShapes)
{
sal_Int32 nCount(mpChildrenShapes->GetCount()); // all shapes and the table if (mxTempAcc.is())
++nCount; if (nChildIndex < 0 || nChildIndex >= nCount) throw lang::IndexOutOfBoundsException();
uno::Reference < XAccessible > xAccessible = mpChildrenShapes->Get(nChildIndex); if (xAccessible.is())
{
uno::Reference<drawing::XShape> xShape;
bResult = mpChildrenShapes->IsSelected(nChildIndex, xShape); // throws no lang::IndexOutOfBoundsException if Index is too high
} else
{ if (mxTempAcc.is() && nChildIndex == nCount)
bResult = true; else
bResult = IsTableSelected();
}
} return bResult;
}
if (mpChildrenShapes)
nCount = mpChildrenShapes->GetSelectedCount();
if (IsTableSelected())
++nCount;
if (mxTempAcc.is())
++nCount;
return nCount;
}
uno::Reference<XAccessible > SAL_CALL
ScAccessibleDocument::getSelectedAccessibleChild( sal_Int64 nSelectedChildIndex )
{
SolarMutexGuard aGuard;
ensureAlive();
uno::Reference<XAccessible> xAccessible; if (mpChildrenShapes)
{
sal_Int64 nCount(getSelectedAccessibleChildCount()); //all shapes and the table if (nSelectedChildIndex < 0 || nSelectedChildIndex >= nCount) throw lang::IndexOutOfBoundsException();
bool bTabMarked(IsTableSelected());
if (mpChildrenShapes)
xAccessible = mpChildrenShapes->GetSelected(nSelectedChildIndex, bTabMarked); // throws no lang::IndexOutOfBoundsException if Index is too high if (mxTempAcc.is() && nSelectedChildIndex == nCount - 1)
xAccessible = mxTempAcc; elseif (bTabMarked)
xAccessible = GetAccessibleSpreadsheet();
}
OSL_ENSURE(xAccessible.is(), "here should always be an accessible object or an exception thrown");
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.